Class: Krane::Deployment

Inherits:
KubernetesResource show all
Defined in:
lib/krane/kubernetes_resource/deployment.rb

Constant Summary collapse

TIMEOUT =
7.minutes
SYNC_DEPENDENCIES =
%w(Pod ReplicaSet)
REQUIRED_ROLLOUT_ANNOTATION =
"required-rollout"
REQUIRED_ROLLOUT_TYPES =
%w(maxUnavailable full none).freeze
DEFAULT_REQUIRED_ROLLOUT =
'full'

Constants inherited from KubernetesResource

KubernetesResource::ALLOWED_DEPLOY_METHOD_OVERRIDES, KubernetesResource::DEBUG_RESOURCE_NOT_FOUND_MESSAGE, KubernetesResource::DEPLOY_METHOD_OVERRIDE_ANNOTATION, KubernetesResource::DISABLED_EVENT_INFO_MESSAGE, KubernetesResource::DISABLED_LOG_INFO_MESSAGE, KubernetesResource::DISABLE_FETCHING_EVENT_INFO, KubernetesResource::DISABLE_FETCHING_LOG_INFO, KubernetesResource::GLOBAL, KubernetesResource::LAST_APPLIED_ANNOTATION, KubernetesResource::LOG_LINE_COUNT, KubernetesResource::SENSITIVE_TEMPLATE_CONTENT, KubernetesResource::SERVER_DRY_RUNNABLE, KubernetesResource::SERVER_DRY_RUN_DISABLED_ERROR, KubernetesResource::STANDARD_TIMEOUT_MESSAGE, KubernetesResource::TIMEOUT_OVERRIDE_ANNOTATION, KubernetesResource::UNUSUAL_FAILURE_MESSAGE

Instance Attribute Summary

Attributes inherited from KubernetesResource

#context, #deploy_started_at, #global, #name, #namespace, #type

Instance Method Summary collapse

Methods inherited from KubernetesResource

#<=>, #after_sync, build, class_for_kind, #debug_message, #deploy_method, #deploy_method_override, #deploy_started?, #disappeared?, #exists?, #file_path, #global?, #group, #id, #initialize, kind, #kubectl_resource_type, #pretty_status, #report_status_to_statsd, #selected?, #sensitive_template_content?, #server_dry_run_validated?, #server_dry_runnable_resource?, #sync_debug_info, #terminating?, timeout, #timeout, #timeout_override, #to_kubeclient_resource, #use_generated_name, #uses_generate_name?, #validation_error_msg, #validation_failed?, #version

Constructor Details

This class inherits a constructor from Krane::KubernetesResource

Instance Method Details

#deploy_failed?Boolean

Returns:

  • (Boolean)


58
59
60
61
# File 'lib/krane/kubernetes_resource/deployment.rb', line 58

def deploy_failed?
  @latest_rs&.deploy_failed? &&
  observed_generation == current_generation
end

#deploy_succeeded?Boolean

Returns:

  • (Boolean)


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/krane/kubernetes_resource/deployment.rb', line 36

def deploy_succeeded?
  return false unless exists? && @latest_rs.present?
  return false unless observed_generation == current_generation

  if required_rollout == 'full'
    @latest_rs.deploy_succeeded? &&
    @latest_rs.desired_replicas == desired_replicas && # latest RS fully scaled up
    rollout_data["updatedReplicas"].to_i == desired_replicas &&
    rollout_data["updatedReplicas"].to_i == rollout_data["availableReplicas"].to_i
  elsif required_rollout == 'none'
    true
  elsif required_rollout == 'maxUnavailable' || percent?(required_rollout)
    minimum_needed = min_available_replicas

    @latest_rs.desired_replicas >= minimum_needed &&
    @latest_rs.ready_replicas >= minimum_needed &&
    @latest_rs.available_replicas >= minimum_needed
  else
    raise FatalDeploymentError, rollout_annotation_err_msg
  end
end

#deploy_timed_out?Boolean

Returns:

  • (Boolean)


90
91
92
93
94
95
96
# File 'lib/krane/kubernetes_resource/deployment.rb', line 90

def deploy_timed_out?
  return false if deploy_failed?
  return super if timeout_override

  # Do not use the hard timeout if progress deadline is set
  progress_condition.present? ? deploy_failing_to_progress? : super
end

#failure_messageObject



63
64
65
66
# File 'lib/krane/kubernetes_resource/deployment.rb', line 63

def failure_message
  return unless @latest_rs.present?
  "Latest ReplicaSet: #{@latest_rs.name}\n\n#{@latest_rs.failure_message}"
end

#fetch_debug_logsObject



32
33
34
# File 'lib/krane/kubernetes_resource/deployment.rb', line 32

def fetch_debug_logs
  @latest_rs.fetch_debug_logs
end

#fetch_events(kubectl) ⇒ Object



22
23
24
25
26
# File 'lib/krane/kubernetes_resource/deployment.rb', line 22

def fetch_events(kubectl)
  own_events = super
  return own_events unless @latest_rs.present?
  own_events.merge(@latest_rs.fetch_events(kubectl))
end

#pretty_timeout_typeObject



80
81
82
83
84
85
86
87
88
# File 'lib/krane/kubernetes_resource/deployment.rb', line 80

def pretty_timeout_type
  if timeout_override
    "timeout override: #{timeout_override}s"
  elsif progress_deadline.present?
    "progress deadline: #{progress_deadline}s"
  else
    super
  end
end

Returns:

  • (Boolean)


28
29
30
# File 'lib/krane/kubernetes_resource/deployment.rb', line 28

def print_debug_logs?
  @latest_rs.present?
end

#statusObject



17
18
19
20
# File 'lib/krane/kubernetes_resource/deployment.rb', line 17

def status
  return super unless exists?
  rollout_data.map { |state_replicas, num| "#{num} #{state_replicas.chop.pluralize(num)}" }.join(", ")
end

#sync(cache) ⇒ Object



12
13
14
15
# File 'lib/krane/kubernetes_resource/deployment.rb', line 12

def sync(cache)
  super
  @latest_rs = exists? ? find_latest_rs(cache) : nil
end

#timeout_messageObject



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/krane/kubernetes_resource/deployment.rb', line 68

def timeout_message
  reason_msg = if timeout_override
    STANDARD_TIMEOUT_MESSAGE
  elsif progress_condition.present?
    "Timeout reason: #{progress_condition['reason']}"
  else
    "Timeout reason: hard deadline for #{type}"
  end
  return reason_msg unless @latest_rs.present?
  "#{reason_msg}\nLatest ReplicaSet: #{@latest_rs.name}\n\n#{@latest_rs.timeout_message}"
end

#validate_definitionObject



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/krane/kubernetes_resource/deployment.rb', line 98

def validate_definition(*, **)
  super

  unless REQUIRED_ROLLOUT_TYPES.include?(required_rollout) || percent?(required_rollout)
    @validation_errors << rollout_annotation_err_msg
  end

  strategy = @definition.dig('spec', 'strategy', 'type').to_s
  if required_rollout.downcase == 'maxunavailable' && strategy.present? && strategy.downcase != 'rollingupdate'
    @validation_errors << "'#{Annotation.for(REQUIRED_ROLLOUT_ANNOTATION)}: #{required_rollout}' " \
      "is incompatible with strategy '#{strategy}'"
  end

  @validation_errors.empty?
end