.. _tutorial_namespace:

Namespaces
============

.. objectives:: Objectives

   We are going to need a new tool, the concept of :term:`namespaces <namespace>`.

   And our use case is going to evolve.
   We're going to use a Firefox add-on called `Foxy Proxy <https://addons.mozilla.org/en-US/firefox/addon/foxyproxy-standard/>`_.
   In this context we will have a new way of organizing our structure files.


.. 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:`1.1_180 <src/tag/1.1_180/README.md>` to :tutorial:`1.1_181 <src/tag/1.1_181/README.md>`
    in the repository.

    ::

       git clone https://forge.cloud.silique.fr/stove/rougail-tutorials.git
       git switch --detach 1.1_180

.. note:: The purpose here is not to teach how to use the Foxy Proxy addon, 
    but rather to explain that using this Firefox plugin will require us
    to make decisions about how to organize our variables. 

    We will store them in namespaces.


Namespace
------------

The :term:`namespaces <namespace>` are a new, completely different way of separating and organising our :term:`structure files <structure file>`.
We're gonna see how.
We will begin by adding a parameter to our Rougail CLI:

.. raw:: html
   :class: terminal
   :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_180/config/01/cmd_ro.txt

..
    rougail -m firefox/ -s Firefox --types types/proxy --modes_level basic standard advanced -u yaml -yf config/01/config.yml

Now let's pay attention to the `-s` parameter. This namespace option has the value `Firefox`.
What does this imply?

So far, to assign our :term:`user data` to a structure file like this one:

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_180/firefox/60-dns_over_https.yml
   :language: yaml
   :caption: The `firefox/60-dns_over_https.yml` structure file

..
    %YAML 1.2
    ---
    version: 1.1

    dns_over_https:  # DNS over HTTPS

      enable_dns_over_https: false  # Enable DNS over HTTPS

      provider:
        description: Use Provider
        choices:
          - Cloudflare
          - NextDNS
          - Custom
        default: Cloudflare
        disabled:
          variable: _.enable_dns_over_https
          when: false

      custom_dns_url:
        description: Custom DNS URL
        type: web_address
        validators:
          - jinja: |-
              {{ _.custom_dns_url.startswith("http://") }}
            return_type: boolean
            description: must starts with 'https://' only
        disabled:
          jinja: |-
            {{ _.provider is propertyerror or _.provider != 'Custom' }}
          return_type: boolean
          description: if "_.provider" is not "Custom"
    ...

We had to enter :term:`user data` of this new shape:

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_170/config/02/config.yml
   :language: yaml
   :caption: user data settings with the `dns_over_https` family

..
    ---
    dns_over_https:
      enable_dns_over_https: true

But now that we have defined a namespace, we need to populate our :term:`user data` in this shape:

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_180/config/01/config.yml
   :language: yaml
   :caption: user data settings about the `dns_over_https` family with the `firefox` namespace

..
    ---
    firefox:
      dns_over_https:
        enable_dns_over_https: true

Notice the difference: we have now a `firefox` namespace. 
Contrary to a misinterpretation we might have upon first reading, it is not a family.
It's a namespace.

.. questions:: What is the purpose of creating a namespace?

    Well, this allows for logical grouping. We'll be able to clearly separate
    the user data related to our Foxy Proxy plugin.

New "FoxyProxy" namespace
----------------------------

.. type-along:: For those who follow the tutorial with the help of the git repository

    Now you need to checkout the :tutorial:`1.1_181 <src/tag/1.1_181/README.md>` version::

          git switch --detach 1.1_181

.. image:: images/foxyproxy.png

We can see in the FoxyProxy widget that it is possible to add as many proxies as needed.

So our use case enables us to handle variables related to the Foxy Proxy plugin
that should be stored in a separate namespace.

.. type-along:: Handling multiple namespaces

It is perfectly possible to define multiple namespaces with Rougail.
In the Rougail CLI, the `-s` option is reserved for the main namespace.
If we need  to add a namespace named FoxyProxy, we must use the `-xn FoxyProxy` option.
However, we also need to specify the parameter that indicates the location 
of the structure files corresponding to this namespace.
The `-xd 0 foxyproxy/` option is used to specify the relevant file or folder, 
here, the :file:`foxyproxy` folder:

.. raw:: html
   :class: terminal
   :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_181/config/01/cmd_ro.txt

..
    rougail -m firefox/ -s Firefox -xn FoxyProxy -xd 0 foxyproxy/ --types types/proxy --modes_level basic standard advanced -u yaml -yf config/01/config.yml

The additional namespace is therefore specified via the two command-line options:

.. code-block:: shell

    -xn FoxyProxy -xd 0 foxyproxy/

.. keypoints:: let's review the key points

   We learned how to create a namespace for our use case, and even how to use 
   multiple namespaces—that is, how to implement several logical separations.
