add 'template' services

This commit is contained in:
Emmanuel Garette 2019-12-02 14:22:40 +01:00
parent 0846c4c5cc
commit 939f93253e
16 changed files with 179 additions and 40 deletions

View File

@ -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.

View File

@ -13,7 +13,7 @@ public: false
domain: server-domain
parameters:
serverid:
server_id:
type: Number
description: |
Identifiant du serveur supprimé.

View File

@ -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.

View File

@ -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

View File

@ -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

View File

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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -0,0 +1 @@
from .server import Risotto

View File

@ -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}]

View File

@ -14,6 +14,30 @@ class Risotto(Controller):
async def servermodel_describe(self, inheritance, creolefuncs, servermodelid, schema, conffiles, resolvdepends, probes):
schema = """<?xml version='1.0' encoding='UTF-8'?>
<creole>
<family name="containers">
<family name="container0" doc="test">
<family doc="files" name="files">
<family doc="file0" name="file0">
<variable doc="" multi="False" name="mkdir" type="boolean">
<value>False</value>
</variable>
<variable doc="" multi="False" name="name" type="string">
<value>/etc/mailname</value>
</variable>
<variable doc="" multi="False" name="rm" type="boolean">
<value>False</value>
</variable>
<variable doc="" multi="False" name="source" type="string">
<value>mailname</value>
</variable>
<variable doc="" multi="False" name="activate" type="boolean">
<value>True</value>
</variable>
</family>
</family>
<property>basic</property>
</family>
</family>
<family doc="" name="creole">
<family doc="general" name="general">
<property>normal</property>
@ -38,5 +62,4 @@ class Risotto(Controller):
<separators/>
</family>
</creole>"""
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': ''}

View File

@ -0,0 +1 @@
from .template import Risotto

View File

@ -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}

1
templates/1/mailname Normal file
View File

@ -0,0 +1 @@
mode_conteneur_actif: %%mode_conteneur_actif