hippo-cli 1.0.1 → 1.1.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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/cli/apply_config.rb +4 -5
- data/cli/apply_services.rb +3 -3
- data/cli/console.rb +6 -6
- data/cli/deploy.rb +11 -22
- data/cli/install.rb +22 -23
- data/cli/kubectl.rb +3 -3
- data/cli/secrets_edit.rb +34 -0
- data/cli/secrets_key.rb +20 -0
- data/lib/hippo.rb +19 -0
- data/lib/hippo/cli.rb +210 -0
- data/lib/hippo/deployment_monitor.rb +82 -0
- data/lib/hippo/error.rb +0 -12
- data/lib/hippo/image.rb +74 -0
- data/lib/hippo/manifest.rb +81 -0
- data/lib/hippo/object_definition.rb +63 -0
- data/lib/hippo/secret.rb +61 -114
- data/lib/hippo/secret_manager.rb +43 -32
- data/lib/hippo/stage.rb +157 -7
- data/lib/hippo/util.rb +56 -33
- data/lib/hippo/version.rb +1 -1
- data/template/Hippofile +12 -13
- data/template/config/{production/env-vars.yaml → env-vars.yaml} +0 -0
- data/template/jobs/{upgrade → deploy}/db-migration.yaml +0 -0
- data/template/stages/production.yaml +1 -0
- metadata +31 -16
- metadata.gz.sig +0 -0
- data/cli/build.rb +0 -16
- data/cli/edit-secret.rb +0 -45
- data/cli/objects.rb +0 -34
- data/cli/publish.rb +0 -17
- data/cli/secrets.rb +0 -23
- data/cli/status.rb +0 -15
- data/lib/hippo/build_spec.rb +0 -32
- data/lib/hippo/cli_steps.rb +0 -315
- data/lib/hippo/kubernetes.rb +0 -200
- data/lib/hippo/recipe.rb +0 -126
- data/lib/hippo/repository.rb +0 -122
- data/lib/hippo/yaml_part.rb +0 -47
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hippo-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Cooke
|
@@ -30,8 +30,28 @@ cert_chain:
|
|
30
30
|
3wUJNGnT5XYq+qvTqmjkTSTfdGvZCM63C6bGdN5CAyMokGOOatGqyCMAONolWnfC
|
31
31
|
gm3t2GWWrxY=
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2020-01
|
33
|
+
date: 2020-02-01 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: encryptor
|
37
|
+
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '3.0'
|
42
|
+
- - "<"
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '4.0'
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '3.0'
|
52
|
+
- - "<"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.0'
|
35
55
|
- !ruby/object:Gem::Dependency
|
36
56
|
name: git
|
37
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -103,37 +123,32 @@ files:
|
|
103
123
|
- bin/hippo
|
104
124
|
- cli/apply_config.rb
|
105
125
|
- cli/apply_services.rb
|
106
|
-
- cli/build.rb
|
107
126
|
- cli/console.rb
|
108
127
|
- cli/deploy.rb
|
109
|
-
- cli/edit-secret.rb
|
110
128
|
- cli/help.rb
|
111
129
|
- cli/init.rb
|
112
130
|
- cli/install.rb
|
113
131
|
- cli/kubectl.rb
|
114
|
-
- cli/
|
115
|
-
- cli/
|
116
|
-
- cli/secrets.rb
|
117
|
-
- cli/status.rb
|
132
|
+
- cli/secrets_edit.rb
|
133
|
+
- cli/secrets_key.rb
|
118
134
|
- lib/hippo.rb
|
119
|
-
- lib/hippo/
|
120
|
-
- lib/hippo/
|
135
|
+
- lib/hippo/cli.rb
|
136
|
+
- lib/hippo/deployment_monitor.rb
|
121
137
|
- lib/hippo/error.rb
|
122
|
-
- lib/hippo/
|
123
|
-
- lib/hippo/
|
124
|
-
- lib/hippo/
|
138
|
+
- lib/hippo/image.rb
|
139
|
+
- lib/hippo/manifest.rb
|
140
|
+
- lib/hippo/object_definition.rb
|
125
141
|
- lib/hippo/secret.rb
|
126
142
|
- lib/hippo/secret_manager.rb
|
127
143
|
- lib/hippo/stage.rb
|
128
144
|
- lib/hippo/util.rb
|
129
145
|
- lib/hippo/version.rb
|
130
|
-
- lib/hippo/yaml_part.rb
|
131
146
|
- template/Hippofile
|
132
|
-
- template/config/
|
147
|
+
- template/config/env-vars.yaml
|
133
148
|
- template/deployments/web.yaml
|
134
149
|
- template/deployments/worker.yaml
|
150
|
+
- template/jobs/deploy/db-migration.yaml
|
135
151
|
- template/jobs/install/load-schema.yaml
|
136
|
-
- template/jobs/upgrade/db-migration.yaml
|
137
152
|
- template/services/main.ingress.yaml
|
138
153
|
- template/services/web.svc.yaml
|
139
154
|
- template/stages/production.yaml
|
metadata.gz.sig
CHANGED
Binary file
|
data/cli/build.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
command :build do
|
4
|
-
desc 'Build an image for the given 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
|
-
action do |context|
|
11
|
-
require 'hippo/cli_steps'
|
12
|
-
steps = Hippo::CLISteps.setup(context)
|
13
|
-
steps.prepare_repository
|
14
|
-
steps.build
|
15
|
-
end
|
16
|
-
end
|
data/cli/edit-secret.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
command :'edit-secret' do
|
4
|
-
desc 'Create/edit an encrypted secrets file'
|
5
|
-
|
6
|
-
option '--create-key', 'Create a new encryption key if missing' do |_value, options|
|
7
|
-
options[:create_key] = true
|
8
|
-
end
|
9
|
-
|
10
|
-
action do |context|
|
11
|
-
require 'hippo/cli_steps'
|
12
|
-
steps = Hippo::CLISteps.setup(context)
|
13
|
-
|
14
|
-
secret_name = context.args[0]
|
15
|
-
raise Hippo::Error, 'You must provide a secret name' if secret_name.nil?
|
16
|
-
|
17
|
-
require 'hippo/secret_manager'
|
18
|
-
manager = Hippo::SecretManager.new(steps.recipe, steps.stage)
|
19
|
-
if !manager.key_available? && context.options[:create_key]
|
20
|
-
manager.create_key
|
21
|
-
elsif !manager.key_available?
|
22
|
-
puts "\e[31mNo key has been published for this stage yet. You can create"
|
23
|
-
puts "a key automatically by adding --create-key to this command.\e[0m"
|
24
|
-
exit 2
|
25
|
-
elsif context.options[:create_key]
|
26
|
-
puts "\e[31mThe --create-key option can only be provided when a key has not already"
|
27
|
-
puts "been generated. Remove the key from the Kubernetes API to regenerate.\e[0m"
|
28
|
-
exit 2
|
29
|
-
end
|
30
|
-
|
31
|
-
secret = manager.secret(secret_name)
|
32
|
-
if secret.exists?
|
33
|
-
secret.edit
|
34
|
-
else
|
35
|
-
puts "No secret exists at #{secret.path}. Would you like to create one?"
|
36
|
-
response = STDIN.gets.strip.downcase.strip
|
37
|
-
if %w[y yes please].include?(response)
|
38
|
-
secret.create
|
39
|
-
secret.edit
|
40
|
-
else
|
41
|
-
puts 'Not a problem. You can make it later.'
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
data/cli/objects.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
command :objects do
|
4
|
-
desc 'Build and publish an image for the given 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 '--types [TYPES]', 'The types of objects you wish to see' do |value, options|
|
11
|
-
options[:types] = value.split(/,/)
|
12
|
-
end
|
13
|
-
|
14
|
-
action do |context|
|
15
|
-
require 'hippo/cli_steps'
|
16
|
-
steps = Hippo::CLISteps.setup(context)
|
17
|
-
commit = steps.prepare_repository(fetch: false)
|
18
|
-
|
19
|
-
if context.options[:types].nil? || context.options[:types].include?('all')
|
20
|
-
types = Hippo::Kubernetes::OBJECT_DIRECTORY_NAMES
|
21
|
-
else
|
22
|
-
types = context.options[:types]
|
23
|
-
end
|
24
|
-
|
25
|
-
objects = []
|
26
|
-
types.each do |type|
|
27
|
-
next unless Hippo::Kubernetes::OBJECT_DIRECTORY_NAMES.include?(type)
|
28
|
-
|
29
|
-
objects += steps.recipe.kubernetes.objects(type, steps.stage, commit, deploy_id: 'preview')
|
30
|
-
end
|
31
|
-
|
32
|
-
puts objects.map { |o| o.hash.to_yaml }
|
33
|
-
end
|
34
|
-
end
|
data/cli/publish.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
command :publish do
|
4
|
-
desc 'Build and publish an image for the given 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
|
-
action do |context|
|
11
|
-
require 'hippo/cli_steps'
|
12
|
-
steps = Hippo::CLISteps.setup(context)
|
13
|
-
steps.prepare_repository
|
14
|
-
steps.build
|
15
|
-
steps.publish
|
16
|
-
end
|
17
|
-
end
|
data/cli/secrets.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
command :secrets do
|
4
|
-
desc 'View all secrets'
|
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_steps'
|
12
|
-
cli = Hippo::CLISteps.setup(context)
|
13
|
-
|
14
|
-
require 'hippo/secret_manager'
|
15
|
-
manager = Hippo::SecretManager.new(cli.recipe, cli.stage)
|
16
|
-
unless manager.key_available?
|
17
|
-
puts "\e[31mNo key has been published for this stage yet.\e[0m"
|
18
|
-
exit 2
|
19
|
-
end
|
20
|
-
|
21
|
-
puts manager.secrets.map(&:to_editable_yaml)
|
22
|
-
end
|
23
|
-
end
|
data/cli/status.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
command :status do
|
4
|
-
desc 'Print status information from Kubernetes'
|
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_steps'
|
12
|
-
cli = Hippo::CLISteps.setup(context)
|
13
|
-
exec cli.stage.kubectl('get pods,deployments,job,statefulset,pvc,svc,ingress')
|
14
|
-
end
|
15
|
-
end
|
data/lib/hippo/build_spec.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Hippo
|
4
|
-
class BuildSpec
|
5
|
-
attr_reader :name
|
6
|
-
|
7
|
-
def initialize(recipe, name, options)
|
8
|
-
@recipe = recipe
|
9
|
-
@name = name
|
10
|
-
@options = options
|
11
|
-
end
|
12
|
-
|
13
|
-
def dockerfile
|
14
|
-
@options['dockerfile'] || 'Dockerfile'
|
15
|
-
end
|
16
|
-
|
17
|
-
def image_name
|
18
|
-
@options['image-name']
|
19
|
-
end
|
20
|
-
|
21
|
-
def image_name_for_commit(commit_ref)
|
22
|
-
"#{image_name}:#{commit_ref}"
|
23
|
-
end
|
24
|
-
|
25
|
-
def template_vars
|
26
|
-
{
|
27
|
-
'dockerfile' => dockerfile,
|
28
|
-
'image-name' => image_name
|
29
|
-
}
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
data/lib/hippo/cli_steps.rb
DELETED
@@ -1,315 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'open3'
|
4
|
-
require 'digest'
|
5
|
-
require 'hippo/error'
|
6
|
-
require 'hippo/recipe'
|
7
|
-
|
8
|
-
module Hippo
|
9
|
-
class CLISteps
|
10
|
-
attr_reader :recipe
|
11
|
-
attr_reader :stage
|
12
|
-
|
13
|
-
def initialize(recipe, stage)
|
14
|
-
@recipe = recipe
|
15
|
-
@stage = stage
|
16
|
-
end
|
17
|
-
|
18
|
-
# Prepare the repository for this build by getting the latest
|
19
|
-
# version from the remote and checking out the branch.
|
20
|
-
def prepare_repository(fetch: true)
|
21
|
-
info "Using repository #{@recipe.repository.url}"
|
22
|
-
if fetch
|
23
|
-
if @recipe.repository.cloned?
|
24
|
-
info 'Repository is already cloned'
|
25
|
-
action 'Fetching the latest repository data...'
|
26
|
-
@recipe.repository.fetch
|
27
|
-
else
|
28
|
-
info 'Repository is not yet cloned.'
|
29
|
-
action 'Cloning repository...'
|
30
|
-
@recipe.repository.clone
|
31
|
-
end
|
32
|
-
|
33
|
-
elsif !fetch && !@recipe.repository.cloned?
|
34
|
-
raise Error, 'Repository is not cloned yet so cannot continue'
|
35
|
-
else
|
36
|
-
info 'Not fetching latest repository, using cached copy'
|
37
|
-
end
|
38
|
-
|
39
|
-
action "Checking out '#{@stage.branch}' branch..."
|
40
|
-
@recipe.repository.checkout(@stage.branch)
|
41
|
-
@commit = @recipe.repository.commit
|
42
|
-
info "Latest commit on branch is #{@commit.objectish}"
|
43
|
-
info "Message: #{@commit.message.split("\n").first}"
|
44
|
-
@commit
|
45
|
-
end
|
46
|
-
|
47
|
-
def build
|
48
|
-
if @commit.nil?
|
49
|
-
raise Error, 'You cannot build without first preparing the repository'
|
50
|
-
end
|
51
|
-
|
52
|
-
Dir.chdir(@recipe.repository.path) do
|
53
|
-
@recipe.build_specs.each do |_, build_spec|
|
54
|
-
if build_spec.image_name.nil?
|
55
|
-
raise Error, "No image-name has been specified for build #{build_spec.name}"
|
56
|
-
end
|
57
|
-
|
58
|
-
image_name = build_spec.image_name_for_commit(@commit)
|
59
|
-
action "Building #{build_spec.name} with tag #{image_name}"
|
60
|
-
|
61
|
-
command = [
|
62
|
-
'docker', 'build', '.',
|
63
|
-
'-f', build_spec.dockerfile,
|
64
|
-
'-t', image_name,
|
65
|
-
'--build-arg', "commit_ref=#{@commit.objectish}"
|
66
|
-
]
|
67
|
-
external_command do
|
68
|
-
if system(*command)
|
69
|
-
@built_commit = @commit
|
70
|
-
success "Successfully built image #{build_spec.image_name} for #{build_spec.name}"
|
71
|
-
else
|
72
|
-
raise Error, "Image for #{build_spec.name} did not succeed. Check output and try again."
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def publish
|
80
|
-
if @built_commit.nil?
|
81
|
-
raise Error, 'You cannot publish without first building the image'
|
82
|
-
end
|
83
|
-
|
84
|
-
Dir.chdir(@recipe.repository.path) do
|
85
|
-
@recipe.build_specs.each do |_, build_spec|
|
86
|
-
if build_spec.image_name.nil?
|
87
|
-
raise Error, "No image-name has been specified for build #{build_spec.name}"
|
88
|
-
end
|
89
|
-
|
90
|
-
image_name = build_spec.image_name_for_commit(@built_commit.objectish)
|
91
|
-
action "Publishing #{build_spec.name} with tag #{image_name}"
|
92
|
-
|
93
|
-
command = ['docker', 'push', image_name]
|
94
|
-
external_command do
|
95
|
-
if system(*command)
|
96
|
-
success "Successfully published image #{image_name} for #{build_spec.name}"
|
97
|
-
else
|
98
|
-
raise Error, "Image for #{build_spec.name} was not published successfully. Check output and try again."
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def run_install_jobs
|
106
|
-
run_jobs('install')
|
107
|
-
end
|
108
|
-
|
109
|
-
def run_deploy_jobs
|
110
|
-
run_jobs('deploy')
|
111
|
-
end
|
112
|
-
|
113
|
-
def deploy
|
114
|
-
action 'Applying deployments'
|
115
|
-
@deploy_id = Digest::SHA1.hexdigest(Time.now.to_f.to_s)[0, 10]
|
116
|
-
deployments = @recipe.kubernetes.objects('deployments', @stage, @commit, deploy_id: @deploy_id)
|
117
|
-
|
118
|
-
if deployments.nil?
|
119
|
-
info 'No deployments file configured. Not applying any deployments'
|
120
|
-
end
|
121
|
-
|
122
|
-
external_command do
|
123
|
-
@recipe.kubernetes.apply_with_kubectl(@stage, deployments)
|
124
|
-
end
|
125
|
-
success 'Deployments applied successfully'
|
126
|
-
puts 'Waiting for all deployments to rollout...'
|
127
|
-
|
128
|
-
count = 0
|
129
|
-
loop do
|
130
|
-
sleep 4
|
131
|
-
count += 1
|
132
|
-
replica_sets = @recipe.kubernetes.get_with_kubectl(@stage, [
|
133
|
-
'rs',
|
134
|
-
'--selector',
|
135
|
-
'hippo.adam.ac/deployID=' + @deploy_id
|
136
|
-
])
|
137
|
-
pending_replica_sets = replica_sets.reject do |deploy|
|
138
|
-
deploy['status']['availableReplicas'] == deploy['status']['replicas']
|
139
|
-
end
|
140
|
-
|
141
|
-
names = replica_sets.map { |d| d['metadata']['name'].split('-').first }.join(', ')
|
142
|
-
|
143
|
-
if pending_replica_sets.empty?
|
144
|
-
success 'All deployments have rolled out successfully.'
|
145
|
-
puts
|
146
|
-
replica_sets.each do |rs|
|
147
|
-
name = rs['metadata']['name'].split('-').first
|
148
|
-
quantity = rs['status']['availableReplicas']
|
149
|
-
puts " * \e[35m#{name}\e[0m has #{quantity} #{quantity == 1 ? 'replica' : 'replicas'}"
|
150
|
-
end
|
151
|
-
puts
|
152
|
-
break
|
153
|
-
else
|
154
|
-
if count == 15
|
155
|
-
error "Looks like things aren't going to plan with some deployments."
|
156
|
-
puts 'You can review potential issues using the commads below:'
|
157
|
-
pending_replica_sets.each do |rs|
|
158
|
-
puts
|
159
|
-
name = rs['metadata']['name'].split('-').first
|
160
|
-
puts " hippo #{stage.name} kubectl -- describe deployment \e[35m#{name}\e[0m"
|
161
|
-
puts " hippo #{stage.name} kubectl -- logs deployment/\e[35m#{name}\e[0m --all-containers"
|
162
|
-
end
|
163
|
-
puts
|
164
|
-
|
165
|
-
break
|
166
|
-
else
|
167
|
-
puts 'Waiting for ' + pending_replica_sets.map { |rs| rs['metadata']['name'].split('-').first }.join(', ')
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
def apply_services
|
174
|
-
action 'Applying services'
|
175
|
-
objects = @recipe.kubernetes.objects('services', @stage, @commit)
|
176
|
-
if objects.empty?
|
177
|
-
info 'No services have been defined'
|
178
|
-
else
|
179
|
-
external_command do
|
180
|
-
@recipe.kubernetes.apply_with_kubectl(@stage, objects)
|
181
|
-
end
|
182
|
-
success 'Services applied successfully'
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
def apply_namespace
|
187
|
-
action 'Applying namespace'
|
188
|
-
external_command { @recipe.kubernetes.apply_namespace(@stage) }
|
189
|
-
success 'Namespace applied successfully'
|
190
|
-
end
|
191
|
-
|
192
|
-
def apply_config
|
193
|
-
action 'Applying configuration'
|
194
|
-
objects = @recipe.kubernetes.objects('config', @stage, @commit)
|
195
|
-
if objects.empty?
|
196
|
-
info 'No configuration files have been defined'
|
197
|
-
else
|
198
|
-
external_command do
|
199
|
-
@recipe.kubernetes.apply_with_kubectl(@stage, objects)
|
200
|
-
end
|
201
|
-
success 'Configuration applied successfully'
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
def apply_secrets
|
206
|
-
require 'hippo/secret_manager'
|
207
|
-
action 'Applying secrets'
|
208
|
-
manager = SecretManager.new(@recipe, @stage)
|
209
|
-
unless manager.key_available?
|
210
|
-
error 'No secret encryption key was available. Not applying secrets.'
|
211
|
-
return
|
212
|
-
end
|
213
|
-
|
214
|
-
yamls = manager.secrets.map(&:to_secret_yaml).join("---\n")
|
215
|
-
external_command do
|
216
|
-
@recipe.kubernetes.apply_with_kubectl(@stage, yamls)
|
217
|
-
end
|
218
|
-
success 'Secrets applicated successfully'
|
219
|
-
end
|
220
|
-
|
221
|
-
private
|
222
|
-
|
223
|
-
def info(text)
|
224
|
-
puts text
|
225
|
-
end
|
226
|
-
|
227
|
-
def success(text)
|
228
|
-
puts "\e[32m#{text}\e[0m"
|
229
|
-
end
|
230
|
-
|
231
|
-
def action(text)
|
232
|
-
puts "\e[33m#{text}\e[0m"
|
233
|
-
end
|
234
|
-
|
235
|
-
def error(text)
|
236
|
-
puts "\e[31m#{text}\e[0m"
|
237
|
-
end
|
238
|
-
|
239
|
-
def external_command
|
240
|
-
$stdout.print "\e[37m"
|
241
|
-
yield
|
242
|
-
ensure
|
243
|
-
$stdout.print "\e[0m"
|
244
|
-
end
|
245
|
-
|
246
|
-
def run_jobs(type)
|
247
|
-
objects = @recipe.kubernetes.objects("jobs/#{type}", @stage, @commit)
|
248
|
-
if objects.empty?
|
249
|
-
info "No #{type} jobs exist so not applying anything"
|
250
|
-
return true
|
251
|
-
end
|
252
|
-
|
253
|
-
action "Applying #{type} job objects objects to Kubernetes"
|
254
|
-
|
255
|
-
result = nil
|
256
|
-
external_command do
|
257
|
-
# Remove any previous jobs that might have been running before
|
258
|
-
objects.each do |job|
|
259
|
-
@recipe.kubernetes.delete_job(@stage, job['metadata']['name'])
|
260
|
-
end
|
261
|
-
|
262
|
-
result = @recipe.kubernetes.apply_with_kubectl(@stage, objects)
|
263
|
-
end
|
264
|
-
|
265
|
-
puts 'Waiting for all scheduled jobs to finish...'
|
266
|
-
timeout, jobs = @recipe.kubernetes.wait_for_jobs(@stage, result.keys)
|
267
|
-
success_jobs = []
|
268
|
-
failed_jobs = []
|
269
|
-
jobs.each do |job|
|
270
|
-
if job['status']['succeeded']
|
271
|
-
success_jobs << job
|
272
|
-
else
|
273
|
-
failed_jobs << job
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
if success_jobs.size == jobs.size
|
278
|
-
success 'All jobs completed successfully.'
|
279
|
-
puts 'You can review the logs for these by running the commands below.'
|
280
|
-
puts
|
281
|
-
result = true
|
282
|
-
else
|
283
|
-
error 'Not all install jobs completed successfully.'
|
284
|
-
puts 'You should review the logs for these using the commands below.'
|
285
|
-
puts
|
286
|
-
result = false
|
287
|
-
end
|
288
|
-
|
289
|
-
jobs.each do |job|
|
290
|
-
icon = if job['status']['succeeded']
|
291
|
-
'✅'
|
292
|
-
else
|
293
|
-
'❌'
|
294
|
-
end
|
295
|
-
puts " #{icon} " + @stage.kubectl("logs job/#{job['metadata']['name']}")
|
296
|
-
end
|
297
|
-
puts
|
298
|
-
|
299
|
-
result
|
300
|
-
end
|
301
|
-
|
302
|
-
class << self
|
303
|
-
def setup(context)
|
304
|
-
recipe = Hippo::Recipe.load_from_file(context.options[:hippofile] || './Hippofile')
|
305
|
-
|
306
|
-
stage = recipe.stages[CURRENT_STAGE]
|
307
|
-
if stage.nil?
|
308
|
-
raise Error, "Invalid stage name `#{CURRENT_STAGE}`. Check this has been defined in in your stages directory with a matching name?"
|
309
|
-
end
|
310
|
-
|
311
|
-
new(recipe, stage)
|
312
|
-
end
|
313
|
-
end
|
314
|
-
end
|
315
|
-
end
|