Group variables inside families ================================= .. objectives:: Objectives We will learn how to: - create a :term:`family` - gather :term:`variable`\ s into a :term:`family` - make a variable within a variable, which turns this variable container into being a family .. 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 tags :tutorial:`v1.1_020 ` to :tutorial:`v1.1_022 ` in the repository. :: git clone https://forge.cloud.silique.fr/stove/rougail-tutorials.git git switch --detach v1.1_020 .. type-along:: let's recap how far we've come We have this choice variable in its structure definition file: .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_010/firefox/00-proxy.yml :linenos: :language: yaml :caption: The `proxy_mode` choice type variable in the :file:`firefox/00-proxy.yml` structure file .. --- proxy_mode: description: Configure Proxy Access to the Internet choices: - No proxy - Auto-detect proxy settings for this network - Use system proxy settings - Manual proxy configuration - Automatic proxy configuration URL default: No proxy .. We're gonna put it in a :term:`family`. In short, let's describe our `proxy_mode` variable like this: .. confval:: proxy_mode :type: `choice` :default: No proxy Proxy mode's settings Now we will define new variables, and other structure definitions. For the sake of clarity, we will put the structure definitions in separate files. Please have a look at the :ref:`file naming and organizing convention `. Here we made a :file:`firefox/00-proxy.yml` structure file and we're gonna make a new structure file named :file:`firefox/10-manual.yml`:: . └── firefox ├── 00-proxy.yml └── 10-manual.yml Creating a new family ----------------------- Let's create a family named `manual` which obviously corresponds to the proxy's manual configuration choice. .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_020/firefox/10-manual.yml :language: yaml :caption: A family structure file description named `manual` in a :file:`firefox/10-manual.yml` file :name: RougailManualFamily .. --- manual: description: Manual proxy configuration type: family We can see that we have defined a :term:`family` here, and this family is *empty* which means that this family is a container variable that contains no variable yet. .. warning:: If a family is empty, we need to specify the :term:`family` type here because if we don't, the Rougail's type engine will infer it by default as a :term:`variable`. We have to force the family type inference. It's because we don't have set any :term:`variable` inside yet. When we will have a variable inside of this family, we will make a YAML block (to create a block in YAML, you just need to indent the lines) and the Rougail's type inference engine will implicitely infer the variable's container as a family type. Or a sub family ---------------- .. type-along:: For those who follow the tutorial with the help of the git repository Now you need to checkout the `v1.1_021` version:: git switch --detach v1.1_021 .. glossary:: sub family A sub family is a family inside a family. Creating a family hierarchy of family container types is very easy, here is an example: .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_021/firefox/10-manual.yml :language: yaml :caption: A rougail structure description file with a hierarchy. :name: RougailFirstFamilyHierarchy .. --- manual: description: Manual proxy configuration type: family http_proxy: description: HTTP Proxy type: family :tutorial:`Download this file from the rougail-tutorials git repository ` Note that the `http_proxy` family lives inside the `manual` family. Putting a variable inside of a family or a sub family ----------------------------------------------------------- .. type-along:: For those who follow the tutorial with the help of the git repository Now you need to checkout the `v1.1_022` version:: git switch --detach v1.1_022 We are going to put a variable inside of a family or a sub family Let's create a variable in the `http_proxy` family. This time, the type of this new variable is a `domainname` type: .. 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 :name: RougailVariableInSubFamily .. --- manual: description: Manual proxy configuration type: family http_proxy: description: HTTP Proxy type: family address: description: HTTP address type: domainname :tutorial:`Download this file from the rougail-tutorials git repository ` Now that the :confval:`address` variable is declared, the :term:`operator` can set :term:`a value ` to it. In short, let's describe our `address` variable like this: .. confval:: address :type: `domainname` :default: None This is the HTTP address of the proxy .. note:: We encountered here a new type of variable there: the `domainname` type. There are a bunch of types available in Rougail. We have reached the definition of the address in the `http_proxy` family; there will be other variables to define in this family. .. image:: images/firefox_manual_family.png .. type-along:: Assigning a user value Now we need to set a value ​​for the :confval:`address` variable, otherwise we will get an error if we try to access this variable: .. raw:: html :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_022/config/01/output_ro.html :class: error-box ..
🛑 ERRORS
    ┣━━ The following variables are mandatory but have no value:
    ┗━━   - manual.http_proxy.address (HTTP address)
    
.. type-along:: let's set user values in a user data file Here is a user data file sample: .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_022/config/02/config.yml :language: yaml :caption: A user file named :file:`config/03/config.yml` with a value set for the `address` variable :name: RougailAddresseVariableUserValue .. --- proxy_mode: Manual proxy configuration manual: http_proxy: address: example.net :tutorial:`Download this file from the rougail-tutorials git repository ` Let's validate the consitency of the :term:`configuration`: .. raw:: html :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_022/config/02/cmd_ro.txt :class: terminal .. rougail -m firefox/ -u yaml -yf config/02/config.yml Everything is OK: .. raw:: html :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_022/config/02/output_ro.html :class: output ..
╭──────── Caption ────────╮
    │ Variable Default value  │
    │          Modified value │
    ╰─────────────────────────╯
    Variables:
    ┣━━ 📓 Configure Proxy Access to the Internet: No proxy
    ┗━━ 📂 Manual proxy configuration
        ┗━━ 📂 HTTP Proxy
            ┗━━ 📓 HTTP address: example.net ◀ loaded from the YAML file "config/02/config.yml"
    
Let's recap about the user datas. We can see in this rougail CLI output that: - the `proxy_mode` value is set by default by the :term:`integrator` - the `address` value is has been set by an :term:`operator` .. type-along:: A second variable in the `http_proxy` family Now let's add a `port` variable in the `http_proxy` family: .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_022/config/03/config.yml :language: yaml :caption: The :file:`config/03/config.yml` user data file with the `port` number added :linenos: .. --- manual: description: Manual proxy configuration http_proxy: description: HTTP Proxy address: description: HTTP address type: domainname port: description: HTTP Port default: 8080 :tutorial:`Download this file from the rougail-tutorials git repository ` In short: .. confval:: port :type: `port` :default: 8080 The HTTP Port .. keypoints:: let's review the key points **Keywords** - we know how to define :term:`variable`\ s inside of a family - we now know what a :term:`mandatory` variable is and why it is necessary to assign values to the variables - we kwow how to set a variable's :term:`user value ` - we have the big picture : the :term:`configuration`, which is (the structure files + the user data files) **Progress** - we have a :term:`family` named `manual` and a sub family named `http_proxy` - And we have now two variables: :confval:`proxy_mode` and :confval:`address`.