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 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