minfra-cli 1.13.3 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +1 -2
- data/.rubocop.yml +31 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile.lock +1 -1
- data/README.md +13 -1
- data/exe/minfra +1 -3
- data/lib/deep_merge.rb +35 -36
- data/lib/hash.rb +19 -18
- data/lib/minfra/cli/ask.rb +18 -16
- data/lib/minfra/cli/cli_starter.rb +173 -0
- data/lib/minfra/cli/command.rb +4 -1
- data/lib/minfra/cli/commands/dev.rb +26 -15
- data/lib/minfra/cli/commands/kube.rb +97 -88
- data/lib/minfra/cli/commands/plugin.rb +9 -8
- data/lib/minfra/cli/commands/project/branch.rb +7 -5
- data/lib/minfra/cli/commands/project/tag.rb +7 -6
- data/lib/minfra/cli/commands/project.rb +40 -40
- data/lib/minfra/cli/commands/setup.rb +18 -18
- data/lib/minfra/cli/commands/stack/app_template.rb +10 -13
- data/lib/minfra/cli/commands/stack/client_template.rb +10 -8
- data/lib/minfra/cli/commands/stack/kube_stack_template.rb +49 -51
- data/lib/minfra/cli/commands/stack.rb +55 -46
- data/lib/minfra/cli/commands/tag.rb +9 -8
- data/lib/minfra/cli/common.rb +7 -10
- data/lib/minfra/cli/config.rb +36 -63
- data/lib/minfra/cli/core_ext.rb +7 -0
- data/lib/minfra/cli/document.rb +5 -2
- data/lib/minfra/cli/env.rb +24 -0
- data/lib/minfra/cli/errors.rb +10 -0
- data/lib/minfra/cli/helm_runner.rb +3 -1
- data/lib/minfra/cli/hiera_looker.rb +54 -0
- data/lib/minfra/cli/hook.rb +36 -24
- data/lib/minfra/cli/kubectl_runner.rb +3 -1
- data/lib/minfra/cli/logging.rb +5 -1
- data/lib/minfra/cli/main_command.rb +2 -1
- data/lib/minfra/cli/plugin.rb +74 -0
- data/lib/minfra/cli/plugins.rb +18 -87
- data/lib/minfra/cli/runner.rb +23 -23
- data/lib/minfra/cli/templater.rb +17 -17
- data/lib/minfra/cli/version.rb +3 -1
- data/lib/minfra/cli.rb +20 -114
- data/lib/orchparty/ast.rb +13 -14
- data/lib/orchparty/cli.rb +35 -33
- data/lib/orchparty/context.rb +15 -15
- data/lib/orchparty/dsl_parser.rb +7 -11
- data/lib/orchparty/dsl_parser_kubernetes.rb +46 -56
- data/lib/orchparty/plugin.rb +10 -9
- data/lib/orchparty/plugins/env.rb +14 -13
- data/lib/orchparty/transformations/all.rb +3 -1
- data/lib/orchparty/transformations/mixin.rb +24 -24
- data/lib/orchparty/transformations/remove_internal.rb +3 -2
- data/lib/orchparty/transformations/sort.rb +2 -1
- data/lib/orchparty/transformations/variable.rb +6 -5
- data/lib/orchparty/transformations.rb +2 -0
- data/lib/orchparty/version.rb +3 -1
- data/lib/orchparty.rb +14 -14
- metadata +9 -2
data/lib/minfra/cli.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'thor'
|
2
4
|
require 'open3'
|
3
5
|
require 'json'
|
4
6
|
require 'ostruct'
|
5
7
|
require 'hiera'
|
6
8
|
|
9
|
+
require_relative 'cli/core_ext'
|
10
|
+
require_relative 'cli/errors'
|
7
11
|
require_relative 'cli/logging'
|
8
12
|
require_relative 'cli/templater'
|
9
13
|
|
@@ -19,137 +23,39 @@ require_relative 'cli/runner'
|
|
19
23
|
require_relative 'cli/helm_runner'
|
20
24
|
require_relative 'cli/kubectl_runner'
|
21
25
|
require_relative 'cli/plugins'
|
26
|
+
require_relative 'cli/plugin'
|
27
|
+
require_relative 'cli/hiera_looker'
|
28
|
+
require_relative 'cli/env'
|
29
|
+
require_relative 'cli/cli_starter'
|
22
30
|
|
23
31
|
require 'active_support'
|
24
32
|
require 'active_support/core_ext'
|
25
33
|
|
26
|
-
require "#{ENV
|
34
|
+
require "#{ENV.fetch('MINFRA_PATH', nil)}/config/preload.rb" if File.exist?("#{ENV.fetch('MINFRA_PATH', nil)}/config/preload.rb")
|
27
35
|
|
28
36
|
module Minfra
|
29
37
|
module Cli
|
30
|
-
|
31
38
|
extend Minfra::Cli::Logging
|
32
39
|
include Minfra::Cli::Hook
|
33
40
|
|
34
|
-
|
35
|
-
@logger
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.init(argv)
|
39
|
-
@argv = argv
|
40
|
-
# we'll set the context very early!
|
41
|
-
|
42
|
-
if idx=@argv.index("-e")
|
43
|
-
@config = Config.load(@argv[idx+1])
|
44
|
-
@argv.delete_at(idx)
|
45
|
-
@argv.delete_at(idx)
|
46
|
-
else
|
47
|
-
@config = Config.load('dev')
|
48
|
-
end
|
49
|
-
|
50
|
-
@logger=Logger.new(STDERR)
|
51
|
-
logger.level=ENV["MINFRA_LOGGING_LEVEL"] || @config.project.minfra.logging_level || 'warn'
|
52
|
-
|
53
|
-
project_minfrarc_path = @config.base_path.join("config",'minfrarc.rb')
|
54
|
-
require project_minfrarc_path if project_minfrarc_path.exist?
|
55
|
-
me_minfrarc_path = @config.me_path.join('minfrarc.rb')
|
56
|
-
require @me_minfrarc_path if me_minfrarc_path.exist?
|
57
|
-
|
58
|
-
@logger.debug("Minfra: loglevel: #{@logger.level}, env: #{@config.orch_env}")
|
59
|
-
|
60
|
-
hiera_init
|
61
|
-
|
62
|
-
@plugins = Minfra::Cli::Plugins.load
|
63
|
-
@plugins.prepare
|
64
|
-
|
65
|
-
Minfra::Cli.scan
|
66
|
-
require_relative 'cli/main_command'
|
67
|
-
Minfra::Cli.resolve
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.run
|
74
|
-
Minfra::Cli::Main.start(@argv)
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.root_path
|
78
|
-
Pathname.new(File.expand_path(File.join(__FILE__, '../../../')))
|
79
|
-
end
|
80
|
-
|
81
|
-
def self.hiera_init
|
82
|
-
@hiera_root = Pathname.new("#{ENV["MINFRA_PATH"]}/hiera")
|
83
|
-
hiera = Hiera.new(:config => @hiera_root.join('hiera.yaml').to_s)
|
84
|
-
Hiera.logger=:noop
|
85
|
-
env= @config.orch_env
|
86
|
-
hiera_main_path=@hiera_root.join("hieradata/#{config.project.minfra.hiera.env_path}/#{env}.eyaml")
|
87
|
-
raise("unknown environment #{env}, I expact a file at #{hiera_main_path}") unless hiera_main_path.exist?
|
88
|
-
|
89
|
-
scope={ "minfra_path" => ENV["MINFRA_PATH"], "hieraroot" => @hiera_root.to_s, "env" => env}
|
90
|
-
special_lookups=hiera.lookup("lookup_options", {}, scope, nil, :priority)
|
91
|
-
|
92
|
-
node_scope=hiera.lookup("env", {}, scope, nil, :deeper)
|
93
|
-
scope=scope.merge(node_scope)
|
94
|
-
cache={}
|
95
|
-
Kernel.define_method(:l) do |value,default=nil|
|
96
|
-
|
97
|
-
return cache[value] if cache.has_key?(value)
|
98
|
-
|
99
|
-
values=value.split(".")
|
100
|
-
fst_value=values.shift
|
41
|
+
cattr_accessor :logger, :config, :subcommands,:cli
|
101
42
|
|
102
|
-
|
103
|
-
|
104
|
-
else
|
105
|
-
lookup_type=:deep
|
106
|
-
end
|
107
|
-
|
108
|
-
result=hiera.lookup(fst_value, default, scope, nil, lookup_type)
|
109
|
-
if !values.empty? && result.kind_of?(Hash) # we return nil or the scalar value and only drill down on hashes
|
110
|
-
result=result.dig(*values)
|
111
|
-
end
|
112
|
-
|
113
|
-
result=Hashie::Mash.new(result) if result.kind_of?(Hash)
|
114
|
-
cache[value] = result
|
115
|
-
result
|
116
|
-
end
|
117
|
-
Kernel.define_method(:l!) do |value,default=nil|
|
118
|
-
v=l(value,default)
|
119
|
-
raise("Value not found! #{value}") if v.nil?
|
120
|
-
v
|
121
|
-
end
|
43
|
+
def self.init?
|
44
|
+
!!cli
|
122
45
|
end
|
123
46
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
end
|
128
|
-
|
129
|
-
def self.scan
|
130
|
-
#loading built in commands
|
131
|
-
root_path.join("lib/minfra/cli/commands").each_child do |command_path|
|
132
|
-
require command_path if command_path.to_s.match(/\.rb$/) && !command_path.to_s.match(/\#/)
|
133
|
-
end
|
134
|
-
@plugins.setup
|
135
|
-
end
|
136
|
-
|
137
|
-
def self.plugins
|
138
|
-
@plugins
|
47
|
+
def self.init(argv = [])
|
48
|
+
self.subcommands ||= {}
|
49
|
+
self.cli = CliStarter.new(argv)
|
139
50
|
end
|
140
51
|
|
141
|
-
def self.
|
142
|
-
|
143
|
-
|
144
|
-
@subcommands[subcommand.to_sym]= OpenStruct.new(name: subcommand, info: info, command: command)
|
52
|
+
def self.exec(argv)
|
53
|
+
init(argv) unless init?
|
54
|
+
cli.run
|
145
55
|
end
|
146
56
|
|
147
|
-
def self.
|
148
|
-
|
149
|
-
Minfra::Cli::Main.desc(sub.name,sub.info)
|
150
|
-
Minfra::Cli::Main.subcommand(sub.name,sub.command)
|
151
|
-
end
|
57
|
+
def self.register(subcommand, info, command)
|
58
|
+
self.subcommands[subcommand.to_sym] = OpenStruct.new(name: subcommand, info:, command:)
|
152
59
|
end
|
153
|
-
|
154
60
|
end
|
155
61
|
end
|
data/lib/orchparty/ast.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'hashie'
|
2
4
|
|
3
5
|
module Orchparty
|
@@ -13,14 +15,12 @@ module Orchparty
|
|
13
15
|
binding
|
14
16
|
end
|
15
17
|
|
16
|
-
def inspect(indent=0)
|
17
|
-
start="\n"
|
18
|
+
def inspect(indent = 0)
|
19
|
+
start = "\n"
|
18
20
|
each_pair do |name, ast|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
start << "#{' ' * indent}#{name}: #{ast.inspect}\n"
|
23
|
-
end
|
21
|
+
start << "#{' ' * indent}#{name}: #{ast.inspect(indent + 1)}\n"
|
22
|
+
rescue ArgumentError
|
23
|
+
start << "#{' ' * indent}#{name}: #{ast.inspect}\n"
|
24
24
|
end
|
25
25
|
start
|
26
26
|
end
|
@@ -39,28 +39,27 @@ module Orchparty
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def self.mixin(args = {})
|
42
|
-
Node.new({services: {}, _mixins: {}, volumes: {}, _variables: {}, networks: {}, _service_order: []}).merge(args)
|
42
|
+
Node.new({ services: {}, _mixins: {}, volumes: {}, _variables: {}, networks: {}, _service_order: [] }).merge(args)
|
43
43
|
end
|
44
44
|
|
45
45
|
def self.application(args = {})
|
46
|
-
Node.new({services: {}, _mixins: {}, _mix:[], volumes: {}, _variables: {}, networks: {}, _service_order: []}).merge(args)
|
46
|
+
Node.new({ services: {}, _mixins: {}, _mix: [], volumes: {}, _variables: {}, networks: {}, _service_order: [] }).merge(args)
|
47
47
|
end
|
48
48
|
|
49
49
|
def self.all(args = {})
|
50
|
-
Node.new(_mix:[], _variables: {}).merge(args)
|
50
|
+
Node.new(_mix: [], _variables: {}).merge(args)
|
51
51
|
end
|
52
52
|
|
53
53
|
def self.application_mixin(args = {})
|
54
|
-
Node.new(_mix:[], _variables: {}).merge(args)
|
54
|
+
Node.new(_mix: [], _variables: {}).merge(args)
|
55
55
|
end
|
56
56
|
|
57
57
|
def self.service(args = {})
|
58
|
-
Node.new(_mix:[], _variables: {}).merge(args)
|
58
|
+
Node.new(_mix: [], _variables: {}).merge(args)
|
59
59
|
end
|
60
60
|
|
61
61
|
def self.chart(args = {})
|
62
|
-
Node.new(_mix:[], _variables: {}, _services: []).merge(args)
|
62
|
+
Node.new(_mix: [], _variables: {}, _services: []).merge(args)
|
63
63
|
end
|
64
|
-
|
65
64
|
end
|
66
65
|
end
|
data/lib/orchparty/cli.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'orchparty'
|
2
4
|
require 'gli'
|
3
5
|
|
@@ -11,57 +13,57 @@ class OrchPartyApp
|
|
11
13
|
|
12
14
|
subcommand_option_handling :normal
|
13
15
|
|
14
|
-
desc
|
16
|
+
desc 'install kubernetes application'
|
15
17
|
command :print do |com|
|
16
|
-
com.flag [:cluster_name
|
17
|
-
com.flag [:filename
|
18
|
-
com.flag [
|
19
|
-
com.switch :
|
20
|
-
com.flag [
|
18
|
+
com.flag [:cluster_name, :c, 'cluster-name'], required: true, desc: 'The cluster to install the app'
|
19
|
+
com.flag [:filename, :f, 'file-name'], required: true, desc: 'The Orchparty input file'
|
20
|
+
com.flag %i[application a], required: true, desc: 'The application that should be installed'
|
21
|
+
com.switch :'force-variable-definition', default_value: false, desc: 'Raises an Error if the input contains a not defined variable'
|
22
|
+
com.flag %i[method m], required: true, desc: 'method to print upgrade/install'
|
21
23
|
com.action do |_, args|
|
22
|
-
Orchparty.print(cluster_name: args[:c], application_name: args[:a], force_variable_definition: args[
|
24
|
+
Orchparty.print(cluster_name: args[:c], application_name: args[:a], force_variable_definition: args['force-variable-definition'], file_name: args[:f], method: args[:m])
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
26
|
-
desc
|
28
|
+
desc 'install kubernetes application'
|
27
29
|
command :install do |com|
|
28
|
-
com.flag [:cluster_name
|
29
|
-
com.flag [:filename
|
30
|
-
com.flag [
|
31
|
-
com.switch :
|
30
|
+
com.flag [:cluster_name, :c, 'cluster-name'], required: true, desc: 'The cluster to install the app'
|
31
|
+
com.flag [:filename, :f, 'file-name'], required: true, desc: 'The Orchparty input file'
|
32
|
+
com.flag %i[application a], required: true, desc: 'The application that should be installed'
|
33
|
+
com.switch :'force-variable-definition', default_value: false, desc: 'Raises an Error if the input contains a not defined variable'
|
32
34
|
com.action do |_, args|
|
33
|
-
Orchparty.install(cluster_name: args[:c], application_name: args[:a], force_variable_definition: args[
|
35
|
+
Orchparty.install(cluster_name: args[:c], application_name: args[:a], force_variable_definition: args['force-variable-definition'], file_name: args[:f])
|
34
36
|
end
|
35
37
|
end
|
36
38
|
|
37
|
-
desc
|
39
|
+
desc 'upgrade kubernetes application'
|
38
40
|
command :upgrade do |com|
|
39
|
-
com.flag [:cluster_name
|
40
|
-
com.flag [:filename
|
41
|
-
com.flag [
|
42
|
-
com.switch :
|
41
|
+
com.flag [:cluster_name, :c, 'cluster-name'], required: true, desc: 'The cluster to install the app'
|
42
|
+
com.flag [:filename, :f, 'file-name'], required: true, desc: 'The Orchparty input file'
|
43
|
+
com.flag %i[application a], required: true, desc: 'The application that should be installed'
|
44
|
+
com.switch :'force-variable-definition', default_value: false, desc: 'Raises an Error if the input contains a not defined variable'
|
43
45
|
com.action do |_, args|
|
44
|
-
Orchparty.upgrade(cluster_name: args[:c], application_name: args[:a], force_variable_definition: args[
|
46
|
+
Orchparty.upgrade(cluster_name: args[:c], application_name: args[:a], force_variable_definition: args['force-variable-definition'], file_name: args[:f])
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
48
|
-
desc
|
50
|
+
desc 'Compiles a Orchparty input file to a orchestration framework configuration'
|
49
51
|
command :generate do |com|
|
50
52
|
Orchparty.plugins.each do |name, plugin|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
53
|
+
com.desc plugin.desc
|
54
|
+
com.command(name) do |plugin_command|
|
55
|
+
plugin_command.flag [:filename, :f, 'file-name'], required: true, desc: 'The Orchparty input file'
|
56
|
+
plugin_command.flag %i[application a], required: true, desc: 'The application that should be compiled'
|
57
|
+
plugin_command.switch :'force-variable-definition', default_value: false, desc: 'Raises an Error if the input contains a not defined variable'
|
58
|
+
plugin.define_flags(plugin_command)
|
59
|
+
plugin_command.action do |_global_options, plugin_options, _args|
|
60
|
+
options = plugin_options.delete(GLI::Command::PARENT)
|
61
|
+
options[:application] = plugin_options[:application]
|
62
|
+
options[:filename] = plugin_options[:filename]
|
63
|
+
options[:force_variable_definition] = plugin_options[:'force-variable-definition']
|
64
|
+
Orchparty.generate(name, options, plugin_options)
|
64
65
|
end
|
66
|
+
end
|
65
67
|
end
|
66
68
|
end
|
67
69
|
end
|
data/lib/orchparty/context.rb
CHANGED
@@ -1,22 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Orchparty
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
class Context < ::Hashie::Mash
|
5
|
+
include Hashie::Extensions::DeepMerge
|
6
|
+
include Hashie::Extensions::DeepMergeConcat
|
7
|
+
include Hashie::Extensions::MethodAccess
|
8
|
+
include Hashie::Extensions::Mash::KeepOriginalKeys
|
7
9
|
|
10
|
+
def method_missing(name, *args)
|
11
|
+
raise "#{name} not declared for #{application.name}.#{service.name}" if @_force_variable_definition && !key?(name) && !key?(name.to_s)
|
8
12
|
|
9
|
-
|
10
|
-
|
11
|
-
super
|
12
|
-
end
|
13
|
+
super
|
14
|
+
end
|
13
15
|
|
14
|
-
|
15
|
-
@_force_variable_definition = v
|
16
|
-
end
|
16
|
+
attr_writer :_force_variable_definition
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
end
|
18
|
+
def context
|
19
|
+
self
|
21
20
|
end
|
21
|
+
end
|
22
22
|
end
|
data/lib/orchparty/dsl_parser.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'pathname'
|
2
4
|
module Orchparty
|
3
5
|
class DSLParser
|
@@ -17,7 +19,7 @@ module Orchparty
|
|
17
19
|
|
18
20
|
class Builder
|
19
21
|
def self.build(*args, block)
|
20
|
-
builder =
|
22
|
+
builder = new(*args)
|
21
23
|
builder.instance_eval(&block)
|
22
24
|
builder._build
|
23
25
|
end
|
@@ -35,7 +37,6 @@ module Orchparty
|
|
35
37
|
end
|
36
38
|
|
37
39
|
class RootBuilder < Builder
|
38
|
-
|
39
40
|
def initialize
|
40
41
|
@root = AST.root
|
41
42
|
end
|
@@ -64,9 +65,8 @@ module Orchparty
|
|
64
65
|
end
|
65
66
|
|
66
67
|
class MixinBuilder < Builder
|
67
|
-
|
68
68
|
def initialize(name)
|
69
|
-
@mixin = AST.mixin(name:
|
69
|
+
@mixin = AST.mixin(name:)
|
70
70
|
end
|
71
71
|
|
72
72
|
def service(name, &block)
|
@@ -99,9 +99,8 @@ module Orchparty
|
|
99
99
|
end
|
100
100
|
|
101
101
|
class ApplicationBuilder < Builder
|
102
|
-
|
103
102
|
def initialize(name)
|
104
|
-
@application = AST.application(name:
|
103
|
+
@application = AST.application(name:)
|
105
104
|
end
|
106
105
|
|
107
106
|
def mix(name)
|
@@ -143,7 +142,6 @@ module Orchparty
|
|
143
142
|
end
|
144
143
|
|
145
144
|
class HashBuilder < Builder
|
146
|
-
|
147
145
|
def method_missing(_, *values, &block)
|
148
146
|
if block_given?
|
149
147
|
value = HashBuilder.build(block)
|
@@ -180,7 +178,6 @@ module Orchparty
|
|
180
178
|
end
|
181
179
|
|
182
180
|
class CommonBuilder < Builder
|
183
|
-
|
184
181
|
def initialize(node)
|
185
182
|
@node = node
|
186
183
|
end
|
@@ -191,7 +188,7 @@ module Orchparty
|
|
191
188
|
|
192
189
|
def method_missing(name, *values, &block)
|
193
190
|
if block_given?
|
194
|
-
assign_or_merge(@node, name,
|
191
|
+
assign_or_merge(@node, name, HashBuilder.build(block))
|
195
192
|
else
|
196
193
|
assign_or_merge(@node, name, values.first)
|
197
194
|
end
|
@@ -221,9 +218,8 @@ module Orchparty
|
|
221
218
|
end
|
222
219
|
|
223
220
|
class ServiceBuilder < CommonBuilder
|
224
|
-
|
225
221
|
def initialize(name)
|
226
|
-
super AST.service(name:
|
222
|
+
super AST.service(name:)
|
227
223
|
end
|
228
224
|
end
|
229
225
|
end
|