hippo-cli 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
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