450 lines
17 KiB
ReStructuredText
450 lines
17 KiB
ReStructuredText
Some suitable types
|
||
=====================
|
||
|
||
.. objectives:: Objectives
|
||
|
||
There aren't just the basic available types such as `string`, `integer` or `boolean`,
|
||
that are some much more suited to our use case, such as `domainname` or `port`.
|
||
|
||
.. prerequisites:: Prerequisites
|
||
|
||
- We assume that Rougail's library is :ref:`installed <installation>` on your computer.
|
||
|
||
- It is possible to retrieve the current state of the various Rougail files manipulated in this tutorial step
|
||
by checking out the corresponding tag of the `rougail-tutorials` git repository.
|
||
Each tag corresponds to a stage of progress in the tutorial.
|
||
Of course, you can also decide to copy/paste or download the tutorial files contents while following the tutorial steps.
|
||
|
||
If you want to follow this tutorial with the help of the corresponding :tutorial:`rougail-tutorials git repository <src/branch/1.1>`,
|
||
this workshop page corresponds to the tags :tutorial:`v1.1_030 <src/tag/v1.1_030>` to :tutorial:`v1.1_033 <src/tag/v1.1_033>`
|
||
in the repository.
|
||
|
||
::
|
||
|
||
git clone https://forge.cloud.silique.fr/stove/rougail-tutorials.git
|
||
git switch --detach v1.1_030
|
||
|
||
.. type-along:: let's recap how far we've come
|
||
|
||
We have an `http_proxy` family with an `address` variable in it.
|
||
|
||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_030/firefox/10-manual.yml
|
||
:language: yaml
|
||
:caption: An `address` variable in the `http_proxy` family
|
||
|
||
..
|
||
manual: # Manual proxy configuration
|
||
http_proxy: # HTTP Proxy
|
||
address:
|
||
description: HTTP address
|
||
type: domainname
|
||
|
||
:tutorial:`Download this file from the rougail-tutorials git repository <src/tag/v1.1_030/firefox/10-manual.yml>`
|
||
|
||
A variable with type `domainname`
|
||
-----------------------------------
|
||
|
||
Notice that we have assigned a type to this variable:
|
||
|
||
.. code-block:: yaml
|
||
:linenos:
|
||
:caption: The `address` variable with the `domainname` type assigned
|
||
|
||
address:
|
||
type: domainname
|
||
|
||
Assigning a type is convenient for reading, but what else does it bring?
|
||
|
||
Well, with a correct user data like this one,
|
||
|
||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_030/config/01/config.yml
|
||
:language: yaml
|
||
:caption: A domain name user data setting
|
||
|
||
..
|
||
---
|
||
manual:
|
||
http_proxy:
|
||
address: net.example
|
||
|
||
:tutorial:`Download this file from the rougail-tutorials git repository <src/tag/v1.1_030/config/01/config.yml>`
|
||
|
||
if we launch the Rougail CLI on it:
|
||
|
||
.. raw:: html
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_030/config/01/cmd_ro.txt
|
||
:class: terminal
|
||
|
||
..
|
||
rougail -m firefox/ -u yaml -yf config/01/config.yml
|
||
|
||
We have this output:
|
||
|
||
.. raw:: html
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_030/config/01/output_ro.html
|
||
:class: output
|
||
..
|
||
<pre>╭──────── Caption ────────╮
|
||
│ Variable <span style="color: #ffd700">Default value</span> │
|
||
│ <span style="color: #00aa00">Modified value</span> │
|
||
╰─────────────────────────╯
|
||
Variables:
|
||
<span style="color: #5c5cff">┣━━ </span>📓 Configure Proxy Access to the Internet: <span style="color: #ffd700">No proxy</span>
|
||
<span style="color: #5c5cff">┗━━ </span>📂 Manual proxy configuration
|
||
<span style="color: #5c5cff"> </span><span style="color: #5c5cff">┗━━ </span>📂 HTTP Proxy
|
||
<span style="color: #5c5cff"> </span><span style="color: #5c5cff"> </span><span style="color: #5c5cff">┗━━ </span>📓 HTTP address: <span style="color: #00aa00">example.net</span> ◀ loaded from the YAML file
|
||
<span style="color: #5c5cff"> </span><span style="color: #5c5cff"> </span><span style="color: #5c5cff"> </span>"config/01/config.yml"
|
||
</pre>
|
||
|
||
|
||
And we don't really see any change associated with the fact that we have assigned
|
||
a type to this variable. But if we assign this (wrong) user data:
|
||
|
||
.. type-along:: A domain name has no space in it
|
||
|
||
Let's have a look at an example of user setting that does not fit the
|
||
`domainname` type:
|
||
|
||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_030/config/03/config.yml
|
||
:language: yaml
|
||
:caption: An invalid domain name for the :file:`config/03/config.yml` user data setting
|
||
|
||
..
|
||
---
|
||
manual:
|
||
http_proxy:
|
||
address: bla bla
|
||
|
||
:tutorial:`Download this file from the rougail-tutorials git repository <src/tag/v1.1_030/config/03/config.yml>`
|
||
|
||
The value is obviously not a domain name, then when we will launch the Rougail CLI:
|
||
|
||
.. raw:: html
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_030/config/03/cmd_invalid.txt
|
||
:class: terminal
|
||
|
||
..
|
||
rougail -m firefox/ -u yaml -yf config/03/config.yml --cli.invalid_user_datas_error
|
||
|
||
we then have this output:
|
||
|
||
.. raw:: html
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_030/config/03/output_invalid.html
|
||
:class: error
|
||
|
||
..
|
||
<pre><span style="font-weight: bold; color: #ff0000">🛑 ERRORS</span>
|
||
<span style="color: #ff0000">┗━━ </span>the value "bla bla" is an invalid domain name for
|
||
<span style="color: #ff0000"> </span>"manual.http_proxy.address" (HTTP address), must not be an IP, it will be
|
||
<span style="color: #ff0000"> </span>ignored when loading from the YAML file "config/02/config.yml"
|
||
</pre>
|
||
|
||
.. type-along:: what if we set an IP address instead of a domain name?
|
||
|
||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_030/config/02/config.yml
|
||
:language: yaml
|
||
:caption: A domain name in the :file:`config/02/config.yml` user data setting with an IP address
|
||
|
||
..
|
||
---
|
||
manual:
|
||
http_proxy:
|
||
address: 19.168.230.51
|
||
|
||
:tutorial:`Download this file from the rougail-tutorials git repository <src/tag/v1.1_030/config/02/config.yml>`
|
||
|
||
With a value that *is not a domain name* but an IP address, then when we will launch the Rougail CLI
|
||
we will see a little problem:
|
||
|
||
.. raw:: html
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_030/config/02/cmd_invalid.txt
|
||
:class: terminal
|
||
|
||
..
|
||
rougail -m firefox/ -u yaml -yf config/02/config.yml --cli.invalid_user_datas_error
|
||
|
||
we then have this output:
|
||
|
||
.. raw:: html
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_030/config/02/output_invalid.html
|
||
:class: error
|
||
|
||
..
|
||
<pre><span style="font-weight: bold; color: #ff0000">🛑 ERRORS</span>
|
||
<span style="color: #ff0000">┗━━ </span>the value "192.168.0.1" is an invalid domain name for
|
||
<span style="color: #ff0000"> </span>"manual.http_proxy.address" (HTTP address), must not be an IP, it will be
|
||
<span style="color: #ff0000"> </span>ignored when loading from the YAML file "config/02/config.yml"
|
||
</pre>
|
||
|
||
We observe that an error has been raised because an IP address is not a domain name.
|
||
Therefore, a type validation is taking place because we declared the type `domainname`.
|
||
|
||
.. type-along:: A variable with type's parameters
|
||
|
||
.. questions:: Question
|
||
|
||
OK I agree with the `domainname` necessary type validation, but what if I want to specify
|
||
an IP address as a user value for this `address` variable?
|
||
Because it is therefore simply impossible to do so now.
|
||
|
||
Is there a way for my `address` variable to accept an IP address?
|
||
|
||
Well, it is possible to configure the type so that it accepts IP addresses.
|
||
We need to specify whether our variable accepts to be filled using an IP or a domain name only.
|
||
This is where the ability to parameterize our variable comes in.
|
||
|
||
.. rubric:: Let's add a type parameter.
|
||
|
||
.. type-along:: For those who follow the tutorial with the help of the git repository
|
||
|
||
Now you need to checkout the `v1.1_031` version::
|
||
|
||
git switch --detach v1.1_031
|
||
|
||
Let's add a type parameter named `allow_ip`:
|
||
|
||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_031/firefox/10-manual.yml
|
||
:language: yaml
|
||
:caption: The `allow_ip` type parameter set in the :file:`firefox/10-manual.yml` structure file
|
||
:linenos:
|
||
..
|
||
---
|
||
manual:
|
||
description: Manual proxy configuration
|
||
|
||
http_proxy:
|
||
description: HTTP Proxy
|
||
|
||
address:
|
||
description: HTTP address
|
||
type: domainname
|
||
params:
|
||
allow_ip: true
|
||
|
||
The params allow the domain name `address` variable to be set with IPs.
|
||
|
||
.. glossary::
|
||
|
||
parameter
|
||
|
||
A parameter is a property of a variable that can refine its behavior.
|
||
It is declared by adding the `params` attribute in the variable's
|
||
definition.
|
||
|
||
Now we will test with an IP address as the value for our `address` variable.
|
||
|
||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_031/config/02/config.yml
|
||
:language: yaml
|
||
:caption: An IP address as a value in the :file:`config/02/config.yml` user value
|
||
|
||
..
|
||
---
|
||
manual:
|
||
http_proxy:
|
||
address: 192.168.0.1
|
||
|
||
:tutorial:`Download this file from the rougail-tutorials git repository <src/tag/v1.1_031/config/02/config.yml>`
|
||
|
||
if we launch the Rougail CLI on it:
|
||
|
||
.. raw:: html
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_031/config/02/cmd_ro.txt
|
||
:class: terminal
|
||
|
||
..
|
||
rougail -m firefox/ -u yaml -yf config/02/config.yml
|
||
|
||
We have this output:
|
||
|
||
.. raw:: html
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_031/config/02/output_ro.html
|
||
:class: output
|
||
|
||
We can see that the IP address value has been accepted.
|
||
|
||
A variable with type `port`
|
||
------------------------------
|
||
|
||
.. type-along:: For those who follow the tutorial with the help of the git repository
|
||
|
||
Now you need to checkout the `v1.1_032` version::
|
||
|
||
git switch --detach v1.1_032
|
||
|
||
|
||
After the `address` variable let's add, according to our use case,
|
||
|
||
.. image:: images/firefox_port.png
|
||
|
||
a new variable of type `port`. Our structure file looks like this:
|
||
|
||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_032/firefox/10-manual.yml
|
||
:language: yaml
|
||
:caption: The `port` type variable in the :file:`firefox/10-manual.yml` structure file
|
||
:linenos:
|
||
..
|
||
port:
|
||
description: HTTP Port
|
||
type: port
|
||
default: 8080
|
||
|
||
:tutorial:`Download this file from the rougail-tutorials git repository <src/tag/v1.1_032/firefox/10-manual.yml>`
|
||
|
||
Let's assing a value to this port:
|
||
|
||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_032/config/02/config.yml
|
||
:language: yaml
|
||
:caption: A user data :file:`config/02/config.yml` setting a value to the port variable
|
||
|
||
..
|
||
proxy_mode: Manual proxy configuration
|
||
manual:
|
||
http_proxy:
|
||
address: example.net
|
||
port: 3128
|
||
|
||
:tutorial:`Download this file from the rougail-tutorials git repository <src/tag/v1.1_032/config/02/config.yml>`
|
||
|
||
If we launch the Rougail CLI:
|
||
|
||
.. raw:: html
|
||
:class: terminal
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_032/config/02/cmd_ro.txt
|
||
|
||
We have this output:
|
||
|
||
.. raw:: html
|
||
:class: output
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_032/config/02/output_ro.html
|
||
|
||
..
|
||
<pre>╭─────────────────────────── Caption ────────────────────────────╮
|
||
│ Variable <span style="color: #00aa00">Modified value</span> │
|
||
│ <span style="color: #ff0000">Undocumented but modified variable</span> (⏳ Original default value) │
|
||
╰────────────────────────────────────────────────────────────────╯
|
||
Variables:
|
||
<span style="color: #5c5cff">┣━━ </span>📓 <span style="color: #ff0000">Configure Proxy Access to the Internet</span>: <span style="color: #00aa00">Manual proxy configuration</span> ◀
|
||
<span style="color: #5c5cff">┃ </span>loaded from the YAML file "config/02/config.yml" (⏳ No proxy)
|
||
<span style="color: #5c5cff">┗━━ </span>📂 Manual proxy configuration
|
||
<span style="color: #5c5cff"> </span><span style="color: #5c5cff">┗━━ </span>📂 HTTP Proxy
|
||
<span style="color: #5c5cff"> </span><span style="color: #5c5cff"> </span><span style="color: #5c5cff">┣━━ </span>📓 <span style="color: #ff0000">HTTP address</span>: <span style="color: #00aa00">example.net</span> ◀ loaded from the YAML file
|
||
<span style="color: #5c5cff"> </span><span style="color: #5c5cff"> </span><span style="color: #5c5cff">┃ </span>"config/02/config.yml"
|
||
<span style="color: #5c5cff"> </span><span style="color: #5c5cff"> </span><span style="color: #5c5cff">┗━━ </span>📓 <span style="color: #ff0000">HTTP Port</span>: <span style="color: #00aa00">3128</span> ◀ loaded from the YAML file
|
||
<span style="color: #5c5cff"> </span><span style="color: #5c5cff"> </span><span style="color: #5c5cff"> </span>"config/02/config.yml" (⏳ 8080)
|
||
</pre>
|
||
|
||
How can we know what validations the port type performs on the value assigned to the variable?
|
||
|
||
There are a number of validations that are carried out with this `port` type:
|
||
|
||
- well-known ports (1 to 1023) are allowed
|
||
- registred ports (1024 to 49151) are allowed
|
||
|
||
.. - private ports (greater than 49152) are allowed
|
||
|
||
Now let's assign a value that is outside the allowed ports:
|
||
|
||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_032/config/03/config.yml
|
||
:language: yaml
|
||
:caption: A user value in :file:`config/03/config.yml` that is not allowed
|
||
|
||
:tutorial:`Download this file from the rougail-tutorials git repository <src/tag/v1.1_032/config/03/config.yml>`
|
||
|
||
Again, we launch the Rougail CLI:
|
||
|
||
.. raw:: html
|
||
:class: terminal
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_032/config/03/cmd_invalid.txt
|
||
|
||
.. rougail -m firefox/ -u yaml -yf config/03/config.yml --cli.invalid_user_datas_error
|
||
|
||
And we have this output:
|
||
|
||
.. raw:: html
|
||
:class: error
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_032/config/03/output_invalid.html
|
||
|
||
..
|
||
<pre><span style="font-weight: bold; color: #ff0000">🛑 ERRORS</span>
|
||
<span style="color: #ff0000">┗━━ </span>the value "100000" is an invalid port for "manual.http_proxy.port" (HTTP
|
||
<span style="color: #ff0000"> </span>Port), must be between 1 and 65535, it will be ignored when loading from the
|
||
<span style="color: #ff0000"> </span>YAML file "config/03/config.yml"
|
||
</pre>
|
||
|
||
We observe that, as with the `domainname` type, a number of validations are performed
|
||
to ensure that the value assigned to this variable conforms to the `port` type.
|
||
|
||
A variable with type `boolean`
|
||
-----------------------------------
|
||
|
||
.. type-along:: For those who follow the tutorial with the help of the git repository
|
||
|
||
Now you need to checkout the `v1.1_033` version::
|
||
|
||
git switch --detach v1.1_033
|
||
|
||
Let's add one more variable in the `manual` family, with a much more basic type: `boolean`.
|
||
|
||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_033/firefox/20-manual.yml
|
||
:language: yaml
|
||
:caption: A new structure file :file:`firefox/20-manual.yml` with one variable
|
||
|
||
..
|
||
%YAML 1.2
|
||
---
|
||
version: 1.1
|
||
|
||
manual:
|
||
|
||
use_for_https: true # Also use this proxy for HTTPS
|
||
...
|
||
|
||
:tutorial:`Download this file from the rougail-tutorials git repository <src/tag/v1.1_033/firefox/20-manual.yml>`
|
||
|
||
.. note::
|
||
|
||
- it is not necessary to declare the variable as a boolean type
|
||
this type is *inferred* by the `true` default value
|
||
|
||
- we have decided to create a new structure file :file:`firefox/20-manual.yml`.
|
||
This is not necessary but usefull, please have a look at the :ref:`structure file organization and naming conventions <namingconvention>`
|
||
|
||
Let's switch this boolean variable to a `false` value:
|
||
|
||
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_033/config/02/config.yml
|
||
:language: yaml
|
||
:caption: A :file:`config/02/config.yml` user data file with false as a value for `use_for_https`
|
||
|
||
..
|
||
---
|
||
manual:
|
||
http_proxy:
|
||
address: example.net
|
||
use_for_https: false
|
||
|
||
:tutorial:`Download this file from the rougail-tutorials git repository <src/tag/v1.1_033/config/02/config.yml>`
|
||
|
||
|
||
Let's run the Rougail CLI:
|
||
|
||
.. raw:: html
|
||
:class: terminal
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_033/config/02/cmd_ro.txt
|
||
|
||
..
|
||
rougail -m firefox/ -u yaml -yf config/02/config.yml
|
||
|
||
the result is:
|
||
|
||
.. raw:: html
|
||
:class: output
|
||
:url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_033/config/02/output_ro.html
|
||
|
||
We could of course perform several tests on type validators, but here the validation is simple: only two values are allowed (`true` or `false`).
|
||
|
||
.. keypoints:: let's review the key points
|
||
|
||
- we can assign a `domainname` type to a variable
|
||
- we can set a :term:`parameter` to a `domainname` variable to refine their typing behavior
|
||
- we can assign a `port` type to a variable
|
||
- we know how to set a `boolean` type variable to `true` or `false`
|