feat: add rougail secret_manager
This commit is contained in:
parent
d35fe16cd9
commit
999b53889c
53 changed files with 652 additions and 64 deletions
|
@ -43,7 +43,7 @@ def tiramisu_display_name(
|
|||
"""Replace the Tiramisu display_name function to display path + description"""
|
||||
doc = kls._get_information(subconfig, "doc", None)
|
||||
comment = f" ({doc})" if doc and doc != kls.impl_getname() else ""
|
||||
if "{{ identifier }}" in comment:
|
||||
if "{{ identifier }}" in comment and subconfig.identifiers:
|
||||
comment = comment.replace("{{ identifier }}", str(subconfig.identifiers[-1]))
|
||||
path = kls.impl_getpath()
|
||||
if "{{ identifier }}" in path and subconfig.identifiers:
|
||||
|
|
|
@ -136,7 +136,9 @@ class Annotator(Walk):
|
|||
)
|
||||
if family.version == "1.0" and "{{ suffix }}" in path:
|
||||
path = path.replace("{{ suffix }}", "{{ identifier }}")
|
||||
self.objectspace.dynamics_variable.setdefault(path, []).append(family.path)
|
||||
self.objectspace.dynamics_variable.setdefault(path, []).append(
|
||||
family.path
|
||||
)
|
||||
self.objectspace.informations.add(family.path, "dynamic_variable", path)
|
||||
|
||||
def change_modes(self):
|
||||
|
@ -341,7 +343,7 @@ class Annotator(Walk):
|
|||
if self._has_mode(variable):
|
||||
msg = _(
|
||||
'the variable "{0}" is in "{1}" mode but family has the higher family mode "{2}"'
|
||||
).format(variable.name, variable_mode, family_mode)
|
||||
).format(variable.path, variable_mode, family_mode)
|
||||
raise DictConsistencyError(msg, 61, variable.xmlfiles)
|
||||
self._set_auto_mode(variable, family_mode)
|
||||
if not variable.mode:
|
||||
|
|
|
@ -69,12 +69,28 @@ class Annotator(Walk): # pylint: disable=R0903
|
|||
bool: "boolean",
|
||||
float: "float",
|
||||
}
|
||||
self.verify_secret_managers()
|
||||
self.verify_choices()
|
||||
self.convert_variable()
|
||||
self.convert_test()
|
||||
self.convert_examples()
|
||||
self.convert_help()
|
||||
|
||||
def verify_secret_managers(self):
|
||||
for variable in self.get_variables():
|
||||
if not variable.secret_manager:
|
||||
continue
|
||||
path = variable.path
|
||||
if variable.type not in ["unix_user", "secret"]:
|
||||
msg = _('only "unix_user" or "secret" variable type can have "secret_manager" attribute, but "{0}" has type "{1}"')
|
||||
raise DictConsistencyError(msg.format(path, variable.type), 56, variable.xmlfiles)
|
||||
if variable.multi and path not in self.objectspace.leaders:
|
||||
msg = _('the variable "{0}" has attribute "secret_manager" but is a multi variable')
|
||||
raise DictConsistencyError(msg.format(path), 57, variable.xmlfiles)
|
||||
if variable.default is not None:
|
||||
msg = _('the variable "{0}" has attribute "secret_manager" so must not have default value')
|
||||
raise DictConsistencyError(msg.format(path), 59, variable.xmlfiles)
|
||||
|
||||
def convert_variable(self):
|
||||
"""convert variable"""
|
||||
for variable in self.get_variables():
|
||||
|
@ -130,7 +146,9 @@ class Annotator(Walk): # pylint: disable=R0903
|
|||
):
|
||||
return
|
||||
# copy type and params
|
||||
calculated_variable, identifier = variable.default.get_variable(self.objectspace)
|
||||
calculated_variable, identifier = variable.default.get_variable(
|
||||
self.objectspace
|
||||
)
|
||||
if calculated_variable is None:
|
||||
return
|
||||
variable.type = calculated_variable.type
|
||||
|
|
|
@ -73,8 +73,7 @@ def get_level(module):
|
|||
|
||||
|
||||
class _RougailConfig:
|
||||
def __init__(self, backward_compatibility: bool,
|
||||
add_extra_options: bool):
|
||||
def __init__(self, backward_compatibility: bool, add_extra_options: bool):
|
||||
self.backward_compatibility = backward_compatibility
|
||||
self.add_extra_options = add_extra_options
|
||||
self.root = None
|
||||
|
@ -86,7 +85,9 @@ class _RougailConfig:
|
|||
)
|
||||
if self.root:
|
||||
rougailconfig.config.value.importation(self.config.value.exportation())
|
||||
rougailconfig.config.property.importation(self.config.property.exportation())
|
||||
rougailconfig.config.property.importation(
|
||||
self.config.property.exportation()
|
||||
)
|
||||
rougailconfig.config.property.read_only()
|
||||
rougailconfig.root = self.root
|
||||
rougailconfig.config = self.config
|
||||
|
@ -99,7 +100,9 @@ class _RougailConfig:
|
|||
return rougailconfig
|
||||
|
||||
def generate_config(self):
|
||||
root, extra_vars = _rougail_config(self.backward_compatibility, self.add_extra_options)
|
||||
root, extra_vars = _rougail_config(
|
||||
self.backward_compatibility, self.add_extra_options
|
||||
)
|
||||
self.root = root
|
||||
self.config = Config(
|
||||
self.root,
|
||||
|
@ -343,6 +346,13 @@ load_unexist_redefine:
|
|||
commandline: false
|
||||
default: False
|
||||
|
||||
secret_manager:
|
||||
|
||||
pattern:
|
||||
description: {_("The secret pattern to build item name in Bitwarden")}
|
||||
help: {_("The pattern is in Jinja format")}
|
||||
default: "{{{{ project }}}} - {{{{ environment }}}} - {{{{ service }}}} - {{{{ user }}}}"
|
||||
|
||||
"""
|
||||
processes = {
|
||||
"structural": [],
|
||||
|
@ -367,14 +377,22 @@ load_unexist_redefine:
|
|||
|
||||
{NAME}:
|
||||
description: Select for {NAME}
|
||||
choices:
|
||||
""".format(
|
||||
NAME=normalize_family(process),
|
||||
)
|
||||
if process != "structural":
|
||||
rougail_process += """
|
||||
alternative_name: {NAME[0]}
|
||||
""".format(
|
||||
NAME=normalize_family(process),
|
||||
)
|
||||
rougail_process += """
|
||||
choices:
|
||||
"""
|
||||
for obj in objects:
|
||||
rougail_process += f" - {obj['name']}\n"
|
||||
if process == "structural":
|
||||
# rougail_process += """ commandline: false
|
||||
# rougail_process += """ commandline: false
|
||||
rougail_process += """ multi: true
|
||||
default:
|
||||
- directory
|
||||
|
@ -391,11 +409,11 @@ load_unexist_redefine:
|
|||
jinja: |
|
||||
"""
|
||||
for hidden_output in hidden_outputs:
|
||||
rougail_process += """ {% if _.output == 'NAME' %}
|
||||
rougail_process += """ {% if _.output is not propertyerror and _.output == 'NAME' %}
|
||||
Cannot load structural for NAME output
|
||||
{% endif %}""".replace(
|
||||
"NAME", hidden_output
|
||||
)
|
||||
{% endif %}
|
||||
""".replace("NAME", hidden_output
|
||||
)
|
||||
elif process == "user data":
|
||||
rougail_process += """ multi: true
|
||||
mandatory: false"""
|
||||
|
@ -411,7 +429,7 @@ load_unexist_redefine:
|
|||
jinja: |
|
||||
"""
|
||||
for hidden_output in hidden_outputs:
|
||||
rougail_process += """ {% if _.output == 'NAME' %}
|
||||
rougail_process += """ {% if _.output is not propertyerror and _.output == 'NAME' %}
|
||||
Cannot load user data for NAME output
|
||||
{% endif %}""".replace(
|
||||
"NAME", hidden_output
|
||||
|
@ -455,10 +473,7 @@ default_params:
|
|||
mandatory: false
|
||||
default: {value}
|
||||
"""
|
||||
for process_empty in processes_empty:
|
||||
rougail_process += process_empty
|
||||
rougail_options += rougail_process
|
||||
# print(rougail_options)
|
||||
convert = FakeRougailConvert(add_extra_options)
|
||||
convert.init()
|
||||
convert.namespace = None
|
||||
|
@ -468,6 +483,13 @@ default_params:
|
|||
"1.1",
|
||||
YAML().load(rougail_options),
|
||||
)
|
||||
for process_empty in processes_empty:
|
||||
convert.parse_root_file(
|
||||
"rougail.config",
|
||||
"",
|
||||
"1.1",
|
||||
YAML().load(process_empty),
|
||||
)
|
||||
extra_vars = {}
|
||||
objects = []
|
||||
for obj in sorted(
|
||||
|
|
|
@ -179,12 +179,16 @@ class ParserVariable:
|
|||
]
|
||||
self.structurals = rougailconfig["step.structural"]
|
||||
self.user_datas = rougailconfig["step.user_data"]
|
||||
self.output = rougailconfig["step.output"]
|
||||
try:
|
||||
self.output = rougailconfig["step.output"]
|
||||
except:
|
||||
self.output = None
|
||||
self.tiramisu_cache = rougailconfig["tiramisu_cache"]
|
||||
self.load_unexist_redefine = rougailconfig["load_unexist_redefine"]
|
||||
self.secret_pattern = rougailconfig['secret_manager.pattern']
|
||||
# change default initkwargs in CONVERT_OPTION
|
||||
if hasattr(rougailconfig, 'config'):
|
||||
for sub_od in rougailconfig.config.option('default_params'):
|
||||
if hasattr(rougailconfig, "config"):
|
||||
for sub_od in rougailconfig.config.option("default_params"):
|
||||
for option in sub_od:
|
||||
if option.owner.isdefault():
|
||||
continue
|
||||
|
@ -216,9 +220,7 @@ class ParserVariable:
|
|||
family = type(
|
||||
family.__name__ + "_" + structural, (family, module.Family), {}
|
||||
)
|
||||
if "Walker" in module.__all__:
|
||||
if self.walker:
|
||||
raise Exception("multiple walker defined!")
|
||||
if not self.walker and "Walker" in module.__all__:
|
||||
self.walker = module.Walker
|
||||
self.variable = variable
|
||||
self.family = family
|
||||
|
@ -393,7 +395,7 @@ class ParserVariable:
|
|||
exists = obj.pop("exists", None)
|
||||
else:
|
||||
exists = None
|
||||
force_to_attrs = list(self.list_attributes(obj))
|
||||
force_to_attrs = list(self.list_attributes(obj, filename))
|
||||
for key, value in obj.items():
|
||||
if key in force_to_attrs:
|
||||
if key.startswith("_"):
|
||||
|
@ -406,7 +408,9 @@ class ParserVariable:
|
|||
if family_obj:
|
||||
if exists in [None, True] and not obj.pop("redefine", False):
|
||||
msg = _('family "{0}" define multiple time').format(path)
|
||||
raise DictConsistencyError(msg, 32, self.paths[path].xmlfiles + [filename])
|
||||
raise DictConsistencyError(
|
||||
msg, 32, self.paths[path].xmlfiles + [filename]
|
||||
)
|
||||
# convert to Calculation objects
|
||||
self.parse_parameters(
|
||||
path,
|
||||
|
@ -499,10 +503,17 @@ class ParserVariable:
|
|||
def list_attributes(
|
||||
self,
|
||||
obj: Dict[str, Any],
|
||||
filename: str,
|
||||
) -> Iterator[str]:
|
||||
"""List attributes"""
|
||||
force_to_variable = []
|
||||
for key, value in obj.items():
|
||||
if not isinstance(key, str):
|
||||
raise DictConsistencyError(
|
||||
f'a key is not in string format: {key}',
|
||||
103,
|
||||
[filename],
|
||||
)
|
||||
if key in force_to_variable:
|
||||
continue
|
||||
if key.startswith("_"):
|
||||
|
@ -656,13 +667,17 @@ class ParserVariable:
|
|||
version,
|
||||
)
|
||||
self.parse_params(path, obj, filename)
|
||||
self.parse_secret_manager(path, obj, filename, version, family_is_dynamic)
|
||||
exists = obj.pop("exists", None)
|
||||
if path in self.paths:
|
||||
if not self.load_unexist_redefine and exists is False:
|
||||
return
|
||||
if not obj.pop("redefine", False):
|
||||
msg = _('variable "{0}" define multiple time').format(path)
|
||||
raise DictConsistencyError(msg, 45, self.paths[path].xmlfiles + [filename])
|
||||
if not self.load_unexist_redefine:
|
||||
if exists is False:
|
||||
return
|
||||
if not obj.pop("redefine", False):
|
||||
msg = _('variable "{0}" define multiple time').format(path)
|
||||
raise DictConsistencyError(
|
||||
msg, 45, self.paths[path].xmlfiles + [filename]
|
||||
)
|
||||
self.paths.add(
|
||||
path,
|
||||
self.paths[path].model_copy(update=obj),
|
||||
|
@ -764,10 +779,11 @@ class ParserVariable:
|
|||
if "params" not in obj:
|
||||
return
|
||||
if not isinstance(obj["params"], dict):
|
||||
raise DictConsistencyError(_("params must be a dict for {0}").format(path),
|
||||
55,
|
||||
[filename],
|
||||
)
|
||||
raise DictConsistencyError(
|
||||
_("params must be a dict for {0}").format(path),
|
||||
55,
|
||||
[filename],
|
||||
)
|
||||
params = []
|
||||
for key, val in obj["params"].items():
|
||||
try:
|
||||
|
@ -780,17 +796,45 @@ class ParserVariable:
|
|||
is_follower=None,
|
||||
attribute=None,
|
||||
family_is_dynamic=None,
|
||||
namespace=self.namespace,
|
||||
xmlfiles=[filename],
|
||||
)
|
||||
)
|
||||
except ValidationError as err:
|
||||
raise DictConsistencyError(
|
||||
_('"{0}" has an invalid "params" for {1}: {2}').format(key, path, err),
|
||||
_('"{0}" has an invalid "params" for {1}: {2}').format(
|
||||
key, path, err
|
||||
),
|
||||
54,
|
||||
[filename],
|
||||
) from err
|
||||
obj["params"] = params
|
||||
|
||||
def parse_secret_manager(self, path, obj, filename, version, family_is_dynamic):
|
||||
"""Parse variable secret_manager"""
|
||||
if "secret_manager" not in obj:
|
||||
return
|
||||
if not isinstance(obj["secret_manager"], dict):
|
||||
raise DictConsistencyError(
|
||||
_("secret_manager must be a dict for {0}").format(path),
|
||||
64,
|
||||
[filename],
|
||||
)
|
||||
secret_manager = {"type": "jinja",
|
||||
"jinja": self.secret_pattern,
|
||||
"params": obj["secret_manager"],
|
||||
}
|
||||
self.set_calculation(
|
||||
obj,
|
||||
"secret_manager",
|
||||
secret_manager,
|
||||
path,
|
||||
family_is_dynamic,
|
||||
False,
|
||||
version,
|
||||
[filename],
|
||||
)
|
||||
|
||||
def add_variable(
|
||||
self,
|
||||
name: str,
|
||||
|
@ -878,6 +922,9 @@ class ParserVariable:
|
|||
calculations = calculations[1]
|
||||
if not isinstance(value, dict) or attribute not in calculations:
|
||||
return False
|
||||
return self.check_auto_type(value)
|
||||
|
||||
def check_auto_type(self, value):
|
||||
if "type" in value:
|
||||
return value["type"] in CALCULATION_TYPES
|
||||
# auto set type
|
||||
|
@ -943,6 +990,7 @@ class ParserVariable:
|
|||
val["family_is_dynamic"] = family_is_dynamic
|
||||
val["is_follower"] = is_follower
|
||||
val["attribute"] = attribute
|
||||
val["namespace"] = self.namespace
|
||||
val["xmlfiles"] = xmlfiles
|
||||
if param_typ not in PARAM_TYPES:
|
||||
raise DictConsistencyError(
|
||||
|
@ -968,7 +1016,7 @@ class ParserVariable:
|
|||
)
|
||||
#
|
||||
if typ == "identifier" and not family_is_dynamic:
|
||||
msg = f'identifier calculation for "{attribute}" in "{path}" cannot be set none dynamic family'
|
||||
msg = f'identifier calculation for "{attribute}" in "{path}" cannot be set variable is not in dynamic family'
|
||||
raise DictConsistencyError(msg, 53, xmlfiles)
|
||||
if attribute in PROPERTY_ATTRIBUTE:
|
||||
calc = CALCULATION_PROPERTY_TYPES[typ](**calculation_object)
|
||||
|
@ -1106,7 +1154,9 @@ class RougailConvert(ParserVariable):
|
|||
|
||||
def parse_directories(self) -> None:
|
||||
if not self.walker:
|
||||
msg = _('invalid "structural" definition ({0}), we cannot load any structural file!').format(self.structurals)
|
||||
msg = _(
|
||||
'invalid "structural" definition ({0}), we cannot load any structural file!'
|
||||
).format(self.structurals)
|
||||
raise DictConsistencyError(msg, 51, None)
|
||||
self.init()
|
||||
self.walker(self)
|
||||
|
|
|
@ -113,23 +113,23 @@ def get_convert_option_types():
|
|||
if obj == tiramisu.SymLinkOption:
|
||||
continue
|
||||
if obj == tiramisu.ChoiceOption:
|
||||
inst = obj('a', 'a', ('a',), **initkwargs)
|
||||
inst = obj("a", "a", ("a",), **initkwargs)
|
||||
else:
|
||||
inst = obj('a', 'a', **initkwargs)
|
||||
extra = getattr(inst, '_extra', {})
|
||||
inst = obj("a", "a", **initkwargs)
|
||||
extra = getattr(inst, "_extra", {})
|
||||
if not extra:
|
||||
continue
|
||||
params = []
|
||||
for key, value in extra.items():
|
||||
if key.startswith('_'):
|
||||
if key.startswith("_"):
|
||||
continue
|
||||
multi = False
|
||||
if isinstance(value, bool):
|
||||
key_type = 'boolean'
|
||||
key_type = "boolean"
|
||||
elif isinstance(value, str):
|
||||
key_type = 'string'
|
||||
key_type = "string"
|
||||
elif isinstance(value, list):
|
||||
key_type = 'string'
|
||||
key_type = "string"
|
||||
multi = True
|
||||
params.append((key, key_type, multi, value))
|
||||
yield typ, params
|
||||
|
@ -137,6 +137,7 @@ def get_convert_option_types():
|
|||
|
||||
class Param(BaseModel):
|
||||
key: str
|
||||
namespace: Optional[str]
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
def __init__(
|
||||
|
@ -191,19 +192,24 @@ class IndexParam(Param):
|
|||
self,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
|
||||
if not kwargs["is_follower"]:
|
||||
msg = f'the variable "{kwargs["path"]}" is not a follower, so cannot have index type for param in "{kwargs["attribute"]}"'
|
||||
raise DictConsistencyError(msg, 25, kwargs["xmlfiles"])
|
||||
super().__init__(**kwargs)
|
||||
|
||||
|
||||
class NamespaceParam(Param):
|
||||
type: str
|
||||
namespace: str
|
||||
|
||||
|
||||
PARAM_TYPES = {
|
||||
"any": AnyParam,
|
||||
"variable": VariableParam,
|
||||
"identifier": IdentifierParam,
|
||||
"information": InformationParam,
|
||||
"index": IndexParam,
|
||||
"namespace": NamespaceParam,
|
||||
}
|
||||
|
||||
|
||||
|
@ -238,7 +244,7 @@ class Calculation(BaseModel):
|
|||
)
|
||||
if not variable:
|
||||
if not param.get("optional"):
|
||||
msg = f'cannot find variable "{param["variable"]}" defined attribute in "{self.attribute_name}" for "{self.path}"'
|
||||
msg = f'cannot find variable "{param["variable"]}" defined in attribute "{self.attribute_name}" for "{self.path}"'
|
||||
raise DictConsistencyError(msg, 22, self.xmlfiles)
|
||||
continue
|
||||
if not isinstance(variable, objectspace.variable):
|
||||
|
@ -288,6 +294,7 @@ class JinjaCalculation(Calculation):
|
|||
"validators",
|
||||
"choices",
|
||||
"dynamic",
|
||||
"secret_manager",
|
||||
]
|
||||
jinja: StrictStr
|
||||
params: Optional[List[Param]] = None
|
||||
|
@ -366,7 +373,7 @@ class JinjaCalculation(Calculation):
|
|||
self,
|
||||
objectspace,
|
||||
) -> dict:
|
||||
if self.attribute_name == "default":
|
||||
if self.attribute_name in ["default", "secret_manager"]:
|
||||
if self.return_type:
|
||||
raise Exception("return_type not allowed!")
|
||||
variable = objectspace.paths[self.path]
|
||||
|
@ -474,7 +481,8 @@ class _VariableCalculation(Calculation):
|
|||
"variable": variable,
|
||||
"propertyerror": self.propertyerror,
|
||||
}
|
||||
if isinstance(self, VariableCalculation) and self.optional:
|
||||
is_variable_calculation = isinstance(self, VariableCalculation)
|
||||
if is_variable_calculation and self.optional:
|
||||
param["optional"] = self.optional
|
||||
if identifier:
|
||||
param["identifier"] = identifier
|
||||
|
@ -520,9 +528,10 @@ class _VariableCalculation(Calculation):
|
|||
variable.multi
|
||||
or variable.path.rsplit(".", 1)[0] != self.path.rsplit(".", 1)[0]
|
||||
):
|
||||
# it's not a follower or not in same leadership
|
||||
msg = f'the variable "{self.path}" has an invalid attribute "{self.attribute_name}", the variable "{variable.path}" is a multi'
|
||||
raise DictConsistencyError(msg, 21, self.xmlfiles)
|
||||
if is_variable_calculation:
|
||||
# it's not a follower or not in same leadership
|
||||
msg = f'the variable "{self.path}" has an invalid attribute "{self.attribute_name}", the variable "{variable.path}" is a multi'
|
||||
raise DictConsistencyError(msg, 21, self.xmlfiles)
|
||||
else:
|
||||
params[None][0]["index"] = {"index": {"type": "index"}}
|
||||
if self.path in objectspace.followers:
|
||||
|
@ -598,9 +607,12 @@ class VariablePropertyCalculation(_VariableCalculation):
|
|||
when = self.when_not
|
||||
inverse = True
|
||||
else:
|
||||
if variable.type != "boolean":
|
||||
raise Exception("only boolean!")
|
||||
when = True
|
||||
if variable.multi:
|
||||
when = []
|
||||
else:
|
||||
if variable.type != "boolean":
|
||||
raise Exception("only boolean!")
|
||||
when = True
|
||||
inverse = False
|
||||
params["when"] = when
|
||||
params["inverse"] = inverse
|
||||
|
@ -737,13 +749,31 @@ class IndexCalculation(Calculation):
|
|||
}
|
||||
|
||||
|
||||
class NamespaceCalculation(Calculation):
|
||||
attribute_name: Literal["default", "secret_manager"]
|
||||
|
||||
def to_function(
|
||||
self,
|
||||
objectspace,
|
||||
) -> dict:
|
||||
namespace = objectspace.namespace
|
||||
if namespace:
|
||||
namespace = objectspace.paths[namespace].description
|
||||
return {
|
||||
"function": "calc_value",
|
||||
"params": {None: [namespace]},
|
||||
}
|
||||
|
||||
|
||||
CALCULATION_TYPES = {
|
||||
"jinja": JinjaCalculation,
|
||||
"information": InformationCalculation,
|
||||
"variable": VariableCalculation,
|
||||
"identifier": IdentifierCalculation,
|
||||
# FOR VERSION 1.0
|
||||
"suffix": IdentifierCalculation,
|
||||
"index": IndexCalculation,
|
||||
"namespace": NamespaceCalculation,
|
||||
}
|
||||
CALCULATION_PROPERTY_TYPES = {
|
||||
"jinja": JinjaCalculation,
|
||||
|
@ -753,6 +783,7 @@ CALCULATION_PROPERTY_TYPES = {
|
|||
"index": IndexCalculation,
|
||||
}
|
||||
BASETYPE_CALC = Union[StrictBool, StrictInt, StrictFloat, StrictStr, Calculation, None]
|
||||
SECRET_BASETYPE_CALC = Union[StrictStr, JinjaCalculation]
|
||||
|
||||
|
||||
class Family(BaseModel):
|
||||
|
@ -799,6 +830,7 @@ class Variable(BaseModel):
|
|||
validators: Optional[List[Calculation]] = None
|
||||
# value
|
||||
default: Union[List[BASETYPE_CALC], BASETYPE_CALC] = None
|
||||
secret_manager: Optional[JinjaCalculation] = None
|
||||
# properties
|
||||
auto_save: bool = False
|
||||
mandatory: Union[None, bool, Calculation] = None
|
||||
|
|
|
@ -86,8 +86,10 @@ def test_propertyerror(value: Any) -> bool:
|
|||
ENV.tests["propertyerror"] = test_propertyerror
|
||||
|
||||
|
||||
def load_functions(path):
|
||||
def load_functions(path, dict_func=None):
|
||||
global _SourceFileLoader, _spec_from_loader, _module_from_spec, func
|
||||
if dict_func is None:
|
||||
dict_func = func
|
||||
loader = _SourceFileLoader("func", path)
|
||||
spec = _spec_from_loader(loader.name, loader)
|
||||
func_ = _module_from_spec(spec)
|
||||
|
@ -95,7 +97,7 @@ def load_functions(path):
|
|||
for function in dir(func_):
|
||||
if function.startswith("_"):
|
||||
continue
|
||||
func[function] = getattr(func_, function)
|
||||
dict_func[function] = getattr(func_, function)
|
||||
|
||||
|
||||
def rougail_calc_value(*args, __default_value=None, __internal_multi=False, **kwargs):
|
||||
|
@ -107,6 +109,21 @@ def rougail_calc_value(*args, __default_value=None, __internal_multi=False, **kw
|
|||
return values
|
||||
|
||||
|
||||
def kw_to_string(kw, root=None):
|
||||
# {'_': {'interfaces': {'ip': ['192.168.44.19', '192.168.44.12'], 'domain_name': ['nginx-reverse-proxy.reverseproxy.test.net', 'nginx-reverse-proxy.localdns.test.net']}, 'dns_client_address': 'nginx-reverse-proxy.localdns.test.net'}}
|
||||
for name, data in kw.items():
|
||||
if root is None:
|
||||
path = name
|
||||
else:
|
||||
path = root + '.' + name
|
||||
if isinstance(data, dict):
|
||||
yield from kw_to_string(data, root=path)
|
||||
else:
|
||||
yield f"{path}={data}"
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@function_waiting_for_error
|
||||
def jinja_to_function(
|
||||
__internal_variable,
|
||||
|
@ -144,12 +161,13 @@ def jinja_to_function(
|
|||
try:
|
||||
values = ENV.get_template(__internal_jinja).render(kw, **func).strip()
|
||||
except Exception as err:
|
||||
kw_str = ", ".join(kw_to_string(kw))
|
||||
raise ConfigError(
|
||||
f'cannot calculating "{__internal_attribute}" attribute for variable "{__internal_variable}" in {display_xmlfiles(__internal_files)}: {err}'
|
||||
f'cannot calculating "{__internal_attribute}" attribute for variable "{__internal_variable}" in {display_xmlfiles(__internal_files)} with parameters "{kw_str}": {err}'
|
||||
) from err
|
||||
convert = CONVERT_OPTION[__internal_type].get("func", str)
|
||||
if __internal_multi:
|
||||
values = [convert(val) for val in values.split("\n") if val != ""]
|
||||
values = [convert(val.strip()) for val in values.split("\n") if val.strip() != ""]
|
||||
if not values and __default_value is not None:
|
||||
return __default_value
|
||||
return values
|
||||
|
@ -204,6 +222,7 @@ func["jinja_to_property"] = jinja_to_property
|
|||
func["jinja_to_property_help"] = jinja_to_property_help
|
||||
func["variable_to_property"] = variable_to_property
|
||||
func["valid_with_jinja"] = valid_with_jinja
|
||||
func["normalize_family"] = normalize_family
|
||||
|
||||
|
||||
class ConvertDynOptionDescription(DynOptionDescription):
|
||||
|
|
|
@ -350,6 +350,11 @@ class Common:
|
|||
else:
|
||||
value = str(param["value"])
|
||||
return "ParamValue(" + value + ")"
|
||||
if param["type"] == "namespace":
|
||||
namespace = param["namespace"]
|
||||
if namespace:
|
||||
namespace = self.objectspace.paths[param["namespace"]].description
|
||||
return f"ParamValue('{namespace}')"
|
||||
raise Exception("pfff")
|
||||
|
||||
def build_option_param(
|
||||
|
|
|
@ -23,7 +23,12 @@ from typing import List
|
|||
from re import findall
|
||||
|
||||
from tiramisu import undefined, Calculation
|
||||
from tiramisu.error import PropertiesOptionError, LeadershipError, ConfigError, CancelParam
|
||||
from tiramisu.error import (
|
||||
PropertiesOptionError,
|
||||
LeadershipError,
|
||||
ConfigError,
|
||||
CancelParam,
|
||||
)
|
||||
|
||||
from .i18n import _
|
||||
from .object_model import CONVERT_OPTION
|
||||
|
@ -151,8 +156,15 @@ class UserDatas:
|
|||
if path not in self.values:
|
||||
continue
|
||||
options = self.values[path].get("options", {})
|
||||
if options.get('allow_secrets_variables', True) is False and option.type() == 'password':
|
||||
self.errors.append(_('the variable "{0}" contains secrets and should not be defined in {1}').format(path, self.values[path]["source"]))
|
||||
if (
|
||||
options.get("allow_secrets_variables", True) is False
|
||||
and option.type() == "password"
|
||||
):
|
||||
self.errors.append(
|
||||
_(
|
||||
'the variable "{0}" contains secrets and should not be defined in {1}'
|
||||
).format(path, self.values[path]["source"])
|
||||
)
|
||||
continue
|
||||
value = self.values[path]["values"]
|
||||
needs_convert = options.get("needs_convert", False)
|
||||
|
@ -212,7 +224,9 @@ class UserDatas:
|
|||
option = self.config.option(path)
|
||||
if option.isoptiondescription():
|
||||
self.errors.warnings(
|
||||
_('the option "{0}" is an option description').format(option.path())
|
||||
_('the option "{0}" is an option description').format(
|
||||
option.path()
|
||||
)
|
||||
)
|
||||
continue
|
||||
value = data["values"]
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"rougail.variable": {
|
||||
"owner": "default",
|
||||
"value": "Rougail"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"rougail.variable": "Rougail"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"rougail.variable": {
|
||||
"owner": "default",
|
||||
"value": "Rougail"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1,15 @@
|
|||
from tiramisu import *
|
||||
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
|
||||
from re import compile as re_compile
|
||||
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
|
||||
load_functions('../rougail-tests/funcs/test.py')
|
||||
try:
|
||||
groups.namespace
|
||||
except:
|
||||
groups.addgroup('namespace')
|
||||
ALLOWED_LEADER_PROPERTIES.add("basic")
|
||||
ALLOWED_LEADER_PROPERTIES.add("standard")
|
||||
ALLOWED_LEADER_PROPERTIES.add("advanced")
|
||||
option_2 = StrOption(name="variable", doc="a variable", default=Calculation(func['calc_value'], Params((ParamValue("Rougail")))), properties=frozenset({"standard"}), informations={'type': 'string'})
|
||||
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2], properties=frozenset({"standard"}))
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"rougail.variable": {
|
||||
"owner": "default",
|
||||
"value": "Rougail"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"rougail.variable": "Rougail"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"rougail.variable": {
|
||||
"owner": "default",
|
||||
"value": "Rougail"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1,16 @@
|
|||
from tiramisu import *
|
||||
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
|
||||
from re import compile as re_compile
|
||||
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
|
||||
load_functions('../rougail-tests/funcs/test.py')
|
||||
try:
|
||||
groups.namespace
|
||||
except:
|
||||
groups.addgroup('namespace')
|
||||
ALLOWED_LEADER_PROPERTIES.add("basic")
|
||||
ALLOWED_LEADER_PROPERTIES.add("standard")
|
||||
ALLOWED_LEADER_PROPERTIES.add("advanced")
|
||||
dict_env['default_rougail.variable'] = "{{ namespace }}"
|
||||
option_2 = StrOption(name="variable", doc="a variable", default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_rougail.variable"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/00_8calculation_param_namespace/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("rougail.variable"), 'namespace': ParamValue('Rougail')})), properties=frozenset({"standard"}), informations={'type': 'string'})
|
||||
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2], properties=frozenset({"standard"}))
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"rougail.condition": {
|
||||
"owner": "default",
|
||||
"value": []
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"rougail.condition": []
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"rougail.condition": {
|
||||
"owner": "default",
|
||||
"value": []
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
["rougail.condition"]
|
|
@ -0,0 +1,16 @@
|
|||
from tiramisu import *
|
||||
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
|
||||
from re import compile as re_compile
|
||||
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
|
||||
load_functions('../rougail-tests/funcs/test.py')
|
||||
try:
|
||||
groups.namespace
|
||||
except:
|
||||
groups.addgroup('namespace')
|
||||
ALLOWED_LEADER_PROPERTIES.add("basic")
|
||||
ALLOWED_LEADER_PROPERTIES.add("standard")
|
||||
ALLOWED_LEADER_PROPERTIES.add("advanced")
|
||||
option_2 = StrOption(name="condition", doc="a condition", multi=True, properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
|
||||
option_3 = StrOption(name="variable", doc="a variable", multi=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((ParamValue("disabled"), ParamOption(option_2)), kwargs={'__internal_multi': ParamValue(True), 'when': ParamValue([]), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'type': 'string'})
|
||||
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3], properties=frozenset({"basic"}))
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
|
|
@ -0,0 +1,11 @@
|
|||
from tiramisu import *
|
||||
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
|
||||
from re import compile as re_compile
|
||||
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
|
||||
load_functions('../rougail-tests/funcs/test.py')
|
||||
ALLOWED_LEADER_PROPERTIES.add("basic")
|
||||
ALLOWED_LEADER_PROPERTIES.add("standard")
|
||||
ALLOWED_LEADER_PROPERTIES.add("advanced")
|
||||
option_1 = StrOption(name="condition", doc="a condition", multi=True, properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
|
||||
option_2 = StrOption(name="variable", doc="a variable", multi=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((ParamValue("disabled"), ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(True), 'when': ParamValue([]), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'type': 'string'})
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2])
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"rougail.condition": {
|
||||
"owner": "default",
|
||||
"value": [
|
||||
"val1",
|
||||
"val2"
|
||||
]
|
||||
},
|
||||
"rougail.variable": {
|
||||
"owner": "default",
|
||||
"value": []
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"rougail.condition": [
|
||||
"val1",
|
||||
"val2"
|
||||
],
|
||||
"rougail.variable": []
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"rougail.condition": {
|
||||
"owner": "default",
|
||||
"value": [
|
||||
"val1",
|
||||
"val2"
|
||||
]
|
||||
},
|
||||
"rougail.variable": {
|
||||
"owner": "default",
|
||||
"value": []
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
["rougail.variable"]
|
|
@ -0,0 +1,16 @@
|
|||
from tiramisu import *
|
||||
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
|
||||
from re import compile as re_compile
|
||||
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
|
||||
load_functions('../rougail-tests/funcs/test.py')
|
||||
try:
|
||||
groups.namespace
|
||||
except:
|
||||
groups.addgroup('namespace')
|
||||
ALLOWED_LEADER_PROPERTIES.add("basic")
|
||||
ALLOWED_LEADER_PROPERTIES.add("standard")
|
||||
ALLOWED_LEADER_PROPERTIES.add("advanced")
|
||||
option_2 = StrOption(name="condition", doc="a condition", multi=True, default=["val1", "val2"], default_multi="val1", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
|
||||
option_3 = StrOption(name="variable", doc="a variable", multi=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((ParamValue("disabled"), ParamOption(option_2)), kwargs={'__internal_multi': ParamValue(True), 'when': ParamValue([]), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'type': 'string'})
|
||||
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3], properties=frozenset({"basic"}))
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
|
|
@ -0,0 +1,11 @@
|
|||
from tiramisu import *
|
||||
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
|
||||
from re import compile as re_compile
|
||||
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
|
||||
load_functions('../rougail-tests/funcs/test.py')
|
||||
ALLOWED_LEADER_PROPERTIES.add("basic")
|
||||
ALLOWED_LEADER_PROPERTIES.add("standard")
|
||||
ALLOWED_LEADER_PROPERTIES.add("advanced")
|
||||
option_1 = StrOption(name="condition", doc="a condition", multi=True, default=["val1", "val2"], default_multi="val1", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
|
||||
option_2 = StrOption(name="variable", doc="a variable", multi=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((ParamValue("disabled"), ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(True), 'when': ParamValue([]), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'type': 'string'})
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2])
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"rougail.var": {
|
||||
"owner": "default",
|
||||
"value": [
|
||||
"val.1",
|
||||
"val.2"
|
||||
]
|
||||
},
|
||||
"rougail.dynval_1.var1": {
|
||||
"owner": "default",
|
||||
"value": "val.1"
|
||||
},
|
||||
"rougail.dynval_1.var2": {
|
||||
"owner": "default",
|
||||
"value": "val.1"
|
||||
},
|
||||
"rougail.dynval_2.var1": {
|
||||
"owner": "default",
|
||||
"value": "val.2"
|
||||
},
|
||||
"rougail.dynval_2.var2": {
|
||||
"owner": "default",
|
||||
"value": "val.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"rougail.var": [
|
||||
"val.1",
|
||||
"val.2"
|
||||
],
|
||||
"rougail.dynval_1.var1": "val.1",
|
||||
"rougail.dynval_1.var2": "val.1",
|
||||
"rougail.dynval_2.var1": "val.2",
|
||||
"rougail.dynval_2.var2": "val.2"
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"rougail.var": {
|
||||
"owner": "default",
|
||||
"value": [
|
||||
"val.1",
|
||||
"val.2"
|
||||
]
|
||||
},
|
||||
"rougail.dynval_1.var1": {
|
||||
"owner": "default",
|
||||
"value": "val.1"
|
||||
},
|
||||
"rougail.dynval_1.var2": {
|
||||
"owner": "default",
|
||||
"value": "val.1"
|
||||
},
|
||||
"rougail.dynval_2.var1": {
|
||||
"owner": "default",
|
||||
"value": "val.2"
|
||||
},
|
||||
"rougail.dynval_2.var2": {
|
||||
"owner": "default",
|
||||
"value": "val.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1,19 @@
|
|||
from tiramisu import *
|
||||
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
|
||||
from re import compile as re_compile
|
||||
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
|
||||
load_functions('../rougail-tests/funcs/test.py')
|
||||
try:
|
||||
groups.namespace
|
||||
except:
|
||||
groups.addgroup('namespace')
|
||||
ALLOWED_LEADER_PROPERTIES.add("basic")
|
||||
ALLOWED_LEADER_PROPERTIES.add("standard")
|
||||
ALLOWED_LEADER_PROPERTIES.add("advanced")
|
||||
dict_env['default_rougail.dyn{{ identifier }}.var2'] = "{{ identifier }}"
|
||||
option_2 = StrOption(name="var", doc="A suffix variable", multi=True, default=["val.1", "val.2"], default_multi="val.1", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
|
||||
option_4 = StrOption(name="var1", doc="A dynamic variable", default=Calculation(func['calc_value'], Params((ParamIdentifier()))), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
|
||||
option_5 = StrOption(name="var2", doc="A dynamic variable", default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_rougail.dyn{{ identifier }}.var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/60_0family_dynamic_forbidden_char/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("rougail.dyn{{ identifier }}.var2"), 'identifier': ParamIdentifier()})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
|
||||
optiondescription_3 = ConvertDynOptionDescription(name="dyn{{ identifier }}", doc="A dynamic family", identifiers=Calculation(func['calc_value'], Params((ParamOption(option_2)))), children=[option_4, option_5], properties=frozenset({"standard"}), informations={'dynamic_variable': 'rougail.var'})
|
||||
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, optiondescription_3], properties=frozenset({"standard"}))
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
|
|
@ -0,0 +1,14 @@
|
|||
from tiramisu import *
|
||||
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
|
||||
from re import compile as re_compile
|
||||
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
|
||||
load_functions('../rougail-tests/funcs/test.py')
|
||||
ALLOWED_LEADER_PROPERTIES.add("basic")
|
||||
ALLOWED_LEADER_PROPERTIES.add("standard")
|
||||
ALLOWED_LEADER_PROPERTIES.add("advanced")
|
||||
dict_env['default_dyn{{ identifier }}.var2'] = "{{ identifier }}"
|
||||
option_1 = StrOption(name="var", doc="A suffix variable", multi=True, default=["val.1", "val.2"], default_multi="val.1", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
|
||||
option_3 = StrOption(name="var1", doc="A dynamic variable", default=Calculation(func['calc_value'], Params((ParamIdentifier()))), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
|
||||
option_4 = StrOption(name="var2", doc="A dynamic variable", default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_dyn{{ identifier }}.var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/60_0family_dynamic_forbidden_char/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("dyn{{ identifier }}.var2"), 'identifier': ParamIdentifier()})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
|
||||
optiondescription_2 = ConvertDynOptionDescription(name="dyn{{ identifier }}", doc="A dynamic family", identifiers=Calculation(func['calc_value'], Params((ParamOption(option_1)))), children=[option_3, option_4], properties=frozenset({"standard"}), informations={'dynamic_variable': 'var'})
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2])
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"rougail.var1": {
|
||||
"owner": "default",
|
||||
"value": []
|
||||
},
|
||||
"rougail.var2": {
|
||||
"owner": "default",
|
||||
"value": null
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"rougail.var1": [],
|
||||
"rougail.var2": null
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"rougail.var1": {
|
||||
"owner": "default",
|
||||
"value": []
|
||||
},
|
||||
"rougail.var2": {
|
||||
"owner": "default",
|
||||
"value": null
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
["rougail.var2"]
|
|
@ -0,0 +1,18 @@
|
|||
from tiramisu import *
|
||||
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
|
||||
from re import compile as re_compile
|
||||
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
|
||||
load_functions('../rougail-tests/funcs/test.py')
|
||||
try:
|
||||
groups.namespace
|
||||
except:
|
||||
groups.addgroup('namespace')
|
||||
ALLOWED_LEADER_PROPERTIES.add("basic")
|
||||
ALLOWED_LEADER_PROPERTIES.add("standard")
|
||||
ALLOWED_LEADER_PROPERTIES.add("advanced")
|
||||
option_2 = StrOption(name="var1", doc="A suffix variable", multi=True, properties=frozenset({"standard"}), informations={'type': 'string', 'test': ('val1',)})
|
||||
option_4 = StrOption(name="var", doc="A dynamic variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
|
||||
optiondescription_3 = ConvertDynOptionDescription(name="dyn{{ identifier }}", doc="dyn{{ identifier }}", identifiers=Calculation(func['calc_value'], Params((ParamOption(option_2)))), children=[option_4], properties=frozenset({"basic"}), informations={'dynamic_variable': 'rougail.var1'})
|
||||
option_5 = StrOption(name="var2", doc="A variable calculated", default=Calculation(func['calc_value'], Params((ParamDynOption(option_4, ["val1"], optional=True)))), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
|
||||
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, optiondescription_3, option_5], properties=frozenset({"basic"}))
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"rougail.var2": {
|
||||
"owner": "default",
|
||||
"value": null
|
||||
},
|
||||
"rougail.var1": {
|
||||
"owner": "default",
|
||||
"value": []
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"rougail.var2": null,
|
||||
"rougail.var1": []
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"rougail.var2": {
|
||||
"owner": "default",
|
||||
"value": null
|
||||
},
|
||||
"rougail.var1": {
|
||||
"owner": "default",
|
||||
"value": []
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
["rougail.var2"]
|
|
@ -0,0 +1,18 @@
|
|||
from tiramisu import *
|
||||
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
|
||||
from re import compile as re_compile
|
||||
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
|
||||
load_functions('../rougail-tests/funcs/test.py')
|
||||
try:
|
||||
groups.namespace
|
||||
except:
|
||||
groups.addgroup('namespace')
|
||||
ALLOWED_LEADER_PROPERTIES.add("basic")
|
||||
ALLOWED_LEADER_PROPERTIES.add("standard")
|
||||
ALLOWED_LEADER_PROPERTIES.add("advanced")
|
||||
option_5 = StrOption(name="var", doc="A dynamic variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
|
||||
option_2 = StrOption(name="var2", doc="A variable calculated", default=Calculation(func['calc_value'], Params((ParamDynOption(option_5, ["val1"], optional=True)))), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
|
||||
option_3 = StrOption(name="var1", doc="A suffix variable", multi=True, properties=frozenset({"standard"}), informations={'type': 'string', 'test': ('val1', 'val2')})
|
||||
optiondescription_4 = ConvertDynOptionDescription(name="dyn{{ identifier }}", doc="dyn{{ identifier }}", identifiers=Calculation(func['calc_value'], Params((ParamOption(option_3)))), children=[option_5], properties=frozenset({"basic"}), informations={'dynamic_variable': 'rougail.var1'})
|
||||
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3, optiondescription_4], properties=frozenset({"basic"}))
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"rougail.var": {
|
||||
"owner": "default",
|
||||
"value": [
|
||||
"val1",
|
||||
"val2"
|
||||
]
|
||||
},
|
||||
"rougail.my_dyn_family_val1.var": {
|
||||
"owner": "default",
|
||||
"value": "val1"
|
||||
},
|
||||
"rougail.my_dyn_family_val2.var": {
|
||||
"owner": "default",
|
||||
"value": "val2"
|
||||
},
|
||||
"rougail.var2": {
|
||||
"owner": "default",
|
||||
"value": [
|
||||
"val1",
|
||||
"val2"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"rougail.var": [
|
||||
"val1",
|
||||
"val2"
|
||||
],
|
||||
"rougail.my_dyn_family_val1.var": "val1",
|
||||
"rougail.my_dyn_family_val2.var": "val2",
|
||||
"rougail.var2": [
|
||||
"val1",
|
||||
"val2"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"rougail.var": {
|
||||
"owner": "default",
|
||||
"value": [
|
||||
"val1",
|
||||
"val2"
|
||||
]
|
||||
},
|
||||
"rougail.my_dyn_family_val1.var": {
|
||||
"owner": "default",
|
||||
"value": "val1"
|
||||
},
|
||||
"rougail.my_dyn_family_val2.var": {
|
||||
"owner": "default",
|
||||
"value": "val2"
|
||||
},
|
||||
"rougail.var2": {
|
||||
"owner": "default",
|
||||
"value": [
|
||||
"val1",
|
||||
"val2"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1,18 @@
|
|||
from tiramisu import *
|
||||
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
|
||||
from re import compile as re_compile
|
||||
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
|
||||
load_functions('../rougail-tests/funcs/test.py')
|
||||
try:
|
||||
groups.namespace
|
||||
except:
|
||||
groups.addgroup('namespace')
|
||||
ALLOWED_LEADER_PROPERTIES.add("basic")
|
||||
ALLOWED_LEADER_PROPERTIES.add("standard")
|
||||
ALLOWED_LEADER_PROPERTIES.add("advanced")
|
||||
option_2 = StrOption(name="var", doc="a suffix variable", multi=True, default=["val1", "val2"], default_multi="val1", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
|
||||
option_4 = StrOption(name="var", doc="a variable inside a dynamic family", default=Calculation(func['calc_value'], Params((ParamIdentifier()))), properties=frozenset({"standard"}), informations={'type': 'string'})
|
||||
optiondescription_3 = ConvertDynOptionDescription(name="my_dyn_family_{{ identifier }}", doc="a dynamic family", identifiers=Calculation(func['calc_value'], Params((ParamOption(option_2, notraisepropertyerror=True)), kwargs={'allow_none': ParamValue(True)})), children=[option_4], properties=frozenset({"standard"}), informations={'dynamic_variable': 'rougail.var'})
|
||||
option_5 = StrOption(name="var2", doc="a variable", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_4)), kwargs={'__internal_multi': ParamValue(True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
|
||||
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, optiondescription_3, option_5], properties=frozenset({"standard"}))
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
|
|
@ -45,7 +45,7 @@ excludes = set([
|
|||
])
|
||||
test_ok -= excludes
|
||||
test_raise -= excludes
|
||||
# test_ok = ['00_9default_calculation_multi_optional']
|
||||
# test_ok = ['00_8calculation_param_namespace']
|
||||
#test_ok = []
|
||||
#test_raise = ['88valid_enum_invalid_default']
|
||||
#test_raise = []
|
||||
|
|
Loading…
Reference in a new issue