add 'template' services
This commit is contained in:
parent
0846c4c5cc
commit
939f93253e
|
@ -17,7 +17,7 @@ parameters:
|
||||||
type: Number
|
type: Number
|
||||||
ref: Server.ServerId
|
ref: Server.ServerId
|
||||||
description: |
|
description: |
|
||||||
Identifiant de la configuration.
|
Identifiant du serveur.
|
||||||
deploy:
|
deploy:
|
||||||
type: Boolean
|
type: Boolean
|
||||||
description: Configuration de type déployée.
|
description: Configuration de type déployée.
|
||||||
|
|
|
@ -13,7 +13,7 @@ public: false
|
||||||
domain: server-domain
|
domain: server-domain
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
serverid:
|
server_id:
|
||||||
type: Number
|
type: Number
|
||||||
description: |
|
description: |
|
||||||
Identifiant du serveur supprimé.
|
Identifiant du serveur supprimé.
|
||||||
|
|
|
@ -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.
|
|
@ -3,7 +3,7 @@ title: Server
|
||||||
type: object
|
type: object
|
||||||
description: Description du serveur.
|
description: Description du serveur.
|
||||||
properties:
|
properties:
|
||||||
serverid:
|
server_id:
|
||||||
type: number
|
type: number
|
||||||
description: Identifiant du serveur.
|
description: Identifiant du serveur.
|
||||||
ref: Server.ServerId
|
ref: Server.ServerId
|
||||||
|
@ -33,7 +33,7 @@ properties:
|
||||||
type: string
|
type: string
|
||||||
description: Timestamp de la dernière connexion avec le serveur.
|
description: Timestamp de la dernière connexion avec le serveur.
|
||||||
required:
|
required:
|
||||||
- serverid
|
- server_id
|
||||||
- servername
|
- servername
|
||||||
- serverdescription
|
- serverdescription
|
||||||
- servermodelid
|
- servermodelid
|
||||||
|
|
|
@ -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
|
|
@ -4,4 +4,7 @@ ROOT_CACHE_DIR = 'cache'
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
DATABASE_DIR = 'database'
|
DATABASE_DIR = 'database'
|
||||||
INTERNAL_USER = 'internal'
|
INTERNAL_USER = 'internal'
|
||||||
|
CONFIGURATION_DIR = 'configurations'
|
||||||
|
TEMPLATE_DIR = 'templates'
|
||||||
|
TMP_DIR = 'tmp'
|
||||||
ROUGAIL_DTD_PATH = '../rougail/data/creole.dtd'
|
ROUGAIL_DTD_PATH = '../rougail/data/creole.dtd'
|
||||||
|
|
|
@ -60,7 +60,7 @@ class CallDispatcher:
|
||||||
mandatories = list(config.value.mandatory())
|
mandatories = list(config.value.mandatory())
|
||||||
if mandatories:
|
if mandatories:
|
||||||
mand = [mand.split('.')[-1] for mand in 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:
|
try:
|
||||||
config.value.dict()
|
config.value.dict()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
|
@ -238,6 +238,10 @@ class Dispatcher(register.RegisterDispatcher, CallDispatcher, PublishDispatcher)
|
||||||
# return the config
|
# return the config
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
def get_service(self,
|
||||||
|
name: str):
|
||||||
|
return self.injected_self[name]
|
||||||
|
|
||||||
|
|
||||||
dispatcher = Dispatcher()
|
dispatcher = Dispatcher()
|
||||||
register.dispatcher = dispatcher
|
register.dispatcher = dispatcher
|
||||||
|
|
|
@ -159,7 +159,8 @@ class RegisterDispatcher:
|
||||||
# valid function's arguments
|
# valid function's arguments
|
||||||
if self.messages[version][message]['pattern'] == 'rpc':
|
if self.messages[version][message]['pattern'] == 'rpc':
|
||||||
if notification is undefined:
|
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
|
valid_params = self.valid_rpc_params
|
||||||
else:
|
else:
|
||||||
valid_params = self.valid_event_params
|
valid_params = self.valid_event_params
|
||||||
|
|
|
@ -53,7 +53,7 @@ class Risotto(Controller):
|
||||||
""" pre-load servermodel and server
|
""" pre-load servermodel and server
|
||||||
"""
|
"""
|
||||||
await self.load_servermodels(risotto_context)
|
await self.load_servermodels(risotto_context)
|
||||||
# FIXME await self.load_servers(risotto_context)
|
await self.load_servers(risotto_context)
|
||||||
|
|
||||||
async def load_servermodels(self,
|
async def load_servermodels(self,
|
||||||
risotto_context: Context) -> None:
|
risotto_context: Context) -> None:
|
||||||
|
@ -82,6 +82,11 @@ class Risotto(Controller):
|
||||||
servermodel['servermodelid'],
|
servermodel['servermodelid'],
|
||||||
servermodelparentid)
|
servermodelparentid)
|
||||||
|
|
||||||
|
def get_funcs_filename(self,
|
||||||
|
servermodelid: int):
|
||||||
|
return join(ROOT_CACHE_DIR, str(servermodelid)+".creolefuncs")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def load_servermodel(self,
|
async def load_servermodel(self,
|
||||||
risotto_context: Context,
|
risotto_context: Context,
|
||||||
|
@ -90,7 +95,7 @@ class Risotto(Controller):
|
||||||
""" Loads a servermodel
|
""" Loads a servermodel
|
||||||
"""
|
"""
|
||||||
cache_file = join(ROOT_CACHE_DIR, str(servermodelid)+".xml")
|
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,
|
log.info_msg(risotto_context,
|
||||||
None,
|
None,
|
||||||
f'Load servermodel {servermodelname} ({servermodelid})')
|
f'Load servermodel {servermodelname} ({servermodelid})')
|
||||||
|
@ -216,29 +221,32 @@ class Risotto(Controller):
|
||||||
# loads servers
|
# loads servers
|
||||||
for server in servers:
|
for server in servers:
|
||||||
try:
|
try:
|
||||||
self.load_server(server['serverid'],
|
self.load_server(risotto_context,
|
||||||
|
server['server_id'],
|
||||||
server['servername'],
|
server['servername'],
|
||||||
server['servermodelid'])
|
server['servermodelid'])
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
|
if DEBUG:
|
||||||
|
print_exc()
|
||||||
servername = server['servername']
|
servername = server['servername']
|
||||||
serverid = server['serverid']
|
server_id = server['server_id']
|
||||||
msg = _(f'Unable to load server {servername} ({serverid}): {err}')
|
msg = _(f'unable to load server {servername} ({server_id}): {err}')
|
||||||
log.error_msg(risotto_context,
|
log.error_msg(risotto_context,
|
||||||
None,
|
None,
|
||||||
msg)
|
msg)
|
||||||
|
|
||||||
def load_server(self,
|
def load_server(self,
|
||||||
risotto_context: Context,
|
risotto_context: Context,
|
||||||
serverid: int,
|
server_id: int,
|
||||||
servername: str,
|
servername: str,
|
||||||
servermodelid: int) -> None:
|
servermodelid: int) -> None:
|
||||||
""" Loads a server
|
""" Loads a server
|
||||||
"""
|
"""
|
||||||
if serverid in self.server:
|
if server_id in self.server:
|
||||||
return
|
return
|
||||||
log.info_msg(risotto_context,
|
log.info_msg(risotto_context,
|
||||||
None,
|
None,
|
||||||
f'Load server {servername} ({serverid})')
|
f'Load server {servername} ({server_id})')
|
||||||
if not servermodelid in self.servermodel:
|
if not servermodelid in self.servermodel:
|
||||||
msg = f'unable to find servermodel with id {servermodelid}'
|
msg = f'unable to find servermodel with id {servermodelid}'
|
||||||
log.error_msg(risotto_context,
|
log.error_msg(risotto_context,
|
||||||
|
@ -247,61 +255,61 @@ class Risotto(Controller):
|
||||||
raise CallError(msg)
|
raise CallError(msg)
|
||||||
|
|
||||||
# check if server was already created
|
# check if server was already created
|
||||||
session_id = f's_{serverid}'
|
session_id = f's_{server_id}'
|
||||||
is_new_config = session_id not in list_sessions()
|
|
||||||
|
|
||||||
# get the servermodel's metaconfig
|
# get the servermodel's metaconfig
|
||||||
metaconfig = self.servermodel[servermodelid]
|
metaconfig = self.servermodel[servermodelid]
|
||||||
|
|
||||||
# create server configuration and server 'to deploy' configuration and store it
|
# create server configuration and server 'to deploy' configuration and store it
|
||||||
self.server[serverid] = {'server': self.build_config(session_id,
|
self.server[server_id] = {'server': self.build_config(session_id,
|
||||||
is_new_config),
|
server_id,
|
||||||
'server_to_deploy': self.build_config(f'std_{serverid}',
|
servername,
|
||||||
is_new_config)}
|
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,
|
def build_config(self,
|
||||||
session_id: str,
|
session_id: str,
|
||||||
is_new_config: bool) -> None:
|
server_id: int,
|
||||||
|
servername: str,
|
||||||
|
metaconfig: MetaConfig) -> None:
|
||||||
""" build server's config
|
""" build server's config
|
||||||
"""
|
"""
|
||||||
config = metaconfig.config.new(session_id,
|
config = metaconfig.config.new(session_id,
|
||||||
|
storage=self.save_storage,
|
||||||
persistent=True)
|
persistent=True)
|
||||||
config.information.set('server_id', serverid)
|
config.information.set('server_id', server_id)
|
||||||
config.information.set('server_name', servername)
|
config.information.set('server_name', servername)
|
||||||
config.owner.set(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()
|
config.property.read_only()
|
||||||
|
return config
|
||||||
|
|
||||||
@register('v1.server.created')
|
@register('v1.server.created')
|
||||||
async def server_created(self,
|
async def server_created(self,
|
||||||
serverid: int,
|
risotto_context: Context,
|
||||||
|
server_id: int,
|
||||||
servername: str,
|
servername: str,
|
||||||
servermodelid: int) -> None:
|
servermodelid: int) -> None:
|
||||||
""" Loads server's configuration when a new server is created
|
""" Loads server's configuration when a new server is created
|
||||||
"""
|
"""
|
||||||
self.load_server(serverid,
|
self.load_server(risotto_context,
|
||||||
|
server_id,
|
||||||
servername,
|
servername,
|
||||||
servermodelid)
|
servermodelid)
|
||||||
|
|
||||||
@register('v1.server.deleted')
|
@register('v1.server.deleted')
|
||||||
async def server_deleted(self,
|
async def server_deleted(self,
|
||||||
serverid: int) -> None:
|
server_id: int) -> None:
|
||||||
# delete config to it's parents
|
# 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():
|
for parent in config.config.parents():
|
||||||
parent.config.pop(config.config.name())
|
parent.config.pop(config.config.name())
|
||||||
delete_session(config.config.name())
|
delete_session(config.config.name())
|
||||||
# delete metaconfig
|
# delete metaconfig
|
||||||
del self.server[serverid]
|
del self.server[server_id]
|
||||||
|
|
||||||
@register('v1.servermodel.created')
|
@register('v1.servermodel.created')
|
||||||
async def servermodel_created(self,
|
async def servermodel_created(self,
|
||||||
|
@ -369,7 +377,8 @@ class Risotto(Controller):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
del self.server[server_id]
|
del self.server[server_id]
|
||||||
self.load_server(server_id,
|
self.load_server(risotto_context,
|
||||||
|
server_id,
|
||||||
server_name,
|
server_name,
|
||||||
servermodelid)
|
servermodelid)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
from .server import Risotto
|
|
@ -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}]
|
|
@ -14,6 +14,30 @@ class Risotto(Controller):
|
||||||
async def servermodel_describe(self, inheritance, creolefuncs, servermodelid, schema, conffiles, resolvdepends, probes):
|
async def servermodel_describe(self, inheritance, creolefuncs, servermodelid, schema, conffiles, resolvdepends, probes):
|
||||||
schema = """<?xml version='1.0' encoding='UTF-8'?>
|
schema = """<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<creole>
|
<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="" name="creole">
|
||||||
<family doc="general" name="general">
|
<family doc="general" name="general">
|
||||||
<property>normal</property>
|
<property>normal</property>
|
||||||
|
@ -38,5 +62,4 @@ class Risotto(Controller):
|
||||||
<separators/>
|
<separators/>
|
||||||
</family>
|
</family>
|
||||||
</creole>"""
|
</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': ''}]
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
from .template import Risotto
|
|
@ -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}
|
|
@ -0,0 +1 @@
|
||||||
|
mode_conteneur_actif: %%mode_conteneur_actif
|
Loading…
Reference in New Issue