Skip to content

Commit dbf3b31

Browse files
Add files via upload
1 parent c04c45f commit dbf3b31

File tree

5 files changed

+586
-0
lines changed

5 files changed

+586
-0
lines changed

Child_BGP_l3out.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
def main():
2+
import getpass
3+
from Master_Parent import Client
4+
host = input("Enter the Fabric Controller IP/Hostname Ex:172.19.254.4 :")
5+
usr = input("Enter the Fabric username admin:")
6+
pwd = getpass.getpass(prompt="Enter the password:")
7+
tn = input("Enter the Tenant Name:")
8+
vrf = input("Enter the VRF Name:")
9+
bd = input("Enter the Bridge_ID Name:")
10+
L3OUT_NAME = input("Enter the L3OUT Name:")
11+
L3OUT_DOMAIN = input("Enter the L3OUT Domain Name ex:L3Dom:")
12+
EXTERNAL_SUBNETS_NAME = input("Enter the L3OUT EXTERNAL_SUBNETS_NAME:")
13+
Node_ID = input("Enter the Leaf/Node_ID :")
14+
PORT = input("Enter the Ethernet interface 1/X :")
15+
SVI_VLAN = input("Enter the .1Q SVI_VLAN#:")
16+
SVI_PRI_IP = input("Enter the SVI Primary_IP address/Mask:")
17+
SVI_SEC_IP = input("Enter the SVI Secondary_IP address/Mask:")
18+
ROUTER_ID = input("Enter the unique ROUTER_ID per Node:")
19+
MTU = input("Enter the MTU Size:")
20+
BGP_Peer_IP = input("Enter the BGP_Neigbor_IP:")
21+
REMOTE_ASN = input("Enter the BGP REMOTE_ASN:")
22+
LOCAL_ASN = input("Enter the BGP LOCAL_ASN:")
23+
24+
ACTION = input("Are you sure you want to push the configuration (y/n): ")
25+
26+
if ACTION in ("y","yes","Y","YES"):
27+
#FABRIC=Client(cfg.host, cfg.usr, cfg.pwd)
28+
FABRIC=Client(host, usr, pwd)
29+
print("Calling the Master function -> Authenticating into the Controller")
30+
FABRIC.login()
31+
t1=FABRIC.tenant(tn,vrf,bd)
32+
t20=FABRIC.L3OUT_BGPRAS(tn,vrf,L3OUT_NAME,L3OUT_DOMAIN,EXTERNAL_SUBNETS_NAME,Node_ID,PORT,SVI_VLAN,SVI_PRI_IP,MTU,BGP_Peer_IP,ROUTER_ID,REMOTE_ASN)
33+
t21=FABRIC.L3OUT_BGPLAS(tn,L3OUT_NAME,Node_ID,PORT,BGP_Peer_IP,LOCAL_ASN)
34+
t22=FABRIC.L3OUT_SEC_IP(tn,L3OUT_NAME,Node_ID,PORT,SVI_SEC_IP)
35+
elif ACTION in ("n","no","N","No"):
36+
print("Ending the script")
37+
else:
38+
print("Please enter yes or no.")
39+
40+
41+
if __name__ == '__main__':
42+
main()

FW_GW_Static_L3out_Prework.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
def main():
2+
import getpass
3+
from FW_GW_project_Master import Client
4+
host = "172.19.254.4"
5+
usr="admin"
6+
pwd = "!@#CiScO123"
7+
#tn = input("Enter the Tenant Name:")
8+
tn = "HNSEC_FW_GW"
9+
vrf = input("Enter the VRF Name:")
10+
#L3OUT_NAME = input("Enter the L3OUT Name:")
11+
L3OUT_NAME = vrf
12+
L3OUT_DOMAIN = "fw_l3Dom"
13+
#L3OUT_SUBNETS_NAME = input("Enter the L3OUT L3OUT_SUBNETS_NAME:")
14+
L3OUT_SUBNETS_NAME = L3OUT_NAME+"_Ext_Network"
15+
SVI_VLAN = input("Enter the .1Q SVI_VLAN ID#:")
16+
PRI_Node_ID = input("Enter the Leaf PRI_Node_ID Ex:10X :")
17+
SEC_Node_ID = input("Enter the Leaf SEC_Node_ID Ex:10Y:")
18+
PRI_PORT = input("Enter the Ethernet interface on Leaf PRI_Node_ID X/X :")
19+
SEC_PORT = input("Enter the Ethernet interface on Leaf SEC_Node_ID X/X :")
20+
PRI_SVI_IP = input("Enter the SVI Primary_IP address/Mask:")
21+
SEC_SVI_IP = input("Enter the SVI Secondary_IP address/Mask:")
22+
SVI_GW_IP = input("Enter the SVI GW_IP(HSRP_IP)address/Mask:")
23+
Next_hop = input("Enter the L3out Next_hop :")
24+
PRI_ROUTER_ID = input("Enter the unique Leaf PRI_Node ROUTER_ID (Node.Node.MgmtIP.#):")
25+
SEC_ROUTER_ID = input("Enter the unique Leaf SEC_Node ROUTER_ID (Node.Node.MgmtIP.#):")
26+
APP = "3tier_APP"
27+
Consumer_EPG = "WEB_EPG"
28+
Subnet = "192.168.4.1/24"
29+
#Dest_Network = input("Enter the L3out External Network Ex:0.0.0.0/0 :")
30+
Provider_EPG = L3OUT_SUBNETS_NAME
31+
Dest_Network = "0.0.0.0/0"
32+
#Contract_name1 = input("Enter the Contract Name :")
33+
Contract_name = vrf+"_ct"
34+
#Contract_name = "APP_ct"
35+
Contract_sub = Contract_name+"_sub"
36+
#Contract_Scope = input("Enter the Contract Scope (vrf,tenant,global) :")
37+
Contract_Scope = "tenant"
38+
#Contract_Scope = "VRF"
39+
#MTU = input("Enter the MTU Size:")
40+
MTU = "1500"
41+
#host = input("Enter the Fabric Controller IP/Hostname Ex:172.19.254.4 :")
42+
#usr = input("Enter the Fabric username admin:")
43+
#pwd = getpass.getpass(prompt="Enter the password:")
44+
#bd = input("Enter the Bridge_ID Name:")
45+
46+
ACTION = input("Are you sure you want to push the configuration (y/n): ")
47+
48+
if ACTION in ("y","yes","Y","YES"):
49+
#FABRIC=Client(cfg.host, cfg.usr, cfg.pwd)
50+
FABRIC=Client(host, usr, pwd)
51+
print("Calling the Master function -> Authenticating into the Controller")
52+
FABRIC.login()
53+
t1=FABRIC.tenant(tn,vrf)
54+
t20=FABRIC.L3OUT_Config(tn,vrf,L3OUT_NAME,L3OUT_DOMAIN,L3OUT_SUBNETS_NAME,PRI_Node_ID,PRI_PORT,SVI_VLAN,PRI_SVI_IP,MTU,PRI_ROUTER_ID)
55+
t22=FABRIC.L3OUT_GW_IP(tn,L3OUT_NAME,PRI_Node_ID,PRI_PORT,SVI_GW_IP)
56+
t23=FABRIC.L3OUT_Static(tn,L3OUT_NAME,PRI_Node_ID,Dest_Network,Next_hop)
57+
t20_1=FABRIC.L3OUT_Config(tn,vrf,L3OUT_NAME,L3OUT_DOMAIN,L3OUT_SUBNETS_NAME,SEC_Node_ID,SEC_PORT,SVI_VLAN,SEC_SVI_IP,MTU,SEC_ROUTER_ID)
58+
t22_1=FABRIC.L3OUT_GW_IP(tn,L3OUT_NAME,SEC_Node_ID,SEC_PORT,SVI_GW_IP)
59+
t23_1=FABRIC.L3OUT_Static(tn,L3OUT_NAME,SEC_Node_ID,Dest_Network,Next_hop)
60+
t24=FABRIC.L3OUT_Subnets(tn,L3OUT_NAME,L3OUT_SUBNETS_NAME,Dest_Network)
61+
t25=FABRIC.Contract(tn,Contract_name,Contract_sub,Contract_Scope)
62+
t26=FABRIC.Prov_Contract(tn,L3OUT_NAME,Contract_name,Provider_EPG)
63+
t27=FABRIC.Cons_Contract(tn,Contract_name,APP,Consumer_EPG)
64+
65+
elif ACTION in ("n","no","N","No"):
66+
print("Ending the script")
67+
else:
68+
print("Please enter yes or no.")
69+
70+
71+
if __name__ == '__main__':
72+
main()

FW_GW_project_Master.py

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import requests
2+
import json
3+
from string import Template
4+
requests.urllib3.disable_warnings()
5+
"""
6+
Author: Ganesh Mohan
7+
Date: 12/23/2020
8+
Purpose: Send API calls to APIC and print status
9+
Version: 1.3
10+
"""
11+
12+
class AuthenticationError(Exception):
13+
pass
14+
class Client:
15+
def __init__(self, host, usr, pwd):
16+
#self.jar = requests.cookies.RequestsCookieJar()
17+
self.host = host
18+
self.usr = usr
19+
self.pwd = pwd
20+
self.client = requests.Session()
21+
#Pushing the configuration in the APIC controller
22+
def POST(self, url, data,Role):
23+
response= self.client.post('https://%s%s' % (self.host, url),data=json.dumps(data),timeout=5,verify=False)
24+
resp=response.text
25+
if 'error' in resp:
26+
print("\n!!!!{}: Config already exist or config issue..Code{}\n".format(Role,response))
27+
print("!!!!Error code:{}\n".format(resp))
28+
#raise AuthenticationError
29+
else:
30+
print(">>>>{}:>>>>>Done # Status Code>{}".format(Role,response))
31+
return response
32+
#Pulling the data in the APIC controller
33+
def get(self, url):
34+
print("getting into the controller:{}".format(url))
35+
r=self.client.get('https://%s%s' % (self.host, url),timeout=5,verify=False)
36+
print("get response {}".format(r))
37+
return r
38+
#Login into APIC using static Credentials.
39+
def login(self):
40+
data = {"aaaUser": {"attributes": {"name": self.usr, "pwd": self.pwd}}}
41+
res= self.client.post('https://%s/api/aaaLogin.json' % (self.host),data=json.dumps(data),timeout=5,verify=False)
42+
print(res)
43+
if res.status_code != 200 or 'error' in res.json()['imdata'][0]:
44+
raise AuthenticationError
45+
46+
47+
#T1:Create Tenant,VRF
48+
def tenant(self,Tname,VRF):
49+
Role='T1:tenant:{},VRF:{}'.format(Tname,VRF)
50+
print("\nCreating the tenant:{}\n".format(Tname))
51+
data = { "fvTenant":{"attributes":{"dn":"uni/tn-"+Tname,"status":"created,modified"},"children":[
52+
#{"fvBD":{"attributes":{"dn":"uni/tn-"+Tname+"/BD-"+BD+"_bd","name":BD+"_bd","arpFlood":"true","unicastRoute":"true","rn":"BD-"+BD+"_bd","status":"created,modified"},
53+
#"children":[{"fvRsCtx":{"attributes":{"tnFvCtxName":VRF+"_vrf","status":"created,modified"},"children":[] }}],
54+
{"fvCtx":{"attributes":{"dn":"uni/tn-"+Tname+"/ctx-"+VRF+"_vrf","name": VRF+"_vrf","rn":"ctx-"+VRF+"_vrf","status":"created,modified"},"children":[]
55+
}}]}}
56+
return self.POST('/api/mo/uni/tn-{}.json'.format(Tname), data,Role)
57+
58+
#T2:Create L3 BD,Subnet and Scope of the subnet.
59+
def bd_Subnet(self,Tname,BD,Subnet,Scope):
60+
Role='T2: Creating the L3 BD:{} with Anycast GW:{} on Scope:{}'.format(BD,Subnet,Scope)
61+
scope_list = ['public', 'shared','private']
62+
if Scope in scope_list:
63+
data = {"fvSubnet": {"attributes": {"dn": "uni/tn-"+Tname+"/BD-"+BD+"_bd/subnet-["+Subnet+"]", "ctrl": "", "ip": Subnet, "rn": "subnet-["+Subnet+"]","scope":Scope, "status": "created,modified"},"children": [] } }
64+
else:
65+
data = {"fvSubnet": {"attributes": {"dn": "uni/tn-"+Tname+"/BD-"+BD+"_bd/subnet-["+Subnet+"]", "ctrl": "", "ip": Subnet, "rn": "subnet-["+Subnet+"]", "status": "created"},"children": [] } }
66+
return self.POST('/api/node/mo/uni/tn-{}/BD-{}_bd/subnet-[{}].json'.format(Tname,BD,Subnet), data,Role)
67+
68+
69+
70+
71+
72+
#T19 Create L2 BD domain.
73+
def bd_L2(self,Tname,BD):
74+
Role="T19:{}-L2 BD domain(Flood/Unicast disabled):".format(BD)
75+
data = {"fvBD":{"attributes":{"dn":"uni/tn-"+Tname+"/BD-"+BD+"_bd","arpFlood":"true","unicastRoute":"false","unkMacUcastAct":"flood","status":"created,modified"},"children":[]}}
76+
return self.POST('/api/mo/uni/tn-{}/BD-{}_bd.json'.format(Tname,BD), data,Role)
77+
78+
#T20 Create L3OUT Primary IP & Secondary IP
79+
def L3OUT_Config(self,Tname,VRF,L3OUT_NAME,L3OUT_DOMAIN,L3OUT_SUBNETS,Node_ID,PORT,SVI_VLAN,SVI_IP,MTU,ROUTER_ID):
80+
Role="T20:{}-Configure the L3OUT:".format(L3OUT_NAME)
81+
data = {"l3extOut":{"attributes":{"dn":"uni/tn-"+Tname+"/out-"+L3OUT_NAME,"name":L3OUT_NAME,"rn":"out-"+L3OUT_NAME,"status":"created,modified"},
82+
"children":[
83+
#{"l3extInstP":{"attributes":{"dn":"uni/tn-"+Tname+"/out-"+L3OUT_NAME+"/instP-"+L3OUT_SUBNETS,"name":L3OUT_SUBNETS,"rn":"instP-"+L3OUT_SUBNETS,"status":"created,modified"},"children":[{"l3extSubnet":{"attributes":{"dn":"uni/tn-"+Tname+"/out-"+L3OUT_NAME+"/instP-"+L3OUT_SUBNETS+"/extsubnet-[0.0.0.0/0]","ip":"0.0.0.0/0","status":"created,modified"},"children":[]}}]}},
84+
{"l3extInstP":{"attributes":{"dn":"uni/tn-"+Tname+"/out-"+L3OUT_NAME+"/instP-"+L3OUT_SUBNETS,"name":L3OUT_SUBNETS,"rn":"instP-"+L3OUT_SUBNETS,"status":"created,modified"},"children":[]}},
85+
{"l3extLNodeP":{"attributes":{"dn":"uni/tn-"+Tname+"/out-"+L3OUT_NAME+"/lnodep-"+L3OUT_NAME+"_nodeProfile","name":L3OUT_NAME+"_nodeProfile","status":"created,modified"},
86+
"children":[{"l3extLIfP":{"attributes":{"dn":"uni/tn-"+Tname+"/out-"+L3OUT_NAME+"/lnodep-"+L3OUT_NAME+"_nodeProfile/lifp-"+L3OUT_NAME+"_interfaceProfile","name":L3OUT_NAME+"_interfaceProfile","status":"created,modified"},
87+
"children":[{"l3extRsPathL3OutAtt":{"attributes":{"dn":"uni/tn-"+Tname+"/out-"+L3OUT_NAME+"/lnodep-"+L3OUT_NAME+"_nodeProfile/lifp-"+L3OUT_NAME+"_interfaceProfile/rspathL3OutAtt-[topology/pod-1/paths-"+Node_ID+"/pathep-[eth"+PORT+"]]","tDn":"topology/pod-1/paths-"+Node_ID+"/pathep-[eth"+PORT+"]","addr":SVI_IP,"ifInstT":"ext-svi","mtu":MTU,"encap":"vlan-"+SVI_VLAN,"status":"created,modified","rn":"rspathL3OutAtt-[topology/pod-1/paths-"+Node_ID+"/pathep-[eth"+PORT+"]]"},
88+
"children":[] }}]}},
89+
{"l3extRsNodeL3OutAtt":{"attributes":{"dn":"uni/tn-"+Tname+"/out-"+L3OUT_NAME+"/lnodep-"+L3OUT_NAME+"_nodeProfile/rsnodeL3OutAtt-[topology/pod-1/node-"+Node_ID+"]","tDn":"topology/pod-1/node-"+Node_ID,"rtrId":ROUTER_ID,"rtrIdLoopBack":"false","status":"created,modified"},
90+
"children":[]}}]}},
91+
{"l3extRsEctx":{"attributes":{"tnFvCtxName":VRF+"_vrf","status":"created,modified"},"children":[]}},{"l3extRsL3DomAtt":{"attributes":{"tDn":"uni/l3dom-"+L3OUT_DOMAIN,"status":"created,modified"},"children":[]}}]}}
92+
return self.POST('/api/node/mo/uni/tn-{}/out-{}.json'.format(Tname,L3OUT_NAME), data,Role)
93+
94+
def L3OUT_GW_IP(self,Tname,L3OUT_NAME,Node_ID,PORT,SVI_GW_IP):
95+
Role="T21:{}-L3OUT_Configure the secondary IP:".format(L3OUT_NAME)
96+
data = {"l3extIp":{"attributes":{"addr":SVI_GW_IP,"status":"created"},"children":[]}}
97+
return self.POST('/api/node/mo/uni/tn-{}/out-{}/lnodep-{}_nodeProfile/lifp-{}_interfaceProfile/rspathL3OutAtt-[topology/pod-1/paths-{}/pathep-[eth{}]].json'.format(Tname,L3OUT_NAME,L3OUT_NAME,L3OUT_NAME,Node_ID,PORT),data,Role)
98+
99+
#T22 Create Static L3OUT
100+
def L3OUT_Static(self,Tname,L3OUT_NAME,Node_ID,Dest_Network,Next_hop):
101+
Role= "T22:{}-L3 Static Route Configure Network {} as Next-hop:{}:".format(L3OUT_NAME,Dest_Network,Next_hop)
102+
data = {"ipRouteP":{"attributes":{"dn":"uni/tn-"+Tname+"/out-"+L3OUT_NAME+"/lnodep-"+L3OUT_NAME+"_nodeProfile/rsnodeL3OutAtt-[topology/pod-1/node-"+Node_ID+"]/rt-["+Dest_Network+"]","ip":Dest_Network,"rn":"rt-["+Dest_Network+"]","status":"created,modified"},
103+
"children":[{"ipNexthopP":{"attributes":{"dn":"uni/tn-"+Tname+"/out-"+L3OUT_NAME+"/lnodep-"+L3OUT_NAME+"_nodeProfile/rsnodeL3OutAtt-[topology/pod-1/node-"+Node_ID+"]/rt-["+Dest_Network+"]/nh-["+Next_hop+"]","nhAddr":Next_hop,"rn":"nh-["+Next_hop+"]","status":"created,modified"},"children":[]}}]}}
104+
return self.POST('/api/node/mo/uni/tn-{}/out-{}/lnodep-{}_nodeProfile/rsnodeL3OutAtt-[topology/pod-1/node-{}]/rt-[{}].json'.format(Tname,L3OUT_NAME,L3OUT_NAME,Node_ID,Dest_Network), data,Role)
105+
#T23 Create Static L3OUT
106+
def L3OUT_Subnets(self,Tname,L3OUT_NAME,L3OUT_SUBNETS,Dest_Network):
107+
Role= "T23:{}-L3out Subnets for Network {}:".format(L3OUT_NAME,Dest_Network)
108+
Dest_Network_list = ['0.0.0.0/0']
109+
if Dest_Network in Dest_Network_list:
110+
data= {"l3extSubnet":{"attributes":{"dn":"uni/tn-"+Tname+"/out-"+L3OUT_NAME+"/instP-"+L3OUT_SUBNETS+"/extsubnet-["+Dest_Network+"]","ip":Dest_Network,"scope":"import-security,shared-security,shared-rtctrl","aggregate":"shared-rtctrl","rn":"extsubnet-["+Dest_Network+"]","status":"created,modified"},"children":[]}}
111+
else:
112+
data= {"l3extSubnet":{"attributes":{"dn":"uni/tn-"+Tname+"/out-"+L3OUT_NAME+"/instP-"+L3OUT_SUBNETS+"/extsubnet-["+Dest_Network+"]","ip":Dest_Network,"scope":"import-security,shared-security,shared-rtctrl","aggregate":"","rn":"extsubnet-["+Dest_Network+"]","status":"created,modified"},"children":[]}}
113+
return self.POST('/api/node/mo/uni/tn-{}/out-{}/instP-{}/extsubnet-[{}].json'.format(Tname,L3OUT_NAME,L3OUT_SUBNETS,Dest_Network),data,Role)
114+
115+
#T24 Create Contract
116+
def Contract(self,Tname,Contract_name,Contract_sub,Scope):
117+
Role= "T24:Create Contract {} under Tenant {}:".format(Contract_name,Tname)
118+
scope_list = ['tenant','global']
119+
if Scope in scope_list:
120+
data ={"vzBrCP":{"attributes":{"dn":"uni/tn-"+Tname+"/brc-"+Contract_name,"name":Contract_name,"scope":Scope,"rn":"brc-"+Contract_name,"status":"created,modified"},
121+
"children":[{"vzSubj":{"attributes":{"dn":"uni/tn-"+Tname+"/brc-"+Contract_name+"/subj-"+Contract_sub+"","name":Contract_sub,"rn":"subj-"+Contract_sub,"status":"created,modified"},
122+
"children":[{"vzRsSubjFiltAtt":{"attributes":{"status":"created,modified","tnVzFilterName":"default","directives":"none"},"children":[]}}]}}]}}
123+
else:
124+
data ={"vzBrCP":{"attributes":{"dn":"uni/tn-"+Tname+"/brc-"+Contract_name,"name":Contract_name,"rn":"brc-"+Contract_name,"status":"created,modified"},
125+
"children":[{"vzSubj":{"attributes":{"dn":"uni/tn-"+Tname+"/brc-"+Contract_name+"/subj-"+Contract_sub+"","name":Contract_sub,"rn":"subj-"+Contract_sub,"status":"created,modified"},
126+
"children":[{"vzRsSubjFiltAtt":{"attributes":{"status":"created,modified","tnVzFilterName":"default","directives":"none"},"children":[]}}]}}]}}
127+
return self.POST('/api/node/mo/uni/tn-{}/brc-{}.json'.format(Tname,Contract_name),data,Role)
128+
129+
#T25 Provider Contract
130+
def Prov_Contract(self,Tname,L3OUT_NAME,Contract_name,P_EPG):
131+
Role= "T25:Apply the Provider Contract under EPG {}:".format(P_EPG)
132+
data={"fvRsProv":{"attributes":{"tnVzBrCPName":Contract_name,"status":"created,modified"},"children":[]}}
133+
return self.POST('/api/node/mo/uni/tn-{}/out-{}/instP-{}.json'.format(Tname,L3OUT_NAME,P_EPG),data,Role)
134+
#T25 Consumer Contract
135+
def Cons_Contract(self,Tname,Contract_name,APP,C_EPG):
136+
#print ("Calling Cons_Contract")
137+
Role= "T26:Apply the Consumer Contract under EPG {}:".format(C_EPG)
138+
data ={"fvRsCons":{"attributes":{"tnVzBrCPName":Contract_name,"status":"created,modified"},"children":[]}}
139+
return self.POST('/api/node/mo/uni/tn-{}/ap-{}/epg-{}.json'.format(Tname,APP,C_EPG),data,Role)
140+
141+
def main():
142+
143+
import apic_cfg as cfg
144+
client = Client(cfg.host, cfg.usr, cfg.pwd)
145+
print("\n Authenication in to the controller: {}\n".format(cfg.host))
146+
client.login()
147+
148+
if __name__ == '__main__':
149+
main()

0 commit comments

Comments
 (0)