Define access to variable or family ========================================== .. objectives:: Objectives In this section we will see what a disabled variable or family is, and why it can be interesting to assign the `disabled` property to a variable or a family. We'll also learn the difference between disabling and hiding families or variables. We will: - create a `disabled` family - use a new family or variable's property: the `hidden` property .. 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_050 ` to :tutorial:`v1.1_053 ` in the repository. :: git clone https://forge.cloud.silique.fr/stove/rougail-tutorials.git git switch --detach v1.1_050 A disabled family ------------------ Disabling and hiding are two families or variables properties. Let's begin with defining what a property is: .. glossary:: property A property is a state (`disabled`, `mandatory`, `frozen`, `hidden`...) of a family, a subfamily or a variable. These properties change the usual behavior of a variable or family. Here we are going to assign the `disabled` property to the `manual` family: .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_050/firefox/10-manual.yml :language: yaml :caption: The `manual` family has the `disabled` property set in this :file:`firefox/10-manual.yml` structure file .. %YAML 1.2 --- version: 1.1 manual: description: Manual proxy configuration disabled: true http_proxy: # HTTP Proxy address: description: HTTP address type: domainname params: allow_ip: true port: description: HTTP Port type: port default: 8080 Notice that we have this `disabled: true` property assigned to the `manual` family. Let's launch the Rougail CLI on this structure file (whith an empty user data file): .. raw:: html :class: terminal :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_050/config/01/cmd_ro.txt .. rougail -m firefox/ -u yaml -yf config/02/config.yml The Rougail CLI outputs this: .. raw:: html :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_050/config/01/output_ro.html :class: output We can deduce from the Rougail CLI output that the `manual` family is not taken into account by Rougail. So what does this disabled property exactly? .. glossary:: disabled The disabled property is a property that can be assigned to a variable or a family. It makes the :term:`configuration` act as if the variable or family that has this property has not even been defined. It simply doesn't exist (it is deactivated) for the whole configuration. .. note:: Note that, as with any property, if a family has been disabled, all variables and sub-families that it contains are disabled. And if we try to assign values to variables that have been disabled, here is what happens: .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_050/config/02/config.yml :language: yaml :caption: In this :file:`config/02/config.yml` user data file, we assign values to variables that have been disabled If we launch the Rougail CLI: .. raw:: html :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_050/config/02/cmd_ro.txt :class: terminal It outputs: .. raw:: html :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_050/config/02/output_ro.html :class: output We can see that the Rougail CLI is warning us about the variables that we are trying to assign values on which are disabled. Because it is not logical. We are trying to assign values to variables that are not taken into account in the :term:`configuration`. Let's look again at our use case. We have a choice between five options in order to set the proxy mode: .. image:: images/firefox_01.png These five choices are: - No proxy - Auto-detect proxy settings for this network - Use system proxy settings - Manual proxy configuration - Automatic proxy configuration URL Actually if the `Manual proxy configuration` is not selected, we don't need to set these `address` and `port` variables, there is no point in setting them in four out of our five use cases. The first point is that we disable them in order to expose the fact that we don't use them, but it's not just that: if we fill them in, there might be a problem in the overall integrity of the whole :term:`configuration`. We shall fill and use in these variables in the `Manual proxy configuration` use case context only. Otherwise, **we need to disable them when they are not used**. In a practical point of view, if we fill them in, Rougail CLI will output a warning and the :term:`operator` will see it. He will wonder : "oh, what am I doing?", I shall fill and use in these variables only in the `Manual proxy configuration` context. .. important:: We need to **disable** variables or families that are not used in a given usage context. .. type-along:: Disabling a family Disabling variables one by one can be replaced by disabling a whole family. If we don't choose the manual mode, we need to **disable** the whole `manual` family, it will disable all the subfamilies and the variables in it. Note that we've placed theses variables in the `http_proxy` subfamily. We can then disable it or even the parent `manual` subfamily in order to disable the `http_proxy` family and all the variables that are placed in it, because the `manual` family variables shall be used only in the manual proxy use case context. Notice the `disabled: true` parameter set in the `manual` family: .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_050/firefox/10-manual.yml :linenos: :language: yaml :caption: The `http_proxy` subfamily in the :file:`firefox/10-manual.yml` structure file is disabled here .. --- manual: description: Manual proxy configuration disabled: true http_proxy: description: HTTP Proxy address: description: HTTP address type: domainname params: allow_ip: true port: description: HTTP Port type: port default: 8080 A conditional disabled family ------------------------------ .. type-along:: For those who follow the tutorial with the help of the git repository Now you need to checkout the `v1.1_051` version:: git switch --detach v1.1_051 What could be usefull here is a *dynamically* disable or enable the `manual` family. The idea in this section is to dynamically set the enable/disable property according to the chosen use case context. In rougail, we can set a property's value **depending on** the value of another variable. **The property's value is conditioned by** another variable. .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_051/firefox/10-manual.yml :linenos: :language: yaml :caption: The :file:`firefox/10-manual.yml` structure file. The `manual` family dynamically enabled or disabled .. %YAML 1.2 --- version: 1.1 manual: description: Manual proxy configuration disabled: variable: _.proxy_mode when_not: Manual proxy configuration http_proxy: # HTTP Proxy address: description: HTTP address type: domainname params: allow_ip: true port: description: HTTP Port type: port default: 8080 Now the `disabled` property has some parameter defined. First, let's explaine the `variable` parameter. This parameter specifies the target variable. The value of this target variable will be used to dynamically enable or disable our `manual` family. We can see here that the `manual` family disabled or enabled property is contitionned by the `_.proxy_mode` variable's value. The target variable is `_.proxy_mode`. .. note:: The `_.` notation means the current path of the family you're currently in. Now regarding the `when_not` parameter, this means that if the target variable's value is `Manual proxy configuration` then the `manual` familiy **will not** be disabled (that is, it will be **enabled**). Regarding as the default value use case, the `proxy_mode`'s variable is `No proxy` by default. The `manual` familiy is then **disabled by default**. Let's launch the Rougail CLI on an empty user value file: .. raw:: html :class: terminal :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_051/config/01/cmd_ro.txt .. rougail -m firefox/ -u yaml -yf config/01/config.ym We have this output: .. raw:: html :class: output :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_051/config/01/output_ro.html ..
╭──────────────────── Caption ─────────────────────╮
    │ Undocumented but modified variable Default value │
    ╰──────────────────────────────────────────────────╯
    Variables:
    ┗━━ 📓 Configure Proxy Access to the Internet: No proxy
    
We can see that the `manual` family and all the variables into it are not present. .. type-along:: Dynamically enabling the `manual` family Now we are going to choose the **manual mode**, that is the `Manual proxy configuration` value for the `proxy_mode` variable, and things will become slightly different. If the manual mode for the proxy is not selected, then the `manual` family is disabled. On the other hand, if the manual proxy's configuration mode is selected, then the `manual` family **is enabled**: .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_051/config/02/config.yml :linenos: :language: yaml :caption: The `proxy_mode`'s manual setting in the :file:`config/02/config.yaml` user datas file .. --- proxy_mode: Manual proxy configuration manual: http_proxy: address: http.proxy.net port: 3128 use_for_https: false Let's launch the Rougail CLI to verify this: .. raw:: html :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_051/config/02/cmd_ro.txt :class: terminal .. rougail -m firefox/ -u yaml -yf config/02/config.yml It outputs: .. raw:: html :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_051/config/02/output_ro.html :class: output ..
╭────────────── Caption ───────────────╮
    │ Variable Modified value              │
    │          (⏳ Original default value) │
    ╰──────────────────────────────────────╯
    Variables:
    ┣━━ 📓 proxy_mode (Configure Proxy Access to the Internet): Manual proxy 
    configuration ◀ loaded from the YAML file "config/02/config.yml" (⏳ No 
    proxy)
    ┗━━ 📂 manual (Manual proxy configuration)
        ┣━━ 📂 http_proxy (HTTP Proxy)
        ┣━━ 📓 address (HTTP address): http.proxy.net ◀ loaded from the YAML 
        file "config/02/config.yml"
        ┗━━ 📓 port (HTTP Port): 3128 ◀ loaded from the YAML file 
            "config/02/config.yml" (⏳ 8080)
        ┗━━ 📓 use_for_https (Also use this proxy for HTTPS): false ◀ loaded from 
            the YAML file "config/02/config.yml" (⏳ true)
    
.. rubric:: Explanation Here the `disabled` property **depends on** the value of the `proxy_mode` variable. It is the `variable` parameter that allows you to define the name of the target variable on which the `disabled` property depends. Please remember that this activation/deactivation of the `manual` family depends on the value of the `proxy_mode` variable. Here we have chosen the `Manual proxy configuration` value, so the `address` and `port` variables appear. A hidden family ------------------- .. type-along:: For those who follow the tutorial with the help of the git repository Now you need to checkout the `v1.1_052` version:: git switch --detach v1.1_052 Let's introduce a new property here: .. glossary:: hidden A variable or family's property is hidden if its value **shall not be seen** in a given :term:`context`. Anyway, these variables can be used if the context evolves. This is the main difference between the `hidden` and the `disabled` properties: - with the `disabled` property, the variables are *deactivated* - with the `hidden` property, the variables are just not seen. Now we can set a `hidden` property to the `https_proxy` family: Here is our new :file:`20-manual.yml` structure file: .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_052/firefox/20-manual.yml :linenos: :language: yaml :caption: The :file:`firefox/20-manual.yml` structure file with the `hidden` property on the `https_proxy` family. .. %YAML 1.2 --- version: 1.1 manual: use_for_https: true # Also use this proxy for HTTPS https_proxy: description: HTTPS Proxy hidden: true address: description: HTTPS address default: variable: __.http_proxy.address port: description: HTTPS Port default: variable: __.http_proxy.port ... We have now a `hidden` property assigned to the `https_proxy` family. A conditional hidden family ---------------------------- .. type-along:: For those who follow the tutorial with the help of the git repository Now you need to checkout the `v1.1_053` version:: git switch --detach v1.1_053 The variable that drives the hidden/show behavior is the `use_for_https` variable because the `hidden` property has a `variable` target parameter that points to it: `variable: _.use_for_https`. .. prerequisites:: Reminder The underscore and the point before the variable (`_.use_for_https`) points to the variable that lives in the parent family. Now we will focus on configuring the HTTPS mode in case of `"Manual proxy configuration"` value has been chosen, let's have a look at our use case again: .. image:: images/firefox_manual_https.png We have added two other variables for the HTTPS use only: .. confval:: https_proxy.address :type: `domainname` This is an address setting for the manual HTTPS configuration .. confval:: https_proxy.port :type: `port` This is a port setting for the manual HTTPS configuration We have now two very similar variables, a `manual.http_proxy.address` variable and a `manual.https_proxy.address` variable. In the same way, we have a `manual.http_proxy.port` variable and a `manual.https_proxy.port` variable. Let's introduce a new Rougail concept here: .. glossary:: context A :term:`configuration` is highly statefull and can change at any moment. Sometimes somes minor changes in the :term:`user data ` may involve chain reactions in the whole :term:`configuration`. The **context** is the state of the user data at one moment, the set of the values of the variables at a given moment. This term refers in Rougail to the ability of a system to handle the *statefull* state of a configuration. It expresses the transition between one situation to another situation, that is, the deeply **statefull** aspects of a data set. .. type-along:: A new variable which has the `boolean` type The best way to reproduce the `"Also use this HTTP proxy variables for HTTPS"` checkbox in the firefox interface is to add this `use_for_https` variable in our structure file. This boolean variable can reproduce this binary choice option. - if the use of the proxy variables for https are the same of the proxy variables for http, that is, if `use_for_https` is true, the https configuration variables are hidden, that's OK. - if the use of the proxy variables for https **are not** the same of the proxy variables for http, we would like to set their default values to the http proxy variables values. Do we want to reuse, for the HTTPS mode, the same configuration as for the HTTP mode? Well, it depends on the :term:`context`. We have added a new variable, named `use_for_https` here: .. confval:: use_for_https :type: `boolean` :default: `true` This is a setting that enables to reuse or not the HTTP proxy configuration for HTTPS .. questions:: Question: how does it work? How will this variable drive the reuse of HTTP data to HTTPS data? With this :confval:`use_for_https` boolean variable, there are two possibilities, and only two: - The http proxy's configuration will be reused for the https proxy's configuration - The http proxy's will not be reused for the https proxy's configuration .. questions:: Question: shall we use the `disabled` property here? Is it relevant to use the :term:`disabled property ` here? **answer**: No! Because we *need* to use these variables at any :term:`context` of the proxy's manual configuration use case, we simply have to point their values ​​in one direction or another depending on this or that context, that's why it is absolutely not a question of disabling them. The `manual.https_proxy.address` and the `manual.http_proxy.port` variables shall not be disabled in the manual mode. Here is an example with different user values for handling HTTP and HTTPS: .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_053/config/01/config.yml :linenos: :language: yaml :caption: User datas in the user data file :file:`config/01/config.yml` with `use_for_https` as false .. --- proxy_mode: Manual proxy configuration manual: http_proxy: address: http.proxy.net port: 3128 use_for_https: false https_proxy: address: https.proxy.net If we launch the Rougail CLI: .. raw:: html :class: terminal :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_053/config/01/cmd_ro.txt .. rougail -m firefox/ -u yaml -yf config/01/config.yml We have this output: .. raw:: html :class: output :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_053/config/01/output_ro.html ..
╭────────────── Caption ───────────────╮
    │ Variable Default value               │
    │          Modified value              │
    │          (⏳ Original default value) │
    ╰──────────────────────────────────────╯
    Variables:
    ┣━━ 📓 proxy_mode (Configure Proxy Access to the Internet): Manual proxy 
    configuration ◀ loaded from the YAML file "config/01/config.yml" (⏳ No 
    proxy)
    ┗━━ 📂 manual (Manual proxy configuration)
        ┣━━ 📂 http_proxy (HTTP Proxy)
        ┣━━ 📓 address (HTTP address): http.proxy.net ◀ loaded from the YAML 
        file "config/01/config.yml"
        ┗━━ 📓 port (HTTP Port): 3128 ◀ loaded from the YAML file 
            "config/01/config.yml" (⏳ 8080)
        ┣━━ 📓 use_for_https (Also use this proxy for HTTPS): false ◀ loaded from 
        the YAML file "config/01/config.yml" (⏳ true)
        ┗━━ 📂 https_proxy (HTTPS Proxy)
            ┣━━ 📓 address (HTTPS address): https.proxy.net ◀ loaded from the YAML 
            file "config/01/config.yml"
            ┗━━ 📓 port (HTTPS Port): 8080
    
Notice that we have a `use_for_https` new variable, this variable is a `boolean` type, its default value is `True`. We want to offer the possibility of providing an identical or possibly different proxy configuration for the HTTP and for the HTTPS protocols. Here is an example with identical HTTP and HTTPS proxy configuration: .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_053/config/02/config.yml :linenos: :language: yaml :caption: User datas in the user data file :file:`config/02/config.yml` with `use_for_https` as true .. --- proxy_mode: Manual proxy configuration manual: http_proxy: address: http.proxy.net port: 3128 use_for_https: true Let's launch the Rougail CLI: .. raw:: html :class: terminal :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_053/config/02/cmd_ro.txt .. rougail -m firefox/ -u yaml -yf config/02/config.yml We have this output: .. raw:: html :class: output :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_053/config/02/output_ro.html ..
🛑 Caution
    ┗━━ manual (Manual proxy configuration)
        ┗━━ https_proxy (HTTPS Proxy)
            ┗━━ address (HTTPS address): 🛑 mandatory variable but is inaccessible 
                and has no value
    
Which is logical, HTTPS proxy variables have no values set yet. We are going to see how to point HTTPS variables to HTTP variables. .. keypoints:: Key points progress **summary** We have now the ability to build *contextual settings*: - if the `proxy_mode` variable's value is not `'Manual proxy configuration'` the `manual` family is disabled - if the `proxy_mode` variable's value is `'Manual proxy configuration'` then the `manual` family is enabled - if the `use_for_https` variable's value is `true`, the HTTP configuration will be reused in the HTTPS situation and the `https_proxy` familiy will be hidden - if the `manual.https_proxy.address` has no value set, the defaut value is the same as the `manual.http_proxy.address`'s value (same behavior with the HTTP port and the HTTPS port variable) And yes, we did it. We have arrived at the end of the proxy's manual configuration's section. **Keywords** - We now know what a *property* is, we have seen in details the :term:`disabled` property, - We can target a variable's value in the `disabled` property's value, we call it a variable based contextual disabled family, - The :term:`hidden` property set to a family, - The fact that a property can be set dynamically, - The conditional dependency of a `hidden` property can depends on a `boolean` variable, - We know whant a calculated default value is.