masakari-monitors/masakarimonitors/hostmonitor/consul_check/consul_helper.py

123 lines
3.7 KiB
Python

# Copyright(c) 2021 Inspur
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Main abstraction layer for retrieving node status from consul
"""
import consul
from masakarimonitors.i18n import _
class ConsulException(Exception):
"""Base Consul Exception"""
msg_fmt = _("An unknown exception occurred.")
def __init__(self, message=None, **kwargs):
if not message:
message = self.msg_fmt % kwargs
super(ConsulException, self).__init__(message)
class ConsulAgentNotExist(ConsulException):
msg_fmt = _("Consul agent of %(cluster)s not exist.")
class ConsulGetMembersException(ConsulException):
msg_fmt = _("Failed to get members of %(cluster)s: %(err)s.")
class ConsulManager(object):
"""Consul manager class
This class helps to pull health data from all consul clusters,
and return health data in sequence.
"""
def __init__(self, CONF):
self.agents = {}
self.init_agents(CONF)
def init_agents(self, CONF):
if CONF.consul.agent_manage:
addr, port = CONF.consul.agent_manage.split(':')
self.agents['manage'] = ConsulAgent('manage', addr, port)
if CONF.consul.agent_tenant:
addr, port = CONF.consul.agent_tenant.split(':')
self.agents['tenant'] = ConsulAgent('tenant', addr, port)
if CONF.consul.agent_storage:
addr, port = CONF.consul.agent_storage.split(':')
self.agents['storage'] = ConsulAgent('storage', addr, port)
def valid_agents(self, sequence):
for name in sequence:
if self.agents.get(name) is None:
raise ConsulAgentNotExist(cluster=name)
def get_health(self, sequence):
hosts_health = {}
all_agents = []
for name in sequence:
consul_agent = self.agents.get(name)
agent_health = consul_agent.get_health()
hosts_health[name] = agent_health
if not all_agents:
all_agents = agent_health.keys()
sequence_hosts_health = {}
for host in all_agents:
sequence_hosts_health[host] = []
for name in sequence:
state = hosts_health[name].get(host)
if state:
sequence_hosts_health[host].append(state)
else:
continue
return sequence_hosts_health
class ConsulAgent(object):
"""Agent to consul cluster"""
def __init__(self, name, addr=None, port=None):
self.name = name
self.addr = addr
self.port = port
# connection to consul cluster
self.cluster = consul.Consul(host=addr, port=self.port)
def get_agents(self):
try:
members = self.cluster.agent.members()
except Exception as e:
raise ConsulGetMembersException(cluster=self.name, err=str(e))
return members
def get_health(self):
agents_health = {}
agents = self.get_agents()
for agent in agents:
host = agent.get('Name')
status = agent.get('Status')
if status == 1:
agents_health[host] = 'up'
else:
agents_health[host] = 'down'
return agents_health