ConfigLMM 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }