ConfigLMM 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +70 -0
  3. data/CNAME +1 -0
  4. data/Examples/.lmm.state.yaml +159 -0
  5. data/Examples/ConfigLMM.mm.yaml +32 -0
  6. data/Examples/Implemented.mm.yaml +252 -4
  7. data/Examples/SmallBusiness.mm.yaml +492 -0
  8. data/Plugins/Apps/Answer/answer.lmm.rb +165 -0
  9. data/Plugins/Apps/Answer/answer@.service +40 -0
  10. data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.conf.erb +0 -3
  11. data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.lmm.rb +0 -1
  12. data/Plugins/Apps/Authentik/Authentik-ProxyOutpost.container +20 -0
  13. data/Plugins/Apps/Authentik/Authentik-Server.container +7 -1
  14. data/Plugins/Apps/Authentik/Authentik-Worker.container +7 -1
  15. data/Plugins/Apps/Authentik/Authentik.conf.erb +18 -6
  16. data/Plugins/Apps/Authentik/Authentik.lmm.rb +232 -45
  17. data/Plugins/Apps/BookStack/BookStack.conf.erb +38 -0
  18. data/Plugins/Apps/BookStack/BookStack.container +20 -0
  19. data/Plugins/Apps/BookStack/BookStack.lmm.rb +91 -0
  20. data/Plugins/Apps/Cassandra/Cassandra.lmm.rb +9 -19
  21. data/Plugins/Apps/ClickHouse/ClickHouse.container +28 -0
  22. data/Plugins/Apps/ClickHouse/ClickHouse.lmm.rb +113 -0
  23. data/Plugins/Apps/ClickHouse/Config/listen.yaml +2 -0
  24. data/Plugins/Apps/ClickHouse/Config/logger.yaml +8 -0
  25. data/Plugins/Apps/ClickHouse/Config/zookeepers.yaml +5 -0
  26. data/Plugins/Apps/ClickHouse/Connection.rb +96 -0
  27. data/Plugins/Apps/Discourse/Discourse-Sidekiq.container +22 -0
  28. data/Plugins/Apps/Discourse/Discourse.conf.erb +38 -0
  29. data/Plugins/Apps/Discourse/Discourse.container +21 -0
  30. data/Plugins/Apps/Discourse/Discourse.lmm.rb +156 -0
  31. data/Plugins/Apps/Dovecot/Dovecot.lmm.rb +87 -52
  32. data/Plugins/Apps/ERPNext/ERPNext-Frontend.container +24 -0
  33. data/Plugins/Apps/ERPNext/ERPNext-Queue.container +22 -0
  34. data/Plugins/Apps/ERPNext/ERPNext-Scheduler.container +22 -0
  35. data/Plugins/Apps/ERPNext/ERPNext-Websocket.container +24 -0
  36. data/Plugins/Apps/ERPNext/ERPNext.container +23 -0
  37. data/Plugins/Apps/ERPNext/ERPNext.lmm.rb +204 -0
  38. data/Plugins/Apps/ERPNext/ERPNext.network +12 -0
  39. data/Plugins/Apps/ERPNext/sites/apps.json +10 -0
  40. data/Plugins/Apps/ERPNext/sites/apps.txt +3 -0
  41. data/Plugins/Apps/ERPNext/sites/common_site_config.json +11 -0
  42. data/Plugins/Apps/GitLab/GitLab.container +9 -2
  43. data/Plugins/Apps/GitLab/GitLab.lmm.rb +52 -33
  44. data/Plugins/Apps/Homepage/Homepage.conf.erb +86 -0
  45. data/Plugins/Apps/Homepage/Homepage.container +19 -0
  46. data/Plugins/Apps/Homepage/Homepage.lmm.rb +54 -0
  47. data/Plugins/Apps/IPFS/IPFS.conf.erb +0 -3
  48. data/Plugins/Apps/IPFS/IPFS.lmm.rb +0 -1
  49. data/Plugins/Apps/InfluxDB/InfluxDB.conf.erb +0 -3
  50. data/Plugins/Apps/InfluxDB/InfluxDB.lmm.rb +0 -1
  51. data/Plugins/Apps/Jackett/Jackett.conf.erb +0 -3
  52. data/Plugins/Apps/Jackett/Jackett.lmm.rb +0 -1
  53. data/Plugins/Apps/Jellyfin/Jellyfin.conf.erb +0 -3
  54. data/Plugins/Apps/Jellyfin/Jellyfin.lmm.rb +0 -1
  55. data/Plugins/Apps/LetsEncrypt/LetsEncrypt.lmm.rb +78 -0
  56. data/Plugins/Apps/LetsEncrypt/hooks/dovecot.sh +2 -0
  57. data/Plugins/Apps/LetsEncrypt/hooks/nginx.sh +2 -0
  58. data/Plugins/Apps/LetsEncrypt/hooks/postfix.sh +2 -0
  59. data/Plugins/Apps/LetsEncrypt/renew-certificates.service +7 -0
  60. data/Plugins/Apps/LetsEncrypt/renew-certificates.timer +12 -0
  61. data/Plugins/Apps/LetsEncrypt/rfc2136.ini +11 -0
  62. data/Plugins/Apps/LibreTranslate/LibreTranslate.container +21 -0
  63. data/Plugins/Apps/LibreTranslate/LibreTranslate.lmm.rb +34 -0
  64. data/Plugins/Apps/Lobsters/Containerfile +81 -0
  65. data/Plugins/Apps/Lobsters/Lobsters-Tasks.container +26 -0
  66. data/Plugins/Apps/Lobsters/Lobsters.conf.erb +99 -0
  67. data/Plugins/Apps/Lobsters/Lobsters.container +27 -0
  68. data/Plugins/Apps/Lobsters/Lobsters.lmm.rb +196 -0
  69. data/Plugins/Apps/Lobsters/crontab +3 -0
  70. data/Plugins/Apps/Lobsters/database.yml +26 -0
  71. data/Plugins/Apps/Lobsters/entrypoint.sh +30 -0
  72. data/Plugins/Apps/Lobsters/generateCredentials.rb +19 -0
  73. data/Plugins/Apps/Lobsters/lobsters-cron.sh +25 -0
  74. data/Plugins/Apps/Lobsters/lobsters-daily.sh +23 -0
  75. data/Plugins/Apps/Lobsters/puma.rb +49 -0
  76. data/Plugins/Apps/MariaDB/Connection.rb +55 -0
  77. data/Plugins/Apps/MariaDB/MariaDB.lmm.rb +122 -0
  78. data/Plugins/Apps/Mastodon/Mastodon-Sidekiq.container +22 -0
  79. data/Plugins/Apps/Mastodon/Mastodon-Streaming.container +20 -0
  80. data/Plugins/Apps/Mastodon/Mastodon.conf.erb +34 -45
  81. data/Plugins/Apps/Mastodon/Mastodon.container +28 -0
  82. data/Plugins/Apps/Mastodon/Mastodon.lmm.rb +240 -5
  83. data/Plugins/Apps/Mastodon/configlmm.rake +30 -0
  84. data/Plugins/Apps/Mastodon/entrypoint.sh +16 -0
  85. data/Plugins/Apps/Matrix/Element.container +19 -0
  86. data/Plugins/Apps/Matrix/Matrix.conf.erb +47 -9
  87. data/Plugins/Apps/Matrix/Matrix.lmm.rb +119 -5
  88. data/Plugins/Apps/Matrix/Synapse.container +22 -0
  89. data/Plugins/Apps/Matrix/config.json +50 -0
  90. data/Plugins/Apps/Matrix/homeserver.yaml +70 -0
  91. data/Plugins/Apps/Matrix/log.config +30 -0
  92. data/Plugins/Apps/Netdata/Netdata.conf.erb +0 -3
  93. data/Plugins/Apps/Netdata/Netdata.lmm.rb +0 -1
  94. data/Plugins/Apps/Nextcloud/Nextcloud.conf.erb +3 -4
  95. data/Plugins/Apps/Nextcloud/Nextcloud.lmm.rb +155 -48
  96. data/Plugins/Apps/Nextcloud/autoconfig.php +13 -0
  97. data/Plugins/Apps/Nextcloud/config.php +10 -1
  98. data/Plugins/Apps/Nextcloud/nextcloudcron.service +8 -0
  99. data/Plugins/Apps/Nextcloud/nextcloudcron.timer +10 -0
  100. data/Plugins/Apps/Nginx/Connection.rb +93 -0
  101. data/Plugins/Apps/Nginx/conf.d/configlmm.conf +54 -4
  102. data/Plugins/Apps/Nginx/conf.d/languages.conf +21 -0
  103. data/Plugins/Apps/Nginx/config-lmm/errors.conf +33 -22
  104. data/Plugins/Apps/Nginx/config-lmm/gateway-errors.conf +20 -0
  105. data/Plugins/Apps/Nginx/config-lmm/proxy.conf +6 -2
  106. data/Plugins/Apps/Nginx/main.conf.erb +7 -3
  107. data/Plugins/Apps/Nginx/nginx.conf +2 -2
  108. data/Plugins/Apps/Nginx/nginx.lmm.rb +103 -81
  109. data/Plugins/Apps/Nginx/proxy.conf.erb +24 -6
  110. data/Plugins/Apps/Odoo/Odoo.conf.erb +0 -3
  111. data/Plugins/Apps/Odoo/Odoo.container +7 -1
  112. data/Plugins/Apps/Odoo/Odoo.lmm.rb +4 -5
  113. data/Plugins/Apps/Ollama/Ollama.container +26 -0
  114. data/Plugins/Apps/Ollama/Ollama.lmm.rb +73 -0
  115. data/Plugins/Apps/OpenTelemetry/Config/config.yaml +704 -0
  116. data/Plugins/Apps/OpenTelemetry/OpenTelemetry.lmm.rb +154 -0
  117. data/Plugins/Apps/OpenVidu/Ingress.container +23 -0
  118. data/Plugins/Apps/{GitLab/GitLab.conf.erb → OpenVidu/OpenVidu.conf.erb} +8 -3
  119. data/Plugins/Apps/OpenVidu/OpenVidu.container +21 -0
  120. data/Plugins/Apps/OpenVidu/OpenVidu.lmm.rb +94 -0
  121. data/Plugins/Apps/OpenVidu/OpenViduCall.conf.erb +32 -0
  122. data/Plugins/Apps/OpenVidu/OpenViduCall.container +20 -0
  123. data/Plugins/Apps/OpenVidu/ingress.yaml +10 -0
  124. data/Plugins/Apps/OpenVidu/livekit.yaml +13 -0
  125. data/Plugins/Apps/PHP-FPM/Connection.rb +91 -0
  126. data/Plugins/Apps/PHP-FPM/PHP-FPM.lmm.rb +31 -4
  127. data/Plugins/Apps/Peppermint/Peppermint.conf.erb +2 -9
  128. data/Plugins/Apps/Peppermint/Peppermint.container +7 -1
  129. data/Plugins/Apps/Peppermint/Peppermint.lmm.rb +29 -33
  130. data/Plugins/Apps/Perplexica/Perplexica.container +25 -0
  131. data/Plugins/Apps/Perplexica/Perplexica.lmm.rb +92 -0
  132. data/Plugins/Apps/Perplexica/config.toml +26 -0
  133. data/Plugins/Apps/Podman/Connection.rb +24 -0
  134. data/Plugins/Apps/Podman/Podman.lmm.rb +80 -0
  135. data/Plugins/Apps/Podman/storage.conf +6 -0
  136. data/Plugins/Apps/Postfix/Postfix.lmm.rb +249 -145
  137. data/Plugins/Apps/PostgreSQL/Connection.rb +97 -0
  138. data/Plugins/Apps/PostgreSQL/PostgreSQL.lmm.rb +204 -99
  139. data/Plugins/Apps/Pterodactyl/Pterodactyl.conf.erb +0 -3
  140. data/Plugins/Apps/Pterodactyl/Pterodactyl.lmm.rb +0 -2
  141. data/Plugins/Apps/Pterodactyl/Wings.conf.erb +0 -3
  142. data/Plugins/Apps/RVM/RVM.lmm.rb +57 -0
  143. data/Plugins/Apps/Roundcube/Roundcube.conf.erb +72 -0
  144. data/Plugins/Apps/Roundcube/Roundcube.lmm.rb +141 -0
  145. data/Plugins/Apps/SSH/SSH.lmm.rb +9 -15
  146. data/Plugins/Apps/SearXNG/SearXNG.container +22 -0
  147. data/Plugins/Apps/SearXNG/SearXNG.lmm.rb +79 -0
  148. data/Plugins/Apps/SearXNG/limiter.toml +40 -0
  149. data/Plugins/Apps/SearXNG/settings.yml +2 -0
  150. data/Plugins/Apps/SigNoz/Config/alerts.yml +11 -0
  151. data/Plugins/Apps/SigNoz/Config/otel-collector-config.yaml +110 -0
  152. data/Plugins/Apps/SigNoz/Config/otel-collector-opamp-config.yaml +1 -0
  153. data/Plugins/Apps/SigNoz/Config/prometheus.yml +18 -0
  154. data/Plugins/Apps/SigNoz/SigNoz-Collector.container +23 -0
  155. data/Plugins/Apps/SigNoz/SigNoz-Migrator.container +17 -0
  156. data/Plugins/Apps/SigNoz/SigNoz.conf.erb +61 -0
  157. data/Plugins/Apps/SigNoz/SigNoz.container +26 -0
  158. data/Plugins/Apps/SigNoz/SigNoz.lmm.rb +319 -0
  159. data/Plugins/Apps/Solr/log4j2.xml +89 -0
  160. data/Plugins/Apps/Solr/solr.lmm.rb +82 -0
  161. data/Plugins/Apps/Sunshine/Sunshine.conf.erb +0 -3
  162. data/Plugins/Apps/Sunshine/Sunshine.lmm.rb +0 -1
  163. data/Plugins/Apps/Tunnel/tunnel.lmm.rb +59 -0
  164. data/Plugins/Apps/Tunnel/tunnelTCP.service +9 -0
  165. data/Plugins/Apps/Tunnel/tunnelTCP.socket +9 -0
  166. data/Plugins/Apps/Tunnel/tunnelUDP.service +9 -0
  167. data/Plugins/Apps/Tunnel/tunnelUDP.socket +9 -0
  168. data/Plugins/Apps/UVdesk/UVdesk.conf.erb +0 -3
  169. data/Plugins/Apps/Umami/Umami.container +19 -0
  170. data/Plugins/Apps/Umami/Umami.lmm.rb +108 -0
  171. data/Plugins/Apps/Valkey/Valkey.lmm.rb +64 -20
  172. data/Plugins/Apps/Vaultwarden/Vaultwarden.conf.erb +9 -6
  173. data/Plugins/Apps/Vaultwarden/Vaultwarden.container +7 -1
  174. data/Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb +67 -28
  175. data/Plugins/Apps/Wiki.js/Wiki.js.conf.erb +39 -0
  176. data/Plugins/Apps/Wiki.js/Wiki.js.container +20 -0
  177. data/Plugins/Apps/Wiki.js/Wiki.js.lmm.rb +55 -0
  178. data/Plugins/Apps/YaCy/YaCy.conf.erb +93 -0
  179. data/Plugins/Apps/YaCy/YaCy.container +21 -0
  180. data/Plugins/Apps/YaCy/YaCy.lmm.rb +160 -0
  181. data/Plugins/Apps/ZooKeeper/ZooKeeper.container +24 -0
  182. data/Plugins/Apps/ZooKeeper/ZooKeeper.lmm.rb +68 -0
  183. data/Plugins/Apps/bitmagnet/bitmagnet.conf.erb +0 -3
  184. data/Plugins/Apps/bitmagnet/bitmagnet.lmm.rb +0 -1
  185. data/Plugins/Apps/gollum/gollum.conf.erb +40 -4
  186. data/Plugins/Apps/gollum/gollum.container +10 -1
  187. data/Plugins/Apps/gollum/gollum.lmm.rb +56 -47
  188. data/Plugins/Apps/llama.cpp/llama.cpp.container +28 -0
  189. data/Plugins/Apps/llama.cpp/llama.cpp.lmm.rb +90 -0
  190. data/Plugins/Apps/vLLM/vLLM.container +32 -0
  191. data/Plugins/Apps/vLLM/vLLM.lmm.rb +89 -0
  192. data/Plugins/OS/General/Utils.lmm.rb +26 -0
  193. data/Plugins/OS/Linux/Connection.rb +472 -0
  194. data/Plugins/OS/Linux/Debian/preseed.cfg.erb +81 -0
  195. data/Plugins/OS/Linux/Distributions.yaml +32 -0
  196. data/Plugins/OS/Linux/Flavours.yaml +24 -0
  197. data/Plugins/OS/Linux/Grub/grub.cfg +10 -0
  198. data/Plugins/OS/Linux/HTTP.rb +32 -0
  199. data/Plugins/OS/Linux/Linux.lmm.rb +708 -174
  200. data/Plugins/OS/Linux/Packages.yaml +67 -3
  201. data/Plugins/OS/Linux/Proxmox/answer.toml.erb +30 -0
  202. data/Plugins/OS/Linux/Services.yaml +8 -0
  203. data/Plugins/OS/Linux/Shell.rb +70 -0
  204. data/Plugins/OS/Linux/Syslinux/default +8 -0
  205. data/Plugins/OS/Linux/WireGuard/WireGuard.lmm.rb +93 -40
  206. data/Plugins/OS/Linux/WireGuard/wg0.conf.erb +3 -0
  207. data/Plugins/OS/Linux/openSUSE/autoinst.xml.erb +29 -3
  208. data/Plugins/OS/Linux/systemd/systemd.lmm.rb +13 -11
  209. data/Plugins/OS/Routers/Aruba/ArubaInstant.lmm.rb +6 -5
  210. data/Plugins/Platforms/GitHub.lmm.rb +73 -28
  211. data/Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb +10 -7
  212. data/Plugins/Platforms/Proxmox/Proxmox.lmm.rb +402 -0
  213. data/Plugins/Platforms/Proxmox/XTerm.rb +321 -0
  214. data/Plugins/Platforms/libvirt/libvirt.lmm.rb +41 -15
  215. data/Plugins/Platforms/porkbun.lmm.rb +12 -2
  216. data/Plugins/Platforms/porkbun_spec.rb +2 -2
  217. data/Plugins/Services/DNS/AmberBit.lmm.rb +1 -1
  218. data/Plugins/Services/DNS/ArubaItDNS.lmm.rb +1 -1
  219. data/Plugins/Services/DNS/NICLV.lmm.rb +1 -1
  220. data/Plugins/Services/DNS/PowerDNS.lmm.rb +130 -41
  221. data/Plugins/Services/DNS/tonic.lmm.rb +22 -12
  222. data/bootstrap.sh +41 -3
  223. data/lib/ConfigLMM/Framework/plugins/dns.rb +4 -3
  224. data/lib/ConfigLMM/Framework/plugins/linuxApp.rb +187 -144
  225. data/lib/ConfigLMM/Framework/plugins/nginxApp.rb +54 -6
  226. data/lib/ConfigLMM/Framework/plugins/plugin.rb +68 -140
  227. data/lib/ConfigLMM/Framework/plugins/store.rb +4 -4
  228. data/lib/ConfigLMM/Framework/variables.rb +75 -0
  229. data/lib/ConfigLMM/Framework.rb +1 -0
  230. data/lib/ConfigLMM/cli.rb +13 -5
  231. data/lib/ConfigLMM/commands/cleanup.rb +1 -0
  232. data/lib/ConfigLMM/commands/configsCommand.rb +38 -5
  233. data/lib/ConfigLMM/commands/diff.rb +33 -9
  234. data/lib/ConfigLMM/context.rb +22 -3
  235. data/lib/ConfigLMM/io/configList.rb +85 -7
  236. data/lib/ConfigLMM/io/connection.rb +143 -0
  237. data/lib/ConfigLMM/io/dhcp.rb +330 -0
  238. data/lib/ConfigLMM/io/http.rb +78 -0
  239. data/lib/ConfigLMM/io/local.rb +207 -0
  240. data/lib/ConfigLMM/io/pxe.rb +92 -0
  241. data/lib/ConfigLMM/io/ssh.rb +156 -0
  242. data/lib/ConfigLMM/io/tftp.rb +105 -0
  243. data/lib/ConfigLMM/io.rb +2 -0
  244. data/lib/ConfigLMM/secrets/envStore.rb +39 -0
  245. data/lib/ConfigLMM/secrets/fileStore.rb +43 -0
  246. data/lib/ConfigLMM/state.rb +12 -3
  247. data/lib/ConfigLMM/version.rb +2 -1
  248. data/lib/ConfigLMM.rb +1 -0
  249. data/{Examples → scripts}/configlmmAuth.sh +7 -5
  250. metadata +257 -9
@@ -0,0 +1,492 @@
1
+
2
+ _VARIABLES_:
3
+ ProxmoxDomain: proxmox.example.org
4
+ ProxmoxIP: 192.168.1.2
5
+ IngressDomain: ingress.example.org
6
+ IngressPublicIP: 1.2.3.4
7
+ IngressIP: 10.0.0.3
8
+ ServicesHostName: services.example.org
9
+ ServicesIP: 10.0.0.4
10
+
11
+ Bootstrap:
12
+ Type: Linux
13
+ Location: @me
14
+ Hosts:
15
+ "${VAR:ProxmoxIP}":
16
+ - ${VAR:ProxmoxDomain}
17
+ "${VAR:IngressIP}":
18
+ - ${VAR:IngressDomain}
19
+ "${VAR:ServicesIP}":
20
+ - ${VAR:ServicesHostName}
21
+ SSH:
22
+ Config:
23
+ proxmox:
24
+ User: root
25
+ HostName: ${VAR:ProxmoxDomain}
26
+ ingress:
27
+ User: root
28
+ HostName: ${VAR:IngressDomain}
29
+ services:
30
+ User: root
31
+ HostName: ${VAR:ServicesHostName}
32
+
33
+ Porkbun:
34
+ Type: PorkbunDNS
35
+ DNS:
36
+ example.org:
37
+ '@':
38
+ - ALIAS=${VAR:IngressDomain}
39
+ - MX=10 mail.example.org
40
+ ingress:
41
+ - A=${VAR:IngressPublicIP}
42
+ mail:
43
+ - CNAME=${VAR:IngressDomain}
44
+
45
+ Proxmox:
46
+ Type: Linux
47
+ Location: pxe://
48
+ AlternativeLocation: ssh://proxmox/
49
+ Distro: Debian
50
+ Flavour: Proxmox VE
51
+ Firmware: UEFI
52
+ Domain: ${VAR:ProxmoxDomain}
53
+ EMail: proxmox@example.org
54
+ Users:
55
+ root:
56
+ Subuids:
57
+ - 100000-265536
58
+ Subgids:
59
+ - 100000-265536
60
+ AuthorizedKeys:
61
+ - ~/.ssh/id_ed25519.pub
62
+ Sysctl:
63
+ net.ipv4.ip_forward: 1 # Need to work as router
64
+ vm.overcommit_memory: 1 # Need for ValKey
65
+ Network:
66
+ Interfaces:
67
+ enp3s0:
68
+ IP: ${VAR:ProxmoxIP}/24
69
+ Gateway: 192.168.1.1
70
+ DNS: 192.168.1.1
71
+ vmbr0:
72
+ Ports:
73
+ - enp1s0
74
+ VLANFiltering: yes
75
+ VLANS: 1-5
76
+ vmbr0.1:
77
+ IP: 10.0.0.2/24
78
+ Gateway: 10.0.0.1
79
+ DNS: 10.0.0.1
80
+ Apps:
81
+ - sshd
82
+ - vim
83
+ - smartmontools
84
+ - htop
85
+ - iotop
86
+
87
+ Ingress:
88
+ Type: Linux
89
+ Location: proxmox://${VAR:ProxmoxDomain}/?insecure
90
+ AlternativeLocation: ssh://ingress/
91
+ Distro: openSUSE Leap
92
+ Domain: ${VAR:IngressDomain}
93
+ LXC: no
94
+ CPU: 12
95
+ RAM: 64 GiB
96
+ Swap: 10 GiB
97
+ Storage: 500 GiB
98
+ Apps:
99
+ - sshd
100
+ - fish
101
+ - vim
102
+ - htop
103
+ Firewall: yes
104
+ Hosts:
105
+ "${VAR:ServicesIP}":
106
+ - ${VAR:ServicesHostName}
107
+ Users:
108
+ root:
109
+ AuthorizedKeys:
110
+ - ~/.ssh/id_ed25519.pub
111
+ NIC:
112
+ - Bridge: vmbr0
113
+ VLAN: 2
114
+ - Bridge: vmbr0
115
+ VLAN: 1
116
+ Network:
117
+ IP: ${VAR:IngressPublicIP}/24
118
+ Gateway: 1.2.3.1
119
+ DNS: 1.1.1.1
120
+ Interfaces:
121
+ eth1:
122
+ IP: ${VAR:IngressIP}/24
123
+
124
+ IngressSSH:
125
+ Type: SSH
126
+ Location: ssh://ingress/
127
+ ListenAddress: ${VAR:IngressIP}
128
+ Settings:
129
+ PasswordAuthentication: no
130
+ KbdInteractiveAuthentication: no
131
+
132
+ IngressDovecot:
133
+ Type: Dovecot
134
+ Location: ssh://ingress/
135
+ Protocols:
136
+ - imap
137
+ - lmtp
138
+ Resources:
139
+ IngressDovecotDNS:
140
+ Type: Porkbun
141
+ DNS:
142
+ example.org:
143
+ IMAP: CNAME=${VAR:IngressDomain}
144
+
145
+ IngressPostfix:
146
+ Type: Postfix
147
+ Location: ssh://ingress/
148
+ Domain: mail.example.org
149
+ Submission: yes
150
+ ForwardDovecot: yes
151
+ Settings:
152
+ inet_interfaces: $myhostname, localhost
153
+ virtual_alias_maps: pcre:/etc/postfix/virtual
154
+ virtual_mailbox_maps: lmdb:/etc/postfix/mailboxes
155
+ Aliases:
156
+ root: Admin@example.org
157
+ postmaster: postmaster@example.org
158
+ Accounts:
159
+ signoz@example.org:
160
+ nextcloud@example.org:
161
+ vaultwarden@example.org:
162
+
163
+ IngressNginx:
164
+ Type: Nginx
165
+ Location: ssh://ingress/
166
+
167
+ IngressLetsEncrypt:
168
+ Type: LetsEncrypt
169
+ Location: ssh://ingress/
170
+ EMail: dns@example.org
171
+ Domain: '*.example.org'
172
+ DNS: porkbun
173
+ Hooks:
174
+ - nginx
175
+ - postfix
176
+ - dovecot
177
+
178
+ IngressOtelCollector:
179
+ Type: OtelCollector
180
+ Location: ssh://ingress/
181
+ Services:
182
+ nginx:
183
+ Exporters:
184
+ otlp:
185
+ endpoint: ${VAR:ServicesHostName}:4317
186
+ tls:
187
+ insecure: true
188
+
189
+
190
+ Services:
191
+ Type: Linux
192
+ Location: proxmox://${VAR:ProxmoxDomain}/?insecure
193
+ AlternativeLocation: proxmox+xterm://${VAR:ProxmoxDomain}/?insecure
194
+ Distro: openSUSE Leap
195
+ LXC:
196
+ - idmap: u 0 100000 165536
197
+ - idmap: g 0 100000 165536
198
+ - mount.entry: /dev/net dev/net none bind,create=dir
199
+ Features:
200
+ - nesting # For Podman
201
+ - fuse # Need for Podman performance workaround
202
+ CPU: 24
203
+ RAM: 128 GiB
204
+ Swap: 20 GiB
205
+ Domain: ${VAR:ServicesHostName}
206
+ Tmpfs: 2G
207
+ Hosts:
208
+ "${VAR:IngressIP}":
209
+ - ${VAR:IngressDomain}
210
+ Apps:
211
+ - sshd
212
+ - fish
213
+ - vim
214
+ - htop
215
+ - systemd-container
216
+ Firewall: yes
217
+ Users:
218
+ root:
219
+ Shell: fish
220
+ AuthorizedKeys:
221
+ - ~/.ssh/id_ed25519.pub
222
+ NIC:
223
+ - Bridge: vmbr0
224
+ VLAN: 1
225
+ Network:
226
+ IP: ${VAR:ServicesIP}/24
227
+ Gateway: 10.0.0.1
228
+ DNS: 10.0.0.1
229
+
230
+ ServicesSystemd:
231
+ Type: systemd
232
+ Location: ssh://services/
233
+ UserCgroups: yes # Need for Podman
234
+
235
+ ServicesPostgreSQL:
236
+ Type: PostgreSQL
237
+ Location: ssh://services/
238
+ AllowReplication:
239
+ - 10.0.0.0/24
240
+ Users:
241
+ replication:
242
+ Replication: yes
243
+ Password: ${GENERATE:ServicesPostgreSQL:REPLICATION_PASSWORD}
244
+ Settings:
245
+ wal_level: logical # for Logical Replication
246
+
247
+ ServicesMariaDB:
248
+ Type: MariaDB
249
+ Location: ssh://services/
250
+
251
+ ServicesValkey:
252
+ Type: Valkey
253
+ Location: ssh://services/
254
+ Password: no
255
+
256
+ ServicesPHPFPM:
257
+ Type: PHPFPM
258
+ Location: ssh://services/
259
+ Settings:
260
+ memory_limit: 1G
261
+ opcache.memory_consumption: 512
262
+ opcache.interned_strings_buffer: 64
263
+ opcache.max_accelerated_files: 50000
264
+ opcache.max_wasted_percentage: 15
265
+ opcache.validate_timestamps: 0
266
+
267
+ ServicesAuthentik:
268
+ Type: Authentik
269
+ Location: ssh://services/
270
+ Proxy: no
271
+ Domain: auth.example.org
272
+ Outposts:
273
+ - Proxy
274
+ Admin:
275
+ Name: admin
276
+ EMail: admin@example.org
277
+ SMTP:
278
+ SecretId: IngressPostfix
279
+ Host: mail.example.org
280
+ Port: 465
281
+ Username: auth@example.org
282
+ From: Auth <auth@example.org>
283
+ Groups:
284
+ accountants:
285
+ Resources:
286
+ ServicesAuthentikDNS:
287
+ Type: Porkbun
288
+ DNS:
289
+ example.org:
290
+ auth: CNAME=@
291
+ ServicesAuthentikProxy:
292
+ Type: Authentik
293
+ Location: ssh://ingress/
294
+ Domain: auth.example.org
295
+ Server: ${VAR:IngressDomain}
296
+ Proxy: only
297
+ Outposts:
298
+ - Proxy
299
+
300
+ ServicesSigNoz:
301
+ Type: SigNoz
302
+ Location: ssh://services/
303
+ Admin:
304
+ EMail: admin@exmaple.org
305
+ FirstName: admin
306
+ OrganizationName: example.org
307
+ SMTP:
308
+ SecretId: IngressPostfix
309
+ Host: mail.example.org
310
+ Port: 465
311
+ Username: signoz@example.org
312
+ FromAddress: signoz@example.org
313
+
314
+ ServicesSigNozCollector:
315
+ Type: SigNozCollector
316
+ Location: ssh://services/
317
+ Listen: 0.0.0.0
318
+ Environment: production
319
+
320
+ ServicesVaultwarden:
321
+ Type: Vaultwarden
322
+ Location: ssh://services/
323
+ Proxy: no
324
+ Domain: vaultwarden.example.org
325
+ SMTP:
326
+ SecretId: IngressPostfix
327
+ Host: mail.example.org
328
+ Port: 465
329
+ Username: vaultwarden@example.org
330
+ FromAddress: vaultwarden@example.org
331
+ Resources:
332
+ ServicesVaultwardenDNS:
333
+ Type: Porkbun
334
+ DNS:
335
+ example.org:
336
+ vaultwarden: CNAME=@
337
+ ServicesVaultwardenProxy:
338
+ Type: Vaultwarden
339
+ Location: ssh://ingress/
340
+ Domain: vaultwarden.example.org
341
+ Server: ${VAR:ServicesHostName}:18000
342
+ Proxy: only
343
+
344
+
345
+ # Needed for Nextcloud
346
+ ServicesNginx:
347
+ Type: Nginx
348
+ Location: ssh://services/
349
+ Mime:
350
+ mjs: text/javascript
351
+
352
+ ServicesNextcloud:
353
+ Type: Nextcloud
354
+ Location: ssh://services/
355
+ Domain: nextcloud.example.org
356
+ TLS: no
357
+ Admin:
358
+ Name: admin
359
+ EMail: admin@example.org
360
+ Database:
361
+ Type: pgsql
362
+ Apps:
363
+ - Calendar
364
+ - Contacts
365
+ - Mail
366
+ - SSO
367
+ SMTP:
368
+ SecretId: IngressPostfix
369
+ Host: mail.example.org
370
+ Port: 465
371
+ Username: nextcloud@example.org
372
+ FromAddress: nextcloud@example.org
373
+ Config:
374
+ trusted_proxies:
375
+ - ${VAR:IngressIP}
376
+ Resources:
377
+ ServicesNextcloudDNS:
378
+ Type: Porkbun
379
+ DNS:
380
+ example.org:
381
+ nextcloud: CNAME=@
382
+ ServicesNextcloudProxy:
383
+ Type: NginxProxy
384
+ Location: ssh://ingress/
385
+ Domain: nextcloud.example.org
386
+ Proxy: http://${VAR:ServicesHostName}
387
+ HandleErrors: no
388
+
389
+ ServicesGitLab:
390
+ Type: GitLab
391
+ Location: ssh://services/
392
+ Proxy: no
393
+ Domain: git.example.org
394
+ SMTP:
395
+ SecretId: IngressPostfix
396
+ Host: mail.example.org
397
+ Port: 465
398
+ Username: gitlab@example.org
399
+ TLS: yes
400
+ Resources:
401
+ ServicesGitLabDNS:
402
+ Type: Porkbun
403
+ DNS:
404
+ example.org:
405
+ git: CNAME=@
406
+ ServicesGitLabProxy:
407
+ Type: NginxProxy
408
+ Location: ssh://Ingress/
409
+ Domain: git.example.org
410
+ Proxy: http://${VAR:ServicesHostName}:18100
411
+ ServicesGitLabTunnel:
412
+ Type: Tunnel
413
+ Location: ssh://Ingress/
414
+ Port: 22
415
+ Remote: ${VAR:ServicesHostName}:22
416
+
417
+ ServicesERPNext:
418
+ Type: ERPNext
419
+ Location: ssh://services/
420
+ Proxy: no
421
+ Admin:
422
+ FullName: admin
423
+ EMail: admin@example.org
424
+ Resources:
425
+ ServicesERPNextDNS:
426
+ Type: Porkbun
427
+ DNS:
428
+ example.org:
429
+ erp: CNAME=@
430
+ ServicesERPNextProxy:
431
+ Type: NginxProxy
432
+ Location: ssh://ingress/
433
+ Domain: erp.example.org
434
+ Proxy: http://${VAR:ServicesHostName}:18400
435
+ HandleErrors: no
436
+ ServicesERPNextAuth:
437
+ Type: Authentik
438
+ Location: https://auth.example.org/?SecretId=ServicesAuthentik
439
+ Deploy: no
440
+ Providers:
441
+ ERPNext:
442
+ Type: OAuth2
443
+ Client: Confidential
444
+ Subject: UUID
445
+ Applications:
446
+ erpnext:
447
+ Name: ERPNext
448
+ Provider: ERPNext
449
+ Policies:
450
+ - accountants:
451
+ Type: Group
452
+
453
+ ServicesOtelCollector:
454
+ Type: OtelCollector
455
+ Location: ssh://services/
456
+ Environment: production
457
+ Services:
458
+ nginx:
459
+ postgresql:
460
+ php:
461
+ Users:
462
+ - nextcloud
463
+ Receivers:
464
+ filelog/nextcloud:
465
+ include: /var/lib/nextcloud/data/nextcloud.log
466
+ storage: file_storage
467
+ resource:
468
+ service.name: nextcloud
469
+ operators:
470
+ - type: json_parser
471
+ timestamp:
472
+ parse_from: attributes.time
473
+ layout_type: strptime
474
+ layout: "%FT%T%j"
475
+ - type: copy
476
+ from: attributes.message
477
+ to: resource['log.message']
478
+ - type: severity_parser
479
+ parse_from: attributes.level
480
+ overwrite_text: true
481
+ mapping:
482
+ info: 0
483
+ warn: 1
484
+ error: 2
485
+ fatal: 3
486
+ Exporters:
487
+ otlp:
488
+ endpoint: 127.0.0.1:4317
489
+ tls:
490
+ insecure: true
491
+ sending_queue:
492
+ queue_size: 20000
@@ -0,0 +1,165 @@
1
+
2
+ module ConfigLMM
3
+ module LMM
4
+ class Answer < Framework::Plugin
5
+
6
+ USER = 'answer'
7
+ HOME_DIR = '/var/lib/answer'
8
+ INSTALL_PATH = '/usr/local/bin/'
9
+ GITHUB_REPO_ID = 'apache/answer'
10
+ PORT = 18700
11
+
12
+ persistBuildDir
13
+
14
+ def actionAnswerBuild(id, target, activeState, context, options)
15
+ if !target['Plugins'].to_a.empty?
16
+ Linux.withConnection(local) do |localLinux|
17
+ begin
18
+ localLinux.ensurePackages(['go', 'pnpm'], options) unless localLinux.hasBinaries?(['go', 'pnpm'], options)
19
+ rescue RuntimeError => error
20
+ prompt.say(error, :color => :red)
21
+ end
22
+ outputFolder = File.expand_path(options['output'] + '/' + id)
23
+ if !localLinux.filePresent?(outputFolder + '/answer')
24
+ downloadAnswer(localLinux, context, options)
25
+
26
+ local.mkdir(outputFolder, options[:dry])
27
+ plugins = target['Plugins'].join(',')
28
+
29
+ localLinux.exec("/tmp/answer/answer build --build-dir #{outputFolder}/build --output #{outputFolder}/answer --with #{plugins}", false, options)
30
+ localLinux.exec("rm -rf /tmp/answer /tmp/answer.tar.gz", false, options)
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def downloadAnswer(connection, context, options)
37
+ releases = GitHub::getReleases(GITHUB_REPO_ID, logger, context, options)
38
+ asset = GitHub::getReleaseAsset('apache-answer-*-bin-linux-amd64.tar.gz', releases)
39
+ connection.exec("curl --silent --location --output /tmp/answer.tar.gz #{asset['browser_download_url']}", false, options)
40
+ connection.exec("mkdir -p /tmp/answer", false, options)
41
+ connection.exec("tar --extract --strip-components=1 --directory /tmp/answer --file /tmp/answer.tar.gz", false, options)
42
+ end
43
+
44
+ def actionAnswerDeploy(id, target, activeState, context, options)
45
+ self.withConnection(target['Location'], target) do |connection|
46
+ Linux.withConnection(connection) do |linuxConnection|
47
+
48
+ answerUser = USER
49
+ answerHomeDir = HOME_DIR
50
+ answerPort = PORT
51
+ if target.key?('Instance')
52
+ answerUser += target['Instance'].to_s
53
+ answerHomeDir += target['Instance'].to_s
54
+ answerPort += target['Instance'].to_i
55
+ end
56
+
57
+ prepareSettings(target, answerUser, answerUser)
58
+
59
+ linuxConnection.createServiceUser(answerUser, answerHomeDir, 'Apache Answer', options)
60
+
61
+ if !linuxConnection.filePresent?(INSTALL_PATH + 'answer')
62
+ if target['Plugins'].to_a.empty?
63
+ downloadAnswer(linuxConnection, context, options)
64
+ else
65
+ dir = options['output'] + '/' + id + '/'
66
+ linuxConnection.exec("mkdir -p /tmp/answer", false, options)
67
+ linuxConnection.upload(dir + 'answer', '/tmp/answer/answer', options)
68
+ end
69
+ linuxConnection.exec("mv /tmp/answer/answer #{INSTALL_PATH}", false, options)
70
+ linuxConnection.exec("rm -rf /tmp/answer /tmp/answer.tar.gz", false, options)
71
+ end
72
+
73
+ db = configureDatabase(target, linuxConnection, options)
74
+
75
+ if !linuxConnection.filePresent?(answerHomeDir + '/data/conf/config.yaml')
76
+
77
+ target['Site'] ||= {}
78
+ target['Site']['Language'] = 'en-US' unless target['Site']['Language']
79
+ target['Site']['Name'] = 'Q&A' unless target['Site']['Name']
80
+
81
+ raise Framework::PluginProcessError.new('Domain field must be set!') unless target['Domain']
82
+ raise Framework::PluginProcessError.new('Site.ContactEMail field must be set!') unless target['Site']['ContactEMail']
83
+ raise Framework::PluginProcessError.new('Admin.Username field must be set!') unless target['Admin']['Username']
84
+ raise Framework::PluginProcessError.new('Admin.EMail field must be set!') unless target['Admin']['EMail']
85
+
86
+ linuxConnection.withUserShell(answerUser) do |shell|
87
+
88
+ adminPassword = SecureRandom.urlsafe_base64(20)
89
+
90
+ installEnv = "AUTO_INSTALL=true SITE_ADDR=127.0.0.1:#{answerPort} INSTALL_PORT=#{answerPort+1} "
91
+ installEnv += "DB_TYPE=#{db['Type']} DB_HOST=#{db['HostName']} DB_NAME=#{db['Name']} DB_USERNAME=#{db['User']} DB_PASSWORD=unused "
92
+ installEnv += " LANGUAGE=#{target['Site']['Language']} SITE_NAME='#{target['Site']['Name']}' SITE_URL=https://#{target['Domain']} CONTACT_EMAIL=#{target['Site']['ContactEMail']} "
93
+ installEnv += " ADMIN_NAME=#{target['Admin']['Username'].downcase} ADMIN_EMAIL=#{target['Admin']['EMail']} ADMIN_PASSWORD=#{adminPassword} "
94
+ shell.exec(installEnv + INSTALL_PATH + "answer init --data-path #{answerHomeDir}/data", false, { **options, hide: true })
95
+
96
+ prompt.say("Answer Administrator #{target['Admin']['EMail']} password: #{adminPassword}", :color => :magenta)
97
+ end
98
+
99
+ linuxConnection.fileReplace(answerHomeDir + '/data/conf/config.yaml', 'show: true', 'show: false', options)
100
+ end
101
+
102
+ linuxConnection.upload(__dir__ + '/answer@.service', Systemd::SYSTEMD_CONFIG_PATH, options)
103
+ linuxConnection.reloadServiceManager(options)
104
+ linuxConnection.ensureServiceAutoStart("answer@#{answerUser}.service", options)
105
+ linuxConnection.startService("answer@#{answerUser}.service", options)
106
+ end
107
+ end
108
+ end
109
+
110
+ def prepareSettings(target, userName, dbName)
111
+ target['Database'] ||= {}
112
+ target['Database']['Type'] = 'postgres' unless target['Database']['Type']
113
+ target['Database']['HostName'] = '/run/postgresql' unless target['Database']['HostName']
114
+ target['Database']['Port'] = 5432 unless target['Database']['Port']
115
+ target['Database']['Name'] = userName unless target['Database']['Name']
116
+ target['Database']['User'] = dbName unless target['Database']['User']
117
+
118
+ raise 'Using this DB type is not implemented!' if target['Database']['Type'] != 'postgres'
119
+ end
120
+
121
+ def configureDatabase(target, linuxConnection, options)
122
+ dbSettings = {}
123
+ dbSettings['HostName'] = target['Database']['HostName']
124
+ dbSettings['Port'] = target['Database']['Port']
125
+ PostgreSQL.withConnection(dbSettings, linuxConnection) do |postgresConnection|
126
+ password = SecureRandom.alphanumeric(20)
127
+ postgresConnection.createUserAndDB(target['Database']['Name'], password, options)
128
+ end
129
+ target['Database']
130
+ end
131
+
132
+ def cleanup(configs, state, context, options)
133
+ cleanupType(:Answer, configs, state, context, options) do |item, id, state, context, options, connection|
134
+ Linux.withConnection(connection) do |linuxConnection|
135
+
136
+ answerUser = USER
137
+ answerHomeDir = HOME_DIR
138
+ deleteAnswer = true
139
+ if target.key?('Instance')
140
+ answerUser += target['Instance'].to_s
141
+ answerHomeDir += target['Instance'].to_s
142
+ deleteAnswer = false
143
+ end
144
+
145
+ linuxConnection.stopService("answer@#{answerUser}.service", options)
146
+ linuxConnection.disableService("answer@#{answerUser}.service", options)
147
+
148
+ if deleteAnswer
149
+ linuxConnection.rm(Systemd::SYSTEMD_CONFIG_PATH + 'answer@.service', options[:dry])
150
+ linuxConnection.rm(INSTALL_PATH + 'answer', options[:dry])
151
+ end
152
+
153
+ state.item(id)['Status'] = State::STATUS_DELETED unless options[:dry]
154
+
155
+ if options[:destroy]
156
+ linuxConnection.deleteUserAndGroup(answerUser, options)
157
+ linuxConnection.rm(answerHomeDir, options[:dry])
158
+ state.item(id)['Status'] = State::STATUS_DESTROYED unless options[:dry]
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,40 @@
1
+ [Unit]
2
+ Description=Apache Answer
3
+ After=network.target
4
+
5
+ [Service]
6
+ User=%i
7
+ Group=%i
8
+ ExecStart=/usr/local/bin/answer run --data-path /var/lib/%i/data
9
+ Restart=on-failure
10
+ UMask=0077
11
+ CapabilityBoundingSet=
12
+ LockPersonality=true
13
+ MemoryDenyWriteExecute=true
14
+ NoNewPrivileges=true
15
+ PrivateDevices=true
16
+ PrivateMounts=true
17
+ PrivateTmp=true
18
+ PrivateUsers=true
19
+ ProcSubset=pid
20
+ ProtectClock=true
21
+ ProtectControlGroups=true
22
+ ProtectHome=true
23
+ ProtectHostname=true
24
+ ProtectKernelLogs=true
25
+ ProtectKernelModules=true
26
+ ProtectKernelTunables=true
27
+ ProtectProc=invisible
28
+ ProtectSystem=strict
29
+ ReadWritePaths=/var/lib/%i/data
30
+ RemoveIPC=true
31
+ RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
32
+ RestrictNamespaces=true
33
+ RestrictRealtime=true
34
+ RestrictSUIDSGID=true
35
+ SystemCallArchitectures=native
36
+ SystemCallFilter=@system-service
37
+ SystemCallFilter=~@privileged
38
+
39
+ [Install]
40
+ WantedBy=multi-user.target
@@ -18,9 +18,6 @@ server {
18
18
 
19
19
  root /opt/ArchiSteamFarm-bin/www;
20
20
 
21
- access_log /var/log/nginx/ArchiSteamFarm.access.log;
22
- error_log /var/log/nginx/ArchiSteamFarm.error.log;
23
-
24
21
  include config-lmm/private.conf;
25
22
  include config-lmm/errors.conf;
26
23