kubernetes-deploy 0.14.1 → 0.15.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2b7eaf966de6685ee13686190feda92f7d5e249c
4
- data.tar.gz: 7bc442ae69145779cd8965caababf22545a5d954
3
+ metadata.gz: 6f73fbf31b907e647a5c5fb9f37672cda04f2fbb
4
+ data.tar.gz: 37ff614545966a6aed17f814e71f244ec571c0de
5
5
  SHA512:
6
- metadata.gz: 983f99b3be92381d2838bc7b7cd4d9efd4220e9b13cd68d795d1d5523cd550d15effea7da8dc273d6dec8825e23372a63ff82a05e577ebcbdac0a3c2b9c2095b
7
- data.tar.gz: 28eb00deaa911348e3d27be549bcd0c788e8efc00977edd1c3986521b9e82367b06a8d80a258a371ec9dcd9d4b9dc7100d6e4856f0f98596fd2ab2b43dfd005b
6
+ metadata.gz: da6efb2e3f67dcb4e322559fb39deaa2d87606269cb1f1ab1f1609cc4a01d7af766e0bae0483a1ad448143de4f3db80a81938221a9bff6daefb4e475c0400d11
7
+ data.tar.gz: 5991bc3e2dc085d46c28ad3c11fc057cf9bbc79785cd2b92bef41b9d637e96b2b74650852ab7bdc574f1f3b8d55ea7a3513e94440fe360292c3dc876833b46f8
@@ -1,3 +1,10 @@
1
+ - name: 'Run Test Suite (:kubernetes: 1.10-latest)'
2
+ command: bin/ci
3
+ agents:
4
+ queue: minikube-ci
5
+ env:
6
+ LOGGING_LEVEL: 4
7
+ KUBERNETES_VERSION: v1.10-latest
1
8
  - name: 'Run Test Suite (:kubernetes: 1.9-latest)'
2
9
  command: bin/ci
3
10
  agents:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ### 0.15.0
2
+ *Bug Fixes*
3
+ - None
4
+
5
+ *Enhancements*
6
+ - Support for cronjob resource ([#206](https://github.com/Shopify/kubernetes-deploy/pull/206])).
7
+ - Make it possible to override the tool's hard timeout for one specific resource via the `kubernetes-deploy.shopify.io/timeout-override`
8
+ annotation ([#232](https://github.com/Shopify/kubernetes-deploy/pull/232)).
9
+ - Make it possible to modify how many replicas need to be updated and available before a deployment is considered
10
+ successful via the `kubernetes-deploy.shopify.io/required-rollout` annotation ([#208](https://github.com/Shopify/kubernetes-deploy/pull/208)).
11
+
1
12
  ### 0.14.1
2
13
  *Bug Fixes*
3
14
  - Make deployments whose pods crash because of CreateContainerConfigError fail fast in 1.8+ too (they would previously time out).
data/README.md CHANGED
@@ -39,6 +39,7 @@ This repo also includes related tools for [running tasks](#kubernetes-run) and [
39
39
  * [Installation](#installation)
40
40
  * [Usage](#usage)
41
41
  * [Using templates and variables](#using-templates-and-variables)
42
+ * [Customizing behaviour with annotations](#customizing-behaviour-with-annotations)
42
43
  * [Running tasks at the beginning of a deploy](#running-tasks-at-the-beginning-of-a-deploy)
43
44
  * [Deploying Kubernetes secrets (from EJSON)](#deploying-kubernetes-secrets-from-ejson)
44
45
 
@@ -120,6 +121,20 @@ All templates must be YAML formatted. You can also use ERB. The following local
120
121
  You can add additional variables using the `--bindings=BINDINGS` option. For example, `kubernetes-deploy my-app cluster1 --bindings=color=blue,size=large` will expose `color` and `size` in your templates.
121
122
 
122
123
 
124
+ ### Customizing behaviour with annotations
125
+ - `kubernetes-deploy.shopify.io/timeout-override`: Override the tool's hard timeout for one specific resource. Both full ISO8601 durations and the time portion of ISO8601 durations are valid. Value must be between 1 second and 24 hours.
126
+ - _Example values_: 45s / 3m / 1h / PT0.25H
127
+ - _Compatibility_: all resource types (Note: `Deployment` timeouts are based on `spec.progressDeadlineSeconds` if present, and that field has a default value as of the `apps/v1beta1` group version. Using this annotation will have no effect on `Deployment`s that time out with "Timeout reason: ProgressDeadlineExceeded".)
128
+ - `kubernetes-deploy.shopify.io/required-rollout`: Modifies how much of the rollout needs to finish
129
+ before the deployment is considered successful.
130
+ - _Compatibility_: Deployment
131
+ - `full`: The deployment is successful when all pods in the new `replicaSet` are ready.
132
+ - `none`: The deployment is successful as soon as the new `replicaSet` is created for the deployment.
133
+ - `maxUnavailable`: The deploy is successful when minimum availability is reached in the new `replicaSet`.
134
+ In other words, the number of new pods that must be ready is equal to `spec.replicas` - `strategy.RollingUpdate.maxUnavailable`
135
+ (converted from percentages by rounding up, if applicable). This option is only valid for deployments
136
+ that use the `RollingUpdate` strategy.
137
+
123
138
 
124
139
  ### Running tasks at the beginning of a deploy
125
140
 
@@ -28,6 +28,7 @@ require 'kubernetes-deploy/kubernetes_resource'
28
28
  topic
29
29
  bucket
30
30
  stateful_set
31
+ cron_job
31
32
  ).each do |subresource|
32
33
  require "kubernetes-deploy/kubernetes_resource/#{subresource}"
33
34
  end
@@ -65,18 +66,28 @@ module KubernetesDeploy
65
66
  # core/v1/ReplicationController -- superseded by deployments/replicasets
66
67
  # extensions/v1beta1/ReplicaSet -- managed by deployments
67
68
  # core/v1/Secret -- should not committed / managed by shipit
68
- PRUNE_WHITELIST = %w(
69
- core/v1/ConfigMap
70
- core/v1/Pod
71
- core/v1/Service
72
- batch/v1/Job
73
- extensions/v1beta1/DaemonSet
74
- extensions/v1beta1/Deployment
75
- apps/v1beta1/Deployment
76
- extensions/v1beta1/Ingress
77
- apps/v1beta1/StatefulSet
78
- autoscaling/v1/HorizontalPodAutoscaler
79
- ).freeze
69
+ def prune_whitelist
70
+ wl = %w(
71
+ core/v1/ConfigMap
72
+ core/v1/Pod
73
+ core/v1/Service
74
+ batch/v1/Job
75
+ extensions/v1beta1/DaemonSet
76
+ extensions/v1beta1/Deployment
77
+ apps/v1beta1/Deployment
78
+ extensions/v1beta1/Ingress
79
+ apps/v1beta1/StatefulSet
80
+ autoscaling/v1/HorizontalPodAutoscaler
81
+ )
82
+ if server_version >= Gem::Version.new('1.8.0')
83
+ wl << "batch/v1beta1/CronJob"
84
+ end
85
+ wl
86
+ end
87
+
88
+ def server_version
89
+ kubectl.server_version
90
+ end
80
91
 
81
92
  NOT_FOUND_ERROR = 'NotFound'
82
93
 
@@ -383,7 +394,7 @@ module KubernetesDeploy
383
394
 
384
395
  if prune
385
396
  command.push("--prune", "--all")
386
- PRUNE_WHITELIST.each { |type| command.push("--prune-whitelist=#{type}") }
397
+ prune_whitelist.each { |type| command.push("--prune-whitelist=#{type}") }
387
398
  end
388
399
 
389
400
  out, err, st = kubectl.run(*command, log_failure: false)
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KubernetesDeploy
4
+ ##
5
+ # This class is a less strict extension of ActiveSupport::Duration::ISO8601Parser.
6
+ # In addition to full ISO8601 durations, it can parse unprefixed ISO8601 time components (e.g. '1H').
7
+ # It is also case-insensitive.
8
+ # For example, this class considers the values "1H", "1h" and "PT1H" to be valid and equivalent.
9
+
10
+ class DurationParser
11
+ class ParsingError < ArgumentError; end
12
+
13
+ def initialize(value)
14
+ @iso8601_str = value.to_s.strip.upcase
15
+ end
16
+
17
+ def parse!
18
+ ActiveSupport::Duration.parse("PT#{@iso8601_str}") # By default assume it is just a time component
19
+ rescue ActiveSupport::Duration::ISO8601Parser::ParsingError
20
+ begin
21
+ ActiveSupport::Duration.parse(@iso8601_str)
22
+ rescue ActiveSupport::Duration::ISO8601Parser::ParsingError => e
23
+ raise ParsingError, e.message
24
+ end
25
+ end
26
+ end
27
+ end
@@ -28,6 +28,14 @@ module KubernetesDeploy
28
28
  )
29
29
  end
30
30
 
31
+ def build_batch_v1beta1_kubeclient(context)
32
+ _build_kubeclient(
33
+ api_version: "v1beta1",
34
+ context: context,
35
+ endpoint_path: "/apis/batch/"
36
+ )
37
+ end
38
+
31
39
  def build_policy_v1beta1_kubeclient(context)
32
40
  _build_kubeclient(
33
41
  api_version: "v1beta1",
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ module KubernetesDeploy
3
+ class CronJob < KubernetesResource
4
+ TIMEOUT = 30.seconds
5
+
6
+ def sync
7
+ _, _err, st = kubectl.run("get", type, @name)
8
+ @status = st.success? ? "Available" : "Unknown"
9
+ @found = st.success?
10
+ end
11
+
12
+ def deploy_succeeded?
13
+ exists?
14
+ end
15
+
16
+ def deploy_failed?
17
+ !exists?
18
+ end
19
+
20
+ def timeout_message
21
+ UNUSUAL_FAILURE_MESSAGE
22
+ end
23
+
24
+ def exists?
25
+ @found
26
+ end
27
+ end
28
+ end
@@ -2,6 +2,9 @@
2
2
  module KubernetesDeploy
3
3
  class Deployment < KubernetesResource
4
4
  TIMEOUT = 7.minutes
5
+ REQUIRED_ROLLOUT_ANNOTATION = 'kubernetes-deploy.shopify.io/required-rollout'
6
+ REQUIRED_ROLLOUT_TYPES = %w(maxUnavailable full none).freeze
7
+ DEFAULT_REQUIRED_ROLLOUT = 'full'
5
8
 
6
9
  def sync
7
10
  raw_json, _err, st = kubectl.run("get", type, @name, "--output=json")
@@ -19,6 +22,7 @@ module KubernetesDeploy
19
22
  conditions = deployment_data.fetch("status", {}).fetch("conditions", [])
20
23
  @progress_condition = conditions.find { |condition| condition['type'] == 'Progressing' }
21
24
  @progress_deadline = deployment_data['spec']['progressDeadlineSeconds']
25
+ @max_unavailable = deployment_data.dig('spec', 'strategy', 'rollingUpdate', 'maxUnavailable')
22
26
  else # reset
23
27
  @latest_rs = nil
24
28
  @rollout_data = { "replicas" => 0 }
@@ -26,6 +30,7 @@ module KubernetesDeploy
26
30
  @progress_condition = nil
27
31
  @progress_deadline = @definition['spec']['progressDeadlineSeconds']
28
32
  @desired_replicas = -1
33
+ @max_unavailable = @definition.dig('spec', 'strategy', 'rollingUpdate', 'maxUnavailable')
29
34
  end
30
35
  end
31
36
 
@@ -43,10 +48,23 @@ module KubernetesDeploy
43
48
  def deploy_succeeded?
44
49
  return false unless @latest_rs.present?
45
50
 
46
- @latest_rs.deploy_succeeded? &&
47
- @latest_rs.desired_replicas == @desired_replicas && # latest RS fully scaled up
48
- @rollout_data["updatedReplicas"].to_i == @desired_replicas &&
49
- @rollout_data["updatedReplicas"].to_i == @rollout_data["availableReplicas"].to_i
51
+ case required_rollout
52
+ when 'full'
53
+ @latest_rs.deploy_succeeded? &&
54
+ @latest_rs.desired_replicas == @desired_replicas && # latest RS fully scaled up
55
+ @rollout_data["updatedReplicas"].to_i == @desired_replicas &&
56
+ @rollout_data["updatedReplicas"].to_i == @rollout_data["availableReplicas"].to_i
57
+ when 'none'
58
+ true
59
+ when 'maxUnavailable'
60
+ minimum_needed = min_available_replicas
61
+
62
+ @latest_rs.desired_replicas >= minimum_needed &&
63
+ @latest_rs.ready_replicas >= minimum_needed &&
64
+ @latest_rs.available_replicas >= minimum_needed
65
+ else
66
+ raise FatalDeploymentError, rollout_annotation_err_msg
67
+ end
50
68
  end
51
69
 
52
70
  def deploy_failed?
@@ -81,8 +99,29 @@ module KubernetesDeploy
81
99
  @found
82
100
  end
83
101
 
102
+ def validate_definition
103
+ super
104
+
105
+ unless REQUIRED_ROLLOUT_TYPES.include?(required_rollout)
106
+ @validation_errors << rollout_annotation_err_msg
107
+ end
108
+
109
+ strategy = @definition.dig('spec', 'strategy', 'type').to_s
110
+ if required_rollout.downcase == 'maxunavailable' && strategy.downcase != 'rollingupdate'
111
+ @validation_errors << "'#{REQUIRED_ROLLOUT_ANNOTATION}: #{required_rollout}' is incompatible "\
112
+ "with strategy '#{strategy}'"
113
+ end
114
+
115
+ @validation_errors.empty?
116
+ end
117
+
84
118
  private
85
119
 
120
+ def rollout_annotation_err_msg
121
+ "'#{REQUIRED_ROLLOUT_ANNOTATION}: #{required_rollout}' is invalid. "\
122
+ "Acceptable values: #{REQUIRED_ROLLOUT_TYPES.join(', ')}"
123
+ end
124
+
86
125
  def deploy_failing_to_progress?
87
126
  return false unless @progress_condition.present?
88
127
 
@@ -98,18 +137,22 @@ module KubernetesDeploy
98
137
  Time.parse(@progress_condition["lastUpdateTime"]).to_i >= (@deploy_started_at - 5.seconds).to_i
99
138
  end
100
139
 
101
- def find_latest_rs(deployment_data)
102
- label_string = deployment_data["spec"]["selector"]["matchLabels"].map { |k, v| "#{k}=#{v}" }.join(",")
140
+ def all_rs_data(match_labels)
141
+ label_string = match_labels.map { |k, v| "#{k}=#{v}" }.join(",")
103
142
  raw_json, _err, st = kubectl.run("get", "replicasets", "--output=json", "--selector=#{label_string}")
104
- return unless st.success?
143
+ return {} unless st.success?
144
+
145
+ JSON.parse(raw_json)["items"]
146
+ end
105
147
 
106
- all_rs_data = JSON.parse(raw_json)["items"]
148
+ def find_latest_rs(deployment_data)
107
149
  current_revision = deployment_data["metadata"]["annotations"]["deployment.kubernetes.io/revision"]
108
150
 
109
- latest_rs_data = all_rs_data.find do |rs|
151
+ latest_rs_data = all_rs_data(deployment_data["spec"]["selector"]["matchLabels"]).find do |rs|
110
152
  rs["metadata"]["ownerReferences"].any? { |ref| ref["uid"] == deployment_data["metadata"]["uid"] } &&
111
153
  rs["metadata"]["annotations"]["deployment.kubernetes.io/revision"] == current_revision
112
154
  end
155
+
113
156
  return unless latest_rs_data.present?
114
157
 
115
158
  rs = ReplicaSet.new(
@@ -123,5 +166,18 @@ module KubernetesDeploy
123
166
  rs.sync(latest_rs_data)
124
167
  rs
125
168
  end
169
+
170
+ def min_available_replicas
171
+ if @max_unavailable =~ /%/
172
+ (@desired_replicas * (100 - @max_unavailable.to_i) / 100.0).ceil
173
+ else
174
+ @desired_replicas - @max_unavailable.to_i
175
+ end
176
+ end
177
+
178
+ def required_rollout
179
+ @definition.dig('metadata', 'annotations', REQUIRED_ROLLOUT_ANNOTATION).presence ||
180
+ DEFAULT_REQUIRED_ROLLOUT
181
+ end
126
182
  end
127
183
  end
@@ -3,13 +3,15 @@ require 'kubernetes-deploy/kubernetes_resource/pod_set_base'
3
3
  module KubernetesDeploy
4
4
  class ReplicaSet < PodSetBase
5
5
  TIMEOUT = 5.minutes
6
- attr_reader :desired_replicas, :pods
6
+ attr_reader :desired_replicas, :ready_replicas, :available_replicas, :pods
7
7
 
8
8
  def initialize(namespace:, context:, definition:, logger:, parent: nil, deploy_started_at: nil)
9
9
  @parent = parent
10
10
  @deploy_started_at = deploy_started_at
11
11
  @rollout_data = { "replicas" => 0 }
12
12
  @desired_replicas = -1
13
+ @ready_replicas = -1
14
+ @available_replicas = -1
13
15
  @pods = []
14
16
  super(namespace: namespace, context: context, definition: definition, logger: logger)
15
17
  end
@@ -26,6 +28,8 @@ module KubernetesDeploy
26
28
  @rollout_data = { "replicas" => 0 }.merge(
27
29
  rs_data["status"].slice("replicas", "availableReplicas", "readyReplicas")
28
30
  )
31
+ @ready_replicas = @rollout_data['readyReplicas'].to_i
32
+ @available_replicas = @rollout_data["availableReplicas"].to_i
29
33
  @status = @rollout_data.map { |state_replicas, num| "#{num} #{state_replicas.chop.pluralize(num)}" }.join(", ")
30
34
  @pods = find_pods(rs_data)
31
35
  else # reset
@@ -34,6 +38,8 @@ module KubernetesDeploy
34
38
  @status = nil
35
39
  @pods = []
36
40
  @desired_replicas = -1
41
+ @ready_replicas = -1
42
+ @available_replicas = -1
37
43
  end
38
44
  end
39
45
 
@@ -6,7 +6,7 @@ require 'kubernetes-deploy/kubectl'
6
6
 
7
7
  module KubernetesDeploy
8
8
  class KubernetesResource
9
- attr_reader :name, :namespace, :context, :validation_error_msg
9
+ attr_reader :name, :namespace, :context
10
10
  attr_writer :type, :deploy_started_at
11
11
 
12
12
  TIMEOUT = 5.minutes
@@ -22,6 +22,8 @@ module KubernetesDeploy
22
22
  If you have reason to believe it will succeed, retry the deploy to continue to monitor the rollout.
23
23
  MSG
24
24
 
25
+ TIMEOUT_OVERRIDE_ANNOTATION = "kubernetes-deploy.shopify.io/timeout-override"
26
+
25
27
  def self.build(namespace:, context:, definition:, logger:)
26
28
  opts = { namespace: namespace, context: context, definition: definition, logger: logger }
27
29
  if KubernetesDeploy.const_defined?(definition["kind"])
@@ -39,9 +41,17 @@ module KubernetesDeploy
39
41
  end
40
42
 
41
43
  def timeout
44
+ return timeout_override if timeout_override.present?
42
45
  self.class.timeout
43
46
  end
44
47
 
48
+ def timeout_override
49
+ return @timeout_override if defined?(@timeout_override)
50
+ @timeout_override = DurationParser.new(timeout_annotation).parse!.to_i
51
+ rescue DurationParser::ParsingError
52
+ @timeout_override = nil
53
+ end
54
+
45
55
  def pretty_timeout_type
46
56
  "timeout: #{timeout}s"
47
57
  end
@@ -59,20 +69,26 @@ module KubernetesDeploy
59
69
  @logger = logger
60
70
  @definition = definition
61
71
  @statsd_report_done = false
62
- @validation_error_msg = nil
72
+ @validation_errors = []
63
73
  end
64
74
 
65
75
  def validate_definition
66
- @validation_error_msg = nil
76
+ @validation_errors = []
77
+ validate_timeout_annotation
78
+
67
79
  command = ["create", "-f", file_path, "--dry-run", "--output=name"]
68
80
  _, err, st = kubectl.run(*command, log_failure: false)
69
81
  return true if st.success?
70
- @validation_error_msg = err
82
+ @validation_errors << err
71
83
  false
72
84
  end
73
85
 
86
+ def validation_error_msg
87
+ @validation_errors.join("\n")
88
+ end
89
+
74
90
  def validation_failed?
75
- @validation_error_msg.present?
91
+ @validation_errors.present?
76
92
  end
77
93
 
78
94
  def id
@@ -277,6 +293,23 @@ module KubernetesDeploy
277
293
 
278
294
  private
279
295
 
296
+ def validate_timeout_annotation
297
+ return if timeout_annotation.nil?
298
+
299
+ override = DurationParser.new(timeout_annotation).parse!
300
+ if override <= 0
301
+ @validation_errors << "#{TIMEOUT_OVERRIDE_ANNOTATION} annotation is invalid: Value must be greater than 0"
302
+ elsif override > 24.hours
303
+ @validation_errors << "#{TIMEOUT_OVERRIDE_ANNOTATION} annotation is invalid: Value must be less than 24h"
304
+ end
305
+ rescue DurationParser::ParsingError => e
306
+ @validation_errors << "#{TIMEOUT_OVERRIDE_ANNOTATION} annotation is invalid: #{e}"
307
+ end
308
+
309
+ def timeout_annotation
310
+ @definition.dig("metadata", "annotations", TIMEOUT_OVERRIDE_ANNOTATION)
311
+ end
312
+
280
313
  def file
281
314
  @file ||= create_definition_tempfile
282
315
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module KubernetesDeploy
3
- VERSION = "0.14.1"
3
+ VERSION = "0.15.0"
4
4
  end
@@ -8,6 +8,7 @@ require 'active_support/core_ext/string/inflections'
8
8
  require 'active_support/core_ext/string/strip'
9
9
  require 'active_support/core_ext/hash/keys'
10
10
  require 'active_support/core_ext/array/conversions'
11
+ require 'active_support/duration'
11
12
  require 'colorized_string'
12
13
 
13
14
  require 'kubernetes-deploy/version'
@@ -17,6 +18,7 @@ require 'kubernetes-deploy/deploy_task'
17
18
  require 'kubernetes-deploy/statsd'
18
19
  require 'kubernetes-deploy/concurrency'
19
20
  require 'kubernetes-deploy/bindings_parser'
21
+ require 'kubernetes-deploy/duration_parser'
20
22
 
21
23
  module KubernetesDeploy
22
24
  KubernetesDeploy::StatsD.build
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.14.1
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katrina Verey
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2017-12-20 00:00:00.000000000 Z
12
+ date: 2018-01-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -227,6 +227,7 @@ files:
227
227
  - lib/kubernetes-deploy/concurrency.rb
228
228
  - lib/kubernetes-deploy/deferred_summary_logging.rb
229
229
  - lib/kubernetes-deploy/deploy_task.rb
230
+ - lib/kubernetes-deploy/duration_parser.rb
230
231
  - lib/kubernetes-deploy/ejson_secret_provisioner.rb
231
232
  - lib/kubernetes-deploy/errors.rb
232
233
  - lib/kubernetes-deploy/formatted_logger.rb
@@ -238,6 +239,7 @@ files:
238
239
  - lib/kubernetes-deploy/kubernetes_resource/bugsnag.rb
239
240
  - lib/kubernetes-deploy/kubernetes_resource/cloudsql.rb
240
241
  - lib/kubernetes-deploy/kubernetes_resource/config_map.rb
242
+ - lib/kubernetes-deploy/kubernetes_resource/cron_job.rb
241
243
  - lib/kubernetes-deploy/kubernetes_resource/daemon_set.rb
242
244
  - lib/kubernetes-deploy/kubernetes_resource/deployment.rb
243
245
  - lib/kubernetes-deploy/kubernetes_resource/elasticsearch.rb
@@ -287,7 +289,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
287
289
  version: '0'
288
290
  requirements: []
289
291
  rubyforge_project:
290
- rubygems_version: 2.5.2.1
292
+ rubygems_version: 2.6.14
291
293
  signing_key:
292
294
  specification_version: 4
293
295
  summary: Kubernetes deploy scripts