From 939f93253e2cc2caf8566f8ceddb1a788b9bbde0 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Mon, 2 Dec 2019 14:22:40 +0100 Subject: [PATCH] add 'template' services --- .../config.configuration.server.get.yml | 2 +- messages/v1/messages/server.deleted.yml | 2 +- .../v1/messages/{old => }/server.list.yml | 0 messages/v1/messages/template.generate.yml | 26 +++++++ messages/v1/types/server.yml | 4 +- messages/v1/types/template.yml | 14 ++++ src/risotto/config.py | 3 + src/risotto/dispatcher.py | 6 +- src/risotto/register.py | 3 +- src/risotto/services/config/config.py | 73 +++++++++++-------- src/risotto/services/server/__init__.py | 1 + src/risotto/services/server/server.py | 8 ++ .../services/servermodel/servermodel.py | 27 ++++++- src/risotto/services/template/__init__.py | 1 + src/risotto/services/template/template.py | 48 ++++++++++++ templates/1/mailname | 1 + 16 files changed, 179 insertions(+), 40 deletions(-) rename messages/v1/messages/{old => }/server.list.yml (100%) create mode 100644 messages/v1/messages/template.generate.yml create mode 100644 messages/v1/types/template.yml create mode 100644 src/risotto/services/server/__init__.py create mode 100644 src/risotto/services/server/server.py create mode 100644 src/risotto/services/template/__init__.py create mode 100644 src/risotto/services/template/template.py create mode 100644 templates/1/mailname diff --git a/messages/v1/messages/config.configuration.server.get.yml b/messages/v1/messages/config.configuration.server.get.yml index a0eaf36..02c4b67 100644 --- a/messages/v1/messages/config.configuration.server.get.yml +++ b/messages/v1/messages/config.configuration.server.get.yml @@ -17,7 +17,7 @@ parameters: type: Number ref: Server.ServerId description: | - Identifiant de la configuration. + Identifiant du serveur. deploy: type: Boolean description: Configuration de type déployée. diff --git a/messages/v1/messages/server.deleted.yml b/messages/v1/messages/server.deleted.yml index 09d0f92..d0c9ac5 100644 --- a/messages/v1/messages/server.deleted.yml +++ b/messages/v1/messages/server.deleted.yml @@ -13,7 +13,7 @@ public: false domain: server-domain parameters: - serverid: + server_id: type: Number description: | Identifiant du serveur supprimé. diff --git a/messages/v1/messages/old/server.list.yml b/messages/v1/messages/server.list.yml similarity index 100% rename from messages/v1/messages/old/server.list.yml rename to messages/v1/messages/server.list.yml diff --git a/messages/v1/messages/template.generate.yml b/messages/v1/messages/template.generate.yml new file mode 100644 index 0000000..0b9b2a2 --- /dev/null +++ b/messages/v1/messages/template.generate.yml @@ -0,0 +1,26 @@ +--- +uri: template.generate + +description: | + Génère et récupère les templates générés. + +sampleuse: ~ + +pattern: rpc + +public: true + +domain: template-domain + +parameters: + server_id: + type: Number + ref: Server.ServerId + shortarg: s + description: | + Identifiant du serveur. + +response: + type: Template + description: | + Les fichiers de configuration générés. diff --git a/messages/v1/types/server.yml b/messages/v1/types/server.yml index b45f0cd..0c0ebba 100644 --- a/messages/v1/types/server.yml +++ b/messages/v1/types/server.yml @@ -3,7 +3,7 @@ title: Server type: object description: Description du serveur. properties: - serverid: + server_id: type: number description: Identifiant du serveur. ref: Server.ServerId @@ -33,7 +33,7 @@ properties: type: string description: Timestamp de la dernière connexion avec le serveur. required: - - serverid + - server_id - servername - serverdescription - servermodelid diff --git a/messages/v1/types/template.yml b/messages/v1/types/template.yml new file mode 100644 index 0000000..739f6da --- /dev/null +++ b/messages/v1/types/template.yml @@ -0,0 +1,14 @@ +--- +title: Template +type: object +description: Les fichiers de configuration générés. +properties: + server_id: + type: Number + description: Identifiant du serveur. + template_dir: + type: String + description: Nom du répertoire avec les fichiers de configuration générés. +required: + - server_id + - template_dir diff --git a/src/risotto/config.py b/src/risotto/config.py index de87374..e6b8b8e 100644 --- a/src/risotto/config.py +++ b/src/risotto/config.py @@ -4,4 +4,7 @@ ROOT_CACHE_DIR = 'cache' DEBUG = True DATABASE_DIR = 'database' INTERNAL_USER = 'internal' +CONFIGURATION_DIR = 'configurations' +TEMPLATE_DIR = 'templates' +TMP_DIR = 'tmp' ROUGAIL_DTD_PATH = '../rougail/data/creole.dtd' diff --git a/src/risotto/dispatcher.py b/src/risotto/dispatcher.py index 4166f42..112a343 100644 --- a/src/risotto/dispatcher.py +++ b/src/risotto/dispatcher.py @@ -60,7 +60,7 @@ class CallDispatcher: mandatories = list(config.value.mandatory()) if mandatories: mand = [mand.split('.')[-1] for mand in mandatories] - raise ValueError(_(f'missing parameters in response: {mand}')) + raise ValueError(_(f'missing parameters in response: {mand} in message "{risotto_context.message}"')) try: config.value.dict() except Exception as err: @@ -238,6 +238,10 @@ class Dispatcher(register.RegisterDispatcher, CallDispatcher, PublishDispatcher) # return the config return config + def get_service(self, + name: str): + return self.injected_self[name] + dispatcher = Dispatcher() register.dispatcher = dispatcher diff --git a/src/risotto/register.py b/src/risotto/register.py index b4d12f7..8c28172 100644 --- a/src/risotto/register.py +++ b/src/risotto/register.py @@ -159,7 +159,8 @@ class RegisterDispatcher: # valid function's arguments if self.messages[version][message]['pattern'] == 'rpc': if notification is undefined: - raise RegistrationError(_('notification is mandatory when registered {message} with {module_name}.{function_name} even if you set None')) + function_name = function.__name__ + raise RegistrationError(_(f'notification is mandatory when registered "{message}" with "{module_name}.{function_name}" even if you set None')) valid_params = self.valid_rpc_params else: valid_params = self.valid_event_params diff --git a/src/risotto/services/config/config.py b/src/risotto/services/config/config.py index d9316ad..56a508d 100644 --- a/src/risotto/services/config/config.py +++ b/src/risotto/services/config/config.py @@ -53,7 +53,7 @@ class Risotto(Controller): """ pre-load servermodel and server """ await self.load_servermodels(risotto_context) - # FIXME await self.load_servers(risotto_context) + await self.load_servers(risotto_context) async def load_servermodels(self, risotto_context: Context) -> None: @@ -82,6 +82,11 @@ class Risotto(Controller): servermodel['servermodelid'], servermodelparentid) + def get_funcs_filename(self, + servermodelid: int): + return join(ROOT_CACHE_DIR, str(servermodelid)+".creolefuncs") + + async def load_servermodel(self, risotto_context: Context, @@ -90,7 +95,7 @@ class Risotto(Controller): """ Loads a servermodel """ cache_file = join(ROOT_CACHE_DIR, str(servermodelid)+".xml") - funcs_file = join(ROOT_CACHE_DIR, str(servermodelid)+".creolefuncs") + funcs_file = self.get_funcs_filename(servermodelid) log.info_msg(risotto_context, None, f'Load servermodel {servermodelname} ({servermodelid})') @@ -216,29 +221,32 @@ class Risotto(Controller): # loads servers for server in servers: try: - self.load_server(server['serverid'], + self.load_server(risotto_context, + server['server_id'], server['servername'], server['servermodelid']) except Exception as err: + if DEBUG: + print_exc() servername = server['servername'] - serverid = server['serverid'] - msg = _(f'Unable to load server {servername} ({serverid}): {err}') + server_id = server['server_id'] + msg = _(f'unable to load server {servername} ({server_id}): {err}') log.error_msg(risotto_context, None, msg) def load_server(self, risotto_context: Context, - serverid: int, + server_id: int, servername: str, servermodelid: int) -> None: """ Loads a server """ - if serverid in self.server: + if server_id in self.server: return log.info_msg(risotto_context, None, - f'Load server {servername} ({serverid})') + f'Load server {servername} ({server_id})') if not servermodelid in self.servermodel: msg = f'unable to find servermodel with id {servermodelid}' log.error_msg(risotto_context, @@ -247,61 +255,61 @@ class Risotto(Controller): raise CallError(msg) # check if server was already created - session_id = f's_{serverid}' - is_new_config = session_id not in list_sessions() + session_id = f's_{server_id}' # get the servermodel's metaconfig metaconfig = self.servermodel[servermodelid] # create server configuration and server 'to deploy' configuration and store it - self.server[serverid] = {'server': self.build_config(session_id, - is_new_config), - 'server_to_deploy': self.build_config(f'std_{serverid}', - is_new_config)} + self.server[server_id] = {'server': self.build_config(session_id, + server_id, + servername, + metaconfig), + 'server_to_deploy': self.build_config(f'std_{server_id}', + server_id, + servername, + metaconfig), + 'funcs_file': self.get_funcs_filename(servermodelid)} def build_config(self, session_id: str, - is_new_config: bool) -> None: + server_id: int, + servername: str, + metaconfig: MetaConfig) -> None: """ build server's config """ config = metaconfig.config.new(session_id, + storage=self.save_storage, persistent=True) - config.information.set('server_id', serverid) + config.information.set('server_id', server_id) config.information.set('server_name', servername) config.owner.set(servername) - - # if new config, remove force_store_value before switchint to read-only mode - # force_store_value is not allowed for new server (wait when configuration is deploy) - if is_new_config: - ro = list(config.property.getdefault('read_only', 'append')) - ro.remove('force_store_value') - config.property.setdefault(frozenset(ro), 'read_only', 'append') - rw = list(config.property.getdefault('read_write', 'append')) - rw.remove('force_store_value') - config.property.setdefault(frozenset(rw), 'read_write', 'append') config.property.read_only() + return config @register('v1.server.created') async def server_created(self, - serverid: int, + risotto_context: Context, + server_id: int, servername: str, servermodelid: int) -> None: """ Loads server's configuration when a new server is created """ - self.load_server(serverid, + self.load_server(risotto_context, + server_id, servername, servermodelid) @register('v1.server.deleted') async def server_deleted(self, - serverid: int) -> None: + server_id: int) -> None: # delete config to it's parents - for config in self.server[serverid].values(): + for config in self.server[server_id].values(): for parent in config.config.parents(): parent.config.pop(config.config.name()) delete_session(config.config.name()) # delete metaconfig - del self.server[serverid] + del self.server[server_id] @register('v1.servermodel.created') async def servermodel_created(self, @@ -369,7 +377,8 @@ class Risotto(Controller): except: pass del self.server[server_id] - self.load_server(server_id, + self.load_server(risotto_context, + server_id, server_name, servermodelid) else: diff --git a/src/risotto/services/server/__init__.py b/src/risotto/services/server/__init__.py new file mode 100644 index 0000000..3e60340 --- /dev/null +++ b/src/risotto/services/server/__init__.py @@ -0,0 +1 @@ +from .server import Risotto diff --git a/src/risotto/services/server/server.py b/src/risotto/services/server/server.py new file mode 100644 index 0000000..77a4bb8 --- /dev/null +++ b/src/risotto/services/server/server.py @@ -0,0 +1,8 @@ +from ...controller import Controller +from ...register import register + + +class Risotto(Controller): + @register('v1.server.list', None) + async def server_list(self): + return [{'server_id': 1, 'servername': 'one', 'serverdescription': 'the first', 'servermodelid': 1}] diff --git a/src/risotto/services/servermodel/servermodel.py b/src/risotto/services/servermodel/servermodel.py index d8e9c4c..8729573 100644 --- a/src/risotto/services/servermodel/servermodel.py +++ b/src/risotto/services/servermodel/servermodel.py @@ -14,6 +14,30 @@ class Risotto(Controller): async def servermodel_describe(self, inheritance, creolefuncs, servermodelid, schema, conffiles, resolvdepends, probes): schema = """ + + + + + + False + + + /etc/mailname + + + False + + + mailname + + + True + + + + basic + + normal @@ -38,5 +62,4 @@ class Risotto(Controller): """ - print('pouet') - return [{'servermodelid': 1, 'servermodelname': 'name', 'servermodeldescription': 'description', 'subreleasename': 'name', 'sourceid': 1, 'schema': schema, 'creolefuncs': ''}] + return {'servermodelid': 1, 'servermodelname': 'name', 'servermodeldescription': 'description', 'subreleasename': 'name', 'sourceid': 1, 'schema': schema, 'creolefuncs': ''} diff --git a/src/risotto/services/template/__init__.py b/src/risotto/services/template/__init__.py new file mode 100644 index 0000000..9bb372b --- /dev/null +++ b/src/risotto/services/template/__init__.py @@ -0,0 +1 @@ +from .template import Risotto diff --git a/src/risotto/services/template/template.py b/src/risotto/services/template/template.py new file mode 100644 index 0000000..23e3703 --- /dev/null +++ b/src/risotto/services/template/template.py @@ -0,0 +1,48 @@ +from os import mkdir +from os.path import isdir, join +from shutil import rmtree +from rougail.template import generate +from tiramisu import Storage +from ...config import ROOT_CACHE_DIR, CONFIGURATION_DIR, TEMPLATE_DIR, TMP_DIR +from ...controller import Controller +from ...register import register +from ...dispatcher import dispatcher + +class Risotto(Controller): + def __init__(self): + self.storage = Storage(engine='dictionary') + + @register('v1.template.generate', None) + async def template_get(self, + server_id: int): + config_module = dispatcher.get_service('config') + server = config_module.server[server_id] + config = meta = server['server'].config.deepcopy(storage=self.storage) + while True: + try: + children = list(config.config.list()) + except: + break + if children: + config = children[0] + else: + break + print(config.value.dict()) + configurations_dir = join(CONFIGURATION_DIR, + str(server_id)) + if isdir(configurations_dir): + rmtree(configurations_dir) + mkdir(configurations_dir) + tmp_dir = join(TMP_DIR, str(server_id)) + if isdir(tmp_dir): + rmtree(tmp_dir) + mkdir(tmp_dir) + templates_dir = join(TEMPLATE_DIR, str(server_id)) + generate(config, + server['funcs_file'], + templates_dir, + tmp_dir, + configurations_dir) + + return {'server_id': server_id, + 'template_dir': configurations_dir} diff --git a/templates/1/mailname b/templates/1/mailname new file mode 100644 index 0000000..2031a31 --- /dev/null +++ b/templates/1/mailname @@ -0,0 +1 @@ +mode_conteneur_actif: %%mode_conteneur_actif