def main(): """ Main execution routine :return: None """ creds = Credentials('apic') creds.add_argument('--tenant', help='The name of Tenant') creds.add_argument('--app', help='The name of ApplicationProfile') creds.add_argument('--bd', help='The name of BridgeDomain') creds.add_argument('--epg', help='The name of EPG') creds.add_argument('--json', const='false', nargs='?', help='Json output only') args = creds.get() session = Session(args.url, args.login, args.password) session.login() tenant = Tenant(args.tenant) app = AppProfile(args.app, tenant) bd = BridgeDomain(args.bd, tenant) epg = EPG(args.epg, app) epg.add_bd(bd) if args.json: print(tenant.get_json()) else: resp = session.push_to_apic(tenant.get_url(), tenant.get_json()) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text)
def send_to_apic(): """ Login to APIC and push the config :param tenant: Tenant class instance :return: request response object """ description = 'Basic Connectivity Example' creds = Credentials('apic', description) args = creds.get() # Login to APIC session = Session(args.url, args.login, args.password, False) session.login() tenants = aci.Tenant.get(session) user_tenant = "OneView-APIC-Tenant-1" user_appProfile = "OneView-APIC-AppProfile-1" for tenant in tenants: if str(tenant) == user_tenant.strip(): apps = aci.AppProfile.get(session, tenant) for app in apps: if str(app) == user_appProfile: epg1 = "EPG" for number in range(0, 10): epgg = epg1 + str(number) epg = EPG(epgg, app) domains = aci.VmmDomain.get(session) for domain in domains: if str(domain) == "OneView-APIC-vSwitch-Bay1": epg.attach(domain) resp = tenant.push_to_apic(session)
def main(): """ Main execution routine :return: None """ # Take login credentials from the command line if provided # Otherwise, take them from your environment variables file ~/.profile description = ( 'Simple application that logs on to the APIC and displays all' ' of the physical nodes; both belonging to and connected to the fabric.' ) creds = Credentials('apic', description) args = creds.get() # Login to APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') sys.exit(0) # List of classes to get and print phy_classes = (Node, ENode) for phy_class in phy_classes: # Print the class name class_name = phy_class.__name__ print(class_name) print('=' * len(class_name)) # Get and print all of the items from the APIC items = phy_class.get(session) for item in items: print(item.info())
def main(): """ Main execution routine :return: None """ # Take login credentials from the command line if provided # Otherwise, take them from your environment variables file ~/.profile description = ('Simple application that logs on to the APIC and displays all' ' of the physical nodes; both belonging to and connected to the fabric.') creds = Credentials('apic', description) args = creds.get() # Login to APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') sys.exit(0) # List of classes to get and print phy_classes = (Node, ExternalSwitch) for phy_class in phy_classes: # Print the class name class_name = phy_class.__name__ print(class_name) print('=' * len(class_name)) # Get and print all of the items from the APIC items = phy_class.get(session) for item in items: print(item.info())
def acilint(): """ Main execution routine :return: None """ description = ('acilint - A static configuration analysis tool. ' 'Checks can be individually disabled by generating' ' and editing a configuration file. If no config ' 'file is given, all checks will be run.') creds = Credentials('apic', description) # this should get the creds from environment # Login to APIC session = Session(os.environ['APIC_URL'], os.environ['APIC_LOGIN'], os.environ['APIC_PASSWORD']) resp = session.login() html = None checker = Checker(session, 'html', html) if not resp.ok: checker.output_handler('%% Could not login to APIC') sys.exit(1) else: msg = "Successfully able to authenticate to the APIC APIC with status code {}".format( resp.status_code) print json.dumps({ "result": "Passed", "pluginResponse": msg, "pluginHTMLResponse": "<h1>{}</h1>".format(msg) })
def main(): """ Main execution routine :return: None """ # Take login credentials from the command line if provided # Otherwise, take them from your environment variables description = ('Simple application that logs on to the APIC and displays' ' the physical inventory.') creds = Credentials('apic', description) args = creds.get() # Login to APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') sys.exit(0) # Print the inventory of each Pod pods = Pod.get(session) for pod in pods: pod.populate_children(deep=True) pod_name = 'Pod: %s' % pod.name print(pod_name) print('=' * len(pod_name)) print_inventory(pod)
def get_apic_session(self): description = 'Basic Connectivity Example' creds = Credentials('apic', description) args = creds.get() apic_session = Session(args.url, args.login, args.password, False) apic_session.login() return apic_session
def main(): """ Main execution routine :return: None """ # Take login credentials from the command line if provided # Otherwise, take them from your environment variables description = "Simple application that logs on to the APIC and displays" " the physical inventory." creds = Credentials("apic", description) args = creds.get() # Login to APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print("%% Could not login to APIC") sys.exit(0) # Print the inventory of each Pod pods = Pod.get(session) for pod in pods: pod.populate_children(deep=True) pod_name = "Pod: %s" % pod.name print(pod_name) print("=" * len(pod_name)) print_inventory(pod)
def login(self): url = self._policy.ip_address if str(self._policy.use_https).lower() == 'true': url = 'https://' + url else: url = 'http://' + url self._session = Session(url, self._policy.user_name, self._policy.password) resp = self._session.login() return resp
def get_interface_stats_from_nodes(): """ Main execution routine :return: None """ description = ('get_stats - A program to fetch statistics from an ACI ' 'Fabric.') creds = Credentials('apic', description) creds.add_argument('-f', '--format', required=False, default='text', help='Specify output format [csv, text]') creds.add_argument('-i', '--interval', required=False, default='15min', help='Specify the aggregation interval') creds.add_argument('-n', '--node_type', required=False, default='spine', help='Specify the type of node [spine, leaf, both]') creds.add_argument('-t', '--threshold', required=False, default=60, type=int, help='Specify the threshold for printing usage.') creds.add_argument('-v', '--verbose', action='count', help='Specify verbosity of debug output.') args = creds.get() if args.format not in ['text', 'csv']: print >> sys.stderr, "Error: Unknown output format: '{}'".format( args.format) sys.exit(3) if args.interval not in ['5min', '15min', '1h', '1d', '1w', '1mo', '1qtr', '1year']: print >> sys.stderr, "Error: Unknown interval '{}'".format( args.interval) sys.exit(4) if args.node_type in ['spine', 'leaf']: node_type = [args.node_type] elif args.node_type in ['both']: node_type = ['spine', 'leaf'] else: print >> sys.stderr, "Error: Unknown node type: '{}'".format( args.node_type) sys.exit(5) if args.threshold > 100: threshold = 100 elif args.threshold < 0: threshold = 0 else: threshold = args.threshold # Login to APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') sys.exit(0) statistics = Stats(session, args.format, args.verbose) statistics.get_int_traffic(node_type, args.interval, threshold)
def acilint(): """ Main execution routine :return: None """ description = ('acilint - A static configuration analysis tool. ' 'Checks can be individually disabled by generating' ' and editing a configuration file. If no config ' 'file is given, all checks will be run.') creds = Credentials('apic', description) # this should get the creds from environment # Login to APIC session = Session(os.environ['APIC_URL'], os.environ['APIC_LOGIN'], os.environ['APIC_PASSWORD']) resp = session.login() if not resp.ok: print('%% Could not login to APIC') sys.exit(1) html = open("tmp.html", "w") checker = Checker(session, 'html', html) methods = [] for method in dir(Checker): if method.startswith(('warning_', 'error_', 'critical_')): methods.append(method) if LIVE: html.write(""" <table border="2" style="width:100%"> <tr> <th>Severity</th> <th>Rule</th> <th>Description</th> </tr> """) checker.execute(methods) html.close() with open('tmp.html', 'r') as html: # resp = { "result": checker.result, "pluginHTMLResponse": html.read() } print json.dumps(resp) else: print json.dumps({"result": STATIC_RESULT})
def main(): creds = Credentials('apic') args = creds.get() session = Session(args.url, args.login, args.password) session.login() tenant = 'A_SCRIPT_MADE_ME' theTenant = Tenant(tenant) create_interface(theTenant, session, {'provide':'Outbound_Server', 'consume':'Web'}) print ("Created a Layer 3 External gateway in tenant {}.".format(theTenant)) print ("Everything seems to have worked if you are seeing this.")
def main(): """ Main execution routine """ creds = Credentials('apic') args = creds.get() session = Session(args.url, args.login, args.password) session.login() tenant = Tenant('ATX16_l3Out') context = Context('vrf', tenant) outside_l3 = OutsideL3('out-1', tenant) outside_l3.add_context(context) phyif = Interface('eth', '1', '104', '1', '41') phyif.speed = '1G' l2if = L2Interface('eth 1/104/1/41', 'vlan', '1330') l2if.attach(phyif) l3if = L3Interface('l3if') #l3if.set_l3if_type('l3-port') l3if.set_l3if_type('sub-interface') l3if.set_mtu('1500') l3if.set_addr('1.1.1.2/30') l3if.add_context(context) l3if.attach(l2if) rtr = OSPFRouter('rtr-1') rtr.set_router_id('23.23.23.23') rtr.set_node_id('101') ifpol = OSPFInterfacePolicy('myospf-pol', tenant) ifpol.set_nw_type('p2p') ospfif = OSPFInterface('ospfif-1', router=rtr, area_id='1') ospfif.set_area_type('nssa') ospfif.auth_key = 'password' ospfif.int_policy_name = ifpol.name ospfif.auth_keyid = '1' ospfif.auth_type = 'simple' tenant.attach(ospfif) ospfif.networks.append('55.5.5.0/24') ospfif.attach(l3if) contract1 = Contract('contract-1') outside_epg = OutsideEPG('outepg', outside_l3) outside_epg.provide(contract1) contract2 = Contract('contract-2') outside_epg.consume(contract2) outside_l3.attach(ospfif) print(tenant.get_json()) resp = session.push_to_apic(tenant.get_url(), tenant.get_json()) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text)
def main(): """ Main execution routine """ creds = Credentials('apic') args = creds.get() session = Session(args.url, args.login, args.password) session.login() tenant = Tenant('Cisco-Demo') context = Context('ctx1', tenant) outside_l3 = OutsideL3('out-1', tenant) outside_l3.add_context(context) phyif = Interface('eth', '1', '101', '1', '46') phyif.speed = '1G' l2if = L2Interface('eth 1/101/1/46', 'vlan', '1') l2if.attach(phyif) l3if = L3Interface('l3if') l3if.set_l3if_type('l3-port') l3if.set_mtu('1500') l3if.set_addr('1.1.1.2/30') l3if.add_context(context) l3if.attach(l2if) rtr = OSPFRouter('rtr-1') rtr.set_router_id('23.23.23.23') rtr.set_node_id('101') ifpol = OSPFInterfacePolicy('myospf-pol', tenant) ifpol.set_nw_type('p2p') ospfif = OSPFInterface('ospfif-1', router=rtr, area_id='1') ospfif.set_area_type('nssa') ospfif.auth_key = 'password' ospfif.int_policy_name = ifpol.name ospfif.auth_keyid = '1' ospfif.auth_type = 'simple' tenant.attach(ospfif) ospfif.networks.append('55.5.5.0/24') ospfif.attach(l3if) contract1 = Contract('contract-1') outside_epg = OutsideEPG('outepg', outside_l3) outside_epg.provide(contract1) contract2 = Contract('contract-2') outside_epg.consume(contract2) outside_l3.attach(ospfif) print(tenant.get_json()) resp = session.push_to_apic(tenant.get_url(), tenant.get_json()) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text)
def create_tenant(tenant_name): session = Session(config_data.get('url'), config_data.get('login'), config_data.get('password')) resp = session.login() if not resp.ok: print('%% Could not login to APIC') tenant = Tenant(tenant_name) # resp = tenant.push_to_apic(session) resp = session.push_to_acpi(tenant.get_url(), data=tenant.get_json()) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text)
def create_application_profile(tenant_name, ap_name): session = Session(config_data.get('url'), config_data.get('login'), config_data.get('password')) resp = session.login() if not resp.ok: print('%% Could not login to APIC') tenant = Tenant(tenant_name) ap = AppProfile(ap_name, tenant) resp = tenant.push_to_apic(session) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text)
def del_tenant(tenant_name): session = Session(config_data.get('url'), config_data.get('login'), config_data.get('password')) resp = session.login() if not resp.ok: print('%% Could not login to APIC') tenant = Tenant(tenant_name) tenant.mark_as_deleted() resp = tenant.push_to_apic(session) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text)
def main(login, password, url): """ Main execution routine :return: None """ # Take login credentials from the command line if provided # Otherwise, take them from your environment variables file ~/.profile #description = 'Simple application that logs on to the APIC and displays all of the Interfaces.' #creds = ACI.Credentials('apic', description) #args = creds.get() # Login to APIC #session = ACI.Session(args.url, args.login, args.password) session = Session(url, login, password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') sys.exit(0) # Download all of the interfaces # and store the data as tuples in a list data = [] interfaces = ACI.Interface.get(session) for interface in interfaces: data.append( (interface.attributes['if_name'], interface.attributes['porttype'], interface.attributes['adminstatus'], interface.attributes['operSt'], interface.attributes['speed'], interface.attributes['mtu'], interface.attributes['usage'])) # Display the data downloaded #print data template = "{0:17} {1:6} {2:^6} {3:^6} {4:7} {5:6} {6:9} " print( template.format("INTERFACE", "TYPE", "ADMIN", "OPER", "SPEED", "MTU", "USAGE")) print( template.format("---------", "----", "------", "------", "-----", "___", "---------")) count = 0 for rec in data: count += 1 if count > 23: os.system("read -p \"Press enter key\"") count = 0 print(template.format(*rec))
def main(): creds = Credentials('apic') args = creds.get() session = Session(args.url, args.login, args.password) session.login() tenant = 'A_SCRIPT_MADE_ME' theTenant = Tenant(tenant) create_interface(theTenant, session, { 'provide': 'Outbound_Server', 'consume': 'Web' }) print("Created a Layer 3 External gateway in tenant {}.".format(theTenant)) print("Everything seems to have worked if you are seeing this.")
def main(login,password,url): """ Main execution routine :return: None """ # Take login credentials from the command line if provided # Otherwise, take them from your environment variables file ~/.profile #description = 'Simple application that logs on to the APIC and displays all of the Interfaces.' #creds = ACI.Credentials('apic', description) #args = creds.get() # Login to APIC #session = ACI.Session(args.url, args.login, args.password) session = Session(url, login, password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') sys.exit(0) # Download all of the interfaces # and store the data as tuples in a list data = [] interfaces = ACI.Interface.get(session) for interface in interfaces: data.append((interface.attributes['if_name'], interface.attributes['porttype'], interface.attributes['adminstatus'], interface.attributes['operSt'], interface.attributes['speed'], interface.attributes['mtu'], interface.attributes['usage'])) # Display the data downloaded #print data template = "{0:17} {1:6} {2:^6} {3:^6} {4:7} {5:6} {6:9} " print(template.format("INTERFACE", "TYPE", "ADMIN", "OPER", "SPEED", "MTU", "USAGE")) print(template.format("---------", "----", "------", "------", "-----", "___", "---------")) count = 0 for rec in data: count += 1 if count > 23: os.system("read -p \"Press enter key\"") count = 0 print(template.format(*rec))
def del_epg(tenant_name, ap_name, epg_name, bd_name): session = Session(config_data.get('url'), config_data.get('login'), config_data.get('password')) resp = session.login() if not resp.ok: print('%% Could not login to APIC') tenant = Tenant(tenant_name) ap = AppProfile(ap_name, tenant) bd = BridgeDomain(bd_name, tenant) epg = EPG(epg_name, ap) epg.mark_as_deleted() resp = tenant.push_to_apic(session) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text)
def main(): with open(CONFFILE, 'r') as r: conf = json.loads(r.read()) #login to apic session = Session(conf['url'], conf['login'], conf['password']) resp = session.login() if not resp.ok: print('%% Could not login to APIC') return sys.exit(0) tenants = Tenant.get(session) for tenant in tenants: print(tenant.name)
def main(): """ Main execution routine :return: None """ creds = Credentials('apic') creds.add_argument('--tenant', help='The name of Tenant') creds.add_argument('--vrf', help='The name of VRF') creds.add_argument('--bd', help='The name of BridgeDomain') creds.add_argument('--address', help='Subnet IPv4 Address') creds.add_argument('--scope', help='The scope of subnet ("public", "private", "shared", "public,shared", "private,shared", "shared,public", "shared,private")') creds.add_argument('--json', const='false', nargs='?', help='Json output only') args = creds.get() session = Session(args.url, args.login, args.password) session.login() tenant = Tenant(args.tenant) vrf = Context(args.vrf) bd = BridgeDomain(args.bd, tenant) bd.add_context(vrf) if args.address is None: bd.set_arp_flood('yes') bd.set_unicast_route('no') else: bd.set_arp_flood('no') bd.set_unicast_route('yes') subnet = Subnet('', bd) subnet.addr = args.address if args.scope is None: subnet.set_scope("private") else: subnet.set_scope(args.scope) if args.json: print(tenant.get_json()) else: resp = session.push_to_apic(tenant.get_url(), tenant.get_json()) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text)
def connect_to_apic(self): logging.debug('Connecting to APIC...') # Connect to APIC apic_config = self.cdb.get_apic_config() url = apic_config.ip_address if apic_config.use_https: url = 'https://' + url else: url = 'http://' + url if self.apic is not None: logging.debug('APIC is previously connected') self.apic = Session(url, apic_config.user_name, apic_config.password) resp = self.apic.login() # TODO: need to clear out the databases first # Get all of the subnets query_url = '/api/mo/uni.json?query-target=subtree&target-subtree-class=l3extSubnet' subnets = self.apic.get(query_url) for subnet in subnets.json()['imdata']: subnet_event = SubnetEvent(subnet) self._subnets.store_subnet_event(subnet_event) # Get all of the inherited relations tag_query_url = '/api/class/tagInst.json?query-target-filter=wcard(tagInst.name,"inherited:")' tags = self.apic.get(tag_query_url) for tag in tags.json()['imdata']: tag_event = TagEvent(tag) # Create a database entry for the inherited relations self._inheritance_tags.store_tag(tag_event) # Get all of the relations. We need this to track relations that are already present # i.e. configured but not through inheritance so that we can tell the difference query_url = '/api/mo/uni.json?query-target=subtree&target-subtree-class=fvRsProv,fvRsCons,fvRsProtBy,fvRsConsIf' relations = self.apic.get(query_url) for relation in relations.json()['imdata']: self._relations.store_relation(RelationEvent(relation)) # Get all of the policies that are inherited from but not inheriting parent_only_policies = [] for policy in self.cdb.get_inheritance_policies(): inherited_from = False if policy.allowed and not policy.enabled: for child_policy in self.cdb.get_inheritance_policies(): if child_policy.has_inherit_from() and child_policy.inherit_from == policy.epg: inherited_from = True if inherited_from: parent_only_policies.append(policy) # Issue all of the subscriptions for policy in self.cdb.get_inheritance_policies(): self.subscribe(policy) for parent_only_policy in parent_only_policies: self.subscribe(parent_only_policy) tag_query_url += '&subscription=yes' self.apic.subscribe(tag_query_url) self._inheritance_tag_subscriptions.append(tag_query_url)
def send_to_apic(tenant): """ Login to APIC and push the config :param tenant: Tenant class instance :return: request response object """ description = 'Basic Connectivity Example' creds = Credentials('apic', description) args = creds.get() # Login to APIC session = Session(args.url, args.login, args.password, False) session.login() resp = tenant.push_to_apic(session) if resp.ok: print('Success') return resp
def acilint(): """ Main execution routine :return: None """ description = ('acilint - A static configuration analysis tool. ' 'Checks can be individually disabled by generating' ' and editing a configuration file. If no config ' 'file is given, all checks will be run.') creds = Credentials('apic', description) creds.add_argument('-c', '--configfile', type=argparse.FileType('r')) creds.add_argument('-g', '--generateconfigfile', type=argparse.FileType('w')) args = creds.get() if args.generateconfigfile: print 'Generating configuration file....' f = args.generateconfigfile f.write(('# acilint configuration file\n# Remove or comment out any ' 'warnings or errors that you no longer wish to see\n')) methods = dir(Checker) for method in methods: if method.startswith(('warning_', 'critical_', 'error_')): f.write(method + '\n') f.close() sys.exit(0) methods = [] if args.configfile: f = args.configfile for line in f: method = line.split('\n')[0] if method in dir(Checker) and method.startswith( ('warning_', 'error_', 'critical_')): methods.append(method) f.close() else: for method in dir(Checker): if method.startswith(('warning_', 'error_', 'critical_')): methods.append(method) if args.snapshotfiles: session = FakeSession(filenames=args.snapshotfiles) else: # Login to APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print '%% Could not login to APIC' sys.exit(0) checker = Checker(session) checker.execute(methods)
def main(): """ Main execution routine :return: None """ creds = Credentials('apic') args = creds.get() session = Session(args.url, args.login, args.password) session.login() tenant = Tenant('cisco') context = Context('ctx1', tenant) outside_l3 = OutsideL3('out-1', tenant) phyif = Interface('eth', '1', '101', '1', '46') phyif.speed = '1G' l2if = L2Interface('eth 1/101/1/46', 'vlan', '1') l2if.attach(phyif) l3if = L3Interface('l3if') l3if.set_l3if_type('l3-port') l3if.set_addr('1.1.1.2/30') l3if.add_context(context) l3if.attach(l2if) bgpif = BGPSession('test', peer_ip='1.1.1.1', node_id='101') bgpif.router_id = '172.1.1.1' bgpif.attach(l3if) bgpif.options = 'send-ext-com' bgpif.networks.append('0.0.0.0/0') contract1 = Contract('icmp') outside_epg = OutsideEPG('outepg', outside_l3) outside_epg.provide(contract1) outside_l3.add_context(context) outside_epg.consume(contract1) outside_l3.attach(bgpif) bgp_json = bgpif.get_json() resp = session.push_to_apic(tenant.get_url(), tenant.get_json()) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text)
def dettach_epg_provide_contract(tenant_name, ap_name, epg_name, provided_contract="", consumed_contract=""): session = Session(config_data.get('url'), config_data.get('login'), config_data.get('password')) resp = session.login() if not resp.ok: print('%% Could not login to APIC') tenant = Tenant(tenant_name) ap = AppProfile(ap_name, tenant) epg = EPG(epg_name, ap) if provided_contract: provided_contract = Contract(provided_contract, tenant) epg.dont_provide(provided_contract) if consumed_contract: consumed_contract = Contract(consumed_contract, tenant) epg.dont_consume(consumed_contract) resp = tenant.push_to_apic(session) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text)
def main(): with open(CONFFILE, 'r') as r: conf = json.loads(r.read()) #login to apic session = Session(conf['url'], conf['login'], conf['password']) resp = session.login() if not resp.ok: print('%% Could not login to APIC') return sys.exit(0) nodes = Node.get(session) for node in nodes: print('=' * 50) print('Pod: {}'.format(node.pod)) print('Node: {}'.format(node.node)) print('Mode: {}'.format(node.mode)) print('Model: {}'.format(node.model)) print('Vendor: {}'.format(node.vendor)) print('Serial: {}'.format(node.serial))
def EPG_deletion(): description = 'Basic Connectivity Example' creds = Credentials('apic', description) args = creds.get() # Login to APIC session = Session(args.url, args.login, args.password, False) session.login() tenants = aci.Tenant.get(session) for tenant in tenants: apps = aci.AppProfile.get(session, tenant) for app in apps: epgs = aci.EPG.get(session, app, tenant) for epg in epgs: if re.match("EPG\d+", str(epg)): epg.mark_as_deleted() resp = tenant.push_to_apic(session) if resp.ok: print "Deleted", str(epg) else: print 'Could not delete tenant', str(epg) print resp.text
class Apic(object): def __init__(self, apic_policy): self._policy = apic_policy self._session = None def login(self): url = self._policy.ip_address if str(self._policy.use_https).lower() == 'true': url = 'https://' + url else: url = 'http://' + url self._session = Session(url, self._policy.user_name, self._policy.password) resp = self._session.login() return resp def logged_in(self): return self._session.logged_in() def get_name(self): return self._policy.ip_address def get_session(self): return self._session
def main(login, password, url): """ Main execution routine :return: None """ # Take login credentials from the command line if provided # Otherwise, take them from your environment variables description = ('Simple application that logs on to the APIC and displays' ' the physical inventory.') #creds = Credentials('apic', description) #args1 = creds.get() #print type(args1) #print "args url ", args1.url #print "args user ", args1.login #print "args password", args1.password #url = 'http://172.31.216.24' #login = '******' #password = '******' # Login to APIC session = Session(url, login, password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') sys.exit(0) # Print the inventory of each Pod pods = Pod.get(session) for pod in pods: pod.populate_children(deep=True) pod_name = 'Pod: %s' % pod.name print(pod_name) print('=' * len(pod_name)) print_inventory(pod)
def main(login,password,url): """ Main execution routine :return: None """ # Take login credentials from the command line if provided # Otherwise, take them from your environment variables description = ('Simple application that logs on to the APIC and displays' ' the physical inventory.') #creds = Credentials('apic', description) #args1 = creds.get() #print type(args1) #print "args url ", args1.url #print "args user ", args1.login #print "args password", args1.password #url = 'http://172.31.216.24' #login = '******' #password = '******' # Login to APIC session = Session(url, login, password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') sys.exit(0) # Print the inventory of each Pod pods = Pod.get(session) for pod in pods: pod.populate_children(deep=True) pod_name = 'Pod: %s' % pod.name print(pod_name) print('=' * len(pod_name)) print_inventory(pod)
@author: AlexFeng ''' from acitoolkit.acitoolkit import Session,Tenant from acitoolkit.aciphysobject import Node,Link,Powersupply from acitoolkit.acibaseobject import BaseACIObject from credentials.credentials import * # Take login credentials from the command line if provided # Otherwise, take them from your environment variables file ~/.profile # Login to APIC session = Session(URL, LOGIN, PASSWORD) session.login() # List of classes to get and print phy_class = (Node) Phy_links=(Link) Phy_pwrs=(Powersupply) # Get and print all of the items from the APIC items = phy_class.get(session) for item in items: print item.info() links=Phy_links.get(session)
assert tenant_left is not None and middle_left is not None and type_left is not None assert tenant_right is not None and middle_right is not None and type_right is not None assert len(tenant_left) > 0 and len(middle_left) > 0 and len(type_left) > 0 assert len(tenant_right) > 0 and len(middle_right) > 0 and len(type_right) > 0 items["left"]["Tenant"] = tenant_left items["right"]["Tenant"] = tenant_right items["left"][args.type] = type_left items["right"][args.type] = type_right if args.type == "EPG": items["left"]["AppProfile"] = middle_left items["right"]["AppProfile"] = middle_right except: fatal("[E] Incorrect object format for the %s type." % args.type) # Now, we log into the APIC session = Session(args.url, args.login, args.password) response = session.login() if response.ok is False: print(response.content) sys.exit(1) # Retrieve Tenant data and split it into smaller components. Note that we # will keep reusing the "left" and "right" variables all the time until # we get to the object we need try: left = Tenant.get_deep(session, [items["left"]["Tenant"]])[0] left = split_tenant(left) right = Tenant.get_deep(session, [items["right"]["Tenant"]])[0] right = split_tenant(right) except: print("[E] Error, couldn't retrieve data from fabric")
import sys from acitoolkit.acitoolkit import Session from acitoolkit.aciphysobject import Node, ENode from acisampleslib import get_login_info from acitoolkit.acitoolkit import * from credentials import * import credentials # Take login credentials from the command line if provided # Otherwise, take them from your environment variables file ~/.profile description = 'Simple application that logs on to the APIC and displays all of the physical nodes; both belonging to and connected to the fabric.' parser = get_login_info(description) args = parser.parse_args() # Login to APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print '%% Could not login to APIC' sys.exit(0) # List of classes to get and print phy_classes = (Node, ENode) for phy_class in phy_classes: # Print the class name class_name = phy_class.__name__ print class_name print '=' * len(class_name) # Get and print all of the items from the APIC
""" from acitoolkit.acitoolkit import Session from acitoolkit import Faults from credentials import URL, LOGIN, PASSWORD import requests, json requests.packages.urllib3.disable_warnings() # Disable warning message fault_count = {"total": 0, "critical": 0} # MISSION: Provide the proper ACI Toolkit code to create a Session # object and use it to login to the APIC. # NOTE: Variables URL, LOGIN, and PASSWORD were imported from # the credentials file. session = Session(URL, LOGIN, PASSWORD) resp = session.login() if not resp.ok: print('%% Could not login to APIC') sys.exit(1) # MISSION: Create an instance of the toolkit class representing ACI Faults # Hint: the class is called "Faults" and takes no parameters faults_obj = Faults() # Monitor the Faults on the APIC faults_obj.subscribe_faults(session) while faults_obj.has_faults(session): if faults_obj.has_faults(session): faults = faults_obj.get_faults(session)
class Monitor(threading.Thread): """ Thread responsible for monitoring EPG-to-Contract relations. """ def __init__(self, cdb): threading.Thread.__init__(self) self.cdb = cdb self._monitor_frequency = 1 self._exit = False self._relation_subscriptions = [] self._inheritance_tag_subscriptions = [] self._subnet_subscriptions = [] self._relations = RelationDB() self._inheritance_tags = TagDB() self._subnets = SubnetDB() self._old_relations = {} self.apic = None def exit(self): """ Indicate that the thread should exit. """ self._exit = True def subscribe(self, policy): query_url = "" epg = policy.epg epg_data = (epg.tenant, epg.epg_container_name, epg.name) if epg.epg_container_type == "app": query_url = "/api/mo/uni/tn-%s/ap-%s/epg-%s.json" % epg_data elif epg.epg_container_type == "l3out": subnet_query_url = "/api/mo/uni/tn-%s/out-%s/instP-%s.json" % epg_data subnet_query_url += "?query-target=subtree&target-subtree-class=l3extSubnet" subnet_query_url += "&subscription=yes" if subnet_query_url not in self._subnet_subscriptions: self.apic.subscribe(subnet_query_url) self._subnet_subscriptions.append(subnet_query_url) query_url = "/api/mo/uni/tn-%s/out-%s/instP-%s.json" % epg_data elif epg.epg_container_type == "l2out": query_url = "/api/mo/uni/tn-%s/l2out-%s/instP-%s.json" % epg_data query_url += "?query-target=subtree&target-subtree-class=fvRsProv,fvRsCons,fvRsProtBy,fvRsConsIf" query_url += "&subscription=yes" if query_url not in self._relation_subscriptions: self.apic.subscribe(query_url) self._relation_subscriptions.append(query_url) def connect_to_apic(self): logging.debug("Connecting to APIC...") # Connect to APIC apic_config = self.cdb.get_apic_config() url = apic_config.ip_address if apic_config.use_https: url = "https://" + url else: url = "http://" + url if self.apic is not None: logging.debug("APIC is previously connected") self.apic = Session(url, apic_config.user_name, apic_config.password) resp = self.apic.login() # TODO: need to clear out the databases first assert len(self._inheritance_tags.db) == 0 # Get all of the subnets query_url = "/api/mo/uni.json?query-target=subtree&target-subtree-class=l3extSubnet" subnets = self.apic.get(query_url) for subnet in subnets.json()["imdata"]: subnet_event = SubnetEvent(subnet) self._subnets.store_subnet_event(subnet_event) # Get all of the inherited relations tag_query_url = '/api/class/tagInst.json?query-target-filter=wcard(tagInst.name,"inherited:")' tags = self.apic.get(tag_query_url) for tag in tags.json()["imdata"]: tag_event = TagEvent(tag) # Create a database entry for the inherited relations self._inheritance_tags.store_tag(tag_event) self._old_relations = self._inheritance_tags.get_relations() # Get all of the relations. We need this to track relations that are already present # i.e. configured but not through inheritance so that we can tell the difference query_url = "/api/mo/uni.json?query-target=subtree&target-subtree-class=fvRsProv,fvRsCons,fvRsProtBy,fvRsConsIf" relations = self.apic.get(query_url) for relation in relations.json()["imdata"]: # Skip any in-band and out-of-band interfaces if "/mgmtp-" in relation[relation.keys()[0]]["attributes"]["dn"]: continue self._relations.store_relation(RelationEvent(relation)) # Get all of the policies that are inherited from but not inheriting parent_only_policies = [] for policy in self.cdb.get_inheritance_policies(): inherited_from = False if policy.allowed and not policy.enabled: for child_policy in self.cdb.get_inheritance_policies(): if child_policy.has_inherit_from() and child_policy.inherit_from == policy.epg: inherited_from = True if inherited_from: parent_only_policies.append(policy) # Issue all of the subscriptions for policy in self.cdb.get_inheritance_policies(): self.subscribe(policy) for parent_only_policy in parent_only_policies: self.subscribe(parent_only_policy) tag_query_url += "&subscription=yes" self.apic.subscribe(tag_query_url) self._inheritance_tag_subscriptions.append(tag_query_url) def _does_tenant_have_contract(self, tenant_name, contract_name, contract_type="brc"): logging.debug("tenant: %s contract: %s contract_type: %s", tenant_name, contract_name, contract_type) query_url = "/api/mo/uni/tn-%s/%s-%s.json" % (tenant_name, contract_type, contract_name) resp = self.apic.get(query_url) return resp.ok and int(resp.json()["totalCount"]) > 0 def does_tenant_have_contract_if(self, tenant_name, contract_if_name): return self._does_tenant_have_contract(tenant_name, contract_if_name, contract_type="cif") def does_tenant_have_contract(self, tenant_name, contract_name): return self._does_tenant_have_contract(tenant_name, contract_name) def _add_inherited_relation(self, tenants, epg, relation, deleted=False): tenant_found = False # Find the tenant. Add if necessary for tenant in tenants: if tenant.name == epg.tenant: tenant_found = True break if not tenant_found: tenant = Tenant(epg.tenant) tenants.append(tenant) # Find the EPG Container. Add if necessary if epg.is_l3out(): epg_container_class = OutsideL3 else: epg_container_class = AppProfile epg_containers = tenant.get_children(only_class=epg_container_class) epg_container_found = False for epg_container in epg_containers: if epg_container.name == epg.epg_container_name: epg_container_found = True break if not epg_container_found: epg_container = epg_container_class(epg.epg_container_name, tenant) # Find the EPG. Add if necessary if epg.is_l3out(): epg_class = OutsideEPG else: epg_class = EPG epgs = tenant.get_children(only_class=epg_class) epg_found = False for tenant_epg in epgs: if tenant_epg.name == epg.name: epg_found = True break if not epg_found: tenant_epg = epg_class(epg.name, epg_container) # Add the relation (relation_type, relation_name) = relation if relation_type == "fvRsProv": contract = Contract(relation_name, tenant) tenant_epg.provide(contract) if deleted: tenant_epg.provide(contract) tenant_epg.dont_provide(contract) elif relation_type == "fvRsCons": contract = Contract(relation_name, tenant) tenant_epg.consume(contract) if deleted: tenant_epg.consume(contract) tenant_epg.dont_consume(contract) elif relation_type == "fvRsConsIf": contract_interface = ContractInterface(relation_name, tenant) tenant_epg.consume_cif(contract_interface) if deleted: tenant_epg.consume_cif(contract_interface) tenant_epg.dont_consume_cif(contract_interface) elif relation_type == "fvRsProtBy": taboo = Taboo(relation_name, tenant) tenant_epg.protect(taboo) if deleted: tenant_epg.protect(taboo) tenant_epg.dont_protect(taboo) tenant_epg.add_tag("inherited:%s:%s" % (relation_type, relation_name)) if deleted: tenant_epg.delete_tag("inherited:%s:%s" % (relation_type, relation_name)) return tenants def add_inherited_relation(self, tenants, epg, relation): return self._add_inherited_relation(tenants, epg, relation) def remove_inherited_relation(self, tenants, epg, relation): return self._add_inherited_relation(tenants, epg, relation, deleted=True) def _calculate_relations_for_l3out_policy(self, inheritance_policy): logging.debug("_calculate_relations_for_l3out_policy: %s", inheritance_policy) # Get all of the EPGs covering this policy's EPG's subnets covering_epgs = self._subnets.get_all_covering_epgs(inheritance_policy.epg) # Remove any EPGs that are not allowed to be inherited for covering_epg in covering_epgs: if not self.cdb.is_inheritance_allowed(covering_epg): covering_epgs.remove(covering_epg) # Get all of the relations for the remaining covering EPGs relations = [] for covering_epg in covering_epgs: epg_relations = self._relations.get_relations_for_epg(covering_epg) for epg_relation in epg_relations: if epg_relation not in relations: relations.append(epg_relation) logging.debug("Relations to be inherited: %s", relations) # Need to add any configured relations configured_relations = self._relations.get_relations_for_epg(inheritance_policy.epg) for configured_relation in configured_relations: if configured_relation not in relations: logging.debug("Adding configured relation: %s", configured_relation) if not self._inheritance_tags.is_inherited(inheritance_policy.epg, configured_relation): relations.append(configured_relation) return relations def _calculate_relations_for_app_policy(self, inheritance_policy): logging.debug("policy: %s", inheritance_policy) relations = [] # Check if this policy is even inheritance enabled if not inheritance_policy.has_inherit_from(): logging.warning("EPG is not inheriting from a parent EPG") return relations # Get the EPG that this policy is inheriting from parent_epg = inheritance_policy.inherit_from # Is inheritance allowed on that EPG ? if not self.cdb.is_inheritance_allowed(parent_epg): logging.warning("Parent EPG policy does not allow inheritance") return relations # Get the relations belonging to that EPG return self._relations.get_relations_for_epg(parent_epg) def calculate_relations(self): relations = {} for inheritance_policy in self.cdb.get_inheritance_policies(): if not inheritance_policy.enabled: continue if inheritance_policy.epg.is_l3out(): epg_relations = self._calculate_relations_for_l3out_policy(inheritance_policy) else: # TODO: may eventually need to process l2out epg_relations = self._calculate_relations_for_app_policy(inheritance_policy) relations[inheritance_policy.epg.get_json()] = epg_relations return relations def process_relation_event(self, event): logging.debug("process_event EVENT: %s", event.event) self._relations.store_relation(event) def process_subnet_event(self, event): logging.debug("Received subnet event: %s", event) # Store the subnet in the SubnetDB self._subnets.store_subnet_event(event) def process_inheritance_tag_event(self, event): logging.debug("Received subnet event: %s", event) # Store the tag in the TagDB self._inheritance_tags.store_tag(event) def _process_events(self, old_relations): while self.apic is None: pass if old_relations is None: old_relations = self._inheritance_tags.get_relations() # Check for any tag events for subscription in self._inheritance_tag_subscriptions: while self.apic.has_events(subscription): event = TagEvent(self.apic.get_event(subscription)["imdata"][0]) self.process_inheritance_tag_event(event) # Check for relation events for subscription in self._relation_subscriptions: while self.apic.has_events(subscription): event = RelationEvent(self.apic.get_event(subscription)["imdata"][0]) self.process_relation_event(event) # Check for subnet events for subscription in self._subnet_subscriptions: while self.apic.has_events(subscription): event = SubnetEvent(self.apic.get_event(subscription)["imdata"][0]) self.process_subnet_event(event) # Calculate the new set of relations new_relations = self.calculate_relations() for old_epg in old_relations: logging.debug(old_epg) for new_epg in new_relations: logging.debug(new_epg) # Compare the old and the new relations for changes tenants = [] for new_epg in new_relations: if new_epg not in old_relations: # New EPG, so we need to add all of the relations for new_relation in new_relations[new_epg]: if self._inheritance_tags.is_inherited(EPGPolicy(json.loads(new_epg)), new_relation): # If it's inherited, but we don't have the relation. We are likely coming up and not populated # the old_relations yet pass # If just configured, we will have a relationDB entry. Otherwise, we need to inherit it if self._relations.has_relation_for_epg(EPGPolicy(json.loads(new_epg)), new_relation): continue tenants = self.add_inherited_relation(tenants, EPGPolicy(json.loads(new_epg)), new_relation) else: # Handle any new added relations for new_relation in new_relations[new_epg]: if new_relation not in old_relations[new_epg]: if self._relations.has_relation_for_epg(EPGPolicy(json.loads(new_epg)), new_relation): continue tenants = self.add_inherited_relation(tenants, EPGPolicy(json.loads(new_epg)), new_relation) # Handle any deleted relations for old_relation in old_relations[new_epg]: if old_relation not in new_relations[new_epg]: if self._inheritance_tags.is_inherited(EPGPolicy(json.loads(new_epg)), old_relation): tenants = self.remove_inherited_relation( tenants, EPGPolicy(json.loads(new_epg)), old_relation ) else: # Must have been configured and manually deleted pass for old_epg in old_relations: if old_epg not in new_relations: for old_relation in old_relations[old_epg]: if self._inheritance_tags.is_inherited(EPGPolicy(json.loads(old_epg)), old_relation): tenants = self.remove_inherited_relation(tenants, EPGPolicy(json.loads(old_epg)), old_relation) # Push the necessary config to the APIC for tenant in tenants: tenant_json = tenant.get_json() # Check that the tenant actually has the contracts since they may actually be tenant common contracts. # If tenant common is used, we need to clean up the tenant JSON to not create an empty contract within # this tenant for child in tenant_json["fvTenant"]["children"]: if "vzBrCP" in child: if not self.does_tenant_have_contract(tenant.name, child["vzBrCP"]["attributes"]["name"]): tenant_json["fvTenant"]["children"].remove(child) elif "vzCPIf" in child: if not self.does_tenant_have_contract_if(tenant.name, child["vzCPIf"]["attributes"]["name"]): tenant_json["fvTenant"]["children"].remove(child) logging.debug("Pushing tenant configuration to the APIC: %s", tenant_json) resp = self.apic.push_to_apic(tenant.get_url(), tenant_json) if resp.ok: logging.debug("Pushed to APIC successfully") else: logging.error("Error pushing to APIC", resp.text) return new_relations def run(self): loop_count = 0 accelerated_cleanup_done = False while not self._exit: time.sleep(self._monitor_frequency) self._old_relations = self._process_events(self._old_relations)
from flask import Flask, render_template import os from acitoolkit.acitoolkit import Session, Tenant from acitoolkit.aciHealthScore import HealthScore import json # initialize ACI toolkit session APIC_URL = os.getenv("APIC_URL") APIC_LOGIN = os.getenv("APIC_LOGIN") APIC_PASSWORD = os.getenv("APIC_PASSWORD") SESSION = Session(APIC_URL, APIC_LOGIN, APIC_PASSWORD) SESSION.login() # Eliminate Trailing slash if APIC_URL.endswith('/'): APIC_URL = APIC_URL[:-1] app = Flask(__name__) def get_tenants(): """ return a list of ACIToolkit tenant objects """ # your code goes here pass def get_tenant_healthscore(obj): """ Returns a healthscore for a particular tenants
def get_interface_stats_from_nodes(): """ Main execution routine :return: None """ description = ('get_stats - A program to fetch statistics from an ACI ' 'Fabric.') creds = Credentials('apic', description) creds.add_argument('-f', '--format', required=False, default='text', help='Specify output format [csv, text]') creds.add_argument('-i', '--interval', required=False, default='15min', help='Specify the aggregation interval') creds.add_argument('-n', '--node_type', required=False, default='spine', help='Specify the type of node [spine, leaf, both]') creds.add_argument('-t', '--threshold', required=False, default=60, type=int, help='Specify the threshold for printing usage.') creds.add_argument('-v', '--verbose', action='count', help='Specify verbosity of debug output.') args = creds.get() if args.format not in ['text', 'csv']: print >> sys.stderr, "Error: Unknown output format: '{}'".format( args.format) sys.exit(3) if args.interval not in [ '5min', '15min', '1h', '1d', '1w', '1mo', '1qtr', '1year' ]: print >> sys.stderr, "Error: Unknown interval '{}'".format( args.interval) sys.exit(4) if args.node_type in ['spine', 'leaf']: node_type = [args.node_type] elif args.node_type in ['both']: node_type = ['spine', 'leaf'] else: print >> sys.stderr, "Error: Unknown node type: '{}'".format( args.node_type) sys.exit(5) if args.threshold > 100: threshold = 100 elif args.threshold < 0: threshold = 0 else: threshold = args.threshold # Login to APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print '%% Could not login to APIC' sys.exit(0) statistics = Stats(session, args.format, args.verbose) statistics.get_int_traffic(node_type, args.interval, threshold)
def acilint(): """ Main execution routine :return: None """ description = ('acilint - A static configuration analysis tool. ' 'Checks can be individually disabled by generating' ' and editing a configuration file. If no config ' 'file is given, all checks will be run.') creds = Credentials('apic', description) creds.add_argument('-c', '--configfile', type=argparse.FileType('r')) creds.add_argument('-g', '--generateconfigfile', type=argparse.FileType('w')) creds.add_argument('-o', '--output', required=False, default='console') args = creds.get() if args.generateconfigfile: print('Generating configuration file....') f = args.generateconfigfile f.write(('# acilint configuration file\n# Remove or comment out any ' 'warnings or errors that you no longer wish to see\n')) methods = dir(Checker) for method in methods: if method.startswith(('warning_', 'critical_', 'error_')): f.write(method + '\n') f.close() sys.exit(0) methods = [] if args.configfile: f = args.configfile for line in f: method = line.split('\n')[0] if method in dir(Checker) and method.startswith(('warning_', 'error_', 'critical_')): methods.append(method) f.close() else: for method in dir(Checker): if method.startswith(('warning_', 'error_', 'critical_')): methods.append(method) if args.snapshotfiles: session = FakeSession(filenames=args.snapshotfiles) else: # Login to APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') sys.exit(0) html = None if args.output == 'html': print('Creating file lint.html') html = open('lint.html', 'w') html.write(""" <table border="2" style="width:100%"> <tr> <th>Severity</th> <th>Rule</th> <th>Description</th> </tr> """) checker = Checker(session, args.output, html) checker.execute(methods)
class Monitor(threading.Thread): """ Thread responsible for monitoring EPG-to-Contract relations. """ def __init__(self, cdb): threading.Thread.__init__(self) self.cdb = cdb self._monitor_frequency = 1 self._exit = False self._relation_subscriptions = [] self._inheritance_tag_subscriptions = [] self._subnet_subscriptions = [] self._relations = RelationDB() self._inheritance_tags = TagDB() self._subnets = SubnetDB() self.apic = None def exit(self): """ Indicate that the thread should exit. """ self._exit = True def subscribe(self, policy): query_url = '' epg = policy.epg epg_data = (epg.tenant, epg.epg_container_name, epg.name) if epg.epg_container_type == 'app': query_url = '/api/mo/uni/tn-%s/ap-%s/epg-%s.json' % epg_data elif epg.epg_container_type == 'l3out': subnet_query_url = '/api/mo/uni/tn-%s/out-%s/instP-%s.json' % epg_data subnet_query_url += '?query-target=subtree&target-subtree-class=l3extSubnet' subnet_query_url += '&subscription=yes' if subnet_query_url not in self._subnet_subscriptions: self.apic.subscribe(subnet_query_url) self._subnet_subscriptions.append(subnet_query_url) query_url = '/api/mo/uni/tn-%s/out-%s/instP-%s.json' % epg_data elif epg.epg_container_type == 'l2out': query_url = '/api/mo/uni/tn-%s/l2out-%s/instP-%s.json' % epg_data query_url += '?query-target=subtree&target-subtree-class=fvRsProv,fvRsCons,fvRsProtBy,fvRsConsIf' query_url += '&subscription=yes' if query_url not in self._relation_subscriptions: self.apic.subscribe(query_url) self._relation_subscriptions.append(query_url) def connect_to_apic(self): logging.debug('Connecting to APIC...') # Connect to APIC apic_config = self.cdb.get_apic_config() url = apic_config.ip_address if apic_config.use_https: url = 'https://' + url else: url = 'http://' + url if self.apic is not None: logging.debug('APIC is previously connected') self.apic = Session(url, apic_config.user_name, apic_config.password) resp = self.apic.login() # TODO: need to clear out the databases first # Get all of the subnets query_url = '/api/mo/uni.json?query-target=subtree&target-subtree-class=l3extSubnet' subnets = self.apic.get(query_url) for subnet in subnets.json()['imdata']: subnet_event = SubnetEvent(subnet) self._subnets.store_subnet_event(subnet_event) # Get all of the inherited relations tag_query_url = '/api/class/tagInst.json?query-target-filter=wcard(tagInst.name,"inherited:")' tags = self.apic.get(tag_query_url) for tag in tags.json()['imdata']: tag_event = TagEvent(tag) # Create a database entry for the inherited relations self._inheritance_tags.store_tag(tag_event) # Get all of the relations. We need this to track relations that are already present # i.e. configured but not through inheritance so that we can tell the difference query_url = '/api/mo/uni.json?query-target=subtree&target-subtree-class=fvRsProv,fvRsCons,fvRsProtBy,fvRsConsIf' relations = self.apic.get(query_url) for relation in relations.json()['imdata']: self._relations.store_relation(RelationEvent(relation)) # Get all of the policies that are inherited from but not inheriting parent_only_policies = [] for policy in self.cdb.get_inheritance_policies(): inherited_from = False if policy.allowed and not policy.enabled: for child_policy in self.cdb.get_inheritance_policies(): if child_policy.has_inherit_from() and child_policy.inherit_from == policy.epg: inherited_from = True if inherited_from: parent_only_policies.append(policy) # Issue all of the subscriptions for policy in self.cdb.get_inheritance_policies(): self.subscribe(policy) for parent_only_policy in parent_only_policies: self.subscribe(parent_only_policy) tag_query_url += '&subscription=yes' self.apic.subscribe(tag_query_url) self._inheritance_tag_subscriptions.append(tag_query_url) def _add_inherited_relation(self, tenants, epg, relation, deleted=False): tenant_found = False # Find the tenant. Add if necessary for tenant in tenants: if tenant.name == epg.tenant: tenant_found = True break if not tenant_found: tenant = Tenant(epg.tenant) tenants.append(tenant) # Find the EPG Container. Add if necessary if epg.is_l3out: epg_container_class = OutsideL3 else: epg_container_class = AppProfile epg_containers = tenant.get_children(only_class=epg_container_class) epg_container_found = False for epg_container in epg_containers: if epg_container.name == epg.epg_container_name: epg_container_found = True break if not epg_container_found: epg_container = epg_container_class(epg.epg_container_name, tenant) # Find the EPG. Add if necessary if epg.is_l3out: epg_class = OutsideEPG else: epg_class = EPG epgs = tenant.get_children(only_class=epg_class) epg_found = False for tenant_epg in epgs: if tenant_epg.name == epg.name: epg_found = True break if not epg_found: tenant_epg = epg_class(epg.name, epg_container) # Add the relation (relation_type, relation_name) = relation if relation_type == 'fvRsProv': contract = Contract(relation_name, tenant) tenant_epg.provide(contract) if deleted: tenant_epg.provide(contract) tenant_epg.dont_provide(contract) elif relation_type == 'fvRsCons': contract = Contract(relation_name, tenant) tenant_epg.consume(contract) if deleted: tenant_epg.consume(contract) tenant_epg.dont_consume(contract) elif relation_type == 'fvRsConsIf': contract_interface = ContractInterface(relation_name, tenant) tenant_epg.consume_cif(contract_interface) if deleted: tenant_epg.consume_cif(contract_interface) tenant_epg.dont_consume_cif(contract_interface) elif relation_type == 'fvRsProtBy': taboo = Taboo(relation_name, tenant) tenant_epg.protect(taboo) if deleted: tenant_epg.protect(taboo) tenant_epg.dont_protect(taboo) tenant_epg.add_tag('inherited:%s:%s' % (relation_type, relation_name)) if deleted: tenant_epg.delete_tag('inherited:%s:%s' % (relation_type, relation_name)) return tenants def add_inherited_relation(self, tenants, epg, relation): return self._add_inherited_relation(tenants, epg, relation) def remove_inherited_relation(self, tenants, epg, relation): return self._add_inherited_relation(tenants, epg, relation, deleted=True) def _calculate_relations_for_l3out_policy(self, inheritance_policy): logging.debug('_calculate_relations_for_l3out_policy: %s', inheritance_policy) # Get all of the EPGs covering this policy's EPG's subnets covering_epgs = self._subnets.get_all_covering_epgs(inheritance_policy.epg) # Remove any EPGs that are not allowed to be inherited for covering_epg in covering_epgs: if not self.cdb.is_inheritance_allowed(covering_epg): covering_epgs.remove(covering_epg) # Get all of the relations for the remaining covering EPGs relations = [] for covering_epg in covering_epgs: epg_relations = self._relations.get_relations_for_epg(covering_epg) for epg_relation in epg_relations: if epg_relation not in relations: relations.append(epg_relation) logging.debug('Relations to be inherited: %s', relations) # Need to add any configured relations configured_relations = self._relations.get_relations_for_epg(inheritance_policy.epg) for configured_relation in configured_relations: if configured_relation not in relations: logging.debug('Adding configured relation: %s', configured_relation) if not self._inheritance_tags.is_inherited(inheritance_policy.epg, configured_relation): relations.append(configured_relation) return relations def _calculate_relations_for_app_policy(self, inheritance_policy): pass def calculate_relations(self): relations = {} for inheritance_policy in self.cdb.get_inheritance_policies(): if not inheritance_policy.enabled: continue if inheritance_policy.epg.is_l3out(): epg_relations = self._calculate_relations_for_l3out_policy(inheritance_policy) else: # TODO: may eventually need to process l2out self._calculate_relations_for_app_policy(inheritance_policy) relations[inheritance_policy.epg.get_json()] = epg_relations return relations def process_relation_event(self, event): logging.debug('process_event EVENT: %s', event.event) self._relations.store_relation(event) def process_subnet_event(self, event): logging.debug('Received subnet event: %s', event) # Store the subnet in the SubnetDB self._subnets.store_subnet_event(event) def process_inheritance_tag_event(self, event): logging.debug('Received subnet event: %s', event) # Store the tag in the TagDB self._inheritance_tags.store_tag(event) def _process_events(self, old_relations): while self.apic is None: pass # Check for any tag events for subscription in self._inheritance_tag_subscriptions: while self.apic.has_events(subscription): event = TagEvent(self.apic.get_event(subscription)['imdata'][0]) self.process_inheritance_tag_event(event) # Check for relation events for subscription in self._relation_subscriptions: while self.apic.has_events(subscription): event = RelationEvent(self.apic.get_event(subscription)['imdata'][0]) self.process_relation_event(event) # Check for subnet events for subscription in self._subnet_subscriptions: while self.apic.has_events(subscription): event = SubnetEvent(self.apic.get_event(subscription)['imdata'][0]) self.process_subnet_event(event) # Calculate the new set of relations new_relations = self.calculate_relations() logging.debug('OLD_RELATIONS: %s %s', len(old_relations), old_relations) for old_epg in old_relations: logging.debug(old_epg) logging.debug('NEW_RELATIONS: %s %s', len(new_relations), new_relations) for new_epg in new_relations: logging.debug(new_epg) # Compare the old and the new relations for changes tenants = [] for new_epg in new_relations: if new_epg not in old_relations: # New EPG, so we need to add all of the relations for new_relation in new_relations[new_epg]: if self._inheritance_tags.is_inherited(EPGPolicy(json.loads(new_epg)), new_relation): # If it's inherited, but we don't have the relation. We are likely coming up and not populated # the old_relations yet #continue pass # If just configured, we will have a relationDB entry. Otherwise, we need to inherit it if self._relations.has_relation_for_epg(EPGPolicy(json.loads(new_epg)), new_relation): continue tenants = self.add_inherited_relation(tenants, EPGPolicy(json.loads(new_epg)), new_relation) else: # Handle any new added relations for new_relation in new_relations[new_epg]: if new_relation not in old_relations[new_epg]: if self._relations.has_relation_for_epg(EPGPolicy(json.loads(new_epg)), new_relation): continue tenants = self.add_inherited_relation(tenants, EPGPolicy(json.loads(new_epg)), new_relation) # Handle any deleted relations for old_relation in old_relations[new_epg]: if old_relation not in new_relations[new_epg]: if self._inheritance_tags.is_inherited(EPGPolicy(json.loads(new_epg)), old_relation): tenants = self.remove_inherited_relation(tenants, EPGPolicy(json.loads(new_epg)), old_relation) else: # Must have been configured and manually deleted pass for old_epg in old_relations: if old_epg not in new_relations: for old_relation in old_relations[old_epg]: if self._inheritance_tags.is_inherited(EPGPolicy(json.loads(old_epg)), old_relation): tenants = self.remove_inherited_relation(tenants, EPGPolicy(json.loads(old_epg)), old_relation) # Push the necessary config to the APIC for tenant in tenants: resp = tenant.push_to_apic(self.apic) if resp.ok: logging.debug('Pushed to APIC successfully') else: logging.error('Error pushing to APIC', resp.text) return new_relations def run(self): loop_count = 0 accelerated_cleanup_done = False old_relations = {} while not self._exit: time.sleep(self._monitor_frequency) old_relations = self._process_events(old_relations)
# 2. Configuration file called credentials.py # 3. Environment variables # 4. Interactively querying the user # At the end, we should have an object args with all the necessary info. description = 'APIC credentials' creds = Credentials('apic', description) creds.add_argument('-d', "--debug", default=None, help='Enable Debug mode') args = creds.get() # Process all relevant command-line parameters and print our welcome banner if args.debug is not None: debug_enable() print_banner() # Now, we log into the APIC session = Session(args.url, args.login, args.password) response = session.login() if response.ok is False: fatal(response.content) else: output("Successfully connected to %s" % args.url) # Retrieve the list of existing tenants tenants = Tenant.get(session) # Subscribe to each one urls=[] for tn in tenants: url = "/api/mo/uni/tn-%s.json?query-target=subtree&subscription=yes" % tn.name try: debug("Subscribing to '%s'" % url)