13 from novaclient import client as openstackclient
14 from kubernetes import client, config
15 from netaddr import IPAddress, IPNetwork
18 #############################################################################################
19 # Start: configurations that you must change for a new ONAP installation
20 external_net_addr = '10.12.0.0'
21 external_net_prefix_len = 16
22 #############################################################################################
23 # set the openstack cloud access credentials here
27 '--os-auth-url': 'http://10.12.25.2:5000',
28 '--os-username': 'kxi',
29 '--os-user-domain-id': 'default',
30 '--os-project-domain-id': 'default',
31 '--os-tenant-id': 'bc43d50ffcb84750bac0c1707a9a765b' if oom_mode else '1e097c6713e74fd7ac8e4295e605ee1e',
32 '--os-region-name': 'RegionOne',
33 '--os-password': 'n3JhGMGuDzD8',
34 '--os-project-domain-name': 'Integration-SB-03' if oom_mode else 'Integration-SB-07',
35 '--os-identity-api-version': '3'
38 common_preload_config = {
39 'oam_onap_net': 'oam_network_2No2' if oom_mode else 'oam_onap_lAky',
40 'oam_onap_subnet': 'oam_network_2No2' if oom_mode else 'oam_onap_lAky',
41 'public_net': 'external',
42 'public_net_id': '971040b2-7059-49dc-b220-4fab50cb2ad4'
44 sdnc_controller_pod = 'dev-sdnc-sdnc-0'
46 #############################################################################################
48 template_variable_symbol = '${'
49 cpe_vm_prefix = 'zdcpe'
50 #############################################################################################
51 # preloading network config
53 # value = [subnet_start_ip, subnet_gateway_ip]
54 preload_network_config = {
55 'cpe_public': ['10.2.0.2', '10.2.0.1'],
56 'cpe_signal': ['10.4.0.2', '10.4.0.1'],
57 'brg_bng': ['10.3.0.2', '10.3.0.1'],
58 'bng_mux': ['10.1.0.10', '10.1.0.1'],
59 'mux_gw': ['10.5.0.10', '10.5.0.1']
62 dcae_ves_collector_name = 'dcae-bootstrap'
63 global_subscriber_id = 'SDN-ETHERNET-INTERNET'
64 project_name = 'Project-Demonstration'
65 owning_entity_id = '520cc603-a3c4-4ec2-9ef4-ca70facd79c0'
66 owning_entity_name = 'OE-Demonstration1'
68 def __init__(self, extra_host_names=None):
69 rootlogger = logging.getLogger()
70 handler = logging.StreamHandler()
71 formatter = logging.Formatter('%(asctime)s %(levelname)s %(name)s.%(funcName)s(): %(message)s')
72 handler.setFormatter(formatter)
73 rootlogger.addHandler(handler)
74 rootlogger.setLevel(logging.INFO)
76 self.logger = logging.getLogger(__name__)
77 self.logger.propagate = False
78 self.logger.addHandler(handler)
79 self.logger.setLevel(logging.DEBUG)
80 self.logger.info('Initializing configuration')
82 # CHANGEME: vgw_VfModuleModelInvariantUuid is in rescust service csar, look in service-VcpesvcRescust1118-template.yml for groups vgw module metadata. TODO: read this value automcatically
83 self.vgw_VfModuleModelInvariantUuid = '26d6a718-17b2-4ba8-8691-c44343b2ecd2'
84 # CHANGEME: OOM: this is the address that the brg and bng will nat for sdnc access - 10.0.0.x address of k8 host for sdnc-0 container
85 self.sdnc_oam_ip = self.get_pod_node_oam_ip('sdnc-sdnc-0')
86 # CHANGEME: OOM: this is a k8s host external IP, e.g. oom-k8s-01 IP
87 self.oom_so_sdnc_aai_ip = self.get_pod_node_public_ip('sdnc-sdnc-0')
88 # CHANGEME: OOM: this is a k8s host external IP, e.g. oom-k8s-01 IP
89 self.oom_dcae_ves_collector = self.oom_so_sdnc_aai_ip
90 # CHANGEME: OOM: this is a k8s host external IP, e.g. oom-k8s-01 IP
91 self.mr_ip_addr = self.oom_so_sdnc_aai_ip
92 self.mr_ip_port = '30227'
93 self.so_nbi_port = '30277' if self.oom_mode else '8080'
94 self.sdnc_preloading_port = '30202' if self.oom_mode else '8282'
95 self.aai_query_port = '30233' if self.oom_mode else '8443'
96 self.sniro_port = '30288' if self.oom_mode else '8080'
98 self.host_names = ['sdc', 'so', 'sdnc', 'robot', 'aai-inst1', self.dcae_ves_collector_name]
100 self.host_names.extend(extra_host_names)
102 self.hosts = self.get_vm_ip(self.host_names, self.external_net_addr, self.external_net_prefix_len)
103 # this is the keyword used to name vgw stack, must not be used in other stacks
104 self.vgw_name_keyword = 'base_vcpe_vgw'
105 # this is the file that will keep the index of last assigned SO name
106 self.vgw_vfmod_name_index_file= '__var/vgw_vfmod_name_index'
107 self.svc_instance_uuid_file = '__var/svc_instance_uuid'
108 self.preload_dict_file = '__var/preload_dict'
109 self.vgmux_vnf_name_file = '__var/vgmux_vnf_name'
110 self.product_family_id = 'f9457e8c-4afd-45da-9389-46acd9bf5116'
111 self.custom_product_family_id = 'a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb'
112 self.instance_name_prefix = {
113 'service': 'vcpe_svc',
114 'network': 'vcpe_net',
116 'vfmodule': 'vcpe_vfmodule'
118 self.aai_userpass = 'AAI', 'AAI'
119 self.pub_key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKXDgoo3+WOqcUG8/5uUbk81+yczgwC4Y8ywTmuQqbNxlY1oQ0YxdMUqUnhitSXs5S/yRuAVOYHwGg2mCs20oAINrP+mxBI544AMIb9itPjCtgqtE2EWo6MmnFGbHB4Sx3XioE7F4VPsh7japsIwzOjbrQe+Mua1TGQ5d4nfEOQaaglXLLPFfuc7WbhbJbK6Q7rHqZfRcOwAMXgDoBqlyqKeiKwnumddo2RyNT8ljYmvB6buz7KnMinzo7qB0uktVT05FH9Rg0CTWH5norlG5qXgP2aukL0gk1ph8iAt7uYLf1ktp+LJI2gaF6L0/qli9EmVCSLr1uJ38Q8CBflhkh'
120 self.os_tenant_id = self.cloud['--os-tenant-id']
121 self.os_region_name = self.cloud['--os-region-name']
122 self.common_preload_config['pub_key'] = self.pub_key
123 self.sniro_url = 'http://' + self.hosts['robot'] + ':' + self.sniro_port + '/__admin/mappings'
124 self.sniro_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
125 self.homing_solution = 'sniro' # value is either 'sniro' or 'oof'
126 # self.homing_solution = 'oof'
127 self.customer_location_used_by_oof = {
128 "customerLatitude": "32.897480",
129 "customerLongitude": "-97.040443",
130 "customerName": "some_company"
133 #############################################################################################
135 self.sdc_be_port = '30205'
136 self.sdc_be_request_userpass = 'vid', 'Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U'
137 self.sdc_be_request_headers = {'X-ECOMP-InstanceID': 'VID'}
138 self.sdc_be_url_prefix = 'http://' + self.hosts['sdc'] + ':' + self.sdc_be_port
139 self.sdc_service_list_url = self.sdc_be_url_prefix + '/sdc/v1/catalog/services'
141 self.sdc_fe_port = '30206'
142 self.sdc_fe_request_userpass = 'beep', 'boop'
143 self.sdc_fe_request_headers = {'USER_ID': 'demo', 'Content-Type': 'application/json'}
144 self.sdc_fe_url_prefix = 'http://' + self.hosts['sdc'] + ':' + self.sdc_fe_port
145 self.sdc_get_category_list_url = self.sdc_fe_url_prefix + '/sdc1/feProxy/rest/v1/categories'
146 self.sdc_create_allotted_resource_subcategory_url = self.sdc_fe_url_prefix + '/sdc1/feProxy/rest/v1/category/resources/resourceNewCategory.allotted%20resource/subCategory'
148 #############################################################################################
150 self.sdnc_userpass = 'admin', 'Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U'
151 self.sdnc_db_name = 'sdnctl'
152 self.sdnc_db_user = 'sdnctl'
153 self.sdnc_db_pass = 'gamma'
154 self.sdnc_db_port = '32774'
155 self.sdnc_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
156 self.sdnc_preload_network_url = 'http://' + self.hosts['sdnc'] + \
157 ':' + self.sdnc_preloading_port + '/restconf/operations/VNF-API:preload-network-topology-operation'
158 self.sdnc_preload_vnf_url = 'http://' + self.hosts['sdnc'] + \
159 ':' + self.sdnc_preloading_port + '/restconf/operations/VNF-API:preload-vnf-topology-operation'
160 self.sdnc_preload_gra_url = 'http://' + self.hosts['sdnc'] + \
161 ':' + self.sdnc_preloading_port + '/restconf/operations/GENERIC-RESOURCE-API:preload-vf-module-topology-operation'
162 self.sdnc_ar_cleanup_url = 'http://' + self.hosts['sdnc'] + ':' + self.sdnc_preloading_port + \
163 '/restconf/config/GENERIC-RESOURCE-API:'
165 #############################################################################################
166 # SO urls, note: do NOT add a '/' at the end of the url
167 self.so_req_api_url = {'v4': 'http://' + self.hosts['so'] + ':' + self.so_nbi_port + '/onap/so/infra/serviceInstantiation/v7/serviceInstances',
168 'v5': 'http://' + self.hosts['so'] + ':' + self.so_nbi_port + '/onap/so/infra/serviceInstantiation/v7/serviceInstances'}
169 self.so_check_progress_api_url = 'http://' + self.hosts['so'] + ':' + self.so_nbi_port + '/onap/so/infra/orchestrationRequests/v6'
170 self.so_userpass = 'InfraPortalClient', 'password1$'
171 self.so_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
172 self.so_db_name = 'catalogdb'
173 self.so_db_user = 'root'
174 self.so_db_pass = 'password'
175 self.so_db_port = '30252' if self.oom_mode else '32769'
177 self.vpp_inf_url = 'http://{0}:8183/restconf/config/ietf-interfaces:interfaces'
178 self.vpp_api_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
179 self.vpp_api_userpass = ('admin', 'admin')
180 self.vpp_ves_url= 'http://{0}:8183/restconf/config/vesagent:vesagent'
182 def headbridge(self, openstack_stack_name, svc_instance_uuid):
184 Add vserver information to AAI
186 self.logger.info('Adding vServer information to AAI for {0}'.format(openstack_stack_name))
187 if not self.oom_mode:
188 cmd = '/opt/demo.sh heatbridge {0} {1} vCPE'.format(openstack_stack_name, svc_instance_uuid)
189 ret = commands.getstatusoutput("ssh -i onap_dev root@{0} '{1}'".format(self.hosts['robot'], cmd))
190 self.logger.debug('%s', ret)
192 print('To add vGMUX vserver info to AAI, do the following:')
193 print('- ssh to rancher')
195 print('- cd /root/oom/kubernetes/robot')
196 print('- ./demo-k8s.sh onap heatbridge {0} {1} vCPE'.format(openstack_stack_name, svc_instance_uuid))
198 def get_brg_mac_from_sdnc(self):
200 Check table DHCP_MAP in the SDNC DB. Find the newly instantiated BRG MAC address.
201 Note that there might be multiple BRGs, the most recently instantiated BRG always has the largest IP address.
203 cnx = mysql.connector.connect(user=self.sdnc_db_user, password=self.sdnc_db_pass, database=self.sdnc_db_name,
204 host=self.hosts['sdnc'], port=self.sdnc_db_port)
205 cursor = cnx.cursor()
206 query = "SELECT * from DHCP_MAP"
207 cursor.execute(query)
209 self.logger.debug('DHCP_MAP table in SDNC')
212 for mac, ip in cursor:
213 self.logger.debug(mac + ':' + ip)
214 this_host = int(ip.split('.')[-1])
224 def execute_cmds_sdnc_db(self, cmds):
225 self.execute_cmds_db(cmds, self.sdnc_db_user, self.sdnc_db_pass, self.sdnc_db_name,
226 self.hosts['sdnc'], self.sdnc_db_port)
228 def execute_cmds_so_db(self, cmds):
229 self.execute_cmds_db(cmds, self.so_db_user, self.so_db_pass, self.so_db_name,
230 self.hosts['so'], self.so_db_port)
232 def execute_cmds_db(self, cmds, dbuser, dbpass, dbname, host, port):
233 cnx = mysql.connector.connect(user=dbuser, password=dbpass, database=dbname, host=host, port=port)
234 cursor = cnx.cursor()
236 self.logger.debug(cmd)
238 self.logger.debug('%s', cursor)
243 def find_file(self, file_name_keyword, file_ext, search_dir):
245 :param file_name_keyword: keyword used to look for the csar file, case insensitive matching, e.g, infra
246 :param file_ext: e.g., csar, json
247 :param search_dir path to search
248 :return: path name of the file
250 file_name_keyword = file_name_keyword.lower()
251 file_ext = file_ext.lower()
252 if not file_ext.startswith('.'):
253 file_ext = '.' + file_ext
256 for file_name in os.listdir(search_dir):
257 file_name_lower = file_name.lower()
258 if file_name_keyword in file_name_lower and file_name_lower.endswith(file_ext):
260 self.logger.error('Multiple files found for *{0}*.{1} in '
261 'directory {2}'.format(file_name_keyword, file_ext, search_dir))
263 filenamepath = os.path.abspath(os.path.join(search_dir, file_name))
268 self.logger.error("Cannot find *{0}*{1} in directory {2}".format(file_name_keyword, file_ext, search_dir))
272 def network_name_to_subnet_name(network_name):
274 :param network_name: example: vcpe_net_cpe_signal_201711281221
275 :return: vcpe_net_cpe_signal_subnet_201711281221
277 fields = network_name.split('_')
278 fields.insert(-1, 'subnet')
279 return '_'.join(fields)
281 def set_network_name(self, network_name):
282 param = ' '.join([k + ' ' + v for k, v in self.cloud.items()])
283 openstackcmd = 'openstack ' + param
284 cmd = ' '.join([openstackcmd, 'network set --name', network_name, 'ONAP-NW1'])
287 def set_subnet_name(self, network_name):
289 Example: network_name = vcpe_net_cpe_signal_201711281221
290 set subnet name to vcpe_net_cpe_signal_subnet_201711281221
293 param = ' '.join([k + ' ' + v for k, v in self.cloud.items()])
294 openstackcmd = 'openstack ' + param
296 # expected results: | subnets | subnet_id |
297 subnet_info = os.popen(openstackcmd + ' network show ' + network_name + ' |grep subnets').read().split('|')
298 if len(subnet_info) > 2 and subnet_info[1].strip() == 'subnets':
299 subnet_id = subnet_info[2].strip()
300 subnet_name = self.network_name_to_subnet_name(network_name)
301 cmd = ' '.join([openstackcmd, 'subnet set --name', subnet_name, subnet_id])
303 self.logger.info("Subnet name set to: " + subnet_name)
306 self.logger.error("Can't get subnet info from network name: " + network_name)
309 def is_node_in_aai(self, node_type, node_uuid):
311 search_node_type = None
312 if node_type == 'service':
313 search_node_type = 'service-instance'
314 key = 'service-instance-id'
315 elif node_type == 'vnf':
316 search_node_type = 'generic-vnf'
319 logging.error('Invalid node_type: ' + node_type)
322 url = 'https://{0}:{1}/aai/v11/search/nodes-query?search-node-type={2}&filter={3}:EQUALS:{4}'.format(
323 self.hosts['aai-inst1'], self.aai_query_port, search_node_type, key, node_uuid)
325 headers = {'Content-Type': 'application/json', 'Accept': 'application/json', 'X-FromAppID': 'vCPE-Robot', 'X-TransactionId': 'get_aai_subscr'}
326 requests.packages.urllib3.disable_warnings()
327 r = requests.get(url, headers=headers, auth=self.aai_userpass, verify=False)
329 self.logger.debug('aai query: ' + url)
330 self.logger.debug('aai response:\n' + json.dumps(response, indent=4, sort_keys=True))
331 return 'result-data' in response
334 def extract_ip_from_str(net_addr, net_addr_len, sz):
336 :param net_addr: e.g. 10.5.12.0
337 :param net_addr_len: e.g. 24
339 :return: the first IP address matching the network, e.g. 10.5.12.3
341 network = ipaddress.ip_network(unicode('{0}/{1}'.format(net_addr, net_addr_len)), strict=False)
342 ip_list = re.findall(r'[0-9]+(?:\.[0-9]+){3}', sz)
344 this_net = ipaddress.ip_network(unicode('{0}/{1}'.format(ip, net_addr_len)), strict=False)
345 if this_net == network:
349 def get_pod_node_oam_ip(self, pod):
351 :Assuming kubectl is available and configured by default config (~/.kube/config)
352 :param pod: pod name substring, e.g. 'sdnc-sdnc-0'
353 :return pod's cluster node oam ip (10.0.0.0/16)
356 config.load_kube_config()
357 api = client.CoreV1Api()
358 kslogger = logging.getLogger('kubernetes')
359 kslogger.setLevel(logging.INFO)
360 res = api.list_pod_for_all_namespaces()
362 if pod in i.metadata.name:
363 self.logger.debug("found {0}\t{1}\t{2}".format(i.metadata.name, i.status.host_ip, i.spec.node_name))
364 ret = i.status.host_ip
368 ret = raw_input("Enter sdnc-sdnc-0 pod cluster node OAM IP address(10.0.0.0/16): ")
371 def get_pod_node_public_ip(self, pod):
373 :Assuming kubectl is available and configured by default config (~/.kube/config)
374 :param pod: pod name substring, e.g. 'sdnc-sdnc-0'
375 :return pod's cluster node public ip (i.e. 10.12.0.0/16)
378 config.load_kube_config()
379 api = client.CoreV1Api()
380 kslogger = logging.getLogger('kubernetes')
381 kslogger.setLevel(logging.INFO)
382 res = api.list_pod_for_all_namespaces()
384 if pod in i.metadata.name:
385 ret = self.get_vm_public_ip_by_nova(i.spec.node_name)
386 self.logger.debug("found node {0} public ip: {1}".format(i.spec.node_name, ret))
390 ret = raw_input("Enter sdnc-sdnc-0 pod cluster node public IP address(i.e. 10.12.0.0/16): ")
393 def get_vm_public_ip_by_nova(self, vm):
395 This method uses openstack nova api to retrieve vm public ip
399 subnet = IPNetwork('{0}/{1}'.format(self.external_net_addr, self.external_net_prefix_len))
400 nova = openstackclient.Client(2, self.cloud['--os-username'], self.cloud['--os-password'], self.cloud['--os-tenant-id'], self.cloud['--os-auth-url'])
401 for i in nova.servers.list():
403 for k, v in i.networks.items():
405 if IPAddress(ip) in subnet:
409 def get_vm_ip(self, keywords, net_addr=None, net_addr_len=None):
411 :param keywords: list of keywords to search for vm, e.g. ['bng', 'gmux', 'brg']
412 :param net_addr: e.g. 10.12.5.0
413 :param net_addr_len: e.g. 24
414 :return: dictionary {keyword: ip}
417 net_addr = self.external_net_addr
420 net_addr_len = self.external_net_prefix_len
422 param = ' '.join([k + ' ' + v for k, v in self.cloud.items() if 'identity' not in k])
423 openstackcmd = 'nova ' + param + ' list'
424 self.logger.debug(openstackcmd)
426 results = os.popen(openstackcmd).read()
427 all_vm_ip_dict = self.extract_vm_ip_as_dict(results, net_addr, net_addr_len)
428 latest_vm_list = self.remove_old_vms(all_vm_ip_dict.keys(), self.cpe_vm_prefix)
429 latest_vm_ip_dict = {vm: all_vm_ip_dict[vm] for vm in latest_vm_list}
430 ip_dict = self.select_subset_vm_ip(latest_vm_ip_dict, keywords)
432 ip_dict.update(self.get_oom_onap_vm_ip(keywords))
434 if len(ip_dict) != len(keywords):
435 self.logger.error('Cannot find all desired IP addresses for %s.', keywords)
436 self.logger.error(json.dumps(ip_dict, indent=4, sort_keys=True))
437 self.logger.error('Temporarily continue.. remember to check back vcpecommon.py line: 396')
441 def get_oom_onap_vm_ip(self, keywords):
443 onap_vm_list = set(['sdc', 'so', 'sdnc', 'aai-inst1', 'robot', self.dcae_ves_collector_name])
445 if vm in onap_vm_list:
446 vm_ip[vm] = self.oom_so_sdnc_aai_ip
449 def extract_vm_ip_as_dict(self, novalist_results, net_addr, net_addr_len):
451 for line in novalist_results.split('\n'):
452 fields = line.split('|')
456 ip = self.extract_ip_from_str(net_addr, net_addr_len, ip_info)
457 vm_ip_dict[vm_name] = ip
461 def remove_old_vms(self, vm_list, prefix):
463 For vms with format name_timestamp, only keep the one with the latest timestamp.
465 zdcpe1cpe01brgemu01_201805222148 (drop this)
466 zdcpe1cpe01brgemu01_201805222229 (keep this)
467 zdcpe1cpe01gw01_201805162201
470 same_type_vm_dict = {}
472 fields = vm.split('_')
473 if vm.startswith(prefix) and len(fields) == 2 and len(fields[-1]) == len('201805222148') and fields[-1].isdigit():
474 if vm > same_type_vm_dict.get(fields[0], '0'):
475 same_type_vm_dict[fields[0]] = vm
477 new_vm_list.append(vm)
479 new_vm_list.extend(same_type_vm_dict.values())
482 def select_subset_vm_ip(self, all_vm_ip_dict, vm_name_keyword_list):
484 for keyword in vm_name_keyword_list:
485 for vm, ip in all_vm_ip_dict.items():
487 vm_ip_dict[keyword] = ip
491 def del_vgmux_ves_mode(self):
492 url = self.vpp_ves_url.format(self.hosts['mux']) + '/mode'
493 r = requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
494 self.logger.debug('%s', r)
496 def del_vgmux_ves_collector(self):
497 url = self.vpp_ves_url.format(self.hosts['mux']) + '/config'
498 r = requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
499 self.logger.debug('%s', r)
501 def set_vgmux_ves_collector(self ):
502 url = self.vpp_ves_url.format(self.hosts['mux'])
504 {'server-addr': self.hosts[self.dcae_ves_collector_name],
505 'server-port': '30235' if self.oom_mode else '8081',
506 'read-interval': '10',
510 r = requests.post(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass, json=data)
511 self.logger.debug('%s', r)
513 def set_vgmux_packet_loss_rate(self, lossrate, vg_vnf_instance_name):
514 url = self.vpp_ves_url.format(self.hosts['mux'])
516 {"working-mode": "demo",
517 "base-packet-loss": str(lossrate),
518 "source-name": vg_vnf_instance_name
521 r = requests.post(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass, json=data)
522 self.logger.debug('%s', r)
524 # return all the VxLAN interface names of BRG or vGMUX based on the IP address
525 def get_vxlan_interfaces(self, ip, print_info=False):
526 url = self.vpp_inf_url.format(ip)
527 self.logger.debug('url is this: %s', url)
528 r = requests.get(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
529 data = r.json()['interfaces']['interface']
532 if 'name' in inf and 'type' in inf and inf['type'] == 'v3po:vxlan-tunnel':
533 print(json.dumps(inf, indent=4, sort_keys=True))
535 return [inf['name'] for inf in data if 'name' in inf and 'type' in inf and inf['type'] == 'v3po:vxlan-tunnel']
537 # delete all VxLAN interfaces of each hosts
538 def delete_vxlan_interfaces(self, host_dic):
539 for host, ip in host_dic.items():
541 self.logger.info('{0}: Getting VxLAN interfaces'.format(host))
542 inf_list = self.get_vxlan_interfaces(ip)
546 self.logger.info("{0}: Deleting VxLAN crossconnect {1}".format(host, inf))
547 url = self.vpp_inf_url.format(ip) + '/interface/' + inf + '/v3po:l2'
548 requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
553 self.logger.info("{0}: Deleting VxLAN interface {1}".format(host, inf))
554 url = self.vpp_inf_url.format(ip) + '/interface/' + inf
555 requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
557 if len(self.get_vxlan_interfaces(ip)) > 0:
558 self.logger.error("Error deleting VxLAN from {0}, try to restart the VM, IP is {1}.".format(host, ip))
562 self.logger.info("{0}: no VxLAN interface found, nothing to delete".format(host))
566 def save_object(obj, filepathname):
567 with open(filepathname, 'wb') as fout:
568 pickle.dump(obj, fout)
571 def load_object(filepathname):
572 with open(filepathname, 'rb') as fin:
573 return pickle.load(fin)
576 def increase_ip_address_or_vni_in_template(vnf_template_file, vnf_parameter_name_list):
577 with open(vnf_template_file) as json_input:
578 json_data = json.load(json_input)
579 param_list = json_data['VNF-API:input']['VNF-API:vnf-topology-information']['VNF-API:vnf-parameters']
580 for param in param_list:
581 if param['vnf-parameter-name'] in vnf_parameter_name_list:
582 ipaddr_or_vni = param['vnf-parameter-value'].split('.')
583 number = int(ipaddr_or_vni[-1])
588 ipaddr_or_vni[-1] = str(number)
589 param['vnf-parameter-value'] = '.'.join(ipaddr_or_vni)
591 assert json_data is not None
592 with open(vnf_template_file, 'w') as json_output:
593 json.dump(json_data, json_output, indent=4, sort_keys=True)
595 def save_preload_data(self, preload_data):
596 self.save_object(preload_data, self.preload_dict_file)
598 def load_preload_data(self):
599 return self.load_object(self.preload_dict_file)
601 def save_vgmux_vnf_name(self, vgmux_vnf_name):
602 self.save_object(vgmux_vnf_name, self.vgmux_vnf_name_file)
604 def load_vgmux_vnf_name(self):
605 return self.load_object(self.vgmux_vnf_name_file)