ConfigLMM 0.1.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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.yardopts +4 -0
- data/CHANGELOG.md +5 -0
- data/Examples/Android.mm.yaml +8 -0
- data/Examples/Apps/Blog.mm.yaml +7 -0
- data/Examples/Apps/Jellyfin.mm.yaml +3 -0
- data/Examples/Implemented.mm.yaml +155 -0
- data/Examples/Keys.ini +7 -0
- data/Examples/Linux.mm.yaml +16 -0
- data/Examples/Windows.mm.yaml +11 -0
- data/Examples/configlmmAuth.sh +26 -0
- data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.conf.erb +38 -0
- data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.lmm.rb +19 -0
- data/Plugins/Apps/IPFS/IPFS.conf.erb +44 -0
- data/Plugins/Apps/IPFS/IPFS.lmm.rb +23 -0
- data/Plugins/Apps/InfluxDB/InfluxDB.conf.erb +34 -0
- data/Plugins/Apps/InfluxDB/InfluxDB.lmm.rb +19 -0
- data/Plugins/Apps/Jackett/Jackett.conf.erb +38 -0
- data/Plugins/Apps/Jackett/Jackett.lmm.rb +19 -0
- data/Plugins/Apps/Jellyfin/Jellyfin.conf.erb +59 -0
- data/Plugins/Apps/Jellyfin/Jellyfin.lmm.rb +23 -0
- data/Plugins/Apps/Mastodon/Mastodon.conf.erb +81 -0
- data/Plugins/Apps/Mastodon/Mastodon.lmm.rb +23 -0
- data/Plugins/Apps/Matrix/Matrix.conf.erb +36 -0
- data/Plugins/Apps/Matrix/Matrix.lmm.rb +23 -0
- data/Plugins/Apps/Netdata/Netdata.conf.erb +37 -0
- data/Plugins/Apps/Netdata/Netdata.lmm.rb +23 -0
- data/Plugins/Apps/Nextcloud/Nextcloud.conf.erb +165 -0
- data/Plugins/Apps/Nextcloud/Nextcloud.lmm.rb +23 -0
- data/Plugins/Apps/Nginx/config-lmm/errors.conf +31 -0
- data/Plugins/Apps/Nginx/config-lmm/private.conf +6 -0
- data/Plugins/Apps/Nginx/config-lmm/proxy.conf +15 -0
- data/Plugins/Apps/Nginx/config-lmm/public.conf +3 -0
- data/Plugins/Apps/Nginx/config-lmm/ssl.conf +18 -0
- data/Plugins/Apps/Nginx/main.conf +30 -0
- data/Plugins/Apps/Nginx/nginx.conf +90 -0
- data/Plugins/Apps/Nginx/nginx.lmm.rb +62 -0
- data/Plugins/Apps/Nginx/proxy.conf.erb +31 -0
- data/Plugins/Apps/Odoo/Odoo.conf.erb +44 -0
- data/Plugins/Apps/Odoo/Odoo.lmm.rb +23 -0
- data/Plugins/Apps/Pterodactyl/Pterodactyl.conf.erb +50 -0
- data/Plugins/Apps/Pterodactyl/Pterodactyl.lmm.rb +30 -0
- data/Plugins/Apps/Pterodactyl/Wings.conf.erb +38 -0
- data/Plugins/Apps/Sunshine/Sunshine.conf.erb +31 -0
- data/Plugins/Apps/Sunshine/Sunshine.lmm.rb +21 -0
- data/Plugins/Apps/Vaultwarden/Vaultwarden.conf.erb +48 -0
- data/Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb +25 -0
- data/Plugins/Apps/bitmagnet/bitmagnet.conf.erb +35 -0
- data/Plugins/Apps/bitmagnet/bitmagnet.lmm.rb +19 -0
- data/Plugins/Apps/gollum/config.ru +11 -0
- data/Plugins/Apps/gollum/gollum.conf.erb +41 -0
- data/Plugins/Apps/gollum/gollum.lmm.rb +52 -0
- data/Plugins/OS/Linux.lmm.rb +64 -0
- data/Plugins/OS/Routers/Aruba/ArubaInstant.lmm.rb +144 -0
- data/Plugins/Platforms/GitHub.lmm.rb +57 -0
- data/Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb +83 -0
- data/Plugins/Platforms/GoDaddy/zone.txt.erb +13 -0
- data/Plugins/Platforms/porkbun.lmm.rb +129 -0
- data/Plugins/Platforms/porkbun_spec.rb +110 -0
- data/Plugins/Services/DNS/AmberBit.lmm.rb +14 -0
- data/Plugins/Services/DNS/ArubaItDNS.lmm.rb +14 -0
- data/Plugins/Services/DNS/NICLV.lmm.rb +18 -0
- data/Plugins/Services/DNS/PowerDNS.lmm.rb +261 -0
- data/Plugins/Services/DNS/tonic.lmm.rb +126 -0
- data/README.md +337 -0
- data/Rakefile +15 -0
- data/UNLICENSE +24 -0
- data/bin/configlmm +7 -0
- data/bin/console +11 -0
- data/bin/setup +8 -0
- data/lib/ConfigLMM/Framework/plugins/dns.rb +63 -0
- data/lib/ConfigLMM/Framework/plugins/errors.rb +23 -0
- data/lib/ConfigLMM/Framework/plugins/nginxApp.rb +55 -0
- data/lib/ConfigLMM/Framework/plugins/plugin.rb +167 -0
- data/lib/ConfigLMM/Framework/plugins/ssh.rb +37 -0
- data/lib/ConfigLMM/Framework/plugins/store.rb +57 -0
- data/lib/ConfigLMM/Framework/plugins.rb +5 -0
- data/lib/ConfigLMM/Framework/registrator.rb +32 -0
- data/lib/ConfigLMM/Framework.rb +9 -0
- data/lib/ConfigLMM/LMM/plugins.rb +5 -0
- data/lib/ConfigLMM/LMM.rb +8 -0
- data/lib/ConfigLMM/cli.rb +161 -0
- data/lib/ConfigLMM/command.rb +53 -0
- data/lib/ConfigLMM/commands/build.rb +41 -0
- data/lib/ConfigLMM/commands/cleanup.rb +30 -0
- data/lib/ConfigLMM/commands/configsCommand.rb +167 -0
- data/lib/ConfigLMM/commands/deploy.rb +39 -0
- data/lib/ConfigLMM/commands/diff.rb +45 -0
- data/lib/ConfigLMM/commands/list.rb +15 -0
- data/lib/ConfigLMM/commands/refresh.rb +46 -0
- data/lib/ConfigLMM/commands/types.rb +35 -0
- data/lib/ConfigLMM/commands/validate.rb +49 -0
- data/lib/ConfigLMM/context.rb +52 -0
- data/lib/ConfigLMM/io/configList.rb +98 -0
- data/lib/ConfigLMM/io/path.rb +48 -0
- data/lib/ConfigLMM/io/source.rb +47 -0
- data/lib/ConfigLMM/io.rb +2 -0
- data/lib/ConfigLMM/state.rb +78 -0
- data/lib/ConfigLMM/utils/filters.rb +126 -0
- data/lib/ConfigLMM/version.rb +5 -0
- data/lib/ConfigLMM.rb +6 -0
- data/sig/ConfigLMM.rbs +4 -0
- metadata +485 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
module ConfigLMM
|
|
3
|
+
module LMM
|
|
4
|
+
class Odoo < Framework::NginxApp
|
|
5
|
+
|
|
6
|
+
def actionOdooBuild(id, target, state, context, options)
|
|
7
|
+
writeNginxConfig(__dir__, 'Odoo', id, target, state, context, options)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def actionOdooDiff(id, target, activeState, context, options)
|
|
11
|
+
# TODO
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def actionOdooDeploy(id, target, activeState, context, options)
|
|
15
|
+
if !target['Location'] || target['Location'] == '@me'
|
|
16
|
+
deployNginxConfig(id, target, activeState, context, options)
|
|
17
|
+
activeState['Location'] = '@me'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
server {
|
|
4
|
+
|
|
5
|
+
<% if !config['TLS'] %>
|
|
6
|
+
listen <%= config['Port'] %>;
|
|
7
|
+
listen [::]:<%= config['Port'] %>;
|
|
8
|
+
<% else %>
|
|
9
|
+
listen <%= config['Port'] %> ssl;
|
|
10
|
+
listen [::]:<%= config['Port'] %> ssl;
|
|
11
|
+
http2 on;
|
|
12
|
+
include config-lmm/ssl.conf;
|
|
13
|
+
<% end %>
|
|
14
|
+
|
|
15
|
+
server_name <%= config['Domain'] %>;
|
|
16
|
+
|
|
17
|
+
access_log /var/log/nginx/pterodactyl.access.log;
|
|
18
|
+
error_log /var/log/nginx/pterodactyl.error.log;
|
|
19
|
+
|
|
20
|
+
include config-lmm/private.conf;
|
|
21
|
+
include config-lmm/errors.conf;
|
|
22
|
+
|
|
23
|
+
root /usr/share/webapps/pterodactyl/public/;
|
|
24
|
+
index index.php;
|
|
25
|
+
|
|
26
|
+
# allow larger file uploads and longer script runtimes
|
|
27
|
+
client_max_body_size 100m;
|
|
28
|
+
client_body_timeout 120s;
|
|
29
|
+
|
|
30
|
+
sendfile off;
|
|
31
|
+
|
|
32
|
+
location / {
|
|
33
|
+
try_files $uri $uri/ /index.php?$query_string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
location ~ \.php$ {
|
|
37
|
+
fastcgi_pass unix:/run/php-fpm/php-fpm-pterodactyl.sock;
|
|
38
|
+
include fastcgi.conf;
|
|
39
|
+
fastcgi_param HTTP_PROXY "";
|
|
40
|
+
fastcgi_buffer_size 16k;
|
|
41
|
+
fastcgi_buffers 4 16k;
|
|
42
|
+
|
|
43
|
+
fastcgi_send_timeout 300;
|
|
44
|
+
fastcgi_read_timeout 300;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
location ~ /\.ht {
|
|
48
|
+
include config-lmm/private.conf;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
module ConfigLMM
|
|
3
|
+
module LMM
|
|
4
|
+
class Pterodactyl < Framework::NginxApp
|
|
5
|
+
|
|
6
|
+
def actionPterodactylBuild(id, target, state, context, options)
|
|
7
|
+
writeNginxConfig(__dir__, 'Pterodactyl', id, target, state, context, options)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def actionPterodactylDeploy(id, target, activeState, context, options)
|
|
11
|
+
if !target['Location'] || target['Location'] == '@me'
|
|
12
|
+
deployNginxConfig(id, target, activeState, context, options)
|
|
13
|
+
activeState['Location'] = '@me'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def actionWingsBuild(id, target, state, context, options)
|
|
18
|
+
writeNginxConfig(__dir__, 'Wings', id, target, state, context, options)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def actionWingsDeploy(id, target, activeState, context, options)
|
|
22
|
+
if !target['Location'] || target['Location'] == '@me'
|
|
23
|
+
deployNginxConfig(id, target, activeState, context, options)
|
|
24
|
+
activeState['Location'] = '@me'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
upstream wings {
|
|
3
|
+
server 127.0.0.1:1200;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
server {
|
|
7
|
+
|
|
8
|
+
<% if !config['TLS'] %>
|
|
9
|
+
listen <%= config['Port'] %>;
|
|
10
|
+
listen [::]:<%= config['Port'] %>;
|
|
11
|
+
<% else %>
|
|
12
|
+
listen <%= config['Port'] %> ssl;
|
|
13
|
+
listen [::]:<%= config['Port'] %> ssl;
|
|
14
|
+
http2 on;
|
|
15
|
+
include config-lmm/ssl.conf;
|
|
16
|
+
<% end %>
|
|
17
|
+
|
|
18
|
+
server_name <%= config['Domain'] %>;
|
|
19
|
+
|
|
20
|
+
access_log /var/log/nginx/wings.access.log;
|
|
21
|
+
error_log /var/log/nginx/wings.error.log;
|
|
22
|
+
|
|
23
|
+
include config-lmm/private.conf;
|
|
24
|
+
include config-lmm/errors.conf;
|
|
25
|
+
|
|
26
|
+
location / {
|
|
27
|
+
proxy_pass http://wings;
|
|
28
|
+
|
|
29
|
+
include config/proxy.conf;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
location ~ \/ws$ {
|
|
33
|
+
proxy_pass http://wings;
|
|
34
|
+
|
|
35
|
+
include config/proxy.conf;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
upstream sunshine {
|
|
3
|
+
server 127.0.0.1:47990 fail_timeout=0;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
server {
|
|
7
|
+
|
|
8
|
+
<% if !config['TLS'] %>
|
|
9
|
+
listen <%= config['Port'] %>;
|
|
10
|
+
listen [::]:<%= config['Port'] %>;
|
|
11
|
+
<% else %>
|
|
12
|
+
listen <%= config['Port'] %> ssl;
|
|
13
|
+
listen [::]:<%= config['Port'] %> ssl;
|
|
14
|
+
http2 on;
|
|
15
|
+
include config-lmm/ssl.conf;
|
|
16
|
+
<% end %>
|
|
17
|
+
|
|
18
|
+
server_name <%= config['Domain'] %>;
|
|
19
|
+
|
|
20
|
+
access_log /var/log/nginx/sunshine.access.log;
|
|
21
|
+
error_log /var/log/nginx/sunshine.error.log;
|
|
22
|
+
|
|
23
|
+
include config-lmm/private.conf;
|
|
24
|
+
include config-lmm/errors.conf;
|
|
25
|
+
|
|
26
|
+
location / {
|
|
27
|
+
proxy_pass https://sunshine;
|
|
28
|
+
include config-lmm/proxy.conf;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
|
|
4
|
+
module ConfigLMM
|
|
5
|
+
module LMM
|
|
6
|
+
class Sunshine < Framework::NginxApp
|
|
7
|
+
|
|
8
|
+
def actionSunshineBuild(id, target, state, context, options)
|
|
9
|
+
writeNginxConfig(__dir__, 'Sunshine', id, target, state, context, options)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def actionSunshineDeploy(id, target, activeState, context, options)
|
|
13
|
+
if !target['Location'] || target['Location'] == '@me'
|
|
14
|
+
deployNginxConfig(id, target, activeState, context, options)
|
|
15
|
+
activeState['Location'] = '@me'
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
|
|
2
|
+
upstream vaultwarden {
|
|
3
|
+
server 127.0.0.1:8000;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
upstream vaultwarden-websocket {
|
|
7
|
+
server 127.0.0.1:3012;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
server {
|
|
11
|
+
|
|
12
|
+
<% if !config['TLS'] %>
|
|
13
|
+
listen <%= config['Port'] %>;
|
|
14
|
+
listen [::]:<%= config['Port'] %>;
|
|
15
|
+
<% else %>
|
|
16
|
+
listen <%= config['Port'] %> ssl;
|
|
17
|
+
listen [::]:<%= config['Port'] %> ssl;
|
|
18
|
+
http2 on;
|
|
19
|
+
include config-lmm/ssl.conf;
|
|
20
|
+
<% end %>
|
|
21
|
+
|
|
22
|
+
server_name <%= config['Domain'] %>;
|
|
23
|
+
|
|
24
|
+
<% if config['Private'] %>
|
|
25
|
+
include config-lmm/private.conf;
|
|
26
|
+
<% end %>
|
|
27
|
+
|
|
28
|
+
access_log /var/log/nginx/vaultwarden.access.log;
|
|
29
|
+
error_log /var/log/nginx/vaultwarden.error.log;
|
|
30
|
+
|
|
31
|
+
client_max_body_size 200M;
|
|
32
|
+
|
|
33
|
+
include config-lmm/errors.conf;
|
|
34
|
+
|
|
35
|
+
location / {
|
|
36
|
+
proxy_pass http://vaultwarden;
|
|
37
|
+
include config-lmm/proxy.conf;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
location /notifications/ {
|
|
41
|
+
proxy_pass http://vaultwarden-websocket/;
|
|
42
|
+
|
|
43
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
44
|
+
proxy_set_header Connection "upgrade";
|
|
45
|
+
include config-lmm/proxy.conf;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
|
|
4
|
+
module ConfigLMM
|
|
5
|
+
module LMM
|
|
6
|
+
class Vaultwarden < Framework::NginxApp
|
|
7
|
+
|
|
8
|
+
def actionVaultwardenBuild(id, target, state, context, options)
|
|
9
|
+
writeNginxConfig(__dir__, 'Vaultwarden', id, target, state, context, options)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def actionVaultwardenDiff(id, target, activeState, context, options)
|
|
13
|
+
# TODO
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def actionVaultwardenDeploy(id, target, activeState, context, options)
|
|
17
|
+
if !target['Location'] || target['Location'] == '@me'
|
|
18
|
+
deployNginxConfig(id, target, activeState, context, options)
|
|
19
|
+
activeState['Location'] = '@me'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
upstream bitmagnet {
|
|
3
|
+
server 127.0.0.1:3333;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
server {
|
|
7
|
+
<% if !config['TLS'] %>
|
|
8
|
+
listen <%= config['Port'] %>;
|
|
9
|
+
listen [::]:<%= config['Port'] %>;
|
|
10
|
+
<% else %>
|
|
11
|
+
listen <%= config['Port'] %> ssl;
|
|
12
|
+
listen [::]:<%= config['Port'] %> ssl;
|
|
13
|
+
http2 on;
|
|
14
|
+
include config-lmm/ssl.conf;
|
|
15
|
+
<% end %>
|
|
16
|
+
|
|
17
|
+
server_name <%= config['Domain'] %>;
|
|
18
|
+
|
|
19
|
+
access_log /var/log/nginx/bitmagnet.access.log;
|
|
20
|
+
error_log /var/log/nginx/bitmagnet.error.log;
|
|
21
|
+
|
|
22
|
+
include config-lmm/private.conf;
|
|
23
|
+
include config-lmm/errors.conf;
|
|
24
|
+
|
|
25
|
+
location / {
|
|
26
|
+
proxy_pass http://bitmagnet;
|
|
27
|
+
include config-lmm/proxy.conf;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
location = /graphql {
|
|
31
|
+
proxy_read_timeout 10m;
|
|
32
|
+
proxy_pass http://bitmagnet;
|
|
33
|
+
include config-lmm/proxy.conf;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
module ConfigLMM
|
|
3
|
+
module LMM
|
|
4
|
+
class Bitmagnet < Framework::NginxApp
|
|
5
|
+
|
|
6
|
+
def actionBitmagnetBuild(id, target, state, context, options)
|
|
7
|
+
writeNginxConfig(__dir__, 'bitmagnet', id, target, state, context, options)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def actionBitmagnetDeploy(id, target, activeState, context, options)
|
|
11
|
+
if !target['Location'] || target['Location'] == '@me'
|
|
12
|
+
deployNginxConfig(id, target, activeState, context, options)
|
|
13
|
+
activeState['Location'] = '@me'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'rubygems'
|
|
3
|
+
require 'gollum/app'
|
|
4
|
+
|
|
5
|
+
gollum_path = File.expand_path(File.dirname(__FILE__)) + '/repo'
|
|
6
|
+
|
|
7
|
+
wiki_options = {:universal_toc => false}
|
|
8
|
+
Precious::App.set(:gollum_path, gollum_path)
|
|
9
|
+
Precious::App.set(:default_markup, :markdown) # set your favorite markup language
|
|
10
|
+
Precious::App.set(:wiki_options, wiki_options)
|
|
11
|
+
run Precious::App
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
server {
|
|
3
|
+
|
|
4
|
+
<% if !config['TLS'] %>
|
|
5
|
+
listen <%= config['Port'] %>;
|
|
6
|
+
listen [::]:<%= config['Port'] %>;
|
|
7
|
+
<% else %>
|
|
8
|
+
listen <%= config['Port'] %> ssl;
|
|
9
|
+
listen [::]:<%= config['Port'] %> ssl;
|
|
10
|
+
http2 on;
|
|
11
|
+
include config-lmm/ssl.conf;
|
|
12
|
+
<% end %>
|
|
13
|
+
|
|
14
|
+
server_name <%= config['Domain'] %>;
|
|
15
|
+
|
|
16
|
+
root <%= config['Root'] %>;
|
|
17
|
+
passenger_app_root /srv/gollum;
|
|
18
|
+
|
|
19
|
+
try_files $uri @Passenger;
|
|
20
|
+
|
|
21
|
+
access_log /var/log/nginx/gollum.access.log;
|
|
22
|
+
error_log /var/log/nginx/gollum.error.log;
|
|
23
|
+
|
|
24
|
+
include config-lmm/private.conf;
|
|
25
|
+
include config-lmm/errors.conf;
|
|
26
|
+
|
|
27
|
+
<% if config['CertName'] %>
|
|
28
|
+
ssl_certificate "/etc/letsencrypt/live/<%= config['CertName'] %>/fullchain.pem";
|
|
29
|
+
ssl_certificate_key "/etc/letsencrypt/live/<%= config['CertName'] %>/privkey.pem";
|
|
30
|
+
ssl_trusted_certificate "/etc/letsencrypt/live/<%= config['CertName'] %>/chain.pem";
|
|
31
|
+
<% end %>
|
|
32
|
+
|
|
33
|
+
location @Passenger {
|
|
34
|
+
passenger_enabled on;
|
|
35
|
+
passenger_min_instances 1;
|
|
36
|
+
rails_env production;
|
|
37
|
+
|
|
38
|
+
#passenger_set_cgi_param HTTP_X_FORWARDED_PROTO https;
|
|
39
|
+
#limit_req zone=one burst=5;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
|
|
2
|
+
module ConfigLMM
|
|
3
|
+
module LMM
|
|
4
|
+
class Gollum < Framework::NginxApp
|
|
5
|
+
|
|
6
|
+
NAME = 'gollum'
|
|
7
|
+
GOLLUM_PATH = '/srv/gollum'
|
|
8
|
+
|
|
9
|
+
def actionGollumBuild(id, target, activeState, context, options)
|
|
10
|
+
if !target['Root'] && (!target['Location'] || target['Location'] == '@me')
|
|
11
|
+
target['Root'] = File.dirname(`gem which gollum`.strip) + '/gollum/public'
|
|
12
|
+
end
|
|
13
|
+
writeNginxConfig(__dir__, NAME, id, target, activeState, context, options)
|
|
14
|
+
targetDir = options['output'] + GOLLUM_PATH
|
|
15
|
+
mkdir(targetDir, options['dry'])
|
|
16
|
+
copy(__dir__ + '/config.ru', targetDir, options['dry'])
|
|
17
|
+
`git init #{targetDir}/repo`
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def actionGollumRefresh(id, target, activeState, context, options)
|
|
21
|
+
# Would need to parse deployed config to implement
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def actionGollumDeploy(id, target, activeState, context, options)
|
|
25
|
+
if !target['Location'] || target['Location'] == '@me'
|
|
26
|
+
targetDir = GOLLUM_PATH
|
|
27
|
+
mkdir(targetDir, options['dry'])
|
|
28
|
+
deployNginxConfig(id, target, activeState, context, options)
|
|
29
|
+
copy(options['output'] + GOLLUM_PATH + '/config.ru', GOLLUM_PATH, options['dry'])
|
|
30
|
+
copyNotPresent(options['output'] + GOLLUM_PATH + '/repo', GOLLUM_PATH, options['dry'])
|
|
31
|
+
chown('http', 'http', GOLLUM_PATH, options['dry'])
|
|
32
|
+
activeState['Location'] = '@me'
|
|
33
|
+
else
|
|
34
|
+
# TODO
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def cleanup(configs, state, context, options)
|
|
39
|
+
items = state.selectType(:Gollum)
|
|
40
|
+
items.each do |id, item|
|
|
41
|
+
if !configs.key?(id)
|
|
42
|
+
if item['Location'] == '@me'
|
|
43
|
+
cleanupNginxConfig(NAME, id, state, context, options)
|
|
44
|
+
else
|
|
45
|
+
# TODO
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
|
|
2
|
+
module ConfigLMM
|
|
3
|
+
module LMM
|
|
4
|
+
class Linux < Framework::Plugin
|
|
5
|
+
|
|
6
|
+
HOSTS_FILE = '/etc/hosts'
|
|
7
|
+
HOSTS_SECTION_BEGIN = "# -----BEGIN CONFIGLMM-----\n"
|
|
8
|
+
HOSTS_SECTION_END = "# -----END CONFIGLMM-----\n"
|
|
9
|
+
|
|
10
|
+
def actionLinuxBuild(id, target, activeState, context, options)
|
|
11
|
+
if target['Hosts']
|
|
12
|
+
hosts = "#\n"
|
|
13
|
+
hosts += "# /etc/hosts: static lookup table for host names\n"
|
|
14
|
+
hosts += "#\n\n"
|
|
15
|
+
hosts += "#<ip-address> <hostname.domain.org> <hostname>\n"
|
|
16
|
+
hosts += "127.0.0.1 localhost\n"
|
|
17
|
+
hosts += "::1 localhost\n\n"
|
|
18
|
+
hosts += HOSTS_SECTION_BEGIN
|
|
19
|
+
target['Hosts'].each do |ip, entries|
|
|
20
|
+
hosts += ip.ljust(16) + entries.join(' ') + "\n"
|
|
21
|
+
end
|
|
22
|
+
hosts += HOSTS_SECTION_END
|
|
23
|
+
|
|
24
|
+
mkdir(options['output'] + '/etc', options[:dry])
|
|
25
|
+
fileWrite(options['output'] + HOSTS_FILE, hosts, options[:dry])
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def actionLinuxDeploy(id, target, activeState, context, options)
|
|
30
|
+
if !target['Location'] || target['Location'] == '@me'
|
|
31
|
+
if target['Hosts']
|
|
32
|
+
hostsLines = File.read(HOSTS_FILE).lines
|
|
33
|
+
sectionBeginIndex = hostsLines.index(HOSTS_SECTION_BEGIN)
|
|
34
|
+
sectionEndIndex = hostsLines.index(HOSTS_SECTION_END)
|
|
35
|
+
if sectionBeginIndex.nil?
|
|
36
|
+
linesBefore = hostsLines
|
|
37
|
+
linesBefore << "\n"
|
|
38
|
+
linesBefore << HOSTS_SECTION_BEGIN
|
|
39
|
+
linesAfter = [HOSTS_SECTION_END]
|
|
40
|
+
linesAfter << "\n"
|
|
41
|
+
else
|
|
42
|
+
linesBefore = hostsLines[0..sectionBeginIndex]
|
|
43
|
+
if sectionEndIndex.nil?
|
|
44
|
+
linesAfter = [HOSTS_SECTION_END]
|
|
45
|
+
linesAfter << "\n"
|
|
46
|
+
else
|
|
47
|
+
linesAfter = hostsLines[sectionEndIndex..hostsLines.length]
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
hostsLines = linesBefore
|
|
52
|
+
target['Hosts'].each do |ip, entries|
|
|
53
|
+
hostsLines << ip.ljust(16) + entries.join(' ') + "\n"
|
|
54
|
+
end
|
|
55
|
+
hostsLines += linesAfter
|
|
56
|
+
|
|
57
|
+
fileWrite(HOSTS_FILE, hostsLines.join(), options[:dry])
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
|
|
2
|
+
require 'expect'
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
require 'socket'
|
|
5
|
+
require 'pty'
|
|
6
|
+
require 'tty-which'
|
|
7
|
+
require 'webrick'
|
|
8
|
+
|
|
9
|
+
module ConfigLMM
|
|
10
|
+
module LMM
|
|
11
|
+
class ArubaInstant < Framework::SSH
|
|
12
|
+
|
|
13
|
+
CERT_BASE = '/etc/letsencrypt/live/'
|
|
14
|
+
HTTP_PORT = 6582
|
|
15
|
+
|
|
16
|
+
def actionArubaInstantDeploy(id, target, activeState, context, options)
|
|
17
|
+
if !target['Location']
|
|
18
|
+
raise Framework::PluginProcessError.new(id + ': Location must be provided!')
|
|
19
|
+
end
|
|
20
|
+
if target['CertificateName']
|
|
21
|
+
fullchain = CERT_BASE + target['CertificateName'] + '/fullchain.pem'
|
|
22
|
+
privkey = CERT_BASE + target['CertificateName'] + '/privkey.pem'
|
|
23
|
+
if !File.exist?(fullchain) || !File.exist?(privkey)
|
|
24
|
+
prompt.error('Couldn\'t find certificate!')
|
|
25
|
+
prompt.error("Looked at #{fullchain} and #{privkey}")
|
|
26
|
+
raise Framework::PluginProcessError.new(id + ': Certificate not found!')
|
|
27
|
+
end
|
|
28
|
+
certData = File.read(fullchain)
|
|
29
|
+
certData += File.read(privkey)
|
|
30
|
+
certFileName = SecureRandom.hex(10)
|
|
31
|
+
File.write(options['output'] + '/' + certFileName, certData)
|
|
32
|
+
|
|
33
|
+
httpThread = Thread.new do
|
|
34
|
+
server = WEBrick::HTTPServer.new(Port: HTTP_PORT,
|
|
35
|
+
DocumentRoot: options['output'],
|
|
36
|
+
Logger: WEBrick::Log.new("/dev/null"),
|
|
37
|
+
AccessLog: [])
|
|
38
|
+
server.start
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
ourIP = Socket.ip_address_list.select { |addr| addr.ipv4_private? }.first.ip_address
|
|
42
|
+
|
|
43
|
+
firewallcmd = TTY::Which.which("firewall-cmd")
|
|
44
|
+
if firewallcmd
|
|
45
|
+
`#{firewallcmd} --add-port #{HTTP_PORT}/tcp >/dev/null 2>&1`
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
creds = parseLocation(target['Location'])
|
|
49
|
+
password = ENV['ARUBA_INSTANT_PASSWORD']
|
|
50
|
+
|
|
51
|
+
# Couldn't get it working with net-ssh gem so using `ssh` as workaround
|
|
52
|
+
# Net::SSH.start(creds[:hostname], creds[:user], password: password, port: creds[:port]) do |ssh|
|
|
53
|
+
PTY.spawn("ssh -o NumberOfPasswordPrompts=1 -o HostKeyAlgorithms=ssh-rsa #{creds[:user]}@#{creds[:hostname]}") do |reader, writer, pid|
|
|
54
|
+
reader.expect(/password:/) do |result|
|
|
55
|
+
writer.puts(password)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
output = ''
|
|
59
|
+
lastWrite = nil
|
|
60
|
+
error = nil
|
|
61
|
+
thread = Thread.new do
|
|
62
|
+
reader.each do |line|
|
|
63
|
+
output += line
|
|
64
|
+
lastWrite = Time.now.to_f
|
|
65
|
+
end
|
|
66
|
+
rescue SystemCallError => err
|
|
67
|
+
# Most likely wrong password
|
|
68
|
+
error = err
|
|
69
|
+
end
|
|
70
|
+
while lastWrite.nil? || Time.now.to_f - lastWrite < 5 # It takes while to respond
|
|
71
|
+
sleep(0.2)
|
|
72
|
+
if error
|
|
73
|
+
raise Framework::PluginProcessError.new(id + ': ' + error.message)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
output = ''
|
|
77
|
+
lastWrite = nil
|
|
78
|
+
writer.puts('show version')
|
|
79
|
+
while lastWrite.nil? || Time.now.to_f - lastWrite < 2
|
|
80
|
+
sleep(0.2)
|
|
81
|
+
end
|
|
82
|
+
thread.terminate
|
|
83
|
+
if output.include?('ArubaOS')
|
|
84
|
+
result = output.match(/MODEL: (\d+)., Version ([\d\.]+)/)
|
|
85
|
+
prompt.say("ArubaOS Version: #{result[2]}")
|
|
86
|
+
prompt.say("MODEL: #{result[1]}")
|
|
87
|
+
if result[1] == '275'
|
|
88
|
+
output = ''
|
|
89
|
+
lastWrite = nil
|
|
90
|
+
# See Aruba Instant 8.x Command-Line Interface Reference Guide
|
|
91
|
+
# download-cert ui <url> format pem [psk <psk>]
|
|
92
|
+
writer.puts("download-cert ui http://#{ourIP}:#{HTTP_PORT}/#{certFileName}")
|
|
93
|
+
thread = Thread.new do
|
|
94
|
+
reader.each do |line|
|
|
95
|
+
output += line
|
|
96
|
+
lastWrite = Time.now.to_f
|
|
97
|
+
prompt.say(line)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
while lastWrite.nil? || Time.now.to_f - lastWrite < 4
|
|
101
|
+
sleep(0.2)
|
|
102
|
+
end
|
|
103
|
+
thread.terminate
|
|
104
|
+
if output.include?('error')
|
|
105
|
+
message = 'Something went wrong! :('
|
|
106
|
+
prompt.error(message)
|
|
107
|
+
raise Framework::PluginProcessError.new(id + ': ' + message)
|
|
108
|
+
end
|
|
109
|
+
else
|
|
110
|
+
message = 'Not risking with untested device! Please test and submit PR! :)'
|
|
111
|
+
prompt.error(message)
|
|
112
|
+
raise Framework::PluginProcessError.new(id + ': ' + message)
|
|
113
|
+
end
|
|
114
|
+
else
|
|
115
|
+
message = 'This is not Aruba device!'
|
|
116
|
+
prompt.error(message)
|
|
117
|
+
raise Framework::PluginProcessError.new(id + ': ' + message)
|
|
118
|
+
end
|
|
119
|
+
reader.close
|
|
120
|
+
writer.close
|
|
121
|
+
rescue Framework::PluginProcessError => error
|
|
122
|
+
`#{firewallcmd} --remove-port #{HTTP_PORT}/tcp` if firewallcmd
|
|
123
|
+
raise error
|
|
124
|
+
end
|
|
125
|
+
httpThread.terminate
|
|
126
|
+
`#{firewallcmd} --remove-port #{HTTP_PORT}/tcp` if firewallcmd
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def authenticate(actionMethod, target, activeState, context, options)
|
|
131
|
+
if ENV['ARUBA_INSTANT_PASSWORD'].to_s.empty? || ENV['ARUBA_INSTANT_PASSWORD'].to_s.empty?
|
|
132
|
+
prompt.error('Set your Aruba Instant SSH password to ARUBA_INSTANT_PASSWORD as Environment Variable')
|
|
133
|
+
raise Framework::PluginPrerequisite.new('Need ARUBA_INSTANT_PASSWORD')
|
|
134
|
+
else
|
|
135
|
+
if !target['Location']
|
|
136
|
+
raise Framework::PluginProcessError.new('Location must be provided!')
|
|
137
|
+
end
|
|
138
|
+
checkSSHAuth!(target['Location'], ENV['ARUBA_INSTANT_PASSWORD'])
|
|
139
|
+
end
|
|
140
|
+
true
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|