Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove unsupported Kubernetes and Ruby versions from Krane and CI #905

Merged
merged 10 commits into from
Oct 11, 2022
26 changes: 8 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,20 @@ jobs:
matrix:
ruby:
# Use unique Ruby versions, or GitHub gets confused when building the rest of the matrix
- '3.1.2' # With k8s 1.23
- '3.1.2' # With k8s 1.24
- '3.1.1' # With k8s 1.23
- '3.0.3' # With k8s 1.23
- '3.0.2' # With k8s 1.22
- '3.0.1' # With k8s 1.21
- '3.0' # With k8s 1.20
- '2.7' # With k8s 1.19
include:
# Match kind images with chosen version https://github.com/kubernetes-sigs/kind/releases
- ruby: '3.1.2'
kind_version: 'v0.11.1'
kind_version: 'v0.14.0'
kubernetes_version: '1.24.0'
kind_image: 'kindest/node:v1.24.0@sha256:0866296e693efe1fed79d5e6c7af8df71fc73ae45e3679af05342239cdc5bc8e'
- ruby: '3.1.1'
kind_version: 'v0.11.0'
kubernetes_version: '1.23.0'
kind_image: 'kindest/node:v1.23.0@sha256:49824ab1727c04e56a21a5d8372a402fcd32ea51ac96a2706a12af38934f81ac'
kind_image: 'kindest/node:v1.24.0@sha256:0866296e693efe1fed79d5e6c7af8df71fc73ae45e3679af05342239cdc5bc8e'
- ruby: '3.0.3'
kind_version: 'v0.11.1'
kubernetes_version: '1.23.0'
Expand All @@ -32,18 +34,6 @@ jobs:
kind_version: 'v0.11.1'
kubernetes_version: '1.22.0'
kind_image: 'kindest/node:v1.22.0@sha256:b8bda84bb3a190e6e028b1760d277454a72267a5454b57db34437c34a588d047'
- ruby: '3.0.1'
kind_version: 'v0.11.1'
kubernetes_version: '1.21.1'
kind_image: 'kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6'
- ruby: '3.0'
kind_version: 'v0.11.1'
kubernetes_version: '1.20.7'
kind_image: 'kindest/node:v1.20.7@sha256:cbeaf907fc78ac97ce7b625e4bf0de16e3ea725daf6b04f930bd14c67c671ff9'
- ruby: '2.7'
kind_version: 'v0.11.1'
kubernetes_version: '1.19.11'
kind_image: 'kindest/node:v1.19.11@sha256:07db187ae84b4b7de440a73886f008cf903fcf5764ba8106a9fd5243d6f32729'

steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ This gem uses subclasses of `KubernetesResource` to implement custom success/fai

If you work for Shopify, just run `dev up`, but otherwise:

1. [Install kubectl version 1.10.0 or higher](https://kubernetes.io/docs/user-guide/prereqs/) and make sure it is in your path
1. [Install kubectl version 1.22.0 or higher](https://kubernetes.io/docs/user-guide/prereqs/) and make sure it is in your path
2. [Install minikube](https://kubernetes.io/docs/getting-started-guides/minikube/#installation) (required to run the test suite)
3. [Install any required minikube drivers](https://github.com/kubernetes/minikube/blob/master/docs/drivers.md) (on OS X, you may need the [hyperkit driver](https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#hyperkit-driver)
4. Check out the repo
Expand Down
21 changes: 13 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,23 +74,28 @@ If you need the ability to render dynamic values in templates before deploying,
## Prerequisites

* Ruby 2.7+
* Your cluster must be running Kubernetes v1.19.0 or higher<sup>1</sup>
* Your cluster must be running Kubernetes v1.22.0 or higher<sup>1</sup>

<sup>1</sup> We run integration tests against these Kubernetes versions. You can find our
official compatibility chart below.
## Compatibility

<sup>1</sup> We run integration tests against these Kubernetes versions. You can find our official compatibility chart below.

Krane provides support for official upstream supported versions [Kubernetes](https://endoflife.date/kubernetes), [Ruby](https://endoflife.date/ruby) that are part of the compatibility matrix; Nevertheless, older releases are still likely to work.

| Kubernetes version | Currently Tested? | Last officially supported in gem version |
|:------------------:|-------------------|:----------------------------------------:|
| 1.18 | No | 2.3.7 |
| 1.19 | Yes | -- |
| 1.20 | Yes | -- |
| 1.21 | Yes | -- |
| 1.19 | No | 2.4.9 |
| 1.20 | No | 2.4.9 |
| 1.21 | No | 2.4.9 |
| 1.22 | Yes | -- |
| 1.23 | Yes | -- |
| 1.24 | Yes | -- |
| 1.25 | No | -- |

## Installation

1. [Install kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl-binary-via-curl) (requires v1.19.0 or higher) and make sure it is available in your $PATH
1. [Install kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl-binary-via-curl) (requires v1.22.0 or higher) and make sure it is available in your $PATH
2. Set up your [kubeconfig file](https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/) for access to your cluster(s).
3. `gem install krane`

Expand Down Expand Up @@ -497,7 +502,7 @@ resource to restart.

## Prerequisites

* You've already deployed a [`PodTemplate`](https://v1-15.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/#podtemplate-v1-core) object with field `template` containing a `Pod` specification that does not include the `apiVersion` or `kind` parameters. An example is provided in this repo in `test/fixtures/hello-cloud/template-runner.yml`.
* You've already deployed a [`PodTemplate`](https://v1-22.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#podtemplate-v1-core) object with field `template` containing a `Pod` specification that does not include the `apiVersion` or `kind` parameters. An example is provided in this repo in `test/fixtures/hello-cloud/template-runner.yml`.
* The `Pod` specification in that template has a container named `task-runner`.

Based on this specification `krane run` will create a new pod with the entrypoint of the `task-runner ` container overridden with the supplied arguments.
Expand Down
2 changes: 1 addition & 1 deletion bin/ci
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ docker run --rm \
-e VERBOSE=1 \
-e PARALLELISM=$PARALLELISM \
-w /usr/src/app \
ruby:"${RUBY_VERSION:-2.6.6}" \
ruby:"${RUBY_VERSION:-2.7.6}" \
bin/test
4 changes: 2 additions & 2 deletions bin/setup
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ if [ ! -x "$(which minikube)" ]; then
fi

if [ ! -x "$(which kubectl)" ]; then
echo -e "\n\033[0;33mPlease install kubectl version 1.15.0 or higher:\nhttps://kubernetes.io/docs/user-guide/prereqs/\033[0m"
echo -e "\n\033[0;33mPlease install kubectl version 1.22.0 or higher:\nhttps://kubernetes.io/docs/user-guide/prereqs/\033[0m"
else
KUBECTL_VERSION=$(kubectl version --short --client | grep -oe "v[[:digit:]\.]\+")
echo -e "\n\033[0;32mKubectl version $KUBECTL_VERSION is already installed. This gem requires version v1.15.0 or greater.\033[0m"
echo -e "\n\033[0;32mKubectl version $KUBECTL_VERSION is already installed. This gem requires version v1.22.0 or greater.\033[0m"
fi
4 changes: 2 additions & 2 deletions dev.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
name: krane
up:
- ruby: '3.0.3' # Matches gemspec
- ruby: '3.1.2' # Matches gemspec
- bundler
- podman
- kind:
name: krane
image: kindest/node:v1.22.0@sha256:b8bda84bb3a190e6e028b1760d277454a72267a5454b57db34437c34a588d047
image: kindest/node:v1.24.0@sha256:0866296e693efe1fed79d5e6c7af8df71fc73ae45e3679af05342239cdc5bc8e
commands:
test:
run: bin/test
Expand Down
2 changes: 1 addition & 1 deletion krane.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Gem::Specification.new do |spec|

spec.metadata['allowed_push_host'] = "https://rubygems.org"

spec.required_ruby_version = '>= 2.6.0'
spec.required_ruby_version = '>= 2.7.6'
spec.add_dependency("activesupport", ">= 5.0")
spec.add_dependency("kubeclient", "~> 4.9")
spec.add_dependency("googleauth", "~> 1.2")
Expand Down
2 changes: 1 addition & 1 deletion lib/krane/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
require 'krane/task_config_validator'

module Krane
MIN_KUBE_VERSION = '1.15.0'
MIN_KUBE_VERSION = '1.22.0'
end
71 changes: 0 additions & 71 deletions test/integration-serial/serial_deploy_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -546,77 +546,6 @@ def test_batch_dry_run_apply_success_precludes_individual_resource_dry_run_valid
], in_order: true)
end

# Note: After we drop support for K8s 1.21 this test can be removed, since webhooks must be dry-run safe.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there matching code that was making this work with <=1.21 that should also be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, all this PR needs to be reverted #798 as there are no more sideeffects during dry-run for mutatingwebhook

https://kubernetes.io/docs/reference/using-api/deprecation-guide/#webhook-resources-v122

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reverted in 9f1fe2a

def test_resources_with_side_effect_inducing_webhooks_are_not_batched_server_side_dry_run
result = deploy_global_fixtures("mutating_webhook_configurations", subset: %(ingress_hook.yaml))
assert_deploy_success(result)

# Note: We have to mock `has_side_effects?`, since this won't be possible with K8s 1.22+.
Krane::MutatingWebhookConfiguration::Webhook.any_instance.stubs(:has_side_effects?).returns(true)

Krane::ResourceDeployer.any_instance.expects(:dry_run).with do |params|
# We expect the ingress to not be included in the batch run
params.length == 3 && (params.map(&:type).sort == ["ConfigMap", "Deployment", "Service"])
end.returns(true)

[Krane::ConfigMap, Krane::Deployment, Krane::Service].each do |r|
r.any_instance.expects(:validate_definition).with { |params| params[:dry_run] == false }
end
Krane::Ingress.any_instance.expects(:validate_definition).with { |params| params[:dry_run] }
result = deploy_fixtures('hello-cloud', subset: %w(web.yml.erb configmap-data.yml), render_erb: true)
assert_deploy_success(result)
assert_logs_match_all([
"Result: SUCCESS",
"Successfully deployed 4 resources",
], in_order: true)
end

# Note: After we drop support for K8s 1.21 this test can be removed, since webhooks must be dry-run safe.
def test_resources_with_side_effect_inducing_webhooks_with_transitive_dependency_does_not_fail_batch_running
result = deploy_global_fixtures("mutating_webhook_configurations", subset: %(secret_hook.yaml))
assert_deploy_success(result)

# Note: We have to mock `has_side_effects?`, since this won't be possible with K8s 1.22+.
Krane::MutatingWebhookConfiguration::Webhook.any_instance.stubs(:has_side_effects?).returns(true)

actual_dry_runs = 0
Krane::KubernetesResource.any_instance.expects(:validate_definition).with do |params|
actual_dry_runs += 1 if params[:dry_run]
true
end.times(5)
result = deploy_fixtures('hello-cloud', subset: %w(web.yml.erb secret.yml configmap-data.yml),
render_erb: true) do |fixtures|
container = fixtures['web.yml.erb']['Deployment'][0]['spec']['template']['spec']
container['volumes'] = [{
'name' => 'secret',
'secret' => {
'secretName' => fixtures['secret.yml']["Secret"][0]['metadata']['name'],
},
}]
end
assert_deploy_success(result)
assert_equal(actual_dry_runs, 1)
assert_logs_match_all([
"Result: SUCCESS",
"Successfully deployed 5 resources",
], in_order: true)
end

# Note: After we drop support for K8s 1.21 this test can be removed, since webhooks must be dry-run safe.
def test_multiple_resources_with_side_effect_inducing_webhooks_are_properly_partitioned
result = deploy_global_fixtures("mutating_webhook_configurations", subset: %(secret_hook.yaml ingress_hook.yaml))
assert_deploy_success(result)

# Note: We have to mock `has_side_effects?`, since this won't be possible with K8s 1.22+.
Krane::MutatingWebhookConfiguration::Webhook.any_instance.stubs(:has_side_effects?).returns(true)

Krane::KubernetesResource.any_instance.expects(:validate_definition).with { |p| p[:dry_run] }.times(2)
result = deploy_fixtures('hello-cloud', subset: %w(web.yml.erb secret.yml), render_erb: true) do |fixtures|
fixtures["web.yml.erb"] = fixtures["web.yml.erb"].keep_if { |key| key == "Ingress" }
end
assert_deploy_success(result)
end

private

def rollout_conditions_annotation_key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,66 +28,4 @@ def test_load_from_json
assert_equal(rule.resources, ['secrets'])
end

# Note: After we drop support for K8s 1.21 this test can be removed, since webhooks must be dry-run safe.
def test_webhook_configuration_matches_when_side_effects
secret_def = YAML.load_file(File.join(fixture_path('hello-cloud'), 'secret.yml'))
secret = Krane::Secret.new(namespace: 'test', context: 'nope', definition: secret_def,
logger: @logger, statsd_tags: nil)

definition = YAML.load_file(File.join(fixture_path("mutating_webhook_configurations"), "secret_hook.yaml"))
webhook_configuration = Krane::MutatingWebhookConfiguration.new(
namespace: 'test', context: 'nope', definition: definition,
logger: @logger, statsd_tags: nil
)
webhook = webhook_configuration.webhooks.first
# Note: We have to mock `has_side_effects?`, since this won't be possible with K8s 1.22+.
webhook.stubs(:has_side_effects?).returns(true).at_least_once
assert(webhook.has_side_effects?)
assert(webhook.matches_resource?(secret))
assert(webhook.matches_resource?(secret, skip_rule_if_side_effect_none: true))
assert(webhook.matches_resource?(secret, skip_rule_if_side_effect_none: false))
end

# Note: After we drop support for K8s 1.21 this test can be removed, since webhooks must be dry-run safe.
def test_matches_webhook_configuration_doesnt_match_when_no_side_effects_and_flag
secret_def = YAML.load_file(File.join(fixture_path('hello-cloud'), 'secret.yml'))
secret = Krane::Secret.new(namespace: 'test', context: 'nope', definition: secret_def,
logger: @logger, statsd_tags: nil)

definition = YAML.load_file(File.join(fixture_path("mutating_webhook_configurations"), "secret_hook.yaml"))
webhook_configuration = Krane::MutatingWebhookConfiguration.new(
namespace: 'test', context: 'nope', definition: definition,
logger: @logger, statsd_tags: nil
)
webhook = webhook_configuration.webhooks.first
webhook.stubs(:has_side_effects?).returns(false).at_least_once
refute(webhook.matches_resource?(secret))
refute(webhook.matches_resource?(secret, skip_rule_if_side_effect_none: true))
assert(webhook.matches_resource?(secret, skip_rule_if_side_effect_none: false))
end

# Note: After we drop support for K8s 1.21 this test can be removed, since webhooks must be dry-run safe.
def test_no_match_when_policy_is_exact_and_resource_doesnt_match
secret_def = YAML.load_file(File.join(fixture_path('hello-cloud'), 'secret.yml'))
secret = Krane::Secret.new(namespace: 'test', context: 'nope', definition: secret_def,
logger: @logger, statsd_tags: nil)

definition = YAML.load_file(File.join(fixture_path("mutating_webhook_configurations"), "secret_hook.yaml"))
webhook_configuration = Krane::MutatingWebhookConfiguration.new(
namespace: 'test', context: 'nope', definition: definition,
logger: @logger, statsd_tags: nil
)

webhook = webhook_configuration.webhooks.first
# Note: We have to mock `has_side_effects?`, since this won't be possible with K8s 1.22+.
webhook.stubs(:has_side_effects?).returns(true).at_least_once
assert(webhook.matches_resource?(secret))
webhook.expects(:match_policy).returns(Krane::MutatingWebhookConfiguration::Webhook::EXACT).at_least(1)
assert(webhook.matches_resource?(secret))
secret.expects(:group).returns('fake').once
refute(webhook.matches_resource?(secret))
secret.unstub(:group)
secret.expects(:type).returns('fake').once
refute(webhook.matches_resource?(secret))
end
end