Package: runAM-evpn
runAM (run-a-module) EVPNrunAM (run-a-module) EVPNChange LogDisclaimerOverviewInstallationData StoreCLIImportant DependenciesWorkflowProfilesPort (Server) ProvisioningChange Log0.1.1First version with a small subset of runAM features required for port provisioning0.1.2Bug fix for port configuration data generation.0.1.3Bug fix for port configuration data generation: single ticket for every connection to avoid switch_name overwrite0.1.4Add cli argument to add port ticket without generating low level port config dataAdd dedicated command to trigger port config generation0.1.5 (Current Release)Add cli arguments to query server tickets by switch name and switch port.Add cli argument to dump server tickets as YAML docs.Do not print docID for server tickets by default. Add cli arguments to print docIDs if required.Print JSON data in a nice format.DisclaimerWhile runAM-evpn provides a full set of modules required to build EVPN network, it is not covering any possible design.
Data model used is highly subjective and not necessarily optimal for every use case.
Use it only as a reference and build your own set of modules if required.
There is no official support for this module as well, but issues created will be reviewed and fixed or closed.If you are interested in automating Arista EVPN network, please take a look atArista-AVDAnsible collection as well.
Ansible-AVD has superior community support and is definitely recommended as the first stop.
runAM-evpn is not a replacement for Ansible-AVD, but provides alternative approach to archive the same target using native Python.OverviewrunAM stands for "run A Module".
runAM-evpn package contains number of Python modules required to provision Arista EVPN network.
Every module is focused on a specific task. Modules can be changes, unplugged or re-arranged as required, but some modules depend on the data produced by other modules. Please checkWorkflowsection before making any changes.runAM can be used in 3 different ways:Imported from any Python script withimport runAMExecute runAM module withpython3 -m runAM <cli-arguments>Use build in runAM CLI. ExecuterunAM --helpfor details.runAM motto is KISS. Always focus on simplicity, readability and ease of maintenance. Features and code optimization are secondary if not improving simplicity.InstallationCreatedatabasedirectory.Install runAM:pip install runAM-evpnEnable CLI autocompletion:eval "$(register-python-argcomplete runAM)"For details about CLI autocompletion please refer toargcomplete documentation.Data StoreDifferent runAM modules can exchange the data using common data store.
An instance of JSONStore class is initialized when a module starts and provides number of methods for simplified access to a json file holding the data (db.jsonby default).
Relying on a simple JSON file allows to reduce complexity, eliminate unnecessary dependencies and use Git version control.
The data store class can be extended to support any database that is capable to store JSON data.Following classes can be used to interact with the data store:JSONStore- basic methods to interact with the data storePortConfigGenerator(JSONStore)- additional methods required to build low level port configurationProfileTicketStore(JSONStore)- additional methods to work with profile tickets in the data storeServerTicketStore(PortConfigGenerator)- additional methods to work with server tickets in the data storeCLIrunAM provides basic CLI to control typical network provisioning operations.Using CLI is not mandatory. Every module can be called from any 3rd party tool or script. However runAM CLI helps to eliminate dependencies and is the fastest way to start using runAM modules.
runAM CLI is available once the module is installed. UserunAM --helpto get details.To enable autocompletion, useeval "$(register-python-argcomplete runAM)".For details about CLI autocompletion please refer toargcomplete documentation.CLI can be easily adjusted by changing runAM.cli_spec. This dictionary has following data structure:{<cli-command>:{'python_module':<pythonmoduletobetriggeredbythiscommand>,'help':<clicommanddescription>,'add_argument':[# add arguments required for Python module to operate as a list{'arg_name':<fullnameofCLIargument>,'arg_short_name':<shortnameofCLIargument>,'help':<CLIargumenthelp>,}]}}On top of runAM CLI, you can usejqtoolto query any data in the database json file.Important DependenciesWhen possible runAM avoids dependencies to external packages to keep code clean and improve performance.
Nevertheless, some external packages are required for runAM to work:argcomplete- CLI autocompletion for Python scripts.https://pypi.org/project/argcomplete/PyYAML- read/write YAML data.https://pypi.org/project/PyYAML/glom- for easy access to nested data structures. It helps to keep code compact and readable.https://pypi.org/project/glom/jq- jq for Python. Used to make recursive queries with a reasonable performance.https://pypi.org/project/jq/WorkflowThe workflow examples are based on runAM CLI and explain the logic in simplified way. For details please refer to the code.ProfilesProfiles contain common data that is re-used frequently. Every profile is identified by auniquetag set and if referenced somewhere else, data will be merged.
To merge specific profile into any data structure, use:any_dictionary_key:profiles:-['tag1','tag2','tag3']# merge some profile into this dict key-['tag1','tag4']# merge another profile-...Profile tickets can be defined as single- or multi-doc YAMLs. Example:---tags:['fallback','port_channel']# tags must be unique# any data to be merged can be defined belowfallback:mode:individualtimeout:50Merge means that existing data will be retained.Commands:runAM profile.add --input_file <profile-ticket-name>.ymlThis command adds profile ticket to profile_tickets table in the data store.
Actions:Find out if ticket is a dictionary (single-doc) or a list (multi-doc YAML).Verify if tags are unique for every ticket. Raise an error and exit if not.Add every ticket into profile_tickets table.Write the change into the data store on disk.runAM profile.query --tags tag1,tag2,...Find all profiles matching specified tag list.runAM profile.delete --tags tag1,tag2,...Delete all profile tickets matching specified tag list. Save that to the disk.IMPORTANT: profiles must be defined before defining any data structures relying on these profiles.Port (Server) ProvisioningPort provisioning builds low level data required to parse configuration templates for switch ports towards end hosts (server, compute, external route/switch, etc.).The keywordserverused for corresponding CLI command may be a bit confusing, as the workflow is not limited to servers only. But any other keyword can be equally confusing. ChangerunAM.cli_specif required.Port provisioning ticket examples are provided intests > data > server_ticketsCommands:runAM server.add --input_file <server-ticket-name>.ymlAdd a server ticket into the database and build low level data required to parse configuration templates.
Actions:Find out if ticket is a dictionary (single-doc) or a list (multi-doc YAML).Verify if server_id is already present in the database. server_id must be unique. If already present raise an error and exit.Verify if switch_name/switch_port combinations defined in the ticket are already in use. If in use, raise an error and exit.Add tickets into the database.Build low level data required to parse configuration templates.Write the change into the data store on disk.runAM server.query --server_id <server ID>Find a server ticket matching specified server ID. It is also possible to search tickets by--switch_nameand/or--switch_port.--print_yamlcan be used to print output as YAML. That is typically required to dump a ticket for editing.For example,runAM server.query --switch.name LEAF1 --switch.port Ethernet12/1 --print_yamlwill search for a ticket used to provision Ethernet12/1 on LEAF1. Output will be printed as YAML.Use--print_docIDsto print document IDs if required.runAM server.delete --server_id <server ID>Delete a server ticket matching specified server ID.
Actions:Find a server ticket matching the specified server ID.Delete the ticket.Re-build low level data required to parse configuration templates.Write the change into the data store on disk.