ConfigLMM 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,8 +2,11 @@
2
2
 
3
3
  require_relative 'errors'
4
4
  require_relative 'store'
5
+ require 'addressable/uri'
5
6
  require 'http'
6
7
  require 'fileutils'
8
+ require 'net/ssh'
9
+ require 'net/scp'
7
10
 
8
11
  module ConfigLMM
9
12
  module Framework
@@ -42,6 +45,8 @@ module ConfigLMM
42
45
 
43
46
  addMeta :name, :description
44
47
 
48
+ attr_accessor :state
49
+
45
50
  def initialize(logger, prompt, plugins)
46
51
  @Logger = logger
47
52
  @Prompt = prompt
@@ -141,6 +146,111 @@ module ConfigLMM
141
146
  end
142
147
  end
143
148
 
149
+ CONFIGLMM_SECTION_BEGIN = "# -----BEGIN CONFIGLMM-----\n"
150
+ CONFIGLMM_SECTION_END = "# -----END CONFIGLMM-----\n"
151
+
152
+ def updateLocalFile(file, options, atTop = false)
153
+ fileLines = File.read(file).lines
154
+ sectionBeginIndex = fileLines.index(CONFIGLMM_SECTION_BEGIN)
155
+ sectionEndIndex = fileLines.index(CONFIGLMM_SECTION_END)
156
+ if sectionBeginIndex.nil?
157
+ linesBefore = []
158
+ linesBefore = fileLines unless atTop
159
+ linesBefore << "\n"
160
+ linesBefore << CONFIGLMM_SECTION_BEGIN
161
+ linesAfter = [CONFIGLMM_SECTION_END]
162
+ linesAfter << "\n"
163
+ linesAfter += fileLines if atTop
164
+ else
165
+ linesBefore = fileLines[0..sectionBeginIndex]
166
+ if sectionEndIndex.nil?
167
+ linesAfter = [CONFIGLMM_SECTION_END]
168
+ linesAfter << "\n"
169
+ else
170
+ linesAfter = fileLines[sectionEndIndex..fileLines.length]
171
+ end
172
+ end
173
+
174
+ fileLines = linesBefore
175
+ fileLines = yield(fileLines)
176
+ fileLines += linesAfter
177
+
178
+ fileWrite(file, fileLines.join(), options[:dry])
179
+ end
180
+
181
+ def updateRemoteFile(locationOrSSH, file, options, atTop = false, &block)
182
+
183
+ closure = Proc.new do |ssh|
184
+ localFile = options['output'] + '/' + SecureRandom.alphanumeric(10)
185
+ File.write(localFile, '')
186
+ self.class.sshExec!(ssh, "touch #{file}")
187
+ ssh.scp.download!(file, localFile)
188
+ updateLocalFile(localFile, options, atTop, &block)
189
+ ssh.scp.upload!(localFile, file)
190
+ end
191
+
192
+ if locationOrSSH.is_a?(String) || locationOrSSH.is_a?(Addressable::URI)
193
+ uri = Addressable::URI.parse(locationOrSSH)
194
+ raise Framework::PluginProcessError.new("Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
195
+
196
+ self.class.sshStart(uri) do |ssh|
197
+ closure.call(ssh)
198
+ end
199
+ else
200
+ closure.call(locationOrSSH)
201
+ end
202
+ end
203
+
204
+ def self.remoteFilePresent?(file, ssh)
205
+ result = self.sshExec!(ssh, "stat #{file}", true)
206
+ !result.start_with?('stat: cannot')
207
+ end
208
+
209
+ def self.uploadNotPresent(file, target, ssh)
210
+ target += '/' + File.basename(file)
211
+ if !self.remoteFilePresent?(target)
212
+ ssh.scp.upload!(file, target)
213
+ end
214
+ end
215
+
216
+ def self.uploadFolder(folder, target, ssh)
217
+ target += '/' + File.basename(folder) + '/'
218
+ self.sshExec!(ssh, "mkdir -p #{target}")
219
+ Dir[folder + '/*'].each do |file|
220
+ ssh.scp.upload!(file, target + File.basename(file))
221
+ end
222
+ end
223
+
224
+ def self.toSSHparams(locationUri)
225
+ server = locationUri.hostname
226
+ params = {}
227
+ params[:port] = locationUri.port if locationUri.port
228
+ params[:user] = locationUri.user if locationUri.user
229
+ [server, params]
230
+ end
231
+
232
+ def self.sshStart(uri)
233
+ uri = Addressable::URI.parse(uri) if uri.is_a?(String)
234
+ server, sshParams = self.toSSHparams(uri)
235
+ Net::SSH.start(server, nil, sshParams) do |ssh|
236
+ yield(ssh)
237
+ end
238
+ end
239
+
240
+ def self.sshExec!(ssh, command, allowFailure = false)
241
+ status = {}
242
+ output = ''
243
+ channel = ssh.exec(command, status: status) do |channel, stream, data|
244
+ output += data
245
+ end
246
+ channel.wait
247
+ if !allowFailure && !status[:exit_code].zero?
248
+ $stderr.puts(output)
249
+ raise Framework::PluginProcessError.new("Failed '#{command}'")
250
+ end
251
+ output
252
+ end
253
+
144
254
  def renderTemplate(template, target, outputPath, options)
145
255
  variables = {
146
256
  config: target,
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'plugins/dns'
4
+ require_relative 'plugins/linuxApp'
4
5
  require_relative 'plugins/nginxApp'
5
6
  require_relative 'plugins/ssh'
@@ -32,6 +32,9 @@ module ConfigLMM
32
32
 
33
33
  # Create Plugin instances
34
34
  Framework::Store.boot(logger, prompt, @Plugins)
35
+ @Plugins.each do |id, plugin|
36
+ plugin.state = @State
37
+ end
35
38
  end
36
39
 
37
40
  def execute
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ConfigLMM
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ConfigLMM
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dāvis Mosāns
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-11 00:00:00.000000000 Z
11
+ date: 2024-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: filesize
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: fog-libvirt
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: fog-powerdns
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +136,20 @@ dependencies:
108
136
  - - "~>"
109
137
  - !ruby/object:Gem::Version
110
138
  version: 5.1.1
139
+ - !ruby/object:Gem::Dependency
140
+ name: net-scp
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
111
153
  - !ruby/object:Gem::Dependency
112
154
  name: net-ssh
113
155
  requirement: !ruby/object:Gem::Requirement
@@ -366,8 +408,11 @@ files:
366
408
  - Examples/Linux.mm.yaml
367
409
  - Examples/Windows.mm.yaml
368
410
  - Examples/configlmmAuth.sh
411
+ - Images/configINconfig.png
412
+ - Images/singleConfig.png
369
413
  - Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.conf.erb
370
414
  - Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.lmm.rb
415
+ - Plugins/Apps/Dovecot/Dovecot.lmm.rb
371
416
  - Plugins/Apps/IPFS/IPFS.conf.erb
372
417
  - Plugins/Apps/IPFS/IPFS.lmm.rb
373
418
  - Plugins/Apps/InfluxDB/InfluxDB.conf.erb
@@ -388,6 +433,7 @@ files:
388
433
  - Plugins/Apps/Nginx/config-lmm/private.conf
389
434
  - Plugins/Apps/Nginx/config-lmm/proxy.conf
390
435
  - Plugins/Apps/Nginx/config-lmm/public.conf
436
+ - Plugins/Apps/Nginx/config-lmm/security.conf
391
437
  - Plugins/Apps/Nginx/config-lmm/ssl.conf
392
438
  - Plugins/Apps/Nginx/main.conf
393
439
  - Plugins/Apps/Nginx/nginx.conf
@@ -395,11 +441,14 @@ files:
395
441
  - Plugins/Apps/Nginx/proxy.conf.erb
396
442
  - Plugins/Apps/Odoo/Odoo.conf.erb
397
443
  - Plugins/Apps/Odoo/Odoo.lmm.rb
444
+ - Plugins/Apps/Postfix/Postfix.lmm.rb
445
+ - Plugins/Apps/PostgreSQL/PostgreSQL.lmm.rb
398
446
  - Plugins/Apps/Pterodactyl/Pterodactyl.conf.erb
399
447
  - Plugins/Apps/Pterodactyl/Pterodactyl.lmm.rb
400
448
  - Plugins/Apps/Pterodactyl/Wings.conf.erb
401
449
  - Plugins/Apps/Sunshine/Sunshine.conf.erb
402
450
  - Plugins/Apps/Sunshine/Sunshine.lmm.rb
451
+ - Plugins/Apps/Valkey/Valkey.lmm.rb
403
452
  - Plugins/Apps/Vaultwarden/Vaultwarden.conf.erb
404
453
  - Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb
405
454
  - Plugins/Apps/bitmagnet/bitmagnet.conf.erb
@@ -407,11 +456,15 @@ files:
407
456
  - Plugins/Apps/gollum/config.ru
408
457
  - Plugins/Apps/gollum/gollum.conf.erb
409
458
  - Plugins/Apps/gollum/gollum.lmm.rb
410
- - Plugins/OS/Linux.lmm.rb
459
+ - Plugins/OS/Linux/Distributions.yaml
460
+ - Plugins/OS/Linux/Linux.lmm.rb
461
+ - Plugins/OS/Linux/Packages.yaml
462
+ - Plugins/OS/Linux/openSUSE/autoinst.xml.erb
411
463
  - Plugins/OS/Routers/Aruba/ArubaInstant.lmm.rb
412
464
  - Plugins/Platforms/GitHub.lmm.rb
413
465
  - Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb
414
466
  - Plugins/Platforms/GoDaddy/zone.txt.erb
467
+ - Plugins/Platforms/libvirt/libvirt.lmm.rb
415
468
  - Plugins/Platforms/porkbun.lmm.rb
416
469
  - Plugins/Platforms/porkbun_spec.rb
417
470
  - Plugins/Services/DNS/AmberBit.lmm.rb
@@ -430,6 +483,7 @@ files:
430
483
  - lib/ConfigLMM/Framework/plugins.rb
431
484
  - lib/ConfigLMM/Framework/plugins/dns.rb
432
485
  - lib/ConfigLMM/Framework/plugins/errors.rb
486
+ - lib/ConfigLMM/Framework/plugins/linuxApp.rb
433
487
  - lib/ConfigLMM/Framework/plugins/nginxApp.rb
434
488
  - lib/ConfigLMM/Framework/plugins/plugin.rb
435
489
  - lib/ConfigLMM/Framework/plugins/ssh.rb
@@ -478,7 +532,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
478
532
  - !ruby/object:Gem::Version
479
533
  version: '0'
480
534
  requirements: []
481
- rubygems_version: 3.5.11
535
+ rubygems_version: 3.5.15
482
536
  signing_key:
483
537
  specification_version: 4
484
538
  summary: Manage configuration for your applications/systems/services/servers
@@ -1,64 +0,0 @@
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