rougail/docs/tutorial/domainname.rst
2025-12-04 20:36:51 +01:00

465 lines
18 KiB
ReStructuredText
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Some suitable types
=====================
.. objectives:: Objectives
There isn't just the basic `string` available type, here we will discover new
variable types, for example the `boolean` type, and even types that are 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_022/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
:tutorial:`Download this file from the rougail-tutorials git repository <src/tag/v1.1_022/firefox/10-manual.yml>`
A variable with type `domainname`
-----------------------------------
We will add a custom type to our `address` variable:
.. 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>`
Notice that we have assigned the `domainname` 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`.
.. 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.
A variable with type's parameters
-------------------------------------
.. 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::
type parameter
A type parameter is a parameter 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:`type 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`