crosson / newfangled

0 stars 0 forks source link

ACI REST config #1

Open durd opened 6 years ago

durd commented 6 years ago

Hi, Was just wondering what happened to the ACI REST call that is mentioned in the readme? Or is ssh to the APIC preferred nowadays?

Project looks promising! A lot easier to just specify commands to be run over ssh than to write expect-scripts like in rancid.

Thanks!

crosson commented 6 years ago

@durd I yanked it out because I wasn't using it. And now I realize that since I uploaded this afterwords its not in the history. Let me go track down teh API call for you.

One thing to note. When I last talked with TAC they recommended using APIC to generate the config. and use an export policy to send it somewhere. I didn't like this but the concern was using a pull method, we might be missing some calls required to get a full config.

I was OK with this since I was just mostly interested in backing up access policies and tenant policies.

crosson commented 6 years ago

@durd

import cobra.mit.access
import cobra.mit.session
from cobra.internal.codec.jsoncodec import toJSONStr
from cobra.mit.request import DnQuery
from cobra.mit.request import ClassQuery

def get_full_aci_config(apic, user, password, outfile):
    try:
        url = "https://" + apic
        ls = cobra.mit.session.LoginSession(url, "apic:ACS\\" + user, password, secure=False, timeout=30) 
        md = cobra.mit.access.MoDirectory(ls)
        md.login()

        #Get tenant config
        cq = ClassQuery('fvTenant')
        cq.subtree = 'full'
        cq.propInclude= 'config-only'
        tenant_config = md.query(cq)

        #Infra config
        dq = DnQuery('uni/infra')
        dq.subtree = 'full'
        dq.propInclude = 'config-only'
        infra_config = md.query(dq)

        #Fabric config
        dq = DnQuery('uni/fabric')
        dq.subtree = 'full'
        dq.propInclude = 'config-only'
        fabric_config = md.query(dq)
        file = open(outfile, 'w+')
        file.write("# " + apic + " #")
        file.write("\n###########" + '\n')
        file.write("# TENANTS ")
        file.write("\n###########" + '\n')   
        for tenant in tenant_config:
            file.write(toJSONStr(tenant, prettyPrint=True))

        file.write("\n###########" + '\n')
        file.write("# Infra ")
        file.write("\n###########" + '\n')
        for infra in infra_config:
            file.write(toJSONStr(infra, prettyPrint=True))

        file.write("\n###########" + '\n')
        file.write("# Fabric ")
        file.write("\n###########" + '\n')
        for fabric in fabric_config:
            file.write(toJSONStr(fabric, prettyPrint=True))

        file.close()
    except:
        print "Error in get_full_aci_config() for %s: %s" % (apic, sys.exc_info()[0])

I just realized the other reason I removed this is because I was using Cobra. I found that using requests was easier. Their MO tree is already confusing enough as is. Adding more abstraction to the abstraction was driving me a bit nuts. I mean it is rest after all. How abstracted does it need to be cisco?

FYI, if you didn't already know: The apic:ACS\\username will allow you to authenticate with an external provider like TACACS or w/e.