Validating a variable's value ================================ .. objectives:: Objectives We will see how to create strong validations for the values ​​of our variables, that is, validations that go beyond those inherent in the initial type definition. .. prerequisites:: Prerequisites - We assume that Rougail's library is :ref:`installed ` 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 `, this workshop page corresponds to the tag :tutorial:`v1.1_170 ` in the repository. :: git clone https://forge.cloud.silique.fr/stove/rougail-tutorials.git git switch --detach v1.1_170 A variable with custom validation ----------------------------------- First, we would like the :term:`operator` to remember not to forget the http protocol, that is to put `http://` at the beginning of our `web_address` variable's value. Actually the `web_address`\ 's type requires that the address include the HTTP protocol, namely: :: http(s):// However, in our use case, we want *to force* the HTTPS protocol. We don't want `http://`, only `https://`. .. note:: This URL is for DNS over HTTPS, providing greater privacy than using the ISP's DNS, which can filter traffic. If it uses `http://`, it doesn't make sense. But there's no existing type for this specific use case (forcing HTTPS). We just said that a valid value must start with `https://` instead of `http://`. It is possible, instead of creating a new type, to add custom validation of the variable's value. We call it a :term:`validator`. .. glossary:: validator A validator is a Jinja code that parses a variable's value and checks that this value corresponds to some stated criteria. This is a `validator` parameter of our variable, and another `jinja` sub-parameter contains validation code for the variable's value. .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_170/firefox/60-dns_over_https.yml :language: yaml :caption: The :file:`firefox/60-dns_over_https.yml` with the jinja validator Here we can see that the validation code is: .. code-block:: jinja {{ _.custom_dns_url.startswith("http://") }} A validator can return a string, in fact it is its default behavior. If it returns a string of characters, it indicates the validation error. In this case we see that we have specified the `return_type parameter`, which specifies that the Jinja code shall return a boolean value. The validator's `description` parameter serves two purposes: - it does, of course, have a string function for documenting validation, - since the `return_type` parameter is set to boolean, the error message contains this description's string. .. type-along:: example with `http://` in the user data Now, let's try with incorrect user data, containing `http://` and not `https://` .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_170/config/03/config.yml :language: yaml :caption: A :file:`config/03/config.yml` user data file containing `http://` .. --- dns_over_https: enable_dns_over_https: true provider: Custom custom_dns_url: http://dns.net Let's run the Rougail CLI: .. raw:: html :class: terminal :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_170/config/03/cmd_ro.txt .. rougail -m firefox/ --types types/proxy --modes_level basic standard advanced -u yaml -yf config/03/config.yml The result is: .. raw:: html :class: output :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_170/config/03/output_ro.html The warning indicates that the validator did not allow an HTTP protocol to pass: :: ┃ the value "http://dns.net" is an invalid URL, must starts with ┃ 'https://' only, it will be ignored when loading from the YAML file ┃ "config/03/config.yml" .. keypoints:: Let's review the key points We explained the use of validations to refine the type definition of a variable. The variable's parameter is `validator`.