minfra-cli 2.0.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 424233e63c75e0e9b9d65bd7dba78a3f3d2132c547f3cf37b7acb3fdb66784c5
4
- data.tar.gz: 0ad7e2960fff01802a047e33e955d0b77e8cf3284c4033a18111ccde42175aec
3
+ metadata.gz: 20d6ef8704c3f8f61e70deebd60afc9663a9df46e2741f03a30eb9f5020fe2e0
4
+ data.tar.gz: b173a73d17868a0b8f13ce11cdefc0e997aa50af7bb07c0448946fa121d9275d
5
5
  SHA512:
6
- metadata.gz: c689a675040c603ef5acf7f04a6c147212d40749652536599dee68fe0bd078c3e79b4e3f41aec92c2850f5106c72ccee79ad5f9d31e509a7498f8d1bdf4f5644
7
- data.tar.gz: 93816f96aab379a0bf972808359e7298ae55afea97f204683d07878cb1937689dd2054d3ff3aba5bd3d1a4d49796bf32dc164e8692e3a37f765047331de6d094
6
+ metadata.gz: 5725dd5eed53295676e895f14bf84a3d729fa82664b5578dde1540f47455b1050e236d9321291185ed935e14a1a9de3b691e82b8ce83db9c0f7b19419877cab4
7
+ data.tar.gz: 6b92c6757e2d0ccfaefe8d6847c55c77800159e820ff7f41f54c4d3bff9801118b566febed21be9f92bcfd4cd9a443dcb29f09487e8a7366d0273a92858be337
data/.gitignore CHANGED
@@ -14,5 +14,6 @@ vendor
14
14
  spec/docker-compose.run.yml
15
15
 
16
16
  minfra-cli-*.gem
17
+ Gemfile.lock
17
18
 
18
19
  .rspec
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ # 2.2.0
2
+ * fixing: should not modify l('env.roles')
3
+ * cleanup: removing template testing --debug flag, causing noise
4
+ * cleanup: removing Documentation hooks
5
+ * fixing: hiera lookup retrying on gpg memory error exceptions
6
+ *
7
+ # 2.1.0
8
+ * add :all hook
9
+ * fixing setup dev
10
+ * colored errors
11
+ * wrapping hiera lookup errors of gpg
12
+ * adding HIERA_DEBUG_LOOKUPS=true
1
13
  # 2.0.1
2
14
  Refactorings
3
15
  * installing into Kernel only when 'exec' not at 'init' time
@@ -17,7 +29,7 @@
17
29
  * new Kernel method: minfra_cli which is the CliStarter Object
18
30
 
19
31
  # 1.13.3
20
- * BUG: fixing 'labelÄ
32
+ * BUG: fixing 'label'
21
33
  # 1.13.2
22
34
  * BUG: fixing 'generic_secret'
23
35
  # 1.13.1
data/README.md CHANGED
@@ -14,7 +14,9 @@ Is a KIND (k8s in docker) based development environment.
14
14
  | | MINFRA_ARGV_FILE | | --minfra_argv_file [PATH TO A CSV FILE FILE] | |
15
15
  | | MINFRA_LOGGING_LEVEL | minfra.logging_level | | |
16
16
  | | | minfra.hiera.env_path | | |
17
- | | | default_stacks | | env.stacks | env.roles |
17
+ | | | default_stacks | | env.stacks or env.roles |
18
+ | | | | | infra::allow_insecure_k8s_connections |
19
+ | when set to 'true' all hiera lookups are logged on debug level | MINFRA_DEBUG_HIERA_LOOKUPS | | | |
18
20
 
19
21
 
20
22
  ## Expected hiera data
@@ -18,6 +18,7 @@ module Minfra
18
18
  end
19
19
 
20
20
  def self.text(question, default = nil)
21
+ answer = nil
21
22
  loop do
22
23
  message = format('%s%s: ', question, default && " (#{default})")
23
24
  $stdout.write message
@@ -31,6 +31,7 @@ module Minfra
31
31
 
32
32
  init_minfrarc
33
33
  init_envs
34
+
34
35
  init_hiera
35
36
  init_plugins
36
37
 
@@ -140,7 +141,7 @@ module Minfra
140
141
  end
141
142
 
142
143
  def init_hiera
143
- @hiera = @env.hiera
144
+ @hiera = @env.hiera
144
145
  end
145
146
 
146
147
  def init_envs
@@ -149,7 +150,7 @@ module Minfra
149
150
  root = base_path.join('hiera')
150
151
  root.join('hieradata',env_path).glob('*.eyaml').sort.each do |path|
151
152
  env_name = path.basename.sub(/(\..+)/,'').to_s
152
- @envs[env_name]=Env.new(hiera_root: root, hiera_env_path: env_path, name: env_name)
153
+ @envs[env_name]=Env.new(hiera_root: root, hiera_env_path: env_path, name: env_name, hiera_debug_lookups: ENV['MINFRA_DEBUG_HIERA_LOOKUPS'] == 'true')
153
154
  end
154
155
  @env = @envs[@env_name] # set the current env
155
156
  end
@@ -101,7 +101,7 @@ module Minfra
101
101
  run(%(docker network rm #{kind_name}), exit_on_error: false)
102
102
  end
103
103
 
104
- def deploy(stack_name, reason_message)
104
+ def deploy(stack_name, _reason_message)
105
105
  # TBD: options is global, avoid it!
106
106
 
107
107
  test = options[:test]
@@ -145,8 +145,6 @@ module Minfra
145
145
 
146
146
  exit_error('Deployment aborted!') if !(@config.dev? || options[:force] == true) && !Ask.boolean('Are the changes ok?')
147
147
 
148
- message = "deploying stack #{stack.name}: #{reason_message}."
149
- Minfra::Cli::Document.document(@config, "started #{message}")
150
148
  orch = Orchparty::App.new(cluster_name: cluster,
151
149
  application_name: stack.name,
152
150
  force_variable_definition: false,
@@ -154,7 +152,6 @@ module Minfra
154
152
  status_dir: stack.release_path,
155
153
  options:)
156
154
  orch.send(method)
157
- Minfra::Cli::Document.document(@config, "finished #{message}")
158
155
  end
159
156
 
160
157
  def rollback(stack_name, env, deployment, cluster)
@@ -47,9 +47,7 @@ module Minfra
47
47
  ARGV.delete('test')
48
48
 
49
49
  if File.exist?('./bin/run_tests')
50
- # config = Config.load('staging')
51
50
  project = ProjectInfo.load(Pathname.pwd)
52
- # Minfra::Cli::Document.document(config, "Using project specific ./bin/run_tests in #{project.name}")
53
51
  debug "Using project specific ./bin/run_tests in #{project.name}"
54
52
  system('./bin/run_tests', out: $stdout, err: :out)
55
53
  else
@@ -18,8 +18,6 @@ module Minfra
18
18
  def setup_config
19
19
  config = Minfra::Cli.config
20
20
  ensure_path_and_template(config.config_path, config.base_path.join('config', 'me_config.json.erb'))
21
- config.init!
22
- config.load('dev')
23
21
  end
24
22
 
25
23
  def ensure_path_and_template(dest_path, template_path, params = {})
@@ -35,7 +35,7 @@ module Minfra
35
35
  def deploy(stack_name, message = '')
36
36
  stacks = l('env.roles') || l('env.stacks') || []
37
37
  default_stacks = minfra_config.project.default_stacks || []
38
- stacks = stacks.concat(default_stacks)
38
+ stacks = stacks + default_stacks
39
39
  if stacks.include?(stack_name) || options[:force] || options[:test]
40
40
  kube.deploy(stack_name, message)
41
41
  else
@@ -25,14 +25,6 @@ module Minfra
25
25
  end
26
26
  end
27
27
 
28
- def parse_cmd(cmd, silence: false)
29
- reply = JSON.parse(run_cmd(cmd, silence:))
30
- rescue JSON::ParserError, TypeError
31
- error "ERROR: #{$ERROR_INFO.message}"
32
- error reply
33
- error "command was: #{cmd}"
34
- exit 1
35
- end
36
28
  end
37
29
  end
38
30
  end
@@ -2,12 +2,13 @@ module Minfra
2
2
  module Cli
3
3
  class Env
4
4
  attr_reader :name, :hiera
5
- def initialize(name:, hiera_root:, hiera_env_path:)
5
+ def initialize(name:, hiera_root:, hiera_env_path:, hiera_debug_lookups: )
6
6
  @name = name
7
7
  @hiera = HieraLooker.new(
8
8
  root: hiera_root,
9
9
  env_name: name,
10
- env_path: hiera_env_path
10
+ env_path: hiera_env_path,
11
+ debug_lookups: hiera_debug_lookups
11
12
  )
12
13
  end
13
14
 
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'English'
3
4
  module Minfra
4
5
  module Cli
5
6
  class HieraLooker
6
- def initialize(root:, env_name:, env_path:)
7
+ include Logging
8
+ def initialize(root:, env_name:, env_path:, debug_lookups: false)
7
9
  @root = Pathname.new(root)
8
10
  @env_name = env_name
9
11
  @cache = {}
@@ -18,13 +20,15 @@ module Minfra
18
20
  scope = { 'hieraroot' => @root.to_s, 'env' => @env_name }
19
21
 
20
22
  @special_lookups = @hiera.lookup('lookup_options', {}, scope, nil, :priority)
21
-
23
+
22
24
  node_scope = @hiera.lookup('env', {}, scope, nil, :deeper)
23
25
  @scope = scope.merge(node_scope)
26
+ @debug_lookups = debug_lookups
24
27
  end
25
28
 
26
29
  def l(value, default = nil)
27
- # debugger if @env_name == 'production-management' && value == 'env.tags'
30
+ debug "hiera: #{value}" if @debug_lookups
31
+ # debugger if @env_name == 'production-management' && value == 'env.tags'
28
32
  return @cache[value] if @cache.key?(value)
29
33
 
30
34
  values = value.split('.')
@@ -35,7 +39,23 @@ module Minfra
35
39
  else
36
40
  :deep
37
41
  end
38
- result = @hiera.lookup(fst_value, default, @scope, nil, lookup_type)
42
+ retry_attempts = 0
43
+ begin
44
+ result = @hiera.lookup(fst_value, default, @scope, nil, lookup_type)
45
+ rescue GPGME::Error::NoSecretKey
46
+ error("Have no gpg configuration to decrypt your hiera key: #{value}")
47
+ raise Errors::ExitError
48
+ rescue GPGME::Error::BadPassphrase
49
+ error("Your password was wrong for hiera key: #{value}")
50
+ raise Errors::ExitError
51
+ rescue GPGME::Error
52
+ error("Having decrypt problems for hiera key: #{value}, #{$ERROR_INFO.message}")
53
+ raise Errors::ExitError
54
+ rescue Errno::ENOMEM # see https://github.com/ueno/ruby-gpgme/issues/147
55
+ retry_attempts += 1
56
+ sleep 1
57
+ retry if retry_attempts < 5
58
+ end
39
59
  result = result.dig(*values) if !values.empty? && result.is_a?(Hash) # we return nil or the scalar value and only drill down on hashes
40
60
  result = default if result.nil?
41
61
  result = Hashie::Mash.new(result) if result.is_a?(Hash)
@@ -46,9 +66,9 @@ module Minfra
46
66
  def l!(value, default = nil)
47
67
  v = l(value, default)
48
68
  raise("Value not found! #{value}") if v.nil?
69
+
49
70
  v
50
71
  end
51
-
52
72
  end
53
73
  end
54
74
  end
@@ -12,9 +12,12 @@ class Thor
12
12
  elsif public_method?(instance)
13
13
  hooks = instance.instance_variable_get(:@_invocations).values.flatten
14
14
  arity = instance.method(name).arity
15
+ Minfra::Cli.call_before_hooks(instance, ['all']) if hooks.size == 1
15
16
  Minfra::Cli.call_before_hooks(instance, hooks)
17
+ # debugger
16
18
  instance.__send__(name, *args)
17
19
  Minfra::Cli.call_after_hooks(instance, hooks)
20
+ Minfra::Cli.call_after_hooks(instance, ['all']) if hooks.size == 1
18
21
  elsif local_method?(instance, :method_missing)
19
22
  # Minfra::Cli.call_before_hooks(instance,hooks)
20
23
  instance.__send__(:method_missing, name.to_sym, *args)
@@ -77,6 +80,7 @@ module Minfra
77
80
  end
78
81
 
79
82
  def call_after_hooks(obj, names)
83
+ # debug("Checking after hook #{names}")
80
84
  @hooks.select { |h| h.match?(:after, names) }.each do |h|
81
85
  debug("Hook after: #{names.join(',')}")
82
86
  h.exec(obj)
@@ -4,7 +4,7 @@ module Minfra
4
4
  module Cli
5
5
  module Logging
6
6
  def error(str)
7
- logger.error str
7
+ logger.error(colored(str, :red))
8
8
  end
9
9
 
10
10
  def exit_error(str)
@@ -17,11 +17,11 @@ module Minfra
17
17
  end
18
18
 
19
19
  def warn(str)
20
- logger.warn str
20
+ logger.warn(colored(str, :yellow))
21
21
  end
22
22
 
23
23
  def debug(str)
24
- logger.debug str
24
+ logger.debug(str)
25
25
  end
26
26
 
27
27
  def deprecated(comment)
@@ -33,6 +33,14 @@ module Minfra
33
33
  def logger
34
34
  Minfra::Cli.logger
35
35
  end
36
+ LOGGING_COLORS={ red: '1;31;40', green: '1;32;40' , dark_green: '0;32;40' , yellow: '1;33;40' }
37
+ def colored(str, color)
38
+ if $stdout.isatty
39
+ "\e[#{LOGGING_COLORS[color] || LOGGING_COLORS[:color1]}m#{str}\e[0m"
40
+ else
41
+ str
42
+ end
43
+ end
36
44
  end
37
45
  end
38
46
  end
@@ -13,14 +13,16 @@ module Minfra
13
13
 
14
14
  attr_reader :stdout_lines
15
15
 
16
- def initialize
16
+ def initialize(on_output: nil)
17
17
  @stderr_lines = []
18
18
  @stdout_lines = []
19
19
  @status = nil
20
+ @on_output = on_output
20
21
  end
21
22
 
22
23
  def add(line, stream = :stdout)
23
24
  line.chomp!
25
+ @on_output.call(line, stream) if @on_output
24
26
  if stream == :stdout
25
27
  @stdout_lines << line
26
28
  debug line
@@ -60,23 +62,25 @@ module Minfra
60
62
  new(cmd, **args).run
61
63
  end
62
64
 
63
- attr_reader :exit_on_error, :runner, :cmd
65
+ attr_reader :exit_on_error, :runner, :cmd, :on_output
64
66
 
65
- def initialize(cmd, exit_on_error: true, runner: :popen)
67
+ def initialize(cmd, exit_on_error: true, runner: :popen, on_output: nil)
66
68
  @cmd = cmd
67
69
  @exit_on_error = exit_on_error
68
70
  @runner = runner
71
+ @on_output = on_output
69
72
  end
70
73
 
71
74
  def run
72
75
  debug("running (#{@runner}): #{@cmd}")
73
- res = case @runner
76
+ res = Result.new(on_output:)
77
+ case @runner
74
78
  when :system
75
- run_system(Result.new)
79
+ run_system(res)
76
80
  when :popen
77
- run_threaded(Result.new)
81
+ run_threaded(res)
78
82
  when :exec
79
- run_exec(Result.new)
83
+ run_exec(res)
80
84
  else
81
85
  raise "unknown runner #{@runner}"
82
86
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'erb'
4
-
5
4
  module Minfra
6
5
  module Cli
7
6
  # not threadsafe!
@@ -30,14 +29,15 @@ module Minfra
30
29
 
31
30
  source.glob('**/*') do |filename|
32
31
  rel_path = filename.relative_path_from(source)
33
-
34
32
  if File.directory?(filename) # check if it s file and extension is not .tf
35
33
  FileUtils.mkdir_p("#{destination}/#{rel_path}")
36
34
  elsif extensions.include?(File.extname(filename)) # a file
35
+ # puts("templating: #{filename}")
37
36
  content = File.read(filename)
38
37
  modified_content = Minfra::Cli::Templater.render(content, {})
39
38
  File.write("#{destination}/#{rel_path}", modified_content)
40
39
  else
40
+ # puts("copying : #{filename}")
41
41
  FileUtils.cp(filename, destination.join(rel_path))
42
42
  end
43
43
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Minfra
4
4
  module Cli
5
- VERSION = '2.0.1'
5
+ VERSION = '2.2.0'
6
6
  end
7
7
  end
data/lib/minfra/cli.rb CHANGED
@@ -18,7 +18,6 @@ require_relative 'cli/hook'
18
18
  require_relative 'cli/common'
19
19
  require_relative 'cli/command'
20
20
  require_relative 'cli/ask'
21
- require_relative 'cli/document'
22
21
  require_relative 'cli/runner'
23
22
  require_relative 'cli/helm_runner'
24
23
  require_relative 'cli/kubectl_runner'
@@ -188,7 +188,7 @@ module Orchparty
188
188
 
189
189
  def print_install
190
190
  build_chart do |chart_path|
191
- cmd = "helm template --namespace #{namespace} --debug --kube-context #{cluster_name} --output-dir #{chart_path.join(
191
+ cmd = "helm template --namespace #{namespace} --kube-context #{cluster_name} --output-dir #{chart_path.join(
192
192
  '..', 'helm_expanded'
193
193
  )} #{service.name} #{chart_path}"
194
194
  @out_io.puts `$cmd`
data/minfra-cli.gemspec CHANGED
@@ -36,5 +36,6 @@ Gem::Specification.new do |spec|
36
36
  spec.add_runtime_dependency "hiera", "3.9.0"
37
37
  spec.add_runtime_dependency "hiera-eyaml", "3.3.0"
38
38
  spec.add_runtime_dependency "hiera-eyaml-gpg", "0.7.4"
39
+ spec.add_runtime_dependency "gpgme", "~>2.0.0"
39
40
  end
40
41
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minfra-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Schrammel
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-05 00:00:00.000000000 Z
11
+ date: 2024-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -142,6 +142,20 @@ dependencies:
142
142
  - - '='
143
143
  - !ruby/object:Gem::Version
144
144
  version: 0.7.4
145
+ - !ruby/object:Gem::Dependency
146
+ name: gpgme
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: 2.0.0
152
+ type: :runtime
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: 2.0.0
145
159
  description: A cli framework for k8s based development and deployment.
146
160
  email:
147
161
  - peter.schrammel@gmx.de
@@ -157,7 +171,6 @@ files:
157
171
  - CHANGELOG.md
158
172
  - Dockerfile
159
173
  - Gemfile
160
- - Gemfile.lock
161
174
  - README.md
162
175
  - Rakefile
163
176
  - bin/build
@@ -188,7 +201,6 @@ files:
188
201
  - lib/minfra/cli/common.rb
189
202
  - lib/minfra/cli/config.rb
190
203
  - lib/minfra/cli/core_ext.rb
191
- - lib/minfra/cli/document.rb
192
204
  - lib/minfra/cli/env.rb
193
205
  - lib/minfra/cli/errors.rb
194
206
  - lib/minfra/cli/helm_runner.rb
data/Gemfile.lock DELETED
@@ -1,81 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- minfra-cli (2.0.0)
5
- activesupport (= 7.0.7.2)
6
- erubis (~> 2.7)
7
- hashie (~> 3.5)
8
- hiera (= 3.9.0)
9
- hiera-eyaml (= 3.3.0)
10
- hiera-eyaml-gpg (= 0.7.4)
11
- rest-client (~> 2.0)
12
- table_print (= 1.5.6)
13
- thor (~> 1.0, >= 1.0.0)
14
-
15
- GEM
16
- remote: https://rubygems.org/
17
- specs:
18
- activesupport (7.0.7.2)
19
- concurrent-ruby (~> 1.0, >= 1.0.2)
20
- i18n (>= 1.6, < 2)
21
- minitest (>= 5.1)
22
- tzinfo (~> 2.0)
23
- concurrent-ruby (1.2.2)
24
- diff-lcs (1.5.0)
25
- domain_name (0.6.20231109)
26
- erubis (2.7.0)
27
- hashie (3.6.0)
28
- hiera (3.9.0)
29
- hiera-eyaml (3.3.0)
30
- highline
31
- optimist
32
- hiera-eyaml-gpg (0.7.4)
33
- hiera-eyaml (>= 1.3.8)
34
- highline (2.1.0)
35
- http-accept (1.7.0)
36
- http-cookie (1.0.5)
37
- domain_name (~> 0.5)
38
- i18n (1.14.1)
39
- concurrent-ruby (~> 1.0)
40
- mime-types (3.5.1)
41
- mime-types-data (~> 3.2015)
42
- mime-types-data (3.2023.1205)
43
- minitest (5.20.0)
44
- netrc (0.11.0)
45
- optimist (3.1.0)
46
- rake (12.3.3)
47
- rest-client (2.1.0)
48
- http-accept (>= 1.7.0, < 2.0)
49
- http-cookie (>= 1.0.2, < 2.0)
50
- mime-types (>= 1.16, < 4.0)
51
- netrc (~> 0.8)
52
- rspec (3.12.0)
53
- rspec-core (~> 3.12.0)
54
- rspec-expectations (~> 3.12.0)
55
- rspec-mocks (~> 3.12.0)
56
- rspec-core (3.12.2)
57
- rspec-support (~> 3.12.0)
58
- rspec-expectations (3.12.3)
59
- diff-lcs (>= 1.2.0, < 2.0)
60
- rspec-support (~> 3.12.0)
61
- rspec-mocks (3.12.6)
62
- diff-lcs (>= 1.2.0, < 2.0)
63
- rspec-support (~> 3.12.0)
64
- rspec-support (3.12.1)
65
- table_print (1.5.6)
66
- thor (1.3.0)
67
- timecop (0.9.8)
68
- tzinfo (2.0.6)
69
- concurrent-ruby (~> 1.0)
70
-
71
- PLATFORMS
72
- ruby
73
-
74
- DEPENDENCIES
75
- minfra-cli!
76
- rake (~> 12.0)
77
- rspec (~> 3.0)
78
- timecop (~> 0.9.5)
79
-
80
- BUNDLED WITH
81
- 2.1.4
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Minfra
4
- module Cli
5
- class Document
6
- def self.document(config, message)
7
- new(config).document(message)
8
- end
9
-
10
- def initialize(config)
11
- @config = config
12
- end
13
-
14
- def document(_message)
15
- return true if @config.dev?
16
-
17
- puts 'TBD: calling documentation hooks'
18
- true
19
- end
20
- end
21
- end
22
- end