Class: Krane::DeployTask

Inherits:
Object
  • Object
show all
Extended by:
StatsD::MeasureMethods
Includes:
TemplateReporting
Defined in:
lib/krane/deploy_task.rb

Overview

Ship resources to a namespace

Constant Summary collapse

PROTECTED_NAMESPACES =
%w(
  default
  kube-system
  kube-public
)

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from StatsD::MeasureMethods

measure_method

Methods included from TemplateReporting

#add_para_from_list, #record_invalid_template

Constructor Details

#initialize(namespace:, context:, current_sha: nil, logger: nil, kubectl_instance: nil, bindings: {}, global_timeout: nil, selector: nil, selector_as_filter: false, filenames: [], protected_namespaces: nil, render_erb: false, kubeconfig: nil) ⇒ DeployTask

Initializes the deploy task

Parameters:

  • namespace (String)

    Kubernetes namespace (required)

  • context (String)

    Kubernetes context (required)

  • current_sha (String) (defaults to: nil)

    The SHA of the commit

  • logger (Object) (defaults to: nil)

    Logger object (defaults to an instance of Krane::FormattedLogger)

  • kubectl_instance (Kubectl) (defaults to: nil)

    Kubectl instance

  • bindings (Hash) (defaults to: {})

    Bindings parsed by Krane::BindingsParser

  • global_timeout (Integer) (defaults to: nil)

    Timeout in seconds

  • selector (Hash) (defaults to: nil)

    Selector(s) parsed by Krane::LabelSelector

  • selector_as_filter (Boolean) (defaults to: false)

    Allow selecting a subset of Kubernetes resource templates to deploy

  • filenames (Array<String>) (defaults to: [])

    An array of filenames and/or directories containing templates (required)

  • protected_namespaces (Array<String>) (defaults to: nil)

    Array of protected Kubernetes namespaces (defaults to Krane::DeployTask::PROTECTED_NAMESPACES)

  • render_erb (Boolean) (defaults to: false)

    Enable ERB rendering



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/krane/deploy_task.rb', line 108

def initialize(namespace:, context:, current_sha: nil, logger: nil, kubectl_instance: nil, bindings: {},
  global_timeout: nil, selector: nil, selector_as_filter: false, filenames: [], protected_namespaces: nil,
  render_erb: false, kubeconfig: nil)
  @logger = logger || Krane::FormattedLogger.build(namespace, context)
  @template_sets = TemplateSets.from_dirs_and_files(paths: filenames, logger: @logger, render_erb: render_erb)
  @task_config = Krane::TaskConfig.new(context, namespace, @logger, kubeconfig)
  @bindings = bindings
  @namespace = namespace
  @namespace_tags = []
  @context = context
  @current_sha = current_sha
  @kubectl = kubectl_instance
  @global_timeout = global_timeout
  @selector = selector
  @selector_as_filter = selector_as_filter
  @protected_namespaces = protected_namespaces || PROTECTED_NAMESPACES
  @render_erb = render_erb
end

Instance Attribute Details

#task_configObject (readonly)

Returns the value of attribute task_config.



89
90
91
# File 'lib/krane/deploy_task.rb', line 89

def task_config
  @task_config
end

Instance Method Details

#predeploy_sequenceObject



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/krane/deploy_task.rb', line 60

def predeploy_sequence
  default_group = { group: nil }
  before_crs = %w(
    ResourceQuota
    NetworkPolicy
    ConfigMap
    PersistentVolumeClaim
    ServiceAccount
    Role
    RoleBinding
    Secret
  ).map { |r| [r, default_group] }

  after_crs = %w(
    Pod
  ).map { |r| [r, default_group] }

  crs = cluster_resource_discoverer.crds.select(&:predeployed?).map { |cr| [cr.kind, { group: cr.group }] }
  Hash[before_crs + crs + after_crs]
end

#prune_whitelistObject



81
82
83
# File 'lib/krane/deploy_task.rb', line 81

def prune_whitelist
  cluster_resource_discoverer.prunable_resources(namespaced: true)
end

#run(**args) ⇒ Boolean

Runs the task, returning a boolean representing success or failure

Returns:

  • (Boolean)


130
131
132
133
134
135
# File 'lib/krane/deploy_task.rb', line 130

def run(**args)
  run!(**args)
  true
rescue FatalDeploymentError
  false
end

#run!(verify_result: true, prune: true) ⇒ nil

Runs the task, raising exceptions in case of issues

Parameters:

  • verify_result (Boolean) (defaults to: true)

    Wait for completion and verify success

  • prune (Boolean) (defaults to: true)

    Enable deletion of resources that do not appear in the template dir

Returns:

  • (nil)


143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/krane/deploy_task.rb', line 143

def run!(verify_result: true, prune: true)
  start = Time.now.utc
  @logger.reset

  @logger.phase_heading("Initializing deploy")
  validate_configuration(prune: prune)
  resources = discover_resources
  validate_resources(resources)

  @logger.phase_heading("Checking initial resource statuses")
  check_initial_status(resources)

  if deploy_has_priority_resources?(resources)
    @logger.phase_heading("Predeploying priority resources")
    resource_deployer.predeploy_priority_resources(resources, predeploy_sequence)
  end

  @logger.phase_heading("Deploying all resources")
  if @protected_namespaces.include?(@namespace) && prune
    raise FatalDeploymentError, "Refusing to deploy to protected namespace '#{@namespace}' with pruning enabled"
  end

  resource_deployer.deploy!(resources, verify_result, prune)

  StatsD.client.event("Deployment of #{@namespace} succeeded",
    "Successfully deployed all #{@namespace} resources to #{@context}",
    alert_type: "success", tags: statsd_tags + %w(status:success))
  StatsD.client.distribution('all_resources.duration', StatsD.duration(start),
    tags: statsd_tags + %w(status:success))
  @logger.print_summary(:success)
rescue DeploymentTimeoutError
  @logger.print_summary(:timed_out)
  StatsD.client.event("Deployment of #{@namespace} timed out",
    "One or more #{@namespace} resources failed to deploy to #{@context} in time",
    alert_type: "error", tags: statsd_tags + %w(status:timeout))
  StatsD.client.distribution('all_resources.duration', StatsD.duration(start),
    tags: statsd_tags + %w(status:timeout))
  raise
rescue FatalDeploymentError => error
  @logger.summary.add_action(error.message) if error.message != error.class.to_s
  @logger.print_summary(:failure)
  StatsD.client.event("Deployment of #{@namespace} failed",
    "One or more #{@namespace} resources failed to deploy to #{@context}",
    alert_type: "error", tags: statsd_tags + %w(status:failed))
  StatsD.client.distribution('all_resources.duration', StatsD.duration(start),
    tags: statsd_tags + %w(status:failed))
  raise
end

#server_versionObject



85
86
87
# File 'lib/krane/deploy_task.rb', line 85

def server_version
  kubectl.server_version
end