This commit is contained in:
Васильев Евгений Владимирович 2017-02-07 01:58:13 +03:00
parent 1f09875aa3
commit 62cb5c24ba
6 changed files with 174 additions and 144 deletions

View File

@ -1,15 +1,20 @@
{ {
"services": [ "services": [
{"name":"zzy0", {
"name": "zzy0",
"ports": ["tname_aa", "tname_ab", "tname_ba", "tname_bb", "tname_d"] "ports": ["tname_aa", "tname_ab", "tname_ba", "tname_bb", "tname_d"]
}, },
{"name":"zzy1", {
"name": "zzy1",
"ports": ["tname_aa", "tname_ab", "tname_ba", "tname_bb"] "ports": ["tname_aa", "tname_ab", "tname_ba", "tname_bb"]
}, },
{"name":"zzz0", {
"name": "zzz0",
"ports": ["tname_aa", "tname_bb"] "ports": ["tname_aa", "tname_bb"]
}, },
{"name":"zzz1"} {
"name": "zzz1"
}
], ],
"template": "templates/selfcheck.jj2", "template": "templates/selfcheck.jj2",
"dest": "selfcheck", "dest": "selfcheck",

View File

@ -23,7 +23,7 @@ args = parser.parse_args()
config = Config(args.config if args.config else '/etc/surok/conf/surok.json') config = Config(args.config if args.config else '/etc/surok/conf/surok.json')
# Main loop # Main loop
########### #
discovery = Discovery() discovery = Discovery()

View File

@ -23,7 +23,6 @@ type_par - additional parameters for test
''' '''
''' '''
Public Config object Public Config object
================================================== ==================================================
@ -36,8 +35,10 @@ Public Config object
.apps - Apps object. List of AppConfig oblects .apps - Apps object. List of AppConfig oblects
''' '''
class _ConfigTemplate(dict): class _ConfigTemplate(dict):
_conf = {} _conf = {}
def _init_conf(self, params): def _init_conf(self, params):
conf = {} conf = {}
for k in params.keys(): for k in params.keys():
@ -63,7 +64,8 @@ class _ConfigTemplate(dict):
oldvalue = conf.get(key) oldvalue = conf.get(key)
testvalue = testconf.get(key) testvalue = testconf.get(key)
if param is None: if param is None:
self._logger.error('Parameter "', key, '" value "', testvalue, '" type is "', type(testvalue).__name__, '" not found') self._logger.error('Parameter "', key, '" value "', testvalue,
'" type is "', type(testvalue).__name__, '" not found')
else: else:
type_param = param.get('type') type_param = param.get('type')
resvalue = [] resvalue = []
@ -73,7 +75,8 @@ class _ConfigTemplate(dict):
if self._test_value(key, testitem, param): if self._test_value(key, testitem, param):
if 'dict' in type_param: if 'dict' in type_param:
if param.get('params'): if param.get('params'):
res=self._set_conf_params(oldvalue,testitem,param.get('params')) res = self._set_conf_params(
oldvalue, testitem, param.get('params'))
if res is not None: if res is not None:
resvalue.append(res) resvalue.append(res)
else: else:
@ -82,7 +85,8 @@ class _ConfigTemplate(dict):
resvalue = list([None] + resvalue).pop() resvalue = list([None] + resvalue).pop()
if resvalue is not None and 'do' in type_param: if resvalue is not None and 'do' in type_param:
if not self._do_type_set(key, resvalue, param): if not self._do_type_set(key, resvalue, param):
self._logger.warning('Parameter "', key, '" current "', resvalue, '" type is "', type(resvalue).__name__, '" testing failed') self._logger.warning(
'Parameter "', key, '" current "', resvalue, '" type is "', type(resvalue).__name__, '" testing failed')
resvalue = None resvalue = None
if resvalue is not None: if resvalue is not None:
conf[key] = resvalue conf[key] = resvalue
@ -90,14 +94,18 @@ class _ConfigTemplate(dict):
def _test_value(self, key, value, param): def _test_value(self, key, value, param):
type_param = param.get('type') type_param = param.get('type')
type_value=[x for x in type_param if x in ['str', 'int', 'bool', 'dict']] type_value = [
x for x in type_param if x in ['str', 'int', 'bool', 'dict']]
if type_value: if type_value:
if type(value).__name__ not in type_value: if type(value).__name__ not in type_value:
self._logger.error('Parameter "', key, '" must be ', type_value,' types, current "', value, '" (',type(value).__name__,')') self._logger.error(
'Parameter "', key, '" must be ', type_value,
' types, current "', value, '" (', type(value).__name__, ')')
return False return False
if 'value' in type_param: if 'value' in type_param:
if value not in param.get('values', []): if value not in param.get('values', []):
self._logger.error('Value "', value, '" of key "', key, '" unknown') self._logger.error(
'Value "', value, '" of key "', key, '" unknown')
return False return False
if 'dir' in type_param: if 'dir' in type_param:
if not os.path.isdir(value): if not os.path.isdir(value):
@ -109,7 +117,8 @@ class _ConfigTemplate(dict):
return False return False
return True return True
else: else:
self._logger.error('Type for testing "{}" unknown'.format(type_value)) self._logger.error(
'Type for testing "{}" unknown'.format(type_value))
return False return False
def set_config(self, conf_data): def set_config(self, conf_data):
@ -395,7 +404,8 @@ class AppConfig(_ConfigTemplate):
def set_config(self, conf_data): def set_config(self, conf_data):
super().set_config(conf_data) super().set_config(conf_data)
self._conf.setdefault('discovery', self._config.get('default_discovery')) self._conf.setdefault(
'discovery', self._config.get('default_discovery'))
self._conf.setdefault('group', self._get_default_group()) self._conf.setdefault('group', self._get_default_group())
if type(conf_data).__name__ == 'str': if type(conf_data).__name__ == 'str':
self._conf.setdefault('conf_name', os.path.basename(conf_data)) self._conf.setdefault('conf_name', os.path.basename(conf_data))

View File

@ -12,7 +12,9 @@ from .logger import *
# Discovery object # Discovery object
_discovery_singleton = None _discovery_singleton = None
class DiscoveryTemplate: class DiscoveryTemplate:
def __init__(self): def __init__(self):
self._config = Config() self._config = Config()
self._logger = Logger() self._logger = Logger()
@ -56,6 +58,7 @@ class DiscoveryTemplate:
class Discovery: class Discovery:
_discoveries = {} _discoveries = {}
def __new__(cls): def __new__(cls):
global _discovery_singleton global _discovery_singleton
if _discovery_singleton is None: if _discovery_singleton is None:
@ -99,13 +102,15 @@ class Discovery:
if type(ports).__name__ == 'list': if type(ports).__name__ == 'list':
compatible_hosts[service] = [] compatible_hosts[service] = []
for port in ports: for port in ports:
compatible_hosts[service].append({'name':host['name'], compatible_hosts[service].append(
{'name': host['name'],
'ip': host['ip'], 'ip': host['ip'],
'port': str(port)}) 'port': str(port)})
else: else:
compatible_hosts[service] = {} compatible_hosts[service] = {}
for port in ports.keys(): for port in ports.keys():
compatible_host=compatible_hosts[service].setdefault(port,[]) compatible_host = compatible_hosts[
service].setdefault(port, [])
compatible_host.append({'name': host['name'], compatible_host.append({'name': host['name'],
'ip': host['ip'], 'ip': host['ip'],
'port': ports[port]}) 'port': ports[port]})
@ -116,6 +121,7 @@ class Discovery:
class DiscoveryMesos(DiscoveryTemplate): class DiscoveryMesos(DiscoveryTemplate):
_config_section = 'mesos' _config_section = 'mesos'
def resolve(self, app): def resolve(self, app):
hosts = {} hosts = {}
services = app.get('services') services = app.get('services')
@ -123,13 +129,15 @@ class DiscoveryMesos(DiscoveryTemplate):
for service in services: for service in services:
group = service.get('group', app.get('group')) group = service.get('group', app.get('group'))
if group is None: if group is None:
self._logger.error('Group for service "{}" of config "{}" not found'.format(service['name'],app.get('conf_name'))) self._logger.error('Group for service "{}" of config "{}" not found'.format(
service['name'], app.get('conf_name')))
continue continue
ports = service.get('ports') ports = service.get('ports')
name = service['name'] name = service['name']
hosts[name] = {} hosts[name] = {}
serv = hosts[name] serv = hosts[name]
self._logger.debug('group=',group,' ports=',ports,' name=',name,' serv=',serv) self._logger.debug(
'group=', group, ' ports=', ports, ' name=', name, ' serv=', serv)
for prot in ['tcp', 'udp']: for prot in ['tcp', 'udp']:
if ports is not None: if ports is not None:
for port_name in ports: for port_name in ports:
@ -164,15 +172,18 @@ class DiscoveryMarathon(DiscoveryTemplate):
for app in requests.get(hostname + '/v2/apps').json()['apps']: for app in requests.get(hostname + '/v2/apps').json()['apps']:
ports[app['id']] = {} ports[app['id']] = {}
if app.get('container') is not None and app['container'].get('type') == 'DOCKER': if app.get('container') is not None and app['container'].get('type') == 'DOCKER':
ports[app['id']] = app['container']['docker'].get('portMappings',[]) ports[app['id']] = app['container'][
'docker'].get('portMappings', [])
self._ports = ports self._ports = ports
except: except:
self._logger.warning('Apps (',hostname,'/v2/apps) request from Marathon API is failed') self._logger.warning(
'Apps (', hostname, '/v2/apps) request from Marathon API is failed')
pass pass
try: try:
self._tasks = requests.get(hostname + '/v2/tasks').json()['tasks'] self._tasks = requests.get(hostname + '/v2/tasks').json()['tasks']
except: except:
self._logger.warning('Tasks (',hostname,'/v2/tasks) request from Marathon API is failed') self._logger.warning(
'Tasks (', hostname, '/v2/tasks) request from Marathon API is failed')
pass pass
def _test_mask(self, mask, value): def _test_mask(self, mask, value):
@ -187,24 +198,28 @@ class DiscoveryMarathon(DiscoveryTemplate):
# Convert xxx.yyy.zzz to /zzz/yyy/xxx/ format # Convert xxx.yyy.zzz to /zzz/yyy/xxx/ format
group = service.get('group', app.get('group')) group = service.get('group', app.get('group'))
if group is None: if group is None:
self._logger.error('Group for service "{}" of config "{}" not found'.format(service['name'],app.get('conf_name'))) self._logger.error('Group for service "{}" of config "{}" not found'.format(
service['name'], app.get('conf_name')))
continue continue
group = '/' + '/'.join(group.split('.')[::-1]) + '/' group = '/' + '/'.join(group.split('.')[::-1]) + '/'
service_mask = group + service['name'] service_mask = group + service['name']
for task in self._tasks: for task in self._tasks:
if self._test_mask(service_mask, task['appId']): if self._test_mask(service_mask, task['appId']):
name='.'.join(task['appId'][len(group):].split('/')[::-1]) name = '.'.join(
task['appId'][len(group):].split('/')[::-1])
hosts[name] = {} hosts[name] = {}
serv = hosts[name] serv = hosts[name]
hostname = task['host'] hostname = task['host']
for task_port in self._ports[task['appId']]: for task_port in self._ports[task['appId']]:
prot = task_port['protocol'] prot = task_port['protocol']
port_name = task_port['name'] port_name = task_port['name']
port=task['ports'][task['servicePorts'].index(task_port['servicePort'])] port = task['ports'][
task['servicePorts'].index(task_port['servicePort'])]
if 'ports' in service: if 'ports' in service:
for port_mask in service['ports']: for port_mask in service['ports']:
if self._test_mask(port_mask, port_name): if self._test_mask(port_mask, port_name):
serv.setdefault(hostname,{'name':hostname, serv.setdefault(
hostname, {'name': hostname,
'ip': self.do_query_a(hostname)}) 'ip': self.do_query_a(hostname)})
serv[hostname].setdefault(prot, {}) serv[hostname].setdefault(prot, {})
serv[hostname][prot][port_name] = port serv[hostname][prot][port_name] = port