diff --git a/README.md b/README.md index 0d60af5..f367670 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ drop table log; drop table userrole; drop table release; drop table source; drop # Configure the server ./script/cucchiaiata session.server.start -s test +S=xxxxxxxxxxxxxxxxxxxxxx ./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 @@ -63,4 +64,9 @@ drop table log; drop table userrole; drop table release; drop table source; drop ./script/cucchiaiata session.server.stop -s $S -a # Generate configuration +./script/cucchiaiata config.configuration.server.deploy -s test ./script/cucchiaiata template.generate -s test + +# Create a new user and set role 'server_rw' for this server +./script/cucchiaiata user.create -l gnunux -n gnunux -s gnunux +./script/cucchiaiata user.role.create -u gnunux -n 'server_rw' -a 'Server.ServerName' -v test diff --git a/messages/v1/messages/config.configuration.server.deploy.yml b/messages/v1/messages/config.configuration.server.deploy.yml index 86ee2ee..6bce28c 100644 --- a/messages/v1/messages/config.configuration.server.deploy.yml +++ b/messages/v1/messages/config.configuration.server.deploy.yml @@ -1,13 +1,17 @@ --- uri: config.configuration.server.deploy -description: | - Déployer la configuration d'un serveur. +description: Déployer la configuration d'un serveur. -pattern: event +pattern: rpc parameters: - server_id: - type: Number - description: | - Identifiant du serveur. + server_name: + type: String + ref: Server.ServerName + shortarg: s + description: Nom du serveur. + +response: + type: Deploy + description: La configuration du serveur est déployée. diff --git a/messages/v1/messages/config.configuration.server.updated.yml b/messages/v1/messages/config.configuration.server.updated.yml index aa1f84e..4d90d81 100644 --- a/messages/v1/messages/config.configuration.server.updated.yml +++ b/messages/v1/messages/config.configuration.server.updated.yml @@ -11,6 +11,11 @@ parameters: type: Number description: | Identifiant du serveur. + server_name: + type: String + ref: Server.ServerName + shortarg: s + description: Nom du serveur. deployed: type: Boolean description: Configuration de type déployée. diff --git a/messages/v1/messages/template.generate.yml b/messages/v1/messages/template.generate.yml index e805b85..ce28f0d 100644 --- a/messages/v1/messages/template.generate.yml +++ b/messages/v1/messages/template.generate.yml @@ -11,8 +11,7 @@ parameters: type: String ref: Server.ServerName shortarg: s - description: | - Nom du serveur. + description: Nom du serveur. response: type: Template diff --git a/messages/v1/messages/user.role.server.create.yml b/messages/v1/messages/user.role.server.create.yml deleted file mode 100644 index be3eb04..0000000 --- a/messages/v1/messages/user.role.server.create.yml +++ /dev/null @@ -1,23 +0,0 @@ ---- -uri: user.role.server.create - -description: Crée des rôles d'accès aux URI serveur pour un utilisateur. - -pattern: rpc - -parameters: - user_login: - type: String - shortarg: u - description: Login de l'utilisateur. - ref: User.UserLogin - server_name: - type: String - shortarg: s - description: Valeur de l'attribut contrôlé. - ref: Server.ServerName - -response: - type: '[]Role' - description: Description des rôles créés. - diff --git a/messages/v1/types/deploy.yml b/messages/v1/types/deploy.yml new file mode 100644 index 0000000..8e3c581 --- /dev/null +++ b/messages/v1/types/deploy.yml @@ -0,0 +1,20 @@ +--- +title: Deploy +type: object +description: État de déploiement de la configuration. +properties: + server_id: + type: number + description: ID du serveur. + ref: Server.ServerID + server_name: + type: string + ref: Server.ServerName + description: Nom du server. + deployed: + type: boolean + description: État de déploiement. +required: + - server_id + - server_name + - deployed diff --git a/messages/v1/types/template.yml b/messages/v1/types/template.yml index 739f6da..6c856a9 100644 --- a/messages/v1/types/template.yml +++ b/messages/v1/types/template.yml @@ -3,12 +3,13 @@ title: Template type: object description: Les fichiers de configuration générés. properties: - server_id: - type: Number - description: Identifiant du serveur. + server_name: + type: String + description: Nom du serveur. + ref: Server.ServerName template_dir: type: String description: Nom du répertoire avec les fichiers de configuration générés. required: - - server_id + - server_name - template_dir diff --git a/src/risotto/config.py b/src/risotto/config.py index a56c7d4..2f08aef 100644 --- a/src/risotto/config.py +++ b/src/risotto/config.py @@ -1,13 +1,10 @@ MESSAGE_ROOT_PATH = 'messages' -DEBUG = True DATABASE_DIR = 'database' INTERNAL_USER = 'internal' CONFIGURATION_DIR = 'configurations' TEMPLATE_DIR = 'templates' TMP_DIR = 'tmp' ROUGAIL_DTD_PATH = '../rougail/data/creole.dtd' -POSTGRESQL_ADDRESS = '192.168.56.106' -POSTGRESQL_PORT = 5432 DEFAULT_USER = 'Anonymous' import os @@ -22,9 +19,10 @@ def get_config(): 'password': 'risotto', }, 'http_server': {'port': 8080, + #'default_user': "gnunux"}, 'default_user': DEFAULT_USER}, 'global': {'message_root_path': CURRENT_PATH.parents[2] / 'messages', - 'debug': DEBUG, + 'debug': True, 'internal_user': 'internal', 'check_role': True, 'rougail_dtd_path': '../rougail/data/creole.dtd', diff --git a/src/risotto/dispatcher.py b/src/risotto/dispatcher.py index 55bf14e..c3eff4f 100644 --- a/src/risotto/dispatcher.py +++ b/src/risotto/dispatcher.py @@ -7,7 +7,6 @@ from json import dumps, loads from .utils import _ from .error import CallError, NotAllowedError from .logger import log -from .config import DEBUG from .config import get_config from .context import Context from . import register @@ -193,7 +192,7 @@ class Dispatcher(register.RegisterDispatcher, CallDispatcher, PublishDispatcher) try: await subconfig.option(key).value.set(value) except AttributeError: - if DEBUG: + if get_config()['global']['debug']: print_exc() raise ValueError(_(f'unknown parameter in "{uri}": "{key}"')) # check mandatories options @@ -276,7 +275,7 @@ class Dispatcher(register.RegisterDispatcher, CallDispatcher, PublishDispatcher) check_role) except Exception as err: # if there is a problem with arguments, just send an error and do nothing - if DEBUG: + if get_config()['global']['debug']: print_exc() await log.error_msg(risotto_context, kwargs, err) if risotto_context.type == 'rpc': diff --git a/src/risotto/logger.py b/src/risotto/logger.py index 06f24fd..12f9f36 100644 --- a/src/risotto/logger.py +++ b/src/risotto/logger.py @@ -2,12 +2,11 @@ from typing import Dict, Any from json import dumps from .context import Context from .utils import _ -from .config import DEBUG +from .config import get_config class Logger: """ An object to manager log - FIXME should add event to a database """ async def insert(self, msg: str, @@ -24,15 +23,7 @@ class Logger: args.append(dumps(data)) 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: - await risotto_context.connection.fetch(sql, *args) + await risotto_context.connection.fetch(sql, *args) def _get_message_paths(self, risotto_context: Context): @@ -46,7 +37,6 @@ class Logger: else: paths_msg += f'sub-messages: ' paths_msg += ' > '.join(paths) - paths_msg += ':' return paths_msg async def error_msg(self, @@ -57,7 +47,6 @@ class Logger: """ send message when an error append """ paths_msg = self._get_message_paths(risotto_context) - # if DEBUG: print(_(f'{risotto_context.username}: ERROR: {error} ({paths_msg} with arguments "{arguments}": {msg})')) await self.insert(msg, paths_msg, @@ -75,14 +64,8 @@ class Logger: paths_msg = self._get_message_paths(risotto_context) else: paths_msg = '' - if DEBUG: - tmsg = _(f'{risotto_context.username}: INFO:{paths_msg}') - if arguments: - tmsg += _(f' with arguments "{arguments}"') - if msg: - tmsg += f' {msg}' - - print(tmsg) + if get_config()['global']['debug']: + print(_(f'{risotto_context.username}: INFO:{paths_msg}')) await self.insert(msg, paths_msg, risotto_context, @@ -92,7 +75,7 @@ class Logger: async def info(self, risotto_context, msg): - if DEBUG: + if get_config()['global']['debug']: print(msg) await self.insert(msg, None, diff --git a/src/risotto/services/config/config.py b/src/risotto/services/config/config.py index 7f0afad..e7a7044 100644 --- a/src/risotto/services/config/config.py +++ b/src/risotto/services/config/config.py @@ -409,10 +409,15 @@ class Risotto(Controller): @register('v1.config.configuration.server.deploy', 'v1.config.configuration.server.updated') async def deploy_configuration(self, - server_id: int) -> Dict: + risotto_context: Context, + server_name: str) -> Dict: """Copy values, permissions, permissives from config 'to deploy' to active config """ - # FIXME ? + server = await self.call('v1.server.describe', + risotto_context, + server_name=server_name) + server_id = server['server_id'] + # FIXME is server_to_deploy working? config = self.server[server_id]['server'] config_std = self.server[server_id]['server_to_deploy'] @@ -432,4 +437,5 @@ class Risotto(Controller): await config.property.importation(await config_std.property.exportation()) return {'server_id': server_id, + 'server_name': server_name, 'deployed': True} diff --git a/src/risotto/services/server/server.py b/src/risotto/services/server/server.py index 57111e9..c5c768e 100644 --- a/src/risotto/services/server/server.py +++ b/src/risotto/services/server/server.py @@ -38,10 +38,12 @@ class Risotto(Controller): server_name, server_description, servermodel['servermodel_id']) - await self.call('v1.user.role.server.create', + await self.call('v1.user.role.create', risotto_context, user_login=risotto_context.username, - server_name=server_name) + role_name='server_rw', + role_attribute='Server.ServerName', + role_attribute_value=server_name) return {'server_id': server_id, 'server_name': server_name, 'server_description': server_description, diff --git a/src/risotto/services/session/session.py b/src/risotto/services/session/session.py index ce6696a..c8def59 100644 --- a/src/risotto/services/session/session.py +++ b/src/risotto/services/session/session.py @@ -6,7 +6,6 @@ from tiramisu import Storage from ...http import register as register_http -from ...config import DEBUG from ...context import Context from ...utils import _ from .storage import storage_server, storage_servermodel @@ -77,7 +76,7 @@ class Risotto(Controller): 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'] + config = config_module.server[id]['server_to_deploy'] storage = self.get_storage('server') @@ -287,7 +286,7 @@ class Risotto(Controller): id_ = session['id'] config_module = dispatcher.get_service('config') if type == 'server': - config = config_module.server[id_]['server'] + config = config_module.server[id_]['server_to_deploy'] else: config = config_module.servermodel[id_] if save: diff --git a/src/risotto/services/template/template.py b/src/risotto/services/template/template.py index c6f0838..0502b62 100644 --- a/src/risotto/services/template/template.py +++ b/src/risotto/services/template/template.py @@ -28,6 +28,9 @@ class Risotto(Controller): servermodel_id = server['server_servermodel_id'] config_module = dispatcher.get_service('config') server = config_module.server[server_id] + export = await server['server'].value.exportation() + if not export[0]: + raise Exception(_(f'configuration for server "{server_name}" is empty, you should deploy it first')) config = meta = await server['server'].config.deepcopy(storage=self.storage) while True: try: @@ -54,5 +57,5 @@ class Risotto(Controller): tmp_dir, configurations_dir) - return {'server_id': server_id, + return {'server_name': server_name, 'template_dir': configurations_dir} diff --git a/src/risotto/services/uri/uri.py b/src/risotto/services/uri/uri.py index 27683b2..2904d34 100644 --- a/src/risotto/services/uri/uri.py +++ b/src/risotto/services/uri/uri.py @@ -24,7 +24,6 @@ class Risotto(Controller): 'v1.user.delete', 'v1.user.list', 'v1.user.role.create', - 'v1.user.role.server.create', 'v1.config.configuration.server.get', 'v1.user.role.list']: try: @@ -62,15 +61,26 @@ class Risotto(Controller): uri_name=uri) except: pass + for uri in ['v1.server.describe', + 'v1.config.configuration.server.get', + 'v1.config.configuration.server.deploy', + 'v1.session.server.start', + 'v1.template.generate']: + try: + await self._uri_role_join(risotto_context, + role_name='server_rw', + uri_name=uri) + except: + pass @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) + return await self._uri_role_join(risotto_context, + role_name, + uri_name) async def _uri_role_join(self, risotto_context: Context, role_name: str, @@ -100,7 +110,7 @@ class Risotto(Controller): async def uri_role_list(self, risotto_context: Context) -> List[Dict]: sql = ''' - SELECT RoleName as role_name, URI.URIName as uri + SELECT RoleName as role_name, URI.URIName as uri_name FROM RoleURI, URI WHERE RoleURI.URIId = URI.URIId ''' diff --git a/src/risotto/services/user/user.py b/src/risotto/services/user/user.py index 444e966..cab672a 100644 --- a/src/risotto/services/user/user.py +++ b/src/risotto/services/user/user.py @@ -104,15 +104,34 @@ class Risotto(Controller): user_login) if user_id is None: raise Exception(_(f'unable to find user {user_login}')) - sql = '''INSERT INTO UserRole(RoleUserId, RoleName, RoleAttribute, RoleAttributeValue) - VALUES($1,$2,$3,$4) - RETURNING RoleId - ''' - role_id = await risotto_context.connection.fetchval(sql, - user_id, - role_name, - role_attribute, - role_attribute_value) + if role_attribute == role_attribute_value == None: + sql = '''SELECT RoleId + FROM UserRole + WHERE RoleUserId = $1 AND RoleName = $2 + ''' + role_id = await risotto_context.connection.fetchval(sql, + user_id, + role_name) + else: + sql = '''SELECT RoleId + FROM UserRole + WHERE RoleUserId = $1 AND RoleName = $2 AND RoleAttribute = $3 AND RoleAttributeValue = $4 + ''' + role_id = await risotto_context.connection.fetchval(sql, + user_id, + role_name, + role_attribute, + role_attribute_value) + if role_id is None: + sql = '''INSERT INTO UserRole(RoleUserId, RoleName, RoleAttribute, RoleAttributeValue) + VALUES($1,$2,$3,$4) + RETURNING RoleId + ''' + role_id = await risotto_context.connection.fetchval(sql, + user_id, + role_name, + role_attribute, + role_attribute_value) return {'role_id': role_id, 'user_login': user_login, 'role_name': role_name, @@ -190,20 +209,3 @@ class Risotto(Controller): # if role is None: # raise Exception(_(f'unable to find role {role_name}')) # return dict(role) - - @register('v1.user.role.server.create') - async def user_role_server_create(self, - risotto_context: Context, - user_login: str, - server_name: str) -> Dict: - ret = [] - for uri in ['v1.server.describe', - 'v1.config.configuration.server.get', - 'v1.config.configuration.server.deploy', - 'v1.session.server.start', - 'v1.template.generate']: - ret.append(await self.call('v1.user.role.create', - risotto_context, - user_login=user_login, - role_name='server_rw')) - return ret