Compare commits

..

2 Commits

Author SHA1 Message Date
Benjamin Bohard f4d3430885 Test d’un service utilisant une base de données. 2019-12-04 16:00:29 +01:00
Emmanuel Garette a152654b5b Vocabulary 2019-12-04 15:53:58 +01:00
7 changed files with 117 additions and 10 deletions

View File

@ -18,3 +18,14 @@ echo "127.0.0.1 auth.example.com manager.example.com test1.example.com test2.exa
docker run -d --add-host reload.example.com:127.0.0.1 -p 80:80 coudot/lemonldap-ng docker run -d --add-host reload.example.com:127.0.0.1 -p 80:80 coudot/lemonldap-ng
``` ```
Démarrer un serveur postgresql de test
```
podman pull docker.io/library/postgres:11-alpine
podman run -dt -p 5432:5432 postgres:11-alpine
psql -U postgres -h localhost -c "CREATE ROLE risotto WITH LOGIN PASSWORD 'risotto';"
psql -U postgres -h localhost -c "CREATE DATABASE risotto;"
psql -U postgres -h localhost -c "GRANT ALL ON DATABASE risotto TO risotto;"
```

View File

@ -0,0 +1,27 @@
uri: servermodel.init
description: |
Initialise la table pour les modèles de serveur.
sampleuse: |
zephir-client servermodel.init
pattern: rpc
public: true
domain: servermodel-domain
response:
type: ReturnStatus
description: Liste des modèles de serveur disponibles.
errors:
- uri: servermodel.list.error.database_engine_not_available
related:
- servermodel.describe
- servermodel.create
- servermodel.update
- servermodel.delete
- servermodel.event

View File

@ -0,0 +1,14 @@
---
title: ReturnStatus
type: object
description: Résultat dune commande.
properties:
retcode:
type: number
description: Code de retour de la commande.
return:
type: string
description: Retour de la commande.
required:
- retcode
- return

View File

@ -8,3 +8,19 @@ 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 = 'localhost'
POSTGRESQL_PORT = 5432
def get_config():
return {'database': {'host': 'localhost',
'port': 5432,
'dbname': 'risotto',
'user': 'risotto',
'password': 'risotto',
},
'http_server': {'port': 8080},
'global': {'message_root_path': 'messages',
'debug': False,
'internal_user': 'internal',
'rougail_dtd_path': '../rougail/data/creole.dtd'}
}

View File

@ -7,8 +7,10 @@ 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 DEBUG
from .config import get_config
from .context import Context from .context import Context
from . import register from . import register
import asyncpg
class CallDispatcher: class CallDispatcher:
@ -35,6 +37,7 @@ class CallDispatcher:
raise CallError(str(err)) raise CallError(str(err))
else: else:
if not isinstance(returns, dict): if not isinstance(returns, dict):
log.error_msg(risotto_context, kwargs, returns)
err = _(f'function {module_name}.{function_name} has to return a dict') err = _(f'function {module_name}.{function_name} has to return a dict')
log.error_msg(risotto_context, kwargs, err) log.error_msg(risotto_context, kwargs, err)
raise CallError(str(err)) raise CallError(str(err))
@ -94,11 +97,19 @@ class CallDispatcher:
risotto_context.function = obj['function'] risotto_context.function = obj['function']
if obj['risotto_context']: if obj['risotto_context']:
kw['risotto_context'] = risotto_context kw['risotto_context'] = risotto_context
if 'database' in obj and obj['database']:
db_conf = get_config().get('database')
pool = await asyncpg.create_pool(database=db_conf.get('dbname'), user=db_conf.get('user'))
async with pool.acquire() as connection:
risotto_context.connection = connection
async with connection.transaction():
returns = await risotto_context.function(self.injected_self[obj['module']], **kw)
else:
returns = await risotto_context.function(self.injected_self[obj['module']], **kw) returns = await risotto_context.function(self.injected_self[obj['module']], **kw)
except CallError as err: except CallError as err:
raise err raise err
except Exception as err: except Exception as err:
if DEBUG: if get_config().get('global').get('debug'):
print_exc() print_exc()
log.error_msg(risotto_context, log.error_msg(risotto_context,
kwargs, kwargs,

View File

@ -9,7 +9,8 @@ from .config import INTERNAL_USER
def register(uris: str, def register(uris: str,
notification: str=undefined): notification: str=undefined,
database: bool=False):
""" Decorator to register function to the dispatcher """ Decorator to register function to the dispatcher
""" """
if not isinstance(uris, list): if not isinstance(uris, list):
@ -21,6 +22,7 @@ def register(uris: str,
dispatcher.set_function(version, dispatcher.set_function(version,
message, message,
notification, notification,
database,
function) function)
return decorator return decorator
@ -129,6 +131,7 @@ class RegisterDispatcher:
version: str, version: str,
message: str, message: str,
notification: str, notification: str,
database: bool,
function: Callable): function: Callable):
""" register a function to an URI """ register a function to an URI
URI is a message URI is a message
@ -180,6 +183,7 @@ class RegisterDispatcher:
function, function,
function_args, function_args,
inject_risotto_context, inject_risotto_context,
database,
notification) notification)
def register_rpc(self, def register_rpc(self,
@ -189,11 +193,13 @@ class RegisterDispatcher:
function: Callable, function: Callable,
function_args: list, function_args: list,
inject_risotto_context: bool, inject_risotto_context: bool,
database: bool,
notification: Optional[str]): notification: Optional[str]):
self.messages[version][message]['module'] = module_name self.messages[version][message]['module'] = module_name
self.messages[version][message]['function'] = function self.messages[version][message]['function'] = function
self.messages[version][message]['arguments'] = function_args self.messages[version][message]['arguments'] = function_args
self.messages[version][message]['risotto_context'] = inject_risotto_context self.messages[version][message]['risotto_context'] = inject_risotto_context
self.messages[version][message]['database'] = database
if notification: if notification:
self.messages[version][message]['notification'] = notification self.messages[version][message]['notification'] = notification
@ -204,6 +210,7 @@ class RegisterDispatcher:
function: Callable, function: Callable,
function_args: list, function_args: list,
inject_risotto_context: bool, inject_risotto_context: bool,
database: bool,
notification: Optional[str]): notification: Optional[str]):
if 'functions' not in self.messages[version][message]: if 'functions' not in self.messages[version][message]:
self.messages[version][message]['functions'] = [] self.messages[version][message]['functions'] = []

View File

@ -1,14 +1,35 @@
from ...controller import Controller from ...controller import Controller
from ...register import register from ...register import register
sql_init = """
-- Création de la table ServerModel
CREATE TABLE ServerModel (
ServerModelId SERIAL PRIMARY KEY,
ServerModelName VARCHAR(255) NOT NULL,
ServerModelDescription VARCHAR(255) NOT NULL,
ServerModelSourceId INTEGER NOT NULL,
ServerModelParentId INTEGER,
ServerModelSubReleaseId INTEGER NOT NULL,
ServerModelSubReleaseName VARCHAR(255) NOT NULL,
UNIQUE (ServerModelName, ServerModelSubReleaseId)
);
"""
class Risotto(Controller): class Risotto(Controller):
@register('v1.servermodel.list', None) @register('v1.servermodel.init', None, database=True)
async def servermodel_list(self, sourceid): async def servermodel_init(self, risotto_context):
return [{'servermodelid': 1, result = await risotto_context.connection.execute(sql_init)
'servermodelname': 'name', return {'retcode': 0, 'return': result}
'subreleasename': 'name',
'sourceid': 1,
'servermodeldescription': 'description'}] @register('v1.servermodel.list', None, database=True)
async def servermodel_list(self, risotto_context, sourceid):
sql = '''
SELECT * FROM ServerModel
'''
servermodels = await risotto_context.connection.fetch(sql)
return [dict(r) for r in servermodels]
@register('v1.servermodel.describe', None) @register('v1.servermodel.describe', None)
async def servermodel_describe(self, inheritance, creolefuncs, servermodelid, schema, conffiles, resolvdepends, probes): async def servermodel_describe(self, inheritance, creolefuncs, servermodelid, schema, conffiles, resolvdepends, probes):