hippo-cli 1.0.0 → 1.0.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.
- 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
|