cucchiaiata/scripts/cucchiaiata-import

233 lines
8.8 KiB
Plaintext
Raw Permalink Normal View History

2021-04-02 09:16:53 +02:00
#!/usr/bin/python3
"""Zephir-cmd-input script
"""
from sys import exit, argv
from yaml import load, SafeLoader, YAMLError
from time import sleep
from os.path import isfile
2021-04-26 17:57:31 +02:00
from json import dumps
2021-04-02 09:16:53 +02:00
2021-04-26 17:57:31 +02:00
from cucchiaiata import Configuration, JsonError, config
2021-04-02 09:16:53 +02:00
from cucchiaiata.common import Common
from cucchiaiata.i18n import _
class Import(Common):
def __init__(self,
config_file: str,
) -> None:
super().__init__()
with open(config_file, 'r') as stream:
try:
self.config = load(stream,
Loader=SafeLoader,
)
except YAMLError as err:
raise Exception(_('unable to lead the YAML file {}').format(err))
self.remote_config = self.remote_json_to_config(self.cucchiaiata_config.remote_url)
def parse_zones(self) -> None:
for zone in self.config.get('zones', []):
self.configuration('infra',
'zone',
zone,
)
2021-04-24 10:21:31 +02:00
self.send('v1.infra.zone.deploy',
zone_name=zone['name'],
)
2021-04-02 09:16:53 +02:00
def parse_clusters(self) -> None:
for cluster in self.config.get('clusters', []):
self.configuration('infra',
'cluster',
cluster,
zone_name=cluster['zone'],
2021-04-26 17:57:31 +02:00
zones_name=cluster['zones'],
2021-04-02 09:16:53 +02:00
)
for node in cluster.get('nodes', []):
self.configuration('infra',
'cluster.node',
node,
cluster_name=cluster['name'],
)
2021-04-24 10:21:31 +02:00
self.send('v1.infra.cluster.deploy',
cluster_name=cluster['name'],
)
2021-04-02 09:16:53 +02:00
def parse_servermodels(self) -> None:
for servermodel in self.config.get('servermodels', []):
self.add_servermodel(servermodel)
def parse_organizations(self) -> None:
for organization in self.config.get('organizations', []):
self.configuration('infra',
'organization',
organization,
)
for site in organization.get('sites', []):
self.configuration('infra',
'site',
site,
organization_name=organization['name'],
zones_name=site['zones'],
)
for server in site.get('servers', []):
self.configuration('infra',
'server',
server,
site_name=site['name'],
cluster_name=server['cluster'],
zones_name=server['zones'],
servermodel_name=server['servermodel'],
)
2021-04-24 10:21:31 +02:00
self.send('v1.infra.server.deploy',
2021-04-02 09:16:53 +02:00
server_name=server['name'],
)
def configuration(self,
domain: str,
element: str,
dico: dict,
**kwargs,
) -> None:
self.upset_element(domain,
element,
dico['name'],
kwargs,
)
if 'settings' in dico:
#FIXME
sleep(1)
2021-04-26 17:57:31 +02:00
try:
self.apply_settings(element,
dico,
)
except JsonError as err:
raise Exception(f'unable to configure {element} "{dico["name"]}": {err.message["reason"]}')
2021-04-02 09:16:53 +02:00
def apply_settings(self,
element: str,
dico: dict,
) -> None:
session_id = self.send(f'v1.setting.session.{element}.start',
**{f'{element}_name': dico['name']},
)['session_id']
config = Configuration()
config.message = 'v1.setting.session.configure'
config.session_id = session_id
tiramisu = None
tiramisu_namespace = None
for key, value in self.settings_paths(dico['settings']):
current_namespace = key.split('.', 1)[0]
if tiramisu_namespace != current_namespace:
if tiramisu is not None:
self.send_configuration(tiramisu,
session_id,
)
tiramisu_namespace = current_namespace
self.send('v1.setting.session.filter',
session_id=session_id,
namespace=tiramisu_namespace,
)
tiramisu = config.configure_server()
try:
if tiramisu.option(key).option.isfollower():
for val in value:
tiramisu.option(key, val['index']).value.set(val['value'])
else:
if tiramisu.option(key).option.ismulti() and \
not isinstance(value, list):
value = [value]
tiramisu.option(key).value.set(value)
except ValueError as err:
2021-04-26 17:57:31 +02:00
print(_(f'error when setting "{element}" "{dico["name"]}": "{key}" with value "{value}": {err}'))
2021-04-02 09:16:53 +02:00
exit(1)
except Exception as err:
2021-04-26 17:57:31 +02:00
print(_(f'unexpected error when setting "{element}" "{dico["name"]}": "{key}" with value "{value}": {err}'))
2021-04-02 09:16:53 +02:00
exit(1)
self.send_configuration(tiramisu,
session_id,
)
self.send('v1.setting.session.stop',
session_id=session_id,
save=True,
)
def upset_element(self,
domain: str,
element: str,
name: str,
kwargs: dict,
) -> None:
message_name = element
if '.' in message_name:
message_name = message_name.rsplit('.', 1)[-1]
try:
self.send(f'v1.{domain}.{element}.describe',
**{f'{message_name}_name': name},
)
except:
# not exists
print(f'add "{element}" "{name}"')
kwargs[f'{message_name}_name'] = name
self.send(f'v1.{domain}.{element}.create',
**kwargs,
)
def settings_paths(self,
dico: dict,
subpath: str=None,
) -> list:
ret = []
for key, value in dico.items():
if subpath:
key_path = f'{subpath}.{key}'
else:
key_path = key
if isinstance(value, dict):
ret.extend(self.settings_paths(value, key_path))
else:
ret.append((key_path, value))
return ret
def add_servermodel(self,
servermodel: dict,
parents: list=[],
) -> None:
if 'other_parents' in servermodel:
parents = parents.copy()
parents.extend(servermodel['other_parents'])
self.configuration('setting',
'servermodel',
servermodel,
parents_name=parents,
applicationservices_name=servermodel.get('applicationservices', []),
)
if 'children' in servermodel:
child_parents = parents.copy()
child_parents.append(servermodel['name'])
for child in servermodel['children']:
self.add_servermodel(child,
child_parents,
)
if __name__ == "__main__":
if len(argv) != 2 or not isfile(argv[1]):
print(_(f'usage: {argv[0]} filename.yaml'))
exit(1)
imp = Import(argv[1])
2021-04-26 17:57:31 +02:00
try:
imp.parse_zones()
imp.parse_clusters()
imp.parse_servermodels()
imp.parse_organizations()
except JsonError as err:
print(err.message['reason'])
exit(1)
except Exception as err:
print(err)
exit(1)