Charmed-Kubernetes/kubernetes-worker/hooks/relations/prometheus/requires.py

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']]