From 1a3371d280bcc4fe4c59095a2e7c205f2eb21d19 Mon Sep 17 00:00:00 2001 From: Peiran Liu Date: Tue, 8 Jun 2021 20:35:09 -0400 Subject: [PATCH] update --- README.md | 6 ++++-- lib/krane/cli/deploy_command.rb | 7 ++++++- lib/krane/cli/global_deploy_command.rb | 7 ++++++- test/exe/deploy_test.rb | 22 ++++++++++++++++++++++ test/exe/global_deploy_test.rb | 22 ++++++++++++++++++++++ test/integration/krane_deploy_test.rb | 2 +- 6 files changed, 61 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c38d278d2..760394479 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ Refer to `krane help` for the authoritative set of options. - `--global-timeout=duration`: Raise a timeout error if it takes longer than _duration_ for any resource to deploy. - `--selector`: Instructs krane to only prune resources which match the specified label selector, such as `environment=staging`. If you use this option, all resource templates must specify matching labels. See [Sharing a namespace](#sharing-a-namespace) below. -- `--selector-as-filter`: Instructs krane to only deploy resources that are filtered by the specified labels in `--selector`. The deploy will not fail if not all resources match the labels. +- `--selector-as-filter`: Instructs krane to only deploy resources that are filtered by the specified labels in `--selector`. The deploy will not fail if not all resources match the labels. This is useful if you only want to deploy a subset of resources within a given YAML file. See [Sharing a namespace](#sharing-a-namespace) below. - `--no-verify-result`: Skip verification that workloads correctly deployed. - `--protected-namespaces=default kube-system kube-public`: Fail validation if a deploy is targeted at a protected namespace. - `--verbose-log-prefix`: Add [context][namespace] to the log prefix @@ -133,6 +133,8 @@ If you need to, you may specify `--no-prune` to disable all pruning behaviour, b If you need to share a namespace with resources which are managed by other tools or indeed other krane deployments, you can supply the `--selector` option, such that only resources with labels matching the selector are considered for pruning. +If you need to share a namespace with different set of resources using the same YAML file, you can supply the `--selector` and `--selector-as-filter` options, such that only the resources that match with the labels will be deployed. In each run of deploy, you can use different labels in `--selector` to deploy a different set of resources. Only the deployed resources in each run are considered for pruning. + ### Using templates All templates must be YAML formatted. @@ -442,7 +444,7 @@ Refer to `krane global-deploy help` for the authoritative set of options. - `--filenames / -f [PATHS]`: Accepts a list of directories and/or filenames to specify the set of directories/files that will be deployed. Use `-` to specify STDIN. - `--no-prune`: Skips pruning of resources that are no longer in your Kubernetes template set. Not recommended, as it allows your namespace to accumulate cruft that is not reflected in your deploy directory. - `--selector`: Instructs krane to only prune resources which match the specified label selector, such as `environment=staging`. By using this option, all resource templates must specify matching labels. See [Sharing a namespace](#sharing-a-namespace) below. -- `--selector-as-filter`: Instructs krane to only deploy resources that are filtered by the specified labels in `--selector`. The deploy will not fail if not all resources match the labels. +- `--selector-as-filter`: Instructs krane to only deploy resources that are filtered by the specified labels in `--selector`. The deploy will not fail if not all resources match the labels. This is useful if you only want to deploy a subset of resources within a given YAML file. See [Sharing a namespace](#sharing-a-namespace) below. - `--global-timeout=duration`: Raise a timeout error if it takes longer than _duration_ for any resource to deploy. - `--no-verify-result`: Skip verification that resources correctly deployed. diff --git a/lib/krane/cli/deploy_command.rb b/lib/krane/cli/deploy_command.rb index 824f35b1a..23920f3f7 100644 --- a/lib/krane/cli/deploy_command.rb +++ b/lib/krane/cli/deploy_command.rb @@ -26,7 +26,8 @@ class DeployCommand "selector" => { type: :string, banner: "'label=value'", desc: "Select workloads by selector(s)" }, "selector-as-filter" => { type: :boolean, - desc: "Use --selector as a label filter to select a subset of resources to deploy", + desc: "Use --selector as a label filter to deploy only a subset "\ + "of the provided resources", default: false }, "verbose-log-prefix" => { type: :boolean, desc: "Add [context][namespace] to the log prefix", default: false }, @@ -42,6 +43,10 @@ def self.from_options(namespace, context, options) selector = ::Krane::LabelSelector.parse(options[:selector]) if options[:selector] selector_as_filter = options['selector-as-filter'] + if selector_as_filter && selector.to_s.empty? + raise(Thor::RequiredArgumentMissingError, '--selector must be set when --selector-as-filter is set') + end + logger = ::Krane::FormattedLogger.build(namespace, context, verbose_prefix: options['verbose-log-prefix']) diff --git a/lib/krane/cli/global_deploy_command.rb b/lib/krane/cli/global_deploy_command.rb index 9634a41b9..0574b4199 100644 --- a/lib/krane/cli/global_deploy_command.rb +++ b/lib/krane/cli/global_deploy_command.rb @@ -17,7 +17,8 @@ class GlobalDeployCommand "selector" => { type: :string, banner: "'label=value'", required: true, desc: "Select workloads owned by selector(s)" }, "selector-as-filter" => { type: :boolean, - desc: "Use --selector as a label filter to select a subset of resources to deploy", + desc: "Use --selector as a label filter to deploy only a subset "\ + "of the provided resources", default: false }, "prune" => { type: :boolean, desc: "Enable deletion of resources that match"\ " the provided selector and do not appear in the provided templates", @@ -33,6 +34,10 @@ def self.from_options(context, options) selector = ::Krane::LabelSelector.parse(options[:selector]) selector_as_filter = options['selector-as-filter'] + if selector_as_filter && selector.to_s.empty? + raise(Thor::RequiredArgumentMissingError, '--selector must be set when --selector-as-filter is set') + end + filenames = options[:filenames].dup filenames << "-" if options[:stdin] if filenames.empty? diff --git a/test/exe/deploy_test.rb b/test/exe/deploy_test.rb index fd6230517..fb88370a1 100644 --- a/test/exe/deploy_test.rb +++ b/test/exe/deploy_test.rb @@ -95,6 +95,28 @@ def test_deploy_fails_without_filename end end + def test_deploy_fails_with_selector_as_filter_but_without_selector + selector = Krane::LabelSelector.new('key' => 'value') + Krane::LabelSelector.expects(:parse).returns(selector) + set_krane_deploy_expectations(new_args: { + filenames: ['/my/file/path'], + selector: selector, + selector_as_filter: true, + }) + flags = '-f /my/file/path --selector key:value --selector_as_filter' + krane_deploy!(flags: flags) + + flags = '-f /my/file/path --selector-as-filter' + krane = Krane::CLI::Krane.new( + [deploy_task_config.namespace, deploy_task_config.context], + flags.split + ) + assert_raises_message(Thor::RequiredArgumentMissingError, + "--selector must be set when --selector-as-filter is set") do + krane.invoke("deploy") + end + end + def test_stdin_flag_deduped_if_specified_multiple_times Dir.mktmpdir do |tmp_path| $stdin.expects("read").returns("").times(2) diff --git a/test/exe/global_deploy_test.rb b/test/exe/global_deploy_test.rb index 7767717b2..4145c5257 100644 --- a/test/exe/global_deploy_test.rb +++ b/test/exe/global_deploy_test.rb @@ -80,6 +80,28 @@ def test_deploy_fails_without_filename end end + def test_deploy_fails_selector_required + selector = Krane::LabelSelector.new('key' => 'value') + Krane::LabelSelector.expects(:parse).returns(selector) + set_krane_global_deploy_expectations!(new_args: { + filenames: ['/my/file/path'], + selector: "key=value", + selector_as_filter: true, + }) + flags = '-f /my/file/path --selector key:value --selector_as_filter' + krane_global_deploy!(flags: flags) + + flags = '-f /my/file/path --selector-as-filter' + krane = Krane::CLI::Krane.new( + [task_config.context], + flags.split + ) + assert_raises_message(Thor::RequiredArgumentMissingError, + "No value provided for required options '--selector'") do + krane.invoke("global_deploy") + end + end + def test_deploy_parses_selector selector = 'name=web' set_krane_global_deploy_expectations!(new_args: { selector: selector }) diff --git a/test/integration/krane_deploy_test.rb b/test/integration/krane_deploy_test.rb index 197d6e1a1..95ef0f281 100644 --- a/test/integration/krane_deploy_test.rb +++ b/test/integration/krane_deploy_test.rb @@ -167,7 +167,7 @@ def test_selector end def test_select_any - # Deploy only the resource matching the selector without valiation error + # Deploy only the resource matching the selector without validation error assert_deploy_success(deploy_fixtures("slow-cloud", subset: ['web-deploy-1.yml', 'web-deploy-3.yml'], selector: Krane::LabelSelector.parse("branch=master"), selector_as_filter: true))