hippo-cli 1.0.0 → 1.0.1
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/cli/kubectl.rb +2 -1
- data/cli/objects.rb +1 -1
- data/lib/hippo/cli_steps.rb +54 -13
- data/lib/hippo/kubernetes.rb +25 -25
- data/lib/hippo/repository.rb +1 -1
- data/lib/hippo/secret_manager.rb +1 -1
- data/lib/hippo/stage.rb +12 -1
- data/lib/hippo/version.rb +3 -1
- data.tar.gz.sig +0 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d9636ec9f0d56f6cd5633d73bee77605fb30383c3bd5d793c6245db0720b30a
|
4
|
+
data.tar.gz: d1dbc5b162c243d4cc1806e8d15ce5e7f59a7ad631d0ac75986e1003afcc5380
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65da298f8f79ba3b5bf954e67283d8aa5340b0f02276c1c85110f7fcdba305dc64a8aee0075196a1bdf807476d9282ae3211174ad21c6d2708286b44784b87bc
|
7
|
+
data.tar.gz: 9ec88a924598b71181da03ea899adec5472633d97eee8cae6c57bf30e8cf833df93458177ba096937aa7f2f834ac0b06f70051a041fae80af5fc661c0a0fa1ea
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/cli/kubectl.rb
CHANGED
data/cli/objects.rb
CHANGED
@@ -26,7 +26,7 @@ command :objects do
|
|
26
26
|
types.each do |type|
|
27
27
|
next unless Hippo::Kubernetes::OBJECT_DIRECTORY_NAMES.include?(type)
|
28
28
|
|
29
|
-
objects
|
29
|
+
objects += steps.recipe.kubernetes.objects(type, steps.stage, commit, deploy_id: 'preview')
|
30
30
|
end
|
31
31
|
|
32
32
|
puts objects.map { |o| o.hash.to_yaml }
|
data/lib/hippo/cli_steps.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'open3'
|
4
|
+
require 'digest'
|
4
5
|
require 'hippo/error'
|
5
6
|
require 'hippo/recipe'
|
6
7
|
|
@@ -60,7 +61,8 @@ module Hippo
|
|
60
61
|
command = [
|
61
62
|
'docker', 'build', '.',
|
62
63
|
'-f', build_spec.dockerfile,
|
63
|
-
'-t', image_name
|
64
|
+
'-t', image_name,
|
65
|
+
'--build-arg', "commit_ref=#{@commit.objectish}"
|
64
66
|
]
|
65
67
|
external_command do
|
66
68
|
if system(*command)
|
@@ -110,23 +112,62 @@ module Hippo
|
|
110
112
|
|
111
113
|
def deploy
|
112
114
|
action 'Applying deployments'
|
113
|
-
|
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)
|
114
117
|
|
115
118
|
if deployments.nil?
|
116
119
|
info 'No deployments file configured. Not applying any deployments'
|
117
120
|
end
|
118
121
|
|
119
122
|
external_command do
|
120
|
-
@recipe.kubernetes.apply_with_kubectl(deployments)
|
123
|
+
@recipe.kubernetes.apply_with_kubectl(@stage, deployments)
|
121
124
|
end
|
122
125
|
success 'Deployments applied successfully'
|
123
|
-
puts '
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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
|
128
170
|
end
|
129
|
-
puts
|
130
171
|
end
|
131
172
|
|
132
173
|
def apply_services
|
@@ -136,7 +177,7 @@ module Hippo
|
|
136
177
|
info 'No services have been defined'
|
137
178
|
else
|
138
179
|
external_command do
|
139
|
-
@recipe.kubernetes.apply_with_kubectl(objects)
|
180
|
+
@recipe.kubernetes.apply_with_kubectl(@stage, objects)
|
140
181
|
end
|
141
182
|
success 'Services applied successfully'
|
142
183
|
end
|
@@ -155,7 +196,7 @@ module Hippo
|
|
155
196
|
info 'No configuration files have been defined'
|
156
197
|
else
|
157
198
|
external_command do
|
158
|
-
@recipe.kubernetes.apply_with_kubectl(objects)
|
199
|
+
@recipe.kubernetes.apply_with_kubectl(@stage, objects)
|
159
200
|
end
|
160
201
|
success 'Configuration applied successfully'
|
161
202
|
end
|
@@ -172,7 +213,7 @@ module Hippo
|
|
172
213
|
|
173
214
|
yamls = manager.secrets.map(&:to_secret_yaml).join("---\n")
|
174
215
|
external_command do
|
175
|
-
@recipe.kubernetes.apply_with_kubectl(yamls)
|
216
|
+
@recipe.kubernetes.apply_with_kubectl(@stage, yamls)
|
176
217
|
end
|
177
218
|
success 'Secrets applicated successfully'
|
178
219
|
end
|
@@ -218,7 +259,7 @@ module Hippo
|
|
218
259
|
@recipe.kubernetes.delete_job(@stage, job['metadata']['name'])
|
219
260
|
end
|
220
261
|
|
221
|
-
result = @recipe.kubernetes.apply_with_kubectl(objects)
|
262
|
+
result = @recipe.kubernetes.apply_with_kubectl(@stage, objects)
|
222
263
|
end
|
223
264
|
|
224
265
|
puts 'Waiting for all scheduled jobs to finish...'
|
data/lib/hippo/kubernetes.rb
CHANGED
@@ -22,7 +22,7 @@ module Hippo
|
|
22
22
|
# @param commit [String] the commit ref
|
23
23
|
# @param path [String]
|
24
24
|
# @return
|
25
|
-
def objects(path, stage, commit)
|
25
|
+
def objects(path, stage, commit, deploy_id: nil)
|
26
26
|
time = Time.now
|
27
27
|
|
28
28
|
yamls = load_yaml_from_directory(path)
|
@@ -38,28 +38,33 @@ module Hippo
|
|
38
38
|
object['metadata']['namespace'] = stage.namespace
|
39
39
|
end
|
40
40
|
|
41
|
-
# Add our own details to the metadata of all objets created by us so
|
42
|
-
# we know where they came from.
|
43
41
|
object['metadata']['annotations'] ||= {}
|
44
|
-
object['metadata']['
|
45
|
-
object['metadata']['annotations']['hippo.adam.ac/builtBy'] ||= ENV['USER'] || 'unknown'
|
42
|
+
object['metadata']['labels'] ||= {}
|
46
43
|
|
47
44
|
add_default_labels(object, stage)
|
48
45
|
|
49
46
|
# Add some information to Deployments to reflect the latest
|
50
47
|
# information about this deployment.
|
51
48
|
if object['kind'] == 'Deployment'
|
52
|
-
|
49
|
+
if deploy_id
|
50
|
+
object['metadata']['labels']['hippo.adam.ac/deployID'] ||= deploy_id
|
51
|
+
end
|
52
|
+
|
53
53
|
if commit
|
54
54
|
object['metadata']['annotations']['hippo.adam.ac/commitRef'] ||= commit.objectish
|
55
55
|
object['metadata']['annotations']['hippo.adam.ac/commitMessage'] ||= commit.message
|
56
56
|
end
|
57
57
|
|
58
58
|
if pod_metadata = object.dig('spec', 'template', 'metadata')
|
59
|
+
pod_metadata['labels'] ||= {}
|
59
60
|
pod_metadata['annotations'] ||= {}
|
60
|
-
pod_metadata
|
61
|
+
# add_default_labels(pod_metadata, stage)
|
62
|
+
if deploy_id
|
63
|
+
pod_metadata['labels']['hippo.adam.ac/deployID'] = deploy_id
|
64
|
+
end
|
65
|
+
|
61
66
|
if commit
|
62
|
-
pod_metadata['annotations']['hippo.adam.ac/commitRef']
|
67
|
+
pod_metadata['annotations']['hippo.adam.ac/commitRef'] = commit.objectish
|
63
68
|
end
|
64
69
|
end
|
65
70
|
end
|
@@ -77,20 +82,24 @@ module Hippo
|
|
77
82
|
}
|
78
83
|
}
|
79
84
|
add_default_labels(namespace, stage)
|
80
|
-
apply_with_kubectl(namespace.to_yaml)
|
85
|
+
apply_with_kubectl(stage, namespace.to_yaml)
|
81
86
|
end
|
82
87
|
|
83
88
|
# Apply the given configuration with kubectl
|
84
89
|
#
|
85
90
|
# @param config [Array<Hippo::YAMLPart>, String]
|
86
91
|
# @return [void]
|
87
|
-
def apply_with_kubectl(yaml_parts)
|
92
|
+
def apply_with_kubectl(stage, yaml_parts)
|
88
93
|
unless yaml_parts.is_a?(String)
|
89
94
|
yaml_parts = [yaml_parts] unless yaml_parts.is_a?(Array)
|
90
95
|
yaml_parts = yaml_parts.map { |yp| yp.hash.to_yaml }.join("\n---\n")
|
91
96
|
end
|
92
97
|
|
93
|
-
|
98
|
+
command = ['kubectl']
|
99
|
+
command += ['--context', stage.context] if stage.context
|
100
|
+
command += ['apply', '-f', '-']
|
101
|
+
|
102
|
+
Open3.popen3(command.join(' ')) do |stdin, stdout, stderr, wt|
|
94
103
|
stdin.puts yaml_parts
|
95
104
|
stdin.close
|
96
105
|
|
@@ -117,13 +126,9 @@ module Hippo
|
|
117
126
|
# @raises [Hippo::Error]
|
118
127
|
# @return [Array<Hash>]
|
119
128
|
def get_with_kubectl(stage, *names)
|
120
|
-
command =
|
121
|
-
|
122
|
-
|
123
|
-
'get',
|
124
|
-
names,
|
125
|
-
'-o', 'yaml'
|
126
|
-
].flatten.reject(&:nil?)
|
129
|
+
command = stage.kubectl_base_command
|
130
|
+
command += ['get', names, '-o', 'yaml']
|
131
|
+
command = command.flatten.reject(&:nil?)
|
127
132
|
|
128
133
|
Open3.popen3(*command) do |_, stdout, stderr, wt|
|
129
134
|
if wt.value.success?
|
@@ -142,13 +147,8 @@ module Hippo
|
|
142
147
|
# @raises [Hippo::Error]
|
143
148
|
# @return [void]
|
144
149
|
def delete_job(stage, name)
|
145
|
-
command =
|
146
|
-
|
147
|
-
'-n', stage.namespace,
|
148
|
-
'delete',
|
149
|
-
'job',
|
150
|
-
name
|
151
|
-
]
|
150
|
+
command = stage.kubectl_base_command
|
151
|
+
command += ['delete', 'job', name]
|
152
152
|
|
153
153
|
Open3.popen3(*command) do |_, stdout, stderr, wt|
|
154
154
|
if wt.value.success?
|
data/lib/hippo/repository.rb
CHANGED
data/lib/hippo/secret_manager.rb
CHANGED
@@ -34,7 +34,7 @@ module Hippo
|
|
34
34
|
'metadata' => { 'name' => 'hippo-secret-key', 'namespace' => @stage.namespace },
|
35
35
|
'data' => { 'key' => Base64.encode64(secret_key64).gsub("\n", '').strip }
|
36
36
|
}
|
37
|
-
@recipe.kubernetes.apply_with_kubectl(object.to_yaml)
|
37
|
+
@recipe.kubernetes.apply_with_kubectl(@stage, object.to_yaml)
|
38
38
|
@key = secret_key
|
39
39
|
end
|
40
40
|
|
data/lib/hippo/stage.rb
CHANGED
@@ -18,6 +18,10 @@ module Hippo
|
|
18
18
|
@options['namespace']
|
19
19
|
end
|
20
20
|
|
21
|
+
def context
|
22
|
+
@options['context']
|
23
|
+
end
|
24
|
+
|
21
25
|
def template_vars
|
22
26
|
{
|
23
27
|
'name' => name,
|
@@ -28,7 +32,14 @@ module Hippo
|
|
28
32
|
end
|
29
33
|
|
30
34
|
def kubectl(*command)
|
31
|
-
|
35
|
+
(kubectl_base_command + command).join(' ')
|
36
|
+
end
|
37
|
+
|
38
|
+
def kubectl_base_command
|
39
|
+
command = ['kubectl']
|
40
|
+
command += ['--context', context] if context
|
41
|
+
command += ['-n', namespace]
|
42
|
+
command
|
32
43
|
end
|
33
44
|
end
|
34
45
|
end
|
data/lib/hippo/version.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
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.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Cooke
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
3wUJNGnT5XYq+qvTqmjkTSTfdGvZCM63C6bGdN5CAyMokGOOatGqyCMAONolWnfC
|
31
31
|
gm3t2GWWrxY=
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2020-01-
|
33
|
+
date: 2020-01-29 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: git
|
metadata.gz.sig
CHANGED
Binary file
|