krane 1.1.0 → 2.0.0

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 (44) 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/.rubocop-http---shopify-github-io-ruby-style-guide-rubocop-yml +24 -30
  6. data/.rubocop.yml +0 -12
  7. data/.shopify-build/krane.yml +20 -6
  8. data/1.0-Upgrade.md +2 -2
  9. data/CHANGELOG.md +61 -0
  10. data/CONTRIBUTING.md +2 -2
  11. data/README.md +14 -16
  12. data/bin/ci +1 -1
  13. data/bin/test +2 -2
  14. data/dev.yml +1 -1
  15. data/krane.gemspec +7 -5
  16. data/lib/krane/annotation.rb +11 -0
  17. data/lib/krane/cli/deploy_command.rb +3 -4
  18. data/lib/krane/cli/global_deploy_command.rb +3 -3
  19. data/lib/krane/cli/render_command.rb +3 -3
  20. data/lib/krane/cluster_resource_discovery.rb +10 -6
  21. data/lib/krane/concerns/template_reporting.rb +0 -6
  22. data/lib/krane/container_logs.rb +1 -1
  23. data/lib/krane/container_overrides.rb +33 -0
  24. data/lib/krane/deploy_task.rb +16 -13
  25. data/lib/krane/ejson_secret_provisioner.rb +1 -2
  26. data/lib/krane/global_deploy_task.rb +4 -7
  27. data/lib/krane/kubectl.rb +11 -1
  28. data/lib/krane/kubernetes_resource.rb +19 -46
  29. data/lib/krane/kubernetes_resource/custom_resource.rb +2 -2
  30. data/lib/krane/kubernetes_resource/custom_resource_definition.rb +13 -10
  31. data/lib/krane/kubernetes_resource/deployment.rb +5 -7
  32. data/lib/krane/kubernetes_resource/pod.rb +12 -8
  33. data/lib/krane/psych_k8s_compatibility.rb +36 -0
  34. data/lib/krane/render_task.rb +2 -2
  35. data/lib/krane/renderer.rb +2 -0
  36. data/lib/krane/resource_deployer.rb +7 -2
  37. data/lib/krane/resource_watcher.rb +1 -1
  38. data/lib/krane/restart_task.rb +2 -2
  39. data/lib/krane/runner_task.rb +16 -17
  40. data/lib/krane/statsd.rb +2 -2
  41. data/lib/krane/template_sets.rb +1 -1
  42. data/lib/krane/version.rb +1 -1
  43. metadata +27 -17
  44. data/lib/krane/kubernetes_resource/cloudsql.rb +0 -44
@@ -62,7 +62,7 @@ module Krane
62
62
  kind
63
63
  end
64
64
 
65
- def validate_definition(*)
65
+ def validate_definition(*, **)
66
66
  super
67
67
 
68
68
  @crd.validate_rollout_conditions
@@ -70,7 +70,7 @@ module Krane
70
70
  @validation_errors << "The CRD that specifies this resource is using invalid rollout conditions. " \
71
71
  "Krane will not be able to continue until those rollout conditions are fixed.\n" \
72
72
  "Rollout conditions can be found on the CRD that defines this resource (#{@crd.name}), " \
73
- "under the annotation #{CustomResourceDefinition::ROLLOUT_CONDITIONS_ANNOTATION}.\n" \
73
+ "under the annotation #{Annotation.for(CustomResourceDefinition::ROLLOUT_CONDITIONS_ANNOTATION)}.\n" \
74
74
  "Validation failed with: #{e}"
75
75
  end
76
76
 
@@ -2,9 +2,8 @@
2
2
  module Krane
3
3
  class CustomResourceDefinition < KubernetesResource
4
4
  TIMEOUT = 2.minutes
5
- ROLLOUT_CONDITIONS_ANNOTATION_SUFFIX = "instance-rollout-conditions"
6
- ROLLOUT_CONDITIONS_ANNOTATION = "krane.shopify.io/#{ROLLOUT_CONDITIONS_ANNOTATION_SUFFIX}"
7
- TIMEOUT_FOR_INSTANCE_ANNOTATION = "krane.shopify.io/instance-timeout"
5
+ ROLLOUT_CONDITIONS_ANNOTATION = "instance-rollout-conditions"
6
+ TIMEOUT_FOR_INSTANCE_ANNOTATION = "instance-timeout"
8
7
  GLOBAL = true
9
8
 
10
9
  def deploy_succeeded?
@@ -20,7 +19,7 @@ module Krane
20
19
  end
21
20
 
22
21
  def timeout_for_instance
23
- timeout = krane_annotation_value("instance-timeout")
22
+ timeout = krane_annotation_value(TIMEOUT_FOR_INSTANCE_ANNOTATION)
24
23
  DurationParser.new(timeout).parse!.to_i
25
24
  rescue DurationParser::ParsingError
26
25
  nil
@@ -46,6 +45,10 @@ module Krane
46
45
  @definition.dig("spec", "names", "kind")
47
46
  end
48
47
 
48
+ def group
49
+ @definition.dig("spec", "group")
50
+ end
51
+
49
52
  def prunable?
50
53
  prunable = krane_annotation_value("prunable")
51
54
  prunable == "true"
@@ -59,25 +62,25 @@ module Krane
59
62
  def rollout_conditions
60
63
  return @rollout_conditions if defined?(@rollout_conditions)
61
64
 
62
- @rollout_conditions = if krane_annotation_value(ROLLOUT_CONDITIONS_ANNOTATION_SUFFIX)
63
- RolloutConditions.from_annotation(krane_annotation_value(ROLLOUT_CONDITIONS_ANNOTATION_SUFFIX))
65
+ @rollout_conditions = if krane_annotation_value(ROLLOUT_CONDITIONS_ANNOTATION)
66
+ RolloutConditions.from_annotation(krane_annotation_value(ROLLOUT_CONDITIONS_ANNOTATION))
64
67
  end
65
68
  rescue RolloutConditionsError
66
69
  @rollout_conditions = nil
67
70
  end
68
71
 
69
- def validate_definition(*)
72
+ def validate_definition(*, **)
70
73
  super
71
74
 
72
75
  validate_rollout_conditions
73
76
  rescue RolloutConditionsError => e
74
- @validation_errors << "Annotation #{krane_annotation_key(ROLLOUT_CONDITIONS_ANNOTATION_SUFFIX)} "\
77
+ @validation_errors << "Annotation #{Annotation.for(ROLLOUT_CONDITIONS_ANNOTATION)} " \
75
78
  "on #{name} is invalid: #{e}"
76
79
  end
77
80
 
78
81
  def validate_rollout_conditions
79
- if krane_annotation_value(ROLLOUT_CONDITIONS_ANNOTATION_SUFFIX) && @rollout_conditions_validated.nil?
80
- conditions = RolloutConditions.from_annotation(krane_annotation_value(ROLLOUT_CONDITIONS_ANNOTATION_SUFFIX))
82
+ if krane_annotation_value(ROLLOUT_CONDITIONS_ANNOTATION) && @rollout_conditions_validated.nil?
83
+ conditions = RolloutConditions.from_annotation(krane_annotation_value(ROLLOUT_CONDITIONS_ANNOTATION))
81
84
  conditions.validate!
82
85
  end
83
86
 
@@ -5,9 +5,7 @@ module Krane
5
5
  class Deployment < KubernetesResource
6
6
  TIMEOUT = 7.minutes
7
7
  SYNC_DEPENDENCIES = %w(Pod ReplicaSet)
8
- REQUIRED_ROLLOUT_ANNOTATION_SUFFIX = "required-rollout"
9
- REQUIRED_ROLLOUT_ANNOTATION_DEPRECATED = "kubernetes-deploy.shopify.io/#{REQUIRED_ROLLOUT_ANNOTATION_SUFFIX}"
10
- REQUIRED_ROLLOUT_ANNOTATION = "krane.shopify.io/#{REQUIRED_ROLLOUT_ANNOTATION_SUFFIX}"
8
+ REQUIRED_ROLLOUT_ANNOTATION = "required-rollout"
11
9
  REQUIRED_ROLLOUT_TYPES = %w(maxUnavailable full none).freeze
12
10
  DEFAULT_REQUIRED_ROLLOUT = 'full'
13
11
 
@@ -97,7 +95,7 @@ module Krane
97
95
  progress_condition.present? ? deploy_failing_to_progress? : super
98
96
  end
99
97
 
100
- def validate_definition(*)
98
+ def validate_definition(*, **)
101
99
  super
102
100
 
103
101
  unless REQUIRED_ROLLOUT_TYPES.include?(required_rollout) || percent?(required_rollout)
@@ -106,7 +104,7 @@ module Krane
106
104
 
107
105
  strategy = @definition.dig('spec', 'strategy', 'type').to_s
108
106
  if required_rollout.downcase == 'maxunavailable' && strategy.present? && strategy.downcase != 'rollingupdate'
109
- @validation_errors << "'#{krane_annotation_key(REQUIRED_ROLLOUT_ANNOTATION_SUFFIX)}: #{required_rollout}' "\
107
+ @validation_errors << "'#{Annotation.for(REQUIRED_ROLLOUT_ANNOTATION)}: #{required_rollout}' " \
110
108
  "is incompatible with strategy '#{strategy}'"
111
109
  end
112
110
 
@@ -151,7 +149,7 @@ module Krane
151
149
  end
152
150
 
153
151
  def rollout_annotation_err_msg
154
- "'#{krane_annotation_key(REQUIRED_ROLLOUT_ANNOTATION_SUFFIX)}: #{required_rollout}' is invalid. "\
152
+ "'#{Annotation.for(REQUIRED_ROLLOUT_ANNOTATION)}: #{required_rollout}' is invalid. " \
155
153
  "Acceptable values: #{REQUIRED_ROLLOUT_TYPES.join(', ')}"
156
154
  end
157
155
 
@@ -191,7 +189,7 @@ module Krane
191
189
  def min_available_replicas
192
190
  if percent?(required_rollout)
193
191
  (desired_replicas * required_rollout.to_i / 100.0).ceil
194
- elsif max_unavailable =~ /%/
192
+ elsif max_unavailable.is_a?(String) && max_unavailable =~ /%/
195
193
  (desired_replicas * (100 - max_unavailable.to_i) / 100.0).ceil
196
194
  else
197
195
  desired_replicas - max_unavailable.to_i
@@ -219,14 +219,7 @@ module Krane
219
219
  limbo_reason = @status.dig("state", "waiting", "reason")
220
220
  limbo_message = @status.dig("state", "waiting", "message")
221
221
 
222
- if @status.dig("lastState", "terminated", "reason") == "ContainerCannotRun"
223
- # ref: https://github.com/kubernetes/kubernetes/blob/562e721ece8a16e05c7e7d6bdd6334c910733ab2/pkg/kubelet/dockershim/docker_container.go#L353
224
- exit_code = @status.dig('lastState', 'terminated', 'exitCode')
225
- "Failed to start (exit #{exit_code}): #{@status.dig('lastState', 'terminated', 'message')}"
226
- elsif @status.dig("state", "terminated", "reason") == "ContainerCannotRun"
227
- exit_code = @status.dig('state', 'terminated', 'exitCode')
228
- "Failed to start (exit #{exit_code}): #{@status.dig('state', 'terminated', 'message')}"
229
- elsif limbo_reason == "CrashLoopBackOff"
222
+ if limbo_reason == "CrashLoopBackOff"
230
223
  exit_code = @status.dig('lastState', 'terminated', 'exitCode')
231
224
  "Crashing repeatedly (exit #{exit_code}). See logs for more information."
232
225
  elsif limbo_reason == "ErrImagePull" && limbo_message.match(/not found/i)
@@ -234,6 +227,17 @@ module Krane
234
227
  "Did you wait for it to be built and pushed to the registry before deploying?"
235
228
  elsif limbo_reason == "CreateContainerConfigError"
236
229
  "Failed to generate container configuration: #{limbo_message}"
230
+ elsif @status.dig("lastState", "terminated", "reason") == "ContainerCannotRun"
231
+ # ref: https://github.com/kubernetes/kubernetes/blob/562e721ece8a16e05c7e7d6bdd6334c910733ab2/pkg/kubelet/dockershim/docker_container.go#L353
232
+ exit_code = @status.dig('lastState', 'terminated', 'exitCode')
233
+ # We've observed failures here that are actually issues with the node or kube infra, and not with the
234
+ # container. These issues have been transient and result in a 128 exit code, so do not treat these as fatal.
235
+ return if exit_code == 128
236
+ "Failed to start (exit #{exit_code}): #{@status.dig('lastState', 'terminated', 'message')}"
237
+ elsif @status.dig("state", "terminated", "reason") == "ContainerCannotRun"
238
+ exit_code = @status.dig('state', 'terminated', 'exitCode')
239
+ return if exit_code == 128
240
+ "Failed to start (exit #{exit_code}): #{@status.dig('state', 'terminated', 'message')}"
237
241
  end
238
242
  end
239
243
 
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'psych'
4
+
5
+ module PsychK8sCompatibility
6
+ def self.massage_node(n)
7
+ if n.is_a?(Psych::Nodes::Scalar) &&
8
+ (n.style == Psych::Nodes::Scalar::PLAIN) &&
9
+ n.value.is_a?(String) &&
10
+ n.value =~ /\A[+-]?\d+(?:\.\d+)?[eE][+-]?\d+\z/
11
+ n.style = Psych::Nodes::Scalar::DOUBLE_QUOTED
12
+ end
13
+ end
14
+
15
+ refine Psych.singleton_class do
16
+ def dump(o, io = nil, options = {})
17
+ if io.is_a?(Hash)
18
+ options = io
19
+ io = nil
20
+ end
21
+ visitor = Psych::Visitors::YAMLTree.create(options)
22
+ visitor << o
23
+ visitor.tree.each { |n| PsychK8sCompatibility.massage_node(n) }
24
+ visitor.tree.yaml(io, options)
25
+ end
26
+
27
+ def dump_stream(*objects)
28
+ visitor = Psych::Visitors::YAMLTree.create({})
29
+ objects.each do |o|
30
+ visitor << o
31
+ end
32
+ visitor.tree.each { |n| PsychK8sCompatibility.massage_node(n) }
33
+ visitor.tree.yaml
34
+ end
35
+ end
36
+ end
@@ -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
@@ -28,6 +28,8 @@ module Krane
28
28
  ENV["TASK_ID"]
29
29
  elsif current_sha
30
30
  current_sha[0...8] + "-#{SecureRandom.hex(4)}"
31
+ else
32
+ SecureRandom.hex(8)
31
33
  end
32
34
  end
33
35
 
@@ -46,8 +46,13 @@ module Krane
46
46
  bare_pods.first.stream_logs = true
47
47
  end
48
48
 
49
- predeploy_sequence.each do |resource_type|
50
- matching_resources = resource_list.select { |r| r.type == resource_type }
49
+ predeploy_sequence.each do |resource_type, attributes|
50
+ matching_resources = resource_list.select do |r|
51
+ r.type == resource_type &&
52
+ (!attributes[:group] || r.group == attributes[:group])
53
+ end
54
+ StatsD.client.gauge('priority_resources.count', matching_resources.size, tags: statsd_tags)
55
+
51
56
  next if matching_resources.empty?
52
57
  deploy_resources(matching_resources, verify: true, record_summary: false)
53
58
 
@@ -68,7 +68,7 @@ module Krane
68
68
  end
69
69
 
70
70
  def global_timeout?(started_at)
71
- @timeout && (Time.now.utc - started_at > @timeout)
71
+ @timeout && (Time.now.utc - started_at >= @timeout)
72
72
  end
73
73
 
74
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.1.0"
3
+ VERSION = "2.0.0"
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.1.0
4
+ version: 2.0.0
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-12-12 00:00:00.000000000 Z
13
+ date: 2020-08-26 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
@@ -206,14 +212,14 @@ dependencies:
206
212
  requirements:
207
213
  - - "~>"
208
214
  - !ruby/object:Gem::Version
209
- version: '5.0'
215
+ version: '5.12'
210
216
  type: :development
211
217
  prerelease: false
212
218
  version_requirements: !ruby/object:Gem::Requirement
213
219
  requirements:
214
220
  - - "~>"
215
221
  - !ruby/object:Gem::Version
216
- version: '5.0'
222
+ version: '5.12'
217
223
  - !ruby/object:Gem::Dependency
218
224
  name: minitest-stub-const
219
225
  requirement: !ruby/object:Gem::Requirement
@@ -360,14 +366,14 @@ dependencies:
360
366
  requirements:
361
367
  - - "~>"
362
368
  - !ruby/object:Gem::Version
363
- version: 0.76.0
369
+ version: 0.88.0
364
370
  type: :development
365
371
  prerelease: false
366
372
  version_requirements: !ruby/object:Gem::Requirement
367
373
  requirements:
368
374
  - - "~>"
369
375
  - !ruby/object:Gem::Version
370
- version: 0.76.0
376
+ version: 0.88.0
371
377
  - !ruby/object:Gem::Dependency
372
378
  name: codecov
373
379
  requirement: !ruby/object:Gem::Requirement
@@ -392,7 +398,10 @@ extensions: []
392
398
  extra_rdoc_files: []
393
399
  files:
394
400
  - ".buildkite/pipeline.nightly.yml"
401
+ - ".github/CODEOWNERS"
402
+ - ".github/ISSUE_TEMPLATE.md"
395
403
  - ".github/probots.yml"
404
+ - ".github/pull_request_template.md"
396
405
  - ".gitignore"
397
406
  - ".rubocop-http---shopify-github-io-ruby-style-guide-rubocop-yml"
398
407
  - ".rubocop.yml"
@@ -403,7 +412,6 @@ files:
403
412
  - CODE_OF_CONDUCT.md
404
413
  - CONTRIBUTING.md
405
414
  - Gemfile
406
- - ISSUE_TEMPLATE.md
407
415
  - LICENSE.txt
408
416
  - README.md
409
417
  - Rakefile
@@ -415,6 +423,7 @@ files:
415
423
  - exe/krane
416
424
  - krane.gemspec
417
425
  - lib/krane.rb
426
+ - lib/krane/annotation.rb
418
427
  - lib/krane/bindings_parser.rb
419
428
  - lib/krane/cli/deploy_command.rb
420
429
  - lib/krane/cli/global_deploy_command.rb
@@ -428,6 +437,7 @@ files:
428
437
  - lib/krane/concerns/template_reporting.rb
429
438
  - lib/krane/concurrency.rb
430
439
  - lib/krane/container_logs.rb
440
+ - lib/krane/container_overrides.rb
431
441
  - lib/krane/deferred_summary_logging.rb
432
442
  - lib/krane/delayed_exceptions.rb
433
443
  - lib/krane/deploy_task.rb
@@ -441,7 +451,6 @@ files:
441
451
  - lib/krane/kubeclient_builder.rb
442
452
  - lib/krane/kubectl.rb
443
453
  - lib/krane/kubernetes_resource.rb
444
- - lib/krane/kubernetes_resource/cloudsql.rb
445
454
  - lib/krane/kubernetes_resource/config_map.rb
446
455
  - lib/krane/kubernetes_resource/cron_job.rb
447
456
  - lib/krane/kubernetes_resource/custom_resource.rb
@@ -468,6 +477,7 @@ files:
468
477
  - lib/krane/label_selector.rb
469
478
  - lib/krane/oj.rb
470
479
  - lib/krane/options_helper.rb
480
+ - lib/krane/psych_k8s_compatibility.rb
471
481
  - lib/krane/remote_logs.rb
472
482
  - lib/krane/render_task.rb
473
483
  - lib/krane/renderer.rb
@@ -483,7 +493,6 @@ files:
483
493
  - lib/krane/task_config_validator.rb
484
494
  - lib/krane/template_sets.rb
485
495
  - lib/krane/version.rb
486
- - pull_request_template.md
487
496
  - screenshots/deploy-demo.gif
488
497
  - screenshots/migrate-logs.png
489
498
  - screenshots/missing-secret-fail.png
@@ -492,7 +501,8 @@ files:
492
501
  homepage: https://github.com/Shopify/krane
493
502
  licenses:
494
503
  - MIT
495
- metadata: {}
504
+ metadata:
505
+ allowed_push_host: https://rubygems.org
496
506
  post_install_message:
497
507
  rdoc_options: []
498
508
  require_paths:
@@ -501,7 +511,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
501
511
  requirements:
502
512
  - - ">="
503
513
  - !ruby/object:Gem::Version
504
- version: 2.4.0
514
+ version: 2.5.0
505
515
  required_rubygems_version: !ruby/object:Gem::Requirement
506
516
  requirements:
507
517
  - - ">="