add unix_permissions option support and use it for mode

This commit is contained in:
egarette@silique.fr 2023-01-27 11:15:51 +01:00
parent ffdeafcc29
commit 6af98ec1e4
17 changed files with 171 additions and 7 deletions

View file

@ -63,6 +63,7 @@ CONVERT_OPTION = {'number': dict(opttype="IntOption", func=int),
'mac': dict(opttype="MACOption"), 'mac': dict(opttype="MACOption"),
'cidr': dict(opttype="IPOption", initkwargs={'cidr': True}), 'cidr': dict(opttype="IPOption", initkwargs={'cidr': True}),
'network_cidr': dict(opttype="NetworkOption", initkwargs={'cidr': True}), 'network_cidr': dict(opttype="NetworkOption", initkwargs={'cidr': True}),
'unix_permissions': dict(opttype="PermissionsOption", initkwargs={'warnings_only': True}, func=int),
} }

View file

@ -71,7 +71,7 @@
<!ATTLIST file variable_type (variable) "variable"> <!ATTLIST file variable_type (variable) "variable">
<!ATTLIST file source CDATA #IMPLIED> <!ATTLIST file source CDATA #IMPLIED>
<!ATTLIST file source_type (string|variable) "string"> <!ATTLIST file source_type (string|variable) "string">
<!ATTLIST file mode_type (number) "number"> <!ATTLIST file mode_type (unix_permissions) "unix_permissions">
<!ATTLIST file mode CDATA #IMPLIED> <!ATTLIST file mode CDATA #IMPLIED>
<!ATTLIST file owner CDATA #IMPLIED> <!ATTLIST file owner CDATA #IMPLIED>
<!ATTLIST file owner_type (unix_user|variable) "unix_user"> <!ATTLIST file owner_type (unix_user|variable) "unix_user">
@ -111,7 +111,7 @@
<!ELEMENT variable ((choice*|value*)*)> <!ELEMENT variable ((choice*|value*)*)>
<!ATTLIST variable name CDATA #REQUIRED> <!ATTLIST variable name CDATA #REQUIRED>
<!ATTLIST variable type (number|float|string|password|secret|mail|boolean|filename|date|unix_user|ip|local_ip|netmask|network|broadcast|netbios|domainname|hostname|web_address|port|mac|cidr|network_cidr|choice) "string"> <!ATTLIST variable type (number|float|string|password|secret|mail|boolean|filename|date|unix_user|ip|local_ip|netmask|network|broadcast|netbios|domainname|hostname|web_address|port|mac|cidr|network_cidr|choice|unix_permissions) "string">
<!ATTLIST variable description CDATA #IMPLIED> <!ATTLIST variable description CDATA #IMPLIED>
<!ATTLIST variable help CDATA #IMPLIED> <!ATTLIST variable help CDATA #IMPLIED>
<!ATTLIST variable hidden (True|False) "False"> <!ATTLIST variable hidden (True|False) "False">

View file

@ -322,6 +322,7 @@ mapping:
- "cidr" - "cidr"
- "network_cidr" - "network_cidr"
- "choice" - "choice"
- "unix_permissions"
family: family:
type: seq type: seq
sequence: sequence:
@ -467,6 +468,7 @@ mapping:
- "cidr" - "cidr"
- "network_cidr" - "network_cidr"
- "choice" - "choice"
- "unix_permissions"
family: family:
required: false required: false
type: seq type: seq
@ -613,6 +615,7 @@ mapping:
- "cidr" - "cidr"
- "network_cidr" - "network_cidr"
- "choice" - "choice"
- "unix_permissions"
family: family:
required: false required: false
name: name:
@ -787,6 +790,7 @@ mapping:
- "cidr" - "cidr"
- "network_cidr" - "network_cidr"
- "choice" - "choice"
- "unix_permissions"
family: family:
type: seq type: seq
sequence: sequence:
@ -932,6 +936,7 @@ mapping:
- "cidr" - "cidr"
- "network_cidr" - "network_cidr"
- "choice" - "choice"
- "unix_permissions"
family: family:
required: false required: false
name: name:
@ -1092,6 +1097,7 @@ mapping:
- "cidr" - "cidr"
- "network_cidr" - "network_cidr"
- "choice" - "choice"
- "unix_permissions"
family: family:
type: seq type: seq
sequence: sequence:
@ -1237,6 +1243,7 @@ mapping:
- "cidr" - "cidr"
- "network_cidr" - "network_cidr"
- "choice" - "choice"
- "unix_permissions"
family: family:
required: false required: false
name: name:
@ -1397,6 +1404,7 @@ mapping:
- "cidr" - "cidr"
- "network_cidr" - "network_cidr"
- "choice" - "choice"
- "unix_permissions"
constraints: constraints:
required: false required: false
type: seq type: seq

View file

@ -587,6 +587,11 @@ class RougailBaseTemplate:
) -> None: # pragma: no cover ) -> None: # pragma: no cover
raise NotImplementedError(_('cannot instanciate this service type override')) raise NotImplementedError(_('cannot instanciate this service type override'))
def get_data_certificates(self,
*args,
) -> None: # pragma: no cover
pass
async def _load_variables(self, async def _load_variables(self,
optiondescription, optiondescription,
is_variable_namespace: str, is_variable_namespace: str,

View file

@ -56,10 +56,14 @@ class RougailSystemdTemplate(RougailBaseTemplate):
tmp_local_dir = (f"%%filename.startswith('{local_dir}')" for local_dir in LOCAL_DIR) tmp_local_dir = (f"%%filename.startswith('{local_dir}')" for local_dir in LOCAL_DIR)
self.rougail_tmpl_template += '%if ' + ' or '.join(tmp_local_dir) self.rougail_tmpl_template += '%if ' + ' or '.join(tmp_local_dir)
self.rougail_tmpl_template += f""" self.rougail_tmpl_template += f"""
%if {self.rougailconfig['systemd_tmpfile_delete_before_create']} %if {self.rougailconfig['systemd_tmpfile_delete_before_create']}
r %%filename r %%filename
%end if %end if
C %%filename 0%%file.mode %%file.owner %%file.group - {self.rougailconfig['systemd_tmpfile_factory_dir']}%%filename %set %%mode = %%str(%%file.mode)
%if %%len(%%mode) == 3
%set %%mode = '0' + %%mode
%end if
C %%filename %%mode %%file.owner %%file.group - {self.rougailconfig['systemd_tmpfile_factory_dir']}%%filename
%end if %end if
%end def %end def
%for %%service in %%services %for %%service in %%services

View file

@ -0,0 +1,22 @@
{
"services.test_service.files.file.name": {
"owner": "default",
"value": "/etc/file"
},
"services.test_service.files.file.source": {
"owner": "default",
"value": "file"
},
"services.test_service.files.file.activate": {
"owner": "default",
"value": true
},
"services.test_service.activate": {
"owner": "default",
"value": true
},
"services.test_service.manage": {
"owner": "default",
"value": true
}
}

View file

@ -0,0 +1,7 @@
{
"services.test_service.files.file.name": "/etc/file",
"services.test_service.files.file.source": "file",
"services.test_service.files.file.activate": true,
"services.test_service.activate": true,
"services.test_service.manage": true
}

View file

@ -0,0 +1,22 @@
{
"services.test_service.files.file.name": {
"owner": "default",
"value": "/etc/file"
},
"services.test_service.files.file.source": {
"owner": "default",
"value": "file"
},
"services.test_service.files.file.activate": {
"owner": "default",
"value": true
},
"services.test_service.activate": {
"owner": "default",
"value": true
},
"services.test_service.manage": {
"owner": "default",
"value": true
}
}

View file

@ -0,0 +1 @@
test

View file

@ -0,0 +1 @@
C /etc/file 1755 root root - /usr/local/lib/etc/file

View file

@ -0,0 +1,32 @@
from importlib.machinery import SourceFileLoader as _SourceFileLoader
from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec
class func:
pass
def _load_functions(path):
global _SourceFileLoader, _spec_from_loader, _module_from_spec, func
loader = _SourceFileLoader('func', path)
spec = _spec_from_loader(loader.name, loader)
func_ = _module_from_spec(spec)
loader.exec_module(func_)
for function in dir(func_):
if function.startswith('_'):
continue
setattr(func, function, getattr(func_, function))
_load_functions('tests/dictionaries/../eosfunc/test.py')
try:
from tiramisu3 import *
except:
from tiramisu import *
option_5 = FilenameOption(name="name", doc="name", default="/etc/file")
option_6 = StrOption(name="source", doc="source", default="file")
option_4 = BoolOption(name="activate", doc="activate", default=True)
optiondescription_3 = OptionDescription(name="file", doc="file", children=[option_5, option_6, option_4])
optiondescription_3.impl_set_information('mode', 1755)
optiondescription_2 = OptionDescription(name="files", doc="files", children=[optiondescription_3])
option_1 = BoolOption(name="activate", doc="activate", default=True)
option_7 = BoolOption(name="manage", doc="manage", default=True)
optiondescription_9 = OptionDescription(name="test_service", doc="test.service", children=[optiondescription_2, option_1, option_7])
optiondescription_9.impl_set_information('type', "service")
optiondescription_8 = OptionDescription(name="services", doc="services", children=[optiondescription_9], properties=frozenset({"hidden"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_8])

View file

@ -0,0 +1,45 @@
from importlib.machinery import SourceFileLoader as _SourceFileLoader
from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec
class func:
pass
def _load_functions(path):
global _SourceFileLoader, _spec_from_loader, _module_from_spec, func
loader = _SourceFileLoader('func', path)
spec = _spec_from_loader(loader.name, loader)
func_ = _module_from_spec(spec)
loader.exec_module(func_)
for function in dir(func_):
if function.startswith('_'):
continue
setattr(func, function, getattr(func_, function))
_load_functions('tests/dictionaries/../eosfunc/test.py')
try:
from tiramisu3 import *
except:
from tiramisu import *
option_5 = FilenameOption(name="name", doc="name", default="/etc/file")
option_6 = StrOption(name="source", doc="source", default="file")
option_4 = BoolOption(name="activate", doc="activate", default=True)
optiondescription_3 = OptionDescription(name="file", doc="file", children=[option_5, option_6, option_4])
optiondescription_3.impl_set_information('mode', 1755)
optiondescription_2 = OptionDescription(name="files", doc="files", children=[optiondescription_3])
option_1 = BoolOption(name="activate", doc="activate", default=True)
option_7 = BoolOption(name="manage", doc="manage", default=True)
optiondescription_17 = OptionDescription(name="test_service", doc="test.service", children=[optiondescription_2, option_1, option_7])
optiondescription_17.impl_set_information('type', "service")
optiondescription_16 = OptionDescription(name="services", doc="services", children=[optiondescription_17], properties=frozenset({"hidden"}))
optiondescription_15 = OptionDescription(name="1", doc="1", children=[optiondescription_16])
option_12 = FilenameOption(name="name", doc="name", default="/etc/file")
option_13 = StrOption(name="source", doc="source", default="file")
option_11 = BoolOption(name="activate", doc="activate", default=True)
optiondescription_10 = OptionDescription(name="file", doc="file", children=[option_12, option_13, option_11])
optiondescription_10.impl_set_information('mode', 1755)
optiondescription_9 = OptionDescription(name="files", doc="files", children=[optiondescription_10])
option_8 = BoolOption(name="activate", doc="activate", default=True)
option_14 = BoolOption(name="manage", doc="manage", default=True)
optiondescription_20 = OptionDescription(name="test_service", doc="test.service", children=[optiondescription_9, option_8, option_14])
optiondescription_20.impl_set_information('type', "service")
optiondescription_19 = OptionDescription(name="services", doc="services", children=[optiondescription_20], properties=frozenset({"hidden"}))
optiondescription_18 = OptionDescription(name="2", doc="2", children=[optiondescription_19])
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_15, optiondescription_18])

View file

@ -0,0 +1 @@
test

View file

@ -0,0 +1,8 @@
<?xml version='1.0' encoding='UTF-8'?>
<rougail version="0.10">
<services>
<service name="test">
<file mode="1755">/etc/file</file>
</service>
</services>
</rougail>

View file

@ -0,0 +1,7 @@
version: '0.10'
services:
- service:
- name: test
file:
- mode: 1755
text: /etc/file

View file

@ -80,9 +80,9 @@ def parse_dtd(elt_name, elts, space=0):
if set(enum) == {'True', 'False'} or set(enum) == {'True', 'False', 'nil'}: if set(enum) == {'True', 'False'} or set(enum) == {'True', 'False', 'nil'}:
# it's a boolean # it's a boolean
type_ = 'bool' type_ = 'bool'
elif enum == ['number']: elif enum == ['unix_permissions']:
continue continue
elif f'{name}_type' in attributes and list(attributes[f'{name}_type'].itervalues()) == ['number']: elif f'{name}_type' in attributes and list(attributes[f'{name}_type'].itervalues()) == ['unix_permissions']:
type_ = 'int' type_ = 'int'
else: else:
type_ = 'str' type_ = 'str'