krane 1.0.0 → 1.1.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -0
  3. data/{ISSUE_TEMPLATE.md → .github/ISSUE_TEMPLATE.md} +0 -0
  4. data/{pull_request_template.md → .github/pull_request_template.md} +0 -0
  5. data/.gitignore +0 -3
  6. data/.rubocop-http---shopify-github-io-ruby-style-guide-rubocop-yml +1020 -0
  7. data/.rubocop.yml +0 -12
  8. data/.shopify-build/{kubernetes-deploy.yml → krane.yml} +16 -1
  9. data/1.0-Upgrade.md +4 -5
  10. data/CHANGELOG.md +55 -1
  11. data/CONTRIBUTING.md +5 -5
  12. data/Gemfile +0 -11
  13. data/README.md +22 -24
  14. data/bin/ci +1 -1
  15. data/bin/test +2 -2
  16. data/dev.yml +4 -4
  17. data/krane.gemspec +22 -5
  18. data/lib/krane/cli/deploy_command.rb +3 -4
  19. data/lib/krane/cli/global_deploy_command.rb +3 -3
  20. data/lib/krane/cli/render_command.rb +3 -3
  21. data/lib/krane/cluster_resource_discovery.rb +9 -6
  22. data/lib/krane/concurrency.rb +2 -2
  23. data/lib/krane/container_logs.rb +1 -1
  24. data/lib/krane/container_overrides.rb +33 -0
  25. data/lib/krane/deploy_task.rb +5 -5
  26. data/lib/krane/ejson_secret_provisioner.rb +7 -4
  27. data/lib/krane/global_deploy_task.rb +3 -2
  28. data/lib/krane/kubectl.rb +11 -1
  29. data/lib/krane/kubernetes_resource.rb +7 -6
  30. data/lib/krane/kubernetes_resource/custom_resource.rb +1 -1
  31. data/lib/krane/kubernetes_resource/custom_resource_definition.rb +1 -1
  32. data/lib/krane/kubernetes_resource/daemon_set.rb +1 -0
  33. data/lib/krane/kubernetes_resource/deployment.rb +3 -2
  34. data/lib/krane/kubernetes_resource/pod.rb +12 -8
  35. data/lib/krane/kubernetes_resource/replica_set.rb +2 -16
  36. data/lib/krane/kubernetes_resource/service.rb +3 -7
  37. data/lib/krane/kubernetes_resource/stateful_set.rb +1 -0
  38. data/lib/krane/render_task.rb +2 -2
  39. data/lib/krane/resource_cache.rb +6 -0
  40. data/lib/krane/resource_watcher.rb +2 -1
  41. data/lib/krane/restart_task.rb +2 -2
  42. data/lib/krane/runner_task.rb +16 -17
  43. data/lib/krane/statsd.rb +2 -2
  44. data/lib/krane/template_sets.rb +1 -1
  45. data/lib/krane/version.rb +1 -1
  46. metadata +168 -20
  47. data/lib/krane/kubernetes_resource/cloudsql.rb +0 -43
  48. data/shipit.yml +0 -4
@@ -4,16 +4,12 @@ require 'krane/kubernetes_resource/pod'
4
4
  module Krane
5
5
  class Service < KubernetesResource
6
6
  TIMEOUT = 7.minutes
7
+ SYNC_DEPENDENCIES = %w(Pod Deployment StatefulSet)
7
8
 
8
9
  def sync(cache)
9
10
  super
10
- if exists? && selector.present?
11
- @related_pods = cache.get_all(Pod.kind, selector)
12
- @related_workloads = fetch_related_workloads(cache)
13
- else
14
- @related_pods = []
15
- @related_workloads = []
16
- end
11
+ @related_pods = cache.get_all(Pod.kind, selector)
12
+ @related_workloads = fetch_related_workloads(cache)
17
13
  end
18
14
 
19
15
  def status
@@ -4,6 +4,7 @@ module Krane
4
4
  class StatefulSet < PodSetBase
5
5
  TIMEOUT = 10.minutes
6
6
  ONDELETE = 'OnDelete'
7
+ SYNC_DEPENDENCIES = %w(Pod)
7
8
  attr_reader :pods
8
9
 
9
10
  def sync(cache)
@@ -24,8 +24,8 @@ module Krane
24
24
  # Runs the task, returning a boolean representing success or failure
25
25
  #
26
26
  # @return [Boolean]
27
- def run(*args)
28
- run!(*args)
27
+ def run(**args)
28
+ run!(**args)
29
29
  true
30
30
  rescue Krane::FatalDeploymentError
31
31
  false
@@ -36,6 +36,12 @@ module Krane
36
36
  []
37
37
  end
38
38
 
39
+ def prewarm(resources)
40
+ sync_dependencies = resources.flat_map { |r| r.class.const_get(:SYNC_DEPENDENCIES) }
41
+ kinds = (resources.map(&:type) + sync_dependencies).uniq
42
+ Krane::Concurrency.split_across_threads(kinds, max_threads: kinds.count) { |kind| get_all(kind) }
43
+ end
44
+
39
45
  private
40
46
 
41
47
  def statsd_tags
@@ -53,6 +53,7 @@ module Krane
53
53
 
54
54
  def sync_resources(resources)
55
55
  cache = ResourceCache.new(@task_config)
56
+ cache.prewarm(resources)
56
57
  Krane::Concurrency.split_across_threads(resources) { |r| r.sync(cache) }
57
58
  resources.each(&:after_sync)
58
59
  end
@@ -67,7 +68,7 @@ module Krane
67
68
  end
68
69
 
69
70
  def global_timeout?(started_at)
70
- @timeout && (Time.now.utc - started_at > @timeout)
71
+ @timeout && (Time.now.utc - started_at >= @timeout)
71
72
  end
72
73
 
73
74
  def sleep_until_next_sync(min_interval)
@@ -39,8 +39,8 @@ module Krane
39
39
  # Runs the task, returning a boolean representing success or failure
40
40
  #
41
41
  # @return [Boolean]
42
- def run(*args)
43
- perform!(*args)
42
+ def run(**args)
43
+ perform!(**args)
44
44
  true
45
45
  rescue FatalDeploymentError
46
46
  false
@@ -9,6 +9,7 @@ require 'krane/resource_watcher'
9
9
  require 'krane/kubernetes_resource'
10
10
  require 'krane/kubernetes_resource/pod'
11
11
  require 'krane/runner_task_config_validator'
12
+ require 'krane/container_overrides'
12
13
 
13
14
  module Krane
14
15
  # Run a pod that exits upon completing a task
@@ -34,8 +35,8 @@ module Krane
34
35
  # Runs the task, returning a boolean representing success or failure
35
36
  #
36
37
  # @return [Boolean]
37
- def run(*args)
38
- run!(*args)
38
+ def run(**args)
39
+ run!(**args)
39
40
  true
40
41
  rescue DeploymentTimeoutError, FatalDeploymentError
41
42
  false
@@ -50,7 +51,7 @@ module Krane
50
51
  # @param verify_result [Boolean] Wait for completion and verify pod success
51
52
  #
52
53
  # @return [nil]
53
- def run!(template:, command:, arguments:, env_vars: [], verify_result: true)
54
+ def run!(template:, command:, arguments:, env_vars: [], image_tag: nil, verify_result: true)
54
55
  start = Time.now.utc
55
56
  @logger.reset
56
57
 
@@ -59,8 +60,13 @@ module Krane
59
60
  @logger.info("Validating configuration")
60
61
  verify_config!(template)
61
62
  @logger.info("Using namespace '#{@namespace}' in context '#{@context}'")
62
-
63
- pod = build_pod(template, command, arguments, env_vars, verify_result)
63
+ container_overrides = ContainerOverrides.new(
64
+ command: command,
65
+ arguments: arguments,
66
+ env_vars: env_vars,
67
+ image_tag: image_tag
68
+ )
69
+ pod = build_pod(template, container_overrides, verify_result)
64
70
  validate_pod(pod)
65
71
 
66
72
  @logger.phase_heading("Running pod")
@@ -98,11 +104,12 @@ module Krane
98
104
  raise FatalDeploymentError, msg
99
105
  end
100
106
 
101
- def build_pod(template_name, command, args, env_vars, verify_result)
107
+ def build_pod(template_name, container_overrides, verify_result)
102
108
  task_template = get_template(template_name)
103
109
  @logger.info("Using template '#{template_name}'")
104
110
  pod_template = build_pod_definition(task_template)
105
- set_container_overrides!(pod_template, command, args, env_vars)
111
+ container = extract_task_runner_container(pod_template)
112
+ container_overrides.apply!(container)
106
113
  ensure_valid_restart_policy!(pod_template, verify_result)
107
114
  Pod.new(namespace: @namespace, context: @context, logger: @logger, stream_logs: true,
108
115
  definition: pod_template.to_hash.deep_stringify_keys, statsd_tags: [])
@@ -165,7 +172,7 @@ module Krane
165
172
  pod_definition
166
173
  end
167
174
 
168
- def set_container_overrides!(pod_definition, command, args, env_vars)
175
+ def extract_task_runner_container(pod_definition)
169
176
  container = pod_definition.spec.containers.find { |cont| cont.name == 'task-runner' }
170
177
  if container.nil?
171
178
  message = "Pod spec does not contain a template container called 'task-runner'"
@@ -173,15 +180,7 @@ module Krane
173
180
  raise TaskConfigurationError, message
174
181
  end
175
182
 
176
- container.command = command if command
177
- container.args = args if args
178
-
179
- env_args = env_vars.map do |env|
180
- key, value = env.split('=', 2)
181
- { name: key, value: value }
182
- end
183
- container.env ||= []
184
- container.env = container.env.map(&:to_h) + env_args
183
+ container
185
184
  end
186
185
 
187
186
  def ensure_valid_restart_policy!(template, verify)
@@ -35,10 +35,10 @@ module Krane
35
35
  end
36
36
 
37
37
  metric ||= "#{method_name}.duration"
38
- self::InstrumentationProxy.send(:define_method, method_name) do |*args, &block|
38
+ self::InstrumentationProxy.send(:define_method, method_name) do |*args, **kwargs, &block|
39
39
  begin
40
40
  start_time = Time.now.utc
41
- super(*args, &block)
41
+ super(*args, **kwargs, &block)
42
42
  rescue
43
43
  error = true
44
44
  raise
@@ -150,7 +150,7 @@ module Krane
150
150
 
151
151
  if rendering_erb_disabled? && deploying_with_erb_files?
152
152
  errors << "ERB template discovered with rendering disabled. If you were trying to render ERB and " \
153
- "deploy the result, try piping the output of `krane render` to `krane-deploy` with the --stdin flag"
153
+ "deploy the result, try piping the output of `krane render` to `krane-deploy -f -`"
154
154
  end
155
155
 
156
156
  errors
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Krane
3
- VERSION = "1.0.0"
3
+ VERSION = "1.1.4"
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: krane
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katrina Verey
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2019-11-18 00:00:00.000000000 Z
13
+ date: 2020-06-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -46,14 +46,14 @@ dependencies:
46
46
  requirements:
47
47
  - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: 0.8.0
49
+ version: '0.8'
50
50
  type: :runtime
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
54
  - - "~>"
55
55
  - !ruby/object:Gem::Version
56
- version: 0.8.0
56
+ version: '0.8'
57
57
  - !ruby/object:Gem::Dependency
58
58
  name: ejson
59
59
  requirement: !ruby/object:Gem::Requirement
@@ -148,16 +148,22 @@ dependencies:
148
148
  name: thor
149
149
  requirement: !ruby/object:Gem::Requirement
150
150
  requirements:
151
- - - "~>"
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '1.0'
154
+ - - "<"
152
155
  - !ruby/object:Gem::Version
153
- version: 0.20.3
156
+ version: '2.0'
154
157
  type: :runtime
155
158
  prerelease: false
156
159
  version_requirements: !ruby/object:Gem::Requirement
157
160
  requirements:
158
- - - "~>"
161
+ - - ">="
159
162
  - !ruby/object:Gem::Version
160
- version: 0.20.3
163
+ version: '1.0'
164
+ - - "<"
165
+ - !ruby/object:Gem::Version
166
+ version: '2.0'
161
167
  - !ruby/object:Gem::Dependency
162
168
  name: bundler
163
169
  requirement: !ruby/object:Gem::Requirement
@@ -186,20 +192,34 @@ dependencies:
186
192
  - - "~>"
187
193
  - !ruby/object:Gem::Version
188
194
  version: '10.0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: yard
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
189
209
  - !ruby/object:Gem::Dependency
190
210
  name: minitest
191
211
  requirement: !ruby/object:Gem::Requirement
192
212
  requirements:
193
213
  - - "~>"
194
214
  - !ruby/object:Gem::Version
195
- version: '5.0'
215
+ version: '5.12'
196
216
  type: :development
197
217
  prerelease: false
198
218
  version_requirements: !ruby/object:Gem::Requirement
199
219
  requirements:
200
220
  - - "~>"
201
221
  - !ruby/object:Gem::Version
202
- version: '5.0'
222
+ version: '5.12'
203
223
  - !ruby/object:Gem::Dependency
204
224
  name: minitest-stub-const
205
225
  requirement: !ruby/object:Gem::Requirement
@@ -214,6 +234,34 @@ dependencies:
214
234
  - - "~>"
215
235
  - !ruby/object:Gem::Version
216
236
  version: '0.6'
237
+ - !ruby/object:Gem::Dependency
238
+ name: minitest-reporters
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
251
+ - !ruby/object:Gem::Dependency
252
+ name: mocha
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - "~>"
256
+ - !ruby/object:Gem::Version
257
+ version: '1.5'
258
+ type: :development
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - "~>"
263
+ - !ruby/object:Gem::Version
264
+ version: '1.5'
217
265
  - !ruby/object:Gem::Dependency
218
266
  name: webmock
219
267
  requirement: !ruby/object:Gem::Requirement
@@ -229,19 +277,117 @@ dependencies:
229
277
  - !ruby/object:Gem::Version
230
278
  version: '3.0'
231
279
  - !ruby/object:Gem::Dependency
232
- name: mocha
280
+ name: timecop
281
+ requirement: !ruby/object:Gem::Requirement
282
+ requirements:
283
+ - - ">="
284
+ - !ruby/object:Gem::Version
285
+ version: '0'
286
+ type: :development
287
+ prerelease: false
288
+ version_requirements: !ruby/object:Gem::Requirement
289
+ requirements:
290
+ - - ">="
291
+ - !ruby/object:Gem::Version
292
+ version: '0'
293
+ - !ruby/object:Gem::Dependency
294
+ name: pry
295
+ requirement: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - ">="
298
+ - !ruby/object:Gem::Version
299
+ version: '0'
300
+ type: :development
301
+ prerelease: false
302
+ version_requirements: !ruby/object:Gem::Requirement
303
+ requirements:
304
+ - - ">="
305
+ - !ruby/object:Gem::Version
306
+ version: '0'
307
+ - !ruby/object:Gem::Dependency
308
+ name: pry-byebug
309
+ requirement: !ruby/object:Gem::Requirement
310
+ requirements:
311
+ - - ">="
312
+ - !ruby/object:Gem::Version
313
+ version: '0'
314
+ type: :development
315
+ prerelease: false
316
+ version_requirements: !ruby/object:Gem::Requirement
317
+ requirements:
318
+ - - ">="
319
+ - !ruby/object:Gem::Version
320
+ version: '0'
321
+ - !ruby/object:Gem::Dependency
322
+ name: byebug
323
+ requirement: !ruby/object:Gem::Requirement
324
+ requirements:
325
+ - - ">="
326
+ - !ruby/object:Gem::Version
327
+ version: '0'
328
+ type: :development
329
+ prerelease: false
330
+ version_requirements: !ruby/object:Gem::Requirement
331
+ requirements:
332
+ - - ">="
333
+ - !ruby/object:Gem::Version
334
+ version: '0'
335
+ - !ruby/object:Gem::Dependency
336
+ name: ruby-prof
337
+ requirement: !ruby/object:Gem::Requirement
338
+ requirements:
339
+ - - ">="
340
+ - !ruby/object:Gem::Version
341
+ version: '0'
342
+ type: :development
343
+ prerelease: false
344
+ version_requirements: !ruby/object:Gem::Requirement
345
+ requirements:
346
+ - - ">="
347
+ - !ruby/object:Gem::Version
348
+ version: '0'
349
+ - !ruby/object:Gem::Dependency
350
+ name: ruby-prof-flamegraph
351
+ requirement: !ruby/object:Gem::Requirement
352
+ requirements:
353
+ - - ">="
354
+ - !ruby/object:Gem::Version
355
+ version: '0'
356
+ type: :development
357
+ prerelease: false
358
+ version_requirements: !ruby/object:Gem::Requirement
359
+ requirements:
360
+ - - ">="
361
+ - !ruby/object:Gem::Version
362
+ version: '0'
363
+ - !ruby/object:Gem::Dependency
364
+ name: rubocop
233
365
  requirement: !ruby/object:Gem::Requirement
234
366
  requirements:
235
367
  - - "~>"
236
368
  - !ruby/object:Gem::Version
237
- version: '1.5'
369
+ version: 0.78.0
238
370
  type: :development
239
371
  prerelease: false
240
372
  version_requirements: !ruby/object:Gem::Requirement
241
373
  requirements:
242
374
  - - "~>"
243
375
  - !ruby/object:Gem::Version
244
- version: '1.5'
376
+ version: 0.78.0
377
+ - !ruby/object:Gem::Dependency
378
+ name: codecov
379
+ requirement: !ruby/object:Gem::Requirement
380
+ requirements:
381
+ - - ">="
382
+ - !ruby/object:Gem::Version
383
+ version: '0'
384
+ type: :development
385
+ prerelease: false
386
+ version_requirements: !ruby/object:Gem::Requirement
387
+ requirements:
388
+ - - ">="
389
+ - !ruby/object:Gem::Version
390
+ version: '0'
245
391
  description: A command line tool that helps you ship changes to a Kubernetes namespace
246
392
  and understand the result
247
393
  email:
@@ -252,17 +398,20 @@ extensions: []
252
398
  extra_rdoc_files: []
253
399
  files:
254
400
  - ".buildkite/pipeline.nightly.yml"
401
+ - ".github/CODEOWNERS"
402
+ - ".github/ISSUE_TEMPLATE.md"
255
403
  - ".github/probots.yml"
404
+ - ".github/pull_request_template.md"
256
405
  - ".gitignore"
406
+ - ".rubocop-http---shopify-github-io-ruby-style-guide-rubocop-yml"
257
407
  - ".rubocop.yml"
258
408
  - ".shopify-build/VERSION"
259
- - ".shopify-build/kubernetes-deploy.yml"
409
+ - ".shopify-build/krane.yml"
260
410
  - 1.0-Upgrade.md
261
411
  - CHANGELOG.md
262
412
  - CODE_OF_CONDUCT.md
263
413
  - CONTRIBUTING.md
264
414
  - Gemfile
265
- - ISSUE_TEMPLATE.md
266
415
  - LICENSE.txt
267
416
  - README.md
268
417
  - Rakefile
@@ -287,6 +436,7 @@ files:
287
436
  - lib/krane/concerns/template_reporting.rb
288
437
  - lib/krane/concurrency.rb
289
438
  - lib/krane/container_logs.rb
439
+ - lib/krane/container_overrides.rb
290
440
  - lib/krane/deferred_summary_logging.rb
291
441
  - lib/krane/delayed_exceptions.rb
292
442
  - lib/krane/deploy_task.rb
@@ -300,7 +450,6 @@ files:
300
450
  - lib/krane/kubeclient_builder.rb
301
451
  - lib/krane/kubectl.rb
302
452
  - lib/krane/kubernetes_resource.rb
303
- - lib/krane/kubernetes_resource/cloudsql.rb
304
453
  - lib/krane/kubernetes_resource/config_map.rb
305
454
  - lib/krane/kubernetes_resource/cron_job.rb
306
455
  - lib/krane/kubernetes_resource/custom_resource.rb
@@ -342,17 +491,16 @@ files:
342
491
  - lib/krane/task_config_validator.rb
343
492
  - lib/krane/template_sets.rb
344
493
  - lib/krane/version.rb
345
- - pull_request_template.md
346
494
  - screenshots/deploy-demo.gif
347
495
  - screenshots/migrate-logs.png
348
496
  - screenshots/missing-secret-fail.png
349
497
  - screenshots/success.png
350
498
  - screenshots/test-output.png
351
- - shipit.yml
352
499
  homepage: https://github.com/Shopify/krane
353
500
  licenses:
354
501
  - MIT
355
- metadata: {}
502
+ metadata:
503
+ allowed_push_host: https://rubygems.org
356
504
  post_install_message:
357
505
  rdoc_options: []
358
506
  require_paths:
@@ -361,7 +509,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
361
509
  requirements:
362
510
  - - ">="
363
511
  - !ruby/object:Gem::Version
364
- version: 2.4.0
512
+ version: 2.5.0
365
513
  required_rubygems_version: !ruby/object:Gem::Requirement
366
514
  requirements:
367
515
  - - ">="