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