minfra-cli 1.13.2 → 2.0.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 +4 -4
- data/.github/workflows/ruby.yml +1 -2
- data/.rubocop.yml +31 -0
- data/CHANGELOG.md +18 -1
- 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/kubernetes_application.rb +2 -2
- 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
|