jinja and calculations
This commit is contained in:
parent
1da10b7970
commit
91112a905a
6 changed files with 267 additions and 105 deletions
|
|
@ -8,9 +8,6 @@
|
|||
Rougail
|
||||
===========
|
||||
|
||||
.. todolist::
|
||||
|
||||
|
||||
.. todo:: définir les termes suivants
|
||||
|
||||
family.rst:25: WARNING: label non défini: 'convention on variable names'
|
||||
|
|
|
|||
154
docs/tutorial/calculation.rst
Normal file
154
docs/tutorial/calculation.rst
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
Calculation with a jinja type
|
||||
===============================
|
||||
|
||||
.. objectives:: Objectives
|
||||
|
||||
In this section we will learn how to create new ways of calculation.
|
||||
|
||||
|
||||
Up to now, our only way of dynamically (that is, during the runtime) calculating
|
||||
a value is to point on another variable's value. But this is not the only way.
|
||||
|
||||
A jinja calculated variable's hidden property
|
||||
------------------------------------------------
|
||||
|
||||
We can hide or disable some variables or families with other techniques than
|
||||
pointing on a variable's value.
|
||||
|
||||
Let's reason on the previous HTTPS proxy configuration's manual mode:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
manual:
|
||||
|
||||
use_for_https:
|
||||
description: Also use this proxy for HTTPS
|
||||
default: true
|
||||
|
||||
https_proxy:
|
||||
type: family
|
||||
description: HTTPS Proxy
|
||||
hidden:
|
||||
variable: manual.use_for_https
|
||||
|
||||
|
||||
This is extracted from the proxy's manual configuration we discussed before.
|
||||
|
||||
We see here that there is an `https_proxy` family that is going to be hidden
|
||||
depending on the value of another variable:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
https_proxy:
|
||||
type: family
|
||||
hidden:
|
||||
variable: manual.use_for_https
|
||||
|
||||
Now we could write it like that:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
manual:
|
||||
|
||||
use_for_https:
|
||||
description: Also use this proxy for HTTPS
|
||||
default: true
|
||||
|
||||
https_proxy:
|
||||
description: HTTPS Proxy
|
||||
type: family
|
||||
hidden:
|
||||
type: jinja
|
||||
jinja: |
|
||||
{% if rougail.manual.use_for_https %}
|
||||
the HTTPS Proxy family is hidden
|
||||
{% endif %}
|
||||
|
||||
Yes, it's done in a more complicated (but more powerful) way.
|
||||
Let's explain this a little:
|
||||
|
||||
We have replaced this simple hidden property declaration:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
hidden:
|
||||
variable: manual.use_for_https
|
||||
|
||||
by this (more complicated) hidden property declaration:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
hidden:
|
||||
type: jinja
|
||||
jinja: |
|
||||
{% if rougail.manual.use_for_https %}
|
||||
the HTTPS Proxy family is hidden
|
||||
{% endif %}
|
||||
|
||||
The fact is that it has same result, but here we have more possibilities.
|
||||
The hidden process is done by a calculation.
|
||||
|
||||
Another jinja calculation type sample
|
||||
---------------------------------------
|
||||
|
||||
We can now hide or disable some variables or families with other techniques than
|
||||
pointing on a variable's value.
|
||||
|
||||
Let's reason upon the proxy's manual configuration we discussed before.
|
||||
We have the :file:`dict/02-proxy_manual.yml` structure file:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: the :file:`structfile/02-proxy_manual.yml` file
|
||||
|
||||
---
|
||||
version: '1.1'
|
||||
manual:
|
||||
description: Manual proxy configuration
|
||||
type: family
|
||||
disabled:
|
||||
type: jinja
|
||||
jinja: |
|
||||
{% if rougail.proxy.proxy_mode != 'Manual proxy configuration' %}
|
||||
the proxy mode is not manual
|
||||
{% endif %}
|
||||
|
||||
.. questions:: Question
|
||||
|
||||
**question**: OK then. What happens when you select the "Manual proxy configuration"?
|
||||
|
||||
Here if the user selects the "Manual proxy configuration" proxy mode,
|
||||
the the `manual` family will be disabled. This is what the jinja code says.
|
||||
Let's explain it more precisely.
|
||||
|
||||
|
||||
.. note:: The "the proxy mode is not manual" output is be used in the log outputs
|
||||
for example while
|
||||
|
||||
Why Jinja?
|
||||
---------------
|
||||
|
||||
.. questions:: What about this `Jinja` type?
|
||||
|
||||
If the :term:`Jinja` template returns some text, then the family will be `disabled`. Otherwise it is accessible.
|
||||
Deactivating a family means that we will not be able to access it as well as the variables or families included in this family.
|
||||
|
||||
.. note:: If the Jinja template does not return any text, the variable will be **enabled**.
|
||||
Here we are using the Jinja condition statement.
|
||||
|
||||
.. glossary::
|
||||
|
||||
Jinja
|
||||
|
||||
`Jinja <https://jinja.palletsprojects.com>`_ is a template engine.
|
||||
we are using Jinja in a classical way, that is, Jinja allows us to handle different cases,
|
||||
for example with the `if` statement.
|
||||
|
||||
|
||||
.. todo:: montrer aussi ici des exemples de calculs de valeurs variables, ce qui est un des usages principaux de jinja
|
||||
|
||||
.. keypoints:: Key points
|
||||
|
||||
Here we have come to the possibility of making any kind of calculations based on the state of the :term:`configuration`.
|
||||
This is an important feature to manage the stateful aspect of a configuration.
|
||||
|
||||
|
||||
|
|
@ -5,37 +5,40 @@ A dynamic family
|
|||
|
||||
.. objectives:: Objectives
|
||||
|
||||
In this section we will learn how to create a dynamically created family.
|
||||
In this section we will learn how to create a dynamically built family.
|
||||
|
||||
.. prerequisites:: Reminder
|
||||
|
||||
We handled the HTTPS mode in the previous section. But there's more.
|
||||
Let's have a look at the firefox's configuration page:
|
||||
We handled the HTTPS mode in the previous section. But there's more modes to handle.
|
||||
Let's turn back to the firefox's configuration page:
|
||||
|
||||
.. image:: images/soksv5.png
|
||||
|
||||
We see that we need to handle the SOCKS configuration in addition to the HTTPs configuration.
|
||||
Moreover, we can see that these two group of variables are very similar:
|
||||
We see that we need to handle the SOCKS configuration in addition to the HTTPS configuration.
|
||||
Moreover, we can see that these two groups of variables are similar in the structure:
|
||||
they both have a host and a port.
|
||||
|
||||
Creating a generic family
|
||||
----------------------------
|
||||
|
||||
|
||||
There are two proxies that are to be configured :
|
||||
|
||||
- the HTTP proxy
|
||||
- the HTTPS proxy
|
||||
- the SOCKS proxy
|
||||
|
||||
It's not the place here to describe what the HTTP and SOCKS protocols are.
|
||||
The interesting point here is that they are very similar in our firefox's configuration.
|
||||
As they have the same structure, would it be possible to define the two of them
|
||||
in one shot?
|
||||
|
||||
With Rougail, we can create some kind of a model of family.
|
||||
we can use a generic family declaration mode in this use case.
|
||||
We call this genericity family a "dynamic creation" because as we will see below,
|
||||
these families exist at the very moment we define their identifiers.
|
||||
.. note:: It's not the place here to describe what the HTTP and SOCKS protocols are.
|
||||
The interesting point here is that they are very similar in our firefox's
|
||||
configuration and that we can do batch processing.
|
||||
|
||||
what we could do with our current knowledge:
|
||||
With Rougail, it is possible to create some kind of a model of family.
|
||||
Kind of a generic family declaration.
|
||||
We call this generic family creation process a "dynamic creation" because as we will see below,
|
||||
these families exist at the very moment we define their **identifiers**.
|
||||
|
||||
First, here is what we need to make (without identifiers):
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
|
@ -63,14 +66,24 @@ what we could do with our current knowledge:
|
|||
description: SOCKS Port
|
||||
...
|
||||
|
||||
With Rougail we have the ability to declare our families this way:
|
||||
Now with identifiers, we have the ability to declare our families this way:
|
||||
|
||||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_037/firefox/20-manual.yml
|
||||
:language: yaml
|
||||
:caption: firefox/20-proxy.yml
|
||||
.. code-block:: yaml
|
||||
|
||||
What is an identifier?
|
||||
-------------------------
|
||||
"{{ identifier }}_proxy":
|
||||
description: "{{ identifier }} Proxy"
|
||||
dynamic:
|
||||
- HTTPS
|
||||
- SOCKS
|
||||
|
||||
address:
|
||||
description: "{{ identifier }} address"
|
||||
|
||||
port:
|
||||
description: "{{ identifier }} port"
|
||||
|
||||
What is exactly an identifier?
|
||||
-------------------------------
|
||||
|
||||
If you know a YAML declaration tool named Ansible,
|
||||
the variable used to iterate over multiple values in a task is called an **`item`**.
|
||||
|
|
@ -123,8 +136,6 @@ Here is the syntax we are using that allows the declaration of multiple families
|
|||
|
||||
This identifier is a parameter that enables us to create two families named `https_proxy` and `socks_proxy`:
|
||||
|
||||
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
https_proxy:
|
||||
|
|
@ -136,15 +147,15 @@ This identifier is a parameter that enables us to create two families named `htt
|
|||
.. note:: The declaration syntax used is the :term:`Jinja <jinja>` templating syntax,
|
||||
Jinja which is widely used in python.
|
||||
|
||||
.. attention:: Be careful when choosing your identifiers items: the family
|
||||
that will be dynamically created shall not exist already.
|
||||
.. attention:: Be careful when choosing your identifiers items: pay attention that the family
|
||||
that will be dynamically created has not been declared before in some other
|
||||
YAML structure file.
|
||||
|
||||
If you define a dynamic family with the `https` item that will
|
||||
build a `https_proxy` family and if this familiy already exist,
|
||||
then rougail will raise a warning.
|
||||
|
||||
|
||||
Besides, when we launch the rougail command line, we can have a look at the concrete variables here:
|
||||
build a `https_proxy` family and if this familiy already exists,
|
||||
then rougail will raise a family/variable override warning.
|
||||
|
||||
When we launch the rougail command line, we can have a look at the concrete families and variables that have appear:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
|
|
@ -172,15 +183,76 @@ We can see that the dynamic family has created:
|
|||
- an `HTTPS Proxy` family
|
||||
- a `SOCKS Proxy` family
|
||||
|
||||
as we wanted.
|
||||
|
||||
as we wanted, containing an address and a port.
|
||||
|
||||
A conditional hidden familiy
|
||||
--------------------------------
|
||||
|
||||
Yes we have gained in genericity but we have lost in readability, you would say.
|
||||
But we haven't just been generic. We now have the ability to create conditional hidden family
|
||||
(and not only conditionnal hidden variables like we did earlier).
|
||||
Here is the final YAML version of the HTTPS and SOCKS proxy families:
|
||||
|
||||
|
||||
We have added:
|
||||
|
||||
- a conditional hidden family property
|
||||
- a default value
|
||||
|
||||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_037/firefox/20-manual.yml
|
||||
:language: yaml
|
||||
:caption: firefox/20-proxy.yml
|
||||
|
||||
..
|
||||
---
|
||||
manual:
|
||||
|
||||
use_for_https:
|
||||
description: Also use this proxy for HTTPS
|
||||
default: true
|
||||
|
||||
"{{ identifier }}_proxy":
|
||||
description: "{{ identifier }} Proxy"
|
||||
dynamic:
|
||||
- HTTPS
|
||||
- SOCKS
|
||||
hidden:
|
||||
variable: manual.use_for_https
|
||||
|
||||
address:
|
||||
description: "{{ identifier }} address"
|
||||
default:
|
||||
variable: manual.http_proxy.address
|
||||
|
||||
port:
|
||||
description: "{{ identifier }} port"
|
||||
default:
|
||||
variable: manual.http_proxy.port
|
||||
|
||||
|
||||
The conditional property is this one:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
hidden:
|
||||
variable: manual.use_for_https
|
||||
|
||||
it uses `use_for_https` variable:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
||||
use_for_https:
|
||||
description: Also use this proxy for HTTPS
|
||||
default: true
|
||||
|
||||
|
||||
.. keypoints:: Key points
|
||||
|
||||
- We now know what a generic family is, with its identifier.
|
||||
- we now how to create default values for a variable that is calculated
|
||||
because it retrieves the value of another variable.
|
||||
- we know how to hide conditionaly a family with the same mechanism,
|
||||
that is a calculated value. It is calculated because there is a dependancy
|
||||
over another variable.
|
||||
|
||||
We will see other types of calculation in the next section.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ The values entered by the user have to be
|
|||
|
||||
- validated
|
||||
- consitent
|
||||
- conformity
|
||||
|
||||
.. todo:: explain the congruent term. or another term? compliance ? accordance ? conformity ?
|
||||
|
||||
At first glance we can see that we have a selection of five configuration options values that we need to fill in, they are highlighted here in this screenshot:
|
||||
|
||||
|
|
@ -45,4 +48,5 @@ At first glance we can see that we have a selection of five configuration option
|
|||
disabled
|
||||
boolean
|
||||
dynfam
|
||||
calculation
|
||||
|
||||
|
|
|
|||
|
|
@ -250,6 +250,9 @@ In our firefox use case, the real type of the `proxy_mode` variable will be now
|
|||
choice type
|
||||
|
||||
A choice type variable is a variable where the content is constrained by a list
|
||||
|
||||
When a variable's setting is "choice" (`type: choice`), it means that
|
||||
there is a list of available values that can be selected.
|
||||
|
||||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_013/firefox/00-proxy.yml
|
||||
:linenos:
|
||||
|
|
@ -311,12 +314,6 @@ We have the list of the possible (authorized) values:
|
|||
- `Manual proxy configuration`
|
||||
- `Automatic proxy configuration URL`
|
||||
|
||||
.. glossary::
|
||||
|
||||
choice type
|
||||
|
||||
The `proxy_mode` setting is "choice" (`type: choice`) means that
|
||||
there is a list of available values that can be selected.
|
||||
|
||||
.. keypoints:: Key points progress
|
||||
|
||||
|
|
|
|||
|
|
@ -1,68 +1,6 @@
|
|||
|
||||
:orphan:
|
||||
|
||||
The Firefox proxy: the manual configuration
|
||||
=============================================
|
||||
|
||||
.. objectives:: Objectives
|
||||
|
||||
We will learn how to: FIXME
|
||||
|
||||
|
||||
.. prerequisites:: Reminders
|
||||
|
||||
FIXME
|
||||
|
||||
The manual mode
|
||||
------------------
|
||||
|
||||
.. questions:: Question
|
||||
|
||||
**question**: OK then. What happens when you select the "Manual proxy configuration"?
|
||||
|
||||
A good configuration design is to place all the proxy's manual configuration in a :term:`family`.
|
||||
Let's create the :file:`dict/02-proxy_manual.yml` dictionary:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: the the :file:`dict/02-proxy_manual.yml` file
|
||||
|
||||
---
|
||||
version: '1.1'
|
||||
proxy:
|
||||
manual:
|
||||
description: Manual proxy configuration
|
||||
type: family
|
||||
disabled:
|
||||
type: jinja
|
||||
jinja: |
|
||||
{% if rougail.proxy.proxy_mode != 'Manual proxy configuration' %}
|
||||
the proxy mode is not manual
|
||||
{% endif %}
|
||||
|
||||
Well, if the user selects the "Manual proxy configuration" proxy mode, we want to see a new subfamily (that is, a new set of configuration variables) called `manual` to appear (which is disabled).
|
||||
|
||||
.. glossary::
|
||||
|
||||
subfamily
|
||||
|
||||
A subfamily is just a family inside a family, a family that contains a family.
|
||||
|
||||
.. questions:: What about this `Jinja` type?
|
||||
|
||||
If the :term:`Jinja` template returns some text, then the family will be `disabled`. Otherwise it is accessible.
|
||||
Deactivating a family means that we will not be able to access it as well as the variables or families included in this family.
|
||||
|
||||
.. note:: If the Jinja template does not return any text, the variable will be **enabled**.
|
||||
Here we are using the Jinja condition statement.
|
||||
|
||||
.. glossary::
|
||||
|
||||
Jinja
|
||||
|
||||
`Jinja <https://jinja.palletsprojects.com>`_ is a template engine.
|
||||
we are using Jinja in a classical way, that is, Jinja allows us to handle different cases,
|
||||
for example with the `if` statement.
|
||||
|
||||
The HTTP proxy configuration
|
||||
------------------------------
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue