krane 2.4.6 → 3.6.2

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.
data/krane.gemspec CHANGED
@@ -25,14 +25,14 @@ Gem::Specification.new do |spec|
25
25
 
26
26
  spec.metadata['allowed_push_host'] = "https://rubygems.org"
27
27
 
28
- spec.required_ruby_version = '>= 2.6.0'
28
+ spec.required_ruby_version = '>= 2.7.6'
29
29
  spec.add_dependency("activesupport", ">= 5.0")
30
30
  spec.add_dependency("kubeclient", "~> 4.9")
31
- spec.add_dependency("googleauth", "~> 0.8")
31
+ spec.add_dependency("googleauth", "~> 1.2")
32
32
  spec.add_dependency("ejson", "~> 1.0")
33
33
  spec.add_dependency("colorize", "~> 0.8")
34
- spec.add_dependency("statsd-instrument", ['>= 2.8', "< 4"])
35
- spec.add_dependency("oj", "~> 3.0")
34
+ spec.add_dependency("statsd-instrument", ['>= 2.8', "< 3.9"])
35
+ spec.add_dependency("multi_json")
36
36
  spec.add_dependency("concurrent-ruby", "~> 1.1")
37
37
  spec.add_dependency("jsonpath", "~> 1.0")
38
38
  spec.add_dependency("thor", ">= 1.0", "< 2.0")
@@ -43,11 +43,11 @@ Gem::Specification.new do |spec|
43
43
  spec.add_development_dependency("yard")
44
44
 
45
45
  # Test framework
46
- spec.add_development_dependency("minitest", "~> 5.12")
46
+ spec.add_development_dependency("minitest", "~> 5.19")
47
47
  spec.add_development_dependency("minitest-stub-const", "~> 0.6")
48
48
  spec.add_development_dependency("minitest-reporters")
49
- spec.add_development_dependency("mocha", "~> 1.5")
50
- spec.add_development_dependency("webmock", "~> 3.0")
49
+ spec.add_development_dependency("mocha", "~> 2.1")
50
+ spec.add_development_dependency("webmock", "~> 3.18")
51
51
  spec.add_development_dependency("timecop")
52
52
 
53
53
  # Debugging and analysis
@@ -41,7 +41,8 @@ module Krane
41
41
  when '.json'
42
42
  bindings = parse_json(File.read(file_path))
43
43
  when '.yaml', '.yml'
44
- bindings = YAML.safe_load(File.read(file_path), [], [], true, file_path)
44
+ bindings = YAML.safe_load(File.read(file_path), permitted_classes: [], permitted_symbols: [],
45
+ aliases: true, filename: file_path)
45
46
  else
46
47
  raise ArgumentError, "Supplied file does not appear to be JSON or YAML"
47
48
  end
@@ -53,14 +54,14 @@ module Krane
53
54
  end
54
55
 
55
56
  def parse_json(string)
56
- bindings = JSON.parse(string)
57
+ bindings = MultiJson.load(string)
57
58
 
58
59
  unless bindings.is_a?(Hash)
59
60
  raise ArgumentError, "Expected JSON data to be a hash."
60
61
  end
61
62
 
62
63
  bindings
63
- rescue JSON::ParserError
64
+ rescue MultiJson::ParseError
64
65
  nil
65
66
  end
66
67
 
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
  require 'krane'
3
- require 'krane/oj'
4
- require 'thor'
5
- require 'krane/cli/version_command'
6
- require 'krane/cli/restart_command'
7
- require 'krane/cli/run_command'
8
- require 'krane/cli/render_command'
9
3
  require 'krane/cli/deploy_command'
10
4
  require 'krane/cli/global_deploy_command'
5
+ require 'krane/cli/render_command'
6
+ require 'krane/cli/restart_command'
7
+ require 'krane/cli/run_command'
8
+ require 'krane/cli/version_command'
9
+ require 'multi_json'
10
+ require 'thor'
11
11
 
12
12
  module Krane
13
13
  module CLI
@@ -19,7 +19,7 @@ module Krane
19
19
  end
20
20
 
21
21
  def prunable_resources(namespaced:)
22
- black_list = %w(Namespace Node ControllerRevision)
22
+ black_list = %w(Namespace Node ControllerRevision Event)
23
23
  fetch_resources(namespaced: namespaced).map do |resource|
24
24
  next unless resource["verbs"].one? { |v| v == "delete" }
25
25
  next if black_list.include?(resource["kind"])
@@ -37,19 +37,6 @@ module Krane
37
37
  end.compact.uniq { |r| "#{r['apigroup']}/#{r['kind']}" }
38
38
  end
39
39
 
40
- def fetch_mutating_webhook_configurations
41
- command = %w(get mutatingwebhookconfigurations)
42
- raw_json, err, st = kubectl.run(*command, output: "json", attempts: 5, use_namespace: false)
43
- if st.success?
44
- JSON.parse(raw_json)["items"].map do |definition|
45
- Krane::MutatingWebhookConfiguration.new(namespace: namespace, context: context, logger: logger,
46
- definition: definition, statsd_tags: @namespace_tags)
47
- end
48
- else
49
- raise FatalKubeAPIError, "Error retrieving mutatingwebhookconfigurations: #{err}"
50
- end
51
- end
52
-
53
40
  private
54
41
 
55
42
  # During discovery, the api paths may not actually be at the root, so we must programatically find it.
@@ -67,7 +54,7 @@ module Krane
67
54
  @api_path_cache["/"] ||= begin
68
55
  raw_json, err, st = kubectl.run("get", "--raw", base_api_path, attempts: 5, use_namespace: false)
69
56
  paths = if st.success?
70
- JSON.parse(raw_json)["paths"]
57
+ MultiJson.load(raw_json)["paths"]
71
58
  else
72
59
  raise FatalKubeAPIError, "Error retrieving raw path /: #{err}"
73
60
  end
@@ -79,7 +66,7 @@ module Krane
79
66
  @api_path_cache[path] ||= begin
80
67
  raw_json, err, st = kubectl.run("get", "--raw", path, attempts: 2, use_namespace: false)
81
68
  if st.success?
82
- JSON.parse(raw_json)
69
+ MultiJson.load(raw_json)
83
70
  else
84
71
  logger.warn("Error retrieving api path: #{err}")
85
72
  {}
@@ -105,7 +92,7 @@ module Krane
105
92
  raw_json, err, st = kubectl.run("get", "CustomResourceDefinition", output: "json", attempts: 5,
106
93
  use_namespace: false)
107
94
  if st.success?
108
- JSON.parse(raw_json)["items"]
95
+ MultiJson.load(raw_json)["items"]
109
96
  else
110
97
  raise FatalKubeAPIError, "Error retrieving CustomResourceDefinition: #{err}"
111
98
  end
data/lib/krane/common.rb CHANGED
@@ -20,5 +20,5 @@ require 'krane/task_config'
20
20
  require 'krane/task_config_validator'
21
21
 
22
22
  module Krane
23
- MIN_KUBE_VERSION = '1.15.0'
23
+ MIN_KUBE_VERSION = '1.22.0'
24
24
  end
@@ -30,7 +30,6 @@ require 'krane/kubernetes_resource'
30
30
  custom_resource_definition
31
31
  horizontal_pod_autoscaler
32
32
  secret
33
- mutating_webhook_configuration
34
33
  ).each do |subresource|
35
34
  require "krane/kubernetes_resource/#{subresource}"
36
35
  end
@@ -78,7 +77,7 @@ module Krane
78
77
  Hash[before_crs + crs + after_crs]
79
78
  end
80
79
 
81
- def prune_whitelist
80
+ def prune_allowlist
82
81
  cluster_resource_discoverer.prunable_resources(namespaced: true)
83
82
  end
84
83
 
@@ -193,7 +192,7 @@ module Krane
193
192
 
194
193
  def resource_deployer
195
194
  @resource_deployer ||= Krane::ResourceDeployer.new(task_config: @task_config,
196
- prune_whitelist: prune_whitelist, global_timeout: @global_timeout,
195
+ prune_allowlist: prune_allowlist, global_timeout: @global_timeout,
197
196
  selector: @selector, statsd_tags: statsd_tags, current_sha: @current_sha)
198
197
  end
199
198
 
@@ -285,26 +284,11 @@ module Krane
285
284
  end
286
285
  measure_method(:validate_configuration)
287
286
 
288
- def partition_dry_run_resources(resources)
289
- individuals = []
290
- mutating_webhook_configurations = cluster_resource_discoverer.fetch_mutating_webhook_configurations
291
- mutating_webhook_configurations.each do |mutating_webhook_configuration|
292
- mutating_webhook_configuration.webhooks.each do |webhook|
293
- individuals = (individuals + resources.select { |resource| webhook.matches_resource?(resource) }).uniq
294
- resources -= individuals
295
- end
296
- end
297
- [resources, individuals]
298
- end
299
-
300
287
  def validate_resources(resources)
301
288
  validate_globals(resources)
302
- batchable_resources, individuals = partition_dry_run_resources(resources.dup)
303
- batch_dry_run_success = kubectl.server_dry_run_enabled? && validate_dry_run(batchable_resources)
304
- individuals += batchable_resources unless batch_dry_run_success
305
289
  resources.select! { |r| r.selected?(@selector) } if @selector_as_filter
306
290
  Krane::Concurrency.split_across_threads(resources) do |r|
307
- r.validate_definition(kubectl: kubectl, selector: @selector, dry_run: individuals.include?(r))
291
+ r.validate_definition(kubectl: kubectl, selector: @selector, dry_run: true)
308
292
  end
309
293
  failed_resources = resources.select(&:validation_failed?)
310
294
  if failed_resources.present?
@@ -330,15 +314,11 @@ module Krane
330
314
  "Use GlobalDeployTask instead."
331
315
  end
332
316
 
333
- def validate_dry_run(resources)
334
- resource_deployer.dry_run(resources)
335
- end
336
-
337
317
  def namespace_definition
338
318
  @namespace_definition ||= begin
339
319
  definition, _err, st = kubectl.run("get", "namespace", @namespace, use_namespace: false,
340
320
  log_failure: true, raise_if_not_found: true, attempts: 3, output: 'json')
341
- st.success? ? JSON.parse(definition, symbolize_names: true) : nil
321
+ st.success? ? MultiJson.load(definition, symbolize_names: true) : nil
342
322
  end
343
323
  rescue Kubectl::ResourceNotFoundError
344
324
  nil
@@ -372,7 +352,7 @@ module Krane
372
352
  unless st.success?
373
353
  raise EjsonSecretError, "Error retrieving Secret/#{EjsonSecretProvisioner::EJSON_KEYS_SECRET}: #{err}"
374
354
  end
375
- JSON.parse(out)
355
+ MultiJson.load(out)
376
356
  end
377
357
  end
378
358
 
@@ -117,8 +117,8 @@ module Krane
117
117
 
118
118
  def load_ejson_from_file
119
119
  return {} unless File.exist?(@ejson_file)
120
- JSON.parse(File.read(@ejson_file))
121
- rescue JSON::ParserError => e
120
+ MultiJson.load(File.read(@ejson_file))
121
+ rescue MultiJson::ParseError => e
122
122
  raise EjsonSecretError, "Failed to parse encrypted ejson:\n #{e}"
123
123
  end
124
124
 
@@ -139,8 +139,8 @@ module Krane
139
139
  msg = err.presence || out
140
140
  raise EjsonSecretError, msg
141
141
  end
142
- JSON.parse(out)
143
- rescue JSON::ParserError
142
+ MultiJson.load(out)
143
+ rescue MultiJson::ParseError
144
144
  raise EjsonSecretError, "Failed to parse decrypted ejson"
145
145
  end
146
146
 
@@ -108,7 +108,7 @@ module Krane
108
108
 
109
109
  def deploy!(resources, verify_result, prune)
110
110
  resource_deployer = ResourceDeployer.new(task_config: @task_config,
111
- prune_whitelist: prune_whitelist, global_timeout: @global_timeout,
111
+ prune_allowlist: prune_allowlist, global_timeout: @global_timeout,
112
112
  selector: @selector, statsd_tags: statsd_tags)
113
113
  resource_deployer.deploy!(resources, verify_result, prune)
114
114
  end
@@ -194,7 +194,7 @@ module Krane
194
194
  @kubectl ||= Kubectl.new(task_config: @task_config, log_failure_by_default: true)
195
195
  end
196
196
 
197
- def prune_whitelist
197
+ def prune_allowlist
198
198
  cluster_resource_discoverer.prunable_resources(namespaced: false)
199
199
  end
200
200
 
@@ -49,9 +49,9 @@ module Krane
49
49
  )
50
50
  end
51
51
 
52
- def build_policy_v1beta1_kubeclient(context)
52
+ def build_policy_v1_kubeclient(context)
53
53
  build_kubeclient(
54
- api_version: "v1beta1",
54
+ api_version: "v1",
55
55
  context: context,
56
56
  endpoint_path: "/apis/policy/"
57
57
  )
data/lib/krane/kubectl.rb CHANGED
@@ -12,6 +12,7 @@ module Krane
12
12
  DEFAULT_TIMEOUT = 15
13
13
  MAX_RETRY_DELAY = 16
14
14
  SERVER_DRY_RUN_MIN_VERSION = "1.13"
15
+ ALLOW_LIST_MIN_VERSION = "1.26"
15
16
 
16
17
  class ResourceNotFoundError < StandardError; end
17
18
 
@@ -82,9 +83,17 @@ module Krane
82
83
  def version_info
83
84
  @version_info ||=
84
85
  begin
85
- response, _, status = run("version", use_namespace: false, log_failure: true, attempts: 2)
86
+ response, _, status = run("version", output: "json", use_namespace: false, log_failure: true, attempts: 2)
86
87
  raise KubectlError, "Could not retrieve kubectl version info" unless status.success?
87
- extract_version_info_from_kubectl_response(response)
88
+
89
+ version_data = MultiJson.load(response)
90
+ client_version = platform_agnostic_version(version_data.dig("clientVersion", "gitVersion").to_s)
91
+ server_version = platform_agnostic_version(version_data.dig("serverVersion", "gitVersion").to_s)
92
+ unless client_version && server_version
93
+ raise KubectlError, "Received invalid kubectl version data: #{version_data}"
94
+ end
95
+
96
+ { client: client_version, server: server_version }
88
97
  end
89
98
  end
90
99
 
@@ -101,10 +110,14 @@ module Krane
101
110
  end
102
111
 
103
112
  def dry_run_flag
104
- if client_version >= Gem::Version.new("1.18")
105
- "--dry-run=server"
113
+ "--dry-run=server"
114
+ end
115
+
116
+ def allowlist_flag
117
+ if client_version >= Gem::Version.new(ALLOW_LIST_MIN_VERSION)
118
+ "--prune-allowlist"
106
119
  else
107
- "--server-dry-run"
120
+ "--prune-whitelist"
108
121
  end
109
122
  end
110
123
 
@@ -127,15 +140,10 @@ module Krane
127
140
  end
128
141
  end
129
142
 
130
- def extract_version_info_from_kubectl_response(response)
131
- info = {}
132
- response.each_line do |l|
133
- match = l.match(/^(?<kind>Client|Server).* GitVersion:"v(?<version>\d+\.\d+\.\d+)/)
134
- if match
135
- info[match[:kind].downcase.to_sym] = Gem::Version.new(match[:version])
136
- end
143
+ def platform_agnostic_version(version_string)
144
+ if match = version_string.match(/v(?<version>\d+\.\d+\.\d+)/)
145
+ Gem::Version.new(match[:version])
137
146
  end
138
- info
139
147
  end
140
148
  end
141
149
  end
@@ -16,7 +16,7 @@ module Krane
16
16
  end
17
17
 
18
18
  def kubectl_resource_type
19
- 'hpa.v2beta1.autoscaling'
19
+ 'hpa.v2.autoscaling'
20
20
  end
21
21
 
22
22
  def status
@@ -10,6 +10,7 @@ module Krane
10
10
  )
11
11
 
12
12
  attr_accessor :stream_logs
13
+ attr_reader :definition
13
14
 
14
15
  def initialize(namespace:, context:, definition:, logger:,
15
16
  statsd_tags: nil, parent: nil, deploy_started_at: nil, stream_logs: false)
@@ -5,6 +5,7 @@ module Krane
5
5
  class Service < KubernetesResource
6
6
  TIMEOUT = 7.minutes
7
7
  SYNC_DEPENDENCIES = %w(Pod Deployment StatefulSet)
8
+ SKIP_ENDPOINT_VALIDATION_ANNOTATION = 'skip-endpoint-validation'
8
9
 
9
10
  def sync(cache)
10
11
  super
@@ -59,6 +60,9 @@ module Krane
59
60
  end
60
61
 
61
62
  def requires_endpoints?
63
+ # skip validation if the annotation is present
64
+ return false if skip_endpoint_validation
65
+
62
66
  # services of type External don't have endpoints
63
67
  return false if external_name_svc?
64
68
 
@@ -96,5 +100,9 @@ module Krane
96
100
  def published?
97
101
  @instance_data.dig('status', 'loadBalancer', 'ingress').present?
98
102
  end
103
+
104
+ def skip_endpoint_validation
105
+ krane_annotation_value(SKIP_ENDPOINT_VALIDATION_ANNOTATION) == 'true'
106
+ end
99
107
  end
100
108
  end
@@ -5,6 +5,7 @@ module Krane
5
5
  TIMEOUT = 10.minutes
6
6
  ONDELETE = 'OnDelete'
7
7
  SYNC_DEPENDENCIES = %w(Pod)
8
+ REQUIRED_ROLLOUT_TYPES = %w(full).freeze
8
9
  attr_reader :pods
9
10
 
10
11
  def sync(cache)
@@ -19,25 +20,24 @@ module Krane
19
20
  end
20
21
 
21
22
  def deploy_succeeded?
22
- success = observed_generation == current_generation &&
23
- desired_replicas == status_data['readyReplicas'].to_i &&
24
- status_data['currentRevision'] == status_data['updateRevision']
25
- if update_strategy == ONDELETE
26
- # Gem cannot monitor update since it doesn't occur until delete
23
+ success = observed_generation == current_generation
24
+
25
+ if update_strategy == ONDELETE && required_rollout != "full"
27
26
  unless @success_assumption_warning_shown
28
- @logger.warn("WARNING: Your StatefulSet's updateStrategy is set to OnDelete, "\
29
- "which means updates will not be applied until its pods are deleted. "\
30
- "Consider switching to rollingUpdate.")
27
+ @logger.warn("WARNING: Your StatefulSet's updateStrategy is set to #{update_strategy}, "\
28
+ "which means updates will not be applied until its pods are deleted.")
31
29
  @success_assumption_warning_shown = true
32
30
  end
33
31
  else
34
- success &= desired_replicas == status_data['currentReplicas'].to_i
32
+ success &= desired_replicas == status_data['readyReplicas'].to_i
33
+ success &= desired_replicas == status_data['updatedReplicas'].to_i
35
34
  end
35
+
36
36
  success
37
37
  end
38
38
 
39
39
  def deploy_failed?
40
- return false if update_strategy == ONDELETE
40
+ return false if update_strategy == ONDELETE && required_rollout != 'full'
41
41
  pods.present? && pods.any?(&:deploy_failed?) &&
42
42
  observed_generation == current_generation
43
43
  end
@@ -65,7 +65,11 @@ module Krane
65
65
  def parent_of_pod?(pod_data)
66
66
  return false unless pod_data.dig("metadata", "ownerReferences")
67
67
  pod_data["metadata"]["ownerReferences"].any? { |ref| ref["uid"] == @instance_data["metadata"]["uid"] } &&
68
- @instance_data["status"]["currentRevision"] == pod_data["metadata"]["labels"]["controller-revision-hash"]
68
+ @instance_data["status"]["updateRevision"] == pod_data["metadata"]["labels"]["controller-revision-hash"]
69
+ end
70
+
71
+ def required_rollout
72
+ krane_annotation_value("required-rollout") || nil
69
73
  end
70
74
  end
71
75
  end
@@ -226,11 +226,6 @@ module Krane
226
226
  version ? grouping : "core"
227
227
  end
228
228
 
229
- def version
230
- prefix, version = @definition.dig("apiVersion").split("/")
231
- version || prefix
232
- end
233
-
234
229
  def kubectl_resource_type
235
230
  type
236
231
  end
@@ -250,7 +245,7 @@ module Krane
250
245
  end
251
246
 
252
247
  def deploy_method_override
253
- krane_annotation_value(DEPLOY_METHOD_OVERRIDE_ANNOTATION)&.to_sym
248
+ krane_annotation_value(DEPLOY_METHOD_OVERRIDE_ANNOTATION)&.gsub("-", "_")&.to_sym
254
249
  end
255
250
 
256
251
  def sync_debug_info(kubectl)
@@ -558,7 +553,6 @@ module Krane
558
553
  if err.empty? || err.match(SERVER_DRY_RUN_DISABLED_ERROR)
559
554
  _, err, st = validate_with_local_dry_run(kubectl)
560
555
  end
561
-
562
556
  return true if st.success?
563
557
  @validation_errors << if sensitive_template_content?
564
558
  "Validation for #{id} failed. Detailed information is unavailable as the raw error may contain sensitive data."
@@ -569,11 +563,7 @@ module Krane
569
563
 
570
564
  # Server side dry run is only supported on apply
571
565
  def validate_with_server_side_dry_run(kubectl)
572
- command = if kubectl.client_version >= Gem::Version.new('1.18')
573
- ["apply", "-f", file_path, "--dry-run=server", "--output=name"]
574
- else
575
- ["apply", "-f", file_path, "--server-dry-run", "--output=name"]
576
- end
566
+ command = ["apply", "-f", file_path, "--dry-run=server", "--output=name"]
577
567
 
578
568
  kubectl.run(*command, log_failure: false, output_is_sensitive: sensitive_template_content?,
579
569
  retry_whitelist: [:client_timeout, :empty, :context_deadline], attempts: 3)
@@ -584,12 +574,7 @@ module Krane
584
574
  # If the resource template uses generateName, validating with apply will fail
585
575
  def validate_with_local_dry_run(kubectl)
586
576
  verb = deploy_method == :apply ? "apply" : "create"
587
- command = if kubectl.client_version >= Gem::Version.new('1.18')
588
- [verb, "-f", file_path, "--dry-run=client", "--output=name"]
589
- else
590
- [verb, "-f", file_path, "--dry-run", "--output=name"]
591
- end
592
-
577
+ command = [verb, "-f", file_path, "--dry-run=client", "--output=name"]
593
578
  kubectl.run(*command, log_failure: false, output_is_sensitive: sensitive_template_content?,
594
579
  retry_whitelist: [:client_timeout, :empty, :context_deadline], attempts: 3, use_namespace: !global?)
595
580
  end
@@ -64,7 +64,7 @@ module Krane
64
64
  raise KubectlError unless st.success?
65
65
 
66
66
  instances = {}
67
- JSON.parse(raw_json)["items"].each do |resource|
67
+ MultiJson.load(raw_json)["items"].each do |resource|
68
68
  resource_name = resource.dig("metadata", "name")
69
69
  instances[resource_name] = resource
70
70
  end
@@ -11,22 +11,15 @@ module Krane
11
11
  delegate :logger, to: :@task_config
12
12
  attr_reader :statsd_tags
13
13
 
14
- def initialize(task_config:, prune_whitelist:, global_timeout:, current_sha: nil, selector:, statsd_tags:)
14
+ def initialize(task_config:, prune_allowlist:, global_timeout:, current_sha: nil, selector:, statsd_tags:)
15
15
  @task_config = task_config
16
- @prune_whitelist = prune_whitelist
16
+ @prune_allowlist = prune_allowlist
17
17
  @global_timeout = global_timeout
18
18
  @current_sha = current_sha
19
19
  @selector = selector
20
20
  @statsd_tags = statsd_tags
21
21
  end
22
22
 
23
- def dry_run(resources)
24
- apply_all(resources, true, dry_run: true)
25
- true
26
- rescue FatalDeploymentError
27
- false
28
- end
29
-
30
23
  def deploy!(resources, verify_result, prune)
31
24
  if verify_result
32
25
  deploy_all_resources(resources, prune: prune, verify: true)
@@ -102,7 +95,7 @@ module Krane
102
95
  # Apply can be done in one large batch, the rest have to be done individually
103
96
  applyables, individuals = resources.partition { |r| r.deploy_method == :apply }
104
97
  # Prunable resources should also applied so that they can be pruned
105
- pruneable_types = @prune_whitelist.map { |t| t.split("/").last }
98
+ pruneable_types = @prune_allowlist.map { |t| t.split("/").last }
106
99
  applyables += individuals.select { |r| pruneable_types.include?(r.type) && !r.deploy_method_override }
107
100
 
108
101
  individuals.each do |individual_resource|
@@ -147,14 +140,15 @@ module Krane
147
140
  r.deploy_started_at = Time.now.utc unless dry_run
148
141
  end
149
142
  command.push("-f", tmp_dir)
150
- if prune && @prune_whitelist.present?
143
+ if prune && @prune_allowlist.present?
151
144
  command.push("--prune")
152
145
  if @selector
153
146
  command.push("--selector", @selector.to_s)
154
147
  else
155
148
  command.push("--all")
156
149
  end
157
- @prune_whitelist.each { |type| command.push("--prune-whitelist=#{type}") }
150
+ allow_list_flag = kubectl.allowlist_flag
151
+ @prune_allowlist.each { |type| command.push("#{allow_list_flag}=#{type}") }
158
152
  end
159
153
 
160
154
  command.push(kubectl.dry_run_flag) if dry_run
@@ -252,7 +246,7 @@ module Krane
252
246
  # For resources that rely on a generateName attribute, we get the `name` from the result of the call to `create`
253
247
  # We must explicitly set this name value so that the `apply` step for pruning can run successfully
254
248
  if status.success? && resource.uses_generate_name?
255
- resource.use_generated_name(JSON.parse(out))
249
+ resource.use_generated_name(MultiJson.load(out))
256
250
  end
257
251
 
258
252
  [err, status]
@@ -12,10 +12,9 @@ module Krane
12
12
  class FatalRestartError < FatalDeploymentError; end
13
13
 
14
14
  class RestartAPIError < FatalRestartError
15
- def initialize(deployment_name, response)
15
+ def initialize(deployment_name, message)
16
16
  super("Failed to restart #{deployment_name}. " \
17
- "API returned non-200 response code (#{response.code})\n" \
18
- "Response:\n#{response.body}")
17
+ "Error:\n#{message}")
19
18
  end
20
19
  end
21
20
 
@@ -11,7 +11,7 @@ module Krane
11
11
  def from_annotation(conditions_string)
12
12
  return new(default_conditions) if conditions_string.downcase.strip == "true"
13
13
 
14
- conditions = JSON.parse(conditions_string).slice('success_conditions', 'failure_conditions')
14
+ conditions = MultiJson.load(conditions_string).slice('success_conditions', 'failure_conditions')
15
15
  conditions.deep_symbolize_keys!
16
16
 
17
17
  # Create JsonPath objects
@@ -26,7 +26,7 @@ module Krane
26
26
  end
27
27
 
28
28
  new(conditions)
29
- rescue JSON::ParserError => e
29
+ rescue MultiJson::ParseError => e
30
30
  raise RolloutConditionsError, "Rollout conditions are not valid JSON: #{e}"
31
31
  rescue StandardError => e
32
32
  raise RolloutConditionsError,
data/lib/krane/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Krane
3
- VERSION = "2.4.6"
3
+ VERSION = "3.6.2"
4
4
  end