707 lines
30 KiB
Python
707 lines
30 KiB
Python
from lxml.etree import parse
|
|
from io import BytesIO
|
|
from os import urandom # , unlink
|
|
from os.path import isdir, isfile, join
|
|
from binascii import hexlify
|
|
from traceback import print_exc
|
|
from json import dumps
|
|
from typing import Dict, List, Optional, Any
|
|
|
|
from tiramisu import Storage, list_sessions, delete_session, Config, MetaConfig, MixConfig
|
|
from rougail import load as rougail_load
|
|
|
|
from ...controller import Controller
|
|
from ...register import register
|
|
from ...http import register as register_http
|
|
from ...config import ROOT_CACHE_DIR, DATABASE_DIR, DEBUG, ROUGAIL_DTD_PATH
|
|
from ...context import Context
|
|
from ...utils import _
|
|
from ...error import CallError, NotAllowedError, RegistrationError
|
|
from ...logger import log
|
|
from .storage import storage_server, storage_servermodel
|
|
|
|
|
|
if not isdir(ROOT_CACHE_DIR):
|
|
raise RegistrationError(_(f'unable to find the cache dir "{ROOT_CACHE_DIR}"'))
|
|
|
|
|
|
class Risotto(Controller):
|
|
servermodel = {}
|
|
server = {}
|
|
|
|
def __init__(self) -> None:
|
|
self.save_storage = Storage(engine='sqlite3', dir_database=DATABASE_DIR)
|
|
self.modify_storage = Storage(engine='dictionary')
|
|
super().__init__()
|
|
|
|
def valid_user(self,
|
|
session_id: str,
|
|
risotto_context: Context,
|
|
type: str) -> None:
|
|
""" check if current user is the session owner
|
|
"""
|
|
if type == 'server':
|
|
storage = storage_server
|
|
else:
|
|
storage = storage_servermodel
|
|
username = risotto_context.username
|
|
if username != storage.get_session(session_id)['username']:
|
|
raise NotAllowedError()
|
|
|
|
async def on_join(self,
|
|
risotto_context: Context) -> None:
|
|
""" pre-load servermodel and server
|
|
"""
|
|
await self.load_servermodels(risotto_context)
|
|
await self.load_servers(risotto_context)
|
|
|
|
async def load_servermodels(self,
|
|
risotto_context: Context) -> None:
|
|
""" load all available servermodels
|
|
"""
|
|
log.info_msg(risotto_context,
|
|
None,
|
|
'Load servermodels')
|
|
servermodels = await self.call('v1.servermodel.list',
|
|
risotto_context)
|
|
|
|
# load each servermodels
|
|
for servermodel in servermodels:
|
|
try:
|
|
await self.load_servermodel(risotto_context,
|
|
servermodel['servermodelid'],
|
|
servermodel['servermodelname'])
|
|
except CallError as err:
|
|
pass
|
|
|
|
# do link to this servermodel
|
|
for servermodel in servermodels:
|
|
if 'servermodelparentsid' in servermodel:
|
|
for servermodelparentid in servermodel['servermodelparentsid']:
|
|
self.servermodel_legacy(servermodel['servermodelname'],
|
|
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,
|
|
servermodelid: int,
|
|
servermodelname: str) -> None:
|
|
""" Loads a servermodel
|
|
"""
|
|
cache_file = join(ROOT_CACHE_DIR, str(servermodelid)+".xml")
|
|
funcs_file = self.get_funcs_filename(servermodelid)
|
|
log.info_msg(risotto_context,
|
|
None,
|
|
f'Load servermodel {servermodelname} ({servermodelid})')
|
|
|
|
# use file in cache if found, otherwise retrieve it in servermodel context
|
|
if isfile(cache_file):
|
|
fileio = open(cache_file)
|
|
else:
|
|
servermodel = await self.call('v1.servermodel.describe',
|
|
risotto_context,
|
|
servermodelid=servermodelid,
|
|
inheritance=False,
|
|
resolvdepends=False,
|
|
schema=True,
|
|
creolefuncs=True)
|
|
fileio = BytesIO()
|
|
fileio.write(servermodel['schema'].encode())
|
|
fileio.seek(0)
|
|
|
|
with open(cache_file, 'w') as cache:
|
|
cache.write(servermodel['schema'])
|
|
with open(funcs_file, 'w') as cache:
|
|
cache.write(servermodel['creolefuncs'])
|
|
del servermodel
|
|
|
|
# loads tiramisu config and store it
|
|
xmlroot = parse(fileio).getroot()
|
|
self.servermodel[servermodelid] = self.build_metaconfig(servermodelid,
|
|
servermodelname,
|
|
xmlroot,
|
|
funcs_file)
|
|
|
|
def build_metaconfig(self,
|
|
servermodelid: int,
|
|
servermodelname: str,
|
|
xmlroot: str,
|
|
funcs_file: str) -> MetaConfig:
|
|
""" Build metaconfig for a servermodel
|
|
"""
|
|
# build tiramisu's session ID
|
|
session_id = f'v_{servermodelid}'
|
|
optiondescription = rougail_load(xmlroot,
|
|
ROUGAIL_DTD_PATH,
|
|
funcs_file)
|
|
|
|
# build servermodel metaconfig (v_xxx.m_v_xxx)
|
|
metaconfig = MetaConfig([],
|
|
optiondescription=optiondescription,
|
|
persistent=True,
|
|
session_id=session_id,
|
|
storage=self.save_storage)
|
|
mixconfig = MixConfig(children=[],
|
|
optiondescription=optiondescription,
|
|
persistent=True,
|
|
session_id='m_' + session_id,
|
|
storage=self.save_storage)
|
|
metaconfig.config.add(mixconfig)
|
|
|
|
# change default rights
|
|
ro_origin = metaconfig.property.getdefault('read_only', 'append')
|
|
ro_append = frozenset(ro_origin - {'force_store_value'})
|
|
rw_origin = metaconfig.property.getdefault('read_write', 'append')
|
|
rw_append = frozenset(rw_origin - {'force_store_value'})
|
|
metaconfig.property.setdefault(ro_append, 'read_only', 'append')
|
|
metaconfig.property.setdefault(rw_append, 'read_write', 'append')
|
|
|
|
metaconfig.property.read_only()
|
|
metaconfig.permissive.add('basic')
|
|
metaconfig.permissive.add('normal')
|
|
metaconfig.permissive.add('expert')
|
|
|
|
# set informtion and owner
|
|
metaconfig.owner.set('v_{}'.format(servermodelname))
|
|
metaconfig.information.set('servermodel_id', servermodelid)
|
|
metaconfig.information.set('servermodel_name', servermodelname)
|
|
|
|
# return configuration
|
|
return metaconfig
|
|
|
|
def servermodel_legacy(self,
|
|
servermodel_name: str,
|
|
servermodel_id: int,
|
|
servermodel_parent_id: int) -> None:
|
|
""" Make link between parent and children
|
|
"""
|
|
if servermodel_parent_id is None:
|
|
return
|
|
if not self.servermodel.get(servermodel_parent_id):
|
|
if DEBUG:
|
|
msg = _(f'Servermodel with id {servermodel_parent_id} not loaded, skipping legacy for servermodel {servermodel_name} ({servermodel_id})')
|
|
log.error_msg(risotto_context,
|
|
None,
|
|
msg)
|
|
return
|
|
servermodel_parent = self.servermodel[servermodel_parent_id]
|
|
servermodel_parent_name = servermodel_parent.information.get('servermodel_name')
|
|
if DEBUG:
|
|
msg = _(f'Create legacy of servermodel {servermodel_name} ({servermodel_id}) with parent {servermodel_parent_name} ({servermodel_parent_id})')
|
|
log.info_msg(risotto_context,
|
|
None,
|
|
msg)
|
|
|
|
# do link
|
|
mix = servermodel_parent.config.get('m_v_' + str(servermodel_parent_id))
|
|
try:
|
|
mix.config.add(self.servermodel[servermodel_id])
|
|
except Exception as err:
|
|
if DEBUG:
|
|
log.error_msg(risotto_context,
|
|
None,
|
|
str(err))
|
|
|
|
async def load_servers(self,
|
|
risotto_context: Context) -> None:
|
|
""" load all available servers
|
|
"""
|
|
log.info_msg(risotto_context,
|
|
None,
|
|
f'Load servers')
|
|
# get all servers
|
|
servers = await self.call('v1.server.list',
|
|
risotto_context)
|
|
# loads servers
|
|
for server in servers:
|
|
try:
|
|
self.load_server(risotto_context,
|
|
server['server_id'],
|
|
server['servername'],
|
|
server['servermodelid'])
|
|
except Exception as err:
|
|
if DEBUG:
|
|
print_exc()
|
|
servername = server['servername']
|
|
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,
|
|
server_id: int,
|
|
servername: str,
|
|
servermodelid: int) -> None:
|
|
""" Loads a server
|
|
"""
|
|
if server_id in self.server:
|
|
return
|
|
log.info_msg(risotto_context,
|
|
None,
|
|
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,
|
|
None,
|
|
msg)
|
|
raise CallError(msg)
|
|
|
|
# check if server was already created
|
|
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[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,
|
|
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', server_id)
|
|
config.information.set('server_name', servername)
|
|
config.owner.set(servername)
|
|
config.property.read_only()
|
|
return config
|
|
|
|
@register('v1.server.created')
|
|
async def server_created(self,
|
|
risotto_context: Context,
|
|
server_id: int,
|
|
servername: str,
|
|
servermodelid: int) -> None:
|
|
""" Loads server's configuration when a new server is created
|
|
"""
|
|
self.load_server(risotto_context,
|
|
server_id,
|
|
servername,
|
|
servermodelid)
|
|
|
|
@register('v1.server.deleted')
|
|
async def server_deleted(self,
|
|
server_id: int) -> None:
|
|
# delete config to it's parents
|
|
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[server_id]
|
|
|
|
@register('v1.servermodel.created')
|
|
async def servermodel_created(self,
|
|
servermodels) -> None:
|
|
""" when servermodels are created, load it and do link
|
|
"""
|
|
for servermodel in servermodels:
|
|
await self.load_servermodel(servermodel['servermodelid'], servermodel['servermodelname'])
|
|
for servermodel in servermodels:
|
|
if 'servermodelparentsid' in servermodel:
|
|
for servermodelparentid in servermodel['servermodelparentsid']:
|
|
self.servermodel_legacy(servermodel['servermodelname'], servermodel['servermodelid'], servermodelparentid)
|
|
|
|
@register('v1.servermodel.updated')
|
|
async def servermodel_updated(self,
|
|
risotto_context: Context,
|
|
servermodels) -> None:
|
|
for servermodel in servermodels:
|
|
servermodelid = servermodel['servermodelid']
|
|
servermodelname = servermodel['servermodelname']
|
|
servermodelparentsid = servermodel.get('servermodelparentsid')
|
|
log.info_msg(risotto_context,
|
|
None,
|
|
f'Reload servermodel {servermodelname} ({servermodelid})')
|
|
# unlink cache to force download new aggregated file
|
|
cache_file = join(ROOT_CACHE_DIR, str(servermodelid)+".xml")
|
|
if isfile(cache_file):
|
|
unlink(cache_file)
|
|
|
|
# get current servermodel
|
|
old_servermodel = self.servermodel[servermodelid]
|
|
|
|
# create new one
|
|
await self.load_servermodel(servermodelid, servermodelname)
|
|
|
|
# migrate all informations
|
|
self.servermodel[servermodelid].value.importation(old_servermodel.value.exportation())
|
|
self.servermodel[servermodelid].permissive.importation(old_servermodel.permissive.exportation())
|
|
self.servermodel[servermodelid].property.importation(old_servermodel.property.exportation())
|
|
|
|
# remove link to legacy
|
|
if servermodelparentsid:
|
|
for servermodelparentid in servermodelparentsid:
|
|
mix = self.servermodel[servermodelparentid].config.get('m_v_' + str(servermodelparentid))
|
|
try:
|
|
mix.config.pop(old_servermodel.config.name())
|
|
except:
|
|
# if mix config is reloaded too
|
|
pass
|
|
# add new link
|
|
self.servermodel_legacy(servermodelname, servermodelid, servermodelparentid)
|
|
|
|
# reload servers or servermodels in servermodel
|
|
for subconfig in old_servermodel.config.list():
|
|
if not isinstance(subconfig, MixConfig):
|
|
# a server
|
|
name = subconfig.config.name()
|
|
if name.startswith('str_'):
|
|
continue
|
|
server_id = subconfig.information.get('server_id')
|
|
server_name = subconfig.information.get('server_name')
|
|
try:
|
|
old_servermodel.config.pop(name)
|
|
old_servermodel.config.pop(f'std_{server_id}')
|
|
except:
|
|
pass
|
|
del self.server[server_id]
|
|
self.load_server(risotto_context,
|
|
server_id,
|
|
server_name,
|
|
servermodelid)
|
|
else:
|
|
# a servermodel
|
|
for subsubconfig in subconfig.config.list():
|
|
name = subsubconfig.config.name()
|
|
try:
|
|
subconfig.config.pop(name)
|
|
except:
|
|
pass
|
|
self.servermodel_legacy(subsubconfig.information.get('servermodel_name'),
|
|
subsubconfig.information.get('servermodel_id'),
|
|
servermodelid)
|
|
|
|
@register('v1.config.configuration.server.get', None)
|
|
async def get_configuration(self,
|
|
server_id: int,
|
|
deploy: bool) -> bytes:
|
|
if server_id not in self.server:
|
|
msg = _(f'cannot find server with id {server_id}')
|
|
log.error_msg(risotto_context,
|
|
None,
|
|
msg)
|
|
raise CallError(msg)
|
|
|
|
if deploy:
|
|
server = self.server[server_id]['server']
|
|
else:
|
|
server = self.server[server_id]['server_to_deploy']
|
|
|
|
server.property.read_only()
|
|
try:
|
|
dico = server.value.dict(fullpath=True)
|
|
except:
|
|
if deploy:
|
|
msg = _(f'No configuration available for server {server_id}')
|
|
else:
|
|
msg = _(f'No undeployed configuration available for server {server_id}')
|
|
log.error_msg(risotto_context,
|
|
None,
|
|
msg)
|
|
raise CallError(msg)
|
|
return dumps(dico).encode()
|
|
|
|
|
|
@register('v1.config.configuration.server.deploy', 'v1.config.configuration.server.updated')
|
|
async def deploy_configuration(self,
|
|
server_id: int) -> Dict:
|
|
"""Copy values, permissions, permissives from config 'to deploy' to active config
|
|
"""
|
|
config = self.server[server_id]['server']
|
|
config_std = self.server[server_id]['server_to_deploy']
|
|
|
|
# when deploy, calculate force_store_value
|
|
ro = config_std.property.getdefault('read_only', 'append')
|
|
if 'force_store_value' not in ro:
|
|
ro = frozenset(list(ro) + ['force_store_value'])
|
|
config_std.property.setdefault(ro, 'read_only', 'append')
|
|
rw = config_std.property.getdefault('read_write', 'append')
|
|
rw = frozenset(list(rw) + ['force_store_value'])
|
|
config_std.property.setdefault(rw, 'read_write', 'append')
|
|
config_std.property.add('force_store_value')
|
|
|
|
# copy informations from server 'to deploy' configuration to server configuration
|
|
config.value.importation(config_std.value.exportation())
|
|
config.permissive.importation(config_std.permissive.exportation())
|
|
config.property.importation(config_std.property.exportation())
|
|
|
|
return {'server_id': server_id,
|
|
'deploy': True}
|
|
|
|
def get_session(self,
|
|
session_id: str,
|
|
type: str) -> Dict:
|
|
""" Get session information from storage
|
|
"""
|
|
if type == 'server':
|
|
return storage_server.get_session(session_id)
|
|
return storage_servermodel.get_session(session_id)
|
|
|
|
def get_session_informations(self,
|
|
session_id: str,
|
|
type: str) -> Dict:
|
|
""" format session with a session ID name
|
|
"""
|
|
session = self.get_session(session_id,
|
|
type)
|
|
return self.format_session(session_id,
|
|
session)
|
|
|
|
def format_session(self,
|
|
session_name: str,
|
|
session: Dict) -> Dict:
|
|
""" format session
|
|
"""
|
|
return {'session_id': session_name,
|
|
'id': session['id'],
|
|
'username': session['username'],
|
|
'timestamp': session['timestamp'],
|
|
'namespace': session['namespace'],
|
|
'mode': session['mode'],
|
|
'debug': session['debug']}
|
|
|
|
def list_sessions(self,
|
|
type: str) -> List:
|
|
ret = []
|
|
if type == 'server':
|
|
storage = storage_server
|
|
else:
|
|
storage = storage_servermodel
|
|
for session in storage.list_sessions():
|
|
ret.append(self.format_session(session['session_id'], session))
|
|
return ret
|
|
|
|
def load_dict(self,
|
|
session: Dict) -> Dict:
|
|
if not session['option']:
|
|
session['option'] = session['config'].option(session['namespace'])
|
|
return session['option'].dict(remotable='all')
|
|
|
|
@register(['v1.config.session.server.start', 'v1.config.session.servermodel.start'], None)
|
|
async def start_session(self,
|
|
risotto_context: Context,
|
|
id: int) -> Dict:
|
|
""" start a new config session for a server or a servermodel
|
|
"""
|
|
type = risotto_context.message.rsplit('.', 2)[-2]
|
|
server_list = getattr(self, type)
|
|
|
|
if id not in server_list:
|
|
raise Exception(_(f'cannot find {type} with id {id}'))
|
|
|
|
# check if a session already exists, in this case returns it
|
|
session_list = self.list_sessions(type)
|
|
for sess in session_list:
|
|
if sess['id'] == id and sess['username'] == risotto_context.username:
|
|
session_id = sess['session_id']
|
|
session = self.get_session(session_id, type)
|
|
return self.format_session(session_id, session)
|
|
|
|
# create a new session
|
|
if type == 'server':
|
|
storage = storage_server
|
|
else:
|
|
storage = storage_servermodel
|
|
while True:
|
|
session_id = 'z' + hexlify(urandom(23)).decode()
|
|
if not storage.has_session(session_id):
|
|
break
|
|
else:
|
|
print('session {} already exists'.format(session_id))
|
|
username = risotto_context.username
|
|
storage.add_session(session_id,
|
|
server_list[id],
|
|
id,
|
|
username,
|
|
self.modify_storage)
|
|
return self.get_session_informations(session_id,
|
|
type)
|
|
|
|
@register(['v1.config.session.server.list', 'v1.config.session.servermodel.list'], None)
|
|
async def list_session_server(self,
|
|
risotto_context: Context):
|
|
type = risotto_context.message.rsplit('.', 2)[-2]
|
|
return self.list_sessions(type)
|
|
|
|
@register(['v1.config.session.server.filter', 'v1.config.session.servermodel.filter'], None)
|
|
async def filter_session(self,
|
|
risotto_context: Context,
|
|
session_id: str,
|
|
namespace: str,
|
|
mode: str,
|
|
debug: Optional[bool]):
|
|
type = risotto_context.message.rsplit('.', 2)[-2]
|
|
session = self.get_session(session_id,
|
|
type)
|
|
if namespace is not None:
|
|
session['option'] = None
|
|
session['namespace'] = namespace
|
|
if type == 'server':
|
|
storage = storage_server
|
|
else:
|
|
storage = storage_servermodel
|
|
if mode is not None:
|
|
if mode not in ('basic', 'normal', 'expert'):
|
|
raise CallError(f'unknown mode {mode}')
|
|
storage.set_config_mode(session_id,
|
|
mode)
|
|
if debug is not None:
|
|
storage.set_config_debug(session_id,
|
|
debug)
|
|
return self.get_session_informations(session_id,
|
|
type)
|
|
|
|
@register(['v1.config.session.server.configure', 'v1.config.session.servermodel.configure'], None)
|
|
async def configure_session(self,
|
|
risotto_context: Context,
|
|
session_id: str,
|
|
action: str,
|
|
name: str,
|
|
index: int,
|
|
value: Any,
|
|
value_multi: Optional[List]) -> Dict:
|
|
type = risotto_context.message.rsplit('.', 2)[-2]
|
|
session = self.get_session(session_id,
|
|
type)
|
|
ret = {'session_id': session_id,
|
|
'name': name}
|
|
if index is not None:
|
|
ret['index'] = index
|
|
option = session['config'].option(name).option
|
|
if option.ismulti() and not option.isfollower():
|
|
value = value_multi
|
|
try:
|
|
update = {'name': name,
|
|
'action': action,
|
|
'value': value}
|
|
if index is not None:
|
|
update['index'] = index
|
|
if not session['option']:
|
|
session['option'] = session['config'].option(session['namespace'])
|
|
self.load_dict(session)
|
|
updates = {'updates': [update]}
|
|
session['option'].updates(updates)
|
|
ret['status'] = 'ok'
|
|
except Exception as err:
|
|
if DEBUG:
|
|
print_exc()
|
|
ret['message'] = str(err)
|
|
ret['status'] = 'error'
|
|
return ret
|
|
|
|
@register(['v1.config.session.server.validate', 'v1.config.session.servermodel.validate'], None)
|
|
async def validate_session(self,
|
|
risotto_context: Context,
|
|
session_id: str) -> Dict:
|
|
type = risotto_context.message.rsplit('.', 2)[-2]
|
|
session = self.get_session(session_id, type)
|
|
ret = {}
|
|
try:
|
|
session['config'].forcepermissive.option(session['namespace']).value.dict()
|
|
except Exception as err:
|
|
ret['status'] = 'error'
|
|
ret['message'] = str(err)
|
|
else:
|
|
if type == 'server':
|
|
mandatories = list(session['config'].forcepermissive.value.mandatory())
|
|
if mandatories:
|
|
ret['status'] = 'incomplete'
|
|
ret['mandatories'] = mandatories
|
|
else:
|
|
ret['status'] = 'ok'
|
|
else:
|
|
ret['status'] = 'ok'
|
|
return ret
|
|
|
|
@register(['v1.config.session.server.get', 'v1.config.session.servermodel.get'], None)
|
|
async def get_session_(self,
|
|
risotto_context: Context,
|
|
session_id: str) -> Dict:
|
|
type = risotto_context.message.rsplit('.', 2)[-2]
|
|
info = self.get_session_informations(session_id,
|
|
type)
|
|
info['content'] = session_id
|
|
session = self.get_session(session_id,
|
|
type)
|
|
if not session['option']:
|
|
session['option'] = session['config'].option(session['namespace'])
|
|
info['content'] = dumps(session['option'].value.dict(fullpath=True))
|
|
|
|
return info
|
|
|
|
@register(['v1.config.session.server.stop', 'v1.config.session.servermodel.stop'], None)
|
|
async def stop_session(self,
|
|
risotto_context: Context,
|
|
session_id: str,
|
|
save: bool) -> Dict:
|
|
type = risotto_context.message.rsplit('.', 2)[-2]
|
|
self.valid_user(session_id,
|
|
risotto_context,
|
|
type)
|
|
session = self.get_session(session_id,
|
|
type)
|
|
id_ = session['id']
|
|
if type == 'server':
|
|
storage = storage_server
|
|
if save:
|
|
storage.save_values(session_id)
|
|
if self.server[id_].option('creole.general.available_probes').value.get() == "oui":
|
|
self.publish('v1.config.configuration.server.updated', server_id=id_, deploy=False)
|
|
else:
|
|
storage = storage_servermodel
|
|
if save:
|
|
storage.save_values(session_id)
|
|
for probe in self.servermodel[id_].config.list():
|
|
# FIXME should use config.information.get('server_id')
|
|
name = probe.config.name()
|
|
if name.startswith('p_'):
|
|
server_id = int(name.rsplit('_', 1)[-1])
|
|
if self.server[server_id].option('creole.general.available_probes').value.get() == "oui":
|
|
self.publish('v1.config.configuration.server.updated', server_id=server_id)
|
|
storage.del_session(session_id)
|
|
return self.format_session(session_id, session)
|
|
|
|
@register_http('v1', '/config/server/{session_id}')
|
|
async def get_server_api(self,
|
|
request,
|
|
risotto_context: Context,
|
|
session_id: str) -> Dict:
|
|
self.valid_user(session_id,
|
|
risotto_context,
|
|
'server')
|
|
session = storage_server.get_session(session_id)
|
|
return self.load_dict(session)
|
|
|
|
@register_http('v1', '/config/servermodel/{session_id}')
|
|
async def get_servermodel_api(self,
|
|
request,
|
|
risotto_context: Context,
|
|
session_id: str) -> Dict:
|
|
self.valid_user(session_id,
|
|
risotto_context,
|
|
'servermodel')
|
|
session = storage_servermodel.get_session(session_id)
|
|
return self.load_dict(session)
|