pre-commit, black, isort
This commit is contained in:
parent
d93bdf1b46
commit
40132984fd
|
|
@ -5,18 +5,12 @@
|
|||
{
|
||||
"name": "server configuration environment files",
|
||||
"version": "13.0.2.0.0",
|
||||
"depends": [
|
||||
"base",
|
||||
"base_sparse_field",
|
||||
],
|
||||
"depends": ["base", "base_sparse_field"],
|
||||
"author": "Camptocamp,Odoo Community Association (OCA)",
|
||||
"summary": "move some configurations out of the database",
|
||||
"website": "http://github.com/OCA/server-env",
|
||||
"license": "GPL-3 or any later version",
|
||||
"category": "Tools",
|
||||
"data": [
|
||||
'security/res_groups.xml',
|
||||
'serv_config.xml',
|
||||
],
|
||||
'installable': True,
|
||||
"data": ["security/res_groups.xml", "serv_config.xml"],
|
||||
"installable": True,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
# License GPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import logging
|
||||
|
||||
from functools import partialmethod
|
||||
|
||||
from lxml import etree
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
from ..server_env import serv_config
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
|
@ -96,19 +96,20 @@ class ServerEnvMixin(models.AbstractModel):
|
|||
``keychain.backend``.
|
||||
|
||||
"""
|
||||
_name = 'server.env.mixin'
|
||||
_description = 'Mixin to add server environment in existing models'
|
||||
|
||||
_name = "server.env.mixin"
|
||||
_description = "Mixin to add server environment in existing models"
|
||||
|
||||
server_env_defaults = fields.Serialized()
|
||||
|
||||
_server_env_getter_mapping = {
|
||||
'integer': 'getint',
|
||||
'float': 'getfloat',
|
||||
'monetary': 'getfloat',
|
||||
'boolean': 'getboolean',
|
||||
'char': 'get',
|
||||
'selection': 'get',
|
||||
'text': 'get',
|
||||
"integer": "getint",
|
||||
"float": "getfloat",
|
||||
"monetary": "getfloat",
|
||||
"boolean": "getboolean",
|
||||
"char": "get",
|
||||
"selection": "get",
|
||||
"text": "get",
|
||||
}
|
||||
|
||||
@property
|
||||
|
|
@ -180,16 +181,13 @@ class ServerEnvMixin(models.AbstractModel):
|
|||
# _server_env_has_key_defined so we are sure that the value is
|
||||
# either in the global or the record config
|
||||
getter = getattr(serv_config, config_getter)
|
||||
if (section_name in serv_config
|
||||
and field_name in serv_config[section_name]):
|
||||
if section_name in serv_config and field_name in serv_config[section_name]:
|
||||
value = getter(section_name, field_name)
|
||||
else:
|
||||
value = getter(global_section_name, field_name)
|
||||
except Exception:
|
||||
_logger.exception(
|
||||
"error trying to read field %s in section %s",
|
||||
field_name,
|
||||
section_name,
|
||||
"error trying to read field %s in section %s", field_name, section_name
|
||||
)
|
||||
return False
|
||||
return value
|
||||
|
|
@ -203,34 +201,31 @@ class ServerEnvMixin(models.AbstractModel):
|
|||
and field_name in serv_config[global_section_name]
|
||||
)
|
||||
has_config = (
|
||||
section_name in serv_config
|
||||
and field_name in serv_config[section_name]
|
||||
section_name in serv_config and field_name in serv_config[section_name]
|
||||
)
|
||||
return has_global_config or has_config
|
||||
|
||||
def _compute_server_env_from_config(self, field_name, options):
|
||||
getter_name = options.get('getter') if options else None
|
||||
getter_name = options.get("getter") if options else None
|
||||
if not getter_name:
|
||||
field_type = self._fields[field_name].type
|
||||
getter_name = self._server_env_getter_mapping.get(field_type)
|
||||
if not getter_name:
|
||||
# if you get this message and the field is working as expected,
|
||||
# you may want to add the type in _server_env_getter_mapping
|
||||
_logger.warning('server.env.mixin is used on a field of type %s, '
|
||||
'which may not be supported properly')
|
||||
getter_name = 'get'
|
||||
value = self._server_env_read_from_config(
|
||||
field_name, getter_name
|
||||
)
|
||||
_logger.warning(
|
||||
"server.env.mixin is used on a field of type %s, "
|
||||
"which may not be supported properly"
|
||||
)
|
||||
getter_name = "get"
|
||||
value = self._server_env_read_from_config(field_name, getter_name)
|
||||
self[field_name] = value
|
||||
|
||||
def _compute_server_env_from_default(self, field_name, options):
|
||||
if options and options.get('compute_default'):
|
||||
getattr(self, options['compute_default'])()
|
||||
if options and options.get("compute_default"):
|
||||
getattr(self, options["compute_default"])()
|
||||
else:
|
||||
default_field = self._server_env_default_fieldname(
|
||||
field_name
|
||||
)
|
||||
default_field = self._server_env_default_fieldname(field_name)
|
||||
if default_field:
|
||||
self[field_name] = self[default_field]
|
||||
else:
|
||||
|
|
@ -248,9 +243,7 @@ class ServerEnvMixin(models.AbstractModel):
|
|||
record._compute_server_env_from_config(field_name, options)
|
||||
|
||||
else:
|
||||
record._compute_server_env_from_default(
|
||||
field_name, options
|
||||
)
|
||||
record._compute_server_env_from_default(field_name, options)
|
||||
|
||||
def _inverse_server_env(self, field_name):
|
||||
options = self._server_env_fields[field_name]
|
||||
|
|
@ -262,8 +255,8 @@ class ServerEnvMixin(models.AbstractModel):
|
|||
# we update the default value in database
|
||||
|
||||
if record[is_editable_field]:
|
||||
if options and options.get('inverse_default'):
|
||||
getattr(record, options['inverse_default'])()
|
||||
if options and options.get("inverse_default"):
|
||||
getattr(record, options["inverse_default"])()
|
||||
elif default_field:
|
||||
record[default_field] = record[field_name]
|
||||
|
||||
|
|
@ -278,12 +271,8 @@ class ServerEnvMixin(models.AbstractModel):
|
|||
# in ``_inverse_server_env`` it would reset the value of the field
|
||||
for record in self:
|
||||
for field_name in self._server_env_fields:
|
||||
is_editable_field = self._server_env_is_editable_fieldname(
|
||||
field_name
|
||||
)
|
||||
is_editable = not record._server_env_has_key_defined(
|
||||
field_name
|
||||
)
|
||||
is_editable_field = self._server_env_is_editable_fieldname(field_name)
|
||||
is_editable = not record._server_env_has_key_defined(field_name)
|
||||
record[is_editable_field] = is_editable
|
||||
|
||||
def _server_env_view_set_readonly(self, view_arch):
|
||||
|
|
@ -293,37 +282,32 @@ class ServerEnvMixin(models.AbstractModel):
|
|||
for elem in view_arch.findall(field_xpath % field):
|
||||
# set env-computed fields to readonly if the configuration
|
||||
# files have a key set for this field
|
||||
elem.set('attrs',
|
||||
str({'readonly': [(is_editable_field, '=', False)]}))
|
||||
elem.set("attrs", str({"readonly": [(is_editable_field, "=", False)]}))
|
||||
if not view_arch.findall(field_xpath % is_editable_field):
|
||||
# add the _is_editable fields in the view for the 'attrs'
|
||||
# domain
|
||||
view_arch.append(
|
||||
etree.Element(
|
||||
'field',
|
||||
name=is_editable_field,
|
||||
invisible="1"
|
||||
)
|
||||
etree.Element("field", name=is_editable_field, invisible="1")
|
||||
)
|
||||
return view_arch
|
||||
|
||||
def _fields_view_get(self, view_id=None, view_type='form', toolbar=False,
|
||||
submenu=False):
|
||||
def _fields_view_get(
|
||||
self, view_id=None, view_type="form", toolbar=False, submenu=False
|
||||
):
|
||||
view_data = super()._fields_view_get(
|
||||
view_id=view_id, view_type=view_type,
|
||||
toolbar=toolbar, submenu=submenu
|
||||
view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu
|
||||
)
|
||||
view_arch = etree.fromstring(view_data['arch'].encode('utf-8'))
|
||||
view_arch = etree.fromstring(view_data["arch"].encode("utf-8"))
|
||||
view_arch = self._server_env_view_set_readonly(view_arch)
|
||||
view_data['arch'] = etree.tostring(view_arch, encoding='unicode')
|
||||
view_data["arch"] = etree.tostring(view_arch, encoding="unicode")
|
||||
return view_data
|
||||
|
||||
def _server_env_default_fieldname(self, base_field_name):
|
||||
"""Return the name of the field with default value"""
|
||||
options = self._server_env_fields[base_field_name]
|
||||
if options and options.get('no_default_field'):
|
||||
return ''
|
||||
return '%s_env_default' % (base_field_name,)
|
||||
if options and options.get("no_default_field"):
|
||||
return ""
|
||||
return "{}_env_default".format(base_field_name)
|
||||
|
||||
def _server_env_is_editable_fieldname(self, base_field_name):
|
||||
"""Return the name of the field for "is editable"
|
||||
|
|
@ -331,16 +315,14 @@ class ServerEnvMixin(models.AbstractModel):
|
|||
This is the field used to tell if the env-computed field can
|
||||
be edited.
|
||||
"""
|
||||
return '%s_env_is_editable' % (base_field_name,)
|
||||
return "{}_env_is_editable".format(base_field_name)
|
||||
|
||||
def _server_env_transform_field_to_read_from_env(self, field):
|
||||
"""Transform the original field in a computed field"""
|
||||
field.compute = '_compute_server_env'
|
||||
field.compute = "_compute_server_env"
|
||||
|
||||
inverse_method_name = '_inverse_server_env_%s' % field.name
|
||||
inverse_method = partialmethod(
|
||||
type(self)._inverse_server_env, field.name
|
||||
)
|
||||
inverse_method_name = "_inverse_server_env_%s" % field.name
|
||||
inverse_method = partialmethod(type(self)._inverse_server_env, field.name)
|
||||
setattr(type(self), inverse_method_name, inverse_method)
|
||||
field.inverse = inverse_method_name
|
||||
field.store = False
|
||||
|
|
@ -360,7 +342,7 @@ class ServerEnvMixin(models.AbstractModel):
|
|||
# (inherits), we want to override it with a new one
|
||||
if fieldname not in self._fields or self._fields[fieldname].inherited:
|
||||
field = fields.Boolean(
|
||||
compute='_compute_server_env_is_editable',
|
||||
compute="_compute_server_env_is_editable",
|
||||
automatic=True,
|
||||
# this is required to be able to edit fields
|
||||
# on new records
|
||||
|
|
@ -385,14 +367,11 @@ class ServerEnvMixin(models.AbstractModel):
|
|||
if fieldname not in self._fields or self._fields[fieldname].inherited:
|
||||
base_field_cls = base_field.__class__
|
||||
field_args = base_field.args.copy()
|
||||
field_args.pop('_sequence', None)
|
||||
field_args.update({
|
||||
'sparse': 'server_env_defaults',
|
||||
'automatic': True,
|
||||
})
|
||||
field_args.pop("_sequence", None)
|
||||
field_args.update({"sparse": "server_env_defaults", "automatic": True})
|
||||
|
||||
if hasattr(base_field, 'selection'):
|
||||
field_args['selection'] = base_field.selection
|
||||
if hasattr(base_field, "selection"):
|
||||
field_args["selection"] = base_field.selection
|
||||
field = base_field_cls(**field_args)
|
||||
self._add_field(fieldname, field)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,13 +18,14 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import configparser
|
||||
import logging
|
||||
import os
|
||||
import configparser
|
||||
from lxml import etree
|
||||
from itertools import chain
|
||||
|
||||
from odoo import api, models, fields
|
||||
from lxml import etree
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools.config import config as system_base_config
|
||||
|
||||
from .system_info import get_server_environment
|
||||
|
|
@ -33,19 +34,29 @@ _logger = logging.getLogger(__name__)
|
|||
|
||||
try:
|
||||
from odoo.addons import server_environment_files
|
||||
|
||||
_dir = os.path.dirname(server_environment_files.__file__)
|
||||
except ImportError:
|
||||
_logger.info('not using server_environment_files for configuration,'
|
||||
' no directory found')
|
||||
_logger.info(
|
||||
"not using server_environment_files for configuration," " no directory found"
|
||||
)
|
||||
_dir = None
|
||||
|
||||
ENV_VAR_NAMES = ('SERVER_ENV_CONFIG', 'SERVER_ENV_CONFIG_SECRET')
|
||||
ENV_VAR_NAMES = ("SERVER_ENV_CONFIG", "SERVER_ENV_CONFIG_SECRET")
|
||||
|
||||
# Same dict as RawConfigParser._boolean_states
|
||||
_boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
|
||||
'0': False, 'no': False, 'false': False, 'off': False}
|
||||
_boolean_states = {
|
||||
"1": True,
|
||||
"yes": True,
|
||||
"true": True,
|
||||
"on": True,
|
||||
"0": False,
|
||||
"no": False,
|
||||
"false": False,
|
||||
"off": False,
|
||||
}
|
||||
|
||||
if not system_base_config.get('running_env', False):
|
||||
if not system_base_config.get("running_env", False):
|
||||
raise Exception(
|
||||
"The parameter 'running_env' has not be set neither in base config "
|
||||
"file option -c or in openerprc.\n"
|
||||
|
|
@ -56,7 +67,7 @@ if not system_base_config.get('running_env', False):
|
|||
|
||||
ck_path = None
|
||||
if _dir:
|
||||
ck_path = os.path.join(_dir, system_base_config['running_env'])
|
||||
ck_path = os.path.join(_dir, system_base_config["running_env"])
|
||||
|
||||
if not os.path.exists(ck_path):
|
||||
raise Exception(
|
||||
|
|
@ -77,25 +88,29 @@ def setboolean(obj, attr, _bool=None):
|
|||
# Borrowed from MarkupSafe
|
||||
def _escape(s):
|
||||
"""Convert the characters &<>'" in string s to HTML-safe sequences."""
|
||||
return (str(s).replace('&', '&')
|
||||
.replace('>', '>')
|
||||
.replace('<', '<')
|
||||
.replace("'", ''')
|
||||
.replace('"', '"'))
|
||||
return (
|
||||
str(s)
|
||||
.replace("&", "&")
|
||||
.replace(">", ">")
|
||||
.replace("<", "<")
|
||||
.replace("'", "'")
|
||||
.replace('"', """)
|
||||
)
|
||||
|
||||
|
||||
def _listconf(env_path):
|
||||
"""List configuration files in a folder."""
|
||||
files = [os.path.join(env_path, name)
|
||||
for name in sorted(os.listdir(env_path))
|
||||
if name.endswith('.conf')]
|
||||
files = [
|
||||
os.path.join(env_path, name)
|
||||
for name in sorted(os.listdir(env_path))
|
||||
if name.endswith(".conf")
|
||||
]
|
||||
return files
|
||||
|
||||
|
||||
def _load_config_from_server_env_files(config_p):
|
||||
default = os.path.join(_dir, 'default')
|
||||
running_env = os.path.join(_dir,
|
||||
system_base_config['running_env'])
|
||||
default = os.path.join(_dir, "default")
|
||||
running_env = os.path.join(_dir, system_base_config["running_env"])
|
||||
if os.path.isdir(default):
|
||||
conf_files = _listconf(default) + _listconf(running_env)
|
||||
else:
|
||||
|
|
@ -104,12 +119,12 @@ def _load_config_from_server_env_files(config_p):
|
|||
try:
|
||||
config_p.read(conf_files)
|
||||
except Exception as e:
|
||||
raise Exception('Cannot read config files "%s": %s' % (conf_files, e))
|
||||
raise Exception('Cannot read config files "{}": {}'.format(conf_files, e))
|
||||
|
||||
|
||||
def _load_config_from_rcfile(config_p):
|
||||
config_p.read(system_base_config.rcfile)
|
||||
config_p.remove_section('options')
|
||||
config_p.remove_section("options")
|
||||
|
||||
|
||||
def _load_config_from_env(config_p):
|
||||
|
|
@ -120,8 +135,7 @@ def _load_config_from_env(config_p):
|
|||
config_p.read_string(env_config)
|
||||
except configparser.Error as err:
|
||||
raise Exception(
|
||||
'%s content could not be parsed: %s'
|
||||
% (varname, err,)
|
||||
"{} content could not be parsed: {}".format(varname, err)
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -147,13 +161,15 @@ class _Defaults(dict):
|
|||
def __setitem__(self, key, value):
|
||||
def func(*a):
|
||||
return str(value)
|
||||
|
||||
return dict.__setitem__(self, key, func)
|
||||
|
||||
|
||||
class ServerConfiguration(models.TransientModel):
|
||||
"""Display server configuration."""
|
||||
_name = 'server.config'
|
||||
_description = 'Display server configuration'
|
||||
|
||||
_name = "server.config"
|
||||
_description = "Display server configuration"
|
||||
_conf_defaults = _Defaults()
|
||||
|
||||
@classmethod
|
||||
|
|
@ -164,20 +180,20 @@ class ServerConfiguration(models.TransientModel):
|
|||
"""
|
||||
ModelClass = super(ServerConfiguration, cls)._build_model(pool, cr)
|
||||
ModelClass._add_columns()
|
||||
ModelClass.running_env = system_base_config['running_env']
|
||||
ModelClass.running_env = system_base_config["running_env"]
|
||||
# Only show passwords in development
|
||||
ModelClass.show_passwords = ModelClass.running_env in ('dev',)
|
||||
ModelClass.show_passwords = ModelClass.running_env in ("dev",)
|
||||
ModelClass._arch = None
|
||||
ModelClass._build_osv()
|
||||
return ModelClass
|
||||
|
||||
@classmethod
|
||||
def _format_key(cls, section, key):
|
||||
return '%s_I_%s' % (section, key)
|
||||
return "{}_I_{}".format(section, key)
|
||||
|
||||
@classmethod
|
||||
def _format_key_display_name(cls, key_name):
|
||||
return key_name.replace('_I_', ' | ')
|
||||
return key_name.replace("_I_", " | ")
|
||||
|
||||
@classmethod
|
||||
def _add_columns(cls):
|
||||
|
|
@ -185,16 +201,17 @@ class ServerConfiguration(models.TransientModel):
|
|||
cols = chain(
|
||||
list(cls._get_base_cols().items()),
|
||||
list(cls._get_env_cols().items()),
|
||||
list(cls._get_system_cols().items())
|
||||
list(cls._get_system_cols().items()),
|
||||
)
|
||||
for col, value in cols:
|
||||
col_name = col.replace('.', '_')
|
||||
setattr(ServerConfiguration,
|
||||
col_name,
|
||||
fields.Char(
|
||||
string=cls._format_key_display_name(col_name),
|
||||
readonly=True)
|
||||
)
|
||||
col_name = col.replace(".", "_")
|
||||
setattr(
|
||||
ServerConfiguration,
|
||||
col_name,
|
||||
fields.Char(
|
||||
string=cls._format_key_display_name(col_name), readonly=True
|
||||
),
|
||||
)
|
||||
cls._conf_defaults[col_name] = value
|
||||
|
||||
@classmethod
|
||||
|
|
@ -202,7 +219,7 @@ class ServerConfiguration(models.TransientModel):
|
|||
""" Compute base fields"""
|
||||
res = {}
|
||||
for col, item in list(system_base_config.options.items()):
|
||||
key = cls._format_key('odoo', col)
|
||||
key = cls._format_key("odoo", col)
|
||||
res[key] = item
|
||||
return res
|
||||
|
||||
|
|
@ -222,7 +239,7 @@ class ServerConfiguration(models.TransientModel):
|
|||
""" Compute system fields"""
|
||||
res = {}
|
||||
for col, item in get_server_environment():
|
||||
key = cls._format_key('system', col)
|
||||
key = cls._format_key("system", col)
|
||||
res[key] = item
|
||||
return res
|
||||
|
||||
|
|
@ -232,17 +249,19 @@ class ServerConfiguration(models.TransientModel):
|
|||
names = []
|
||||
|
||||
for key in sorted(items):
|
||||
names.append(key.replace('.', '_'))
|
||||
return ('<group col="2" colspan="4">' +
|
||||
''.join(['<field name="%s" readonly="1"/>' %
|
||||
_escape(name) for name in names]) +
|
||||
'</group>')
|
||||
names.append(key.replace(".", "_"))
|
||||
return (
|
||||
'<group col="2" colspan="4">'
|
||||
+ "".join(
|
||||
['<field name="%s" readonly="1"/>' % _escape(name) for name in names]
|
||||
)
|
||||
+ "</group>"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _build_osv(cls):
|
||||
"""Build the view for the current configuration."""
|
||||
arch = ('<form string="Configuration Form">'
|
||||
'<notebook colspan="4">')
|
||||
arch = '<form string="Configuration Form">' '<notebook colspan="4">'
|
||||
|
||||
# Odoo server configuration
|
||||
rcfile = system_base_config.rcfile
|
||||
|
|
@ -265,23 +284,23 @@ class ServerConfiguration(models.TransientModel):
|
|||
arch += cls._group(cls._get_system_cols())
|
||||
arch += '<separator colspan="4"/></page>'
|
||||
|
||||
arch += '</notebook></form>'
|
||||
arch += "</notebook></form>"
|
||||
cls._arch = etree.fromstring(arch)
|
||||
|
||||
@api.model
|
||||
def fields_view_get(self, view_id=None, view_type='form', toolbar=False,
|
||||
submenu=False):
|
||||
def fields_view_get(
|
||||
self, view_id=None, view_type="form", toolbar=False, submenu=False
|
||||
):
|
||||
"""Overwrite the default method to render the custom view."""
|
||||
res = super(ServerConfiguration, self).fields_view_get(view_id,
|
||||
view_type,
|
||||
toolbar)
|
||||
View = self.env['ir.ui.view']
|
||||
if view_type == 'form':
|
||||
res = super(ServerConfiguration, self).fields_view_get(
|
||||
view_id, view_type, toolbar
|
||||
)
|
||||
View = self.env["ir.ui.view"]
|
||||
if view_type == "form":
|
||||
arch_node = self._arch
|
||||
xarch, xfields = View.postprocess_and_fields(
|
||||
self._name, arch_node, view_id)
|
||||
res['arch'] = xarch
|
||||
res['fields'] = xfields
|
||||
xarch, xfields = View.postprocess_and_fields(self._name, arch_node, view_id)
|
||||
res["arch"] = xarch
|
||||
res["fields"] = xfields
|
||||
return res
|
||||
|
||||
@api.model
|
||||
|
|
@ -291,18 +310,19 @@ class ServerConfiguration(models.TransientModel):
|
|||
should be secret.
|
||||
:return: list of secret keywords
|
||||
"""
|
||||
secret_keys = ['passw', 'key', 'secret', 'token']
|
||||
secret_keys = ["passw", "key", "secret", "token"]
|
||||
return any(secret_key in key for secret_key in secret_keys)
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields_list):
|
||||
res = {}
|
||||
if not self.env.user.has_group(
|
||||
'server_environment.has_server_configuration_access'):
|
||||
"server_environment.has_server_configuration_access"
|
||||
):
|
||||
return res
|
||||
for key in self._conf_defaults:
|
||||
if not self.show_passwords and self._is_secret(key=key):
|
||||
res[key] = '**********'
|
||||
res[key] = "**********"
|
||||
else:
|
||||
res[key] = self._conf_defaults[key]()
|
||||
return res
|
||||
|
|
|
|||
|
|
@ -28,38 +28,39 @@ from odoo.tools.config import config
|
|||
|
||||
|
||||
def _get_output(cmd):
|
||||
bindir = config['root_path']
|
||||
p = subprocess.Popen(cmd, shell=True, cwd=bindir, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
bindir = config["root_path"]
|
||||
p = subprocess.Popen(
|
||||
cmd, shell=True, cwd=bindir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
)
|
||||
return p.communicate()[0].rstrip()
|
||||
|
||||
|
||||
def get_server_environment():
|
||||
# inspired by server/bin/service/web_services.py
|
||||
try:
|
||||
rev_id = 'git:%s' % _get_output('git rev-parse HEAD')
|
||||
rev_id = "git:%s" % _get_output("git rev-parse HEAD")
|
||||
except Exception:
|
||||
try:
|
||||
rev_id = 'bzr: %s' % _get_output('bzr revision-info')
|
||||
rev_id = "bzr: %s" % _get_output("bzr revision-info")
|
||||
except Exception:
|
||||
rev_id = 'Can not retrieve revison from git or bzr'
|
||||
rev_id = "Can not retrieve revison from git or bzr"
|
||||
|
||||
os_lang = '.'.join([x for x in locale.getdefaultlocale() if x])
|
||||
os_lang = ".".join([x for x in locale.getdefaultlocale() if x])
|
||||
if not os_lang:
|
||||
os_lang = 'NOT SET'
|
||||
if os.name == 'posix' and platform.system() == 'Linux':
|
||||
lsbinfo = _get_output('lsb_release -a')
|
||||
os_lang = "NOT SET"
|
||||
if os.name == "posix" and platform.system() == "Linux":
|
||||
lsbinfo = _get_output("lsb_release -a")
|
||||
else:
|
||||
lsbinfo = 'not lsb compliant'
|
||||
lsbinfo = "not lsb compliant"
|
||||
return (
|
||||
('platform', platform.platform()),
|
||||
('os.name', os.name),
|
||||
('lsb_release', lsbinfo),
|
||||
('release', platform.release()),
|
||||
('version', platform.version()),
|
||||
('architecture', platform.architecture()[0]),
|
||||
('locale', os_lang),
|
||||
('python', platform.python_version()),
|
||||
('odoo', release.version),
|
||||
('revision', rev_id),
|
||||
("platform", platform.platform()),
|
||||
("os.name", os.name),
|
||||
("lsb_release", lsbinfo),
|
||||
("release", platform.release()),
|
||||
("version", platform.version()),
|
||||
("architecture", platform.architecture()[0]),
|
||||
("locale", os_lang),
|
||||
("python", platform.python_version()),
|
||||
("odoo", release.version),
|
||||
("revision", rev_id),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,29 +6,27 @@ from contextlib import contextmanager
|
|||
from unittest.mock import patch
|
||||
|
||||
from odoo.tests import common
|
||||
from odoo.addons.server_environment import server_env
|
||||
from odoo.tools.config import config
|
||||
|
||||
import odoo.addons.server_environment.models.server_env_mixin as \
|
||||
server_env_mixin
|
||||
import odoo.addons.server_environment.models.server_env_mixin as server_env_mixin
|
||||
from odoo.addons.server_environment import server_env
|
||||
|
||||
|
||||
class ServerEnvironmentCase(common.SavepointCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self._original_running_env = config.get('running_env')
|
||||
config['running_env'] = 'testing'
|
||||
self._original_running_env = config.get("running_env")
|
||||
config["running_env"] = "testing"
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
config['running_env'] = self._original_running_env
|
||||
config["running_env"] = self._original_running_env
|
||||
|
||||
@contextmanager
|
||||
def set_config_dir(self, path):
|
||||
original_dir = server_env._dir
|
||||
if path and not os.path.isabs(path):
|
||||
path = os.path.join(os.path.dirname(__file__,), path)
|
||||
path = os.path.join(os.path.dirname(__file__), path)
|
||||
server_env._dir = path
|
||||
try:
|
||||
yield
|
||||
|
|
@ -39,18 +37,17 @@ class ServerEnvironmentCase(common.SavepointCase):
|
|||
def set_env_variables(self, public=None, secret=None):
|
||||
newkeys = {}
|
||||
if public:
|
||||
newkeys['SERVER_ENV_CONFIG'] = public
|
||||
newkeys["SERVER_ENV_CONFIG"] = public
|
||||
if secret:
|
||||
newkeys['SERVER_ENV_CONFIG_SECRET'] = secret
|
||||
with patch.dict('os.environ', newkeys):
|
||||
newkeys["SERVER_ENV_CONFIG_SECRET"] = secret
|
||||
with patch.dict("os.environ", newkeys):
|
||||
yield
|
||||
|
||||
@contextmanager
|
||||
def load_config(self, public=None, secret=None):
|
||||
original_serv_config = server_env_mixin.serv_config
|
||||
try:
|
||||
with self.set_config_dir(None), \
|
||||
self.set_env_variables(public, secret):
|
||||
with self.set_config_dir(None), self.set_env_variables(public, secret):
|
||||
parser = server_env._load_config()
|
||||
server_env_mixin.serv_config = parser
|
||||
yield
|
||||
|
|
|
|||
|
|
@ -3,43 +3,25 @@
|
|||
|
||||
|
||||
from odoo.addons.server_environment import server_env
|
||||
|
||||
from .common import ServerEnvironmentCase
|
||||
|
||||
|
||||
class TestEnvironmentVariables(ServerEnvironmentCase):
|
||||
|
||||
def test_env_variables(self):
|
||||
public = (
|
||||
"[section]\n"
|
||||
"foo=bar\n"
|
||||
"bar=baz\n"
|
||||
)
|
||||
secret = (
|
||||
"[section]\n"
|
||||
"bar=foo\n"
|
||||
"alice=bob\n"
|
||||
)
|
||||
with self.set_config_dir(None), \
|
||||
self.set_env_variables(public, secret):
|
||||
public = "[section]\n" "foo=bar\n" "bar=baz\n"
|
||||
secret = "[section]\n" "bar=foo\n" "alice=bob\n"
|
||||
with self.set_config_dir(None), self.set_env_variables(public, secret):
|
||||
parser = server_env._load_config()
|
||||
self.assertEqual(
|
||||
list(parser.keys()),
|
||||
['DEFAULT', 'section']
|
||||
)
|
||||
self.assertEqual(list(parser.keys()), ["DEFAULT", "section"])
|
||||
self.assertDictEqual(
|
||||
dict(parser['section'].items()),
|
||||
{'alice': 'bob',
|
||||
'bar': 'foo',
|
||||
'foo': 'bar'}
|
||||
dict(parser["section"].items()),
|
||||
{"alice": "bob", "bar": "foo", "foo": "bar"},
|
||||
)
|
||||
|
||||
def test_env_variables_override(self):
|
||||
public = (
|
||||
"[external_service.ftp]\n"
|
||||
"user=foo\n"
|
||||
)
|
||||
with self.set_config_dir('testfiles'), \
|
||||
self.set_env_variables(public):
|
||||
public = "[external_service.ftp]\n" "user=foo\n"
|
||||
with self.set_config_dir("testfiles"), self.set_env_variables(public):
|
||||
parser = server_env._load_config()
|
||||
val = parser.get('external_service.ftp', 'user')
|
||||
self.assertEqual(val, 'foo')
|
||||
val = parser.get("external_service.ftp", "user")
|
||||
self.assertEqual(val, "foo")
|
||||
|
|
|
|||
|
|
@ -1,34 +1,33 @@
|
|||
# Copyright 2018 Camptocamp (https://www.camptocamp.com).
|
||||
# License GPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo.addons.server_environment import server_env
|
||||
|
||||
from . import common
|
||||
|
||||
|
||||
class TestEnv(common.ServerEnvironmentCase):
|
||||
|
||||
def test_view(self):
|
||||
model = self.env['server.config']
|
||||
model = self.env["server.config"]
|
||||
view = model.fields_view_get()
|
||||
self.assertTrue(view)
|
||||
|
||||
def test_default(self):
|
||||
model = self.env['server.config']
|
||||
model = self.env["server.config"]
|
||||
rec = model.create({})
|
||||
defaults = rec.default_get([])
|
||||
self.assertTrue(defaults)
|
||||
self.assertIsInstance(defaults, dict)
|
||||
pass_checked = False
|
||||
for default in defaults:
|
||||
if 'passw' in default:
|
||||
self.assertNotEqual(defaults[default],
|
||||
'**********')
|
||||
if "passw" in default:
|
||||
self.assertNotEqual(defaults[default], "**********")
|
||||
pass_checked = True
|
||||
self.assertTrue(pass_checked)
|
||||
|
||||
def test_value_retrival(self):
|
||||
with self.set_config_dir('testfiles'):
|
||||
with self.set_config_dir("testfiles"):
|
||||
parser = server_env._load_config()
|
||||
val = parser.get('external_service.ftp', 'user')
|
||||
self.assertEqual(val, 'testing')
|
||||
val = parser.get('external_service.ftp', 'host')
|
||||
self.assertEqual(val, 'sftp.example.com')
|
||||
val = parser.get("external_service.ftp", "user")
|
||||
self.assertEqual(val, "testing")
|
||||
val = parser.get("external_service.ftp", "host")
|
||||
self.assertEqual(val, "sftp.example.com")
|
||||
|
|
|
|||
Loading…
Reference in New Issue