def main(): if LOGGING: logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') with dna.Dnac(HOST) as dnac: dnac.login(USERNAME, PASSWORD) domains = dnac.get("data/customer-facing-service/ConnectivityDomain", ver="v2") segments = dnac.get("data/customer-facing-service/Segment", ver="v2") fmt = "{:4} {:26} {:13} {:7} {:26}" print(fmt.format("VLAN", "Name", "Traffic type", "Layer 2", "Fabric")) print('-' * 80) for segment in segments.response: fabric = dna.find(domains, segment.connectivityDomain.idRef).name print( fmt.format(segment.vlanId, segment.name, segment.trafficType, str(segment.isFloodAndLearn), fabric)) print('=' * 80)
def main(): if LOGGING: logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') with open(CSVFILE) as csvfile: rows = [row for row in csv.DictReader(csvfile, delimiter=DELIMIT)] with dna.Dnac(HOST) as dnac: dnac.login(USERNAME, PASSWORD) # Get fabric domains, virtual networks and virtual network contexts ippools = dnac.get("ippool", ver="api/v2").response sites = dnac.get("group", params={"groupType": "SITE"}).response for row in rows: parent = lookup(ippools, "ipPoolName", row["Parent Pool"]) site = lookup(sites, "groupNameHierarchy", row["Site"]) # Reserve sub pool if parent is not None: print("Reserving %s" % row["IP Pool Name"]) # Request body for new sub pool data = { "ipPoolName": row["IP Pool Name"], "ipPoolOwner": "DNAC", "ipPoolCidr": row["IP Pool CIDR"], "parentUuid": parent.id, "shared": True, "overlapping": make_bool(row["Overlapping"]), "context": [{ "contextKey": "siteId", "contextValue": site.id }], "dhcpServerIps": make_list(row["DHCP Servers"]), "dnsServerIps": make_list(row["DNS Servers"]), "gateways": make_list(row["Gateway"]) } # Commit request logging.debug("data=" + json.dumps(data)) response = dnac.post("ippool/subpool", ver="api/v2", data=data).response print("Waiting for Task") task_result = dnac.wait_on_task(response.taskId).response print("Completed in %s seconds" % (float(task_result.endTime - task_result.startTime) / 1000)) # Make object reference for GUI data = [{ "groupUuid": site.id, "instanceType": "reference", "key": "ip.pool.%s.%s" % (row["Type"].lower(), task_result.progress), "namespace": "global", "type": "reference.setting", "value": [{ "objReferences": [task_result.progress], "type": row["Type"].lower(), "url": "" }] }] # Commit request logging.debug("data=" + json.dumps(data)) response = dnac.post("commonsetting/global/" + site.id, data=data).response print("Waiting for Task") task_result = dnac.wait_on_task(response.taskId).response print("Completed in %s seconds" % (float(task_result.endTime - task_result.startTime) / 1000)) # Create root pool else: print("Adding %s" % row["IP Pool Name"]) # Request body for new IP pool data = dna.JsonObj({ "ipPoolCidr": row["IP Pool CIDR"], "ipPoolName": row["IP Pool Name"], "dhcpServerIps": make_list(row["DHCP Servers"]), "dnsServerIps": make_list(row["DNS Servers"]), "gateways": make_list(row["Gateway"]), "overlapping": make_bool(row["Overlapping"]) }) # Commit request logging.debug("data=" + json.dumps(data)) response = dnac.post("ippool", ver="api/v2", data=data).response print("Waiting for Task") task_result = dnac.wait_on_task(response.taskId).response print("Completed in %s seconds" % (float(task_result.endTime - task_result.startTime) / 1000)) # Task result returns new ip pool id data.id = task_result.progress ippools.append(data)
def main(): if LOGGING: logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') with dna.Dnac(HOST) as dnac: dnac.login(USERNAME, PASSWORD) # Get available templates templates = dnac.get("template-programmer/template") print("Templates:") for i, template in enumerate(templates): print(i, template.projectName, template.name) print('-' * 80) idx = int(raw_input("Select template: ")) # Find latest version of selected template latest = max(templates[idx].versionsInfo, key=lambda vi: vi.version) # Get template template = dnac.get("/template-programmer/template/" + latest.id) logging.debug("content=" + template.templateContent) params = {} if template.templateParams: print("Input template parameters:") for tp in template.templateParams: dtype = tp.dataType if tp.dataType else "STRING" dname = tp.displayName if tp.displayName else tp.parameterName # Make list of selection values, if any v = "" if tp.selection: v = ", ".join(iter(tp.selection.selectionValues.values())) if not v: # Make list of value ranges, if any v = (", ".join("%d-%d" % (r.minValue, r.maxValue) for r in tp.range)) # Compose user prompt for parameter value input prompt = ("%s %s [%s]" % (dtype, dname, v) if v else "%s %s" % (dtype, dname)) params[tp.parameterName] = raw_input("%s: " % prompt) else: print("Template takes no parameters") # Get network-devices devices = dnac.get("network-device").response print("Devices:") for i, device in enumerate(devices): print(i, device.hostname) print('-' * 80) idx = int(raw_input("Select device: ")) # Verify matching template device type if not dna.find(template.deviceTypes, devices[idx].family, "productFamily"): print("Device type mismatch") return # Compose body for template deploy data = [{ "templateId": latest.id, "targetInfo": [{ "type": "MANAGED_DEVICE_UUID", "params": params, "id": devices[idx].id, "hostName": devices[idx].hostname }] }] # Get CFS DeviceInfo of selected device dis = dnac.get("data/customer-facing-service/DeviceInfo", ver="v2", params={ "name": devices[idx].id }).response if not dis: print("Device has not been provisioned yet") return # Instruct CFS to deploy a user template logging.debug("payload=" + json.dumps(data)) payload = base64.b64encode(json.dumps(data).encode()).decode() dis[0].customProvisions = [{ "type": "USER_CLI_TEMPLATE_PROVISION", "payload": payload }] # Commit changes logging.debug("data=" + json.dumps(dis)) response = dnac.put("data/customer-facing-service/DeviceInfo", ver="v2", data=dis).response print("Waiting for Task") task_result = dnac.wait_on_task(response.taskId).response print("Completed in %s seconds" % (float(task_result.endTime - task_result.startTime) / 1000))
def main(): if LOGGING: logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') with open(CSVFILE) as csvfile: rows = [row for row in csv.DictReader(csvfile, delimiter=DELIMIT)] with dna.Dnac(HOST) as dnac: dnac.login(USERNAME, PASSWORD) # Get devices, auth templates, scalable groups and segments devices = dnac.get("network-device") sps = dnac.get("siteprofile", params={"populated": "true"}).response sgts = dnac.get("data/customer-facing-service/scalablegroup", ver="v2").response segments = dnac.get("data/customer-facing-service/Segment", ver="v2").response # Iterate unique hostnames for host in set(r["Hostname"] for r in rows if r["Hostname"] != ""): print("Host:", host) removed = [] updated = [] added = [] # Lookup device matching hostname device = dna.find(devices, host, "hostname") # Get interfaces and device info ifs = dnac.get("interface/network-device/" + device.id).response try: # DNAC 1.1 uses network device id as cfs name di = dnac.get("data/customer-facing-service/DeviceInfo", ver="v2", params={ "name": device.id }).response[0] except IndexError: # DNAC 1.2 uses network device hostname as cfs name di = dnac.get("data/customer-facing-service/DeviceInfo", ver="v2", params={ "name": device.hostname }).response[0] # Iterate csv file rows for this host for row in [r for r in rows if r["Hostname"] == host]: data = None # Lookup objects matching name specified in csv file rows interface = lookup(ifs, "portName", row["Interface"]) auth = lookup(sps, "name", row["Authentication"]) sgt = lookup(sgts, "name", row["Scalable group"]) segment = lookup(segments, "name", row["Data segment"]) voice = lookup(segments, "name", row["Voice segment"]) # Pop interface info from list and store in data dict for idx, dii in enumerate(di.deviceInterfaceInfo): if dii.interfaceId == interface.id: data = di.deviceInterfaceInfo.pop(idx) break # Remove interface action if no values are specified if not any((auth, sgt, segment, voice)): removed.append(interface.portName) if data is None: raise (ValueError(interface.portName + " not in cfs")) data = None # Update interface action if id is found in list elif data is not None: updated.append(interface.portName) # Clear fields data.segment = [] data.pop("authenticationProfile", None) data.pop("scalableGroupId", None) data.pop("connectedDeviceType", None) # Add interface else: added.append(interface.portName) data = dna.JsonObj({ "interfaceId": interface.id, "role": "LAN", "segment": [] }) # Update fields if auth is not None: data.authenticationProfileId = auth.siteProfileUuid if segment is not None: data.segment.append({"idRef": segment.id}) if voice is not None: data.segment.append({"idRef": voice.id}) if sgt is not None: data.scalableGroupId = sgt.id if row["Device type"] != "": data.connectedDeviceType = row["Device type"] # Save in device interface info list if data is not None: di.deviceInterfaceInfo.append(data) print("Removed:", *removed) print("Updated:", *updated) print("Added:", *added) # Commit changes logging.debug("data=" + json.dumps([di])) response = dnac.put("data/customer-facing-service/DeviceInfo", ver="v2", data=[di]).response print("Waiting for Task") task_result = dnac.wait_on_task(response.taskId).response print("Completed in %s seconds" % (float(task_result.endTime - task_result.startTime) / 1000))
def main(): if LOGGING: logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') with dna.Dnac(HOST) as dnac: dnac.login(USERNAME, PASSWORD) # Get available templates templates = dnac.get("template-programmer/template") print("Templates:") for i, template in enumerate(templates): print(i, template.projectName, template.name) print('-' * 80) idx = int(raw_input("Select template: ")) # Find latest version of selected template latest = max(templates[idx].versionsInfo, key=lambda vi: vi.version) # Get template template = dnac.get("/template-programmer/template/" + latest.id) logging.debug("content=" + template.templateContent) params = {} if template.templateParams: print("Input template parameters:") for tp in template.templateParams: dtype = tp.dataType if tp.dataType else "STRING" dname = tp.displayName if tp.displayName else tp.parameterName # Make list of selection values, if any v = "" if tp.selection: v = ", ".join(iter(tp.selection.selectionValues.values())) if not v: # Make list of value ranges, if any v = (", ".join("%d-%d" % (r.minValue, r.maxValue) for r in tp.range)) # Compose user prompt for parameter value input prompt = ("%s %s [%s]" % (dtype, dname, v) if v else "%s %s" % (dtype, dname)) params[tp.parameterName] = raw_input("%s: " % prompt) else: print("Template takes no parameters") # Get network-devices devices = dnac.get("network-device").response print("Devices:") for i, device in enumerate(devices): print(i, device.hostname) print('-' * 80) idx = int(raw_input("Select device: ")) # Verify matching template device type if not dna.find(template.deviceTypes, devices[idx].family, "productFamily"): print("Device type mismatch") return # Body data = { "targetInfo": [{ "id": devices[idx].managementIpAddress, "type": "MANAGED_DEVICE_IP", "params": params }], "templateId": latest.id } logging.debug("data=" + json.dumps(data)) response = dnac.post("template-programmer/template/deploy", data=data).response print("Waiting for Task") task_result = dnac.wait_on_task(response.taskId).response print(task_result.progress) print("Completed in %s seconds" % (float(task_result.endTime - task_result.startTime) / 1000))