krane 3.2.0 → 3.4.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
  SHA256:
3
- metadata.gz: c1c5ae5aab30f6f9065bdf415b4fe94b7b82c8c0a05aecc582a5363349221be8
4
- data.tar.gz: 79d0aefc5abb7671c5c366a02648e183589d1cb90991912f381ac0b6a46c5af6
3
+ metadata.gz: 0a400c15e247a60bf8596665ddf2737abb44c2418358212e689890eb2178956f
4
+ data.tar.gz: '0386e1417ba00c97add6aa7184176785f82d05de5453140a8806540833c85f46'
5
5
  SHA512:
6
- metadata.gz: 33c08fdcb4e09e571667872ea761f046977516e1d882d29638faf54f9f58b00ae0534de616a5f304a7231f2820c2a6938ae7a3eaea761987c619b4f6ffc13693
7
- data.tar.gz: 96d52d7e49b0d50bd12e6c28f8ec65e3db86e3b66704149a6ef7756119a168ca4326d0e7aeb897489a2a04a8a4d0e56e7ca0b6254d88e48e682b134ee7b921a9
6
+ metadata.gz: a8b4c706a3918d6d3b66f098ae03c1e02680d59bef3f8eab34248997bfc11e512206f1b1d1794f50f12965e7a0cffbb2df2293b4639dd28b4b8526db881cf315
7
+ data.tar.gz: 7d113bfa20d8dec893fa3494ea7f55a9bf89c3a59ca7a461e1076c5fed37c2725b495a96efa5034c18b857819c96f5803045dec444a3c205e70f647b162f8106
data/.github/CODEOWNERS CHANGED
@@ -1 +1 @@
1
- * @Shopify/app-lifecycle
1
+ * @Shopify/infrastructure-tooling
@@ -0,0 +1,18 @@
1
+ name: Project automations
2
+ on:
3
+ issues:
4
+ types:
5
+ - opened
6
+ - reopened
7
+ env:
8
+ PROJECT_URL: https://github.com/orgs/Shopify/projects/2279
9
+
10
+ jobs:
11
+ add-to-project:
12
+ name: Issue or PR opened
13
+ runs-on: shopify-ubuntu-latest
14
+ steps:
15
+ - uses: actions/add-to-project@v0.4.0 # https://github.com/actions/add-to-project/tree/v0.4.0
16
+ with:
17
+ project-url: ${{ env.PROJECT_URL }}
18
+ github-token: ${{ secrets.SHOPIFY_GH_ACCESS_TOKEN }}
@@ -16,10 +16,13 @@ jobs:
16
16
  - "3.0.4"
17
17
  - "2.7.6"
18
18
  kubernetes_version:
19
+ - "1.27.3"
19
20
  - "1.26.4"
20
21
  - "1.24.13"
21
22
  - "1.23.17"
22
23
  include:
24
+ - kubernetes_version: "1.27.3"
25
+ kind_image: "kindest/node:v1.27.3@sha256:9dd3392d79af1b084671b05bcf65b21de476256ad1dcc853d9f3b10b4ac52dde"
23
26
  - kubernetes_version: "1.26.4"
24
27
  kind_image: "kindest/node:v1.26.4@sha256:a539833d26264444ab3b8f5e56e23fa3361436445fa23c864e6dec622458858f"
25
28
  - kubernetes_version: "1.24.13"
data/1.0-Upgrade.md CHANGED
@@ -7,7 +7,7 @@
7
7
  * There are breaking changes in the public API (such as the renaming of the `KubernetesDeploy` namespace to `Krane`, and the change in default values for different arguments of the public interface).
8
8
  * StatsD metrics will now be generated with the `krane` prefix.
9
9
  * `krane deploy` now considers all namespaced resources eligible for pruning, including
10
- custom resources. See [blacklist](https://github.com/Shopify/krane/blob/master/lib/krane/cluster_resource_discovery.rb#L20) for exceptions.
10
+ custom resources. See [blacklist](https://github.com/Shopify/krane/blob/main/lib/krane/cluster_resource_discovery.rb#L20) for exceptions.
11
11
  * `kubernetes-deploy` (now `krane deploy`) / `DeployTask` can no longer deploy global (non-namespaced) resources. A new command called `krane global-deploy` and a related class called `GlobalDeployTask` were added to replace that feature.
12
12
  * `krane deploy` will not render erb templates. Use `krane render | krane deploy --stdin` to reproduce this functionality.
13
13
  * If you attempt to install two gems that have conflicting executables, `gem install` will warn you but the most recently installed one will win.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  ## next
2
2
 
3
+ # 3.4.0
4
+
5
+ - Use `prune-allowlist` instead of `prune-whitelist` for 1.26+ clusters. Clusters running 1.25 or less will continue to use `--prune-whitelist`. [#940](https://github.com/Shopify/krane/pull/940)
6
+
7
+ ## 3.3.0
8
+
9
+ *Enhancements*
10
+
11
+ - Enable detection of successful StatefulSet deploys when the `updateStrategy` is `onDelete`, behind an annotation. [#926](https://github.com/Shopify/krane/pull/926)
12
+
3
13
  ## 3.2.0
4
14
 
5
15
  *Enhancements*
@@ -282,7 +292,7 @@ It seems an issue when too many pods are referencing the same secret/configmap h
282
292
  # 1.0.0
283
293
 
284
294
  We've renamed the gem and cli to Krane.
285
- See our [migration guide](https://github.com/Shopify/krane/blob/master/1.0-Upgrade.md) to help navigate the breaking changes.
295
+ See our [migration guide](https://github.com/Shopify/krane/blob/main/1.0-Upgrade.md) to help navigate the breaking changes.
286
296
 
287
297
  ## 1.0.0.pre.2
288
298
 
data/CONTRIBUTING.md CHANGED
@@ -22,7 +22,7 @@ The following is a set of guidelines for contributing to krane. Please take a mo
22
22
  * [CI (External contributors)](#ci-external-contributors)
23
23
  ## Code of Conduct
24
24
 
25
- This project and everyone participating in it are governed by the [Code of Conduct](https://github.com/Shopify/krane/blob/master/CODE_OF_CONDUCT.md).
25
+ This project and everyone participating in it are governed by the [Code of Conduct](https://github.com/Shopify/krane/blob/main/CODE_OF_CONDUCT.md).
26
26
  By participating, you are expected to uphold this code. Please report unacceptable
27
27
  behavior to [krane@shopify.com](mailto:krane@shopify.com).
28
28
 
@@ -95,9 +95,9 @@ This gem uses subclasses of `KubernetesResource` to implement custom success/fai
95
95
  * `deploy_failed?`
96
96
  3. Adjust the `TIMEOUT` constant to an appropriate value for this type.
97
97
  4. Add the new class to list of resources in
98
- [`deploy_task.rb`](https://github.com/Shopify/krane/blob/master/lib/krane/deploy_task.rb#L8)
99
- 5. Add the new resource to the [prune whitelist](https://github.com/Shopify/krane/blob/master/lib/krane/deploy_task.rb#L81)
100
- 6. Add a basic example of the type to the hello-cloud [fixture set](https://github.com/Shopify/krane/tree/master/test/fixtures/hello-cloud) and appropriate assertions to `#assert_all_up` in [`hello_cloud.rb`](https://github.com/Shopify/krane/blob/master/test/helpers/fixture_sets/hello_cloud.rb). This will get you coverage in several existing tests, such as `test_full_hello_cloud_set_deploy_succeeds`.
98
+ [`deploy_task.rb`](https://github.com/Shopify/krane/blob/main/lib/krane/deploy_task.rb#L8)
99
+ 5. Add the new resource to the [prune whitelist](https://github.com/Shopify/krane/blob/main/lib/krane/deploy_task.rb#L81)
100
+ 6. Add a basic example of the type to the hello-cloud [fixture set](https://github.com/Shopify/krane/tree/main/test/fixtures/hello-cloud) and appropriate assertions to `#assert_all_up` in [`hello_cloud.rb`](https://github.com/Shopify/krane/blob/main/test/helpers/fixture_sets/hello_cloud.rb). This will get you coverage in several existing tests, such as `test_full_hello_cloud_set_deploy_succeeds`.
101
101
  7. Add tests for any edge cases you foresee.
102
102
 
103
103
  ### Contributor License Agreement
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # krane [![Build status](https://badge.buildkite.com/35c56e797c3bbd6ba50053aefdded0715898cd8e8c86f7e462.svg?branch=master)](https://buildkite.com/shopify/krane)
1
+ # krane [![Build status](https://badge.buildkite.com/35c56e797c3bbd6ba50053aefdded0715898cd8e8c86f7e462.svg?branch=main)](https://buildkite.com/shopify/krane)
2
2
 
3
- > This project used to be called `kubernetes-deploy`. Check out our [migration guide](https://github.com/Shopify/krane/blob/master/1.0-Upgrade.md) for more information including details about breaking changes.
3
+ > This project used to be called `kubernetes-deploy`. Check out our [migration guide](https://github.com/Shopify/krane/blob/main/1.0-Upgrade.md) for more information including details about breaking changes.
4
4
 
5
5
 
6
6
  `krane` is a command line tool that helps you ship changes to a Kubernetes namespace and understand the result. At Shopify, we use it within our much-beloved, open-source [Shipit](https://github.com/Shopify/shipit-engine#kubernetes) deployment app.
@@ -93,6 +93,7 @@ Krane provides support for official upstream supported versions [Kubernetes](htt
93
93
  | 1.24 | Yes | -- |
94
94
  | 1.25 | No | -- |
95
95
  | 1.26 | Yes | -- |
96
+ | 1.27 | Yes | -- |
96
97
 
97
98
  ## Installation
98
99
 
@@ -155,14 +156,13 @@ If you want dynamic templates, you may render ERB with `krane render` and then p
155
156
  - `krane.shopify.io/required-rollout`: Modifies how much of the rollout needs to finish
156
157
  before the deployment is considered successful.
157
158
  - _Compatibility_: Deployment
158
- - `full`: The deployment is successful when all pods in the new `replicaSet` are ready.
159
- - `none`: The deployment is successful as soon as the new `replicaSet` is created for the deployment.
160
- - `maxUnavailable`: The deploy is successful when minimum availability is reached in the new `replicaSet`.
161
- In other words, the number of new pods that must be ready is equal to `spec.replicas` - `strategy.RollingUpdate.maxUnavailable`
162
- (converted from percentages by rounding up, if applicable). This option is only valid for deployments
163
- that use the `RollingUpdate` strategy.
164
- - Percent (e.g. 90%): The deploy is successful when the number of new pods that are ready is equal to
165
- `spec.replicas` * Percent.
159
+ - `full`: The deployment is successful when all pods in the new `replicaSet` are ready.
160
+ - `none`: The deployment is successful as soon as the new `replicaSet` is created for the deployment.
161
+ - `maxUnavailable`: The deploy is successful when minimum availability is reached in the new `replicaSet`.
162
+ In other words, the number of new pods that must be ready is equal to `spec.replicas` - `strategy.RollingUpdate.maxUnavailable` (converted from percentages by rounding up, if applicable). This option is only valid for deployments that use the `RollingUpdate` strategy.
163
+ - Percent (e.g. 90%): The deploy is successful when the number of new pods that are ready is equal to `spec.replicas` * Percent.
164
+ - _Compatibility_: StatefulSet
165
+ - `full`: The deployment is successful when all pods are ready.
166
166
  - `krane.shopify.io/predeployed`: Causes a Custom Resource to be deployed in the pre-deploy phase.
167
167
  - _Compatibility_: Custom Resource Definition
168
168
  - _Default_: `true`
@@ -337,7 +337,7 @@ status:
337
337
 
338
338
  ### Deploy walkthrough
339
339
 
340
- Let's walk through what happens when you run the `deploy` task with [this directory of templates](https://github.com/Shopify/krane/tree/master/test/fixtures/hello-cloud). This particular example uses ERB templates as well, so we'll use the [krane render](#krane-render) task to achieve that.
340
+ Let's walk through what happens when you run the `deploy` task with [this directory of templates](https://github.com/Shopify/krane/tree/main/test/fixtures/hello-cloud). This particular example uses ERB templates as well, so we'll use the [krane render](#krane-render) task to achieve that.
341
341
 
342
342
  You can test this out for yourself by running the following command:
343
343
 
@@ -404,7 +404,7 @@ In this phase, we:
404
404
 
405
405
  Just like in the previous phase, we essentially run `kubectl apply` on those templates and periodically check the cluster for the current status of each resource so we can display error or success information.
406
406
 
407
- If pruning is enabled (which, again, is the default), any [kind not listed in the blacklist](https://github.com/Shopify/krane/blob/master/lib/krane/cluster_resource_discovery.rb#L20) that we can find in the namespace but not in the templates will be removed. A particular message about pruning will be printed in the next phase if any resource matches this criteria.
407
+ If pruning is enabled (which, again, is the default), any [kind not listed in the blacklist](https://github.com/Shopify/krane/blob/main/lib/krane/cluster_resource_discovery.rb#L20) that we can find in the namespace but not in the templates will be removed. A particular message about pruning will be printed in the next phase if any resource matches this criteria.
408
408
 
409
409
  #### Result
410
410
 
@@ -654,13 +654,13 @@ This is a limitation of the current implementation.
654
654
  # Contributing
655
655
 
656
656
  We :heart: contributors! To make it easier for you and us we've written a
657
- [Contributing Guide](https://github.com/Shopify/krane/blob/master/CONTRIBUTING.md)
657
+ [Contributing Guide](https://github.com/Shopify/krane/blob/main/CONTRIBUTING.md)
658
658
 
659
659
 
660
660
  You can also reach out to us on our slack channel, #krane, at https://kubernetes.slack.com. All are welcome!
661
661
 
662
662
  ## Code of Conduct
663
- Everyone is expected to follow our [Code of Conduct](https://github.com/Shopify/krane/blob/master/CODE_OF_CONDUCT.md).
663
+ Everyone is expected to follow our [Code of Conduct](https://github.com/Shopify/krane/blob/main/CODE_OF_CONDUCT.md).
664
664
 
665
665
 
666
666
  # License
data/krane.gemspec CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.add_dependency("ejson", "~> 1.0")
33
33
  spec.add_dependency("colorize", "~> 0.8")
34
34
  spec.add_dependency("statsd-instrument", ['>= 2.8', "< 4"])
35
- spec.add_dependency("oj", "~> 3.0")
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
@@ -54,14 +54,14 @@ module Krane
54
54
  end
55
55
 
56
56
  def parse_json(string)
57
- bindings = JSON.parse(string)
57
+ bindings = MultiJson.load(string)
58
58
 
59
59
  unless bindings.is_a?(Hash)
60
60
  raise ArgumentError, "Expected JSON data to be a hash."
61
61
  end
62
62
 
63
63
  bindings
64
- rescue JSON::ParserError
64
+ rescue MultiJson::ParseError
65
65
  nil
66
66
  end
67
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
@@ -54,7 +54,7 @@ module Krane
54
54
  @api_path_cache["/"] ||= begin
55
55
  raw_json, err, st = kubectl.run("get", "--raw", base_api_path, attempts: 5, use_namespace: false)
56
56
  paths = if st.success?
57
- JSON.parse(raw_json)["paths"]
57
+ MultiJson.load(raw_json)["paths"]
58
58
  else
59
59
  raise FatalKubeAPIError, "Error retrieving raw path /: #{err}"
60
60
  end
@@ -66,7 +66,7 @@ module Krane
66
66
  @api_path_cache[path] ||= begin
67
67
  raw_json, err, st = kubectl.run("get", "--raw", path, attempts: 2, use_namespace: false)
68
68
  if st.success?
69
- JSON.parse(raw_json)
69
+ MultiJson.load(raw_json)
70
70
  else
71
71
  logger.warn("Error retrieving api path: #{err}")
72
72
  {}
@@ -92,7 +92,7 @@ module Krane
92
92
  raw_json, err, st = kubectl.run("get", "CustomResourceDefinition", output: "json", attempts: 5,
93
93
  use_namespace: false)
94
94
  if st.success?
95
- JSON.parse(raw_json)["items"]
95
+ MultiJson.load(raw_json)["items"]
96
96
  else
97
97
  raise FatalKubeAPIError, "Error retrieving CustomResourceDefinition: #{err}"
98
98
  end
@@ -77,7 +77,7 @@ module Krane
77
77
  Hash[before_crs + crs + after_crs]
78
78
  end
79
79
 
80
- def prune_whitelist
80
+ def prune_allowlist
81
81
  cluster_resource_discoverer.prunable_resources(namespaced: true)
82
82
  end
83
83
 
@@ -192,7 +192,7 @@ module Krane
192
192
 
193
193
  def resource_deployer
194
194
  @resource_deployer ||= Krane::ResourceDeployer.new(task_config: @task_config,
195
- prune_whitelist: prune_whitelist, global_timeout: @global_timeout,
195
+ prune_allowlist: prune_allowlist, global_timeout: @global_timeout,
196
196
  selector: @selector, statsd_tags: statsd_tags, current_sha: @current_sha)
197
197
  end
198
198
 
@@ -328,7 +328,7 @@ module Krane
328
328
  @namespace_definition ||= begin
329
329
  definition, _err, st = kubectl.run("get", "namespace", @namespace, use_namespace: false,
330
330
  log_failure: true, raise_if_not_found: true, attempts: 3, output: 'json')
331
- st.success? ? JSON.parse(definition, symbolize_names: true) : nil
331
+ st.success? ? MultiJson.load(definition, symbolize_names: true) : nil
332
332
  end
333
333
  rescue Kubectl::ResourceNotFoundError
334
334
  nil
@@ -362,7 +362,7 @@ module Krane
362
362
  unless st.success?
363
363
  raise EjsonSecretError, "Error retrieving Secret/#{EjsonSecretProvisioner::EJSON_KEYS_SECRET}: #{err}"
364
364
  end
365
- JSON.parse(out)
365
+ MultiJson.load(out)
366
366
  end
367
367
  end
368
368
 
@@ -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
 
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
 
@@ -85,7 +86,7 @@ module Krane
85
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
88
 
88
- version_data = JSON.parse(response)
89
+ version_data = MultiJson.load(response)
89
90
  client_version = platform_agnostic_version(version_data.dig("clientVersion", "gitVersion").to_s)
90
91
  server_version = platform_agnostic_version(version_data.dig("serverVersion", "gitVersion").to_s)
91
92
  unless client_version && server_version
@@ -112,6 +113,14 @@ module Krane
112
113
  "--dry-run=server"
113
114
  end
114
115
 
116
+ def allowlist_flag
117
+ if client_version >= Gem::Version.new(ALLOW_LIST_MIN_VERSION)
118
+ "--prune-allowlist"
119
+ else
120
+ "--prune-whitelist"
121
+ end
122
+ end
123
+
115
124
  private
116
125
 
117
126
  def build_command_from_options(args, use_namespace, use_context, output)
@@ -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
  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,35 @@ 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
+ @pods.each do |pod|
26
+ success &= pod.definition["metadata"]["labels"]["controller-revision-hash"] == status_data['updateRevision']
27
+ end
28
+
29
+ if update_strategy == 'RollingUpdate'
30
+ success &= status_data['currentRevision'] == status_data['updateRevision']
31
+ success &= desired_replicas == status_data['readyReplicas'].to_i
32
+ success &= desired_replicas == status_data['currentReplicas'].to_i
33
+
34
+ elsif update_strategy == ONDELETE
27
35
  unless @success_assumption_warning_shown
28
36
  @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.")
37
+ "which means the deployment won't succeed until all pods are updated by deletion.")
31
38
  @success_assumption_warning_shown = true
32
39
  end
33
- else
34
- success &= desired_replicas == status_data['currentReplicas'].to_i
40
+
41
+ if required_rollout == 'full'
42
+ success &= desired_replicas == status_data['readyReplicas'].to_i
43
+ success &= desired_replicas == status_data['updatedReplicas'].to_i
44
+ end
35
45
  end
46
+
36
47
  success
37
48
  end
38
49
 
39
50
  def deploy_failed?
40
- return false if update_strategy == ONDELETE
51
+ return false if update_strategy == ONDELETE && required_rollout != 'full'
41
52
  pods.present? && pods.any?(&:deploy_failed?) &&
42
53
  observed_generation == current_generation
43
54
  end
@@ -67,5 +78,9 @@ module Krane
67
78
  pod_data["metadata"]["ownerReferences"].any? { |ref| ref["uid"] == @instance_data["metadata"]["uid"] } &&
68
79
  @instance_data["status"]["currentRevision"] == pod_data["metadata"]["labels"]["controller-revision-hash"]
69
80
  end
81
+
82
+ def required_rollout
83
+ krane_annotation_value("required-rollout") || nil
84
+ end
70
85
  end
71
86
  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,9 +11,9 @@ 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
@@ -102,7 +102,7 @@ module Krane
102
102
  # Apply can be done in one large batch, the rest have to be done individually
103
103
  applyables, individuals = resources.partition { |r| r.deploy_method == :apply }
104
104
  # Prunable resources should also applied so that they can be pruned
105
- pruneable_types = @prune_whitelist.map { |t| t.split("/").last }
105
+ pruneable_types = @prune_allowlist.map { |t| t.split("/").last }
106
106
  applyables += individuals.select { |r| pruneable_types.include?(r.type) && !r.deploy_method_override }
107
107
 
108
108
  individuals.each do |individual_resource|
@@ -147,14 +147,15 @@ module Krane
147
147
  r.deploy_started_at = Time.now.utc unless dry_run
148
148
  end
149
149
  command.push("-f", tmp_dir)
150
- if prune && @prune_whitelist.present?
150
+ if prune && @prune_allowlist.present?
151
151
  command.push("--prune")
152
152
  if @selector
153
153
  command.push("--selector", @selector.to_s)
154
154
  else
155
155
  command.push("--all")
156
156
  end
157
- @prune_whitelist.each { |type| command.push("--prune-whitelist=#{type}") }
157
+ allow_list_flag = kubectl.allowlist_flag
158
+ @prune_allowlist.each { |type| command.push("#{allow_list_flag}=#{type}") }
158
159
  end
159
160
 
160
161
  command.push(kubectl.dry_run_flag) if dry_run
@@ -252,7 +253,7 @@ module Krane
252
253
  # For resources that rely on a generateName attribute, we get the `name` from the result of the call to `create`
253
254
  # We must explicitly set this name value so that the `apply` step for pruning can run successfully
254
255
  if status.success? && resource.uses_generate_name?
255
- resource.use_generated_name(JSON.parse(out))
256
+ resource.use_generated_name(MultiJson.load(out))
256
257
  end
257
258
 
258
259
  [err, status]
@@ -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 = "3.2.0"
3
+ VERSION = "3.4.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: 3.2.0
4
+ version: 3.4.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: 2023-06-14 00:00:00.000000000 Z
13
+ date: 2023-12-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -103,19 +103,19 @@ dependencies:
103
103
  - !ruby/object:Gem::Version
104
104
  version: '4'
105
105
  - !ruby/object:Gem::Dependency
106
- name: oj
106
+ name: multi_json
107
107
  requirement: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - "~>"
109
+ - - ">="
110
110
  - !ruby/object:Gem::Version
111
- version: '3.0'
111
+ version: '0'
112
112
  type: :runtime
113
113
  prerelease: false
114
114
  version_requirements: !ruby/object:Gem::Requirement
115
115
  requirements:
116
- - - "~>"
116
+ - - ">="
117
117
  - !ruby/object:Gem::Version
118
- version: '3.0'
118
+ version: '0'
119
119
  - !ruby/object:Gem::Dependency
120
120
  name: concurrent-ruby
121
121
  requirement: !ruby/object:Gem::Requirement
@@ -212,14 +212,14 @@ dependencies:
212
212
  requirements:
213
213
  - - "~>"
214
214
  - !ruby/object:Gem::Version
215
- version: '5.12'
215
+ version: '5.19'
216
216
  type: :development
217
217
  prerelease: false
218
218
  version_requirements: !ruby/object:Gem::Requirement
219
219
  requirements:
220
220
  - - "~>"
221
221
  - !ruby/object:Gem::Version
222
- version: '5.12'
222
+ version: '5.19'
223
223
  - !ruby/object:Gem::Dependency
224
224
  name: minitest-stub-const
225
225
  requirement: !ruby/object:Gem::Requirement
@@ -254,28 +254,28 @@ dependencies:
254
254
  requirements:
255
255
  - - "~>"
256
256
  - !ruby/object:Gem::Version
257
- version: '1.5'
257
+ version: '2.1'
258
258
  type: :development
259
259
  prerelease: false
260
260
  version_requirements: !ruby/object:Gem::Requirement
261
261
  requirements:
262
262
  - - "~>"
263
263
  - !ruby/object:Gem::Version
264
- version: '1.5'
264
+ version: '2.1'
265
265
  - !ruby/object:Gem::Dependency
266
266
  name: webmock
267
267
  requirement: !ruby/object:Gem::Requirement
268
268
  requirements:
269
269
  - - "~>"
270
270
  - !ruby/object:Gem::Version
271
- version: '3.0'
271
+ version: '3.18'
272
272
  type: :development
273
273
  prerelease: false
274
274
  version_requirements: !ruby/object:Gem::Requirement
275
275
  requirements:
276
276
  - - "~>"
277
277
  - !ruby/object:Gem::Version
278
- version: '3.0'
278
+ version: '3.18'
279
279
  - !ruby/object:Gem::Dependency
280
280
  name: timecop
281
281
  requirement: !ruby/object:Gem::Requirement
@@ -414,6 +414,7 @@ files:
414
414
  - ".github/CODEOWNERS"
415
415
  - ".github/ISSUE_TEMPLATE.md"
416
416
  - ".github/pull_request_template.md"
417
+ - ".github/workflows/add-to-project.yml"
417
418
  - ".github/workflows/ci.yml"
418
419
  - ".github/workflows/cla.yml"
419
420
  - ".gitignore"
@@ -487,7 +488,6 @@ files:
487
488
  - lib/krane/kubernetes_resource/service_account.rb
488
489
  - lib/krane/kubernetes_resource/stateful_set.rb
489
490
  - lib/krane/label_selector.rb
490
- - lib/krane/oj.rb
491
491
  - lib/krane/options_helper.rb
492
492
  - lib/krane/psych_k8s_compatibility.rb
493
493
  - lib/krane/remote_logs.rb
@@ -525,7 +525,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
525
525
  - !ruby/object:Gem::Version
526
526
  version: '0'
527
527
  requirements: []
528
- rubygems_version: 3.4.13
528
+ rubygems_version: 3.4.22
529
529
  signing_key:
530
530
  specification_version: 4
531
531
  summary: A command line tool that helps you ship changes to a Kubernetes namespace
data/lib/krane/oj.rb DELETED
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'oj'
3
-
4
- Oj.mimic_JSON