-
Notifications
You must be signed in to change notification settings - Fork 0
/
aci-extend-vlans.py
206 lines (168 loc) · 6.04 KB
/
aci-extend-vlans.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#!/usr/bin/env python
"""
Originally created for x Proof of Concept
This script will extend VLANs entering the ACI fabric over a single vPC pair.
It will create BDs and EPGs under a tenant/context/AP of your chosing to create a 1:1 vlan mapping to the external network
It is also possible to automatically add a (VMM) domain association to each EPG.
//Rob van der Kind - robvand@cisco.com
"""
import acitoolkit.acitoolkit as aci
import csv
import getpass
import sys
def main():
"""
Main create routine
:return: None
"""
# Login to the APIC
session = aci.Session(raw_input("APIC URL: "), raw_input("APIC username: "), getpass.getpass())
resp = session.login()
if not resp.ok:
print('%% Could not login to APIC')
if resp.ok:
print ("\nApic login successful")
# Selecting Tenant
tenants = aci.Tenant.get(session)
print ('\n')
print ('-------')
print ('Tenants')
print ('-------')
for temp_tenant in tenants:
print(temp_tenant)
tenant_name = raw_input("\nPlease enter the Tenant name: ")
tenant = aci.Tenant(tenant_name)
# Selecting Application Profile
application_profiles = aci.AppProfile.get(session, tenant)
print ('\n')
print ('--------------------')
print ('Application Profiles')
print ('--------------------')
for temp_app_profile in application_profiles:
print(temp_app_profile)
app = aci.AppProfile(raw_input("\nPlease enter the AP name: "), tenant)
contexts = aci.Context.get(session, tenant)
# Selecting VRF or Context for BDs to be created
print ('\n')
print ('--------')
print ('Contexts')
print ('--------')
for temp_context in contexts:
print(temp_context)
context_name = raw_input("\nPlease enter a context for the new BDs: ")
# Select VPC path, defaults to node 101 & 102, edit if required
vpcs = aci.PortChannel.get(session)
print ('\n')
print ('---------')
print ('vPC paths')
print ('---------')
for vpc in vpcs:
print (vpc)
vpc_name = raw_input("\nEnter the vPC name please: ")
VPC_DN = "topology/pod-1/protpaths-101-102/pathep-[{}]".format(vpc_name)
# Select domain type
print ('\n')
print ('-----------')
print ('Domain Type')
print ('-----------')
print ('VMM Domain')
print ('L2')
print ('L3')
print ('Phys')
domain_type = raw_input("\nEnter the domain type please: ")
if domain_type == str("VMM Domain"):
domains = aci.VmmDomain.get(session)
print ("")
print ('----------')
print ('VMM Domain')
print ('----------')
for domain in domains:
print domain.name
vmm_domain_type = raw_input("\nEnter the VMM Domain type (VMware or Microsoft): ")
if vmm_domain_type == str("VMware"):
domain_type_prefix = "uni/vmmp-VMware/dom-"
elif vmm_domain_type == str("Microsoft"):
domain_type_prefix = "uni/vmmp-Microsoft/dom-"
elif domain_type == str("L2"):
domain_type_prefix = "uni/l2dom-"
domains = aci.L2ExtDomain.get(session)
print ("")
print ('------------------')
print ('L2 External Domain')
print ('------------------')
for domain in domains:
print domain.name
elif domain_type == str("L3"):
domain_type_prefix = "uni/l3dom-"
domains = aci.L3ExtDomain.get(session)
print ("")
print ('------------------')
print ('L3 External Domain')
print ('------------------')
for domain in domains:
print domain.name
elif domain_type == str("Phys"):
domain_type_prefix = "uni/phys-"
domains = aci.PhysDomain.get(session)
print ("")
print ('---------------')
print ('Physical domain')
print ('---------------')
for domain in domains:
print domain.name
domain_name = raw_input("\nEnter the domain name please: ")
domain_DN = domain_type_prefix + domain_name
# Importing CSV file containing VLAN,VLAN Name
filename = raw_input("\nPlease enter the path to your .CSV: ")
f = open(filename, 'rt')
input_vlan_bd_pairs = []
extended_vlan_count = 0
try:
reader = csv.reader(f)
for row in reader:
input_vlan_bd_pairs.append(row)
finally:
f.close()
for vlan_bd_pair in input_vlan_bd_pairs:
vlan_id = vlan_bd_pair[0]
bd_name = vlan_bd_pair[1]
# Creating new Bridge domain, change values if required
new_bridge_domain = aci.BridgeDomain(bd_name, tenant)
new_bridge_domain.set_arp_flood("yes")
new_bridge_domain.set_unicast_route("no")
new_bridge_domain.set_unknown_mac_unicast("flood")
new_bridge_domain.set_unknown_multicast("flood")
new_bridge_domain.add_context(aci.Context(context_name, tenant))
#new_bridge_domain.set MULTIDEST FLOODING
# Associate EPG with BD
epg = aci.EPG(bd_name, app)
epg.add_bd(new_bridge_domain)
# Associate path with EPG
static_binding = {"fvRsPathAtt":{"attributes":{"encap":"vlan-{}".format(vlan_id),
"tDn": VPC_DN,
"instrImedcy":"lazy",
"status":"created"}}}
domain = {"fvRsDomAtt":{"attributes":{#"encap":"vlan-{}".format(vlan_id), <- uncomment for static encap. Should be defined in a pool
"tDn": domain_DN,
"instrImedcy":"lazy",
"status":"created"}}}
# Push the changes to the APIC
resp = session.push_to_apic(tenant.get_url(),
tenant.get_json())
epgurl = '/api/node/mo/uni/tn-{}/ap-{}/epg-{}.json'.format(tenant.name, app.name, epg.name)
if not resp.ok:
print('%% Error: Could not push configuration to APIC')
print(resp.text)
domain_server_response = session.push_to_apic(epgurl, domain)
if not resp.ok:
print('%% Error: Could not push configuration to APIC')
print(resp.text)
static_binding_server_response = session.push_to_apic(epgurl, static_binding)
if resp.ok:
extended_vlan_count = extended_vlan_count + 1
print("{}/{} Succesfully extended VLAN {} to ACI fabric").format(extended_vlan_count, len(input_vlan_bd_pairs),bd_name)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass