Class: KubernetesDeploy::KubernetesResource
- Inherits:
-
Object
- Object
- KubernetesDeploy::KubernetesResource
show all
- Defined in:
- lib/kubernetes-deploy/kubernetes_resource.rb
Direct Known Subclasses
Bugsnag, Cloudsql, ConfigMap, DaemonSet, Deployment, Ingress, Memcached, PersistentVolumeClaim, Pod, PodDisruptionBudget, PodTemplate, Redis, ReplicaSet, ResourceQuota, Service, ServiceAccount
Defined Under Namespace
Classes: Event
Constant Summary
collapse
- TIMEOUT =
5.minutes
- LOG_LINE_COUNT =
250
- DEBUG_RESOURCE_NOT_FOUND_MESSAGE =
"None found. Please check your usual logging service (e.g. Splunk)."
- UNUSUAL_FAILURE_MESSAGE =
<<~MSG
It is very unusual for this resource type to fail to deploy. Please try the deploy again.
If that new deploy also fails, contact your cluster administrator.
MSG
- STANDARD_TIMEOUT_MESSAGE =
<<~MSG
Kubernetes will continue to attempt to deploy this resource in the cluster, but at this point it is considered unlikely that it will succeed.
If you have reason to believe it will succeed, retry the deploy to continue to monitor the rollout.
MSG
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(namespace:, context:, definition:, logger:) ⇒ KubernetesResource
Returns a new instance of KubernetesResource.
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 45
def initialize(namespace:, context:, definition:, logger:)
@name = definition.dig("metadata", "name")
unless @name.present?
logger.summary.add_paragraph("Rendered template content:\n#{definition.to_yaml}")
raise FatalDeploymentError, "Template is missing required field metadata.name"
end
@namespace = namespace
@context = context
@logger = logger
@definition = definition
@statsd_report_done = false
@validation_error_msg = nil
end
|
Instance Attribute Details
#context ⇒ Object
Returns the value of attribute context.
9
10
11
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 9
def context
@context
end
|
#deploy_started=(value) ⇒ Object
Sets the attribute deploy_started
10
11
12
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 10
def deploy_started=(value)
@deploy_started = value
end
|
#name ⇒ Object
Returns the value of attribute name.
9
10
11
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 9
def name
@name
end
|
#namespace ⇒ Object
Returns the value of attribute namespace.
9
10
11
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 9
def namespace
@namespace
end
|
#type ⇒ Object
105
106
107
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 105
def type
@type || self.class.name.split('::').last
end
|
#validation_error_msg ⇒ Object
Returns the value of attribute validation_error_msg.
9
10
11
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 9
def validation_error_msg
@validation_error_msg
end
|
Class Method Details
.build(namespace:, context:, definition:, logger:) ⇒ Object
25
26
27
28
29
30
31
32
33
34
35
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 25
def self.build(namespace:, context:, definition:, logger:)
opts = { namespace: namespace, context: context, definition: definition, logger: logger }
if KubernetesDeploy.const_defined?(definition["kind"])
klass = KubernetesDeploy.const_get(definition["kind"])
klass.new(**opts)
else
inst = new(**opts)
inst.type = definition["kind"]
inst
end
end
|
.timeout ⇒ Object
37
38
39
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 37
def self.timeout
self::TIMEOUT
end
|
Instance Method Details
#debug_message ⇒ Object
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 123
def debug_message
helpful_info = []
if deploy_failed?
helpful_info << ColorizedString.new("#{id}: FAILED").red
helpful_info << failure_message if failure_message.present?
else
helpful_info << ColorizedString.new("#{id}: TIMED OUT").yellow + " (limit: #{timeout}s)"
helpful_info << timeout_message if timeout_message.present?
end
helpful_info << " - Final status: #{status}"
events = fetch_events
if events.present?
helpful_info << " - Events (common success events excluded):"
events.each do |identifier, event_hashes|
event_hashes.each { |event| helpful_info << " [#{identifier}]\t#{event}" }
end
else
helpful_info << " - Events: #{DEBUG_RESOURCE_NOT_FOUND_MESSAGE}"
end
if respond_to?(:fetch_logs)
container_logs = fetch_logs
if container_logs.blank? || container_logs.values.all?(&:blank?)
helpful_info << " - Logs: #{DEBUG_RESOURCE_NOT_FOUND_MESSAGE}"
else
sorted_logs = container_logs.sort_by { |_, log_lines| log_lines.length }
sorted_logs.each do |identifier, log_lines|
if log_lines.empty?
helpful_info << " - Logs from container '#{identifier}': #{DEBUG_RESOURCE_NOT_FOUND_MESSAGE}"
next
end
helpful_info << " - Logs from container '#{identifier}' (last #{LOG_LINE_COUNT} lines shown):"
log_lines.each do |line|
helpful_info << " #{line}"
end
end
end
end
helpful_info.join("\n")
end
|
#deploy_failed? ⇒ Boolean
85
86
87
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 85
def deploy_failed?
false
end
|
#deploy_finished? ⇒ Boolean
109
110
111
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 109
def deploy_finished?
deploy_failed? || deploy_succeeded? || deploy_timed_out?
end
|
#deploy_method ⇒ Object
Expected values: :apply, :replace, :replace_force
119
120
121
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 119
def deploy_method
:apply
end
|
#deploy_succeeded? ⇒ Boolean
89
90
91
92
93
94
95
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 89
def deploy_succeeded?
if @deploy_started && !@success_assumption_warning_shown
@logger.warn("Don't know how to monitor resources of type #{type}. Assuming #{id} deployed successfully.")
@success_assumption_warning_shown = true
end
true
end
|
#deploy_timed_out? ⇒ Boolean
113
114
115
116
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 113
def deploy_timed_out?
return false unless @deploy_started
!deploy_succeeded? && !deploy_failed? && (Time.now.utc - @deploy_started > timeout)
end
|
#exists? ⇒ Boolean
97
98
99
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 97
def exists?
nil
end
|
#failure_message ⇒ Object
189
190
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 189
def failure_message
end
|
#fetch_events ⇒ Object
Returns a hash in the following format:
"pod/web-1" => [
"Pulling: pulling image "hello-world:latest" (1 events)",
"Pulled: Successfully pulled image "hello-world:latest" (1 events)"
]
174
175
176
177
178
179
180
181
182
183
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 174
def fetch_events
return {} unless exists?
out, _err, st = kubectl.run("get", "events", "--output=go-template=#{Event.go_template_for(type, name)}")
return {} unless st.success?
event_collector = Hash.new { |hash, key| hash[key] = [] }
Event.(out).each_with_object(event_collector) do |candidate, events|
events[id] << candidate.to_s if candidate.seen_since?(@deploy_started - 5.seconds)
end
end
|
#file_path ⇒ Object
78
79
80
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 78
def file_path
file.path
end
|
#id ⇒ Object
74
75
76
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 74
def id
"#{type}/#{name}"
end
|
#kubectl ⇒ Object
198
199
200
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 198
def kubectl
@kubectl ||= Kubectl.new(namespace: @namespace, context: @context, logger: @logger, log_failure_by_default: false)
end
|
#pretty_status ⇒ Object
192
193
194
195
196
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 192
def pretty_status
padding = " " * [50 - id.length, 1].max
msg = exists? ? status : "not found"
"#{id}#{padding}#{msg}"
end
|
#report_status_to_statsd(watch_time) ⇒ Object
202
203
204
205
206
207
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 202
def report_status_to_statsd(watch_time)
unless @statsd_report_done
::StatsD.measure('resource.duration', watch_time, tags: statsd_tags)
@statsd_report_done = true
end
end
|
#status ⇒ Object
101
102
103
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 101
def status
@status ||= "Unknown"
end
|
#sync ⇒ Object
82
83
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 82
def sync
end
|
#timeout ⇒ Object
41
42
43
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 41
def timeout
self.class.timeout
end
|
#timeout_message ⇒ Object
185
186
187
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 185
def timeout_message
STANDARD_TIMEOUT_MESSAGE
end
|
#validate_definition ⇒ Object
61
62
63
64
65
66
67
68
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 61
def validate_definition
@validation_error_msg = nil
command = ["create", "-f", file_path, "--dry-run", "--output=name"]
_, err, st = kubectl.run(*command, log_failure: false)
return true if st.success?
@validation_error_msg = err
false
end
|
#validation_failed? ⇒ Boolean
70
71
72
|
# File 'lib/kubernetes-deploy/kubernetes_resource.rb', line 70
def validation_failed?
@validation_error_msg.present?
end
|