75 lines
2.8 KiB
Python
75 lines
2.8 KiB
Python
from charms.reactive import Endpoint
|
|
from charms.reactive.flags import toggle_flag
|
|
from charmhelpers.core.hookenv import ingress_address
|
|
|
|
|
|
'''
|
|
This interface is desiged to be compatible with a previous
|
|
implementation based on RelationBase.
|
|
|
|
The old `{endpoint_name}.available` flags are maintained
|
|
'''
|
|
|
|
|
|
class PrometheusRequires(Endpoint):
|
|
def manage_flags(self):
|
|
"""
|
|
Managing the availability flag based on the port field from a connected
|
|
unit. It is convention that remote units signal availability this way.
|
|
"""
|
|
is_available = len(self.targets()) > 0
|
|
toggle_flag(self.expand_name('endpoint.{endpoint_name}.available'),
|
|
is_available)
|
|
# compatibility
|
|
toggle_flag(self.expand_name('{endpoint_name}.available'),
|
|
is_available)
|
|
|
|
def targets(self):
|
|
"""
|
|
Interface method returns a list of available prometheus targets.
|
|
[
|
|
{
|
|
'job_name': name_of_job,
|
|
'targets': [ host_address:host_port, ... ],
|
|
'metrics_path': path_to_metrics_endpoint(optional),
|
|
'scrape_interval': scrape_interval(optional),
|
|
'scrape_timeout': scrape_timeout(optional),
|
|
'labels': { "label": "value", ... },
|
|
},
|
|
# ...
|
|
]
|
|
"""
|
|
services = {}
|
|
for relation in self.relations:
|
|
service_name = relation.application_name
|
|
for unit in relation.units:
|
|
service = services.setdefault(service_name, {
|
|
'job_name': service_name,
|
|
'targets': [],
|
|
})
|
|
|
|
# If the hostname is not provided we use the informaton from
|
|
# the relation
|
|
host = (unit.received['hostname'] or
|
|
ingress_address(relation.relation_id, unit.unit_name))
|
|
port = unit.received['port']
|
|
|
|
# Skipping this unit if it isn't ready yet
|
|
if host and port:
|
|
service['targets'].append('{}:{}'.format(host, port))
|
|
else:
|
|
continue
|
|
|
|
if unit.received['metrics_path']:
|
|
service['metrics_path'] = unit.received['metrics_path']
|
|
if unit.received['labels']:
|
|
service['labels'] = unit.received['labels']
|
|
|
|
# Optional fields
|
|
if unit.received['scrape_interval']:
|
|
service['scrape_interval'] = \
|
|
unit.received['scrape_interval']
|
|
if unit.received['scrape_timeout']:
|
|
service['scrape_timeout'] = unit.received['scrape_timeout']
|
|
return [s for s in services.values() if s['targets']]
|