check symlink type for _type in service

This commit is contained in:
Emmanuel Garette 2021-02-17 07:48:19 +01:00
parent 1272524cc8
commit c7ea03b411
11 changed files with 80 additions and 39 deletions

View file

@ -38,16 +38,6 @@ ERASED_ATTRIBUTES = ('redefine', 'exists', 'optional', 'remove_check', 'namespac
'reflector_object',) 'reflector_object',)
KEY_TYPE = {'variable': 'symlink',
'PortOption': 'port',
'UnicodeOption': 'string',
'NetworkOption': 'network',
'NetmaskOption': 'netmask',
'URLOption': 'web_address',
'FilenameOption': 'filename',
}
class ServiceAnnotator: class ServiceAnnotator:
"""Manage service's object """Manage service's object
for example:: for example::
@ -122,9 +112,11 @@ class ServiceAnnotator:
) )
family.variable = [] family.variable = []
activate_obj = self._generate_element('boolean', activate_obj = self._generate_element('boolean',
None,
None,
'activate', 'activate',
True, True,
elt.xmlfiles, elt,
'.'.join([subpath, 'activate']), '.'.join([subpath, 'activate']),
) )
for key in dir(elt): for key in dir(elt):
@ -137,13 +129,19 @@ class ServiceAnnotator:
value, value,
[]).append(activate_obj) []).append(activate_obj)
continue continue
family.variable.append(self._generate_element(self._get_type(key, if key == 'name':
elttype, dtd_key_type = elttype + '_type'
elt, else:
), dtd_key_type = key + '_type'
elt_type = getattr(elt, dtd_key_type, 'string')
if elt_type == 'variable':
elt_type = 'symlink'
family.variable.append(self._generate_element(elt_type,
dtd_key_type,
elttype,
key, key,
value, value,
elt.xmlfiles, elt,
f'{subpath}.{key}' f'{subpath}.{key}'
)) ))
family.variable.append(activate_obj) family.variable.append(activate_obj)
@ -190,18 +188,26 @@ class ServiceAnnotator:
def _generate_element(self, def _generate_element(self,
type_, type_,
dtd_key_type,
elttype,
key, key,
value, value,
xmlfiles, elt,
path, path,
): # pylint: disable=R0913 ): # pylint: disable=R0913
variable = self.objectspace.variable(xmlfiles) variable = self.objectspace.variable(elt.xmlfiles)
variable.name = normalize_family(key) variable.name = normalize_family(key)
variable.mode = None variable.mode = None
variable.type = type_ variable.type = type_
if type_ == 'symlink': if type_ == 'symlink':
variable.opt = self.objectspace.paths.get_variable(value) variable.opt = self.objectspace.paths.get_variable(value)
variable.multi = None variable.multi = None
if self.objectspace.types[dtd_key_type] != 'variable' and \
variable.opt.type != self.objectspace.types[dtd_key_type]:
msg = _(f'"{key}" in "{elttype}" must be a variable with type '
f'"{self.objectspace.types[dtd_key_type]}" not "{variable.opt.type}"')
raise DictConsistencyError(msg, 58, elt.xmlfiles)
else: else:
variable.doc = key variable.doc = key
variable.default = value variable.default = value
@ -214,21 +220,6 @@ class ServiceAnnotator:
) )
return variable return variable
def _get_type(self,
key: str,
elt_name: str,
elt,
) -> str:
if key == 'name':
dtd_key_type = elt_name + '_type'
else:
dtd_key_type = key + '_type'
if key in self.objectspace.booleans_attributs:
return 'boolean'
if hasattr(elt, dtd_key_type):
return KEY_TYPE[getattr(elt, dtd_key_type)]
return 'string'
def _update_override(self, def _update_override(self,
file_, file_,
service_name, service_name,
@ -247,7 +238,7 @@ class ServiceAnnotator:
file_, file_,
service_name, service_name,
): ):
if not hasattr(file_, 'file_type') or file_.file_type == "UnicodeOption": if not hasattr(file_, 'file_type') or file_.file_type == "string":
if not hasattr(file_, 'source'): if not hasattr(file_, 'source'):
file_.source = basename(file_.name) file_.source = basename(file_.name)
elif not hasattr(file_, 'source'): elif not hasattr(file_, 'source'):

View file

@ -49,21 +49,21 @@
<!ATTLIST service name CDATA #REQUIRED> <!ATTLIST service name CDATA #REQUIRED>
<!ELEMENT port (#PCDATA)> <!ELEMENT port (#PCDATA)>
<!ATTLIST port port_type (PortOption|variable) "PortOption"> <!ATTLIST port port_type (port|variable) "port">
<!ATTLIST port portlist CDATA #IMPLIED> <!ATTLIST port portlist CDATA #IMPLIED>
<!ATTLIST port protocol (tcp|udp) "tcp"> <!ATTLIST port protocol (tcp|udp) "tcp">
<!ELEMENT ip (#PCDATA)> <!ELEMENT ip (#PCDATA)>
<!ATTLIST ip iplist CDATA #IMPLIED> <!ATTLIST ip iplist CDATA #IMPLIED>
<!ATTLIST ip ip_type (NetworkOption|variable) "NetworkOption"> <!ATTLIST ip ip_type (network|variable) "network">
<!ATTLIST ip interface_type (UnicodeOption|variable) "UnicodeOption"> <!ATTLIST ip interface_type (string|variable) "string">
<!ATTLIST ip interface CDATA #REQUIRED> <!ATTLIST ip interface CDATA #REQUIRED>
<!ATTLIST ip netmask_type (NetmaskOption|variable) "NetmaskOption"> <!ATTLIST ip netmask_type (netmask|variable) "netmask">
<!ATTLIST ip netmask CDATA "255.255.255.255"> <!ATTLIST ip netmask CDATA "255.255.255.255">
<!ELEMENT file EMPTY> <!ELEMENT file EMPTY>
<!ATTLIST file name CDATA #REQUIRED> <!ATTLIST file name CDATA #REQUIRED>
<!ATTLIST file file_type (UnicodeOption|variable) "UnicodeOption"> <!ATTLIST file file_type (string|variable) "string">
<!ATTLIST file variable CDATA #IMPLIED> <!ATTLIST file variable CDATA #IMPLIED>
<!ATTLIST file variable_type (variable) "variable"> <!ATTLIST file variable_type (variable) "variable">
<!ATTLIST file source CDATA #IMPLIED> <!ATTLIST file source CDATA #IMPLIED>

View file

@ -110,6 +110,7 @@ class RougailObjSpace:
self.valid_enums = {} self.valid_enums = {}
self.booleans_attributs = [] self.booleans_attributs = []
self.has_dyn_option = False self.has_dyn_option = False
self.types = {}
self.make_object_space_classes(xmlreflector) self.make_object_space_classes(xmlreflector)
self.rougailconfig = rougailconfig self.rougailconfig = rougailconfig
@ -141,6 +142,8 @@ class RougailObjSpace:
if dtd_attr.name in self.booleans_attributs: if dtd_attr.name in self.booleans_attributs:
default_value = convert_boolean(default_value) default_value = convert_boolean(default_value)
attrs[dtd_attr.name] = default_value attrs[dtd_attr.name] = default_value
if dtd_attr.name.endswith('_type'):
self.types[dtd_attr.name] = default_value
if dtd_attr.name == 'redefine': if dtd_attr.name == 'redefine':
# has a redefine attribute, so it's a Redefinable object # has a redefine attribute, so it's a Redefinable object
clstype = Redefinable clstype = Redefinable

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<rougail>
<services>
<service name='ntp'>
<port protocol='udp' port_type="variable">my_variable</port>
<port protocol='tcp' port_type="variable">my_variable</port>
</service>
</services>
<variables>
<variable name='my_variable' type='port'>
<value>123</value>
</variable>
</variables>
</rougail>
<!-- vim: ts=4 sw=4 expandtab
-->

View file

@ -0,0 +1 @@
{"rougail.my_variable": "123", "services.ntp.ports.my_variable.name": "123", "services.ntp.ports.my_variable.protocol": "udp", "services.ntp.ports.my_variable.activate": true, "services.ntp.ports.my_variable_1.name": "123", "services.ntp.ports.my_variable_1.protocol": "tcp", "services.ntp.ports.my_variable_1.activate": true}

View file

@ -0,0 +1,27 @@
from importlib.machinery import SourceFileLoader
from importlib.util import spec_from_loader, module_from_spec
loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py')
spec = spec_from_loader(loader.name, loader)
func = module_from_spec(spec)
loader.exec_module(func)
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try:
from tiramisu3 import *
except:
from tiramisu import *
option_2 = PortOption(name="my_variable", doc="my_variable", default="123", allow_private=True, properties=frozenset({"mandatory", "normal"}))
option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2])
option_7 = SymLinkOption(name="name", opt=option_2)
option_8 = StrOption(name="protocol", doc="protocol", default="udp")
option_9 = BoolOption(name="activate", doc="activate", default=True)
option_6 = OptionDescription(name="my_variable", doc="my_variable", children=[option_7, option_8, option_9])
option_11 = SymLinkOption(name="name", opt=option_2)
option_12 = StrOption(name="protocol", doc="protocol", default="tcp")
option_13 = BoolOption(name="activate", doc="activate", default=True)
option_10 = OptionDescription(name="my_variable_1", doc="my_variable_1", children=[option_11, option_12, option_13])
option_5 = OptionDescription(name="ports", doc="ports", children=[option_6, option_10])
option_4 = OptionDescription(name="ntp", doc="ntp", children=[option_5])
option_3 = OptionDescription(name="services", doc="services", children=[option_4], properties=frozenset({"hidden"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_3])