def post_vn(self): """:input: func 'sec_zone_dict', 'leaf_dict' and local file 'post_vn.csv'. Make vn post payload. :return :Post virtual networks """ dict_set = PostVN.leaf_dict(self) with open('./csv/post_vn.csv', 'r') as file: reader = csv.reader(file) next(reader) for line in reader: vn_template = { "l3_connectivity": "l3Enabled", "label": line[0], "vn_type": line[1], "vn_id": line[2], "ipv4_subnet": line[4], "virtual_gateway_ipv4": line[5], "dhcp_service": line[6], "security_zone_id": PostVN.sec_zone_dict(self)[line[7]], } leaf_id_list = list(set([dict_set[0][hostname] \ for hostname in line[8].split(',')])) vn_template["bound_to"] = [{"system_id": leaf_id, "vlan_id": int(line[3])} \ for leaf_id in leaf_id_list] tag_type_dict = { group_label: line[9] for group_label in dict_set[1] } vn_template["default_endpoint_tag_types"] = tag_type_dict resp = AosApi().bp_vn_post(token, bp_id, address, vn_template) if 'id' in resp.keys(): print(line[0] + ' done') else: print(line[0] + ' ' + json.dumps(resp))
def install_package(self): """ Install IBA collector package under the following condition 'job state' == 'success' 'operation mode' == 'full_control' """ print('##### Install Package to Agents #####') agent_id_list = [] package_list = [ package['name'] for package in AosApi().packages_get( token, bp_id, address)['items'] ] for agent in AosApi().system_agents_get(token, bp_id, address)['items']: if agent['status']['operation_mode'] == 'full_control' and agent[ 'platform_status']['state'] == 'success': for package in package_list: if agent['platform_status']['platform'] in package: payload = { 'packages': package.split(), 'operation_mode': 'full_control' } resp = requests.patch('https://' + address + '/api/system-agents/' + agent['id'], headers={ 'AUTHTOKEN': token, 'Content-Type': 'application/json' }, data=json.dumps(payload), verify=False) if str(resp.status_code) == '202': print( '----- Request has been accepted for processing on ' + agent['device_facts']['hostname']) else: print('----- Error: Request is not accepted on ' + agent['device_facts']['hostname']) sys.exit() agent_id_list.append(agent['id']) time.sleep(5) """ Check package installed status """ while len(agent_id_list) != 0: system_agents = AosApi().system_agents_id_get( token, bp_id, address, agent_id_list[0]) for package in system_agents['status']['packages_installed']: if 'aosstdcollectors-custom' in package: agent_id_list.remove(agent_id_list[0]) print('----- Package installed on ' + system_agents['device_facts']['hostname']) else: print('----- Not installed yet ' + system_agents['device_facts']['hostname']) time.sleep(1) print('##### Done #####') time.sleep(1)
def leaf_dict(self): """:input: All leafs info from graph query. Make dict { leaf_hostname: id }. Redundancy group id overwrite the pair. Make set { link group label } :return: Touple ( dict, set ) """ sys_int_link = AosApi().bp_qe_post( token, bp_id, address, "node('system', name='leaf', role='leaf')\ .out('hosted_interfaces')\ .node('interface', name='int', if_type='ethernet')\ .out('link')\ .node('link', name='link', role='leaf_l2_server')") all_leaf_dict = { node['leaf']['hostname']:node['leaf']['id'] \ for node in sys_int_link['items'] } all_group_label = set( [node['link']['group_label'] for node in sys_int_link['items']]) for node in AosApi().bp_qe_post( token, bp_id, address, "node('redundancy_group', name='rg', rg_type='esi')\ .out('composed_of_systems')\ .node('system', name='leaf', role='leaf')\ ")['items']: all_leaf_dict[node['leaf']['hostname']] = node['rg']['id'] return all_leaf_dict, all_group_label
def sec_zone_dict(self): """:input: get security zone. Make dict { security_zone_label: security_zone_id }. :return: above dict. """ return { sec_zone['vrf_name']:sec_zone['id'] for sec_zone in \ AosApi().bp_security_zone_get(token, bp_id, address)['items'].values() }
def security_zone_id(self): """ :input: security_zone :return: security_zone_id """ for sec_zone in AosApi().bp_security_zone_get( token, bp_id, address)['items'].values(): if sec_zone['label'] == self.security_zone: return sec_zone['id']
def make_hostname_list(self): """ Save hostnames on local CSV file for changing hostname and label. """ with open('hostname_label.csv', 'w') as file: writer = csv.writer(file) writer.writerow( ['ID', 'System_ID', 'Role', 'Hostname', 'New Hostname or Label']) for node in AosApi().bp_qe_post(token, bp_id, address, "node('system', name='system', \ role=is_in(['leaf', 'spine', 'generic']))")['items']: node = node['system'] writer.writerow([node['id'], node['system_id'], node['role'], node['hostname']])
def endpoints(self): """ :return: Server Interface ID list logical(port-channel) and physical(ethernet) facing leafs. If a physical one is member of logical, only port-channel ID returned. """ interface_id = [] for server_host in self.server_list: int_sys_dict = { int_sys['interface']['if_type']:int_sys['interface']['id']\ for int_sys in AosApi().bp_qe_post(token, bp_id, address, "node('system', name='server', role='l2_server', hostname='" + server_host + "')\ .out('hosted_interfaces')\ .node('interface', name='interface')" \ )['items']} if len(int_sys_dict) == 2: interface_id.append(int_sys_dict['port_channel']) elif len(int_sys_dict) == 1: interface_id.append(int_sys_dict['ethernet']) return interface_id
def physical_leaf_list(self): """ :return: Leaf_ID list connected to 'server_list'. Use physical interface "if_type='ethernet'" not 'port_channel' in graph query at this time. Delete duplicate Leaf_ID in the list by 'list(set)'. """ return list(set([ AosApi().bp_qe_post(token, bp_id, address, "node('system', name='server', role='l2_server', hostname='" + server_host + "')\ .out('hosted_interfaces')\ .node('interface', name='server_int', if_type='ethernet')\ .out('link')\ .node('link', name='link')\ .in_('link')\ .node('interface', name='leaf_int')\ .in_('hosted_interfaces')\ .node('system', name='leaf')\ .ensure_different('server_int', 'leaf_int')"\ )['items'][0]['leaf']['id'] for server_host in PostVirtualNetwork.server(self) ]))
def patch_deploy_mode(self): """ Change server deploy mode. """ input_mode = input('deploy_mode:') if input_mode in shared.deploy_mode: payload = {'nodes': {}} for system in AosApi().bp_qe_post(token, bp_id, address, \ "node('system', name='system', system_type='server')")['items']: payload['nodes'][system['system']['id']] = { 'deploy_mode': input_mode } requests.patch('https://' + address + '/api/blueprints/{blueprint_id}'\ .format(blueprint_id = bp_id), headers = {'AUTHTOKEN': token, 'Content-Type': 'application/json'}, data=json.dumps(payload), verify=False) else: print('Error: Wrong deploy mode') sys.exit()
def logical_physical_leaf_list(self): """ :input: physical_leaf_list(self). :return: Leaf_ID list logical(mlag) and physical(not include member of mlag). 1. Create Dict { 'member of mlag system_id' : 'logical(mlag) system_id' } 2. if 'member of mlag' is in physical_leaf_list, then remove the id and append logical system_id instead. 3. Delete duplicate logical system_id in the list by 'list(set)'. :note: AOS push VN config except for VN endpoint to these system on other method. """ leaf_list = PostVirtualNetwork.physical_leaf_list(self) sys_rg_dict = { rg_sys['system']['id']:rg_sys['rg']['id'] \ for rg_sys in AosApi().bp_qe_post(token, bp_id, address, "node('redundancy_group', name='rg', rg_type='mlag')"\ ".out('composed_of_systems')"\ ".node('system', name='system', role='leaf')"\ )['items']} for system_id in sys_rg_dict.items(): if system_id[0] in leaf_list: leaf_list.remove(system_id[0]) leaf_list.append(system_id[1]) return list(set(leaf_list))
def get_nos_config(self): """ Save NOS configs of spine and leaf on local as zip file. """ os.makedirs('./nos_config', exist_ok=True) for system in AosApi().bp_qe_post(token, bp_id, address, \ "node('system', name='system', role=is_in(['leaf', 'spine']))")['items']: url = 'https://' + address \ + '/api/blueprints/{blueprint_id}/nodes/{node_id}/config-rendering'\ .format(blueprint_id = bp_id, node_id = system['system']['id']) with open('./nos_config/' + system['system']['hostname'] + '.conf', 'w') as config: print((requests.get(url, headers={ 'AUTHTOKEN': token, 'Content-Type': 'application/json' }, verify=False).json()['config']), file=config) now = re.sub('[ :]', '-', datetime.datetime.now().strftime("%Y-%m-%d %H:%M")) shutil.make_archive(now, 'zip', 'nos_config') shutil.rmtree('./nos_config/')