def main(): new_device_dict = { "ipAddress": ["192.0.2.1"], "snmpVersion": "v2", "snmpROCommunity": "readonly", "snmpRWCommunity": "readwrite", "snmpRetry": "1", "snmpTimeout": "60", "cliTransport": "ssh", "userName": "******", "password": "******", "enablePassword": "******", } token = get_token() api_path = "https://sandboxdnac.cisco.com/dna" headers = {"Content-Type": "application/json", "X-Auth-Token": token} add_res = requests.post( f"{api_path}/intent/api/v1/network-device", json=new_device_dict, headers=headers, ) print(add_res.json())
def main(): """ Execution begins here. """ # Reuse the get_token() function from before. If it fails # allow exception to crash program token = get_token() # Declare useful local variables to simplify request process api_path = "https://sandboxdnac.cisco.com/dna" headers = {"Content-Type": "application/json", "X-Auth-Token": token} # Issue HTTP GET request to get list of network devices get_resp = requests.get(f"{api_path}/intent/api/v1/network-device", headers=headers) # Debugging output to learn the JSON structure, then quit # import json; print(json.dumps(get_resp.json(), indent=2)) # Iterate over list of dictionaries and print device ID and management IP if get_resp.ok: for device in get_resp.json()["response"]: print( f"ID: {device['id']} IP: {device['managementIpAddress']} Type: {device['type']}" ) else: print(f"Device collection failed with code {get_resp.status_code}") print(f"Failure body: {get_resp.text}")
def main(): """ Execution begins here. """ # Reuse the get_token() function from before. If it fails # allow exception to crash program token = get_token() # Declare useful local variables to simplify request process api_path = "https://sandboxdnac.cisco.com/dna" headers = {"Content-Type": "application/json", "X-Auth-Token": token} # Create a dictionary to represent the new device to add new_device_dict = { "ipAddress": ["192.0.2.1"], "snmpVersion": "v2", "snmpROCommunity": "readonly", "snmpRWCommunity": "readwrite", "snmpRetry": "1", "snmpTimeout": "60", "cliTransport": "ssh", "userName": "******", "password": "******", "enablePassword": "******", } # Issue HTTP POST request to add a new device with the # "new_device_dict" as the body of the request. add_resp = requests.post( f"{api_path}/intent/api/v1/network-device", json=new_device_dict, headers=headers, ) if add_resp.ok: # Wait 10 seconds after server responds print(f"Request accepted: status code {add_resp.status_code}") time.sleep(10) # Query DNA center for the status of the specific task ID task = add_resp.json()["response"]["taskId"] task_resp = requests.get(f"{api_path}/intent/api/v1/task/{task}", headers=headers) # See if the task was completed successfully or not if task_resp.ok: task_data = task_resp.json()["response"] if not task_data["isError"]: print("New device successfully added") else: print(f"Async task error seen: {task_data['progress']}") else: print(f"Async GET failed: status code {task_resp.status_code}") else: # The initial HTTP POST failed; print details print(f"Device addition failed with code {add_resp.status_code}") print(f"Failure body: {add_resp.text}")
def main(argv): """ Execution begins here. """ # Reuse the get_token() function from before. If it fails # allow exception to crash program # https://developer.cisco.com/docs/dna-center-api-1210/ host = "sandboxdnac2.cisco.com" token = get_token(host) # Declare useful local variables to simplify request process headers = {"Content-Type": "application/json", "X-Auth-Token": token} # API requires specifying the epoch as query parameter. Take current # time in epoch seconds, convert to ms, and remove decimal # Note: epoch 0 = 00:00:00 UTC on 1 January 1970 current_epoch = int(time.time() * 1000) params = {"timestamp": current_epoch} # Pass CLI arguments into processor function to return subset of # valid, correctly formatted MAC addresses (error checking) macs = get_macs(argv) # Iterate over all valid MAC addresses for mac in macs: # Add a new key to specify the MAC address to query params["macAddress"] = mac # Issue HTTP GET request to get specific client details get_resp = requests.get( f"https://{host}/dna/intent/api/v1/client-detail", headers=headers, params=params, ) # Print error details (rather than raise error) and exit if failure get_resp_json = get_resp.json() if not get_resp.ok: print(f"Request failed: {get_resp.status_code}/{get_resp.reason}") print(json.dumps(get_resp_json, indent=2)) sys.exit(2) # Print JSON response for troubleshooting and learning # print(json.dumps(get_resp_json, indent=2)) # Request succeeded; print stats = get_resp_json["detail"] print(f"Wireless details for MAC {mac}") print(f" IPv4 Address: {stats['hostIpV4']}") print(f" Freq/chan: {stats['frequency']} GHz / {stats['channel']}") print(f" RSSI/SNR: {stats['rssi']} / {stats['snr']}\n")
def main(): token = get_token() api_path = "https://sandboxdnac.cisco.com/dna" headers = {"Content-Type": "application/json", "X-Auth-Token": token} get_resp = requests.get(f"{api_path}/intent/api/v1/network-device", headers=headers) if get_resp.ok: for device in get_resp.json()['response']: print(f" ID : {device['id']}, IP:i{device['managementIpAddress']}") else: print(f"failure body: {get_resp.text}")
def main(): """ Execution begins here. """ # The FTD sandbox uses a self-signed cert at present, so let's ignore any # obvious security warnings for now. requests.packages.urllib3.disable_warnings() # The API path below is what the DevNet sandbox uses for API testing, # which may change in the future. Be sure to check the IP address as # I suspect this changes frequently. See here for more details: # https://developer.cisco.com/firepower/ api_path = "https://10.10.20.65/api/fdm/latest" token = get_token(api_path) # To authenticate, we issue a POST request with our username/password # as a JSON body to obtain a bearer token in response. post_headers = { "Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}", } # Load the new network objects to be added as Python objects with open("json_state/new_netobjs.json", "r") as handle: network_objs = json.load(handle) # Loop over network objects and issue a POST request for each # network object to add. Raise HTTPError if anything fails for net in network_objs: post_resp = requests.post( f"{api_path}/object/networks", headers=post_headers, json=net, verify=False, ) # Print object details if success or error fails if failed. We # don't wait to raise_for_status() which halts the entire process # even if a single element fails if post_resp.ok: net_json = post_resp.json() print( f"Added {net_json['name']} network object at {net_json['id']}") else: print(f"Couldn't add {net['name']} network object") print(f" Details: {post_resp.status_code} / {post_resp.reason}")
def main(): token = get_token() api_path = "https://sandboxdnac.cisco.com/dna" headers = {"Content-Type": "application/json", "X-Auth-Token": token} get_resp = requests.get(f"{api_path}/intent/api/v1/network-device", headers=headers) # import json; print(json.dumps(get_resp.json(), indent=2)) if get_resp.ok: for device in get_resp.json()["response"]: print(f" ID: {device['id']} IP: {device['managementIpAddress']}") else: print(f"Device collection failed with code {get_resp.status_code}") print(f"Failure body: {get_resp.text}")
def main(): """ Execution begins here. """ # Reuse the get_token() function from before. If it fails # allow exception to crash program # https://developer.cisco.com/docs/dna-center-api-1210/ host = "sandboxdnac2.cisco.com" token = get_token(host) # Declare useful local variables to simplify request process headers = {"Content-Type": "application/json", "X-Auth-Token": token} # API requires specifying the epoch as query parameter. Take current # time in epoch seconds, convert to ms, and remove decimal # Note: epoch 0 = 00:00:00 UTC on 1 January 1970 current_epoch = int(time.time() * 1000) params = {"timestamp": current_epoch} # Issue HTTP GET request to get high-level client health get_resp = requests.get( f"https://{host}/dna/intent/api/v1/client-health", headers=headers, params=params, ) # Raise errors if the request failed, and convert body to JSON get_resp.raise_for_status() get_resp_json = get_resp.json() # Print JSON response for troubleshooting and learning # import json; print(json.dumps(get_resp_json, indent=2)) # Iterate over all score details and categories for score in get_resp_json["response"]: for cat in score["scoreDetail"]: # Print the client type (wired or wireless) then the quantity # of clients at each quality level. Finish up with a newline print(f"{cat['scoreCategory']['value']} client health") for qual in cat["scoreList"]: print(f" {qual['scoreCategory']['value']:<6}", end=" ") print(f"clients: {qual['clientCount']}") print()
def main(): """ Execution begins here. """ # The FTD sandbox uses a self-signed cert at present, so let's ignore any # obvious security warnings for now. requests.packages.urllib3.disable_warnings() # The API path below is what the DevNet sandbox uses for API testing, # which may change in the future. Be sure to check the IP address as # I suspect this changes frequently. See here for more details: # https://developer.cisco.com/firepower/ api_path = "https://10.10.20.65/api/fdm/latest" token = get_token(api_path) # To authenticate, we issue a POST request with our username/password # as a JSON body to obtain a bearer token in response. get_headers = { "Accept": "application/json", "Authorization": f"Bearer {token}", } # Issue a GET request to collect a list of network objects configured # on FTD. These are the IP subnets, hosts, and FQDNs that might be # included in various security access policies. item_list = [] ftd_get_recursive( resource=f"{api_path}/object/networks", headers=get_headers, item_list=item_list, ) # Iterate over the list of networks and print out a few of the # most interesting values such as name, ID, and prefix/FQDN value. for net in item_list: print(f"Name: {net['name']} ({net['description']})") print(f" ID: {net['id']}") print(f" Type / Value: {net['subType']} / {net['value']}") # Write data to a JSON file to simplify future deletions outfile = "json_state/present_netobjs.json" with open(outfile, "w") as handle: json.dump(item_list, handle, indent=2) print(f"Saved present network objects to {outfile}")
def get_device_list(): api_path = "https://sandboxdnac.cisco.com/dna" auth = auth_token.get_token() headers = {"Content-Type": "application/json", "X-Auth-Token": auth} auth_resp = requests.get(f"{api_path}/intent/api/v1/network-device/", headers=headers) auth_resp.raise_for_status() print(auth_resp.json()) print("##########################################") device_list = json.dumps(auth_resp.json(), indent=2) if auth_resp.ok: for device in auth_resp.json()["response"]: print(f"ID: {device['id']} IP: {device['managementIpAddress']}") else: print("operation is not successful") return device_list
def main(): """ Execution begins here. """ # The FTD sandbox uses a self-signed cert at present, so let's ignore any # obvious security warnings for now. requests.packages.urllib3.disable_warnings() # The API path below is what the DevNet sandbox uses for API testing, # which may change in the future. Be sure to check the IP address as # I suspect this changes frequently. See here for more details: # https://developer.cisco.com/firepower/ api_path = "https://10.10.20.65/api/fdm/latest" token = get_token(api_path) # To authenticate, we issue a POST request with our username/password # as a JSON body to obtain a bearer token in response. del_headers = { "Accept": "application/json", "Authorization": f"Bearer {token}", } # Load the currently-configured network objects, which is populated # by the "get" script. These will be targets for deletion with open("json_state/present_netobjs.json", "r") as handle: network_objs = json.load(handle) # Iterate over the loaded objects and issue DELETE requests for each for net in network_objs: del_resp = requests.delete( net["links"]["self"], headers=del_headers, verify=False ) # Print object details if success or error fails if failed. We # don't wait to raise_for_status() which halts the entire process # even if a single element fails if del_resp.ok: print(f"Deleted {net['name']} network object at {net['id']}") else: print(f"Couldn't delete {net['name']} network object at {net['id']}") print(f" Details: {del_resp.status_code} / {del_resp.reason}")
from auth_token import get_token def main(): """ Execution begins here. """ # Reuse the get_token() function from before. If it fails allow exception to crash program token = get_token() # Declare useful local variables to simplify request process api_path = "https://sandboxdnac.cisco.com/dna" headers = {"Content-Type": "application/json", "X-Auth-Token": token} # Issue an HTTP GET to search for a specific device by IP address delete_ip = "1.1.1.1" get_resp = requests.get( f"{api_path}/intent/api/v1/network-device/ip-address/{delete_ip}", headers=headers, ) # If the device was found, continue with deletion if get_resp.ok: delete_id = get_resp.json()["response"]["id"] print(f"Found device with mgmt IP {delete_ip} and ID {delete_id}") # Issue HTTP DELETE and specify the device ID. Like the HTTP POST to add a device, this is an asynchronous operation delete_resp = requests.delete( f"{api_path}/intent/api/v1/network-device/{delete_id}", headers=headers, ) # If delete succeeded, check task ID for completion if delete_resp.ok: # Wait 10 seconds after server responds print(f"Request accepted: status code {delete_resp.status_code}") time.sleep(10) # Query DNA center for the status of the specific task ID task = delete_resp.json()["response"]["taskId"] task_resp = requests.get( f"{api_path}/intent/api/v1/task/{task}", headers=headers ) # See if the task was completed successfully or not if task_resp.ok: task_data = task_resp.json()["response"] if not task_data["isError"]: print("Old device successfully deleted") else: print(f"Async task error seen: {task_data['progress']}") else: print(f"Async GET failed: status code {task_resp.status_code}") else: # The initial HTTP DELETE failed; print details print(f"Device removal failed with code {delete_resp.status_code}") print(f"Failure body: {delete_resp.text}") else: print(f"Could not find device with mgmt IP {delete_ip}") print(f"Code: {get_resp.status_code} Body: {get_resp.text}")
def main(): """ Execution begins here. """ # Reuse the get_token() function from before. If it fails # allow exception to crash program # https://developer.cisco.com/docs/dna-center-api-1210/ host = "sandboxdnac2.cisco.com" token = get_token(host) # Declare useful local variables to simplify request process headers = {"Content-Type": "application/json", "X-Auth-Token": token} # API requires specifying the epoch as query parameter. Take current # time in epoch seconds, convert to ms, and remove decimal # Note: epoch 0 = 00:00:00 UTC on 1 January 1970 current_epoch = int(time.time() * 1000) params = {"timestamp": current_epoch} # Run the loop however many times is specified by ATTEMPTS for i in range(ATTEMPTS): # Code in the "try" block may raise errors try: # Issue HTTP GET request to get high-level client health get_resp = requests.get( f"https://{host}/dna/intent/api/v1/client-health", headers=headers, params=params, timeout=TIMEOUT, ) # Request succeeded, break out of loop early if get_resp.ok: break except requests.exceptions.ReadTimeout: # Catch error, print message, and quit the program # with error code 1 if we are on the last attempt print(f"Timeout {i+1}/{ATTEMPTS} ({TIMEOUT} sec)") if i + 1 == ATTEMPTS: print("Could not collect client health") import sys sys.exit(1) # Convert HTTP response body to JSON to extract health data get_resp_json = get_resp.json() # Print JSON response for troubleshooting and learning # import json; print(json.dumps(get_resp_json, indent=2)) # Iterate over all score details and categories for score in get_resp_json["response"]: for cat in score["scoreDetail"]: # Print the client type (wired or wireless) then the quantity # of clients at each quality level. Finish up with a newline print(f"{cat['scoreCategory']['value']} client health") for qual in cat["scoreList"]: print(f" {qual['scoreCategory']['value']:<6}", end=" ") print(f"clients: {qual['clientCount']}") print()
def main(): """ Execution begins here. """ # Reuse the get_token() function from before. If it fails # allow exception to crash program token = get_token() # Declare useful local variables to simplify request process api_path = "https://sandboxdnac2.cisco.com" headers = {"Content-Type": "application/json", "X-Auth-Token": token} # Issue HTTP GET request to get list of network devices get_resp = requests.get(f"{api_path}/api/v1/network-device", headers=headers) # adding a devices dictionary new_device_dict = { "ipAddress": ["1.1.1.1"], "snmpVersion": "v2", "snmpROCommunity": "readonly", "snmpRWCommunity": "readwrite", "snmpRetry": "1", "snmpTimeout": "60", "cliTransport": "ssh", "userName": "******", "password": "******", "enablePassword": "******", } # Debugging output to learn the JSON structure, then quit import json; print(json.dumps(get_resp.json(), indent=2)) Iterate over list of dictionaries and print device ID and management IP add_resp = requests.post(f"{api_path}/dna/intent/api/v1/network-device", json=new_device_dict, headers=headers) if add_resp.ok: # Wait 10 seconds after server responds print(f"Request accepted: status code {add_resp.status_code}") time.sleep(10) # Query DNA center for the status of the specific task ID task = add_resp.json()["response"]["taskId"] task_resp = requests.get(f"{api_path}/intent/api/v1/task/{task}", headers=headers) # See if the task was completed successfully or not if task_resp.ok: task_data = task_resp.json()["response"] if not task_data["isError"]: print("New device successfully added") else: print(f"Async task error seen: {task_data['progress']}") else: print(f"Async GET failed: status code {task_resp.status_code}") else: # The initial HTTP POST failed; print details print(f"Device addition failed with code {add_resp.status_code}") print(f"Failure body: {add_resp.text}")
from dnacentersdk import DNACenterAPI from auth_token import get_token token = get_token() dnac = api.DNACenterAPI(encoded_auth={token}, base_url='https://sandboxdnac2.cisco.com', version='1.2.10') # Or even just dnac = api.DNACenterAPI() as base_url and version have those values. try: devices = dnac.devices.get_device_list(family='Switches and Hubs') for device in devices.response: print('{:20s}{}'.format(device.hostname, device.upTime)) except ApiError as e: print(e)