Skip to content

Commit 576b549

Browse files
authored
Merge pull request #57 from tkishel/PE-28451_use_v2_metrics
(PE-28451) switch from the v1 to v2 metrics api
2 parents 98e4a76 + 9865135 commit 576b549

File tree

8 files changed

+344
-230
lines changed

8 files changed

+344
-230
lines changed

README.md

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ Table of Contents
2121
This module collects metrics provided by the status endpoints of Puppet Enterprise services.
2222
The metrics can be used to identify performance issues that may be addressed by performance tuning.
2323

24+
> In PE 2018.1.13 and newer and PE 2019.4 and newer, the `/metrics/v1` endpoints are disabled by default and access to the `/metrics/v2` endpoints are restricted to localhost ... in response to CVE-2020-7943.
25+
This module requires access those endpoints to collect additional metrics from PuppetDB, and those metrics will not be collected from remote PuppetDB hosts until these restricted are resolved.
26+
Refer to [Configuration for Distributed Metrics Collection](#Configuration-for-distributed-metrics-collection) for a workaround.
27+
2428

2529
## Setup
2630

@@ -173,22 +177,6 @@ puppetdb/master.example.com/20190404T171001Z.json: "queue_depth": 0,
173177
puppetdb/master.example.com/20190404T171502Z.json: "queue_depth": 0,
174178
```
175179

176-
Example for PE 2016.5 and older:
177-
178-
```bash
179-
grep Cursor puppetdb/master.example.com/*.json
180-
181-
puppetdb/master.example.com/20190404T171001Z.json: "CursorMemoryUsage": 0,
182-
puppetdb/master.example.com/20190404T171001Z.json: "CursorFull": false,
183-
puppetdb/master.example.com/20190404T171001Z.json: "CursorPercentUsage": 0,
184-
puppetdb/master.example.com/20190404T171502Z.json: "CursorMemoryUsage": 0,
185-
puppetdb/master.example.com/20190404T171502Z.json: "CursorFull": false,
186-
puppetdb/master.example.com/20190404T171502Z.json: "CursorPercentUsage": 0,
187-
puppetdb/master.example.com/20190404T172002Z.json: "CursorMemoryUsage": 0,
188-
puppetdb/master.example.com/20190404T172002Z.json: "CursorFull": false,
189-
puppetdb/master.example.com/20190404T172002Z.json: "CursorPercentUsage": 0,
190-
```
191-
192180
### Sharing Metrics Data
193181

194182
When working with Support, you may be asked for an archive of collected metrics data.
@@ -364,17 +352,23 @@ Classify each PE Infrastructure Host with this module, specifying the following
364352
When classifying a Compile Master, specify these additional parameters:
365353

366354
```puppet
355+
class { 'puppet_metrics_collector':
356+
puppetserver_hosts => ['127.0.0.1'],
367357
puppetdb_metrics_ensure => absent,
368358
orchestrator_metrics_ensure => absent,
369359
ace_metrics_ensure => absent,
370360
bolt_metrics_ensure => absent,
361+
}
371362
```
372363

373364
When classifying a PuppetDB Host, specify these additional parameters:
374365

375366
```puppet
367+
class { 'puppet_metrics_collector':
368+
puppetdb_hosts => ['127.0.0.1'],
376369
puppetserver_metrics_ensure => absent,
377370
orchestrator_metrics_ensure => absent,
378371
ace_metrics_ensure => absent,
379372
bolt_metrics_ensure => absent,
373+
}
380374
```

files/pe_metrics.rb

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,20 @@ def setup_connection(url, use_ssl)
8383
def get_endpoint(url, use_ssl)
8484
http, uri = setup_connection(url, use_ssl)
8585

86-
data = JSON.parse(http.get(uri.request_uri).body)
86+
endpoint_data = JSON.parse(http.get(uri.request_uri).body)
87+
if endpoint_data.key?('status')
88+
if endpoint_data['status'] == 200
89+
endpoint_data = endpoint_data['value']
90+
else
91+
$error_array << "HTTP Error #{endpoint_data['status']} for #{url}"
92+
endpoint_data = {}
93+
end
94+
end
95+
return endpoint_data
96+
8797
rescue Exception => e
88-
$error_array << "#{e}"
89-
data = {}
98+
$error_array << "#{e}"
99+
endpoint_data = {}
90100
end
91101

92102
def post_endpoint(url, use_ssl, post_data)
@@ -96,50 +106,37 @@ def post_endpoint(url, use_ssl, post_data)
96106
request.content_type = 'application/json'
97107
request.body = post_data
98108

99-
data = JSON.parse(http.request(request).body)
109+
endpoint_data = JSON.parse(http.request(request).body)
110+
return endpoint_data
111+
100112
rescue Exception => e
101-
$error_array << "#{e}"
102-
data = {}
113+
$error_array << "#{e}"
114+
endpoint_data = {}
103115
end
104116

105-
def individually_retrieve_additional_metrics(host, port, use_ssl, metrics)
106-
host_url = generate_host_url(host, port, use_ssl)
117+
# PE-28451 Disables Metrics API v1 (/metrics/v1/beans/) and restricts v2 (/metrics/v2/read/) to localhost by default.
107118

108-
metrics_array = []
109-
metrics.each do |metric|
110-
endpoint = URI.escape("#{host_url}/metrics/v1/mbeans/#{metric['url']}")
111-
metrics_array << { 'name' => metric['name'], 'data' => get_endpoint(endpoint, use_ssl) }
119+
def retrieve_additional_metrics(host, port, use_ssl, metrics_type, metrics)
120+
if metrics_type == 'puppetdb'
121+
host = '127.0.0.1' if host == CERTNAME
122+
return [] unless ['127.0.0.1', 'localhost'].include?(host)
112123
end
113124

114-
return metrics_array
115-
end
116-
117-
def bulk_retrieve_additional_metrics(host, port, use_ssl, metrics)
118125
host_url = generate_host_url(host, port, use_ssl)
119126

120-
post_data = []
121-
metrics.each do |metric|
122-
post_data << metric['url']
123-
end
127+
endpoint = "#{host_url}/metrics/v2/read"
128+
metrics_output = post_endpoint(endpoint, use_ssl, metrics.to_json)
124129

125-
endpoint = "#{host_url}/metrics/v1/mbeans"
126-
metrics_output = post_endpoint(endpoint, use_ssl, post_data.to_json)
127130
metrics_array = []
128-
129131
metrics.each_index do |index|
130132
metric_name = metrics[index]['name']
131133
metric_data = metrics_output[index]
132-
metrics_array << { 'name' => metric_name, 'data' => metric_data }
133-
end
134-
135-
return metrics_array
136-
end
137-
138-
def retrieve_additional_metrics(host, port, use_ssl, pe_version, metrics)
139-
if Gem::Version.new(pe_version) < Gem::Version.new('2016.2.0') then
140-
metrics_array = individually_retrieve_additional_metrics(host, port, use_ssl, metrics)
141-
else
142-
metrics_array = bulk_retrieve_additional_metrics(host, port, use_ssl, metrics)
134+
if metric_data['status'] == 200
135+
metrics_array << { 'name' => metric_name, 'data' => metric_data['value'] }
136+
else
137+
metric_mbean = metrics[index]['mbean']
138+
$error_array << "HTTP Error #{metric_data['status']} for #{metric_mbean}"
139+
end
143140
end
144141

145142
return metrics_array

files/tk_metrics

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ HOSTS.each do |host|
2626
dataset['servers'][hostkey][METRICS_TYPE] = status_output
2727

2828
unless ADDITIONAL_METRICS.empty? then
29-
metrics_array = retrieve_additional_metrics(host, PORT, USE_SSL, PE_VERSION, ADDITIONAL_METRICS)
29+
metrics_array = retrieve_additional_metrics(host, PORT, USE_SSL, METRICS_TYPE, ADDITIONAL_METRICS)
3030
metrics_array.each do |metric_hash|
3131
metric_name = metric_hash['name']
3232
metric_data = metric_hash['data']

manifests/pe_metric.pp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
$metric_script_file_path = "${puppet_metrics_collector::scripts_dir}/${metric_script_file}"
4949
$conversion_script_file_path = "${puppet_metrics_collector::scripts_dir}/json2timeseriesdb"
5050

51+
# lint:ignore:140chars
5152
if empty($override_metrics_command) {
5253
$base_metrics_command = "${metric_script_file_path} --metrics_type ${metrics_type} --output_dir ${metrics_output_dir}"
5354

@@ -79,10 +80,10 @@
7980
} else {
8081
$metrics_command = "${base_metrics_command} --no-print"
8182
}
82-
8383
} else {
8484
$metrics_command = $override_metrics_command
8585
}
86+
# lint:endignore
8687

8788
cron { "${metrics_type}_metrics_collection" :
8889
ensure => $metric_ensure,

manifests/service/activemq.pp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
Optional[Integer] $metrics_server_port = $puppet_metrics_collector::metrics_server_port,
1313
Optional[String] $metrics_server_db_name = $puppet_metrics_collector::metrics_server_db_name,
1414
) {
15+
# lint:ignore:140chars
1516
$additional_metrics = [
1617
{
1718
'type' => 'read',
@@ -49,6 +50,7 @@
4950
'attribute' => 'AverageBlockedTime,AverageEnqueueTime,AverageMessageSize,ConsumerCount,DequeueCount,DispatchCount,EnqueueCount,ExpiredCount,ForwardCount,InFlightCount,ProducerCount,QueueSize',
5051
},
5152
]
53+
# lint:endignore
5254

5355
file { "${puppet_metrics_collector::scripts_dir}/amq_metrics" :
5456
ensure => $metrics_ensure,

0 commit comments

Comments
 (0)