ConfigLMM 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.yardopts +4 -0
  4. data/CHANGELOG.md +5 -0
  5. data/Examples/Android.mm.yaml +8 -0
  6. data/Examples/Apps/Blog.mm.yaml +7 -0
  7. data/Examples/Apps/Jellyfin.mm.yaml +3 -0
  8. data/Examples/Implemented.mm.yaml +155 -0
  9. data/Examples/Keys.ini +7 -0
  10. data/Examples/Linux.mm.yaml +16 -0
  11. data/Examples/Windows.mm.yaml +11 -0
  12. data/Examples/configlmmAuth.sh +26 -0
  13. data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.conf.erb +38 -0
  14. data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.lmm.rb +19 -0
  15. data/Plugins/Apps/IPFS/IPFS.conf.erb +44 -0
  16. data/Plugins/Apps/IPFS/IPFS.lmm.rb +23 -0
  17. data/Plugins/Apps/InfluxDB/InfluxDB.conf.erb +34 -0
  18. data/Plugins/Apps/InfluxDB/InfluxDB.lmm.rb +19 -0
  19. data/Plugins/Apps/Jackett/Jackett.conf.erb +38 -0
  20. data/Plugins/Apps/Jackett/Jackett.lmm.rb +19 -0
  21. data/Plugins/Apps/Jellyfin/Jellyfin.conf.erb +59 -0
  22. data/Plugins/Apps/Jellyfin/Jellyfin.lmm.rb +23 -0
  23. data/Plugins/Apps/Mastodon/Mastodon.conf.erb +81 -0
  24. data/Plugins/Apps/Mastodon/Mastodon.lmm.rb +23 -0
  25. data/Plugins/Apps/Matrix/Matrix.conf.erb +36 -0
  26. data/Plugins/Apps/Matrix/Matrix.lmm.rb +23 -0
  27. data/Plugins/Apps/Netdata/Netdata.conf.erb +37 -0
  28. data/Plugins/Apps/Netdata/Netdata.lmm.rb +23 -0
  29. data/Plugins/Apps/Nextcloud/Nextcloud.conf.erb +165 -0
  30. data/Plugins/Apps/Nextcloud/Nextcloud.lmm.rb +23 -0
  31. data/Plugins/Apps/Nginx/config-lmm/errors.conf +31 -0
  32. data/Plugins/Apps/Nginx/config-lmm/private.conf +6 -0
  33. data/Plugins/Apps/Nginx/config-lmm/proxy.conf +15 -0
  34. data/Plugins/Apps/Nginx/config-lmm/public.conf +3 -0
  35. data/Plugins/Apps/Nginx/config-lmm/ssl.conf +18 -0
  36. data/Plugins/Apps/Nginx/main.conf +30 -0
  37. data/Plugins/Apps/Nginx/nginx.conf +90 -0
  38. data/Plugins/Apps/Nginx/nginx.lmm.rb +62 -0
  39. data/Plugins/Apps/Nginx/proxy.conf.erb +31 -0
  40. data/Plugins/Apps/Odoo/Odoo.conf.erb +44 -0
  41. data/Plugins/Apps/Odoo/Odoo.lmm.rb +23 -0
  42. data/Plugins/Apps/Pterodactyl/Pterodactyl.conf.erb +50 -0
  43. data/Plugins/Apps/Pterodactyl/Pterodactyl.lmm.rb +30 -0
  44. data/Plugins/Apps/Pterodactyl/Wings.conf.erb +38 -0
  45. data/Plugins/Apps/Sunshine/Sunshine.conf.erb +31 -0
  46. data/Plugins/Apps/Sunshine/Sunshine.lmm.rb +21 -0
  47. data/Plugins/Apps/Vaultwarden/Vaultwarden.conf.erb +48 -0
  48. data/Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb +25 -0
  49. data/Plugins/Apps/bitmagnet/bitmagnet.conf.erb +35 -0
  50. data/Plugins/Apps/bitmagnet/bitmagnet.lmm.rb +19 -0
  51. data/Plugins/Apps/gollum/config.ru +11 -0
  52. data/Plugins/Apps/gollum/gollum.conf.erb +41 -0
  53. data/Plugins/Apps/gollum/gollum.lmm.rb +52 -0
  54. data/Plugins/OS/Linux.lmm.rb +64 -0
  55. data/Plugins/OS/Routers/Aruba/ArubaInstant.lmm.rb +144 -0
  56. data/Plugins/Platforms/GitHub.lmm.rb +57 -0
  57. data/Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb +83 -0
  58. data/Plugins/Platforms/GoDaddy/zone.txt.erb +13 -0
  59. data/Plugins/Platforms/porkbun.lmm.rb +129 -0
  60. data/Plugins/Platforms/porkbun_spec.rb +110 -0
  61. data/Plugins/Services/DNS/AmberBit.lmm.rb +14 -0
  62. data/Plugins/Services/DNS/ArubaItDNS.lmm.rb +14 -0
  63. data/Plugins/Services/DNS/NICLV.lmm.rb +18 -0
  64. data/Plugins/Services/DNS/PowerDNS.lmm.rb +261 -0
  65. data/Plugins/Services/DNS/tonic.lmm.rb +126 -0
  66. data/README.md +337 -0
  67. data/Rakefile +15 -0
  68. data/UNLICENSE +24 -0
  69. data/bin/configlmm +7 -0
  70. data/bin/console +11 -0
  71. data/bin/setup +8 -0
  72. data/lib/ConfigLMM/Framework/plugins/dns.rb +63 -0
  73. data/lib/ConfigLMM/Framework/plugins/errors.rb +23 -0
  74. data/lib/ConfigLMM/Framework/plugins/nginxApp.rb +55 -0
  75. data/lib/ConfigLMM/Framework/plugins/plugin.rb +167 -0
  76. data/lib/ConfigLMM/Framework/plugins/ssh.rb +37 -0
  77. data/lib/ConfigLMM/Framework/plugins/store.rb +57 -0
  78. data/lib/ConfigLMM/Framework/plugins.rb +5 -0
  79. data/lib/ConfigLMM/Framework/registrator.rb +32 -0
  80. data/lib/ConfigLMM/Framework.rb +9 -0
  81. data/lib/ConfigLMM/LMM/plugins.rb +5 -0
  82. data/lib/ConfigLMM/LMM.rb +8 -0
  83. data/lib/ConfigLMM/cli.rb +161 -0
  84. data/lib/ConfigLMM/command.rb +53 -0
  85. data/lib/ConfigLMM/commands/build.rb +41 -0
  86. data/lib/ConfigLMM/commands/cleanup.rb +30 -0
  87. data/lib/ConfigLMM/commands/configsCommand.rb +167 -0
  88. data/lib/ConfigLMM/commands/deploy.rb +39 -0
  89. data/lib/ConfigLMM/commands/diff.rb +45 -0
  90. data/lib/ConfigLMM/commands/list.rb +15 -0
  91. data/lib/ConfigLMM/commands/refresh.rb +46 -0
  92. data/lib/ConfigLMM/commands/types.rb +35 -0
  93. data/lib/ConfigLMM/commands/validate.rb +49 -0
  94. data/lib/ConfigLMM/context.rb +52 -0
  95. data/lib/ConfigLMM/io/configList.rb +98 -0
  96. data/lib/ConfigLMM/io/path.rb +48 -0
  97. data/lib/ConfigLMM/io/source.rb +47 -0
  98. data/lib/ConfigLMM/io.rb +2 -0
  99. data/lib/ConfigLMM/state.rb +78 -0
  100. data/lib/ConfigLMM/utils/filters.rb +126 -0
  101. data/lib/ConfigLMM/version.rb +5 -0
  102. data/lib/ConfigLMM.rb +6 -0
  103. data/sig/ConfigLMM.rbs +4 -0
  104. metadata +485 -0
@@ -0,0 +1,167 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'errors'
4
+ require_relative 'store'
5
+ require 'http'
6
+ require 'fileutils'
7
+
8
+ module ConfigLMM
9
+ module Framework
10
+
11
+ class Plugin
12
+
13
+
14
+ def self.inherited(plugin)
15
+ Store.registerPlugin(plugin)
16
+ end
17
+
18
+ def self.id
19
+ @ID ||= self.normalizeId(self.className.to_s)
20
+ end
21
+
22
+ def self.addMeta(*fields)
23
+ fields.each do |field|
24
+ self.define_singleton_method(field) do |value|
25
+ @Meta ||= {}
26
+ @Meta[field] = value
27
+ end
28
+ end
29
+ end
30
+
31
+ def self.persistBuildDir
32
+ @PersistBuildDir = true
33
+ end
34
+
35
+ def self.persistBuildDir?
36
+ @PersistBuildDir == true
37
+ end
38
+
39
+ class << self
40
+ alias :className :name
41
+ end
42
+
43
+ addMeta :name, :description
44
+
45
+ def initialize(logger, prompt, plugins)
46
+ @Logger = logger
47
+ @Prompt = prompt
48
+ @Plugins = plugins
49
+ @Diff = {}
50
+ end
51
+
52
+ def id
53
+ self.class.id
54
+ end
55
+
56
+ def self.actionMethod(type, action)
57
+ name = type.to_s
58
+ name[0] = name[0].upcase
59
+ ('action' + name + action.to_s.capitalize).to_sym
60
+ end
61
+
62
+ def hasAction?(type, action)
63
+ self.methods.include?(self.class.actionMethod(type, action))
64
+ end
65
+
66
+ def diff
67
+ @Diff
68
+ end
69
+
70
+ def cleanup(configs, state, context, options)
71
+ # Do nothing
72
+ end
73
+
74
+ protected
75
+
76
+ def logger
77
+ @Logger
78
+ end
79
+
80
+ def prompt
81
+ @Prompt
82
+ end
83
+
84
+ def plugins
85
+ @Plugins
86
+ end
87
+
88
+ def shouldMatch(id, targetKey, stateKey, target, activeState)
89
+ if target[targetKey] != activeState[stateKey]
90
+ @Diff.update({targetKey => [target[targetKey], activeState[stateKey]]})
91
+ end
92
+ end
93
+
94
+ def fileWrite(target, data, dry)
95
+ if dry
96
+ prompt.say('Would write file ' + target)
97
+ else
98
+ File.write(target, data)
99
+ end
100
+ end
101
+
102
+ def copy(source, target, dry)
103
+ if dry
104
+ prompt.say('Would copy ' + source + ' to ' + target)
105
+ else
106
+ FileUtils.cp_r(source, target, noop: dry)
107
+ end
108
+ end
109
+
110
+ def copyNotPresent(source, target, dry)
111
+ if !File.exist?(target + File.basename(source))
112
+ if dry
113
+ prompt.say('Would copy ' + source + ' to ' + target)
114
+ else
115
+ FileUtils.cp_r(source, target, noop: dry)
116
+ end
117
+ end
118
+ end
119
+
120
+ def rm(path, dry)
121
+ if dry
122
+ prompt.say('Would remove ' + path)
123
+ else
124
+ FileUtils.rm_r(path, noop: dry)
125
+ end
126
+ end
127
+
128
+ def mkdir(target, dry)
129
+ if dry
130
+ prompt.say('Would create ' + target)
131
+ else
132
+ FileUtils.mkdir_p(target)
133
+ end
134
+ end
135
+
136
+ def chown(user, group, target, dry)
137
+ if dry
138
+ prompt.say("Would chown #{target} as #{user}:#{group}")
139
+ else
140
+ FileUtils.chown_R(user, group, target)
141
+ end
142
+ end
143
+
144
+ def renderTemplate(template, target, outputPath, options)
145
+ variables = {
146
+ config: target,
147
+ }
148
+ result = template.result_with_hash(variables)
149
+ mkdir(File.dirname(outputPath), options['dry'])
150
+ if options['dry']
151
+ prompt.say('Would write to ' + outputPath)
152
+ else
153
+ File.write(outputPath, result)
154
+ end
155
+ end
156
+
157
+ def self.normalizeId(id)
158
+ id = id.split('::').last
159
+ if id.downcase.end_with?('plugin')
160
+ id = id[0...-6]
161
+ end
162
+ id.to_sym
163
+ end
164
+
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,37 @@
1
+
2
+ # frozen_string_literal: true
3
+
4
+ require_relative 'plugin'
5
+ require_relative 'errors'
6
+ require 'net/ssh'
7
+
8
+ module ConfigLMM
9
+ module Framework
10
+
11
+ class SSH < Framework::Plugin
12
+
13
+ def parseLocation(location)
14
+ user, hostname = location.split('@')
15
+ if hostname.nil?
16
+ hostname = user
17
+ user = nil
18
+ end
19
+ hostname, port = hostname.split(':')
20
+ port = 22 unless port
21
+ {
22
+ hostname: hostname,
23
+ user: user,
24
+ port: port
25
+ }
26
+ end
27
+
28
+ def checkSSHAuth!(location, password)
29
+ creds = parseLocation(location)
30
+ Net::SSH.start(creds[:hostname], creds[:user], password: password, port: creds[:port]) do |ssh|
31
+ # All good if we got here
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'errors'
4
+
5
+ module ConfigLMM
6
+ module Framework
7
+ class Store
8
+
9
+ @@AvailablePlugins = {}
10
+
11
+ def self.registerPlugin(plugin)
12
+ @@AvailablePlugins[plugin.id] = plugin
13
+ end
14
+
15
+ def self.plugins
16
+ @@AvailablePlugins.values
17
+ end
18
+
19
+ def self.countPlugins
20
+ @@AvailablePlugins.length
21
+ end
22
+
23
+ def self.plugin(pluginId)
24
+ raise PluginMissingError.new("Couldn't find plugin '#{pluginId}'") unless @@AvailablePlugins.key?(pluginId)
25
+ @@AvailablePlugins[pluginId]
26
+ end
27
+
28
+ def self.leafPlugins
29
+ nonLeaves = Set.new
30
+ @@AvailablePlugins.each do |id, plugin|
31
+ plugin.ancestors.each do |ancestor|
32
+ nonLeaves << ancestor if ancestor != plugin
33
+ end
34
+ end
35
+ @@AvailablePlugins.reject do |id, plugin|
36
+ nonLeaves.include?(plugin)
37
+ end
38
+ end
39
+
40
+ def self.boot(logger, prompt, plugins)
41
+ leafPlugins.each do |id, plugin|
42
+ self.initPlugin(id, logger, prompt, plugins)
43
+ rescue PluginLoadError => error
44
+ logger.warn("Plugin '#{id}' failed to load!\n#{error.message}" + (error.cause ? ' - ' : ''), error.cause)
45
+ end
46
+ true
47
+ end
48
+
49
+ def self.initPlugin(pluginId, logger, prompt, plugins)
50
+ pluginId = pluginId.to_sym
51
+ raise 'Recursive/cyclic plugin' if plugins.key?(pluginId)
52
+ plugins[pluginId] = @@AvailablePlugins[pluginId].new(logger, prompt, plugins)
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'plugins/dns'
4
+ require_relative 'plugins/nginxApp'
5
+ require_relative 'plugins/ssh'
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConfigLMM
4
+ module Framework
5
+ module Registrator
6
+
7
+ @BasePaths = []
8
+
9
+ def self.addPath(basePath)
10
+ @BasePaths << basePath
11
+ end
12
+
13
+ def self.registerAll(logger)
14
+ @BasePaths.each do |basePath|
15
+ self.register(basePath, logger)
16
+ end
17
+ end
18
+
19
+ protected
20
+
21
+ def self.register(basePath, logger)
22
+ Dir.glob(basePath + 'Plugins/**/**.lmm.rb').each do |file|
23
+ require file
24
+ rescue ScriptError => error
25
+ logger.error("Failed to load #{File.realdirpath(file)}\n", error)
26
+ raise error
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConfigLMM
4
+ module Framework
5
+ end
6
+ end
7
+
8
+ require_relative 'Framework/registrator'
9
+ require_relative 'Framework/plugins'
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../Framework/registrator'
4
+
5
+ ConfigLMM::Framework::Registrator.addPath(__dir__ + '/../../../')
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConfigLMM
4
+ module LMM
5
+ end
6
+ end
7
+
8
+ require_relative 'LMM/plugins'
@@ -0,0 +1,161 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'thor'
5
+ require_relative 'LMM'
6
+
7
+ module ConfigLMM
8
+ # Handle the application command line parsing
9
+ # and the dispatch to various command objects
10
+ #
11
+ # @api public
12
+ class CLI < Thor
13
+ ArgumentError = Class.new(RuntimeError)
14
+ MissingArgument = Class.new(ArgumentError)
15
+ InvalidOption = Class.new(ArgumentError)
16
+
17
+ #class_option :locations, type: :string, default: '', group: :configs, desc: 'Filter by config file locations'
18
+ #class_option :things, type: :string, default: '', group: :configs, desc: 'Filter things to use'
19
+ class_option :level, type: :string, enum: ['debug', 'info', 'warn', 'error'], default: 'info', desc: 'Logging level to use'
20
+ class_option :dry, aliases: '-n', type: :boolean, desc: 'Only show actions without performing'
21
+
22
+ desc 'version', 'Show program\'s version'
23
+ def version
24
+ require_relative 'version'
25
+ puts "v" + ConfigLMM::VERSION
26
+ end
27
+ map %w[--version -v] => :version
28
+
29
+
30
+ desc 'list [CONFIGS...]', 'List things'
31
+ method_option :help, aliases: '-h', type: :boolean,
32
+ desc: 'Display usage information'
33
+ def list(*configPaths)
34
+ handleCommand(:list, configPaths, options)
35
+ end
36
+
37
+
38
+ desc 'validate [CONFIGS...]', 'Check whether the configuration is valid'
39
+ method_option :help, aliases: '-h', type: :boolean,
40
+ desc: 'Display usage information'
41
+ def validate(*configPaths)
42
+ handleCommand(:validate, configPaths, options)
43
+ end
44
+
45
+ desc 'refresh [CONFIGS...]', 'Update local state to match deployed things'
46
+ method_option :help, aliases: '-h', type: :boolean,
47
+ desc: 'Display usage information'
48
+ method_option :state, aliases: '-s', type: :string,
49
+ desc: 'Path to the state file'
50
+ method_option :context, aliases: '-c', type: :string,
51
+ desc: 'Path to context file'
52
+ def refresh(*configPaths)
53
+ handleCommand(:refresh, configPaths, options)
54
+ end
55
+
56
+
57
+ desc 'diff [CONFIGS...]', 'Show changes that will be applied with next deploy'
58
+ method_option :help, aliases: '-h', type: :boolean,
59
+ desc: 'Display usage information'
60
+ method_option :state, aliases: '-s', type: :string,
61
+ desc: 'Path to the state file'
62
+ method_option :context, aliases: '-c', type: :string,
63
+ desc: 'Path to context file'
64
+ def diff(*configPaths)
65
+ handleCommand(:diff, configPaths, options)
66
+ end
67
+
68
+
69
+ desc 'build [CONFIGS...]', 'Build configuration in deployable form'
70
+ method_option :help, aliases: '-h', type: :boolean,
71
+ desc: 'Display usage information'
72
+ method_option :context, aliases: '-c', type: :string,
73
+ desc: 'Path to context file'
74
+ method_option :output, aliases: '-o', type: :string,
75
+ default: './build',
76
+ desc: 'Output folder'
77
+ def build(*configPaths)
78
+ handleCommand(:build, configPaths, options)
79
+ end
80
+
81
+
82
+ desc 'deploy [CONFIGS...]', 'Deploy configuration'
83
+ method_option :help, aliases: '-h', type: :boolean,
84
+ desc: 'Display usage information'
85
+ method_option :state, aliases: '-s', type: :string,
86
+ desc: 'Path to the state file'
87
+ method_option :context, aliases: '-c', type: :string,
88
+ desc: 'Path to context file'
89
+ method_option :output, aliases: '-o', type: :string,
90
+ default: '/tmp or ./build',
91
+ desc: 'Output folder'
92
+ def deploy(*configPaths)
93
+ handleCommand(:deploy, configPaths, options)
94
+ end
95
+
96
+
97
+ desc 'cleanup [CONFIGS...]', 'In deployed infrastructure cleanup/delete unused things (eg. deployment leftover junk) (note this can be risky due to mistakes)'
98
+ method_option :help, aliases: '-h', type: :boolean,
99
+ desc: 'Display usage information'
100
+ method_option :state, aliases: '-s', type: :string,
101
+ desc: 'Path to the state file'
102
+ def cleanup(*configPaths)
103
+ handleCommand(:cleanup, configPaths, options)
104
+ end
105
+
106
+ desc 'types', 'List available types/plugins'
107
+ method_option :help, aliases: '-h', type: :boolean,
108
+ desc: 'Display usage information'
109
+ def types
110
+ handleCommand(:types, options)
111
+ end
112
+
113
+ =begin
114
+ # TODO
115
+ desc 'test [CONFIGS...]', 'Test whether deployed things work as expected'
116
+ method_option :help, aliases: '-h', type: :boolean,
117
+ desc: 'Display usage information'
118
+ method_option :load, aliases: '-l', type: :boolean,
119
+ desc: 'Run performance/load tests (might be dangerous as it can affect live users)'
120
+ method_option :chaos, aliases: '-c', type: :boolean,
121
+ desc: 'Test whether systems keep working while random things die (might be dangerous as it can affect live users due to injecting real faults)'
122
+ method_option :alerts, aliases: '-a', type: :boolean,
123
+ desc: 'Test failure conditions and whether alerts work (might be dangerous as it can affect live users due to injecting real faults)'
124
+ method_option :tools, aliases: '-t', type: :string, desc: 'Filter tools to use for testing'
125
+
126
+ def test(*configPaths)
127
+ handleCommand(:test, configPaths, options)
128
+ end
129
+
130
+ desc 'compare [CONFIGS...]', 'Show changes between local state and deployed things'
131
+ method_option :help, aliases: '-h', type: :boolean,
132
+ desc: 'Display usage information'
133
+ method_option :state, aliases: '-s', type: :string,
134
+ desc: 'Path to state file'
135
+ def compare(*configPaths)
136
+ handleCommand(:compare, configPaths, options)
137
+ end
138
+
139
+ =end
140
+
141
+ private
142
+
143
+ def handleCommand(name, *params)
144
+ if options[:help]
145
+ invoke :help, [name.to_s]
146
+ else
147
+ require_relative('commands/' + name.to_s)
148
+ Object.const_get('ConfigLMM::Commands::' + name.to_s.capitalize).new(*params).execute
149
+ end
150
+ rescue ArgumentError => e
151
+ $stderr.puts(e)
152
+ invoke :help, [name.to_s]
153
+ exit 1
154
+ end
155
+
156
+
157
+ def self.exit_on_failure?
158
+ true
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConfigLMM
4
+ class Command
5
+ # Execute this command
6
+ #
7
+ # @api public
8
+ def execute(*)
9
+ raise(NotImplementedError, "#{self.class}##{__method__} must be implemented")
10
+ end
11
+
12
+ # A readable, structured and beautiful logging for the terminal
13
+ #
14
+ # @see http://www.rubydoc.info/gems/tty-logger
15
+ #
16
+ # @api public
17
+ def logger
18
+ if @Logger.nil?
19
+ require 'tty-logger'
20
+ @Logger = TTY::Logger.new do |config|
21
+ yield(config)
22
+ end
23
+ end
24
+ @Logger
25
+ end
26
+
27
+ # The external commands runner
28
+ #
29
+ # @see http://www.rubydoc.info/gems/tty-command
30
+ #
31
+ # @api public
32
+ def command(**options)
33
+ if @Command.nil?
34
+ require 'tty-command'
35
+ @Command = TTY::Command.new(options)
36
+ end
37
+ @Command
38
+ end
39
+
40
+ # The interactive prompt
41
+ #
42
+ # @see http://www.rubydoc.info/gems/tty-prompt
43
+ #
44
+ # @api public
45
+ def prompt
46
+ if @Prompt.nil?
47
+ require 'tty-prompt'
48
+ @Prompt = TTY::Prompt.new
49
+ end
50
+ @Prompt
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'configsCommand'
4
+
5
+ module ConfigLMM
6
+ module Commands
7
+ class Build < ConfigsCommand
8
+ def processConfig(config, options)
9
+
10
+ config.each do |id, target|
11
+
12
+ target['Resources'].to_h.each do |id, target|
13
+ IO::ConfigList.processConfig(id, target, target[:Parent])
14
+ processBuild(IO::ConfigList.normalizeId(id), target, options)
15
+ end
16
+
17
+ processBuild(id, target, options)
18
+ end
19
+ prompt.ok('Build successful, artifacts are in ' + options['output'])
20
+ end
21
+
22
+ def processBuild(id, target, options)
23
+ providers = []
24
+ self.plugins.each do |pluginId, plugin|
25
+ if plugin.hasAction?(target['Type'], :build)
26
+ providers << plugin
27
+ end
28
+ end
29
+
30
+ if providers.empty?
31
+ logger.debug("Skipping ID=#{id} - Type=#{target['Type']}")
32
+ return
33
+ end
34
+
35
+ bestProvider = self.findBestProvider(providers)
36
+ invokeBuildAction(id, bestProvider, target, options)
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'configsCommand'
4
+
5
+ module ConfigLMM
6
+ module Commands
7
+ class Cleanup < ConfigsCommand
8
+
9
+ def processConfig(config, options)
10
+ plugins.each do |pluginId, plugin|
11
+ configs = {}
12
+ loadConfigs(plugin, config, configs)
13
+ plugin.cleanup(configs, state, context, options)
14
+ end
15
+ prompt.ok('Cleanup successful!')
16
+ end
17
+
18
+ def loadConfigs(plugin, config, configs)
19
+ config.each do |id, target|
20
+ loadConfigs(plugin, target['Resources'], configs) if target['Resources']
21
+ if plugin.hasAction?(target['Type'], :deploy)
22
+ configs[id] = target
23
+ end
24
+ end
25
+ configs
26
+ end
27
+
28
+ end
29
+ end
30
+ end