configuration support

This commit is contained in:
Emmanuel Garette 2019-12-02 10:30:29 +01:00
parent 21b8e1566c
commit 61f347aad6
6 changed files with 174 additions and 137 deletions

View File

@ -1,20 +1,22 @@
#!/usr/bin/env python3
"""Zephir-cmd-input script
"""
from sys import exit
from sys import exit, argv
from json import dumps
from traceback import print_exc
from cucchiaiata import Parser, config
from cucchiaiata import Parser, config, Configuration
from cucchiaiata.i18n import _
def main():
# if sys.argv[1] == 'config.session.server.configure' or \
# sys.argv[1] == 'config.session.servermodel.configure':
# configuration(sys.argv[1])
# else:
try:
parser = Parser()
print(parser.get())
if argv[1] in ['config.session.server.configure',
'config.session.servermodel.configure']:
Configuration().get()
else:
parser = Parser()
print(dumps(parser.get(),
indent=config.indent))
except Exception as err:
if config.debug:
print_exc()

View File

@ -1,4 +1,5 @@
from .parser import Parser
from .configuration import Configuration
from .config import config
__all__ = ('Parser', 'config')

68
src/cucchiaiata/common.py Normal file
View File

@ -0,0 +1,68 @@
from os.path import isfile
from requests import get, post
from json import dumps
from typing import Dict
from .config import config
from tiramisu_api import Config
if config.allow_insecure_https:
import warnings
from urllib3.exceptions import InsecureRequestWarning
warnings.simplefilter('ignore', InsecureRequestWarning)
class Common:
def __init__(self):
self.cucchiaiata_config = config
def get_token(self):
if isfile(self.cucchiaiata_config.token_file):
return open(self.cucchiaiata_config.token_file).read()
return ''
def get_error_from_http(self,
req):
try:
json = req.json()
err = json['error']['kwargs']['reason']
except:
err = req.text
return err
def remote_json_to_config(self,
url=None,
config_type=Config):
"retrieves the remote config from the distant api description"
if url is None:
url = self.cucchiaiata_config.remote_url
token = self.get_token()
headers = {'Authorization':'Bearer {}'.format(token)}
req = get(url,
headers=headers,
verify=False)
code = req.status_code
if code != 200:
err = self.get_error_from_http(req)
raise Exception('unable to load url ({}): {} ({})'.format(url,
err,
code))
json = req.json()
return config_type(json)
def send_data(message: str,
payload: Dict):
final_url = '{}/{}'.format(config.remote_url, message)
ret = post(final_url,
data=dumps(payload),
verify=config.allow_insecure_https)
if ret.status_code != 200:
raise Exception(ret.text)
response = ret.json()
if 'error' in response:
if 'reason' in response['error']['kwargs']:
raise Exception("{}".format(response['error']['kwargs']['reason']))
raise Exception('erreur inconnue')
return(response['response'])

View File

@ -33,6 +33,7 @@ version: {version}"""
self.remote_url = 'http://{}/api/{}'.format(self.url, self.version)
self.token_file = join(expanduser("~"), '.zephir-client.jwt.token')
self.indent = config.get('indent', 2)
self.allow_insecure_https = config.get('allow_insecure_https', False)
TO_JSON = {'config.session.server.get': ['content'],

View File

@ -0,0 +1,80 @@
from sys import argv, exit
from tiramisu_cmdline_parser import TiramisuCmdlineParser
from tiramisu_api import Config
from cucchiaiata.i18n import _
from .common import send_data, Common
class ConfigAPI(Config):
def send_data(self,
data):
for index, payload in enumerate(data['updates']):
payload['session_id'] = self.session_id
if isinstance(payload['value'], list):
payload['value_multi'] = payload['value']
del payload['value']
ret = send_data(self.message,
payload)
if ret['status'] == 'error':
msg = _("cannot modify variable {} : {}").format(payload['name'],ret['message'])
raise Exception(msg)
self.updates = []
class Configuration(Common):
def configure_server(self):
if self.message == 'config.session.server.configure':
type = 'server'
else:
type = 'servermodel'
url = '{}/config/{}/{}'.format(self.cucchiaiata_config.remote_url,
type,
self.session_id)
tconfig = self.remote_json_to_config(url,
ConfigAPI)
tconfig.message = self.message
tconfig.session_id = self.session_id
return tconfig
def get_parameters(self):
parameters = argv.copy()
# get and remove config.session.xxxxx.configure
self.message = parameters.pop(1)
# get and remove commandline name
self.prog = parameters.pop(0)
# get and remove sessionid
try:
index = parameters.index('-s')
except ValueError:
try:
index = parameters.index('--sessionid')
except ValueError:
tiramisu_config = self.remote_json_to_config(ConfigAPI)
parser = TiramisuCmdlineParser(tiramisu_config,
self.prog,
unrestraint=True,
fullpath=True)
parser.print_help()
exit(1)
parameters.pop(index)
self.session_id = parameters.pop(index)
return parameters
def get(self):
parameters = self.get_parameters()
tiramisu_config = self.configure_server()
parser = TiramisuCmdlineParser(tiramisu_config,
self.prog,
unrestraint=True,
fullpath=True)
parser.parse_args(parameters,
valid_mandatory=False)
tiramisu_config.send()

View File

@ -1,20 +1,12 @@
"""Zephir Client library
"""
from os.path import isfile
from requests import get, post
from json import dumps, loads
from typing import Dict
# import warnings
# from urllib3.exceptions import InsecureRequestWarning
from json import loads
from tiramisu_cmdline_parser import TiramisuCmdlineParser
from argparse import RawDescriptionHelpFormatter
from tiramisu_api import Config
from .config import config, TO_JSON
# warnings.simplefilter('ignore', InsecureRequestWarning)
from .config import TO_JSON
from .common import Common, send_data
class CucchiaiataParser(TiramisuCmdlineParser):
@ -24,14 +16,11 @@ class CucchiaiataParser(TiramisuCmdlineParser):
return super().print_help(*args, **kwargs)
class Parser:
class Parser(Common):
def __init__(self):
# retrieve config's option
self.cucchiaiata_config = config
self.remote_url = self.cucchiaiata_config.remote_url
self.remote_config = self.remote_json_to_config()
super().__init__()
# build a tiramisu parser and parse argument
self.remote_config = self.remote_json_to_config()
parser = CucchiaiataParser(self.remote_config,
fullpath=False,
remove_empty_od=True,
@ -40,12 +29,17 @@ class Parser:
parser.parse_args()
def get(self):
def _to_json(res):
for key, value in res.items():
if key in TO_JSON[message]:
res[key] = loads(value)
# get current message
message = self.remote_config.option('message').value.get()
payload = self.get_payload(message)
# send message
result = self.send_data(message,
payload)
result = send_data(message,
payload)
# convert some results (file) to json
if message in TO_JSON:
@ -55,53 +49,7 @@ class Parser:
else:
_to_json(result)
return dumps(result, indent=config.indent)
def remote_json_to_config(self,
headers=None,
config_type=Config):
"retrieves the remote config from the distant api description"
req = get(self.remote_url,
headers=headers,
verify=False)
code = req.status_code
if code != 200:
err = self.get_error_from_http(req)
raise Exception('unable to load url ({}): {} ({})'.format(self.remote_url,
err,
code))
json = req.json()
return config_type(json)
def send_data(self,
message: str,
payload: Dict):
# get stored token if available
if isfile(self.cucchiaiata_config.token_file):
token = open(self.cucchiaiata_config.token_file).read()
else:
token = ''
final_url = '{}/{}'.format(self.remote_url, message)
headers = {'Authorization':'Bearer {}'.format(token)}
ret = post(final_url,
data=dumps(payload),
headers=headers,
# FIXME
verify=False)
if ret.status_code != 200:
raise Exception(ret.text)
response = ret.json()
if 'error' in response:
if 'reason' in response['error']['kwargs']:
raise Exception("{}".format(response['error']['kwargs']['reason']))
raise Exception('erreur inconnue')
else:
return(response['response'])
def _to_json(self, res):
for key, value in res.items():
if key in TO_JSON[message]:
res[key] = loads(value)
return result
def get_payload(self,
message: str):
@ -111,66 +59,3 @@ class Parser:
if not option.owner.isdefault() and not option.option.issymlinkoption():
payload[option.option.name()] = option.value.get()
return payload
def get_error_from_http(self,
req):
try:
json = req.json()
err = json['error']['kwargs']['reason']
except:
err = req.text
return err
def configure_server(server, session_id, version, message, reporter=None):
url = 'https://{}/config/{}/api'.format(server, session_id)
token = open(config.token_file).read()
headers = {'Authorization':'Bearer {}'.format(token)}
tconfig = remote_json_to_config(url, headers, ConfigConfigurationAPI)
tconfig.version = version
tconfig.message = message
tconfig.url = server
tconfig.session_id = session_id
tconfig.reporter = reporter
return tconfig
def configuration(config,
session_id,
configure):
parameters = sys.argv.copy()
# get sessionid index session_id
try:
index = parameters.index('-s')
except ValueError:
try:
index = parameters.index('--sessionid')
except ValueError:
remote_config = remote_json_to_config(config.remote_url)
parser = cmdline_factory(remote_config)
parser.print_help()
sys.exit(1)
parameters.pop(index)
session_id = parameters.pop(index)
# remove config.session.server.configure
parameters.pop(1)
# remove commandline
prog = parameters.pop(0)
try:
conf = configure_server(config.url,
session_id,
config.version,
configure)
parser = TiramisuCmdlineParser(conf,
prog,
unrestraint=True,
fullpath=True)
parser.parse_args(parameters,
valid_mandatory=False)
config.send()
except Exception as err:
if config.debug:
print_exc()
print(_("Error: {}").format(err))
sys.exit(1)