ansible-collections / dellemc.enterprise_sonic

Ansible Network Collection for Enterprise SONiC Distribution by Dell Technologies
GNU General Public License v3.0
42 stars 58 forks source link

[QUESTION]: Generate configuration in config_db.json and frr.conf formats #420

Open diego-lopez8 opened 1 month ago

diego-lopez8 commented 1 month ago

How can the team help?

The changes generated by the ansible modules, when ran with --check, generate the changes in a format different from config_db.json, Sample output from the sonic gather facts module over httpapi:

                    {
                        "advertised_speed": null,
                        "auto_negotiate": null,
                        "description": "",
                        "enabled": true,
                        "fec": null,
                        "mtu": 9100,
                        "name": "PortChannel1",
                        "speed": null
                    },

In config_db.json

    "PORTCHANNEL": {
        "PortChannel1": {
            "admin_status": "up",
            "mtu": "9100"
        }
    },

what is this format exactly and through what mechanism does it eventually become integrated with config_db.json? We would like to maintain the configurations for our dell enterprise sonic switches in YAML format and use the prebuilt modules to apply these to the switches, however we would like the standard sonic configuration artifacts to be generated locally on the ansible controller, which can then be used for validation before being applied through open test frameworks like Batfish, which supports sonic. If there are other ways to maintain configurations in YAML, test them through a framework supported by DES and the different format, this would also be helpful.

kerry-meyer commented 1 month ago

The format (hierarchy and definition) of the Ansible "yaml" format configuration displayed for "gather facts" functionality (and for playbook execution output) is specified in the "argspec" file for each resource module. In this case (sonic_interfaces), the argspec definition is in:

https://github.com/ansible-collections/dellemc.enterprise_sonic/plugins/module_utils/network/sonic/argspec/interface/interfaces.py

Configuration examples illustrating use of the argspec in playbooks are shown in the corresponding "module" file for each resource module. In this case, the "module" file is:

https://github.com/ansible-collections/dellemc.enterprise_sonic/blob/main/plugins/modules/sonic_interfaces.py

During Ansible module playbook execution, REST API requests are formulated based on the user input YAML and the current configuration state on the device. These REST APIs, as defined by the appropriate Yang model for the resource module and as advertised via Swagger and similar tools for the matching Yang model path, are sent to the SONiC device and the resulting configuration is stored in the configuration DB on the device in the config_db.json file on the device.

diego-lopez8 commented 1 month ago

Hi @kerry-meyer, thanks for clearing that up. I believe what I am asking for is a way to map from the argspec used by ansible to the model that SONiC uses as stored in the config DB. According to this diagram from the management framework, it seems this is quite involved to get to the final format and goes through the translib. Is there a way to get the resulting SONiC configuration model corresponding to the argspec, all locally in the ansible controller?

kerry-meyer commented 1 month ago

Hi @diego-lopez8 ,

Regarding the question at the end of your most recent post on this Issue:


Is there a way to get the resulting SONiC configuration model corresponding to the argspec, all locally in the ansible controller?


It is possible to execute a playbook that gathers all configuration from the target device in the Ansible argspec (YAML) format and provides the result as output which could easily be saved to a file on the controller during playbook execution. If this would serve your intended purpose, please let me know and I will provide an example. If not, please provide additional explanation of your request.

diego-lopez8 commented 1 month ago

Hi @kerry-meyer, I do not mean pulling the config from a switch and translating to the argspec, i mean, is there a way to have, on the ansible controller, a playbook that will take the argspec and "renders" the actual config_db.json output without pushing it to the switch, or interacting with any switch at all? As an example, Arista's Interface Module has a "rendered" state, which will output the resulting EOS configuration lines, without actually interacting with a switch. This would be so the actual config can be rendered first, then validated before being finally pushed to a switch. Thanks

kerry-meyer commented 1 month ago

Hi @diego-lopez8,

Providing the ability to render the config into the format used in the config_db.json file is an enhancement we could consider for some future release if there is sufficient demand for it.

Before considering further the possibility of simulating the rendered config_db.json format, however, I would like to point out the fact that the actual, operational form of the configuration is not the config_db.json format, but is, instead a database that is not directly available for applications to query or view. The 'config_db.json' format is a way of encoding the configuration so that it can be conveniently stored in a non-volatile location (file) from which it can be restored during system bootup. While it is possible to directly access (read) this translated form of the configuration database, it is also possible read the content of the current 'active' database via REST GET APIs. We could provide a 'forecasted' compilation of configuration in this format without the risky duplication of the target device's algorithm for translating received REST APIs to the config_db.json format. (That is risky because it requires any changes in the proprietary formatting algorithms to stay synchronized in two completely separate source code repositories.) If, instead, we provided a 'rendered' format matching the industry standard Openconfig REST format that our Ansible resource module collection uses for sending requests to the SONiC target device and which those target devices also use for displaying their configuration in response to REST "GET" APIs, it seems that we could fairly easily provide a 'rendered config' capability (in Openconfig format) that would enable a more direct validation of the type you are describing.

diego-lopez8 commented 1 month ago

The main use case (as far as I see) for the rendered configuration is so that the potential changes can be validated and modeled before being applied, in my case with Batfish (which asks specifically for the FRR config and the config_db.json to model SONiC switches and don't have support for the DES format), or other technologies like IP Fabric (which ask for the FRR config and don't have support for the DES format). Rendering the configuration in OpenConfig REST format would likely not do any good as the tools to validate don't expect this. I ask this because we chose DES specifically because we were under the assumption that because it was SONiC under the hood, we can use the nice features of DES (such as this Ansible repository, the management framework cli, etc) and inherit the ecosystem of SONiC as well. Without this type of interoperability between the DES formats of configuration and the actual "raw" configurations such as the FRR config or the config_db artifact, it seems we would not benefit from efforts in the community SONiC ecosystem, and we would have to wait until support for DES specifically is implemented in various tools (something I think may not be a high business priority because someone is probably under the assumption that DES would in fact inherit from the SONiC ecosystem).