kubernetes-deploy 0.9.3 → 0.9.4

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
  SHA1:
3
- metadata.gz: f957b471692e6ab3020ab729e76b02544e63857e
4
- data.tar.gz: 32051ea0acada35ba395fe7075faa3bb2ccb51c2
3
+ metadata.gz: 861c1898e40c08f1120bc55896920e0359f3f674
4
+ data.tar.gz: 6c34e454e654acfba418245f3b2a2896272885cb
5
5
  SHA512:
6
- metadata.gz: 8b3418099ae88193d13948f178968ae432d08860b569c8831985aff46740da265b277b3c10cfd759a387e1163193849ecb10907e9a55368d9919f25395cd7041
7
- data.tar.gz: 34a8799cb0c017d2fa49fe5b0fea72783955b624eeee66bc6d1a537799ca3d17603821e49c631faa5bcbcb60971a21c87caef89197b9c812075c842193ab186e
6
+ metadata.gz: 4fc044006b4330a42b2d7b60e4b45c67b5be86ffd1c2e4017be9042f21d38a9d695058413ce78a9112406b0c8abf8e3c15bcf04f331f7ccf196cdcff6e62b387
7
+ data.tar.gz: 61e7d6cd0d6c706fb1db1a601708f781005db36b3e932e8c22a18463580c4b8c551bfdac2db2df0b0ebef1b75258e2e1ae81044595cf7345c4fced52c4f97b6c
data/README.md CHANGED
@@ -257,6 +257,8 @@ To install this gem onto your local machine, run `bundle exec rake install`.
257
257
 
258
258
  To see the full-color output of a specific integration test, you can use `PRINT_LOGS=1 bundle exec ruby -I test test/integration/kubernetes_deploy_test.rb -n/test_name/`.
259
259
 
260
+ To make StatsD log what it would have emitted, run a test with `STATSD_DEV=1`.
261
+
260
262
 
261
263
 
262
264
  ![test-output](screenshots/test-output.png)
@@ -265,11 +267,12 @@ To see the full-color output of a specific integration test, you can use `PRINT_
265
267
 
266
268
  ## Releasing a new version (Shopify employees)
267
269
 
268
- 1. Update the version number in `version.rb` and commit that change alone to master.
269
- 2. Tag the version with `git tag vx.y.z && git push --tags`
270
- 3. Use the [Shipit Stack](https://shipit.shopify.io/shopify/kubernetes-deploy/rubygems) to build the `.gem` file and upload to [rubygems.org](https://rubygems.org/gems/kubernetes-deploy).
270
+ 1. Update the version number in `version.rb` and commit that change with message "Version x.y.z". Don't push yet or you'll confuse Shipit.
271
+ 2. Tag the version with `git tag vx.y.z -a -m "Version x.y.z"`
272
+ 3. Push both your bump commit and its tag simultaneously with `git push origin master --follow-tags` (note that you can set `git config --global push.followTags true` to turn this flag on by default)
273
+ 4. Use the [Shipit Stack](https://shipit.shopify.io/shopify/kubernetes-deploy/rubygems) to build the `.gem` file and upload to [rubygems.org](https://rubygems.org/gems/kubernetes-deploy).
271
274
 
272
- If Shipit fails with `You need to create the v0.7.9 tag first.` even though you're sure you've already pushed that tag, go to `Settings` > `Resynchronize this stack` > `Clear git cache`.
275
+ If you push your commit and the tag separately, Shipit usually fails with `You need to create the v0.7.9 tag first.`. To make it find your tag, go to `Settings` > `Resynchronize this stack` > `Clear git cache`.
273
276
 
274
277
 
275
278
 
@@ -19,6 +19,7 @@ module KubernetesDeploy
19
19
  if pod_data.blank?
20
20
  raw_json, _err, st = kubectl.run("get", type, @name, "-a", "--output=json")
21
21
  pod_data = JSON.parse(raw_json) if st.success?
22
+ raise_predates_deploy_error if pod_data.present? && unmanaged? && !@deploy_started
22
23
  end
23
24
 
24
25
  if pod_data.present?
@@ -147,6 +148,19 @@ module KubernetesDeploy
147
148
  @already_displayed = true
148
149
  end
149
150
 
151
+ def raise_predates_deploy_error
152
+ example_color = :green
153
+ msg = <<-STRING.strip_heredoc
154
+ Unmanaged pods like #{id} must have unique names on every deploy in order to work as intended.
155
+ The recommended way to achieve this is to include "<%= deployment_id %>" in the pod's name, like this:
156
+ #{ColorizedString.new('kind: Pod').colorize(example_color)}
157
+ #{ColorizedString.new('metadata:').colorize(example_color)}
158
+ #{ColorizedString.new("name: #{@name}-<%= deployment_id %>").colorize(example_color)}
159
+ STRING
160
+ @logger.summary.add_paragraph(msg)
161
+ raise FatalDeploymentError, "#{id} existed before the deploy started"
162
+ end
163
+
150
164
  class Container
151
165
  STATUS_SCAFFOLD = {
152
166
  "state" => {
@@ -187,16 +187,11 @@ module KubernetesDeploy
187
187
 
188
188
  # Inspect the file referenced in the kubectl stderr
189
189
  # to make it easier for developer to understand what's going on
190
- def find_bad_file_from_kubectl_output(stderr)
191
- # Output example:
192
- # Error from server (BadRequest): error when creating "/path/to/configmap-gqq5oh.yml20170411-33615-t0t3m":
193
- match = stderr.match(%r{BadRequest.*"(?<path>\/\S+\.ya?ml\S*)"})
194
- return unless match
195
-
196
- path = match[:path]
197
- if path.present? && File.file?(path)
198
- File.read(path)
199
- end
190
+ def find_bad_files_from_kubectl_output(stderr)
191
+ # stderr often contains one or more lines like the following, from which we can extract the file path(s):
192
+ # Error from server (TypeOfError): error when creating "/path/to/service-gqq5oh.yml": Service "web" is invalid:
193
+ matches = stderr.scan(%r{"(/\S+\.ya?ml\S*)"})
194
+ matches.flatten if matches
200
195
  end
201
196
 
202
197
  def deploy_has_priority_resources?(resources)
@@ -239,17 +234,8 @@ module KubernetesDeploy
239
234
  command = ["create", "-f", file_path, "--dry-run", "--output=name"]
240
235
  _, err, st = kubectl.run(*command, log_failure: false)
241
236
  return if st.success?
242
-
243
- debug_msg = <<-DEBUG_MSG.strip_heredoc
244
- This usually means template '#{original_filename}' is not a valid Kubernetes template.
245
- Error from kubectl:
246
- #{err}
247
- Rendered template content:
248
- DEBUG_MSG
249
- debug_msg += File.read(file_path)
250
- @logger.summary.add_paragraph(debug_msg)
251
-
252
- raise FatalDeploymentError, "Kubectl dry run failed (command: #{Shellwords.join(command)})"
237
+ record_invalid_template(err, file_paths: [file_path], original_filenames: [original_filename])
238
+ raise FatalDeploymentError, "Template validation failed (command: #{Shellwords.join(command)})"
253
239
  end
254
240
 
255
241
  def split_templates(filename)
@@ -270,20 +256,28 @@ module KubernetesDeploy
270
256
  raise FatalDeploymentError, "Template '#{filename}' cannot be parsed"
271
257
  end
272
258
 
273
- def record_apply_failure(err)
274
- file_content = find_bad_file_from_kubectl_output(err)
275
- debug_msg = <<-HELPFUL_MESSAGE.strip_heredoc
276
- This usually means one of your templates is invalid.
277
- Error from kubectl:
278
- #{err}
279
- HELPFUL_MESSAGE
280
- if file_content
281
- debug_msg += "Rendered template content:\n#{file_content}"
259
+ def record_invalid_template(err, file_paths:, original_filenames: nil)
260
+ template_names = Array(original_filenames)
261
+ file_content = Array(file_paths).each_with_object([]) do |file_path, contents|
262
+ next unless File.file?(file_path)
263
+ contents << File.read(file_path)
264
+ template_names << File.basename(file_path) unless original_filenames
265
+ end.join("\n")
266
+ template_list = template_names.compact.join(", ").presence || "See error message"
267
+
268
+ debug_msg = ColorizedString.new("Invalid #{'template'.pluralize(template_names.length)}: #{template_list}\n").red
269
+ debug_msg += "> Error from kubectl:\n#{indent_four(err)}"
270
+ if file_content.present?
271
+ debug_msg += "\n> Rendered template content:\n#{indent_four(file_content)}"
282
272
  end
283
273
 
284
274
  @logger.summary.add_paragraph(debug_msg)
285
275
  end
286
276
 
277
+ def indent_four(str)
278
+ " " + str.gsub("\n", "\n ")
279
+ end
280
+
287
281
  def wait_for_completion(watched_resources, started_at)
288
282
  watcher = ResourceWatcher.new(watched_resources, logger: @logger, deploy_started_at: started_at)
289
283
  watcher.run
@@ -407,7 +401,11 @@ module KubernetesDeploy
407
401
  if st.success?
408
402
  log_pruning(out) if prune
409
403
  else
410
- record_apply_failure(err)
404
+ file_paths = find_bad_files_from_kubectl_output(err)
405
+ warn_msg = "WARNING: Any resources not mentioned in the error below were likely created/updated. " \
406
+ "You may wish to roll back this deploy."
407
+ @logger.summary.add_paragraph(ColorizedString.new(warn_msg).yellow)
408
+ record_invalid_template(err, file_paths: file_paths)
411
409
  raise FatalDeploymentError, "Command failed: #{Shellwords.join(command)}"
412
410
  end
413
411
  end
@@ -1,3 +1,3 @@
1
1
  module KubernetesDeploy
2
- VERSION = "0.9.3"
2
+ VERSION = "0.9.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kubernetes-deploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katrina Verey