krane 1.1.0 → 2.0.0

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