ConfigLMM 0.1.0 → 0.3.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +63 -1
  3. data/Examples/Implemented.mm.yaml +120 -0
  4. data/Examples/Keys.ini +2 -0
  5. data/Examples/Linux.mm.yaml +14 -3
  6. data/Images/configINconfig.png +0 -0
  7. data/Images/singleConfig.png +0 -0
  8. data/Plugins/Apps/Authentik/Authentik-Server.container +18 -0
  9. data/Plugins/Apps/Authentik/Authentik-Worker.container +17 -0
  10. data/Plugins/Apps/Authentik/Authentik.conf.erb +35 -0
  11. data/Plugins/Apps/Authentik/Authentik.lmm.rb +73 -0
  12. data/Plugins/Apps/Cassandra/Cassandra.lmm.rb +41 -0
  13. data/Plugins/Apps/Dovecot/Dovecot.lmm.rb +165 -0
  14. data/Plugins/Apps/GitLab/GitLab.conf.erb +26 -0
  15. data/Plugins/Apps/GitLab/GitLab.container +17 -0
  16. data/Plugins/Apps/GitLab/GitLab.lmm.rb +75 -0
  17. data/Plugins/Apps/Nextcloud/Nextcloud.conf.erb +48 -10
  18. data/Plugins/Apps/Nextcloud/Nextcloud.lmm.rb +59 -2
  19. data/Plugins/Apps/Nextcloud/config.php +18 -0
  20. data/Plugins/Apps/Nginx/conf.d/configlmm.conf +62 -0
  21. data/Plugins/Apps/Nginx/config-lmm/errors.conf +2 -2
  22. data/Plugins/Apps/Nginx/config-lmm/security.conf +4 -0
  23. data/Plugins/Apps/Nginx/main.conf.erb +31 -0
  24. data/Plugins/Apps/Nginx/nginx.conf +3 -68
  25. data/Plugins/Apps/Nginx/nginx.lmm.rb +71 -14
  26. data/Plugins/Apps/Odoo/Odoo.conf.erb +30 -13
  27. data/Plugins/Apps/Odoo/Odoo.container +17 -0
  28. data/Plugins/Apps/Odoo/Odoo.lmm.rb +62 -2
  29. data/Plugins/Apps/Odoo/odoo.conf +37 -0
  30. data/Plugins/Apps/PHP-FPM/PHP-FPM.lmm.rb +95 -0
  31. data/Plugins/Apps/Peppermint/Peppermint.conf.erb +64 -0
  32. data/Plugins/Apps/Peppermint/Peppermint.container +14 -0
  33. data/Plugins/Apps/Peppermint/Peppermint.lmm.rb +58 -0
  34. data/Plugins/Apps/Postfix/Postfix.lmm.rb +184 -0
  35. data/Plugins/Apps/Postfix/smtpd.conf +3 -0
  36. data/Plugins/Apps/PostgreSQL/PostgreSQL.lmm.rb +225 -0
  37. data/Plugins/Apps/SSH/SSH.lmm.rb +51 -0
  38. data/Plugins/Apps/UVdesk/UVdesk.conf.erb +52 -0
  39. data/Plugins/Apps/UVdesk/UVdesk.lmm.rb +85 -0
  40. data/Plugins/Apps/Valkey/Valkey.lmm.rb +56 -0
  41. data/Plugins/Apps/Vaultwarden/Vaultwarden.conf.erb +35 -18
  42. data/Plugins/Apps/Vaultwarden/Vaultwarden.container +16 -0
  43. data/Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb +42 -3
  44. data/Plugins/Apps/gollum/gollum.conf.erb +45 -18
  45. data/Plugins/Apps/gollum/gollum.container +12 -0
  46. data/Plugins/Apps/gollum/gollum.lmm.rb +39 -10
  47. data/Plugins/OS/Linux/Distributions.yaml +16 -0
  48. data/Plugins/OS/Linux/Linux.lmm.rb +389 -0
  49. data/Plugins/OS/Linux/Packages.yaml +51 -0
  50. data/Plugins/OS/Linux/WireGuard/WireGuard.lmm.rb +108 -0
  51. data/Plugins/OS/Linux/WireGuard/wg0.conf.erb +15 -0
  52. data/Plugins/OS/Linux/openSUSE/autoinst.xml.erb +87 -0
  53. data/Plugins/OS/Linux/systemd/systemd.lmm.rb +28 -0
  54. data/Plugins/OS/Linux/systemd/user-0.slice +9 -0
  55. data/Plugins/OS/Linux/systemd/user@.service.d/delegate.conf +3 -0
  56. data/Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb +6 -1
  57. data/Plugins/Platforms/libvirt/libvirt.lmm.rb +103 -0
  58. data/Plugins/Services/DNS/PowerDNS.lmm.rb +69 -6
  59. data/README.md +10 -0
  60. data/bootstrap.sh +54 -0
  61. data/lib/ConfigLMM/Framework/plugins/dns.rb +1 -2
  62. data/lib/ConfigLMM/Framework/plugins/linuxApp.rb +237 -0
  63. data/lib/ConfigLMM/Framework/plugins/nginxApp.rb +24 -6
  64. data/lib/ConfigLMM/Framework/plugins/plugin.rb +150 -0
  65. data/lib/ConfigLMM/Framework/plugins.rb +1 -0
  66. data/lib/ConfigLMM/commands/configsCommand.rb +3 -0
  67. data/lib/ConfigLMM/version.rb +1 -1
  68. metadata +87 -5
  69. data/Plugins/Apps/Nginx/main.conf +0 -30
  70. data/Plugins/OS/Linux.lmm.rb +0 -64
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e1dcd8d8d61d199700f39e2298c45ffaedfcb12822a833ebd16423120c4526c
4
- data.tar.gz: ea7e2be4c9ea59a2babe325a8d63c1440aae67f147106d4b30e17839c0d6abda
3
+ metadata.gz: '0078988f4f9bf52b61e5de21839b6ab1da6c56e24e4999987b9818cab6b5c7ca'
4
+ data.tar.gz: 429aed3d4f1a83271175022c479408db601b85c0f991163d0f87527a6fe55135
5
5
  SHA512:
6
- metadata.gz: 32fcd1db26c56ce7787a4515ce1d653cf96cf9a812f56ac7bcaa94465bcad4fa0a3082f2420cf6bdea7ae7b8e6229c8d416b3be7e4157eb37d3ea11cd4c7a42c
7
- data.tar.gz: fcd652884fe0f191739e830315da87f066507fd719e38b60bdfeb35030116de97ac9eaabf913b9e75f2e33c95a85dafc77539eba985be6968a80f136d545c186
6
+ metadata.gz: afc93dc18858dd5102963d65c27adf37891a69e3cd80a768d2fc8c08c64ccb8cc50478a594a18c3769de7efc6c921d75fc92357fa948ace10091b010a932e6f6
7
+ data.tar.gz: 615fdfbd8cb389fefa0aacd51e6b2cf3739e7e7305d0ed389dec481d79a12cb1289e12a4b3224faf092c8c858cfd357c95e803d584024feb0225409b0d8cca69
data/CHANGELOG.md CHANGED
@@ -1,5 +1,67 @@
1
- ## [Unreleased]
1
+
2
+ ## [0.3.0] - 2024-08-13
3
+
4
+ Implement:
5
+ - systemd UserCgroups
6
+ - Authentik - https://goauthentik.io/
7
+ - WireGuard - https://www.wireguard.com/
8
+ - Dovecot - https://www.dovecot.org/
9
+ - Nextcloud - https://nextcloud.com/
10
+ - Vaultwarden - https://github.com/dani-garcia/vaultwarden
11
+ - Linux: fstab tmpfs
12
+ - Linux: Network config
13
+ - Linux: deployLocal() and Execute commands
14
+ - SSH settings
15
+ - Odoo - https://www.odoo.com/
16
+ - GitLab - https://about.gitlab.com/
17
+ - Partial UVdesk - https://www.uvdesk.com/en/ticket-management-system/
18
+ - Peppermint - https://peppermint.sh/
19
+ - Cassandra - https://cassandra.apache.org/_/index.html
20
+
21
+ Other improvements:
22
+ - Add bootstrap.sh script
23
+ - PowerDNS
24
+ - GoDaddy
25
+ - Nginx
26
+ - PostgreSQL: Support Logical Replication
27
+ - Postfix
28
+ - gollum
29
+ - Linux: Users SSHKey
30
+ - PostgreSQL
31
+ - Valkey
32
+
33
+ ## [0.2.0] - 2024-07-19
34
+
35
+ - openSUSE - https://www.opensuse.org/
36
+ - libvirt - https://libvirt.org/
37
+ - More Linux configs (including SSH)
38
+ - postfix - https://www.postfix.org/
39
+ - PostgreSQL - https://www.postgresql.org/
2
40
 
3
41
  ## [0.1.0] - 2024-06-06
4
42
 
5
43
  - Initial release
44
+ - PorkbunDNS - https://porkbun.com/
45
+ - TonicDNS - https://www.tonic.to/
46
+ - PowerDNS - https://www.powerdns.com/
47
+ - GoDaddy - https://www.godaddy.com/
48
+ - Linux
49
+ - ArubaInstant - https://www.arubanetworks.com/
50
+ - ArchiSteamFarm - https://github.com/JustArchiNET/ArchiSteamFarm
51
+ - Bitmagnet - https://bitmagnet.io/
52
+ - Gollum - https://github.com/gollum/gollum
53
+ - Grafana - https://grafana.com/
54
+ - IPFS - https://ipfs.tech/
55
+ - InfluxDB - https://www.influxdata.com/
56
+ - Jackett - https://github.com/Jackett/Jackett/
57
+ - Jellyfin - https://jellyfin.org/
58
+ - Mastodon - https://github.com/mastodon/mastodon
59
+ - Matrix - https://matrix.org/
60
+ - Netdata - https://www.netdata.cloud/
61
+ - Nextcloud - https://nextcloud.com/
62
+ - Odoo - https://www.odoo.com/
63
+ - Pterodactyl - https://pterodactyl.io/
64
+ - qBittorrent - https://www.qbittorrent.org/
65
+ - Scrutiny - https://github.com/AnalogJ/scrutiny
66
+ - Sunshine - https://app.lizardbyte.dev/Sunshine/
67
+ - Vaultwarden - https://github.com/dani-garcia/vaultwarden
@@ -43,9 +43,53 @@ GoDaddy:
43
43
 
44
44
  Linux:
45
45
  Type: Linux
46
+ Location: qemu:///session
47
+ AlternativeLocation: ssh://example.org/
48
+ Distro: openSUSE Leap
49
+ CPU: 2
50
+ RAM: 4 GiB
51
+ Storage: 30 GiB
52
+ Tmpfs: 1G
53
+ Domain: example.org
46
54
  Hosts:
47
55
  127.0.0.1:
48
56
  - example.org
57
+ Apps:
58
+ - sshd
59
+ - fish
60
+ - vim
61
+ Users:
62
+ root:
63
+ Shell: fish
64
+ SSHKey: yes
65
+ AuthorizedKeys:
66
+ - ~/.ssh/id_ed25519.pub
67
+ SSH:
68
+ Config:
69
+ Example:
70
+ User: root
71
+ HostName: example.org
72
+ Sysctl:
73
+ vm.overcommit_memory: 1 # Need for ValKey
74
+ net.ipv4.ip_forward: 1 # Need for Wanguard
75
+ Network:
76
+ IP: 192.168.1.2/24
77
+ Gateway: 192.168.1.1
78
+ DNS: 192.168.1.1
79
+ Execute:
80
+ sh: echo Hello World from ConfigLMM > /tmp/hello
81
+
82
+ SSH:
83
+ Type: SSH
84
+ Location: ssh://example.org/
85
+ Port: 1234
86
+ Settings:
87
+ PasswordAuthentication: no
88
+
89
+ Systemd:
90
+ Type: systemd
91
+ Location: ssh://example.org/
92
+ UserCgroups: yes # Need for Podman
49
93
 
50
94
  # https://www.arubanetworks.com/
51
95
  ArubaInstant:
@@ -58,11 +102,39 @@ ArchiSteamFarm:
58
102
  Type: ArchiSteamFarm
59
103
  Domain: ASF.example.org
60
104
 
105
+ # https://goauthentik.io/
106
+ Authentik:
107
+ Type: Authentik
108
+ Location: ssh://example.org/
109
+ Domain: auth.example.org
110
+
61
111
  # https://bitmagnet.io/
62
112
  Bitmagnet:
63
113
  Type: Bitmagnet
64
114
  Domain: bitmagnet.example.org
65
115
 
116
+ # https://cassandra.apache.org/_/index.html
117
+ Cassandra:
118
+ Type: Cassandra
119
+ Location: ssh://example.org/
120
+ ClusterName: Cluster
121
+
122
+ # https://www.dovecot.org/
123
+ Dovecot:
124
+ Type: Dovecot
125
+ Location: ssh://example.org/
126
+
127
+ # https://about.gitlab.com/
128
+ GitLab:
129
+ Type: GitLab
130
+ Location: ssh://example.org/
131
+ Domain: git.example.org
132
+ SMTP:
133
+ HostName: email.example.org
134
+ Port: 465
135
+ User: git@example.org
136
+ TLS: yes
137
+
66
138
  # https://github.com/gollum/gollum
67
139
  Gollum:
68
140
  Type: Gollum
@@ -114,11 +186,45 @@ Netdata:
114
186
  Nextcloud:
115
187
  Type: Nextcloud
116
188
  Domain: nextcloud.example.org
189
+ Database:
190
+ Type: pgsql
191
+ HostName: localhost
117
192
 
118
193
  # https://www.odoo.com/
119
194
  Odoo:
120
195
  Type: Odoo
121
196
  Domain: odoo.example.org
197
+ Database:
198
+ HostName: db.example.org
199
+
200
+ # https://peppermint.sh/
201
+ Peppermint:
202
+ Type: Peppermint
203
+ Location: ssh://example.org/
204
+ Domain: Peppermint.example.org
205
+
206
+ # https://www.postfix.org/
207
+ Postfix:
208
+ Type: Postfix
209
+ Location: ssh://example.org/
210
+ AlternativePort: 2525
211
+ SMTP: unix
212
+ ForwardAll: example.com
213
+ ForwardDovecot: yes
214
+ Settings:
215
+ inet_interfaces: $myhostname, localhost
216
+
217
+ PostgreSQL:
218
+ Type: PostgreSQL
219
+ Location: ssh://example.org/
220
+ ListenAll: yes
221
+ Users:
222
+ replication:
223
+ Replication: yes
224
+ Password: ${ENV:POSTGRES_REPLICATION_PASSWORD}
225
+ Subscriptions:
226
+ db:
227
+ Connection: user=replication dbname=db password=${ENV:POSTGRES_REPLICATION_PASSWORD}
122
228
 
123
229
  # https://pterodactyl.io/
124
230
  Pterodactyl:
@@ -149,7 +255,21 @@ Sunshine:
149
255
  Type: Sunshine
150
256
  Domain: sunshine.example.org
151
257
 
258
+ # https://valkey.io/ (Redis fork)
259
+ Valkey:
260
+ Type: Valkey
261
+ Location: ssh://example.org/
262
+
152
263
  # https://github.com/dani-garcia/vaultwarden
153
264
  Vaultwarden:
154
265
  Type: Vaultwarden
155
266
  Domain: vaultwarden.example.org
267
+
268
+ # https://www.wireguard.com/
269
+ WireGuard:
270
+ Type: WireGuard
271
+ Location: ssh://example.org/
272
+ Address: 172.20.0.1/20
273
+ Peers:
274
+ example:
275
+ Endpoint: example.example.org
data/Examples/Keys.ini CHANGED
@@ -1,6 +1,8 @@
1
1
  ARUBA_INSTANT_PASSWORD=
2
2
  GITHUB_TOKEN=
3
3
  GODADDY_SECRET=
4
+ LINUX_ROOT_PASSWORD=
5
+ LINUX_ROOT_PASSWORD_HASH=
4
6
  PORKBUN_API_KEY=
5
7
  PORKBUN_SECRET_API_KEY=
6
8
  POWERDNS_API_KEY=
@@ -1,16 +1,27 @@
1
1
  Linux:
2
- Type: ArchLinux
2
+ Type: Linux
3
+ Distro: ArchLinux
3
4
  Apps:
4
5
  - fish
5
6
  - vim
6
7
  Users:
7
- - user1:
8
+ user1:
8
9
  Admin: Yes
9
10
  Shell: fish
10
- - user2:
11
+ AuthorizedKeys:
12
+ - ~/.ssh/id_ed25519.pub
13
+ user2:
11
14
  Admin: Yes
12
15
  Shell: fish
13
16
  Comment: Other user
17
+ Domain: example.org
14
18
  Hosts:
15
19
  127.0.0.1:
16
20
  - example.org
21
+ SSH:
22
+ Config:
23
+ Example:
24
+ User: root
25
+ HostName: example.org
26
+ Sysctl:
27
+ vm.overcommit_memory: 1
Binary file
Binary file
@@ -0,0 +1,18 @@
1
+
2
+ [Unit]
3
+ Description=Authentik Server container
4
+ After=local-fs.target
5
+
6
+ [Container]
7
+ Image=ghcr.io/goauthentik/server:latest
8
+ Exec=server
9
+ EnvironmentFile=/var/lib/authentik/.config/containers/systemd/Authentik.env
10
+ Network=slirp4netns:allow_host_loopback=true
11
+ PublishPort=127.0.0.1:19000:9000
12
+ PublishPort=127.0.0.1:19300:9300
13
+ UserNS=keep-id:uid=1000,gid=1000
14
+ Volume=/var/lib/authentik/media:/media
15
+ Volume=/var/lib/authentik/templates:/templates
16
+
17
+ [Install]
18
+ WantedBy=multi-user.target default.target
@@ -0,0 +1,17 @@
1
+
2
+ [Unit]
3
+ Description=Authentik Worker container
4
+ After=local-fs.target
5
+
6
+ [Container]
7
+ Image=ghcr.io/goauthentik/server:latest
8
+ Exec=worker
9
+ EnvironmentFile=/var/lib/authentik/.config/containers/systemd/Authentik.env
10
+ Network=slirp4netns:allow_host_loopback=true
11
+ UserNS=keep-id:uid=1000,gid=1000
12
+ Volume=/var/lib/authentik/media:/media
13
+ Volume=/var/lib/authentik/templates:/templates
14
+ Volume=/var/lib/authentik/certs:/certs
15
+
16
+ [Install]
17
+ WantedBy=multi-user.target default.target
@@ -0,0 +1,35 @@
1
+
2
+ # Upstream where your authentik server is hosted.
3
+ upstream authentik {
4
+ server localhost:19000;
5
+
6
+ # Improve performance by keeping some connections alive.
7
+ keepalive 10;
8
+ }
9
+
10
+ server {
11
+ <% if config['NginxVersion'] >= 1.25 %>
12
+ listen 443 ssl;
13
+ listen [::]:443 ssl;
14
+ http2 on;
15
+ http3 on;
16
+ quic_retry on;
17
+ add_header Alt-Svc 'h3=":443"; ma=86400';
18
+ <% else %>
19
+ listen 443 ssl http2;
20
+ listen [::]:443 ssl http2;
21
+ <% end %>
22
+
23
+ include config-lmm/ssl.conf;
24
+
25
+ server_name <%= config['Domain'] %>;
26
+
27
+ access_log /var/log/nginx/authentik.access.log;
28
+ error_log /var/log/nginx/authentik.error.log;
29
+
30
+ # Proxy site
31
+ location / {
32
+ proxy_pass http://authentik;
33
+ include config-lmm/proxy.conf;
34
+ }
35
+ }
@@ -0,0 +1,73 @@
1
+
2
+ module ConfigLMM
3
+ module LMM
4
+ class Authentik < Framework::NginxApp
5
+
6
+ USER = 'authentik'
7
+ HOME_DIR = '/var/lib/authentik'
8
+ HOST_IP = '10.0.2.2'
9
+
10
+ def actionAuthentikBuild(id, target, state, context, options)
11
+ self.writeNginxConfig(__dir__, 'Authentik', id, target, state, context, options)
12
+ end
13
+
14
+ def actionAuthentikDeploy(id, target, activeState, context, options)
15
+ if target['Location'] && target['Location'] != '@me'
16
+ uri = Addressable::URI.parse(target['Location'])
17
+ case uri.scheme
18
+ when 'ssh'
19
+ self.class.sshStart(uri) do |ssh|
20
+ self.prepareConfig(target, ssh)
21
+
22
+ dbPassword = self.configurePostgreSQL(target['Database'], ssh)
23
+ distroInfo = Framework::LinuxApp.currentDistroInfo(ssh)
24
+ Framework::LinuxApp.configurePodmanServiceOverSSH(USER, HOME_DIR, 'Authentik IdP and SSO', distroInfo, ssh)
25
+ self.class.sshExec!(ssh, "su --login #{USER} --shell /bin/sh --command 'mkdir -p ~/media'")
26
+ self.class.sshExec!(ssh, "su --login #{USER} --shell /bin/sh --command 'mkdir -p ~/templates'")
27
+ self.class.sshExec!(ssh, "su --login #{USER} --shell /bin/sh --command 'mkdir -p ~/certs'")
28
+
29
+ path = Framework::LinuxApp::SYSTEMD_CONTAINERS_PATH.gsub('~', HOME_DIR)
30
+ self.class.sshExec!(ssh, " echo 'AUTHENTIK_SECRET_KEY=#{SecureRandom.urlsafe_base64(60)}' > #{path}/Authentik.env")
31
+ self.class.sshExec!(ssh, " echo 'AUTHENTIK_REDIS__HOST=#{HOST_IP}' >> #{path}/Authentik.env")
32
+ self.class.sshExec!(ssh, " echo 'AUTHENTIK_POSTGRESQL__HOST=#{HOST_IP}' >> #{path}/Authentik.env")
33
+ self.class.sshExec!(ssh, " echo 'AUTHENTIK_POSTGRESQL__PASSWORD=#{dbPassword}' >> #{path}/Authentik.env")
34
+ self.class.sshExec!(ssh, "chown #{USER}:#{USER} #{path}/Authentik.env")
35
+ self.class.sshExec!(ssh, "chmod 600 #{path}/Authentik.env")
36
+
37
+ ssh.scp.upload!(__dir__ + '/Authentik-Server.container', path)
38
+ ssh.scp.upload!(__dir__ + '/Authentik-Worker.container', path)
39
+ self.class.sshExec!(ssh, "systemctl --user --machine=#{USER}@ daemon-reload")
40
+ self.class.sshExec!(ssh, "systemctl --user --machine=#{USER}@ start Authentik-Server")
41
+ self.class.sshExec!(ssh, "systemctl --user --machine=#{USER}@ start Authentik-Worker")
42
+
43
+ Framework::LinuxApp.ensureServiceAutoStartOverSSH(NGINX_PACKAGE, ssh)
44
+ self.writeNginxConfig(__dir__, 'Authentik', id, target, state, context, options)
45
+ self.deployNginxConfig(id, target, activeState, context, options)
46
+ Framework::LinuxApp.startServiceOverSSH(NGINX_PACKAGE, ssh)
47
+ end
48
+ else
49
+ raise Framework::PluginProcessError.new("#{id}: Unknown protocol: #{uri.scheme}!")
50
+ end
51
+ else
52
+ # TODO
53
+ end
54
+ end
55
+
56
+ def prepareConfig(target, ssh)
57
+ target['Database'] ||= {}
58
+
59
+ raise Framework::PluginProcessError.new('Domain field must be set!') unless target['Domain']
60
+
61
+ Framework::LinuxApp.ensurePackages([NGINX_PACKAGE], ssh)
62
+ self.class.prepareNginxConfig(target, ssh)
63
+ end
64
+
65
+ def configurePostgreSQL(settings, ssh)
66
+ password = SecureRandom.alphanumeric(20)
67
+ PostgreSQL.createRemoteUserAndDBOverSSH(settings, USER, password, ssh)
68
+ password
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,41 @@
1
+
2
+ module ConfigLMM
3
+ module LMM
4
+ class Cassandra < Framework::Plugin
5
+ PACKAGE_NAME = 'Cassandra'
6
+ SERVICE_NAME = 'cassandra'
7
+
8
+ def actionCassandraDeploy(id, target, activeState, context, options)
9
+ plugins[:Linux].ensurePackage(PACKAGE_NAME, target['Location'])
10
+ plugins[:Linux].ensureServiceAutoStart(SERVICE_NAME, target['Location'])
11
+
12
+ if target['Location'] && target['Location'] != '@me'
13
+ uri = Addressable::URI.parse(target['Location'])
14
+ raise Framework::PluginProcessError.new("#{id}: Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
15
+
16
+ self.class.sshStart(uri) do |ssh|
17
+ distroInfo = Framework::LinuxApp.currentDistroInfo(ssh)
18
+ configFile = '/etc/cassandra/cassandra.yaml'
19
+ if distroInfo['Name'] == 'openSUSE Leap'
20
+ configFile = '/etc/cassandra/conf/cassandra.yaml'
21
+ end
22
+
23
+ cmd = "sed -i 's|^uuid_sstable_identifiers_enabled:.*|uuid_sstable_identifiers_enabled: true|' #{configFile}"
24
+ self.class.sshExec!(ssh, cmd)
25
+ if target['ClusterName']
26
+ cmd = "sed -i 's|^cluster_name:.*|cluster_name: #{target['ClusterName']}|' #{configFile}"
27
+ self.class.sshExec!(ssh, cmd)
28
+ end
29
+ end
30
+ else
31
+ # TODO
32
+ end
33
+
34
+ plugins[:Linux].startService(SERVICE_NAME, target['Location'])
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
41
+
@@ -0,0 +1,165 @@
1
+
2
+ module ConfigLMM
3
+ module LMM
4
+ class Dovecot < Framework::Plugin
5
+ PACKAGE_NAME = 'Dovecot'
6
+ SERVICE_NAME = 'dovecot'
7
+ DOVECOT_DIR = '/etc/dovecot/'
8
+ EMAIL_HOME = '/var/lib/email'
9
+ EMAIL_USER = 'email'
10
+
11
+ def actionDovecotDeploy(id, target, activeState, context, options)
12
+ plugins[:Linux].ensurePackage(PACKAGE_NAME, target['Location'])
13
+ plugins[:Linux].ensureServiceAutoStart(SERVICE_NAME, target['Location'])
14
+
15
+ if target['Location'] && target['Location'] != '@me'
16
+ uri = Addressable::URI.parse(target['Location'])
17
+ raise Framework::PluginProcessError.new("#{id}: Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
18
+
19
+ self.class.sshStart(uri) do |ssh|
20
+ distroInfo = Framework::LinuxApp.currentDistroInfo(ssh)
21
+ addUserCmd = "#{distroInfo['CreateServiceUser']} --home-dir '#{EMAIL_HOME}' --create-home --comment 'Dovecot EMail' #{EMAIL_USER}"
22
+ self.class.sshExec!(ssh, addUserCmd, true)
23
+ uid = self.class.sshExec!(ssh, "id -u #{EMAIL_USER}").strip
24
+
25
+ cmd = "sed -i 's|^#mail_uid =.*|mail_uid = #{uid}|' #{DOVECOT_DIR}conf.d/10-mail.conf"
26
+ self.class.sshExec!(ssh, cmd)
27
+ cmd = "sed -i 's|^#mail_gid =.*|mail_gid = #{uid}|' #{DOVECOT_DIR}conf.d/10-mail.conf"
28
+ self.class.sshExec!(ssh, cmd)
29
+ cmd = "sed -i 's|^#mail_location =.*|mail_location = maildir:~/Mail|' #{DOVECOT_DIR}conf.d/10-mail.conf"
30
+ self.class.sshExec!(ssh, cmd)
31
+
32
+ updateRemoteFile(ssh, DOVECOT_DIR + 'conf.d/10-mail.conf', options) do |configLines|
33
+ configLines << "mail_home = #{EMAIL_HOME}/emails/%u\n"
34
+ configLines << "first_valid_uid = #{uid}\n"
35
+ configLines << "last_valid_uid = #{uid}\n"
36
+ end
37
+
38
+ self.class.cutConfigSection(DOVECOT_DIR + 'conf.d/10-master.conf', 'service lmtp', options, ssh)
39
+ updateRemoteFile(ssh, DOVECOT_DIR + 'conf.d/10-master.conf', options) do |configLines|
40
+ configLines << "service lmtp {\n"
41
+ configLines << " unix_listener lmtp {\n"
42
+ configLines << " user = postfix\n"
43
+ configLines << " group = postfix\n"
44
+ configLines << " mode = 0600\n"
45
+ configLines << " }\n"
46
+ configLines << "}\n"
47
+ end
48
+
49
+ self.class.cutConfigSection(DOVECOT_DIR + 'conf.d/15-mailboxes.conf', 'namespace inbox', options, ssh)
50
+ updateRemoteFile(ssh, DOVECOT_DIR + 'conf.d/15-mailboxes.conf', options) do |configLines|
51
+ configLines << "namespace inbox {\n"
52
+ configLines << " mailbox Drafts {\n"
53
+ configLines << " special_use = \\Drafts\n"
54
+ configLines << " auto = subscribe\n"
55
+ configLines << " }\n"
56
+ #configLines << " mailbox Junk {\n"
57
+ #configLines << " special_use = \\Junk\n"
58
+ #configLines << " auto = subscribe\n"
59
+ #configLines << " }\n"
60
+ configLines << " mailbox Trash {\n"
61
+ configLines << " special_use = \\Trash\n"
62
+ configLines << " auto = subscribe\n"
63
+ configLines << " }\n"
64
+ configLines << " mailbox Sent {\n"
65
+ configLines << " special_use = \\Sent\n"
66
+ configLines << " auto = subscribe\n"
67
+ configLines << " }\n"
68
+ configLines << "}\n"
69
+ end
70
+
71
+ self.class.sshExec!(ssh, "firewall-cmd -q --add-service='imaps'")
72
+ self.class.sshExec!(ssh, "firewall-cmd -q --permanent --add-service='imaps'")
73
+
74
+ cmd = "sed -i 's|^!include auth-system.conf.ext|#!include auth-system.conf.ext|' #{DOVECOT_DIR}conf.d/10-auth.conf"
75
+ self.class.sshExec!(ssh, cmd)
76
+
77
+ if target['OAuth2']
78
+ cmd = "sed -i 's|auth_mechanisms =.*|auth_mechanisms = xoauth2 oauthbearer|' #{DOVECOT_DIR}conf.d/10-auth.conf"
79
+ self.class.sshExec!(ssh, cmd)
80
+
81
+ updateRemoteFile(ssh, DOVECOT_DIR + 'conf.d/10-auth.conf', options) do |configLines|
82
+ configLines << "userdb {\n"
83
+ configLines << " driver = static\n"
84
+ configLines << " args = allow_all_users=yes\n"
85
+ configLines << "}\n"
86
+ configLines << "passdb {\n"
87
+ configLines << " driver = oauth2\n"
88
+ configLines << " mechanisms = xoauth2 oauthbearer\n"
89
+ configLines << " args = #{DOVECOT_DIR}dovecot-oauth2.conf.ext\n"
90
+ configLines << "}\n"
91
+ end
92
+
93
+ updateRemoteFile(ssh, DOVECOT_DIR + 'dovecot-oauth2.conf.ext', options) do |configLines|
94
+ # Need v2.3.16+
95
+ #configLines << "openid_configuration_url = #{target['OAuth2']['OIDC']}\n"
96
+ if target['OAuth2']['TokenInfo']
97
+ configLines << "tokeninfo_url = #{target['OAuth2']['TokenInfo']}\n"
98
+ end
99
+ if target['OAuth2']['Introspection']
100
+ configLines << "introspection_url = #{target['OAuth2']['Introspection']}\n"
101
+ end
102
+ if target['OAuth2']['ClientID']
103
+ configLines << "client_id = #{target['OAuth2']['ClientID']}\n"
104
+ end
105
+ if ENV['DOVECOT_OAUTH2_SECRET']
106
+ configLines << "client_secret = #{ENV['DOVECOT_OAUTH2_SECRET']}\n"
107
+ end
108
+ end
109
+ else
110
+ cmd = "sed -i 's|auth_mechanisms =.*|auth_mechanisms = plain|' #{DOVECOT_DIR}conf.d/10-auth.conf"
111
+ self.class.sshExec!(ssh, cmd)
112
+
113
+ updateRemoteFile(ssh, DOVECOT_DIR + 'conf.d/10-auth.conf', options) do |configLines|
114
+ configLines << "auth_username_format = %u\n"
115
+ configLines << "userdb {\n"
116
+ configLines << " driver = static\n"
117
+ configLines << " args = allow_all_users=yes\n"
118
+ configLines << "}\n"
119
+ configLines << "passdb {\n"
120
+ configLines << " driver = passwd-file\n"
121
+ configLines << " args = #{DOVECOT_DIR}passwords\n"
122
+ configLines << "}\n"
123
+ end
124
+ self.class.sshExec!(ssh, "touch #{DOVECOT_DIR}passwords")
125
+ self.class.sshExec!(ssh, "chown dovecot:dovecot #{DOVECOT_DIR}passwords")
126
+ self.class.sshExec!(ssh, "chmod 600 #{DOVECOT_DIR}passwords")
127
+ end
128
+
129
+ certDir = Framework::LinuxApp.createCertificateOverSSH(ssh)
130
+ updateRemoteFile(ssh, DOVECOT_DIR + 'conf.d/10-ssl.conf', options) do |configLines|
131
+ configLines << "ssl_cert = <#{certDir}fullchain.pem\n"
132
+ configLines << "ssl_key = <#{certDir}privkey.pem\n"
133
+ end
134
+ end
135
+ else
136
+ # TODO
137
+ end
138
+
139
+ plugins[:Linux].startService(SERVICE_NAME, target['Location'])
140
+ end
141
+
142
+ def self.cutConfigSection(file, sectionStart, options, ssh)
143
+ localFile = options['output'] + '/' + SecureRandom.alphanumeric(10)
144
+ File.write(localFile, '')
145
+ self.sshExec!(ssh, "touch #{file}")
146
+ ssh.scp.download!(file, localFile)
147
+ fileData = File.read(localFile)
148
+ position = fileData.index(sectionStart)
149
+ if position
150
+ # Find the index of the closing brace of the section
151
+ # We use a regular expression to find the next non-nested closing brace
152
+ match = fileData[position..-1].match(/(?<=\{)(.*?)(^\})/m)
153
+ if match
154
+ fileData = fileData[0...position] + fileData[(position + match.end(0))..-1]
155
+ else
156
+ fileData = fileData[0...position]
157
+ end
158
+ File.write(localFile, fileData)
159
+ ssh.scp.upload!(localFile, file)
160
+ end
161
+ end
162
+ end
163
+
164
+ end
165
+ end
@@ -0,0 +1,26 @@
1
+
2
+ server {
3
+ <% if config['NginxVersion'] >= 1.25 %>
4
+ listen 443 ssl;
5
+ listen [::]:443 ssl;
6
+ http2 on;
7
+ http3 on;
8
+ quic_retry on;
9
+ add_header Alt-Svc 'h3=":443"; ma=86400';
10
+ <% else %>
11
+ listen 443 ssl http2;
12
+ listen [::]:443 ssl http2;
13
+ <% end %>
14
+
15
+ include config-lmm/ssl.conf;
16
+
17
+ server_name <%= config['Domain'] %>;
18
+
19
+ access_log /var/log/nginx/gitlab.access.log;
20
+ error_log /var/log/nginx/gitlab.error.log;
21
+
22
+ location / {
23
+ proxy_pass http://127.0.0.1:18100;
24
+ include config-lmm/proxy.conf;
25
+ }
26
+ }