Skip to content

Commit ba04739

Browse files
authored
Merge pull request #493 from agrare/check_metrics_connection_validity_before_queueing_perf_captures
Check metrics authentication validity before perf_capture_queue
2 parents 7be0a73 + 0c258a3 commit ba04739

File tree

4 files changed

+107
-67
lines changed

4 files changed

+107
-67
lines changed

app/models/manageiq/providers/kubernetes/container_manager/metrics_capture.rb

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ def log_severity
4949
}
5050
}
5151

52+
def capture_ems_targets(_options = {})
53+
begin
54+
verify_metrics_connection!(ems)
55+
rescue TargetValidationError, TargetValidationWarning => e
56+
_log.send(e.log_severity, e.message)
57+
return []
58+
end
59+
60+
super
61+
end
62+
5263
def prometheus_capture_context(target, start_time, end_time)
5364
PrometheusCaptureContext.new(target, start_time, end_time, INTERVAL)
5465
end
@@ -57,31 +68,36 @@ def metrics_connection(ems)
5768
ems.connection_configurations.prometheus
5869
end
5970

60-
def capture_context(_ems, target, start_time, end_time)
71+
def metrics_connection_valid?(ems)
72+
metrics_connection(ems)&.authentication&.status == "Valid"
73+
end
74+
75+
def verify_metrics_connection!(ems)
76+
raise TargetValidationError, "no provider for #{target_name}" if ems.nil?
77+
78+
raise TargetValidationWarning, "no metrics endpoint found for #{target_name}" if metrics_connection(ems).nil?
79+
raise TargetValidationWarning, "metrics authentication isn't valid for #{target_name}" unless metrics_connection_valid?(ems)
80+
end
81+
82+
def build_capture_context!(ems, target, start_time, end_time)
83+
verify_metrics_connection!(ems)
6184
# make start_time align to minutes
6285
start_time = start_time.beginning_of_minute
6386

64-
prometheus_capture_context(target, start_time, end_time)
87+
context = prometheus_capture_context(target, start_time, end_time)
88+
raise TargetValidationWarning, "no metrics endpoint found for #{target_name}" if context.nil?
89+
90+
context
6591
end
6692

6793
def perf_collect_metrics(interval_name, start_time = nil, end_time = nil)
6894
start_time ||= 15.minutes.ago.beginning_of_minute.utc
6995
ems = target.ext_management_system
7096

71-
target_name = "#{target.class.name.demodulize}(#{target.id})"
72-
_log.info("Collecting metrics for #{target_name} [#{interval_name}] " \
73-
"[#{start_time}] [#{end_time}]")
97+
_log.info("Collecting metrics for #{target_name} [#{interval_name}] [#{start_time}] [#{end_time}]")
7498

7599
begin
76-
raise TargetValidationError, "no provider for #{target_name}" if ems.nil?
77-
78-
connection = metrics_connection(ems)
79-
raise TargetValidationWarning, "no metrics endpoint found for #{target_name}" if connection.nil?
80-
raise TargetValidationWarning, "metrics authentication isn't valid for #{target_name}" unless connection.authentication&.status == "Valid"
81-
82-
context = capture_context(ems, target, start_time, end_time)
83-
84-
raise TargetValidationWarning, "no metrics endpoint found for #{target_name}" if context.nil?
100+
context = build_capture_context!(ems, target, start_time, end_time)
85101
rescue TargetValidationError, TargetValidationWarning => e
86102
_log.send(e.log_severity, "[#{target_name}] #{e.message}")
87103
ems.try(:update,
@@ -110,5 +126,14 @@ def perf_collect_metrics(interval_name, start_time = nil, end_time = nil)
110126
[{target.ems_ref => VIM_STYLE_COUNTERS},
111127
{target.ems_ref => context.ts_values}]
112128
end
129+
130+
private
131+
132+
def target_name
133+
@target_name ||= begin
134+
t = target || ems
135+
"#{t.class.name.demodulize}(#{t.id})"
136+
end
137+
end
113138
end
114139
end

spec/factories/container_group.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
FactoryBot.define do
2+
factory :kubernetes_container_group,
3+
:parent => :container_group,
4+
:class => "ManageIQ::Providers::Kubernetes::ContainerManager::ContainerGroup"
5+
end

spec/factories/ext_management_system.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,17 @@
55
zone
66
end
77
end
8+
9+
trait :with_metrics_endpoint do
10+
after(:create) do |ems|
11+
ems.endpoints << FactoryBot.create(:endpoint, :role => "prometheus")
12+
ems.authentications << FactoryBot.create(:authentication, :authtype => "prometheus", :status => "Valid")
13+
end
14+
end
15+
16+
trait :with_invalid_auth do
17+
after(:create) do |ems|
18+
ems.authentications.update_all(:status => "invalid")
19+
end
20+
end
821
end
Lines changed: 50 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,75 @@
11
describe ManageIQ::Providers::Kubernetes::ContainerManager::MetricsCapture do
2-
before do
3-
# @miq_server is required for worker_settings to work
4-
@miq_server = EvmSpecHelper.local_miq_server(:is_master => true)
5-
@ems_kubernetes = FactoryBot.create(
6-
:ems_kubernetes,
7-
:connection_configurations => [{:endpoint => {:role => :prometheus},
8-
:authentication => {:role => :prometheus}}],
9-
).tap { |ems| ems.authentications.each { |auth| auth.update!(:status => "Valid") } }
10-
@container_project = FactoryBot.create(:container_project, :ext_management_system => @ems_kubernetes)
11-
12-
@node = FactoryBot.create(
13-
:kubernetes_node,
14-
:name => 'node',
15-
:ext_management_system => @ems_kubernetes,
16-
:ems_ref => 'target'
17-
)
18-
19-
@node.computer_system.hardware = FactoryBot.create(
20-
:hardware,
21-
:cpu_total_cores => 2,
22-
:memory_mb => 2048
23-
)
24-
25-
@group = FactoryBot.create(
26-
:container_group,
27-
:ext_management_system => @ems_kubernetes,
28-
:container_node => @node,
29-
:ems_ref => 'group'
30-
)
31-
32-
@container = FactoryBot.create(
33-
:kubernetes_container,
34-
:name => 'container',
35-
:container_group => @group,
36-
:container_project => @container_project,
37-
:ext_management_system => @ems_kubernetes,
38-
:ems_ref => 'target'
39-
)
2+
let(:ems) { FactoryBot.create(:ems_kubernetes_with_zone, :with_metrics_endpoint) }
3+
let(:container_project) { FactoryBot.create(:container_project, :ext_management_system => ems) }
4+
let!(:group) { FactoryBot.create(:kubernetes_container_group, :ext_management_system => ems, :container_node => node) }
5+
let!(:container) { FactoryBot.create(:kubernetes_container, :ext_management_system => ems, :container_group => group, :container_project => container_project) }
6+
let(:node) do
7+
FactoryBot.create(:kubernetes_node, :name => 'node', :ext_management_system => ems, :ems_ref => 'target').tap do |node|
8+
node.computer_system.hardware = FactoryBot.create(:hardware, :cpu_total_cores => 2, :memory_mb => 2_048)
9+
end
4010
end
4111

4212
context "#perf_capture_object" do
4313
it "returns the correct class" do
44-
expect(@ems_kubernetes.perf_capture_object.class).to eq(described_class)
14+
expect(ems.perf_capture_object.class).to eq(described_class)
4515
end
4616
end
4717

48-
context "#capture_context" do
18+
context "#build_capture_context!" do
4919
it "detect prometheus metrics provider" do
50-
metric_capture = described_class.new(@node)
51-
context = metric_capture.capture_context(
52-
@ems_kubernetes,
53-
@node,
54-
5.minutes.ago,
55-
0.minutes.ago
56-
)
20+
metric_capture = described_class.new(node)
21+
context = metric_capture.build_capture_context!(ems, node, 5.minutes.ago, 0.minutes.ago)
5722

5823
expect(context).to be_a(described_class::PrometheusCaptureContext)
5924
end
25+
26+
context "on an invalid target" do
27+
let(:group) { FactoryBot.create(:kubernetes_container_group, :ext_management_system => ems) }
28+
29+
it "raises an exception" do
30+
metric_capture = described_class.new(group)
31+
expect { metric_capture.build_capture_context!(ems, group, 5.minutes.ago, 0.minutes.ago) }
32+
.to raise_error(described_class::TargetValidationWarning, "no associated node")
33+
end
34+
end
35+
end
36+
37+
context "#perf_capture_all_queue" do
38+
it "returns the objects" do
39+
expect(ems.perf_capture_object.perf_capture_all_queue).to include("Container" => [container], "ContainerGroup" => [group], "ContainerNode" => [node])
40+
end
41+
42+
context "with a missing metrics endpoint" do
43+
let(:ems) { FactoryBot.create(:ems_kubernetes) }
44+
45+
it "returns no objects" do
46+
expect(ems.perf_capture_object.perf_capture_all_queue).to be_empty
47+
end
48+
end
49+
50+
context "with invalid authentication on the metrics endpoint" do
51+
let(:ems) { FactoryBot.create(:ems_kubernetes_with_zone, :with_metrics_endpoint, :with_invalid_auth) }
52+
53+
it "returns no objects" do
54+
expect(ems.perf_capture_object.perf_capture_all_queue).to be_empty
55+
end
56+
end
6057
end
6158

6259
context "#perf_collect_metrics" do
6360
it "fails when no ems is defined" do
64-
@node.ext_management_system = nil
65-
expect { @node.perf_collect_metrics('interval_name') }.to raise_error(described_class::TargetValidationError)
61+
node.ext_management_system = nil
62+
expect { node.perf_collect_metrics('interval_name') }.to raise_error(described_class::TargetValidationError)
6663
end
6764

6865
it "fails when no cpu cores are defined" do
69-
@node.hardware.cpu_total_cores = nil
70-
expect { @node.perf_collect_metrics('interval_name') }.to raise_error(described_class::TargetValidationError)
66+
node.hardware.cpu_total_cores = nil
67+
expect { node.perf_collect_metrics('interval_name') }.to raise_error(described_class::TargetValidationError)
7168
end
7269

7370
it "fails when memory is not defined" do
74-
@node.hardware.memory_mb = nil
75-
expect { @node.perf_collect_metrics('interval_name') }.to raise_error(described_class::TargetValidationError)
71+
node.hardware.memory_mb = nil
72+
expect { node.perf_collect_metrics('interval_name') }.to raise_error(described_class::TargetValidationError)
7673
end
7774
end
7875
end

0 commit comments

Comments
 (0)