In this section, you will define the variable data set to create VRFs and Networks along with target switches for attaching and deploying the configuration. You will also create your main command line program file that will take command line arguments, read your variables in from a YAML file to drive all your NDFC API interaction.
Define the YAML data variables that will be used by your command line program to create VRFs and Networks, then attach them to switches.
Both the NDFC APIs for creating VRFs and Networks requires a name, the VRF ID, and VLAN ID to be instantiated. For Networks, there is additional information such as IP address information. Likewise, both NDFC APIs for attaching VRFs and Networks to switches require the switch information. Networks requires the port-attach information. With the API, the switch serial number is actually in your YAML data file you are providing.
touch ~/workspace/ndfclab/scripts/overlay_vars.yml
cat <<EOF >> ~/workspace/ndfclab/scripts/overlay_vars.yml
---
vrfs:
- vrf_name: PythonVRF
vrf_id: 50002
vlan_id: 2002
attach:
- staging-leaf1
- staging-leaf2
networks:
- net_name: PythonNet1
vrf_name: PythonVRF
net_id: 30002
vlan_id: 2302
vlan_name: PythonNet1
ipv4_gw: "172.16.1.1/24"
attach:
- switch: staging-leaf1
port: Ethernet1/2
- switch: staging-leaf2
port: Ethernet1/2
EOF
Via pip, install pyyaml
, which will allow your command line program to
import and read a YAML file that will contain configuration data.
pip install pyyaml
In your VSCode terminal pane, open a new Python file to start creating your command line program:
code-server -r ~/workspace/ndfclab/scripts/overlay_script.py
In your main script, you will leverage some built-in Python packages to accept command line arguments to your script or program.
These include sys
, argparse
, and os
. sys
will be used to successfully close out your
Python program, argparse
will be used to create your command line parser and define what command line options are available to your
program, and os
will be used to read your YAML data file, i.e. your intended overlay configuration defined as YAML data.
yaml
is also imported to make use of pyyaml
as described above. Your ndclient
class is imported.
Lastly, you will be importing the helper functions from the ndfc utility script you created in the previous section.
import sys
import argparse
import os
import yaml
import time
import ndclient
from ndfc_utils import create_vrfs, create_networks, tabulate_vrfs, tabulate_networks
This Python script will only contain a main function. The first part of your main function establishes your command line options using argparse
.
With argparse
, you need to first instantiate the parser. It is good practice to define a description and example(s) to help users use the tool.
With the parser created, you then need to .add_argument
to the parser object. The number of arguments you add are pre-defined here for this lab, however,
this is dependent on the use cases you want to implement. What is created in this lab, could be taken and expanded. You need arguments from a user for ND (IP address or FQDN),
the username and password for ND, the login domain, the fabric in NDFC, and the data you want to provision to NDFC for VRFs and Networks.
def main():
parser = argparse.ArgumentParser(
description='NDFC Command Line Progarm',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=r'''Examples:
%(prog)s --nd 192.168.1.2 --username admin --fabric staging --filename data.yml
'''
)
parser.add_argument('--nd', help='Nexus Dashboard, e.g. nd.example.com or 192.168.1.2', required=True)
parser.add_argument('--username', help='ND username', required=True)
parser.add_argument('--password', default=os.environ.get('ND_PASSWORD'), help='ND password')
parser.add_argument('--domain', default='local', help='ND login domain')
parser.add_argument('--fabric', help='NDFC fabric', required=True)
parser.add_argument('--filename', help='Variables filename')
parser.add_argument('--get', help='Get options', choices=['vrfs', 'networks'])
args = parser.parse_args()
Using your NDClient defined in the previous section and that you imported at the start of this section,
define your NDClient object using the argparse
arguments, called nd
.
Then, using your instantiated nd
object, you can leverage your login
method to authenticate with ND.
nd = ndclient.NDClient(
url='https://' + args.nd,
username=args.username,
password=args.password,
login_domain=args.domain
)
nd.login()
This part of your code is the primary block that creates and attaches VRFs and Networks via NDFC's API.
The if statement is a simple check to ensure that a file is indeed passed on the command line.
The next four lines of code is a method to open your YAML data file, read it, store it in a variable (ndfc_vars
), and then close the file.
Following setting your external data into a variable, the two functions to create VRFs (create_vrfs
) and Networks (create_networks
) are invoked.
Both of these functions have your nd object, fabric name, and YAML data variables stored in a variable passed as arguments.
These functions make use of the code you defined in your utility helper module.
The last if block is a simple if statement used to check if the user desires getting some information from NDFC using the getter or query API endpoints for VRFs or Networks you defined in the previous section. The way your above argparse options are set is to allow for either getting the vrfs or networks, thus the need for another if block that checks for which option specified on the command line to then execute the correct function.
if args.filename:
path = f'{os.path.dirname(__file__)}/{args.filename}'
ndfc_vars_file = open(path, 'r')
ndfc_vars = yaml.full_load(ndfc_vars_file)
ndfc_vars_file.close()
create_vrfs(nd, args.fabric, ndfc_vars)
create_networks(nd, args.fabric, ndfc_vars)
if args.get:
if args.get == 'vrfs':
tabulate_vrfs(nd, args.fabric)
elif args.get == 'networks':
tabulate_networks(nd, args.fabric)
The if __name__ == '__main__':
statement is a way to run your code when it is executed as a script.
if __name__ == '__main__':
sys.exit(main())
Be sure to save your file! Not saving will result in your code not executing.