documentation + fallback on condition

This commit is contained in:
Emmanuel Garette 2021-02-16 10:22:29 +01:00
parent 0585ab0b11
commit bd299e3d2b
28 changed files with 210 additions and 72 deletions

View file

@ -9,17 +9,8 @@ Rougail est un bibliothèque python3 qui permet de charger des dictionnaires (fi
## Les dictionnaires
Un dictionnaire est un fichier XML donc la structure est expliqué ci-dessous.
Un dictionnaire contient en ensemble de variable, utilisable à tout moment, notamment dans des templates.
Il est possible d'avoir plusieurs espace de nom pour classer les variables (appeler aussi "extra") mais il est aussi possible, à l'interieur de ce espace de nom de mettre des familles pour classer les variables.
Les familles et les variables peuvent être défini dans plusieurs dictionnaires. Ces dictionnaires s'aggrège alors. Il est possible de rajouter des familles des variables, des services, des éléments à un service et des contraintes.
Il est également possible de redéfinir des éléments pour changer les comportement d'une variable ou d'un service.
FIXME expliquer les noms des variables dans les extras
- [Les dictionnaires](dictionary/rougail.md)
- [Les dictionnaires extra](dictionary/extra.md)
### Les variables
@ -43,7 +34,3 @@ FIXME expliquer les noms des variables dans les extras
## Les templates
- Type creole
FIXME :
- une variable avec nom unique sauf pour extra

View file

@ -38,6 +38,8 @@ Une fonction de vérification doit prendre en compte 2 aspects important :
À partir de maintenant seule None et des valeurs en minuscule seront autorisés.
Il est possible de définir des [paramètres](../param/README.md) à cette fonction.
## Vérification des valeurs avec avertissement
Dans la contrainte, il est possible de spécifier le niveau d'erreur et le mettre en avertissement :
@ -49,5 +51,3 @@ Dans la contrainte, il est possible de spécifier le niveau d'erreur et le mettr
```
Dans ce cas une valeur avec une majuscule sera accepté, mais un message d'avertissement apparaitra.
Il est possible de définir des [paramètres](../param/README.md) à cette fonction.

View file

@ -1,5 +1,7 @@
# Les conditions
## Un condition
Les conditions permettent d'ajouter ou de supprimer des propriétés à une [variable](../variable/README.md), une [famille](../family/README.md), un [fichier](../service/file.md), un [port](../service/port.md) ou une [ip](../service/ip.md) suivant le contexte.
Nous allons nous concentrer ici sur la condition hidden_if_in, mais [il existe d'autre conditions](conditions.md).
@ -26,6 +28,8 @@ La [cible](../target/README.md) de la condition est ici "my_variable".
Donc ici la variable est caché à l'utilisateur si la variable "condition" est à True (le paramètre).
## Un condition avec plusieurs paramètres
Il est également possible de mettre plusieurs paramètre :
```
@ -43,8 +47,30 @@ Il est également possible de mettre plusieurs paramètre :
</constraints>
```
FIXME
<!ELEMENT condition ((target|param)+)>
<!ATTLIST condition fallback (True|False) "False">
<!ATTLIST condition force_condition_on_fallback (True|False) "False">
<!ATTLIST condition force_inverse_condition_on_fallback (True|False) "False">
## Une condition optionnelle
Il est possible de définir une condition avec une variable source qui n'existe pas dans toutes les contextes.
Dans ce cas, on met la condition en "optionnelle".
Si la variable source existe, la condition s'applique.
Si la variable source n'existe pas :
- si le nom fini en _if_in (par exemple hidden_if_in), l'action est forcée sans condition (les cibles sont hidden)
- si le nom fini en _if_not_in (par exemple hidden_if_not_in), la condition est totalement ignorée
Ces deux comportements peuvent être changé à tout moment avec l'attribut "apply_on_fallback". Dans ce cas :
- si la valeur de "apply_on_fallback" est "True", l'action est forcée sans condition
- si la valeur de "apply_on_fallback" est "False", la condition est totalement ignorée
Exemple :
```
<condition name="hidden_if_in" source="condition" optional="True", apply_on_fallback="False">
<param>yes</param>
<param>maybe</param>
<target>my_variable</target>
</condition>
```

12
doc/dictionary/extra.md Normal file
View file

@ -0,0 +1,12 @@
# Les dictionnaires extra
Un extra est un espace de nom différent. L'idée et de pouvoir classer les variables par thématique.
Les espaces de nom extra doivent être déclaré au moment [de la configuration de Rougail](../dev/config.md).
Dans cet espace de nom :
- des variables et des familles peuvent avoir le même nom dans différentes familles
- la valeur d'un cible, source, leader ou follower des contraintes doivent être avec un chemin complet
- on ne peut pas déclarer des services dans cet espace de nom
- dans un template il faut utiliser des chemins complet (%%my_extra.my_family.my_variable ou %%my_extra.my_family.leader.follower pour une variable suiveuse)

22
doc/dictionary/rougail.md Normal file
View file

@ -0,0 +1,22 @@
# Les dictionnaires
## Un dictionnaire ?
Un dictionnaire est un fichier XML donc la structure est décrite dans cette documentation.
Un dictionnaire contient en ensemble de variable chargé dans Tiramisu, utilisable à tout moment, notamment dans des templates.
Les familles, les variables et les contraintes peuvent être défini dans plusieurs dictionnaires. Ces dictionnaires s'aggrège alors.
Il est également possible de redéfinir des éléments pour changer les comportement d'une variable ou d'un service.
## L'espace de nom par défaut
L'espace de nom par défaut s'appelle "rougail" ([ce nom est personnalisable](../dev/config.md)).
Cet espace de nom est un peu particulier :
- le nom des variables et des familles doivent être unique pour l'ensemble de cet espace (même si ces variables ou familles sont dans des familles différentes)
- la valeur d'un cible, source, leader ou follower des contraintes peuvent être avec nom de la variable ou de la famille ou leurs chemins complet
- on peut déclarer des services dans cet espace de nom
- dans un template on peut utiliser cette variable sans le chemin complet (%%my_variable) ou avec (%%rougail.my_family.my_variable)

View file

@ -112,9 +112,7 @@ Il est possible de définir une [condition](../condition/README.md) de type "dis
</service>
</services>
<variables>
<family name="general">
<variable name="condition" type="boolean"/>
</family>
</variables>
<constraints>
<condition name="disabled_if_in" source="condition">

View file

@ -1,15 +1,72 @@
# La gestion d'une IP
## La balise ip
## La balise IP
La gestion des IP se fait dans un conteneur de [service](service.md).
FIXME
La déclaration de l'attribut permet d'associer une IP autorisé à accéder au service.
<!ELEMENT ip (#PCDATA)>
<!ATTLIST ip iplist CDATA #IMPLIED >
<!ATTLIST ip ip_type (NetworkOption|variable) "NetworkOption">
<!ATTLIST ip interface_type (UnicodeOption|variable) "UnicodeOption">
<!ATTLIST ip interface CDATA #REQUIRED>
<!ATTLIST ip netmask_type (NetmaskOption|variable) "NetmaskOption">
<!ATTLIST ip netmask CDATA "255.255.255.255">
Il est nécessaire, au minimum, de spécifier son adresse IP et l'interface :
```
<ip interface="ens3">192.168.0.1</ip>
```
L'IP peut être un variable :
```
<ip interface="ens3" ip_type="variable">variable_ip</ip>
```
## La gestion d'un réseau
L'adresse IP peut être un réseau :
```
<ip interface="ens3" netmask="255.255.255.0">192.168.0.0</ip>
```
Le masque de réseau peut être un variable :
```
<ip interface="ens3" netmask_type="variable" netmask="variable_netmask" ip_type="variable">variable_ip</ip>
```
## L'interface
Il est possible de spécifier le nom de l'interface si on la connait :
```
<ip interface="ens3">192.168.0.1</ip>
```
Mais il est possible de calculer automatiquement cette valeur :
```
<ip interface="auto">192.168.0.1</ip>
```
Dans ce cas l'interface est déduite à partir de la table de routage.
## Désactiver la génération d'une IP
Il est possible de définir une [condition](../condition/README.md) de type "disabled_if_in" ou "disabled_if_not_in" sur une balise IP :
```
<services>
<service name="test">
<ip interface="ens3" iplist="test_ip">192.168.0.1</ip>
</service>
</services>
<variables>
<variable name="condition" type="boolean"/>
</variables>
<constraints>
<condition name="disabled_if_in" source="condition">
<param>False</param>
<target type="iplist">test_ip</target>
</condition>
</constraints>
```
Dans ce cas, tous les IP avec un attribut iplist à "test_ip" seront désactivé si la variable "condition" est False.

View file

@ -1,5 +1,5 @@
# La cible
- [De type variable)](../target/variable.md)
- [De type famille)](../target/family.md)
- [De type variable](../target/variable.md)
- [De type famille](../target/family.md)
- [De type \*list](../target/list.md)

View file

@ -58,6 +58,30 @@ Il est possible d'en définit d'autres :
</constraints>
```
## Définition des variables meneuse et suiveuse dans un dictionnaire extra
Voici un exemple de définition d'une variable meneuse et de deux variables meneuses dans un espace de nom "example" :
```
<variables>
<family name="family">
<variable name="leader" multi='True'/>
<variable name="follower1"/>
<variable name="follower2" multi='True'/>
</family>
</variables>
<constraints>
<group leader="example.family.leader">
<follower>example.family.follower1</follower>
<follower>example.family.follower2</follower>
</group>
</constraints>
```
Le chemin de la variable meneuse est traditionnel, par contre le chemin des variables suiveuses n'est pas le chemin définitif de la variable.
Le chemin d'une variable suiveuse est normalement "example.family.leader.follower1" mais la variable n'est pas encore une variable suiveuse à ce moment là du traitement. C'est pour cela qu'il ne faut, uniquement dans les groupes, mettre le nom de la variable meneuse dans le chemin.
## Ajout d'une nouvelle variable suiveuse
Pour ajouter, dans un nouveau dictionnaire, une variable suiveuse à notre groupe, rien de plus simple, il suffit de redéfinir un groupe avec cette (ou ces) nouvelle variable :

View file

@ -219,4 +219,20 @@ Ces variables sont généralement des variables obligatoires. En effet ces varia
Une [variable meneuse ou suiveuse](leadership.md) ne peut pas avoir la propriété auto_freeze.
FIXME <!ATTLIST variable test CDATA #IMPLIED>
## Information "test"
L'attribut "test" est un attribut spécial qui permet aux concepteurs d'un dictionnaire d'influancer le robot de test en précisant de valeurs utile à tester.
Concrêtement, le contenu de cet attribut est enregister dans une "information" de l'option Tiramisu correspondante.
Exemple :
```
<variable name="my_variable" test="yes"/>
```
Il est possible de préciser plusieurs valeurs avec le séparateur "|" :
```
<variable name="my_variable" test="yes|no"/>
```

View file

@ -52,7 +52,7 @@ class ConditionAnnotator(TargetAnnotator, ParamAnnotator, Walk):
self.target_is_uniq = False
self.only_variable = False
self.convert_target(self.objectspace.space.constraints.condition)
self.check_condition_fallback()
self.check_condition_optional()
self.convert_condition_source()
self.convert_param(self.objectspace.space.constraints.condition)
self.check_source_target()
@ -106,19 +106,18 @@ class ConditionAnnotator(TargetAnnotator, ParamAnnotator, Walk):
f'{condition.source.path}')
raise DictConsistencyError(msg, 11, condition.xmlfiles)
def check_condition_fallback(self):
"""a condition with a fallback **and** the source variable doesn't exist
def check_condition_optional(self):
"""a condition with a optional **and** the source variable doesn't exist
"""
remove_conditions = []
for idx, condition in enumerate(self.objectspace.space.constraints.condition):
# fallback
if condition.fallback is False or \
if condition.optional is False or \
self.objectspace.paths.path_is_defined(condition.source):
continue
if condition.name in ['disabled_if_in', 'mandatory_if_in', 'hidden_if_in']:
apply_action = not condition.force_condition_on_fallback
if hasattr(condition, 'apply_on_fallback'):
apply_action = condition.apply_on_fallback
else:
apply_action = condition.force_inverse_condition_on_fallback
apply_on_fallback = condition.name.endswith('_if_in'):
remove_conditions.append(idx)
if apply_action:
self.force_actions_to_variable(condition)

View file

@ -32,7 +32,7 @@ from ..utils import normalize_family
from ..error import DictConsistencyError
# a CreoleObjSpace's attribute has some annotations
# that shall not be present in the exported (flatened) XML
ERASED_ATTRIBUTES = ('redefine', 'exists', 'fallback', 'optional', 'remove_check', 'namespace',
ERASED_ATTRIBUTES = ('redefine', 'exists', 'optional', 'remove_check', 'namespace',
'remove_condition', 'path', 'instance_mode', 'index',
'level', 'remove_fill', 'xmlfiles', 'type', 'reflector_name',
'reflector_object',)

View file

@ -197,15 +197,11 @@ class VariableAnnotator(Walk): # pylint: disable=R0903
"""Convert variable tests value
"""
for variable in self.get_variables():
self._convert_test(variable)
def _convert_test(self,
variable,
) -> None:
if not hasattr(variable, 'test'):
continue
if variable.test:
if not hasattr(variable, 'information'):
variable.information = self.objectspace.information(variable.xmlfiles)
if hasattr(variable, 'test'):
if variable.test:
values = variable.test.split('|')
new_values = []
for value in values:
@ -221,6 +217,8 @@ class VariableAnnotator(Walk): # pylint: disable=R0903
"""Convert variable help
"""
for variable in self.get_variables():
if not hasattr(variable, 'information'):
variable.information = self.objectspace.information(variable.xmlfiles)
self._convert_help(variable)
@staticmethod

View file

@ -121,9 +121,8 @@
<!ELEMENT condition ((target|param)+)>
<!ATTLIST condition name (disabled_if_in|disabled_if_not_in|hidden_if_in|hidden_if_not_in|mandatory_if_in|mandatory_if_not_in) #REQUIRED>
<!ATTLIST condition source CDATA #REQUIRED>
<!ATTLIST condition fallback (True|False) "False">
<!ATTLIST condition force_condition_on_fallback (True|False) "False">
<!ATTLIST condition force_inverse_condition_on_fallback (True|False) "False">
<!ATTLIST condition optional (True|False) "False">
<!ATTLIST condition apply_on_fallback (True|False) #IMPLIED>
<!ELEMENT param (#PCDATA)>
<!ATTLIST param type (string|number|nil|boolean|variable|information|suffix) "string">

View file

@ -16,7 +16,7 @@
</family>
</variables>
<constraints>
<condition name="disabled_if_not_in" source="unknown" fallback="True">
<condition name="disabled_if_not_in" source="unknown" optional="True">
<param>no</param>
<target type="variable">disable_variable</target>
<target type="filelist">afilllist</target>

View file

@ -15,13 +15,13 @@
</variables>
<constraints>
<condition name="disabled_if_not_in" source="unknown" force_inverse_condition_on_fallback="True" fallback="True">
<condition name="disabled_if_not_in" source="unknown" apply_on_fallback="True" optional="True">
<param>oui</param>
<target type="variable">mode_conteneur_actif</target>
<target type="variable">mode_conteneur_actif2</target>
<target type="filelist">afilllist</target>
</condition>
<condition name="disabled_if_not_in" source="activer_client_ldap" fallback="True">
<condition name="disabled_if_not_in" source="activer_client_ldap" optional="True">
<param>non</param>
<target type="variable">mode_conteneur_actif</target>
</condition>

View file

@ -20,7 +20,7 @@
<target type="variable">mode_conteneur_actif</target>
<target type="variable">mode_conteneur_actif2</target>
</condition>
<condition name="disabled_if_in" source="activer_client_ldap" fallback="True">
<condition name="disabled_if_in" source="activer_client_ldap" optional="True">
<param>non</param>
<target type="variable">mode_conteneur_actif</target>
</condition>

View file

@ -20,7 +20,7 @@
<target type="variable">mode_conteneur_actif</target>
<target type="variable">mode_conteneur_actif2</target>
</condition>
<condition name="disabled_if_in" source="activer_client_ldap" fallback="True" force_condition_on_fallback="True">
<condition name="disabled_if_in" source="activer_client_ldap" optional="True" apply_on_fallback="False">
<param>non</param>
<target type="variable">mode_conteneur_actif</target>
</condition>

View file

@ -19,7 +19,7 @@
</variables>
<constraints>
<condition name="disabled_if_in" source="activer_clam" fallback="True">
<condition name="disabled_if_in" source="activer_clam" optional="True">
<param>non</param>
<target type="filelist">afilllist</target>
</condition>

View file

@ -18,7 +18,7 @@
</variables>
<constraints>
<condition fallback="True" name="disabled_if_in" source="condition">
<condition optional="True" name="disabled_if_in" source="condition">
<param>oui</param>
<target type="variable">mode_conteneur_actif1</target>
<target type="variable" optional="True">mode_conteneur_actif2</target>

View file

@ -18,7 +18,7 @@
</variables>
<constraints>
<condition fallback="True" name="disabled_if_in" source="condition">
<condition optional="True" name="disabled_if_in" source="condition">
<param>oui</param>
<target type="variable">mode_conteneur_actif1</target>
<target type="variable" optional="True">mode_conteneur_actif2</target>

View file

@ -7,7 +7,7 @@
</variables>
<constraints>
<condition fallback="True" name="disabled_if_in" source="condition">
<condition optional="True" name="disabled_if_in" source="condition">
<param>oui</param>
<target type="variable">mode_conteneur_actif1</target>
<target type="variable" optional="True">mode_conteneur_actif2</target>

View file

@ -20,7 +20,7 @@
</variables>
<constraints>
<condition fallback="True" name="disabled_if_in" source="condition">
<condition optional="True" name="disabled_if_in" source="condition">
<param>oui</param>
<target type="variable">mode_conteneur_actif1</target>
<target type="variable" optional="True">mode_conteneur_actif2</target>

View file

@ -15,7 +15,7 @@
</variables>
<constraints>
<condition fallback="True" name="disabled_if_in" source="condition">
<condition optional="True" name="disabled_if_in" source="condition">
<param>oui</param>
<target type="variable">mode_conteneur_actif1</target>
<target type="variable" optional="True">mode_conteneur_actif2</target>

View file

@ -15,7 +15,7 @@
</variables>
<constraints>
<condition fallback="True" name="disabled_if_in" source="condition">
<condition optional="True" name="disabled_if_in" source="condition">
<param>oui</param>
<target type="variable" optional="True">mode_conteneur_actif2</target>
</condition>

View file

@ -15,7 +15,7 @@
</variables>
<constraints>
<condition fallback="True" name="hidden_if_in" source="condition">
<condition optional="True" name="hidden_if_in" source="condition">
<param>oui</param>
<target type="variable">mode_conteneur_actif1</target>
</condition>

View file

@ -18,7 +18,7 @@
</variables>
<constraints>
<condition fallback="True" name="disabled_if_in" source="condition">
<condition optional="True" name="disabled_if_in" source="condition">
<param>oui</param>
</condition>
</constraints>

View file

@ -16,7 +16,7 @@
</family>
</variables>
<constraints>
<condition name="hidden_if_in" source="activer_clam" fallback="True">
<condition name="hidden_if_in" source="activer_clam" optional="True">
<param>non</param>
<target type="filelist">afilllist</target>
</condition>