diff --git a/README.md b/README.md index 365aada..0d60af5 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,32 @@ Gestion de la base de données avec Sqitch cpanm --quiet --notest App::Sqitch sqitch init risotto --uri https://forge.cadoles.com/Infra/risotto --engine pg ``` + + +Commande : + +# Empty database: +su - postgres +psql -U postgres risotto +drop table log; drop table userrole; drop table release; drop table source; drop table server; drop table servermodel; drop table applicationservice; drop table roleuri; drop table risottouser; drop table uri; + +# Import EOLE +./script/cucchiaiata source.create -n eole -u http://localhost +./script/cucchiaiata source.release.create -s eole -n 2.7.1.1 -d last +./script/cucchiaiata applicationservice.dataset.updated -s eole -r last +./script/cucchiaiata servermodel.dataset.updated -s eole -r last + +# Create a server +./script/cucchiaiata server.create -s test -d description -m eolebase -n eole -r last + +# Configure the server +./script/cucchiaiata session.server.start -s test +./script/cucchiaiata session.server.configure -s $S --creole.reseau.unbound_ip_address_cidr 192.168.1.1/24 --creole.reseau.unbound_route_address 192.168.1.2 --creole.serveur_dns.unbound_allowed_client_cidr 192.168.1.0/24 --creole.serveur_dns.unbound_local_zones cadoles.com +./script/cucchiaiata session.server.configure -s $S --creole.reseau.unbound_domain_name test.cadoles.com +./script/cucchiaiata session.server.filter -s $S -n unbound +./script/cucchiaiata session.server.configure -s $S --unbound.unbound_zone_cadoles_com.hostname_cadoles_com.hostname_cadoles_com toto titi --unbound.unbound_zone_cadoles_com.hostname_cadoles_com.ip_cadoles_com 0 192.168.1.25 --unbound.unbound_zone_cadoles_com.hostname_cadoles_com.type_cadoles_com 1 CNAME --unbound.unbound_zone_cadoles_com.hostname_cadoles_com.cname_cadoles_com 1 toto.cadoles.com +./script/cucchiaiata session.server.validate -s $S +./script/cucchiaiata session.server.stop -s $S -a + +# Generate configuration +./script/cucchiaiata template.generate -s test diff --git a/messages/v1/messages/config.configuration.server.get.yml b/messages/v1/messages/config.configuration.server.get.yml index 73165f0..80b5a01 100644 --- a/messages/v1/messages/config.configuration.server.get.yml +++ b/messages/v1/messages/config.configuration.server.get.yml @@ -7,11 +7,10 @@ description: | pattern: rpc parameters: - server_id: - type: Number - ref: Server.ServerId - description: | - Identifiant du serveur. + server_name: + type: String + ref: Server.ServerName + description: Nom du serveur. deployed: type: Boolean description: Configuration de type déployée. diff --git a/messages/v1/messages/old/servermodel.describe.yml b/messages/v1/messages/old/servermodel.describe.yml deleted file mode 100644 index 588ccbc..0000000 --- a/messages/v1/messages/old/servermodel.describe.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -uri: servermodel.describe - -description: | - Retourne les attributs détaillés d'un modèle de serveur. - -pattern: rpc - -public: true - -parameters: - servermodel_id: - type: Number - shortarg: s - description: Identifiant du modèle de serveur à récupérer. - ref: Servermodel.ServermodelId - -response: - type: Servermodel - description: Description du modèle de serveur. - -errors: - - uri: servermodel.describe.error.database_not_available - - uri: servermodel.describe.error.invalid_servermodel_id - - uri: servermodel.describe.error.unknown_servermodel_id - -related: - - servermodel.list - - servermodel.create - - servermodel.update - - servermodel.delete - - servermodel.event diff --git a/messages/v1/messages/server.create.yml b/messages/v1/messages/server.create.yml index cdd6a04..187ee4d 100644 --- a/messages/v1/messages/server.create.yml +++ b/messages/v1/messages/server.create.yml @@ -14,11 +14,21 @@ parameters: type: String shortarg: d description: Description du serveur. - server_servermodel_id: - type: Number + servermodel_name: + type: String shortarg: m - ref: Servermodel.ServermodelId - description: Identifiant du modèle de serveur. + ref: Servermodel.ServermodelName + description: Nom du modèle de serveur. + source_name: + type: String + shortarg: n + ref: Source.SourceName + description: Nom de la source. + release_distribution: + type: String + shortarg: r + ref: Source.ReleaseDistribution + description: Nom de la sous-version. response: type: Server diff --git a/messages/v1/messages/servermodel.describe.yml b/messages/v1/messages/servermodel.describe.yml new file mode 100644 index 0000000..28025a9 --- /dev/null +++ b/messages/v1/messages/servermodel.describe.yml @@ -0,0 +1,28 @@ +--- +uri: servermodel.describe + +description: | + Retourne les attributs détaillés d'un modèle de serveur. + +pattern: rpc + +parameters: + servermodel_name: + type: String + shortarg: s + description: Identifiant du modèle de serveur à récupérer. + ref: Servermodel.ServermodelId + source_name: + type: String + shortarg: n + description: Nom de la source. + ref: Source.SourceName + release_distribution: + type: String + shortarg: r + description: Nom de la distribution. + ref: Source.ReleaseDistribution + +response: + type: Servermodel + description: Description du modèle de serveur. diff --git a/messages/v1/messages/session.server.start.yml b/messages/v1/messages/session.server.start.yml index 1b8264a..401937f 100644 --- a/messages/v1/messages/session.server.start.yml +++ b/messages/v1/messages/session.server.start.yml @@ -7,12 +7,11 @@ description: | pattern: rpc parameters: - id: - type: Number - ref: Server.ServerId - shortarg: c - description: | - Identifiant de la configuration. + server_name: + type: String + ref: Server.ServerName + shortarg: s + description: Nom du serveur. response: type: Session diff --git a/messages/v1/messages/session.servermodel.start.yml b/messages/v1/messages/session.servermodel.start.yml index 3307e5a..8335017 100644 --- a/messages/v1/messages/session.servermodel.start.yml +++ b/messages/v1/messages/session.servermodel.start.yml @@ -6,12 +6,21 @@ description: | pattern: rpc parameters: - id: - type: Number - ref: Servermodel.ServermodelId - shortarg: c - description: | - Identifiant de la configuration. + servermodel_name: + type: String + ref: Servermodel.ServermodelName + shortarg: s + description: Nom du serveurmodel. + source_name: + type: String + shortarg: n + description: Nom de la source. + ref: Source.SourceName + release_distribution: + type: String + shortarg: r + description: Nom de la distribution. + ref: Source.ReleaseDistribution response: type: Session diff --git a/messages/v1/messages/source.release.create.yml b/messages/v1/messages/source.release.create.yml index f9082fd..893719e 100644 --- a/messages/v1/messages/source.release.create.yml +++ b/messages/v1/messages/source.release.create.yml @@ -7,10 +7,10 @@ description: | pattern: rpc parameters: - source_id: - type: Number - shortarg: i - description: ID de la source. + source_name: + type: String + shortarg: s + description: Nom de la source. release_name: type: String shortarg: n diff --git a/messages/v1/messages/source.release.describe.yml b/messages/v1/messages/source.release.describe.yml new file mode 100644 index 0000000..7900095 --- /dev/null +++ b/messages/v1/messages/source.release.describe.yml @@ -0,0 +1,21 @@ +--- +uri: source.release.describe + +description: | + Retourne la sous-version. + +pattern: rpc + +parameters: + source_name: + type: String + shortarg: s + description: Nom de la source. + release_distribution: + type: String + shortarg: r + description: Nom de la sous-version + +response: + type: 'Release' + description: Sous-version. diff --git a/messages/v1/messages/source.release.list.yml b/messages/v1/messages/source.release.list.yml index 5fe82b7..3d15c1a 100644 --- a/messages/v1/messages/source.release.list.yml +++ b/messages/v1/messages/source.release.list.yml @@ -6,6 +6,12 @@ description: | pattern: rpc +parameters: + source_name: + type: String + shortarg: s + description: Nom de la source. + response: type: '[]Release' description: Liste des versions disponibles. diff --git a/messages/v1/types/config.configuration.yml b/messages/v1/types/config.configuration.yml index fbd26e7..fd31b60 100644 --- a/messages/v1/types/config.configuration.yml +++ b/messages/v1/types/config.configuration.yml @@ -3,10 +3,10 @@ title: ConfigConfiguration type: object description: Description de la configuration. properties: - server_id: - type: number - description: Identifiant du serveur. - ref: Server.ServerId + server_name: + type: string + description: Nom du serveur. + ref: Server.ServerName deployed: type: boolean description: La configuration est déployée. diff --git a/script/database_manager.py b/script/database_manager.py index de25ee2..1d42684 100644 --- a/script/database_manager.py +++ b/script/database_manager.py @@ -87,7 +87,7 @@ CREATE TABLE RoleURI ( CREATE TABLE log( Msg VARCHAR(255) NOT NULL, Level VARCHAR(10) NOT NULL, - Path VARCHAR(255) NOT NULL, + Path VARCHAR(255), Username VARCHAR(100) NOT NULL, Data JSON, Date timestamp DEFAULT current_timestamp diff --git a/src/risotto/dispatcher.py b/src/risotto/dispatcher.py index 40cec40..379853b 100644 --- a/src/risotto/dispatcher.py +++ b/src/risotto/dispatcher.py @@ -298,8 +298,7 @@ class Dispatcher(register.RegisterDispatcher, CallDispatcher, PublishDispatcher) - if function_obj['risotto_context']: - kw['risotto_context'] = risotto_context + kw['risotto_context'] = risotto_context returns = await function(self.injected_self[function_obj['module']], **kw) except CallError as err: if risotto_context.type == 'rpc': diff --git a/src/risotto/http.py b/src/risotto/http.py index 70187fb..17535b6 100644 --- a/src/risotto/http.py +++ b/src/risotto/http.py @@ -55,8 +55,8 @@ class extra_route_handler: if DEBUG: print_exc() raise HTTPInternalServerError(reason=str(err)) - await log.info_msg(kwargs['risotto_context'], - dict(request.match_info)) + # await log.info_msg(kwargs['risotto_context'], + # dict(request.match_info)) return Response(text=dumps(returns)) diff --git a/src/risotto/logger.py b/src/risotto/logger.py index b6d7695..06f24fd 100644 --- a/src/risotto/logger.py +++ b/src/risotto/logger.py @@ -26,6 +26,9 @@ class Logger: sql = insert + ') ' + values + ')' print(sql, args) if not hasattr(risotto_context, 'connection'): + if path == ' http_get message: /api/v1:': + raise Exception('pouet') + print(path) print('MANQUE CONNEXION !!!') print(sql) else: @@ -92,7 +95,7 @@ class Logger: if DEBUG: print(msg) await self.insert(msg, - paths_msg, + None, risotto_context, 'Info') diff --git a/src/risotto/register.py b/src/risotto/register.py index 28c82c4..b484ea9 100644 --- a/src/risotto/register.py +++ b/src/risotto/register.py @@ -3,7 +3,7 @@ from inspect import signature from typing import Callable, Optional import asyncpg -from .utils import undefined, _ +from .utils import _ from .error import RegistrationError from .message import get_messages from .context import Context @@ -11,8 +11,7 @@ from .config import INTERNAL_USER, get_config def register(uris: str, - notification: str=undefined, - database: bool=False): + notification: str=None): """ Decorator to register function to the dispatcher """ if not isinstance(uris, list): @@ -24,7 +23,6 @@ def register(uris: str, dispatcher.set_function(version, message, notification, - database, function) return decorator @@ -71,8 +69,7 @@ class RegisterDispatcher: def get_function_args(): function_args = self.get_function_args(function) # risotto_context is a special argument, remove it - if function_args and function_args[0] == 'risotto_context': - function_args = function_args[1:] + function_args = function_args[1:] return set(function_args) # get message arguments @@ -114,8 +111,7 @@ class RegisterDispatcher: def get_function_args(): function_args = self.get_function_args(function) # risotto_context is a special argument, remove it - if function_args[0] == 'risotto_context': - function_args = function_args[1:] + function_args = function_args[1:] return set(function_args) # get message arguments @@ -135,7 +131,6 @@ class RegisterDispatcher: version: str, message: str, notification: str, - database: bool, function: Callable): """ register a function to an URI URI is a message @@ -153,22 +148,12 @@ class RegisterDispatcher: # True if first argument is the risotto_context function_args = self.get_function_args(function) - if function_args and function_args[0] == 'risotto_context': - inject_risotto_context = True - function_args.pop(0) - else: - inject_risotto_context = False + function_args.pop(0) # check if already register if 'function' in self.messages[version][message]: raise RegistrationError(_(f'uri {version}.{message} already registered')) - # check notification - if self.messages[version][message]['pattern'] == 'rpc': - if notification is undefined: - function_name = function.__name__ - raise RegistrationError(_(f'notification is mandatory when registered "{message}" with "{module_name}.{function_name}" even if you set None')) - # register if self.messages[version][message]['pattern'] == 'rpc': register = self.register_rpc @@ -179,8 +164,6 @@ class RegisterDispatcher: module_name, function, function_args, - inject_risotto_context, - database, notification) def register_rpc(self, @@ -189,14 +172,10 @@ class RegisterDispatcher: module_name: str, function: Callable, function_args: list, - inject_risotto_context: bool, - database: bool, notification: Optional[str]): self.messages[version][message]['module'] = module_name self.messages[version][message]['function'] = function self.messages[version][message]['arguments'] = function_args - self.messages[version][message]['risotto_context'] = inject_risotto_context - self.messages[version][message]['database'] = database if notification: self.messages[version][message]['notification'] = notification @@ -206,18 +185,14 @@ class RegisterDispatcher: module_name: str, function: Callable, function_args: list, - inject_risotto_context: bool, - database: bool, notification: Optional[str]): if 'functions' not in self.messages[version][message]: self.messages[version][message]['functions'] = [] dico = {'module': module_name, 'function': function, - 'arguments': function_args, - 'database': database, - 'risotto_context': inject_risotto_context} - if notification and notification is not undefined: + 'arguments': function_args} + if notification and notification: dico['notification'] = notification self.messages[version][message]['functions'].append(dico) diff --git a/src/risotto/services/applicationservice/applicationservice.py b/src/risotto/services/applicationservice/applicationservice.py index 664a08e..27bbcf2 100644 --- a/src/risotto/services/applicationservice/applicationservice.py +++ b/src/risotto/services/applicationservice/applicationservice.py @@ -35,7 +35,7 @@ class Risotto(Controller): 'applicationservice_release_id': release_id, 'applicationservice_id': applicationservice_id} - @register('v1.applicationservice.create', None, database=True) + @register('v1.applicationservice.create') async def applicationservice_create(self, risotto_context: Context, applicationservice_name: str, @@ -48,7 +48,7 @@ class Risotto(Controller): applicationservice_dependencies, release_id) - @register('v1.applicationservice.dataset.updated', None, database=True) + @register('v1.applicationservice.dataset.updated') async def applicationservice_update(self, risotto_context: Context, source_name: str, @@ -90,7 +90,7 @@ class Risotto(Controller): return {'retcode': 0, 'returns': _('Application Services successfully loaded')} - @register('v1.applicationservice.get_by_id', None, database=True) + @register('v1.applicationservice.get_by_id') async def applicationservice_get_by_id(self, risotto_context: Context, applicationservice_id: int) -> Dict: @@ -104,7 +104,7 @@ class Risotto(Controller): raise Exception(_(f'unknown service with ID {applicationservice_id}')) return dict(applicationservice) - @register('v1.applicationservice.describe', None, database=True) + @register('v1.applicationservice.describe') async def applicationservice_describe(self, risotto_context: Context, applicationservice_name, diff --git a/src/risotto/services/config/config.py b/src/risotto/services/config/config.py index 0e6e41b..5b5ec4f 100644 --- a/src/risotto/services/config/config.py +++ b/src/risotto/services/config/config.py @@ -86,10 +86,18 @@ class Risotto(Controller): # use file in cache with open(cache_file) as fileio: xmlroot = parse(fileio).getroot() - self.servermodel[servermodel_id] = await self.build_metaconfig(servermodel_id, - servermodel_name, - xmlroot, - funcs_file) + try: + self.servermodel[servermodel_id] = await self.build_metaconfig(servermodel_id, + servermodel_name, + xmlroot, + funcs_file) + except Exception as err: + if get_config().get('global').get('debug'): + print_exc() + msg = _(f'unable to load {servermodel_name}: {err}') + await log.error_msg(risotto_context, + None, + msg) async def build_metaconfig(self, servermodel_id: int, @@ -187,7 +195,7 @@ class Risotto(Controller): server['server_name'], server['server_servermodel_id']) except Exception as err: - if DEBUG: + if get_config().get('global').get('debug'): print_exc() server_name = server['server_name'] server_id = server['server_id'] @@ -363,8 +371,13 @@ class Risotto(Controller): @register('v1.config.configuration.server.get', None) async def get_configuration(self, - server_id: int, + risotto_context: Context, + server_name: str, deployed: bool) -> bytes: + server = await self.call('v1.server.describe', + risotto_context, + server_name=server_name) + server_id = server['server_id'] if server_id not in self.server: msg = _(f'cannot find server with id {server_id}') await log.error_msg(risotto_context, @@ -379,7 +392,8 @@ class Risotto(Controller): await server.property.read_only() try: - configuration = await server.value.dict(fullpath=True) + configuration = await server.value.dict(fullpath=True, + leader_to_list=True) except: if deployed: msg = _(f'No configuration available for server {server_id}') @@ -389,7 +403,7 @@ class Risotto(Controller): None, msg) raise CallError(msg) - return {'server_id': server_id, + return {'server_name': server_name, 'deployed': deployed, 'configuration': configuration} diff --git a/src/risotto/services/server/server.py b/src/risotto/services/server/server.py index 37caf07..6ef3303 100644 --- a/src/risotto/services/server/server.py +++ b/src/risotto/services/server/server.py @@ -7,7 +7,7 @@ from ...utils import _ class Risotto(Controller): - @register('v1.server.list', None, database=True) + @register('v1.server.list') async def server_list(self, risotto_context: Context) -> Dict: sql = ''' @@ -17,16 +17,20 @@ class Risotto(Controller): servers = await risotto_context.connection.fetch(sql) return [dict(r) for r in servers] - @register('v1.server.create', 'v1.server.created', database=True) + @register('v1.server.create', 'v1.server.created') async def server_create(self, risotto_context: Context, server_name: str, server_description: str, - server_servermodel_id: int) -> Dict: + servermodel_name: str, + source_name: str, + release_distribution: str) -> Dict: - await self.call('v1.servermodel.get_by_id', - risotto_context, - servermodel_id=server_servermodel_id) + servermodel = await self.call('v1.servermodel.describe', + risotto_context, + servermodel_name=servermodel_name, + source_name=source_name, + release_distribution=release_distribution) server_insert = """INSERT INTO Server(ServerName, ServerDescription, ServerServermodelId) VALUES ($1,$2,$3) RETURNING ServerId @@ -34,13 +38,13 @@ class Risotto(Controller): server_id = await risotto_context.connection.fetchval(server_insert, server_name, server_description, - server_servermodel_id) + servermodel['servermodel_id']) return {'server_id': server_id, 'server_name': server_name, 'server_description': server_description, - 'server_servermodel_id': server_servermodel_id} + 'server_servermodel_id': servermodel['servermodel_id']} - @register('v1.server.describe', None, database=True) + @register('v1.server.describe') async def server_describe(self, risotto_context: Context, server_name: str) -> Dict: diff --git a/src/risotto/services/servermodel/servermodel.py b/src/risotto/services/servermodel/servermodel.py index 37a70e9..143232e 100644 --- a/src/risotto/services/servermodel/servermodel.py +++ b/src/risotto/services/servermodel/servermodel.py @@ -31,9 +31,9 @@ class Risotto(Controller): source_url='none') internal_release = await self.call('v1.source.release.create', risotto_context, - source_id=internal_source['source_id'], + source_name='internal', release_name='none', - release_distribution='stable') + release_distribution='last') self.internal_release_id = internal_release['release_id'] async def servermodel_gen_funcs(self, @@ -245,7 +245,7 @@ class Risotto(Controller): servermodel_name, release_id)['servermodel_id'] - @register('v1.servermodel.dataset.updated', None, database=True) + @register('v1.servermodel.dataset.updated') async def servermodel_update(self, risotto_context: Context, source_name: str, @@ -322,7 +322,7 @@ class Risotto(Controller): servermodel_description['done'] = True return {'retcode': 0, 'returns': _('Servermodels successfully loaded')} - @register('v1.servermodel.list', None, database=True) + @register('v1.servermodel.list') async def servermodel_list(self, risotto_context: Context, source_id: int): @@ -333,10 +333,32 @@ class Risotto(Controller): servermodels = await risotto_context.connection.fetch(sql) return [dict(r) for r in servermodels] - @register('v1.servermodel.get_by_id', None, database=True) + @register('v1.servermodel.describe') + async def servermodel_describe(self, + risotto_context: Context, + servermodel_name, + source_name, + release_distribution) -> Dict: + release = await self.call('v1.source.release.describe', + risotto_context, + source_name=source_name, + release_distribution=release_distribution) + sql = ''' + SELECT ServermodelId as servermodel_id, ServermodelName as servermodel_name, ServermodelDescription as servermodel_description, ServermodelParentsId as servermodel_parents_id, ServermodelReleaseId as release_id + FROM Servermodel + WHERE ServermodelName=$1 AND ServermodelReleaseId=$2 + ''' + servermodel = await risotto_context.connection.fetchrow(sql, + servermodel_name, + release['release_id']) + if not servermodel: + raise Exception(_(f'{servermodel_id} is not a valid ID for a servermodel')) + return dict(servermodel) + + @register('v1.servermodel.get_by_id') async def servermodel_get_by_id(self, - risotto_context: Context, - servermodel_id: int): + risotto_context: Context, + servermodel_id: int) -> Dict: sql = ''' SELECT ServermodelId as servermodel_id, ServermodelName as servermodel_name, ServermodelDescription as servermodel_description, ServermodelParentsId as servermodel_parents_id, ServermodelReleaseId as release_id FROM Servermodel diff --git a/src/risotto/services/session/session.py b/src/risotto/services/session/session.py index 5eaebc8..ce6696a 100644 --- a/src/risotto/services/session/session.py +++ b/src/risotto/services/session/session.py @@ -64,24 +64,22 @@ class Risotto(Controller): 'mode': session['mode'], 'debug': session['debug']} - @register(['v1.session.server.start', 'v1.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 + @register('v1.session.server.start') + async def start_session_server(self, + risotto_context: Context, + server_name: str) -> Dict: + """ start a new config session for a server """ - type = risotto_context.message.rsplit('.', 2)[-2] config_module = dispatcher.get_service('config') - if type == 'server': - if id not in config_module.server: - raise Exception(_(f'cannot find {type} with id {id}')) - config = config_module.server[id]['server'] - else: - if id not in config_module.servermodel: - raise Exception(_(f'cannot find {type} with id {id}')) - config = config_module.servermodel[id] + server = await self.call('v1.server.describe', + risotto_context, + server_name=server_name) + if not server or server['server_id'] not in config_module.server: + raise Exception(_(f'cannot find server with name {server_name}')) + id = server['server_id'] + config = config_module.server[id]['server'] - storage = self.get_storage(type) + storage = self.get_storage('server') # check if a session already exists sessions = storage.get_sessions() @@ -108,9 +106,57 @@ class Risotto(Controller): # return session's information return self.get_session_informations(risotto_context, session_id, - type) + 'server') - @register(['v1.session.server.list', 'v1.session.servermodel.list'], None) + @register('v1.session.servermodel.start') + async def start_session_servermodel(self, + risotto_context: Context, + servermodel_name: str, + source_name: str, + release_distribution: str) -> Dict: + """ start a new config session for a server or a servermodel + """ + config_module = dispatcher.get_service('config') + servermodel = await self.call('v1.servermodel.describe', + risotto_context, + servermodel_name=servermodel_name, + source_name=source_name, + release_distribution=release_distribution) + if not servermodel or servermodel['servermodel_id'] not in config_module.servermodel: + raise Exception(_(f'cannot find servermodel with name {servermodel_name}')) + id = servermodel['servermodel_id'] + config = config_module.servermodel[id] + + storage = self.get_storage('servermodel') + + # check if a session already exists + sessions = storage.get_sessions() + for sess_id, session in sessions.items(): + if session['id'] == id: + if session['username'] == risotto_context.username: + # same user so returns it + return self.format_session(sess_id, + session) + else: + raise Exception(_(f'{username} already edits this configuration')) + + # create a new session + while True: + session_id = 'z' + hexlify(urandom(23)).decode() + if not session_id in sessions: + break + await storage.add_session(session_id, + config, + id, + risotto_context.username, + self.modify_storage) + + # return session's information + return self.get_session_informations(risotto_context, + session_id, + 'servermodel') + + @register(['v1.session.server.list', 'v1.session.servermodel.list']) async def list_session_server(self, risotto_context: Context) -> Dict: type = risotto_context.message.rsplit('.', 2)[-2] @@ -118,7 +164,7 @@ class Risotto(Controller): return [self.format_session(session_id, session) for session_id, session in storage.get_sessions().items()] - @register(['v1.session.server.filter', 'v1.session.servermodel.filter'], None) + @register(['v1.session.server.filter', 'v1.session.servermodel.filter']) async def filter_session(self, risotto_context: Context, session_id: str, @@ -145,7 +191,7 @@ class Risotto(Controller): session_id, type) - @register(['v1.session.server.configure', 'v1.session.servermodel.configure'], None) + @register(['v1.session.server.configure', 'v1.session.servermodel.configure']) async def configure_session(self, risotto_context: Context, session_id: str, @@ -182,7 +228,7 @@ class Risotto(Controller): ret['index'] = index return ret - @register(['v1.session.server.validate', 'v1.session.servermodel.validate'], None) + @register(['v1.session.server.validate', 'v1.session.servermodel.validate']) async def validate_session(self, risotto_context: Context, session_id: str) -> Dict: @@ -211,7 +257,7 @@ class Risotto(Controller): return self.format_session(session_id, session) - @register(['v1.session.server.get', 'v1.session.servermodel.get'], None) + @register(['v1.session.server.get', 'v1.session.servermodel.get']) async def get_session_server(self, risotto_context: Context, session_id: str, @@ -229,7 +275,7 @@ class Risotto(Controller): info['content'] = content return info - @register(['v1.session.server.stop', 'v1.session.servermodel.stop'], None) + @register(['v1.session.server.stop', 'v1.session.servermodel.stop']) async def stop_session(self, risotto_context: Context, session_id: str, diff --git a/src/risotto/services/source/source.py b/src/risotto/services/source/source.py index 5d12848..35cbc25 100644 --- a/src/risotto/services/source/source.py +++ b/src/risotto/services/source/source.py @@ -10,7 +10,7 @@ from ...config import get_config class Risotto(Controller): - @register('v1.source.create', None, database=True) + @register('v1.source.create') async def source_create(self, risotto_context: Context, source_name: str, @@ -43,7 +43,7 @@ class Risotto(Controller): 'source_url': source_url, 'source_id': source_id} - @register('v1.source.describe', None, database=True) + @register('v1.source.describe') async def source_describe(self, risotto_context: Context, source_name: str) -> Dict: @@ -57,7 +57,7 @@ class Risotto(Controller): raise Exception(_(f'unknown source with name {source_name}')) return dict(source) - @register('v1.source.list', None, database=True) + @register('v1.source.list') async def source_list(self, risotto_context: Context) -> List[Dict]: source_list = """SELECT SourceId as source_id, SourceName as source_name, SourceURL as source_url @@ -66,7 +66,7 @@ class Risotto(Controller): result = await risotto_context.connection.fetch(source_list) return [dict(r) for r in result] - @register('v1.source.dataset.update', None, database=True) + @register('v1.source.dataset.update') async def version_update(self, risotto_context: Context, source_id: int, @@ -81,25 +81,28 @@ class Risotto(Controller): return {'release_id': release_id, 'release_name': release_name} - @register('v1.source.release.create', None, database=True) + @register('v1.source.release.create') async def source_release_create(self, risotto_context: Context, - source_id: int, + source_name: str, release_name: str, release_distribution: str) -> Dict: source_get = """SELECT SourceId as source_id, SourceName as source_name, SourceURL as source_url FROM Source - WHERE SourceId = $1 + WHERE SourceName = $1 """ release_upsert = """INSERT INTO Release(ReleaseName, ReleaseSourceId, ReleaseDistribution) VALUES ($1, $2, $3) ON CONFLICT (ReleaseName, ReleaseSourceId) DO UPDATE SET ReleaseName = $1 RETURNING ReleaseId """ - source = dict(await risotto_context.connection.fetchrow(source_get, - source_id)) + source_obj = await risotto_context.connection.fetchrow(source_get, + source_name) + if not source_obj: + raise Exception(_(f'unable to find a source with name {source_name}')) + source = dict(source_obj) release_id = await risotto_context.connection.fetchval(release_upsert, release_name, - source_id, + source['source_id'], release_distribution) del source['source_id'] source['release_id'] = release_id @@ -107,16 +110,33 @@ class Risotto(Controller): source['release_distribution'] = release_distribution return source - @register('v1.source.release.list', None, database=True) + @register('v1.source.release.list') async def release_list(self, - risotto_context): + risotto_context, + source_name: str) -> Dict: release_query = """SELECT ReleaseId as release_id, SourceName as source_name, SourceURL as source_url, ReleaseName as release_name, ReleaseDistribution as release_distribution FROM Release, Source - WHERE Source.SourceId=Release.ReleaseSourceId""" - result = await risotto_context.connection.fetch(release_query) + WHERE Source.SourceName=$1 AND Source.SourceId=Release.ReleaseSourceId""" + result = await risotto_context.connection.fetch(release_query, + source_name) return [dict(r) for r in result] - @register('v1.source.release.get_by_id', None, database=True) + @register('v1.source.release.describe') + async def release_list(self, + risotto_context, + source_name: str, + release_distribution: str) -> Dict: + release_query = """SELECT ReleaseId as release_id, SourceName as source_name, SourceURL as source_url, ReleaseName as release_name, ReleaseDistribution as release_distribution + FROM Release, Source + WHERE Source.SourceName=$1 AND Source.SourceId=Release.ReleaseSourceId AND Release.ReleaseDistribution=$2""" + result = await risotto_context.connection.fetchrow(release_query, + source_name, + release_distribution) + if not result: + raise Exception(_(f'unknown release distribution {release_distribution} in source {source_name}')) + return dict(result) + + @register('v1.source.release.get_by_id') async def release_get_by_id(self, risotto_context: Context, release_id: int) -> Dict: @@ -129,7 +149,7 @@ class Risotto(Controller): raise Exception(_(f'unknown release id {release_id}')) return dict(result) - @register('v1.source.release.get_by_distribution', None, database=True) + @register('v1.source.release.get_by_distribution') async def release_get_by_distribution(self, risotto_context: Context, source_id: int, diff --git a/src/risotto/services/template/template.py b/src/risotto/services/template/template.py index 63efaaf..c6f0838 100644 --- a/src/risotto/services/template/template.py +++ b/src/risotto/services/template/template.py @@ -17,7 +17,7 @@ class Risotto(Controller): self.storage = Storage(engine='dictionary') self.cache_root_path = join(get_config().get('cache').get('root_path'), 'servermodel') - @register('v1.template.generate', None) + @register('v1.template.generate') async def template_get(self, risotto_context, server_name: str) -> Dict: @@ -28,10 +28,10 @@ class Risotto(Controller): servermodel_id = server['server_servermodel_id'] config_module = dispatcher.get_service('config') server = config_module.server[server_id] - config = meta = server['server'].config.deepcopy(storage=self.storage) + config = meta = await server['server'].config.deepcopy(storage=self.storage) while True: try: - children = list(config.config.list()) + children = list(await config.config.list()) except: break if children: @@ -48,11 +48,11 @@ class Risotto(Controller): rmtree(tmp_dir) mkdir(tmp_dir) templates_dir = join(self.cache_root_path, str(servermodel_id), 'templates') - generate(config, - server['funcs_file'], - templates_dir, - tmp_dir, - configurations_dir) + await generate(config, + server['funcs_file'], + templates_dir, + tmp_dir, + configurations_dir) return {'server_id': server_id, 'template_dir': configurations_dir} diff --git a/src/risotto/services/uri/uri.py b/src/risotto/services/uri/uri.py index 0959197..19d11bf 100644 --- a/src/risotto/services/uri/uri.py +++ b/src/risotto/services/uri/uri.py @@ -24,12 +24,12 @@ class Risotto(Controller): 'v1.user.delete', 'v1.user.list', 'v1.user.role.create', + 'v1.config.configuration.server.get', 'v1.user.role.list']: try: - await self.call('v1.uri.role.join', - risotto_context, - role_name='administrator', - uri_name=uri) + await self._uri_role_join(risotto_context, + role_name='administrator', + uri_name=uri) except: pass for uri in ['v1.applicationservice.describe', @@ -56,18 +56,24 @@ class Risotto(Controller): 'v1.source.release.get_by_id', 'v1.source.release.list']: try: - await self.call('v1.uri.role.join', - risotto_context, - role_name='all', - uri_name=uri) + await self._uri_role_join(risotto_context, + role_name='all', + uri_name=uri) except: pass - @register('v1.uri.role.join', None, database=True) - async def uri_role_join(self, - risotto_context: Context, - role_name: str, - uri_name: str) -> Dict: + @register('v1.uri.role.join') + async def _uri_role_join(self, + risotto_context: Context, + role_name: str, + uri_name: str) -> Dict: + await self._uri_role_join(risotto_context, + role_name, + uri_name) + async def _uri_role_join(self, + risotto_context: Context, + role_name: str, + uri_name: str) -> Dict: # Verify if user exists and get ID sql = ''' SELECT URIId @@ -89,7 +95,7 @@ class Risotto(Controller): return {'role_name': role_name, 'uri_name': uri_name} - @register('v1.uri.role.list', None, database=True) + @register('v1.uri.role.list') async def uri_role_list(self, risotto_context: Context) -> List[Dict]: sql = ''' diff --git a/src/risotto/services/user/user.py b/src/risotto/services/user/user.py index b3688b0..0c17f2e 100644 --- a/src/risotto/services/user/user.py +++ b/src/risotto/services/user/user.py @@ -7,7 +7,7 @@ from ...utils import _ class Risotto(Controller): - @register('v1.user.create', None, database=True) + @register('v1.user.create') async def user_create(self, risotto_context: Context, user_login: str, @@ -30,7 +30,7 @@ class Risotto(Controller): 'user_name': user_name, 'user_surname': user_surname} - @register('v1.user.list', None, database=True) + @register('v1.user.list') async def user_list(self, risotto_context: Context) -> Dict: sql = ''' @@ -40,7 +40,7 @@ class Risotto(Controller): users = await risotto_context.connection.fetch(sql) return [dict(r) for r in users] - @register('v1.user.delete', None, database=True) + @register('v1.user.delete') async def user_delete(self, risotto_context: Context, user_login: str) -> Dict: @@ -55,7 +55,7 @@ class Risotto(Controller): raise Exception(_(f'unable to find user {user_login}')) return dict(user) - @register('v1.user.role.create', None, database=True) + @register('v1.user.role.create') async def user_role_create(self, risotto_context: Context, user_login: str, @@ -87,7 +87,7 @@ class Risotto(Controller): 'role_attribute': role_attribute, 'role_attribute_value': role_attribute_value} - @register('v1.user.role.list', None, database=True) + @register('v1.user.role.list') async def user_role_list(self, risotto_context: Context, user_login: Optional[str]) -> Dict: @@ -119,7 +119,7 @@ class Risotto(Controller): return [dict(r) for r in roles] # # FIXME comment savoir quel role il faut supprimer ? avec attribut ou juste l'ID ? -# @register('v1.user.role.delete', None, database=True) +# @register('v1.user.role.delete') # async def user_role_delete(self, # risotto_context: Context, # user_login: str,