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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 432cb14031538080436b685d9bffb44890296eb4ee2e001f47112d0a60cf10ae
4
- data.tar.gz: 155f1cfd1ef594b9ad3e863bb40c3ca89df2bbbb77a5b3657ea6abd4dd324d39
3
+ metadata.gz: 4d9636ec9f0d56f6cd5633d73bee77605fb30383c3bd5d793c6245db0720b30a
4
+ data.tar.gz: d1dbc5b162c243d4cc1806e8d15ce5e7f59a7ad631d0ac75986e1003afcc5380
5
5
  SHA512:
6
- metadata.gz: dbf149c3462eaf4b7b2fcba7afe450d3a60c472a671ba117a991db9db2ae7b94d3f72c2e2f708cc2d316f1dcadb00e5a60e637bdf3d9dc27af724e5f7595da33
7
- data.tar.gz: ce1c8ab412478c7d4dc13a3d975d2734c2ad60a75dfd43e60b95fec1c9493a232036056977e395ee6da021a871fef51c7827419eb11395e6c296475a537601ce
6
+ metadata.gz: 65da298f8f79ba3b5bf954e67283d8aa5340b0f02276c1c85110f7fcdba305dc64a8aee0075196a1bdf807476d9282ae3211174ad21c6d2708286b44784b87bc
7
+ data.tar.gz: 9ec88a924598b71181da03ea899adec5472633d97eee8cae6c57bf30e8cf833df93458177ba096937aa7f2f834ac0b06f70051a041fae80af5fc661c0a0fa1ea
checksums.yaml.gz.sig CHANGED
Binary file
data/cli/kubectl.rb CHANGED
@@ -10,7 +10,8 @@ command :kubectl do
10
10
  action do |context|
11
11
  require 'hippo/cli_steps'
12
12
  cli = Hippo::CLISteps.setup(context)
13
- ARGV.shift
13
+ ARGV.shift(2)
14
+ ARGV.delete('--')
14
15
  exec cli.stage.kubectl(*ARGV)
15
16
  end
16
17
  end
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 |= steps.recipe.kubernetes.objects(type, steps.stage, commit)
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 }
@@ -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
- deployments = @recipe.kubernetes.objects('deployments', @stage, @commit)
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 'You can watch the deployment progressing using the command below:'
124
- puts
125
- puts " ⏰ #{@stage.kubectl('get pods --watch')}"
126
- deployments.each do |deployment|
127
- puts ' 👩🏼‍💻 ' + @stage.kubectl("describe deployment #{deployment['metadata']['name']}")
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...'
@@ -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']['annotations']['hippo.adam.ac/builtAt'] ||= time.to_s
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
- object['metadata']['annotations']['hippo.adam.ac/deployID'] ||= time.to_i.to_s
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['annotations']['hippo.adam.ac/deployID'] ||= time.to_i.to_s
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'] ||= commit.objectish
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
- Open3.popen3('kubectl apply -f -') do |stdin, stdout, stderr, wt|
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
- 'kubectl',
122
- '-n', stage.namespace,
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
- 'kubectl',
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?
@@ -23,7 +23,7 @@ module Hippo
23
23
 
24
24
  @path ||= begin
25
25
  digest = Digest::SHA256.hexdigest(url)
26
- File.join('', 'tmp', 'hippo-repos', digest)
26
+ File.join(ENV['HOME'], '.hippo', 'repos', digest)
27
27
  end
28
28
  end
29
29
 
@@ -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
- "kubectl -n #{namespace} #{command.join(' ')}"
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hippo
2
- VERSION = '1.0.0'
4
+ VERSION = '1.0.1'
3
5
  end
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.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-23 00:00:00.000000000 Z
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