A python-script provides an intermediate abstraction layer between VSD and the router, translating the VSD data model into the 7750 SR, 7450 ESS, or 7950 XRS router CLI data model. VSD uses metadata key=value parameters to provision service-specific attributes on the 7750. The XMPP messages get to the 7750 and are passed transparently to the Python module so that the CLI is generated and the service created.
The CLI generated by the python-script is not saved in the configuration file; it can be displayed by running the info include-dynamic command on the service contexts. The configuration generated by the python-script is protected and cannot be changed by a CLI user.
The following example shows how the python-script works for a VSD generated configuration:
The following configuration is added to the 7750 SR. In this case, py-l2 is the python-policy received from VSD that calls the l2domain_service.py python script:
*A:PE1>config>python# info
----------------------------------------------
python-script "l2-domain_services" create
primary-url "ftp://1.1.1.1/cf2/l2domain_service.py"
no shutdown
exit
python-policy "py-l2" create
description "Python script to create L2 domains"
vsd script "l2-domain_services"
exit
----------------------------------------------
*A:PE1>config>service>vsd# info
----------------------------------------------
service-range 64000 to 65000
----------------------------------------------
VSD sends metadata containing the service parameters. This opaque parameter string is passed to the python script and is composed of tag=value pairs.
In addition, other information provided by the VSD, (domain, vni, rt-i, rt-e, and service type) is bundled with the metadata string and passed to the python script. For example:
{'rt': 'target:64000:64000', 'rte': 'target:64000:64000', 'domain': 'L2-DOMAIN-
1', 'servicetype': 'L2DOMAIN', 'vni': '64000', 'metadata': 'rd=1:1, sap=1/1/
10:3000'}
The user should consider the following:
The python script is solely responsible for generating the configuration; no configuration aspects of the Static-Dynamic model are used. The python script must be written in a manner similar to those used by RADIUS Dynamic Business Services. Currently, RADIUS Dynamic Business Services and the Fully-Dynamic VSD model are mutually exclusive, one or the other can operate on the same system, but not both at the same time.
The following scripts must be defined to set up, modify, revert, and tear down the configuration for a service: setup_script(), modify_script(), revert_script(), and teardown_script(). These names must always be the same in all scripts. The revert script is only required if the modify script is defined, the latter being optional.
When the configuration for a new domain name is received from the VSD, the metadata and the VSD parameters are concatenated into a single dictionary and the setup script is called. Within the python script:
The VSD UI parameters are referenced as vsdParams['rt'], vsdParams ['domain'], and so on.
The metadata parameters are referenced as vsdParams['metadata'].
When the startup script is executed, the config>service>vsd>domain is created outside the script context before running the actual script. The teardown script removes the vsd domain.
If a specified setup script fails, the teardown script is invoked.
When subsequent configuration messages are received from the VSD, the new parameter list is generated again from the VSD message and compared to the last parameter list that was successfully executed.
If the two strings are identical, no action is taken.
If there is a difference between the strings, the modify script function is called.
If the modify script fails, the revert script is invoked. The teardown script is invoked if the revert script fails or does not exist.
The python-policy is always present in the attributes received from VSD; if the VSD user does not include a policy name, VSD includes 'default' as the python-policy. Hence, care must be taken to ensure that the 'default' policy is always configured in the 7750.
If the scripts are incorrect, teardown and modify procedures could leave orphaned objects. An admin mode (enable-vsd-config) is available to enable an administrator to clean up these objects; it is strictly meant for cleaning orphaned objects only.
The CLI configured services cannot be modified when the user is in enable-vsd-config mode.
Unless the CLI user enters the enable-vsd-config mode, changes of the dynamic created services are not allowed in the CLI. However, changes through SNMP are allowed.
The tools perform service vsd evaluate-script command is introduced to allow the user to test their setup and to modify and tear down python scripts in a lab environment without the need to be connected to a VSD. The successful execution of the command for action setup creates a vsd domain and the corresponding configuration, just as the system would do when the parameters are received from VSD.
The following example shows the use of the tools perform service vsd evaluate-script command:
*A:PE1# tools perform service vsd evaluate-script domain-name "L2-DOMAIN-5" type l2-
domain action setup policy "py-l2" vni 64000 rt-i target:64000:64000 rt-
e target:64000:64000 metadata "rd=1:1, sap=1/1/10:3000"
Success
The following example output shows a python-script that can set up or tear down L2-DOMAINs.
*A:PE1# show python python-script "l2-domain_services" source-in-use
===============================================================================
Python script "l2-domain_services"
===============================================================================
Admin state : inService
Oper state : inService
Primary URL : ftp://1.1.1.1/timos86/cses-V71/cf2/l2domain_service.py
Secondary URL : (Not Specified)
Tertiary URL : (Not Specified)
Active URL : primary
-------------------------------------------------------------------------------
Source (dumped from memory)
-------------------------------------------------------------------------------
1 from alc import dyn
2
3 def setup_script(vsdParams):
4
5 print ("These are the VSD params: " + str(vsdParams))
6 servicetype = vsdParams.get('servicetype')
7 vni = vsdParams.get('vni')
8 metadata = vsdParams['metadata']
9 print ("VSD metadata: " + str(metadata))
10 metadata = dict(e.split('=') for e in metadata.split(','))
11 print ("Modified metadata: " + str(metadata))
12 vplsSvc_id = dyn.select_free_id("service-id")
13 print ("this is the free svc id picked up by the system: " + vplsSvc_id)
14
15 if servicetype == "L2DOMAIN":
16 rd = metadata['rd']
17 sap_id = metadata[' sap']
18 print ('servicetype, VPLS id, rd, sap:', servicetype, vplsSvc_id, rd
, sap_id)
19 dyn.add_cli("""
20 configure service
21 vpls %(vplsSvc_id)s name evi%(vplsSvc_id)s customer 1 create
22 description vpls%(vplsSvc_id)s
23 bgp
24 route-distinguisher %(rd)s
25 route-target %(rt)s
26 exit
27 vxlan instance 1 vni %(vni)s create
28 exit
29 bgp-evpn
30 evi %(vplsSvc_id)s
31 vxlan bgp 1 vxlan-instance 1
32 no shutdown
33 exit
34 exit
35 sap %(sap_id)s create
36 exit
37 no shutdown
38 exit
39 exit
40 exit
41 """ % {'vplsSvc_id' : vplsSvc_id, 'vni' : vsdParams['vni'], 'rt' : v
sdParams['rt'], 'rd' : metadata['rd'], 'sap_id' : sap_id})
42 # L2DOMAIN returns setupParams: vplsSvc_id, servicetype, vni, sap
43 return {'vplsSvc_id' : vplsSvc_id, 'servicetype' : servicetype, 'vni
' : vni, 'sap_id' : sap_id}
44
45
46 #---------------------------------------------------------------------------
47
48 def teardown_script(setupParams):
49 print ("These are the teardown_script setupParams: " + str(setupParams))
50 servicetype = setupParams.get('servicetype')
51 if servicetype == "L2DOMAIN":
52 dyn.add_cli("""
53 configure service
54 vpls %(vplsSvc_id)s
55 no description
56 bgp-evpn
57 vxlan
58 shutdown
59 exit
60 no evi
61 exit
62 no vxlan instance 1 vni %(vni)s
63 bgp
64 no route-distinguisher
65 no route-target
66 exit
67 no bgp
68 no bgp-evpn
69 sap %(sap_id)s
70 shutdown
71 exit
72 no sap %(sap_id)s
73 shutdown
74 exit
75 no vpls %(vplsSvc_id)s
76 exit
77 exit
78 """ % {'vplsSvc_id' : setupParams['vplsSvc_id'], 'vni' : setupParams['
vni'], 'sap_id' : setupParams['sap_id']})
79 return setupParams
80
81
82 d = { "script" : (setup_script, None, None, teardown_script) }
83
84 dyn.action(d)
===============================================================================
For instance, assuming that the VSD sends the following:
{'rt': 'target:64000:64000', 'rte': 'target:64000:64000', 'domain': 'L2-DOMAIN-
5', 'servicetype': 'L2DOMAIN', 'vni': '64000', 'metadata': 'rd=1:1, sap=1/1/
10:3000 '}
The system executes the setup script as follows:
123 2015/06/16 23:35:40.22 UTC MINOR: DEBUG #2001 Base dyn-script req=setup
"dyn-script req=setup: L2-DOMAIN-5
state=init->waiting-for-setup
"
124 2015/06/16 23:35:40.22 UTC MINOR: DEBUG #2001 Base dyn-script req=setup
"dyn-script req=setup: L2-DOMAIN-5
state=waiting-for-setup->generating-setup
"
125 2015/06/16 23:35:40.22 UTC MINOR: DEBUG #2001 Base Python Output
"Python Output: l2-domain_services
These are the VSD params: {'rt': 'target:64000:64000', 'rte': 'target:64000:6400
0', 'domain': '', 'servicetype': 'L2DOMAIN', 'vni': '64000', 'metadata': 'rd=1:1
, sap=1/1/10:3000 '}
VSD metadata: rd=1:1, sap=1/1/10:3000
Modified metadata: {'rd': '1:1', ' sap': '1/1/10:3000 '}
this is the free svc id picked up by the system: 64000
('servicetype, VPLS id, rd, sap:', 'L2DOMAIN', '64000', '1:1', '1/1/10:3000 ')
"
Success
126 2015/06/16 23:35:40.22 UTC MINOR: DEBUG #2001 Base Python Result
"Python Result: l2-domain_services
"
127 2015/06/16 23:35:40.22 UTC MINOR: DEBUG #2001 Base dyn-script req=setup
"dyn-script req=setup: L2-DOMAIN-5
state=generating-setup->executing-setup
"
128 2015/06/16 23:35:40.22 UTC MINOR: DEBUG #2001 Base dyn-script cli 1/1
"dyn-script cli 1/1: script:L2-DOMAIN-5(cli 698 dict 0->126)
configure service
vpls 64000 name ‟evi64000” customer 1 create
description vpls64000
bgp
route-distinguisher 1:1
route-target target:64000:64000
exit
vxlan instance 1 vni 64000 create
exit
bgp-evpn
evi 64000
vxlan bgp 1 vxlan-instance 1
no shutdown
exit
exit
sap 1/1/10:3000 create
exit
no shutdown
exit
exit
exit
"
143 2015/06/16 23:35:40.23 UTC MINOR: DEBUG #2001 Base dyn-script req=setup
"dyn-script req=setup: L2-DOMAIN-5
state=executing-setup->established"