def main(): """ Main common routine for show interface description :return: None """ # Set up the command line options creds = Credentials(['apic', 'nosnapshotfiles'], description=("This application replicates the switch " "CLI command 'show interface fex'")) creds.add_argument('-s', '--switch', type=str, default=None, help='Specify a particular switch id, e.g. "101"') args = creds.get() # Login to APIC apic = Session(args.url, args.login, args.password) if not apic.login().ok: print('%% Could not login to APIC') return # Show interface description node_ids = get_node_ids(apic, args) show_interface_fex(apic, node_ids)
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 main(): """ Main execution routine """ description = ('Simple application that logs on to the APIC' ' and displays usage information for a given DN') creds = Credentials('apic', description) creds.add_argument("-d", "--dn_name", help="DN to query for usage information") args = creds.get() session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') url = '/api/mo/{}.json?query-target=children&target-subtree-class=relnFrom' url = url.format(args.dn_name) resp = session.get(url) if resp.ok: used_by = resp.json()['imdata'] for item in used_by: kls = next(iter(item)) attributes = item[kls]['attributes'] data.append((attributes['tDn'], kls)) print(tabulate(data, headers=["Used by", "Class"]))
def main(): """ Main show Process routine :return: None """ description = 'Simple application that logs on to the APIC and check cluster information for a fabric' creds = Credentials('apic', description) args = creds.get() session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print '%% Could not login to APIC' sys.exit(0) cluster = Cluster.get(session) if (cluster.config_size != cluster.cluster_size): print("*******************************************************") print ("WARNING, configured cluster size "), cluster.config_size print (": not equal to the actual size "), cluster.cluster_size print "WARNING, desired stats collection might be lost" print("*******************************************************") print("APICs in the cluster"), cluster.name, (":") for apic in cluster.apics: print json.dumps(apic, indent=4, sort_keys=True) else: print("PASS")
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 main(): """ Main show Process routine :return: None """ description = 'Simple application that logs on to the APIC and check cluster information for a fabric' creds = Credentials('apic', description) args = creds.get() session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print '%% Could not login to APIC' sys.exit(0) cluster = Cluster.get(session) if (cluster.config_size != cluster.cluster_size): print("*******************************************************") print("WARNING, configured cluster size "), cluster.config_size print(": not equal to the actual size "), cluster.cluster_size print "WARNING, desired stats collection might be lost" print("*******************************************************") print("APICs in the cluster"), cluster.name, (":") for apic in cluster.apics: print json.dumps(apic, indent=4, sort_keys=True) else: print("PASS")
def main(): """ Main common routine for show interface description :return: None """ # Set up the command line options creds = Credentials(['apic', 'nosnapshotfiles'], description=("This application replicates the switch " "CLI command 'show interface fex'")) creds.add_argument('-s', '--switch', type=str, default=None, help='Specify a particular switch id, e.g. "101"') creds.add_argument('-i', '--interface', type=str, default=None, help='Specify a particular interface id, e.g. "eth1/10"') creds.add_argument('-b', '--brief', action='store_true', help='Display a brief summary') args = creds.get() if args.brief: interface_collector = InterfaceBriefCollector(args.url, args.login, args.password) interface_collector.show_brief(node=args.switch, intf_id=args.interface) else: interface_collector = InterfaceDetailedCollector(args.url, args.login, args.password) interface_collector.show_detailed(node=args.switch, intf_id=args.interface)
def main(): # Set up the Command Line options creds = Credentials(('apic', 'nosnapshotfiles'), description='') creds.add_argument('--printonly', action='store_true', help='Only print the JSON but do not push to APIC.') group = creds.add_mutually_exclusive_group() group.add_argument('--config', default=None, help='Optional .ini file providing failure scenario configuration') group.add_argument('--delete', action='store_true', help='Delete ALL of the randomized configuration from the APIC') 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') print resp.status_code, resp.text return # Handle the delete case if args.delete: delete_all_randomized_tenants(session) return # Ensure that a config file has been given if args.config is None: print '%% Expected --config or --delete option' return config = ConfigParser.ConfigParser() config.read(args.config) randomizer = ConfigRandomizer(config) interfaces = ['eth 1/101/1/17', 'eth 1/102/1/17'] randomizer.create_random_config(interfaces) flows = randomizer.get_flows(1) flow_json = [] for flow in flows: flow_json.append(flow.get_json()) flow_json = json.dumps({'flows': flow_json}) for tenant in randomizer.tenants: print 'TENANT CONFIG' print '-------------' print tenant.get_json() print print if not args.printonly: resp = tenant.push_to_apic(session) if not resp.ok: print resp.status_code, resp.text assert resp.ok print 'Total number of tenants pushed:', len(randomizer.tenants)
def main(): """ Main execution routine """ description = 'Simple application that logs on to the APIC and displays all of the Tenants.' creds = Credentials('apic', description) creds.add_argument("-d", "--domain-name", type=str, help="list of domains. usage -d tennat.infra") creds.add_argument( "-t", "--tenant-name", type=str, help= "name of the tenant of which faults are to be displayed. If not given faults of all the tenants are shown" ) creds.add_argument('--continuous', action='store_true', help='Continuously monitor for faults') 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') return faults_obj = Faults() fault_filter = None if args.domain_name is not None: fault_filter = {'domain': args.domain_name.split(',')} tenant_name = None if args.tenant_name is not None: tenant_name = args.tenant_name faults_obj.subscribe_faults(session, fault_filter) while faults_obj.has_faults(session, fault_filter) or args.continuous: if faults_obj.has_faults(session, fault_filter): faults = faults_obj.get_faults(session, fault_filter=fault_filter, tenant_name=tenant_name) if faults is not None: for fault in faults: if fault is not None: print("---------------") if fault.descr is not None: print(" descr : " + fault.descr) else: print(" descr : " + " ") print(" dn : " + fault.dn) print(" rule : " + fault.rule) print(" severity : " + fault.severity) print(" type : " + fault.type) print(" domain : " + fault.domain)
def main(): """ Main common routine for show fex description :return: None """ # Set up the command line options creds = Credentials(['apic', 'nosnapshotfiles'], description=("This application replicates the switch " "CLI command 'show interface'")) creds.add_argument('-s', '--switch', type=str, default=None, help='Specify a particular switch id, e.g. "101"') creds.add_argument('-f', '--fex', type=str, default=None, help='Specify a particular FEX id, e.g. "101"') group = creds.add_mutually_exclusive_group() group.add_argument('-d', '--detail', action='store_true', help='Provide a detailed report (equivalent to "show fex detail"') group.add_argument('-t', '--transceiver', action='store_true', help='Provide a transceiver report (equivalent to "show fex transceiver"') group.add_argument('-v', '--version', action='store_true', help='Provide a version report (equivalent to "show fex version"') args = creds.get() fex_collector = FexCollector(args.url, args.login, args.password) # Show interface description fex_collector.show_fex(args.switch, args.fex, args.detail, args.transceiver, args.version)
def main(): # Set up the Command Line options creds = Credentials(('apic', 'nosnapshotfiles'), description='') group = creds.add_mutually_exclusive_group() group.add_argument('--config', default=None, help='Optional .ini file providing failure scenario configuration') group.add_argument('--delete', action='store_true', help='Delete ALL of the randomized configuration from the APIC') 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') print resp.status_code, resp.text return # Handle the delete case if args.delete: delete_all_randomized_tenants(session) return # Ensure that a config file has been given if args.config is None: print '%% Expected --config or --delete option' return config = ConfigParser.ConfigParser() config.read(args.config) # Handle the random creation num_tenants = random_number(int(config.get('Tenants', 'Minimum')), int(config.get('Tenants', 'Maximum'))) for i in range(0, num_tenants): tenant = create_random_tenant_config(config) print 'TENANT CONFIG' print '-------------' print tenant.get_json() print print resp = tenant.push_to_apic(session) if not resp.ok: print resp.status_code, resp.text assert resp.ok print 'Total number of tenants pushed:', num_tenants
def main(): """ Main common routine for show interface description :return: None """ # Set up the command line options creds = Credentials(['apic', 'nosnapshotfiles'], description=("This application replicates the switch " "CLI command 'show interface description'")) creds.add_argument('-s', '--switch', type=str, default=None, help='Specify a particular switch id, e.g. "101"') creds.add_argument('-i', '--interface', type=str, default=None, help='Specify a specific interface, e.g. "eth1/1"') args = creds.get() # Login to APIC apic = Session(args.url, args.login, args.password) if not apic.login().ok: print('%% Could not login to APIC') return # Show interface description node_ids = get_node_ids(apic, args) apic_intf_classes = ['l1PhysIf', 'pcAggrIf', 'l3EncRtdIf', 'sviIf', 'tunnelIf', 'mgmtMgmtIf', 'l3LbRtdIf'] for apic_intf_class in apic_intf_classes: show_interface_description(apic, node_ids, apic_intf_class=apic_intf_class, specific_interface=args.interface)
def main(): """ Main common routine for show interface description :return: None """ # Set up the command line options creds = Credentials(['apic', 'nosnapshotfiles'], description=("This application replicates the switch " "CLI command 'show interface fex'")) creds.add_argument('-s', '--switch', type=str, default=None, help='Specify a particular switch id, e.g. "101"') creds.add_argument('-i', '--interface', type=str, default=None, help='Specify a particular interface id, e.g. "po101"') args = creds.get() interface_collector = InterfaceCollector(args.url, args.login, args.password) interface_collector.show_summary(node=args.switch, intf_id=args.interface)
def main(): """ Main show Subnets 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 Subnets.') creds = Credentials('apic', description) creds.add_argument('--tenant', help='The name of Tenant') 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') # Download all of the tenants, app profiles, and Subnets # and store the names as tuples in a list tenants = Tenant.get(session) for tenant in tenants: check_longest_name(tenant.name, "Tenant") if args.tenant is None: get_subnet(session, tenant) else: if tenant.name == args.tenant: get_subnet(session, tenant) # Display the data downloaded template = '{0:' + str(longest_names["Tenant"]) + '} ' \ '{1:' + str(longest_names["Application Profile"]) + '} ' \ '{2:' + str(longest_names["Bridge Domain"]) + '} ' \ '{3:' + str(longest_names["Subnet"]) + '} ' \ '{4:' + str(longest_names["Scope"]) + '}' print(template.format("Tenant", "Application Profile", "Bridge Domain", "Subnet", "Scope")) print(template.format('-' * longest_names["Tenant"], '-' * longest_names["Application Profile"], '-' * longest_names["Bridge Domain"], '-' * longest_names["Subnet"], '-' * longest_names["Scope"])) for rec in sorted(data): print(template.format(*rec))
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 main(): """ Main execution routine """ description = 'Simple application that logs on to the APIC and displays all of the Tenants.' creds = Credentials('apic', description) creds.add_argument( "-d", "--domain-name", type=str, help="list of domains. usage -d tennat.infra") creds.add_argument( "-t", "--tenant-name", type=str, help="name of the tenant of which faults are to be displayed. If not given faults of all the tenants are shown") creds.add_argument('--continuous', action='store_true', help='Continuously monitor for faults') 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') return faults_obj = Faults() fault_filter = None if args.domain_name is not None: fault_filter = {'domain': args.domain_name.split(',')} tenant_name = None if args.tenant_name is not None: tenant_name = args.tenant_name faults_obj.subscribe_faults(session, fault_filter) while faults_obj.has_faults(session, fault_filter) or args.continuous: if faults_obj.has_faults(session, fault_filter): faults = faults_obj.get_faults( session, fault_filter=fault_filter, tenant_name=tenant_name) if faults is not None: for fault in faults: if fault is not None: print "---------------" if fault.descr is not None: print " descr : " + fault.descr else: print " descr : " + " " print " dn : " + fault.dn print " rule : " + fault.rule print " severity : " + fault.severity print " type : " + fault.type print " domain : " + fault.domain
def main(): """ Main routine """ # Get all the arguments description = 'Creates a tenant with a micro-EPG.' creds = Credentials('apic', description) args = creds.get() # Login to the APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') # Create the Tenant and AppProfile tenant = Tenant('acitoolkit-microepg-example') app_profile = AppProfile('myapp', tenant) # Create a Base EPG that will provide networking for the microEPGs base_epg = EPG('base', app_profile) base_epg.add_static_leaf_binding('101', 'vlan', '1', encap_mode='untagged') vrf = Context('myvrf', tenant) bd = BridgeDomain('mybd', tenant) bd.add_context(vrf) base_epg.add_bd(bd) # Create a microEPG microepg = EPG('microepg', app_profile) microepg.is_attributed_based = True microepg.set_base_epg(base_epg) # Add an IP address to this microepg criterion = AttributeCriterion('criterion', microepg) criterion.add_ip_address('1.2.3.4') # Contracts can be provided/consumed from the microepg as desired (not shown) # Push the tenant to the APIC resp = tenant.push_to_apic(session) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text)
def main(): """ Main Show VM Names 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 virtual machine names.') 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') return # Make a direct call to the APIC REST API # Get all of the VMs (all objects of compVM class) and include the compVNic children # which contain the MAC address of the NIC. # The advantage of using acitoolkit Session.get() instead of direct Requests.get() calls # is that acitoolkit will automatically handle retries and pagination for queries with # large response data class_url = '/api/node/class/compVm.json?rsp-subtree=children&rsp-subtree-class=compVNic' ret = session.get(class_url) vm_list = ret.json()['imdata'] # Process the response. We're looking for the VM name and the associated vNIC MAC addresses. data = [] for vm in vm_list: vm_name = vm['compVm']['attributes']['name'] for vnic in vm['compVm']['children']: vm_mac = vnic['compVNic']['attributes']['mac'] # Store the VM name and MAC address. Note that VM names may be associated with # multiple MAC addresses if they have multiple vNICs. data.append((vm_name, vm_mac)) # Display the data downloaded print(tabulate(data, headers=["VMNAME", "MACADDRESS"]))
def main(): """ Use the Credentials class of ACI toolkit to get the needed args to run the app. Set up an instance of FeedCfg and EventMonitor with provided args. Start the the EventMonitor thread as a daemon and then start the Flask server. """ global feed, cursor, logger # Grab APIC credentials and ip/port for Flask creds = Credentials(qualifier=('apic', 'server'), description='ACI Toolkit') args = creds.get() # Get EventFeeds configuration from disk and instantiate worker thread feed = FeedCfg() event_monitor = EventMonitor(args.url, args.login, args.password) # Set up file and stdout logging msg_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' logging.basicConfig(filename=feed.cfg['log_file'], level=logging.INFO, format=msg_format) stdout = logging.StreamHandler(sys.stdout) formatter = logging.Formatter(msg_format) stdout.setFormatter(formatter) logger.addHandler(stdout) logger.info('Getting DB Connection') try: conn = _get_db() cursor = conn.cursor() except sqlite3.Error as e: logger.critical('Could not get handle to DB: %s', e.message) # Start worker thread event_monitor.start() # Start Flask server app.run(host=args.ip, port=int(args.port), debug=False, use_reloader=False)
def main(): """ Main execution routine """ # Take login credentials from the command line if provided # Otherwise, take them from your environment variables file ~/.profile description = ('Application that logs on to the APIC and tracks' ' all of the Endpoint stats in a MySQL database.') creds = Credentials(qualifier=('apic', 'mysql'), description=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') return # Create the MySQL database cnx = mysql.connector.connect(user=args.mysqllogin, password=args.mysqlpassword, host=args.mysqlip) c = cnx.cursor() c.execute('CREATE DATABASE IF NOT EXISTS acitoolkit_interface_stats;') cnx.commit() c.execute('USE acitoolkit_interface_stats;') all_stats = InterfaceStats.get_all_ports(session, 1) for intf in all_stats: stats = all_stats[intf] for stats_family in stats: if '5min' in stats[stats_family]: for epoch in stats[stats_family]['5min']: if epoch != 0: ss = stats[stats_family]['5min'][epoch] if stats_family not in valid_tables: create_table(c, cnx, stats_family, list(ss.keys())) if not interval_end_exists(c, stats_family, intf, ss['intervalEnd']): insert_stats_row(c, cnx, stats_family, intf, ss)
def main(): """ Main show EPGs routine :return: None """ # Login to APIC description = ('Simple application that logs on to the APIC' ' and displays all of the EPGs.') creds = Credentials('apic', description) creds.add_argument('--tenant', help='The name of Tenant') args = creds.get() session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') # Download all of the tenants, app profiles, and EPGs # and store the names as tuples in a list tenants = Tenant.get(session) for tenant in tenants: check_longest_name(tenant.name, "Tenant") if args.tenant is None: get_epg(session, tenant) else: if tenant.name == args.tenant: get_epg(session, tenant) # Display the data downloaded template = '{0:' + str(longest_names["Tenant"]) + '} ' \ '{1:' + str(longest_names["Application Profile"]) + '} ' \ '{2:' + str(longest_names["EPG"]) + '}' print(template.format("Tenant", "Application Profile", "EPG")) print(template.format('-' * longest_names["Tenant"], '-' * longest_names["Application Profile"], '-' * longest_names["EPG"])) for rec in sorted(data): print(template.format(*rec))
def main(): """ Main common routine for show vlan ext, show vlan brief, and show vlan info :return: None """ # Set up the command line options creds = Credentials(['apic', 'nosnapshotfiles'], description="This application replicates the switch CLI command 'show vlan extended'") creds.add_argument('-s', '--switch', type=str, default=None, help='Specify a particular switch id, e.g. "101"') args = creds.get() # Login to APIC apic = Session(args.url, args.login, args.password) if not apic.login().ok: print('%% Could not login to APIC') return node_ids = get_node_ids(apic, args) show_vlan_brief(apic, node_ids) show_vlan_info(apic, node_ids)
def main(): # Set up the Command Line options creds = Credentials(('apic', 'nosnapshotfiles'), description='') creds.add_argument('--printonly', action='store_true', help='Only print the JSON but do not push to APIC.') creds.add_argument('--testloop', action='store_true', help='Run in a continual testing loop.') group = creds.add_mutually_exclusive_group() group.add_argument( '--config', default=None, help='Optional .ini file providing failure scenario configuration') group.add_argument( '--delete', action='store_true', help='Delete ALL of the randomized configuration from the APIC') 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') print resp.status_code, resp.text return # Handle the delete case if args.delete: delete_all_randomized_tenants(session) return # Ensure that a config file has been given if args.config is None: print '%% Expected --config or --delete option' return if args.testloop: while True: generate_config(session, args) time.sleep(random_number(5, 30)) delete_all_randomized_tenants(session) time.sleep(random_number(5, 30)) else: generate_config(session, args)
def main(): """ Main execution routine """ description = ( 'Simple application that logs on to the APIC' ' and displays all the tenant info of the contract_interface related to the imported contract.' ) creds = Credentials('apic', description) creds.add_argument("-t", "--tenant_name", help="Tenant Name of where the contract is created") creds.add_argument("-i", "--contract_name", help="Imported Contract Name") args = creds.get() if (args.tenant_name is not None) and (args.contract_name is None): args.contract_name = raw_input("Contract Name: ") session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') tenants = Tenant.get_deep(session) for tenant in tenants: contracts_interfaces = tenant.get_children( only_class=ContractInterface) for contract_interface in contracts_interfaces: imported_contract = contract_interface.get_import_contract() if imported_contract is not None: if args.tenant_name is not None: if (imported_contract.name == args.contract_name) and ( imported_contract.get_parent().name == args.tenant_name): apps = AppProfile.get(session, tenant) for app in apps: epgs = EPG.get(session, app, tenant) for epg in epgs: data.append((imported_contract.name, tenant.name, app.name, epg.name)) else: apps = AppProfile.get(session, tenant) for app in apps: epgs = EPG.get(session, app, tenant) for epg in epgs: data.append((imported_contract.name, tenant.name, app.name, epg.name)) print tabulate( data, headers=["IMPORTED_CONTRACT", "TENANT", "APP_PROFILE", "EPG"])
def main(): # Set up the Command Line options creds = Credentials(('apic', 'nosnapshotfiles'), description='') creds.add_argument('--printonly', action='store_true', help='Only print the JSON but do not push to APIC.') creds.add_argument('--testloop', action='store_true', help='Run in a continual testing loop.') group = creds.add_mutually_exclusive_group() group.add_argument('--config', default=None, help='Optional .ini file providing failure scenario configuration') group.add_argument('--delete', action='store_true', help='Delete ALL of the randomized configuration from the APIC') 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') print resp.status_code, resp.text return # Handle the delete case if args.delete: delete_all_randomized_tenants(session) return # Ensure that a config file has been given if args.config is None: print '%% Expected --config or --delete option' return if args.testloop: while True: generate_config(session, args) time.sleep(random_number(5, 30)) delete_all_randomized_tenants(session) time.sleep(random_number(5, 30)) else: generate_config(session, args)
def main(): """ Main execution routine """ description = ('Simple application that logs on to the APIC' ' and displays all the tenant info of the contract_interface related to the imported contract.') creds = Credentials('apic', description) creds.add_argument("-t", "--tenant_name", help="Tenant Name of where the contract is created") creds.add_argument("-i", "--contract_name", help="Imported Contract Name") args = creds.get() if (args.tenant_name is not None) and (args.contract_name is None): args.contract_name = raw_input("Contract Name: ") session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') tenants = Tenant.get_deep(session) for tenant in tenants: contracts_interfaces = tenant.get_children(only_class=ContractInterface) for contract_interface in contracts_interfaces: imported_contract = contract_interface.get_import_contract() if imported_contract is not None: if args.tenant_name is not None: if (imported_contract.name == args.contract_name) and (imported_contract.get_parent().name == args.tenant_name): apps = AppProfile.get(session, tenant) for app in apps: epgs = EPG.get(session, app, tenant) for epg in epgs: data.append((imported_contract.name, tenant.name, app.name, epg.name)) else: apps = AppProfile.get(session, tenant) for app in apps: epgs = EPG.get(session, app, tenant) for epg in epgs: data.append((imported_contract.name, tenant.name, app.name, epg.name)) print tabulate(data, headers=["IMPORTED_CONTRACT", "TENANT", "APP_PROFILE", "EPG"])
def main(): """ Main create tenant routine :return: None """ # Get all the arguments description = 'It logs in to the APIC and will delete tenants named with the specified string.' creds = Credentials(['apic', 'nosnapshotfiles'], description) group = creds.add_mutually_exclusive_group() group.add_argument('--startswith', default=None, help='String to match that starts the tenant name') group.add_argument('--endswith', default=None, help='String to match that ends the tenant name') group.add_argument('--exactmatch', default=None, help='String that exactly matches the tenant name') group.add_argument('--contains', default=None, help='String that is contained in the tenant name') creds.add_argument('--force', action='store_true', help='Attempt to remove the tenants without prompting for confirmation') args = creds.get() # Login to the APIC apic = Session(args.url, args.login, args.password) resp = apic.login() if not resp.ok: print('%% Could not login to APIC') # Get all of the Tenants tenants = Tenant.get(apic) # Find the list of Tenants to delete according to command line options tenants_to_delete = [] for tenant in tenants: if args.startswith is not None: if tenant.name.startswith(args.startswith): tenants_to_delete.append(tenant) elif args.endswith is not None: if tenant.name.endswith(args.endswith): tenants_to_delete.append(tenant) elif args.exactmatch is not None: if args.exactmatch == tenant.name: tenants_to_delete.append(tenant) elif args.contains is not None: if args.contains in tenant.name: tenants_to_delete.append(tenant) # Query the user to be sure of deletion if not args.force: for tenant in tenants_to_delete: prompt = 'Delete tenant %s ? [y/N]' % tenant.name try: resp = raw_input(prompt) except NameError: resp = input(prompt) if not resp.lower().startswith('y'): tenants_to_delete.remove(tenant) print 'Skipping tenant', tenant.name # Delete the tenants for tenant in tenants_to_delete: tenant.mark_as_deleted() resp = tenant.push_to_apic(apic) if resp.ok: print 'Deleted tenant', tenant.name else: print 'Could not delete tenant', tenant.name print resp.text
def main(): """ Main routine :return: None """ # Login to APIC description = ('Simple application that logs on to the APIC' ' and displays all of the External Subnets.') creds = Credentials('apic', description) creds.add_argument('-f', '--find_ip', help='IP address to search for') args = creds.get() session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') if not args.find_ip: print("Error: -f|--find_ip <ip_address> argument required") sys.exit(1) print("searching for " + args.find_ip) # Download all of the tenants, app profiles, and Subnets # and store the names as tuples in two lists priv = [] publ = [] ip = args.find_ip tenants = Tenant.get_deep(session, limit_to=[ 'fvTenant', 'fvSubnet', 'l3extOut', 'l3extInstP', 'l3extSubnet' ]) for tenant in tenants: apps = AppProfile.get(session, tenant) for app in apps: bds = BridgeDomain.get(session, tenant) for bd in bds: subnets = Subnet.get(session, bd, tenant) for subnet in subnets: net = IPNetwork(subnet.addr) if net.Contains(IPNetwork(ip)): priv.append( (tenant.name, app.name, bd.name, subnet.addr, subnet.get_scope())) for tenant in tenants: outside_l3s = tenant.get_children(only_class=OutsideL3) for outside_l3 in outside_l3s: outside_epgs = outside_l3.get_children(only_class=OutsideEPG) for outside_epg in outside_epgs: outside_networks = outside_epg.get_children( only_class=OutsideNetwork) for outside_network in outside_networks: net = IPNetwork(outside_network.addr) if net.Contains(IPNetwork(ip)): publ.append((tenant.name, outside_l3.name, outside_epg.name, outside_network.addr, outside_network.get_scope())) # Display template = "{0:20} {1:20} {2:20} {3:18} {4:15}" if len(priv): print("") print( template.format("Tenant", "App", "Bridge Domain", "Subnet", "Scope")) print(template.format("-" * 20, "-" * 20, "-" * 20, "-" * 18, "-" * 15)) for rec in priv: print(template.format(*rec)) if len(publ): print("") print( template.format("Tenant", "OutsideL3", "OutsideEPG", "Subnet", "Scope")) print(template.format("-" * 20, "-" * 20, "-" * 20, "-" * 18, "-" * 15)) for rec in publ: print(template.format(*rec))
def main(): """ Main show EPGs routine :return: None """ # Login to APIC description = ('Simple application that logs on to the APIC' ' and displays all of the EPGs.') creds = Credentials('apic', description) args = creds.get() session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') return # Download all of the tenants, app profiles, and EPGs # and store the names as tuples in a list tenants = Tenant.get_deep(session) tenants_list = [] for tenant in tenants: tenants_dict = {} tenants_dict['name'] = tenant.name if tenant.descr: tenants_dict['description'] = tenant.descr tenants_dict['app-profiles'] = [] for app in tenant.get_children(AppProfile): app_profiles = {'name': app.name} if app.descr: app_profiles['description'] = app.descr app_profiles['epgs'] = [] for epg in app.get_children(EPG): epgs_info = {'name': epg.name} if epg.descr: epgs_info['description'] = epg.descr epgs_info['endpoints'] = [] for endpoint in epg.get_children(Endpoint): endpoint_info = {'name': endpoint.name} if endpoint.ip != '0.0.0.0': endpoint_info['ip'] = endpoint.ip try: hostname = socket.gethostbyaddr(endpoint.ip)[0] except socket.error: hostname = None if hostname: endpoint_info['hostname'] = hostname if endpoint.descr: endpoint_info['description'] = endpoint.descr epgs_info['endpoints'].append(endpoint_info) app_profiles['epgs'].append(epgs_info) tenants_dict['app-profiles'].append(app_profiles) tenants_list.append(tenants_dict) tenants_info = {'tenants': tenants_list} print(yaml.safe_dump(tenants_info, sys.stdout, indent=4, default_flow_style=False))
tabs[k]['class'], tabs[k]['properties'], headers=tabs.get(k).get('headers')) tenants = class_query(session, 'fvTenant') for t in tenants: createTenantSheet(session, workbook, t) workbook.close() if __name__ == "__main__": description = 'aci-doc' # Gather credentials for ACI creds = Credentials('apic', description) args = creds.get() # Establish an API session to the APIC apic = Session(args.url, args.login, args.password) if apic.login().ok: print("Connected to ACI") print("depending on your configuration, this could take a little while...") with open('config.yaml', 'r') as config: config = yaml.safe_load(config) CreateWorkBook(apic, config['filename'], config['tabs'])
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 main(): """ Main show EPGs routine :return: None """ # Login to APIC description = ('Simple application that logs on to the APIC' ' and displays all of the EPGs.') creds = Credentials('apic', description) args = creds.get() session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') return # Download all of the tenants, app profiles, and EPGs # and store the names as tuples in a list tenants = Tenant.get_deep(session) tenants_list = [] for tenant in tenants: tenants_dict = {} tenants_dict['name'] = tenant.name if tenant.descr: tenants_dict['description'] = tenant.descr tenants_dict['app-profiles'] = [] for app in tenant.get_children(AppProfile): app_profiles = {'name': app.name} if app.descr: app_profiles['description'] = app.descr app_profiles['epgs'] = [] for epg in app.get_children(EPG): epgs_info = {'name': epg.name} if epg.descr: epgs_info['description'] = epg.descr epgs_info['endpoints'] = [] for endpoint in epg.get_children(Endpoint): endpoint_info = {'name': endpoint.name} if endpoint.ip != '0.0.0.0': endpoint_info['ip'] = endpoint.ip try: hostname = socket.gethostbyaddr(endpoint.ip)[0] except socket.error: hostname = None if hostname: endpoint_info['hostname'] = hostname if endpoint.descr: endpoint_info['description'] = endpoint.descr epgs_info['endpoints'].append(endpoint_info) app_profiles['epgs'].append(epgs_info) tenants_dict['app-profiles'].append(app_profiles) tenants_list.append(tenants_dict) tenants_info = {'tenants': tenants_list} print( yaml.safe_dump(tenants_info, sys.stdout, indent=4, default_flow_style=False))
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 Interfaces.' creds = Credentials('apic', description) creds.add_argument('--tenant', help='The name of Tenant') 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) resp = session.get('/api/class/ipv4Addr.json') intfs = json.loads(resp.text)['imdata'] for i in intfs: ip = i['ipv4Addr']['attributes']['addr'] op = i['ipv4Addr']['attributes']['operSt'] cfg = i['ipv4Addr']['attributes']['operStQual'] dn = i['ipv4Addr']['attributes']['dn'] node = dn.split('/')[2] intf = re.split(r'\[|\]', dn)[1] vrf = re.split(r'/|dom-', dn)[7] tn = vrf if vrf.find(":") != -1: tn = re.search("(.*):(.*)", vrf).group(1) check_longest_name(node, "Node") check_longest_name(intf, "Interface") check_longest_name(ip, "IP Address") check_longest_name(cfg, "Admin Status") check_longest_name(op, "Status") if args.tenant is None: if vrf not in data.keys(): data[vrf] = [] else: data[vrf].append((node, intf, ip, cfg, op)) else: if tn == args.tenant: if vrf not in data.keys(): data[vrf] = [] else: data[vrf].append((node, intf, ip, cfg, op)) for k in data.keys(): header = 'IP Interface Status for VRF "{}"'.format(k) print(header) template = '{0:' + str(longest_names["Node"]) + '} ' \ '{1:' + str(longest_names["Interface"]) + '} ' \ '{2:' + str(longest_names["IP Address"]) + '} ' \ '{3:' + str(longest_names["Admin Status"]) + '} ' \ '{4:' + str(longest_names["Status"]) + '}' print( template.format("Node", "Interface", "IP Address", "Admin Status", "Status")) print( template.format('-' * longest_names["Node"], '-' * longest_names["Interface"], '-' * longest_names["IP Address"], '-' * longest_names["Admin Status"], '-' * longest_names["Status"])) for rec in sorted(data[k]): print(template.format(*rec)) print('')
def main(): """ Main routine :return: None """ # Login to APIC description = ('Simple application that logs on to the APIC' ' and displays all of the External Subnets.') creds = Credentials('apic', description) creds.add_argument('-f', '--find_ip', help='IP address to search for') args = creds.get() session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') if not args.find_ip: print("Error: -f|--find_ip <ip_address> argument required") sys.exit(1) print("searching for " + args.find_ip) # Download all of the tenants, app profiles, and Subnets # and store the names as tuples in two lists priv = [] publ = [] ip = args.find_ip tenants = Tenant.get_deep(session, limit_to=['fvTenant', 'fvSubnet', 'l3extOut', 'l3extInstP', 'l3extSubnet']) for tenant in tenants: apps = AppProfile.get(session, tenant) for app in apps: bds = BridgeDomain.get(session, tenant) for bd in bds: subnets = Subnet.get(session, bd, tenant) for subnet in subnets: net = IPNetwork(subnet.addr) if net.Contains(IPNetwork(ip)): priv.append((tenant.name, app.name, bd.name, subnet.addr, subnet.get_scope())) for tenant in tenants: outside_l3s = tenant.get_children(only_class=OutsideL3) for outside_l3 in outside_l3s: outside_epgs = outside_l3.get_children(only_class=OutsideEPG) for outside_epg in outside_epgs: outside_networks = outside_epg.get_children(only_class=OutsideNetwork) for outside_network in outside_networks: net = IPNetwork(outside_network.addr) if net.Contains(IPNetwork(ip)): publ.append((tenant.name, outside_l3.name, outside_epg.name, outside_network.addr, outside_network.get_scope())) # Display template = "{0:20} {1:20} {2:20} {3:18} {4:15}" if len(priv): print("") print(template.format("Tenant", "App", "Bridge Domain", "Subnet", "Scope")) print(template.format("-" * 20, "-" * 20, "-" * 20, "-" * 18, "-" * 15)) for rec in priv: print(template.format(*rec)) if len(publ): print("") print(template.format("Tenant", "OutsideL3", "OutsideEPG", "Subnet", "Scope")) print(template.format("-" * 20, "-" * 20, "-" * 20, "-" * 18, "-" * 15)) for rec in publ: print(template.format(*rec))
def main(): ''' Main Function ''' # Setup Arguments utilizing the ACIToolkit Credentials Method description = ('Help to determine EP movement during Maintenance Windows') creds = Credentials('apic', description) creds.add_argument('-v', '--version', action='version', version='%(prog)s == {}'.format(__version__)) creds.add_argument("--debug", dest="debug", choices=["debug", "info", "warn", "critical"], default="info", help='Enable debugging output to screen') creds.add_argument( '--log', action='store_true', help= 'Write the output to a log file: {}.log. Automatically adds timestamp to filename' .format(__file__.split(".py")[0])) creds.add_argument( '--list', action='store_true', help= 'Print out the list of Tenants / App Profiles / EPGs available to work with' ) creds.add_argument( '--filter', help= 'Specify what to filter on. Eg: "tn-mipetrin" or "ap-mipetrin-AppProfile". Use --list to identify what can be used for filtering. Default = None' ) creds.add_argument( '--pre', help= 'Write the data to a file of your choosing. Specify your prefix. Format will be JSON and this extension is automatically added' ) creds.add_argument( '--post', help= 'Write the data to a file of your choosing. Specify your prefix. Format will be JSON and this extension is automatically added' ) creds.add_argument( '--compare', nargs=2, help= 'Compare the 2 files you specify. Be sure to pick a PRE and POST file') creds.add_argument( '--summary', type=int, help= 'Optionally, print out detailed summary of identified Endpoints greater than x (provide totals per Tenant/App/EPG/MAC/Encap)' ) args = creds.get() # Set up custom logger setup_logger(logger, args.debug, args.log) # If --suumary enabled, set up globals to then utlize the additonal calculations throughout code if args.summary: global detailed_summary global detailed_summary_number detailed_summary = True detailed_summary_number = args.summary # Due to creds / argparse above, will always need to provide APIC / User / Pass even if wanting to do local comparison of PRE/POST JSON files # However, below check will ensure we actually only perform login if NOT doing a comparison. That is, if doing --compare, you can type ANY password even simply hitting enter if not args.compare: # Login to APIC only if NOT doing a comparison - as already have the data we need in the local JSON files session = Session(args.url, args.login, args.password) resp = session.login() # Check if the login was successful if not resp.ok: logger.critical('Could not login to APIC') my_error = resp.json() logger.critical("Specific Error: {}".format( my_error["imdata"][0]["error"]["attributes"]["text"])) exit(0) # Start time count at this point, otherwise takes into consideration the amount of time taken to input the password by the user start_time = time.time() logger.debug("Begin Execution of script") # Order of precedence is to execute list of tenants, pre capture, post capture, compare if args.list: print_header("Gathering available information from APIC...") get_raw_tenant_info(session) elif args.pre: print_header("Gathering 'PRE' Endpoints...") # Setup Filename for PRE file (using user input) and global pre_suffix my_filename_pre = args.pre + pre_suffix # Confirm if user has selected any --filter if args.filter: get_fvCEp(session, my_filename_pre, args.filter) else: get_fvCEp(session, my_filename_pre, "None") elif args.post: print_header("Gathering 'POST' Endpoints...") # Setup Filename for POST file (using user input) and global post_suffix my_filename_post = args.post + post_suffix # Confirm if user has selected any --filter if args.filter: get_fvCEp(session, my_filename_post, args.filter) else: get_fvCEp(session, my_filename_post, "None") elif args.compare: # Ensure *BOTH* the specified PRE and POST files exist. If not, throw error and explain which ones currently exist # Look for the suffix that I auto append during the --pre and --post file generation for file in args.compare: if pre_suffix in file: my_filename_pre = file elif post_suffix in file: my_filename_post = file else: logger.critical( "Issue with file names supplied as don't contain the suffix defined. Are they the files generated by this script via the --pre / --post options?" ) exit(0) # Check that the files do in fact exist and are readable if not os.path.isfile(my_filename_pre): logger.critical( "Need to ensure the PRE capture has been completed and readable" ) exit(0) # Check that the files do in fact exist and are readable if not os.path.isfile(my_filename_post): logger.critical( "Need to ensure the POST capture has been completed and readable" ) exit(0) print_header("Analyzing 'PRE' Endpoints...") analyze_file(my_filename_pre, "pre") print_header("Analyzing 'POST' Endpoints...") analyze_file(my_filename_post, "post") print_header("Comparing 'PRE' and 'POST' Endpoints...") compare_eps() print_header("Endpoints with Movements...") logger.info("\n" + tabulate(ep_tracker_diff, headers=[ "Tenant", "App Profile", "EPG", "MAC", "Stage", "Node", "Interface", "Encap" ], tablefmt="grid")) print_header("Endpoints only in PRE capture") logger.info("\n" + tabulate(ep_only_in_pre_capture, headers=[ "Tenant", "App Profile", "EPG", "MAC", "Stage", "Node", "Interface", "Encap" ], tablefmt="grid")) print_header("Endpoints only in POST capture") logger.info("\n" + tabulate(ep_only_in_post_capture, headers=[ "Tenant", "App Profile", "EPG", "MAC", "Stage", "Node", "Interface", "Encap" ], tablefmt="grid")) # Check if the --summary option is enabled if detailed_summary: print_header( "(Moved/PRE/POST) Category entries that have a total greater than: {}" .format(detailed_summary_number)) logger.debug(ep_category_summary) ep_summary_data = "" # String object to print out detailed summary that will be built using code below # Loop through EP Categories to then be stored in the string object "ep_summary_data" for category, entries in ep_category_summary.iteritems(): ep_summary_data += "\n" + category.upper() + "\n" # Then loop through each item within each category to highlight the particular Tenant/App/EPG/MAC/Encap for item, number in entries.iteritems(): # Check if the current entry has a value greater than or equal to the value specified on the CLI if number >= detailed_summary_number: ep_summary_data += "{:6} == {}\n".format(number, item) # Also provide a tally of the total amount of EPs that are in BOTH / PRE / POST - as identified grand_total_eps = ep_summary["both"] + ep_summary[ "pre"] + ep_summary["post"] ep_summary_data += "\nGRAND TOTAL\n" ep_summary_data += "{:6} EPs across all captures\n".format( grand_total_eps) logger.info(ep_summary_data) # Print out the data print_header("Summary") # Structure of ep_summary{'pre': 11, 'post': 15, 'compare_ep_move_PRE.json': 11, 'compare_ep_move_POST.json': 15} for key, value in sorted(ep_summary.iteritems(), reverse=True): # Loop through dictionary and find if they are the .JSON filenames if "json" in key: if "pre" in key: # Check for _PRE logger.info("PRE Filename: {}".format(key)) logger.info(" Endpoints read: {}".format(value)) logger.info(" Captured on: {}\n".format( ep_analysis_time["pre"])) elif "post" in key: # Check for _POST logger.info("POST Filename: {}".format(key)) logger.info(" Endpoints read: {}".format(value)) logger.info(" Captured on: {}\n".format( ep_analysis_time["post"])) else: logger.warning( "ERROR with determiniation of PRE/POST filename in ep_summary" ) # Print out analysis logger.info("Endpoints with movement: {}".format(ep_summary["both"])) logger.info("Endpoints only in PRE: {}".format(ep_summary["pre"])) logger.info("Endpoints only in POST: {}\n".format(ep_summary["post"])) if args.log: logger.info("Log file written: {}\n".format(logging_filename)) else: logger.critical( "\nSomething wrong with your selections. Please try again or use the --help option\n" ) creds.print_help() finish_time = time.time() # Calculate finish time logger.info("#" * 80) logger.info("Started analysis @ {}".format( time.asctime(time.localtime(start_time)))) logger.info("Ended analysis @ {}".format( time.asctime(time.localtime(finish_time)))) logger.info("--- Total Execution Time: %s seconds ---" % (finish_time - start_time)) logger.info("#" * 80)
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 Interfaces.' creds = Credentials('apic', description) creds.add_argument('--tenant', help='The name of Tenant') 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) resp = session.get('/api/class/ipv4Addr.json') intfs = json.loads(resp.text)['imdata'] for i in intfs: ip = i['ipv4Addr']['attributes']['addr'] op = i['ipv4Addr']['attributes']['operSt'] cfg = i['ipv4Addr']['attributes']['operStQual'] dn = i['ipv4Addr']['attributes']['dn'] node = dn.split('/')[2] intf = re.split(r'\[|\]', dn)[1] vrf = re.split(r'/|dom-', dn)[7] tn = vrf if vrf.find(":") != -1: tn = re.search("(.*):(.*)", vrf).group(1) check_longest_name(node, "Node") check_longest_name(intf, "Interface") check_longest_name(ip, "IP Address") check_longest_name(cfg, "Admin Status") check_longest_name(op, "Status") if args.tenant is None: if vrf not in data.keys(): data[vrf] = [] else: data[vrf].append((node, intf, ip, cfg, op)) else: if tn == args.tenant: if vrf not in data.keys(): data[vrf] = [] else: data[vrf].append((node, intf, ip, cfg, op)) for k in data.keys(): header = 'IP Interface Status for VRF "{}"'.format(k) print(header) template = '{0:' + str(longest_names["Node"]) + '} ' \ '{1:' + str(longest_names["Interface"]) + '} ' \ '{2:' + str(longest_names["IP Address"]) + '} ' \ '{3:' + str(longest_names["Admin Status"]) + '} ' \ '{4:' + str(longest_names["Status"]) + '}' print(template.format("Node", "Interface", "IP Address", "Admin Status", "Status")) print(template.format('-' * longest_names["Node"], '-' * longest_names["Interface"], '-' * longest_names["IP Address"], '-' * longest_names["Admin Status"], '-' * longest_names["Status"])) for rec in sorted(data[k]): print(template.format(*rec)) print('')
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 = ( 'Application dealing with tenant configuration. ' 'It can download a tenant configuration from the APIC and store it as raw JSON in a file. ' 'It can also push a tenant configuration stored as raw JSON in a file to the APIC.' ) creds = Credentials(('apic', 'nosnapshotfiles'), description) creds.add_argument( '--config', default=None, help='Configuration file to push/pull tenant configuration') creds.add_argument('--tenant', default=None, help='Tenant name') group = creds.add_mutually_exclusive_group() group.add_argument('--push-to-apic', action='store_true', help='Push the tenant configuration file to the APIC') group.add_argument('--pull-from-apic', action='store_true', help=('Pull the tenant configuration from the APIC and' 'store in the specified configuration file')) # Get the command line arguments args = creds.get() # Sanity check the command line arguments if args.config is None: print '%% No configuration file given.' creds.print_help() return if args.tenant is None: print '%% No Tenant name given.' creds.print_help() return if not args.push_to_apic and not args.pull_from_apic: print '%% No direction (push-to-apic/pull-from-apic) given.' creds.print_help() return # Login to APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print '%% Could not login to APIC' return # Do the work if args.pull_from_apic: pull_config_from_apic(session, args.tenant, args.config) if args.push_to_apic: push_config_to_apic(session, args.tenant, args.config)
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 = ('Application dealing with tenant configuration. ' 'It can download a tenant configuration from the APIC and store it as raw JSON in a file. ' 'It can also push a tenant configuration stored as raw JSON in a file to the APIC.') creds = Credentials(('apic', 'nosnapshotfiles'), description) creds.add_argument('--config', default=None, help='Configuration file to push/pull tenant configuration') creds.add_argument('--tenant', default=None, help='Tenant name') group = creds.add_mutually_exclusive_group() group.add_argument('--push-to-apic', action='store_true', help='Push the tenant configuration file to the APIC') group.add_argument('--pull-from-apic', action='store_true', help=('Pull the tenant configuration from the APIC and' 'store in the specified configuration file')) # Get the command line arguments args = creds.get() # Sanity check the command line arguments if args.config is None: print '%% No configuration file given.' creds.print_help() return if args.tenant is None: print '%% No Tenant name given.' creds.print_help() return if not args.push_to_apic and not args.pull_from_apic: print '%% No direction (push-to-apic/pull-from-apic) given.' creds.print_help() return # Login to APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print '%% Could not login to APIC' return # Do the work if args.pull_from_apic: pull_config_from_apic(session, args.tenant, args.config) if args.push_to_apic: push_config_to_apic(session, args.tenant, args.config)
def main(): """ Main create tenant routine :return: None """ # Get all the arguments description = 'It logs in to the APIC and will delete tenants named with the specified string.' creds = Credentials(['apic', 'nosnapshotfiles'], description) group = creds.add_mutually_exclusive_group() group.add_argument('--startswith', default=None, help='String to match that starts the tenant name') group.add_argument('--endswith', default=None, help='String to match that ends the tenant name') group.add_argument('--exactmatch', default=None, help='String that exactly matches the tenant name') group.add_argument('--contains', default=None, help='String that is contained in the tenant name') creds.add_argument( '--force', action='store_true', help='Attempt to remove the tenants without prompting for confirmation' ) args = creds.get() # Login to the APIC apic = Session(args.url, args.login, args.password) resp = apic.login() if not resp.ok: print('%% Could not login to APIC') # Get all of the Tenants tenants = Tenant.get(apic) # Find the list of Tenants to delete according to command line options tenants_to_delete = [] for tenant in tenants: if args.startswith is not None: if tenant.name.startswith(args.startswith): tenants_to_delete.append(tenant) elif args.endswith is not None: if tenant.name.endswith(args.endswith): tenants_to_delete.append(tenant) elif args.exactmatch is not None: if args.exactmatch == tenant.name: tenants_to_delete.append(tenant) elif args.contains is not None: if args.contains in tenant.name: tenants_to_delete.append(tenant) # Query the user to be sure of deletion if not args.force: for tenant in tenants_to_delete: prompt = 'Delete tenant %s ? [y/N]' % tenant.name try: resp = raw_input(prompt) except NameError: resp = input(prompt) if not resp.lower().startswith('y'): tenants_to_delete.remove(tenant) print('Skipping tenant', tenant.name) # Delete the tenants for tenant in tenants_to_delete: tenant.mark_as_deleted() resp = tenant.push_to_apic(apic) if resp.ok: print('Deleted tenant', tenant.name) else: print('Could not delete tenant', tenant.name) print resp.text
import sys import re import json import csv import re from acitoolkit import Credentials, Session #Take login credentials from the command line if provided # Otherwise, take them from your environment variables file ~/.profile description = 'Application that logs on to the APIC, and extracts the EPG Static Paths for the user provided input Node ID' creds = Credentials('apic', description) creds.add_argument('--tenant', help='The name of Tenant') 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) while True: try: inputnode = input("Enter the Node ID: ") if (len(inputnode) == 4): nodeidint = int(inputnode) break else: print("Node ID is INVALID ! try again") continue except ValueError:
print 'Writing results to a file....' try: with open('static/epgs.json', 'w') as epg_file: epg_file.write(json.dumps(epgs)) except IOError: print '%% Unable to open configuration file', 'static/epgs.json' sys.exit(0) except ValueError: print '%% File could not be decoded as JSON.' sys.exit(0) @flask_app.route('/') def index(): """ Displays the index page accessible at '/' """ return flask.render_template('bubble-tooltips.html') if __name__ == '__main__': creds = Credentials(('apic', 'server'), 'Endpoints per EPG bubble chart visualization') args = creds.get() print 'Getting data from APIC....' get_data_from_apic(args.url, args.login, args.password) print 'Running server. Point your browser to http://%s:%s' % (args.ip, args.port) flask_app.run(debug=False, host=args.ip, port=int(args.port))
tabs[k]['class'], tabs[k]['properties'], headers=tabs.get(k).get('headers')) tenants = class_query(session, 'fvTenant') for t in tenants: createTenantSheet(session,workbook,t) workbook.close() if __name__ == "__main__": description = 'aci-doc' # Gather credentials for ACI creds = Credentials('apic', description) args = creds.get() # Establish an API session to the APIC apic = Session(args.url, args.login, args.password) if apic.login().ok: print("Connected to ACI") print("depending on your configuration, this could take a little while...") with open('config.yaml', 'r') as config: config = yaml.safe_load(config) CreateWorkBook(apic, config['filename'], config['tabs'])