krane 1.0.0 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
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
  - - ">="