Is it possible to pull config from Cisco APIC controller using REST API from a remote server .
-
1Have you checked out cisco.com/c/en/us/td/docs/switches/datacenter/aci/apic/sw/2-x/… ? – Zac67 Oct 25 '18 at 13:35
I don't know if it's really what you're looking for, but for science you can export APIC configuration in JSON or XML format via REST.
First of all you need to obtain authentication token by running POST request to https://{{APIC}}/api/aaaLogin.json
with JSON body:
{
"aaaUser" : {
"attributes" : {
"name" : "{{username}}",
"pwd" : "{{password}}"
}
}
}
Verify that body type is application/json
.
On Python it will look like this:
import requests
APIC = "10.11.12.13"
APIC_URL = f"https://{APIC}"
API_URL = f"{APIC_URL}/api/node/mo/"
AUTH_URL = f"{APIC_URL}/api/aaaLogin.json"
body = {
"aaaUser" : {
"attributes" : {
"name" : "USERNAME",
"pwd" : "PASSWORD"
}
}
}
def get_auth_token(body):
"""
Obtain authentication cookie for future requests
"""
func_name = get_auth_token.__name__
log_str = f"{func_name}(): "
headers = {'Content-Type': "application/json", 'cache-control': "no-cache"}
result = requests.post(AUTH_URL, data=body, headers=headers, verify=False)
if result.status_code != 200:
print(f"{log_str}HTTP {result.status_code}: request error!")
return
try:
js = result.json()
cookie = {}
cookie['APIC-Cookie'] = js['imdata'][0]['aaaLogin']['attributes']['token']
return cookie
except:
return
Then you can do GET request to obtain uni
child objects which will be configuration you want:
https://{{APIC}}/api/node/mo/uni.json?query-target=children
query-target=children
can also be replaced with query-target=subtree
to get even more data including existing endpoints, counters, etc...
You should include authentication token in your request:
def query_uni(cookie):
"""
Retrieve JSON of requested static VLAN pool
"""
func_name = query_uni.__name__
log_str = f"{func_name}(): "
uri = "uni.json?query-target=children"
result = requests.get(f"{API_URL}{uri}", cookies=cookie, verify=False)
if result.status_code != 200:
print(f"{log_str}HTTP {result.status_code}: request error!")
return
try:
return result.json()
except:
return
You're can also do this with Postman or another app that helps with REST API testing/troubleshooting.
===============================
It is important to note, that configuration obtained with that method cannot be counted as valid fabric backup. For backups you should use special instruments available inside APIC GUI that create snapshots and full backups and store them on APIC or external resources such as FTP/SFTP/TFTP.
I tried the method described previously using either query-target=children or query-target=subtree; I got a json or xml file but all the objects are set at the same indentation level, so, there is no subtree hierarchy shown : for example, all Tenants are shown without their EPGs inside, all EPGs are shown without their Static Ports, nor Domains, ...
I did this test via the following icurl command from APIC bash : icurl -o /tmp/Extract-Full-uni-191023-V4.json -X GET 'http://localhost:7777/api/node/mo/uni.json?query-target=children'
I also tried these 2 other forms :
icurl -o /tmp/Extract-Full-uni-191023-V2.json -X GET 'http://localhost:7777/api/node/mo/uni.json?query-target=subtree&rsp-prop-include=config-only'
icurl -o /tmp/Extract-Full-uni-191023-V3.json -X GET 'http://localhost:7777/api/node/mo/uni.json?query-target=subtree'
none of these 3 forms gave me the real hierarchy of the objects
For info, I frequently extract, via icurl under APIC bash, all Tenants and uni/infa using the following commands and it works perfectly ;
1) collect All Tenants :
icurl -o /tmp/Extract-All-Tenants-181019-V1.json -X GET 'http://localhost:7777/api/class/fvTenant.json?rsp-subtree=full&rsp-prop-include=config-only'
2) collect uni/infra (mostly FAPs) :
icurl -o /tmp/Extract-All-FAPs-181019-V1.json -X GET 'http://localhost:7777/api/node/mo/uni/infra.json?rsp-subtree=full&rsp-prop-include=config-only'
I also get the same results via Python script by using the "requests" Python package : short extract below :
allTenants = session.get(APIC_URL + 'class/fvTenant.json?rsp-subtree=full&rsp-prop-include=config-only')
ALL_TENANTS_JSON_STR = allTenants.text
UniInfra = session.get(APIC_URL + 'node/mo/uni/infra.json?rsp-subtree=full&rsp-prop-include=config-only')
UNI_INFRA_JSON_STR = UniInfra.text
The only problem with getting the Tenant class and the uni/infra object as show just above, is that I miss some useful parts of the APIC MO config such as the Domains (Physical, L2ext,L3ext) and many other things
If I try to use the same option "rsp-subtree=full&rsp-prop-include=config-only" when GETting node/mo/uni.json, I got the following error in the result JSON or XML file : "code":"400","text":"Request failed, rsp-subtree option is not supported for class 'polUni'"
Any idea to fix this problem ?
I understand that I can get the JOSN or XML file I want via APIC GUI : ADMIN ==> Import/Export menus : the resulting tar.gz file contains the good XML/JSON file at the root directory, but I would like to get it via the Python script which also analyzes this config file;
thanks in advance