add role server_rw + role example + deploy

This commit is contained in:
Emmanuel Garette 2020-01-15 09:15:15 +01:00
parent cb2dbe135e
commit 02c38589d4
16 changed files with 118 additions and 104 deletions

View File

@ -55,6 +55,7 @@ drop table log; drop table userrole; drop table release; drop table source; drop
# Configure the server # Configure the server
./script/cucchiaiata session.server.start -s test ./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_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.configure -s $S --creole.reseau.unbound_domain_name test.cadoles.com
./script/cucchiaiata session.server.filter -s $S -n unbound ./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 ./script/cucchiaiata session.server.stop -s $S -a
# Generate configuration # Generate configuration
./script/cucchiaiata config.configuration.server.deploy -s test
./script/cucchiaiata template.generate -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

View File

@ -1,13 +1,17 @@
--- ---
uri: config.configuration.server.deploy uri: config.configuration.server.deploy
description: | description: Déployer la configuration d'un serveur.
Déployer la configuration d'un serveur.
pattern: event pattern: rpc
parameters: parameters:
server_id: server_name:
type: Number type: String
description: | ref: Server.ServerName
Identifiant du serveur. shortarg: s
description: Nom du serveur.
response:
type: Deploy
description: La configuration du serveur est déployée.

View File

@ -11,6 +11,11 @@ parameters:
type: Number type: Number
description: | description: |
Identifiant du serveur. Identifiant du serveur.
server_name:
type: String
ref: Server.ServerName
shortarg: s
description: Nom du serveur.
deployed: deployed:
type: Boolean type: Boolean
description: Configuration de type déployée. description: Configuration de type déployée.

View File

@ -11,8 +11,7 @@ parameters:
type: String type: String
ref: Server.ServerName ref: Server.ServerName
shortarg: s shortarg: s
description: | description: Nom du serveur.
Nom du serveur.
response: response:
type: Template type: Template

View File

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

View File

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

View File

@ -3,12 +3,13 @@ title: Template
type: object type: object
description: Les fichiers de configuration générés. description: Les fichiers de configuration générés.
properties: properties:
server_id: server_name:
type: Number type: String
description: Identifiant du serveur. description: Nom du serveur.
ref: Server.ServerName
template_dir: template_dir:
type: String type: String
description: Nom du répertoire avec les fichiers de configuration générés. description: Nom du répertoire avec les fichiers de configuration générés.
required: required:
- server_id - server_name
- template_dir - template_dir

View File

@ -1,13 +1,10 @@
MESSAGE_ROOT_PATH = 'messages' MESSAGE_ROOT_PATH = 'messages'
DEBUG = True
DATABASE_DIR = 'database' DATABASE_DIR = 'database'
INTERNAL_USER = 'internal' INTERNAL_USER = 'internal'
CONFIGURATION_DIR = 'configurations' CONFIGURATION_DIR = 'configurations'
TEMPLATE_DIR = 'templates' TEMPLATE_DIR = 'templates'
TMP_DIR = 'tmp' TMP_DIR = 'tmp'
ROUGAIL_DTD_PATH = '../rougail/data/creole.dtd' ROUGAIL_DTD_PATH = '../rougail/data/creole.dtd'
POSTGRESQL_ADDRESS = '192.168.56.106'
POSTGRESQL_PORT = 5432
DEFAULT_USER = 'Anonymous' DEFAULT_USER = 'Anonymous'
import os import os
@ -22,9 +19,10 @@ def get_config():
'password': 'risotto', 'password': 'risotto',
}, },
'http_server': {'port': 8080, 'http_server': {'port': 8080,
#'default_user': "gnunux"},
'default_user': DEFAULT_USER}, 'default_user': DEFAULT_USER},
'global': {'message_root_path': CURRENT_PATH.parents[2] / 'messages', 'global': {'message_root_path': CURRENT_PATH.parents[2] / 'messages',
'debug': DEBUG, 'debug': True,
'internal_user': 'internal', 'internal_user': 'internal',
'check_role': True, 'check_role': True,
'rougail_dtd_path': '../rougail/data/creole.dtd', 'rougail_dtd_path': '../rougail/data/creole.dtd',

View File

@ -7,7 +7,6 @@ from json import dumps, loads
from .utils import _ from .utils import _
from .error import CallError, NotAllowedError from .error import CallError, NotAllowedError
from .logger import log from .logger import log
from .config import DEBUG
from .config import get_config from .config import get_config
from .context import Context from .context import Context
from . import register from . import register
@ -193,7 +192,7 @@ class Dispatcher(register.RegisterDispatcher, CallDispatcher, PublishDispatcher)
try: try:
await subconfig.option(key).value.set(value) await subconfig.option(key).value.set(value)
except AttributeError: except AttributeError:
if DEBUG: if get_config()['global']['debug']:
print_exc() print_exc()
raise ValueError(_(f'unknown parameter in "{uri}": "{key}"')) raise ValueError(_(f'unknown parameter in "{uri}": "{key}"'))
# check mandatories options # check mandatories options
@ -276,7 +275,7 @@ class Dispatcher(register.RegisterDispatcher, CallDispatcher, PublishDispatcher)
check_role) check_role)
except Exception as err: except Exception as err:
# if there is a problem with arguments, just send an error and do nothing # if there is a problem with arguments, just send an error and do nothing
if DEBUG: if get_config()['global']['debug']:
print_exc() print_exc()
await log.error_msg(risotto_context, kwargs, err) await log.error_msg(risotto_context, kwargs, err)
if risotto_context.type == 'rpc': if risotto_context.type == 'rpc':

View File

@ -2,12 +2,11 @@ from typing import Dict, Any
from json import dumps from json import dumps
from .context import Context from .context import Context
from .utils import _ from .utils import _
from .config import DEBUG from .config import get_config
class Logger: class Logger:
""" An object to manager log """ An object to manager log
FIXME should add event to a database
""" """
async def insert(self, async def insert(self,
msg: str, msg: str,
@ -24,15 +23,7 @@ class Logger:
args.append(dumps(data)) args.append(dumps(data))
sql = insert + ') ' + values + ')' sql = insert + ') ' + values + ')'
print(sql, args) await risotto_context.connection.fetch(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)
def _get_message_paths(self, def _get_message_paths(self,
risotto_context: Context): risotto_context: Context):
@ -46,7 +37,6 @@ class Logger:
else: else:
paths_msg += f'sub-messages: ' paths_msg += f'sub-messages: '
paths_msg += ' > '.join(paths) paths_msg += ' > '.join(paths)
paths_msg += ':'
return paths_msg return paths_msg
async def error_msg(self, async def error_msg(self,
@ -57,7 +47,6 @@ class Logger:
""" send message when an error append """ send message when an error append
""" """
paths_msg = self._get_message_paths(risotto_context) paths_msg = self._get_message_paths(risotto_context)
# if DEBUG:
print(_(f'{risotto_context.username}: ERROR: {error} ({paths_msg} with arguments "{arguments}": {msg})')) print(_(f'{risotto_context.username}: ERROR: {error} ({paths_msg} with arguments "{arguments}": {msg})'))
await self.insert(msg, await self.insert(msg,
paths_msg, paths_msg,
@ -75,14 +64,8 @@ class Logger:
paths_msg = self._get_message_paths(risotto_context) paths_msg = self._get_message_paths(risotto_context)
else: else:
paths_msg = '' paths_msg = ''
if DEBUG: if get_config()['global']['debug']:
tmsg = _(f'{risotto_context.username}: INFO:{paths_msg}') print(_(f'{risotto_context.username}: INFO:{paths_msg}'))
if arguments:
tmsg += _(f' with arguments "{arguments}"')
if msg:
tmsg += f' {msg}'
print(tmsg)
await self.insert(msg, await self.insert(msg,
paths_msg, paths_msg,
risotto_context, risotto_context,
@ -92,7 +75,7 @@ class Logger:
async def info(self, async def info(self,
risotto_context, risotto_context,
msg): msg):
if DEBUG: if get_config()['global']['debug']:
print(msg) print(msg)
await self.insert(msg, await self.insert(msg,
None, None,

View File

@ -409,10 +409,15 @@ class Risotto(Controller):
@register('v1.config.configuration.server.deploy', 'v1.config.configuration.server.updated') @register('v1.config.configuration.server.deploy', 'v1.config.configuration.server.updated')
async def deploy_configuration(self, 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 """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 = self.server[server_id]['server']
config_std = self.server[server_id]['server_to_deploy'] 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()) await config.property.importation(await config_std.property.exportation())
return {'server_id': server_id, return {'server_id': server_id,
'server_name': server_name,
'deployed': True} 'deployed': True}

View File

@ -38,10 +38,12 @@ class Risotto(Controller):
server_name, server_name,
server_description, server_description,
servermodel['servermodel_id']) servermodel['servermodel_id'])
await self.call('v1.user.role.server.create', await self.call('v1.user.role.create',
risotto_context, risotto_context,
user_login=risotto_context.username, 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, return {'server_id': server_id,
'server_name': server_name, 'server_name': server_name,
'server_description': server_description, 'server_description': server_description,

View File

@ -6,7 +6,6 @@ from tiramisu import Storage
from ...http import register as register_http from ...http import register as register_http
from ...config import DEBUG
from ...context import Context from ...context import Context
from ...utils import _ from ...utils import _
from .storage import storage_server, storage_servermodel 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: if not server or server['server_id'] not in config_module.server:
raise Exception(_(f'cannot find server with name {server_name}')) raise Exception(_(f'cannot find server with name {server_name}'))
id = server['server_id'] id = server['server_id']
config = config_module.server[id]['server'] config = config_module.server[id]['server_to_deploy']
storage = self.get_storage('server') storage = self.get_storage('server')
@ -287,7 +286,7 @@ class Risotto(Controller):
id_ = session['id'] id_ = session['id']
config_module = dispatcher.get_service('config') config_module = dispatcher.get_service('config')
if type == 'server': if type == 'server':
config = config_module.server[id_]['server'] config = config_module.server[id_]['server_to_deploy']
else: else:
config = config_module.servermodel[id_] config = config_module.servermodel[id_]
if save: if save:

View File

@ -28,6 +28,9 @@ class Risotto(Controller):
servermodel_id = server['server_servermodel_id'] servermodel_id = server['server_servermodel_id']
config_module = dispatcher.get_service('config') config_module = dispatcher.get_service('config')
server = config_module.server[server_id] 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) config = meta = await server['server'].config.deepcopy(storage=self.storage)
while True: while True:
try: try:
@ -54,5 +57,5 @@ class Risotto(Controller):
tmp_dir, tmp_dir,
configurations_dir) configurations_dir)
return {'server_id': server_id, return {'server_name': server_name,
'template_dir': configurations_dir} 'template_dir': configurations_dir}

View File

@ -24,7 +24,6 @@ class Risotto(Controller):
'v1.user.delete', 'v1.user.delete',
'v1.user.list', 'v1.user.list',
'v1.user.role.create', 'v1.user.role.create',
'v1.user.role.server.create',
'v1.config.configuration.server.get', 'v1.config.configuration.server.get',
'v1.user.role.list']: 'v1.user.role.list']:
try: try:
@ -62,15 +61,26 @@ class Risotto(Controller):
uri_name=uri) uri_name=uri)
except: except:
pass 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') @register('v1.uri.role.join')
async def uri_role_join(self, async def uri_role_join(self,
risotto_context: Context, risotto_context: Context,
role_name: str, role_name: str,
uri_name: str) -> Dict: uri_name: str) -> Dict:
await self._uri_role_join(risotto_context, return await self._uri_role_join(risotto_context,
role_name, role_name,
uri_name) uri_name)
async def _uri_role_join(self, async def _uri_role_join(self,
risotto_context: Context, risotto_context: Context,
role_name: str, role_name: str,
@ -100,7 +110,7 @@ class Risotto(Controller):
async def uri_role_list(self, async def uri_role_list(self,
risotto_context: Context) -> List[Dict]: risotto_context: Context) -> List[Dict]:
sql = ''' sql = '''
SELECT RoleName as role_name, URI.URIName as uri SELECT RoleName as role_name, URI.URIName as uri_name
FROM RoleURI, URI FROM RoleURI, URI
WHERE RoleURI.URIId = URI.URIId WHERE RoleURI.URIId = URI.URIId
''' '''

View File

@ -104,15 +104,34 @@ class Risotto(Controller):
user_login) user_login)
if user_id is None: if user_id is None:
raise Exception(_(f'unable to find user {user_login}')) raise Exception(_(f'unable to find user {user_login}'))
sql = '''INSERT INTO UserRole(RoleUserId, RoleName, RoleAttribute, RoleAttributeValue) if role_attribute == role_attribute_value == None:
VALUES($1,$2,$3,$4) sql = '''SELECT RoleId
RETURNING RoleId FROM UserRole
''' WHERE RoleUserId = $1 AND RoleName = $2
role_id = await risotto_context.connection.fetchval(sql, '''
user_id, role_id = await risotto_context.connection.fetchval(sql,
role_name, user_id,
role_attribute, role_name)
role_attribute_value) 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, return {'role_id': role_id,
'user_login': user_login, 'user_login': user_login,
'role_name': role_name, 'role_name': role_name,
@ -190,20 +209,3 @@ class Risotto(Controller):
# if role is None: # if role is None:
# raise Exception(_(f'unable to find role {role_name}')) # raise Exception(_(f'unable to find role {role_name}'))
# return dict(role) # 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