hippo-cli 1.1.0 → 1.1.1

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/bin/hippo +4 -4
  5. data/cli/apply_config.rb +1 -0
  6. data/cli/apply_services.rb +1 -0
  7. data/cli/console.rb +2 -0
  8. data/cli/create.rb +83 -0
  9. data/cli/deploy.rb +2 -0
  10. data/cli/init.rb +1 -1
  11. data/cli/install.rb +3 -1
  12. data/cli/key.rb +34 -0
  13. data/cli/kubectl.rb +2 -0
  14. data/cli/logs.rb +56 -0
  15. data/cli/objects.rb +50 -0
  16. data/cli/package_install.rb +30 -0
  17. data/cli/package_list.rb +40 -0
  18. data/cli/package_notes.rb +23 -0
  19. data/cli/package_test.rb +21 -0
  20. data/cli/package_uninstall.rb +27 -0
  21. data/cli/package_upgrade.rb +30 -0
  22. data/cli/package_values.rb +22 -0
  23. data/cli/prepare.rb +18 -0
  24. data/cli/run.rb +37 -0
  25. data/cli/secrets.rb +24 -0
  26. data/cli/stages.rb +26 -0
  27. data/cli/status.rb +25 -0
  28. data/cli/vars.rb +20 -0
  29. data/cli/version.rb +8 -0
  30. data/lib/hippo.rb +12 -0
  31. data/lib/hippo/bootstrap_parser.rb +64 -0
  32. data/lib/hippo/cli.rb +47 -14
  33. data/lib/hippo/extensions.rb +9 -0
  34. data/lib/hippo/image.rb +35 -31
  35. data/lib/hippo/manifest.rb +17 -7
  36. data/lib/hippo/object_definition.rb +18 -5
  37. data/lib/hippo/package.rb +124 -0
  38. data/lib/hippo/repository_tag.rb +38 -0
  39. data/lib/hippo/secret_manager.rb +61 -14
  40. data/lib/hippo/stage.rb +60 -26
  41. data/lib/hippo/util.rb +34 -0
  42. data/lib/hippo/version.rb +1 -1
  43. data/template/Hippofile +10 -2
  44. metadata +44 -13
  45. metadata.gz.sig +0 -0
  46. data/cli/secrets_edit.rb +0 -34
  47. data/cli/secrets_key.rb +0 -20
  48. data/lib/hippo/secret.rb +0 -112
  49. data/template/config/env-vars.yaml +0 -7
  50. data/template/deployments/web.yaml +0 -29
  51. data/template/deployments/worker.yaml +0 -26
  52. data/template/jobs/deploy/db-migration.yaml +0 -22
  53. data/template/jobs/install/load-schema.yaml +0 -22
  54. data/template/services/main.ingress.yaml +0 -13
  55. data/template/services/web.svc.yaml +0 -11
  56. data/template/stages/production.yaml +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 862958b0818bb34f9956e83e82738d1b59b2d4fba32c8bde858b9793129b0c9c
4
- data.tar.gz: 9f3fd4e9587b882cb6588058b94efa85c8049bb31869b013c3a13f81edca5525
3
+ metadata.gz: 96a621d666288ef2ec40ae5384c0a2ba823f011cd2384db2d0eee53d2dbf6fc1
4
+ data.tar.gz: 05cf19519259186bd789f02d996b580ba76a7b7e9f598b308c2705c636d25e6c
5
5
  SHA512:
6
- metadata.gz: f04805d52992d14804d21671dfbc59e1ea85dc28a3d490f135353f3cf6ba94830c1f01a0f5b1f16e3e8cabf2cd433a03e883ded0f7227f727abaa6ecf9d35f83
7
- data.tar.gz: 6aed2eaa5a88fd0f9b99eaeca58de8f208eb72825bee8a7c4ef78068092ecf3e3a901ae0b9784e05a78d7785091d22ac1e4ac523897ca1f696eaeaf39da6eedb
6
+ metadata.gz: 911cfb6bdbbcf16ef73a5dc1d36bd53aa06dc7f94e9f53a9cc0aa964400a266cc25583d97651684ebf3394f340f780520bfb7af0e189a656dd48d2338beed7fb
7
+ data.tar.gz: 466ec97e4b4a4a1dcdd223f18be57fbeddb72aea29aacc1d64fc2b728ca807ec0865619024773b49613ac19aa14dcfea275bcdd9a3cdfa6395ea1dc601b67855
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/bin/hippo CHANGED
@@ -8,18 +8,18 @@ require 'hippo/error'
8
8
  require 'hippo/version'
9
9
  require 'swamp/cli'
10
10
 
11
- COMMANDS_WITHOUT_STAGE = %w[help init].freeze
11
+ COMMANDS_WITHOUT_STAGE = %w[help init version stages].freeze
12
12
 
13
13
  begin
14
14
  cli = Swamp::CLI.new(:hippo, version: Hippo::VERSION)
15
15
  cli.load_from_directory(File.expand_path('../cli', __dir__))
16
16
 
17
17
  args = ARGV.dup
18
- stage = args.shift
19
- command = args.shift
18
+ stage = args[0]
19
+ command = args[1]
20
20
 
21
21
  if COMMANDS_WITHOUT_STAGE.include?(stage) || (command.nil? && stage.nil?)
22
- cli.dispatch([stage || 'help'])
22
+ cli.dispatch(args.empty? ? ['help'] : args)
23
23
  elsif command.nil?
24
24
  puts 'usage: hippo [STAGE] [COMMAND] {options}'
25
25
  puts '(Be sure to specify the stage name before the command)'
data/cli/apply_config.rb CHANGED
@@ -10,6 +10,7 @@ command :'apply-config' do
10
10
  action do |context|
11
11
  require 'hippo/cli'
12
12
  cli = Hippo::CLI.setup(context)
13
+ cli.preflight
13
14
  cli.apply_namespace
14
15
  cli.apply_config
15
16
  end
@@ -10,6 +10,7 @@ command :'apply-services' do
10
10
  action do |context|
11
11
  require 'hippo/cli'
12
12
  cli = Hippo::CLI.setup(context)
13
+ cli.preflight
13
14
  cli.apply_services
14
15
  end
15
16
  end
data/cli/console.rb CHANGED
@@ -23,6 +23,8 @@ command :console do
23
23
  raise Error, 'No console configuration has been provided in Hippofile'
24
24
  end
25
25
 
26
+ cli.preflight
27
+
26
28
  time = Time.now.to_i
27
29
  deployment_name = context.options[:deployment] || cli.manifest.console['deployment']
28
30
  command = context.options[:command] || cli.manifest.console['command'] || 'bash'
data/cli/create.rb ADDED
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ command :create do
4
+ desc 'Create a new stage'
5
+
6
+ option '-h', '--hippofile [RECIPE]', 'The path to the Hippofile (defaults: ./Hippofile)' do |value, options|
7
+ options[:hippofile] = value.to_s
8
+ end
9
+
10
+ option '-n', '--namespace [NAMESPACE]', 'The namespace for the new stage' do |value, options|
11
+ options[:namespace] = value
12
+ end
13
+
14
+ option '-c', '--context [CONTEXT]', 'The context for the new stage' do |value, options|
15
+ options[:context] = value
16
+ end
17
+
18
+ option '--force', 'Override existing stage configuration' do |_value, options|
19
+ options[:force] = true
20
+ end
21
+
22
+ action do |context|
23
+ require 'hippo/manifest'
24
+ manifest = Hippo::Manifest.load_from_file(context.options[:hippofile] || './Hippofile')
25
+
26
+ stage_name = CURRENT_STAGE
27
+ stage_path = File.join(manifest.root, 'stages', "#{stage_name}.yaml")
28
+
29
+ if !context.options[:force] && File.file?(stage_path)
30
+ puts "\e[31mA stage named '#{stage_name}' already exists. Use --force to overwrite configuration.\e[0m"
31
+ exit 1
32
+ end
33
+
34
+ require 'hippo/util'
35
+
36
+ namespace = context.options[:namespace]
37
+ if namespace.nil?
38
+ namespace = Hippo::Util.ask('Enter a namespace for this stage', default: "#{manifest.name}-#{stage_name}")
39
+ end
40
+
41
+ context_name = context.options[:context]
42
+ if context_name.nil?
43
+ context_name = Hippo::Util.ask('Enter a kubectl context for this stage', default: Hippo.current_kubectl_context)
44
+ end
45
+
46
+ yaml = {}
47
+ yaml['name'] = stage_name
48
+ yaml['namespace'] = namespace
49
+ yaml['context'] = context_name
50
+
51
+ require 'hippo/bootstrap_parser'
52
+ yaml['config'] = Hippo::BootstrapParser.parse(manifest.bootstrap['config'])
53
+
54
+ require 'hippo/stage'
55
+ stage = Hippo::Stage.new(manifest, yaml)
56
+
57
+ require 'hippo/cli'
58
+ cli = Hippo::CLI.new(manifest, stage)
59
+ cli.apply_namespace
60
+
61
+ if stage.secret_manager.key_available?
62
+ puts 'Encryption key already exists for this namespace.'
63
+ else
64
+ puts "Creating new encryption key in #{stage.namespace} namespace"
65
+ stage.secret_manager.create_key
66
+ end
67
+
68
+ FileUtils.mkdir_p(File.dirname(stage_path))
69
+ File.open(stage_path, 'w') { |f| f.write(yaml.to_yaml.sub(/\A---\n/m, '')) }
70
+ puts "Written new stage file to stages/#{stage.name}.yaml"
71
+
72
+ secrets = Hippo::BootstrapParser.parse(manifest.bootstrap['secrets'])
73
+ stage.secret_manager.write_file(secrets.to_yaml)
74
+ puts "Written encrypted secrets into secrets/#{stage.name}.yaml"
75
+
76
+ puts
77
+ puts "\e[32mStage '#{stage.name}' has been created successfully.\e[0m"
78
+ puts
79
+ puts 'You can now add any appropriate configuration needed into the'
80
+ puts 'stage file and into the encrypted secrets file if needed.'
81
+ puts
82
+ end
83
+ end
data/cli/deploy.rb CHANGED
@@ -14,6 +14,8 @@ command :deploy do
14
14
  action do |context|
15
15
  require 'hippo/cli'
16
16
  cli = Hippo::CLI.setup(context)
17
+ cli.preflight
18
+
17
19
  cli.verify_image_existence
18
20
 
19
21
  cli.apply_namespace
data/cli/init.rb CHANGED
@@ -13,7 +13,7 @@ command :init do
13
13
  end
14
14
 
15
15
  root = File.expand_path(path)
16
- template_root = File.join(File.expand_path('../', __dir__), 'template')
16
+ template_root = File.join(Hippo.root, 'template')
17
17
 
18
18
  raise Hippo::Error, "File already exists at #{root}" if File.exist?(root)
19
19
 
data/cli/install.rb CHANGED
@@ -18,6 +18,8 @@ command :install do
18
18
  action do |context|
19
19
  require 'hippo/cli'
20
20
  cli = Hippo::CLI.setup(context)
21
+ cli.preflight
22
+
21
23
  cli.verify_image_existence
22
24
 
23
25
  cli.apply_namespace
@@ -29,7 +31,7 @@ command :install do
29
31
  end
30
32
  end
31
33
 
32
- if options[:deploy] == false
34
+ if context.options[:deploy] == false
33
35
  puts 'Not deploying because --no-deploy was specified'
34
36
  exit 0
35
37
  end
data/cli/key.rb ADDED
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ command :key do
4
+ desc 'Display/generate details about the secret encryption key'
5
+
6
+ option '-h', '--hippofile [RECIPE]', 'The path to the Hippofile (defaults: ./Hippofile)' do |value, options|
7
+ options[:hippofile] = value.to_s
8
+ end
9
+
10
+ option '-g', '--generate', 'Generate a new key' do |_value, options|
11
+ options[:generate] = true
12
+ end
13
+ action do |context|
14
+ require 'hippo/cli'
15
+ cli = Hippo::CLI.setup(context)
16
+ cli.preflight
17
+
18
+ sm = cli.stage.secret_manager
19
+ if sm.key_available?
20
+ puts 'Secret encryption key is stored in secret/hippo-secret-key.'
21
+ else
22
+ if context.options[:generate]
23
+ sm.create_key
24
+ puts 'Secret encryption key has been generated and stored in secret/hippo-secret-key.'
25
+ else
26
+ puts 'Secret encryption key has not been generated yet.'
27
+ puts 'Generate a new using:'
28
+ puts
29
+ puts " hippo #{cli.stage.name} key --generate"
30
+ puts
31
+ end
32
+ end
33
+ end
34
+ end
data/cli/kubectl.rb CHANGED
@@ -10,6 +10,8 @@ command :kubectl do
10
10
  action do |context|
11
11
  require 'hippo/cli'
12
12
  cli = Hippo::CLI.setup(context)
13
+ cli.preflight
14
+
13
15
  ARGV.shift(2)
14
16
  ARGV.delete('--')
15
17
  exec cli.stage.kubectl(*ARGV).join(' ')
data/cli/logs.rb ADDED
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ command :logs do
4
+ desc 'Display logs for a particular pod'
5
+
6
+ option '-h', '--hippofile [RECIPE]', 'The path to the Hippofile (defaults: ./Hippofile)' do |value, options|
7
+ options[:hippofile] = value.to_s
8
+ end
9
+
10
+ option '-p', '--pod [POD]', 'The name of the pod' do |value, options|
11
+ options[:pod] = value
12
+ end
13
+
14
+ option '-f', '--follow', 'Follow the log stream' do |_value, options|
15
+ options[:follow] = true
16
+ end
17
+
18
+ action do |context|
19
+ require 'hippo/cli'
20
+ require 'hippo/util'
21
+
22
+ cli = Hippo::CLI.setup(context)
23
+ cli.preflight
24
+
25
+ pod = context.options[:pod]
26
+ if pod.nil?
27
+ # Get all pod names that are running
28
+ stdout, stderr, status = Open3.capture3(*cli.stage.kubectl('get', 'pods'))
29
+ pod_names = []
30
+ stdout.split("\n").each_with_index do |line, index|
31
+ if index.zero?
32
+ puts " #{line}"
33
+ else
34
+ puts "\e[33m#{index.to_s.rjust(3)})\e[0m #{line}"
35
+ pod_names << line.split(/\s+/, 2).first
36
+ end
37
+ end
38
+
39
+ raise Error, 'There are no pods running' if pod_names.empty?
40
+
41
+ until pod
42
+ pod_id = Hippo::Util.ask('Choose a pod to view logs').to_i
43
+ next if pod_id.zero? || pod_id.negative?
44
+
45
+ pod = pod_names[pod_id.to_i - 1]
46
+ end
47
+ end
48
+
49
+ args = []
50
+ args << '--all-containers'
51
+ args << '-f' if context.options[:follow]
52
+
53
+ command = cli.stage.kubectl('logs', pod, *args)
54
+ exec *command
55
+ end
56
+ end
data/cli/objects.rb ADDED
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ command :objects do
4
+ desc 'Display all objects that will be exported'
5
+
6
+ option '-h', '--hippofile [RECIPE]', 'The path to the Hippofile (defaults: ./Hippofile)' do |value, options|
7
+ options[:hippofile] = value.to_s
8
+ end
9
+
10
+ option '-t', '--type [TYPE]', 'Limit which type of object to return (one of config, deployments or services)' do |value, options|
11
+ options[:type] = value
12
+ end
13
+
14
+ option '--to-apply', 'Show objects as they would be applied to Kubernetes' do |_value, options|
15
+ options[:to_apply] = true
16
+ end
17
+
18
+ action do |context|
19
+ require 'hippo/cli'
20
+ cli = Hippo::CLI.setup(context)
21
+ cli.preflight
22
+
23
+ method = if context.options[:to_apply]
24
+ :yaml_to_apply
25
+ else
26
+ :yaml
27
+ end
28
+
29
+ groups = []
30
+ if context.options[:type].nil? || context.options[:type] == 'config'
31
+ groups << cli.stage.configs.map(&method)
32
+ end
33
+
34
+ if context.options[:type].nil? || context.options[:type] == 'deployments'
35
+ groups << cli.stage.deployments.map(&method)
36
+ end
37
+
38
+ if context.options[:type].nil? || context.options[:type] == 'services'
39
+ groups << cli.stage.services.map(&method)
40
+ end
41
+
42
+ groups.each do |group|
43
+ group.each do |object|
44
+ puts object
45
+ .gsub(/^kind\: (.*)$/) { "kind: \e[36m#{Regexp.last_match(1)}\e[0m" }
46
+ .gsub(/^---$/) { "\e[33m#{'=' * 80}\e[0m" }
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ command :'package:install' do
4
+ desc 'Install a named helm package'
5
+
6
+ option '-h', '--hippofile [RECIPE]', 'The path to the Hippofile (defaults: ./Hippofile)' do |value, options|
7
+ options[:hippofile] = value.to_s
8
+ end
9
+
10
+ option '-p', '--package [NAME]', 'The name of the package to install' do |value, options|
11
+ options[:package] = value
12
+ end
13
+
14
+ action do |context|
15
+ require 'hippo/package'
16
+ package, cli = Hippo::Package.setup_from_cli_context(context)
17
+ cli.preflight
18
+
19
+ if package.installed?
20
+ puts "#{package.name} is already installed. You probably want to use helm:upgrade instead."
21
+ else
22
+ cli.apply_namespace
23
+ cli.apply_config
24
+
25
+ puts "Installing #{package.name} with Helm..."
26
+ package.install
27
+ puts "#{package.name} installed successfully"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ command :'package:list' do
4
+ desc 'List all available packages with status'
5
+
6
+ option '-h', '--hippofile [RECIPE]', 'The path to the Hippofile (defaults: ./Hippofile)' do |value, options|
7
+ options[:hippofile] = value.to_s
8
+ end
9
+
10
+ action do |context|
11
+ require 'hippo/cli'
12
+ cli = Hippo::CLI.setup(context)
13
+ cli.preflight
14
+
15
+ if cli.stage.packages.empty?
16
+ puts 'There are no configured packages'
17
+ exit 0
18
+ end
19
+
20
+ puts 'Getting package details...'
21
+
22
+ packages = []
23
+ cli.stage.packages.values.sort_by(&:name).each do |package|
24
+ packages << { name: package.name, installed: package.installed?, package: package.package }
25
+ end
26
+
27
+ packages.each do |package|
28
+ STDOUT.print package[:name].ljust(20)
29
+ STDOUT.print package[:package].ljust(30)
30
+ STDOUT.print '[ '
31
+ if package[:installed]
32
+ STDOUT.print "\e[32m Installed \e[0m"
33
+ else
34
+ STDOUT.print "\e[31mNot present\e[0m"
35
+ end
36
+ STDOUT.print ' ]'
37
+ puts
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ command :'package:notes' do
4
+ desc 'Show notes about an installed Helm package'
5
+
6
+ option '-h', '--hippofile [RECIPE]', 'The path to the Hippofile (defaults: ./Hippofile)' do |value, options|
7
+ options[:hippofile] = value.to_s
8
+ end
9
+
10
+ option '-p', '--package [NAME]', 'The name of the package to install' do |value, options|
11
+ options[:package] = value
12
+ end
13
+
14
+ action do |context|
15
+ require 'hippo/package'
16
+ package, cli = Hippo::Package.setup_from_cli_context(context)
17
+ cli.preflight
18
+
19
+ raise Error, "#{package.name} not installed" unless package.installed?
20
+
21
+ puts package.notes
22
+ end
23
+ end