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

Use TaskConfigValidator for RunnerTask #554

Merged
merged 4 commits into from
Sep 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*Enhancements*
- Officially support Kubernetes 1.15 ([#546](https://github.com/Shopify/kubernetes-deploy/pull/546))
- Make sure that we only declare a Service of type LoadBalancer as deployed after its IP address is published. [#547](https://github.com/Shopify/kubernetes-deploy/pull/547)
- Add more validations to `RunnerTask`. [#554](https://github.com/Shopify/kubernetes-deploy/pull/554)


*Bug Fixes*
Expand Down
46 changes: 12 additions & 34 deletions lib/kubernetes-deploy/runner_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
require 'kubernetes-deploy/resource_watcher'
require 'kubernetes-deploy/kubernetes_resource'
require 'kubernetes-deploy/kubernetes_resource/pod'
require 'kubernetes-deploy/runner_task_config_validator'

module KubernetesDeploy
class RunnerTask
Expand Down Expand Up @@ -35,7 +36,11 @@ def run!(task_template:, entrypoint:, args:, env_vars: [], verify_result: true)
@logger.reset

@logger.phase_heading("Initializing task")
validate_configuration(task_template, args)

@logger.info("Validating configuration")
verify_config!(task_template, args)
@logger.info("Using namespace '#{@namespace}' in context '#{@context}'")

pod = build_pod(task_template, entrypoint, args, env_vars, verify_result)
validate_pod(pod)

Expand Down Expand Up @@ -107,41 +112,14 @@ def record_status_once(pod)
@logger.summary.add_paragraph(warning)
end

def validate_configuration(task_template, args)
@logger.info("Validating configuration")
errors = []

if task_template.blank?
errors << "Task template name can't be nil"
end

if @namespace.blank?
errors << "Namespace can't be empty"
end

if args.blank?
errors << "Args can't be nil"
end

begin
kubeclient.get_namespace(@namespace) if @namespace.present?
@logger.info("Using namespace '#{@namespace}' in context '#{@context}'")

rescue Kubeclient::ResourceNotFoundError
errors << "Namespace was not found"
rescue Kubeclient::HttpError
errors << "Could not connect to kubernetes cluster"
rescue KubernetesDeploy::KubeclientBuilder::ContextMissingError
errors << "Could not connect to kubernetes cluster - context invalid"
end

unless errors.empty?
def verify_config!(task_template, args)
task_config_validator = RunnerTaskConfigValidator.new(task_template, args, @task_config, kubectl,
kubeclient_builder)
unless task_config_validator.valid?
@logger.summary.add_action("Configuration invalid")
@logger.summary.add_paragraph(errors.map { |err| "- #{err}" }.join("\n"))
raise TaskConfigurationError, "Configuration invalid: #{errors.join(', ')}"
@logger.summary.add_paragraph([task_config_validator.errors].map { |err| "- #{err}" }.join("\n"))
raise KubernetesDeploy::TaskConfigurationError
end

TaskConfigValidator.new(@task_config, kubectl, kubeclient_builder, only: [:validate_server_version]).valid?
end

def get_template(template_name)
Expand Down
25 changes: 25 additions & 0 deletions lib/kubernetes-deploy/runner_task_config_validator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true
module KubernetesDeploy
class RunnerTaskConfigValidator < TaskConfigValidator
def initialize(template, args, *arguments)
super(*arguments)
@template = template
@args = args
@validations += %i(validate_template validate_args)
dirceu marked this conversation as resolved.
Show resolved Hide resolved
end

private

def validate_args
if @args.blank?
@errors << "Args can't be nil"
end
end

def validate_template
if @template.blank?
@errors << "Task template name can't be nil"
end
end
end
end
1 change: 0 additions & 1 deletion test/integration-serial/serial_task_run_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ def test_run_without_verify_result_fails_if_pod_was_not_created
# Sketchy, but stubbing the kubeclient doesn't work (and wouldn't be concurrency-friendly)
# Finding a way to reliably trigger a create failure would be much better, if possible
mock = mock()
mock.expects(:get_namespace)
template = kubeclient.get_pod_template('hello-cloud-template-runner', @namespace)
mock.expects(:get_pod_template).returns(template)
mock.expects(:create_pod).raises(Kubeclient::HttpError.new("409", "Pod with same name exists", {}))
Expand Down
50 changes: 47 additions & 3 deletions test/integration/runner_task_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,15 @@ def test_run_bang_raises_exceptions_as_well_as_printing_failure
end

def test_run_fails_if_context_is_invalid
task_runner = build_task_runner(context: "missing")
task_runner = build_task_runner(context: "unknown")
assert_task_run_failure(task_runner.run(run_params))

assert_logs_match_all([
"Initializing task",
"Validating configuration",
"Result: FAILURE",
"Configuration invalid",
"- Could not connect to kubernetes cluster - context invalid",
"Context unknown missing from your kubeconfig file(s)",
], in_order: true)
end

Expand All @@ -200,10 +200,54 @@ def test_run_fails_if_namespace_is_missing
"Validating configuration",
"Result: FAILURE",
"Configuration invalid",
"- Namespace was not found",
"Could not find Namespace:",
], in_order: true)
end

def test_run_fails_if_args_are_missing
task_runner = build_task_runner
result = task_runner.run(task_template: 'hello-cloud-template-runner',
entrypoint: ['/bin/sh', '-c'],
args: nil,
env_vars: ["MY_CUSTOM_VARIABLE=MITTENS"])
assert_task_run_failure(result)

assert_logs_match_all([
"Initializing task",
"Validating configuration",
"Result: FAILURE",
"Configuration invalid",
"Args can't be nil",
], in_order: true)
end

def test_run_fails_if_task_template_is_blank
task_runner = build_task_runner
result = task_runner.run(task_template: '',
entrypoint: ['/bin/sh', '-c'],
args: nil,
env_vars: ["MY_CUSTOM_VARIABLE=MITTENS"])
assert_task_run_failure(result)

assert_logs_match_all([
"Initializing task",
"Validating configuration",
"Result: FAILURE",
"Configuration invalid",
"Task template name can't be nil",
], in_order: true)
end

def test_run_bang_fails_if_task_template_or_args_are_invalid
task_runner = build_task_runner
assert_raises(KubernetesDeploy::TaskConfigurationError) do
task_runner.run!(task_template: '',
entrypoint: ['/bin/sh', '-c'],
args: nil,
env_vars: ["MY_CUSTOM_VARIABLE=MITTENS"])
end
end

def test_run_with_template_missing
task_runner = build_task_runner
assert_task_run_failure(task_runner.run(run_params))
Expand Down
34 changes: 0 additions & 34 deletions test/unit/kubernetes-deploy/runner_task_test.rb

This file was deleted.