minfra-cli 1.11.0 → 1.12.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/CHANGELOG.md +7 -0
- data/lib/minfra/cli/commands/kube.rb +11 -13
- data/lib/minfra/cli/helm_runner.rb +11 -0
- data/lib/minfra/cli/kubectl_runner.rb +11 -0
- data/lib/minfra/cli/runner.rb +48 -15
- data/lib/minfra/cli/version.rb +1 -1
- data/lib/minfra/cli.rb +2 -0
- data/lib/orchparty/kubernetes_application.rb +14 -13
- data/minfra-cli.gemspec +2 -1
- metadata +7 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 2b4880a484c8d4d18875f3b3c355162c0f49eb1fcae69f8a870ee4c5ad8d04d0
         | 
| 4 | 
            +
              data.tar.gz: 1d34cb69b8b8e5a5476dcec8d14463d02a00a2fbdc47ccb12f761a93413a3df9
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 851fbc24107b2efd086f2e69adaaf2580f1ceed98eee55a71067348d4283360be440b14bf94b586f56a3a5180d0432a76553602cad02b6aef3e2715441bef236
         | 
| 7 | 
            +
              data.tar.gz: cffdcda6203c63f9efcc12b7f57dea382caf82f2a2cd8cca605c14b36ef8fe77a82695c72a8cddac31113c311f24fc753de8df7506a03894474d83d360b282ee
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,10 @@ | |
| 1 | 
            +
            # 1.12.0
         | 
| 2 | 
            +
             * refactoring Runner
         | 
| 3 | 
            +
             * adding runner type system (popen is default)
         | 
| 4 | 
            +
             * adding HelmRunner, KubectlRunner
         | 
| 5 | 
            +
             * adding support for infra::allow_insecure_k8s_connections
         | 
| 6 | 
            +
             * easing active support requirement
         | 
| 7 | 
            +
             | 
| 1 8 | 
             
            # 1.11.0
         | 
| 2 9 | 
             
             * generating helm output with resolved vairables in "helm_expanded"
         | 
| 3 10 | 
             
             * adding template_dir to templater to render whole directories
         | 
| @@ -15,7 +15,10 @@ module Minfra | |
| 15 15 |  | 
| 16 16 | 
             
                  def dashboard(stack_name,env,deployment,cluster)
         | 
| 17 17 | 
             
                    stack = init(stack_name,env,deployment,cluster)
         | 
| 18 | 
            -
                     | 
| 18 | 
            +
                    insecure_flag = l("infra::allow_insecure_k8s_connections") ? "--insecure-skip-tls-verify" : ""
         | 
| 19 | 
            +
                    cmd = "k9s #{insecure_flag} --kubeconfig #{kube_config_path} --context #{stack.cluster_name} --namespace #{stack_name} --command pod"
         | 
| 20 | 
            +
                    debug(cmd)
         | 
| 21 | 
            +
                    exec(cmd)
         | 
| 19 22 | 
             
                  end
         | 
| 20 23 |  | 
| 21 24 | 
             
                  def restart
         | 
| @@ -154,9 +157,7 @@ module Minfra | |
| 154 157 |  | 
| 155 158 | 
             
                    extra_args = extra_args.join(' ')
         | 
| 156 159 |  | 
| 157 | 
            -
                     | 
| 158 | 
            -
                    #puts cmd
         | 
| 159 | 
            -
                    run_cmd(cmd, :exec)
         | 
| 160 | 
            +
                    run_helm("--kube-context #{cluster} rollback #{options[:stack]} #{extra_args}")
         | 
| 160 161 | 
             
                  end
         | 
| 161 162 |  | 
| 162 163 | 
             
                  def list
         | 
| @@ -195,9 +196,9 @@ module Minfra | |
| 195 196 |  | 
| 196 197 | 
             
                    cluster = stack.cluster_name
         | 
| 197 198 | 
             
                    if [resource, implicit_resource].include?('pod') && ['delete', 'describe', 'exec', 'logs', 'port-forward'].include?(subcommand)
         | 
| 198 | 
            -
                      cmd_get_pods = " | 
| 199 | 
            +
                      cmd_get_pods = "--kubeconfig #{kube_config_path} --context #{cluster} --namespace #{options[:stack]} get pod -o jsonpath='{range .items[*]}{.metadata.name}{\"\\n\"}'"
         | 
| 199 200 |  | 
| 200 | 
            -
                      pods_list =  | 
| 201 | 
            +
                      pods_list = run_kubectl(cmd_get_pods).stdout_lines
         | 
| 201 202 |  | 
| 202 203 | 
             
                      fuzzy_pod_name = args.shift
         | 
| 203 204 |  | 
| @@ -230,9 +231,8 @@ module Minfra | |
| 230 231 |  | 
| 231 232 | 
             
                    extra_args = extra_args.join(' ')
         | 
| 232 233 |  | 
| 233 | 
            -
                    cmd = " | 
| 234 | 
            -
                     | 
| 235 | 
            -
                    run_cmd(cmd, :exec)
         | 
| 234 | 
            +
                    cmd = "--kubeconfig #{kube_config_path} --context #{cluster} --namespace #{options[:stack]} #{subcommand} #{resource} #{pod_name} #{extra_args}"
         | 
| 235 | 
            +
                    KubeCtlRunner.run(cmd, runner: :exec)
         | 
| 236 236 | 
             
                  end
         | 
| 237 237 |  | 
| 238 238 | 
             
                  private
         | 
| @@ -252,13 +252,11 @@ module Minfra | |
| 252 252 | 
             
                  end
         | 
| 253 253 |  | 
| 254 254 | 
             
                  def run_kubectl(cmd)
         | 
| 255 | 
            -
                     | 
| 256 | 
            -
                    run(%{kubectl #{cmd}})
         | 
| 255 | 
            +
                    KubeCtlRunner.run(cmd, runner: :system)
         | 
| 257 256 | 
             
                  end
         | 
| 258 257 |  | 
| 259 258 | 
             
                  def run_helm(cmd)
         | 
| 260 | 
            -
             | 
| 261 | 
            -
                    run(%{helm #{cmd}})
         | 
| 259 | 
            +
                    HelmRunner.run(cmd, runner: :system)
         | 
| 262 260 | 
             
                  end
         | 
| 263 261 |  | 
| 264 262 | 
             
                  def helm_path
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            module Minfra
         | 
| 2 | 
            +
              module Cli
         | 
| 3 | 
            +
                class HelmRunner < Runner
         | 
| 4 | 
            +
                  def initialize(cmd, **args)
         | 
| 5 | 
            +
                    insecure_flag = l("infra::allow_insecure_k8s_connections") ? "--kube-insecure-skip-tls-verify" : ""
         | 
| 6 | 
            +
                    cmd = "helm #{insecure_flag} #{cmd}"
         | 
| 7 | 
            +
                    super(cmd, **args)
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
            end
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            module Minfra
         | 
| 2 | 
            +
              module Cli
         | 
| 3 | 
            +
                class KubeCtlRunner < Runner
         | 
| 4 | 
            +
                  def initialize(cmd, **args)
         | 
| 5 | 
            +
                    insecure_flag = l("infra::allow_insecure_k8s_connections") ? "--insecure-skip-tls-verify" : ""
         | 
| 6 | 
            +
                    cmd = "kubectl #{insecure_flag} #{cmd}"
         | 
| 7 | 
            +
                    super(cmd, **args)
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
            end
         | 
    
        data/lib/minfra/cli/runner.rb
    CHANGED
    
    | @@ -11,6 +11,8 @@ module Minfra | |
| 11 11 |  | 
| 12 12 | 
             
                    attr_writer :status
         | 
| 13 13 |  | 
| 14 | 
            +
                    attr_reader :stdout_lines
         | 
| 15 | 
            +
                    
         | 
| 14 16 | 
             
                    def initialize
         | 
| 15 17 | 
             
                      @stderr_lines = []
         | 
| 16 18 | 
             
                      @stdout_lines = []
         | 
| @@ -58,18 +60,58 @@ module Minfra | |
| 58 60 | 
             
                    new(cmd, **args).run
         | 
| 59 61 | 
             
                  end
         | 
| 60 62 |  | 
| 61 | 
            -
                  attr_reader :exit_on_error
         | 
| 63 | 
            +
                  attr_reader :exit_on_error, :runner, :cmd
         | 
| 62 64 |  | 
| 63 | 
            -
                  def initialize(cmd, exit_on_error: true)
         | 
| 65 | 
            +
                  def initialize(cmd, exit_on_error: true, runner: :popen)
         | 
| 64 66 | 
             
                    @cmd = cmd
         | 
| 65 67 | 
             
                    @exit_on_error = exit_on_error
         | 
| 68 | 
            +
                    @runner = runner
         | 
| 66 69 | 
             
                  end
         | 
| 67 70 |  | 
| 68 71 | 
             
                  def run
         | 
| 69 | 
            -
                    debug("running: #{@cmd}")
         | 
| 70 | 
            -
                    res | 
| 72 | 
            +
                    debug("running (#{@runner}): #{@cmd}")
         | 
| 73 | 
            +
                    res=case @runner
         | 
| 74 | 
            +
                      when :system
         | 
| 75 | 
            +
                        run_system(Result.new)
         | 
| 76 | 
            +
                      when :popen  
         | 
| 77 | 
            +
                        run_threaded(Result.new)
         | 
| 78 | 
            +
                      when :exec
         | 
| 79 | 
            +
                        run_exec(Result.new)  
         | 
| 80 | 
            +
                      else
         | 
| 81 | 
            +
                        raise "unknown runner #{@runner}"  
         | 
| 82 | 
            +
                    end
         | 
| 83 | 
            +
                    
         | 
| 84 | 
            +
                    if res.error?
         | 
| 85 | 
            +
                      error "command failed: #{@cmd}"
         | 
| 86 | 
            +
                      debug  res.stdout
         | 
| 87 | 
            +
                      info  res.stderr
         | 
| 88 | 
            +
                    end
         | 
| 89 | 
            +
                    if exit_on_error && res.error?
         | 
| 90 | 
            +
                      info "command exiting on error (#{res.exitstatus})"
         | 
| 91 | 
            +
                      exit 1
         | 
| 92 | 
            +
                    end
         | 
| 93 | 
            +
                    res
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
                  
         | 
| 96 | 
            +
                  private
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                  def run_exec(_res)
         | 
| 99 | 
            +
                    exec(@cmd)
         | 
| 100 | 
            +
                  end
         | 
| 101 | 
            +
                  # you don't get stderr .... yet
         | 
| 102 | 
            +
                  def run_system(res)
         | 
| 103 | 
            +
                    #https://stackoverflow.com/questions/6338908/ruby-difference-between-exec-system-and-x-or-backticks
         | 
| 104 | 
            +
                    begin
         | 
| 105 | 
            +
                      out=`#{@cmd}`
         | 
| 106 | 
            +
                      out.each_line do |line| res.add(line, :stdout) end 
         | 
| 107 | 
            +
                    rescue StandardError
         | 
| 108 | 
            +
                    end
         | 
| 109 | 
            +
                    res.status = $?
         | 
| 110 | 
            +
                    res
         | 
| 111 | 
            +
                  end
         | 
| 112 | 
            +
                  
         | 
| 113 | 
            +
                  def run_threaded(res)
         | 
| 71 114 | 
             
                    begin
         | 
| 72 | 
            -
                      res = Result.new
         | 
| 73 115 | 
             
                      # see: http://stackoverflow.com/a/1162850/83386
         | 
| 74 116 | 
             
                      # the whole implementation is problematic as we migth miss some output lines
         | 
| 75 117 | 
             
                      # Open4 might be a solution. Using Select might be a solution. Using Process.fork might be a solution....
         | 
| @@ -91,18 +133,9 @@ module Minfra | |
| 91 133 | 
             
                      end
         | 
| 92 134 | 
             
                    rescue StandardError
         | 
| 93 135 | 
             
                    end
         | 
| 94 | 
            -
             | 
| 95 | 
            -
                    if res.error?
         | 
| 96 | 
            -
                      error "command failed: #{@cmd}"
         | 
| 97 | 
            -
                      debug  res.stdout
         | 
| 98 | 
            -
                      info  res.stderr
         | 
| 99 | 
            -
                    end
         | 
| 100 | 
            -
                    if exit_on_error && res.error?
         | 
| 101 | 
            -
                      info "command exiting on error (#{res.exitstatus})"
         | 
| 102 | 
            -
                      exit 1
         | 
| 103 | 
            -
                    end
         | 
| 104 136 | 
             
                    res
         | 
| 105 137 | 
             
                  end
         | 
| 138 | 
            +
                  
         | 
| 106 139 | 
             
                end
         | 
| 107 140 | 
             
              end
         | 
| 108 141 | 
             
            end
         | 
    
        data/lib/minfra/cli/version.rb
    CHANGED
    
    
    
        data/lib/minfra/cli.rb
    CHANGED
    
    | @@ -16,6 +16,8 @@ require_relative 'cli/command' | |
| 16 16 | 
             
            require_relative 'cli/ask'
         | 
| 17 17 | 
             
            require_relative 'cli/document'
         | 
| 18 18 | 
             
            require_relative 'cli/runner'
         | 
| 19 | 
            +
            require_relative 'cli/helm_runner'
         | 
| 20 | 
            +
            require_relative 'cli/kubectl_runner'
         | 
| 19 21 | 
             
            require_relative 'cli/plugins'
         | 
| 20 22 |  | 
| 21 23 | 
             
            require 'active_support'
         | 
| @@ -47,8 +47,8 @@ module Orchparty | |
| 47 47 |  | 
| 48 48 | 
             
                  def print_install(helm)
         | 
| 49 49 | 
             
                    @out_io.puts "---"
         | 
| 50 | 
            -
                    @out_io.puts install_cmd(helm, value_path(helm))
         | 
| 51 | 
            -
                    @out_io.puts upgrade_cmd(helm, value_path(helm))
         | 
| 50 | 
            +
                    @out_io.puts install_cmd(helm, value_path(helm)).cmd
         | 
| 51 | 
            +
                    @out_io.puts upgrade_cmd(helm, value_path(helm)).cmd
         | 
| 52 52 | 
             
                    @out_io.puts "---"
         | 
| 53 53 | 
             
                    @out_io.puts File.read(template(value_path(helm), helm, flag: "")) if value_path(helm)
         | 
| 54 54 | 
             
                  end
         | 
| @@ -60,11 +60,11 @@ module Orchparty | |
| 60 60 | 
             
                  end
         | 
| 61 61 |  | 
| 62 62 | 
             
                  def upgrade(helm)
         | 
| 63 | 
            -
                    @out_io.puts  | 
| 63 | 
            +
                    @out_io.puts upgrade_cmd(helm).run.stdout
         | 
| 64 64 | 
             
                  end
         | 
| 65 65 |  | 
| 66 66 | 
             
                  def install(helm)
         | 
| 67 | 
            -
                    @out_io.puts  | 
| 67 | 
            +
                    @out_io.puts install_cmd(helm).run.stdout
         | 
| 68 68 | 
             
                  end
         | 
| 69 69 | 
             
                end
         | 
| 70 70 |  | 
| @@ -74,11 +74,11 @@ module Orchparty | |
| 74 74 | 
             
                  end
         | 
| 75 75 |  | 
| 76 76 | 
             
                  def upgrade_cmd(helm, fix_file_path = nil)
         | 
| 77 | 
            -
                    " | 
| 77 | 
            +
                    Minfra::Cli::HelmRunner.new("upgrade --namespace #{namespace} --kube-context #{cluster_name} --version #{helm.version} #{helm.name} #{helm.chart} #{template(value_path(helm), helm, fix_file_path: fix_file_path)}")
         | 
| 78 78 | 
             
                  end
         | 
| 79 79 |  | 
| 80 80 | 
             
                  def install_cmd(helm, fix_file_path = nil)
         | 
| 81 | 
            -
                    " | 
| 81 | 
            +
                    Minfra::Cli::HelmRunner.new("install --create-namespace --namespace #{namespace} --kube-context #{cluster_name} --version #{helm.version} #{helm.name} #{helm.chart} #{template(value_path(helm), helm, fix_file_path: fix_file_path)}")
         | 
| 82 82 | 
             
                  end
         | 
| 83 83 | 
             
                end
         | 
| 84 84 |  | 
| @@ -163,9 +163,10 @@ module Orchparty | |
| 163 163 | 
             
                  def print_install(chart)
         | 
| 164 164 |  | 
| 165 165 | 
             
                    build_chart(chart) do |chart_path|
         | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 168 | 
            -
             | 
| 166 | 
            +
                       cmd="helm template --namespace #{namespace} --debug --kube-context #{cluster_name} --output-dir #{chart_path.join('..','helm_expanded')}   #{chart.name} #{chart_path}"
         | 
| 167 | 
            +
                       @out_io.puts `$cmd`
         | 
| 168 | 
            +
                       if system("#{cmd} > /dev/null")
         | 
| 169 | 
            +
             | 
| 169 170 | 
             
                        info("helm template check: OK")
         | 
| 170 171 | 
             
                      else
         | 
| 171 172 | 
             
                        error("helm template check: FAIL")
         | 
| @@ -181,21 +182,21 @@ module Orchparty | |
| 181 182 | 
             
                  def install(chart)
         | 
| 182 183 | 
             
                    info("Install: #{chart.name}")
         | 
| 183 184 | 
             
                    build_chart(chart) do |chart_path|
         | 
| 184 | 
            -
                       | 
| 185 | 
            +
                      res=Minfra::Cli::HelmRunner.new("install --create-namespace --namespace #{namespace} --kube-context #{cluster_name} #{chart.name} #{chart_path}").run
         | 
| 186 | 
            +
                      @out_io.puts res.stdout
         | 
| 185 187 | 
             
                    end
         | 
| 186 188 | 
             
                  end
         | 
| 187 189 |  | 
| 188 190 | 
             
                  def upgrade(chart)
         | 
| 189 191 | 
             
                    info("Upgrade: #{chart}")
         | 
| 190 192 | 
             
                    build_chart(chart) do |chart_path|
         | 
| 191 | 
            -
                       | 
| 193 | 
            +
                      res=Minfra::Cli::HelmRunner.new("upgrade --namespace #{namespace} --kube-context #{cluster_name} #{chart.name} #{chart_path}").run
         | 
| 194 | 
            +
                      @out_io.puts res.stdout
         | 
| 192 195 | 
             
                    end
         | 
| 193 196 | 
             
                  end
         | 
| 194 197 | 
             
                  private
         | 
| 195 198 |  | 
| 196 199 | 
             
                  def build_chart(chart)
         | 
| 197 | 
            -
                    
         | 
| 198 | 
            -
                    
         | 
| 199 200 | 
             
                    dir = @app.status_dir.join('helm') # duplication
         | 
| 200 201 |  | 
| 201 202 | 
             
                    params = chart._services.map {|s| app_config.services[s.to_sym] }.map{|s| [s.name, s]}.to_h
         | 
    
        data/minfra-cli.gemspec
    CHANGED
    
    | @@ -31,9 +31,10 @@ Gem::Specification.new do |spec| | |
| 31 31 | 
             
              spec.add_runtime_dependency "table_print", "1.5.6"
         | 
| 32 32 | 
             
              spec.add_runtime_dependency "rest-client", "~>2.0"
         | 
| 33 33 | 
             
              spec.add_runtime_dependency "hashie", "~>3.5"
         | 
| 34 | 
            -
              spec.add_runtime_dependency "activesupport", " | 
| 34 | 
            +
              spec.add_runtime_dependency "activesupport", ">= 6.1"
         | 
| 35 35 | 
             
              spec.add_runtime_dependency "erubis", "~> 2.7"
         | 
| 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 39 | 
             
            end
         | 
| 40 | 
            +
             | 
    
        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: 1. | 
| 4 | 
            +
              version: 1.12.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: 2023- | 
| 11 | 
            +
            date: 2023-09-01 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: thor
         | 
| @@ -76,14 +76,14 @@ dependencies: | |
| 76 76 | 
             
              name: activesupport
         | 
| 77 77 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 78 78 | 
             
                requirements:
         | 
| 79 | 
            -
                - - " | 
| 79 | 
            +
                - - ">="
         | 
| 80 80 | 
             
                  - !ruby/object:Gem::Version
         | 
| 81 81 | 
             
                    version: '6.1'
         | 
| 82 82 | 
             
              type: :runtime
         | 
| 83 83 | 
             
              prerelease: false
         | 
| 84 84 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 85 85 | 
             
                requirements:
         | 
| 86 | 
            -
                - - " | 
| 86 | 
            +
                - - ">="
         | 
| 87 87 | 
             
                  - !ruby/object:Gem::Version
         | 
| 88 88 | 
             
                    version: '6.1'
         | 
| 89 89 | 
             
            - !ruby/object:Gem::Dependency
         | 
| @@ -185,7 +185,9 @@ files: | |
| 185 185 | 
             
            - lib/minfra/cli/common.rb
         | 
| 186 186 | 
             
            - lib/minfra/cli/config.rb
         | 
| 187 187 | 
             
            - lib/minfra/cli/document.rb
         | 
| 188 | 
            +
            - lib/minfra/cli/helm_runner.rb
         | 
| 188 189 | 
             
            - lib/minfra/cli/hook.rb
         | 
| 190 | 
            +
            - lib/minfra/cli/kubectl_runner.rb
         | 
| 189 191 | 
             
            - lib/minfra/cli/logging.rb
         | 
| 190 192 | 
             
            - lib/minfra/cli/main_command.rb
         | 
| 191 193 | 
             
            - lib/minfra/cli/plugins.rb
         | 
| @@ -237,7 +239,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 237 239 | 
             
                - !ruby/object:Gem::Version
         | 
| 238 240 | 
             
                  version: '0'
         | 
| 239 241 | 
             
            requirements: []
         | 
| 240 | 
            -
            rubygems_version: 3.4. | 
| 242 | 
            +
            rubygems_version: 3.4.10
         | 
| 241 243 | 
             
            signing_key: 
         | 
| 242 244 | 
             
            specification_version: 4
         | 
| 243 245 | 
             
            summary: A cli framework for k8s based development and deployment.
         |