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 self.logger = logging.getLogger(__name__)
70 self.logger.setLevel(logging.DEBUG)
71 self.logger.info('Initializing configuration')
73 # CHANGEME: vgw_VfModuleModelInvariantUuid is in rescust service csar, look in service-VcpesvcRescust1118-template.yml for groups vgw module metadata. TODO: read this value automcatically
74 self.vgw_VfModuleModelInvariantUuid = '26d6a718-17b2-4ba8-8691-c44343b2ecd2'
75 # 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
76 self.sdnc_oam_ip = self.get_pod_node_oam_ip('sdnc-sdnc-0')
77 # CHANGEME: OOM: this is a k8s host external IP, e.g. oom-k8s-01 IP
78 self.oom_so_sdnc_aai_ip = self.get_pod_node_public_ip('sdnc-sdnc-0')
79 # CHANGEME: OOM: this is a k8s host external IP, e.g. oom-k8s-01 IP
80 self.oom_dcae_ves_collector = self.oom_so_sdnc_aai_ip
81 # CHANGEME: OOM: this is a k8s host external IP, e.g. oom-k8s-01 IP
82 self.mr_ip_addr = self.oom_so_sdnc_aai_ip
83 self.mr_ip_port = '30227'
84 self.so_nbi_port = '30277' if self.oom_mode else '8080'
85 self.sdnc_preloading_port = '30202' if self.oom_mode else '8282'
86 self.aai_query_port = '30233' if self.oom_mode else '8443'
87 self.sniro_port = '30288' if self.oom_mode else '8080'
89 self.host_names = ['sdc', 'so', 'sdnc', 'robot', 'aai-inst1', self.dcae_ves_collector_name]
91 self.host_names.extend(extra_host_names)
93 self.hosts = self.get_vm_ip(self.host_names, self.external_net_addr, self.external_net_prefix_len)
94 # this is the keyword used to name vgw stack, must not be used in other stacks
95 self.vgw_name_keyword = 'base_vcpe_vgw'
96 # this is the file that will keep the index of last assigned SO name
97 self.vgw_vfmod_name_index_file= '__var/vgw_vfmod_name_index'
98 self.svc_instance_uuid_file = '__var/svc_instance_uuid'
99 self.preload_dict_file = '__var/preload_dict'
100 self.vgmux_vnf_name_file = '__var/vgmux_vnf_name'
101 self.product_family_id = 'f9457e8c-4afd-45da-9389-46acd9bf5116'
102 self.custom_product_family_id = 'a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb'
103 self.instance_name_prefix = {
104 'service': 'vcpe_svc',
105 'network': 'vcpe_net',
107 'vfmodule': 'vcpe_vfmodule'
109 self.aai_userpass = 'AAI', 'AAI'
110 self.pub_key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKXDgoo3+WOqcUG8/5uUbk81+yczgwC4Y8ywTmuQqbNxlY1oQ0YxdMUqUnhitSXs5S/yRuAVOYHwGg2mCs20oAINrP+mxBI544AMIb9itPjCtgqtE2EWo6MmnFGbHB4Sx3XioE7F4VPsh7japsIwzOjbrQe+Mua1TGQ5d4nfEOQaaglXLLPFfuc7WbhbJbK6Q7rHqZfRcOwAMXgDoBqlyqKeiKwnumddo2RyNT8ljYmvB6buz7KnMinzo7qB0uktVT05FH9Rg0CTWH5norlG5qXgP2aukL0gk1ph8iAt7uYLf1ktp+LJI2gaF6L0/qli9EmVCSLr1uJ38Q8CBflhkh'
111 self.os_tenant_id = self.cloud['--os-tenant-id']
112 self.os_region_name = self.cloud['--os-region-name']
113 self.common_preload_config['pub_key'] = self.pub_key
114 self.sniro_url = 'http://' + self.hosts['robot'] + ':' + self.sniro_port + '/__admin/mappings'
115 self.sniro_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
116 self.homing_solution = 'sniro' # value is either 'sniro' or 'oof'
117 # self.homing_solution = 'oof'
118 self.customer_location_used_by_oof = {
119 "customerLatitude": "32.897480",
120 "customerLongitude": "-97.040443",
121 "customerName": "some_company"
124 #############################################################################################
126 self.sdc_be_port = '30205'
127 self.sdc_be_request_userpass = 'vid', 'Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U'
128 self.sdc_be_request_headers = {'X-ECOMP-InstanceID': 'VID'}
129 self.sdc_be_url_prefix = 'http://' + self.hosts['sdc'] + ':' + self.sdc_be_port
130 self.sdc_service_list_url = self.sdc_be_url_prefix + '/sdc/v1/catalog/services'
132 self.sdc_fe_port = '30206'
133 self.sdc_fe_request_userpass = 'beep', 'boop'
134 self.sdc_fe_request_headers = {'USER_ID': 'demo', 'Content-Type': 'application/json'}
135 self.sdc_fe_url_prefix = 'http://' + self.hosts['sdc'] + ':' + self.sdc_fe_port
136 self.sdc_get_category_list_url = self.sdc_fe_url_prefix + '/sdc1/feProxy/rest/v1/categories'
137 self.sdc_create_allotted_resource_subcategory_url = self.sdc_fe_url_prefix + '/sdc1/feProxy/rest/v1/category/resources/resourceNewCategory.allotted%20resource/subCategory'
139 #############################################################################################
141 self.sdnc_userpass = 'admin', 'Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U'
142 self.sdnc_db_name = 'sdnctl'
143 self.sdnc_db_user = 'sdnctl'
144 self.sdnc_db_pass = 'gamma'
145 self.sdnc_db_port = '32774'
146 self.sdnc_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
147 self.sdnc_preload_network_url = 'http://' + self.hosts['sdnc'] + \
148 ':' + self.sdnc_preloading_port + '/restconf/operations/VNF-API:preload-network-topology-operation'
149 self.sdnc_preload_vnf_url = 'http://' + self.hosts['sdnc'] + \
150 ':' + self.sdnc_preloading_port + '/restconf/operations/VNF-API:preload-vnf-topology-operation'
151 self.sdnc_preload_gra_url = 'http://' + self.hosts['sdnc'] + \
152 ':' + self.sdnc_preloading_port + '/restconf/operations/GENERIC-RESOURCE-API:preload-vf-module-topology-operation'
153 self.sdnc_ar_cleanup_url = 'http://' + self.hosts['sdnc'] + ':' + self.sdnc_preloading_port + \
154 '/restconf/config/GENERIC-RESOURCE-API:'
156 #############################################################################################
157 # SO urls, note: do NOT add a '/' at the end of the url
158 self.so_req_api_url = {'v4': 'http://' + self.hosts['so'] + ':' + self.so_nbi_port + '/onap/so/infra/serviceInstantiation/v7/serviceInstances',
159 'v5': 'http://' + self.hosts['so'] + ':' + self.so_nbi_port + '/onap/so/infra/serviceInstantiation/v7/serviceInstances'}
160 self.so_check_progress_api_url = 'http://' + self.hosts['so'] + ':' + self.so_nbi_port + '/onap/so/infra/orchestrationRequests/v6'
161 self.so_userpass = 'InfraPortalClient', 'password1$'
162 self.so_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
163 self.so_db_name = 'catalogdb'
164 self.so_db_user = 'root'
165 self.so_db_pass = 'secretpassword'
166 self.so_db_port = '30252' if self.oom_mode else '32769'
168 self.vpp_inf_url = 'http://{0}:8183/restconf/config/ietf-interfaces:interfaces'
169 self.vpp_api_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
170 self.vpp_api_userpass = ('admin', 'admin')
171 self.vpp_ves_url= 'http://{0}:8183/restconf/config/vesagent:vesagent'
173 def headbridge(self, openstack_stack_name, svc_instance_uuid):
175 Add vserver information to AAI
177 self.logger.info('Adding vServer information to AAI for {0}'.format(openstack_stack_name))
178 if not self.oom_mode:
179 cmd = '/opt/demo.sh heatbridge {0} {1} vCPE'.format(openstack_stack_name, svc_instance_uuid)
180 ret = commands.getstatusoutput("ssh -i onap_dev root@{0} '{1}'".format(self.hosts['robot'], cmd))
181 self.logger.debug('%s', ret)
183 print('To add vGMUX vserver info to AAI, do the following:')
184 print('- ssh to rancher')
186 print('- cd /root/oom/kubernetes/robot')
187 print('- ./demo-k8s.sh onap heatbridge {0} {1} vCPE'.format(openstack_stack_name, svc_instance_uuid))
189 def get_brg_mac_from_sdnc(self):
191 Check table DHCP_MAP in the SDNC DB. Find the newly instantiated BRG MAC address.
192 Note that there might be multiple BRGs, the most recently instantiated BRG always has the largest IP address.
194 cnx = mysql.connector.connect(user=self.sdnc_db_user, password=self.sdnc_db_pass, database=self.sdnc_db_name,
195 host=self.hosts['sdnc'], port=self.sdnc_db_port)
196 cursor = cnx.cursor()
197 query = "SELECT * from DHCP_MAP"
198 cursor.execute(query)
200 self.logger.debug('DHCP_MAP table in SDNC')
203 for mac, ip in cursor:
204 self.logger.debug(mac + ':' + ip)
205 this_host = int(ip.split('.')[-1])
215 def execute_cmds_sdnc_db(self, cmds):
216 self.execute_cmds_db(cmds, self.sdnc_db_user, self.sdnc_db_pass, self.sdnc_db_name,
217 self.hosts['sdnc'], self.sdnc_db_port)
219 def execute_cmds_so_db(self, cmds):
220 self.execute_cmds_db(cmds, self.so_db_user, self.so_db_pass, self.so_db_name,
221 self.hosts['so'], self.so_db_port)
223 def execute_cmds_db(self, cmds, dbuser, dbpass, dbname, host, port):
224 cnx = mysql.connector.connect(user=dbuser, password=dbpass, database=dbname, host=host, port=port)
225 cursor = cnx.cursor()
227 self.logger.debug(cmd)
229 self.logger.debug('%s', cursor)
234 def find_file(self, file_name_keyword, file_ext, search_dir):
236 :param file_name_keyword: keyword used to look for the csar file, case insensitive matching, e.g, infra
237 :param file_ext: e.g., csar, json
238 :param search_dir path to search
239 :return: path name of the file
241 file_name_keyword = file_name_keyword.lower()
242 file_ext = file_ext.lower()
243 if not file_ext.startswith('.'):
244 file_ext = '.' + file_ext
247 for file_name in os.listdir(search_dir):
248 file_name_lower = file_name.lower()
249 if file_name_keyword in file_name_lower and file_name_lower.endswith(file_ext):
251 self.logger.error('Multiple files found for *{0}*.{1} in '
252 'directory {2}'.format(file_name_keyword, file_ext, search_dir))
254 filenamepath = os.path.abspath(os.path.join(search_dir, file_name))
259 self.logger.error("Cannot find *{0}*{1} in directory {2}".format(file_name_keyword, file_ext, search_dir))
263 def network_name_to_subnet_name(network_name):
265 :param network_name: example: vcpe_net_cpe_signal_201711281221
266 :return: vcpe_net_cpe_signal_subnet_201711281221
268 fields = network_name.split('_')
269 fields.insert(-1, 'subnet')
270 return '_'.join(fields)
272 def set_network_name(self, network_name):
273 param = ' '.join([k + ' ' + v for k, v in self.cloud.items()])
274 openstackcmd = 'openstack ' + param
275 cmd = ' '.join([openstackcmd, 'network set --name', network_name, 'ONAP-NW1'])
278 def set_subnet_name(self, network_name):
280 Example: network_name = vcpe_net_cpe_signal_201711281221
281 set subnet name to vcpe_net_cpe_signal_subnet_201711281221
284 param = ' '.join([k + ' ' + v for k, v in self.cloud.items()])
285 openstackcmd = 'openstack ' + param
287 # expected results: | subnets | subnet_id |
288 subnet_info = os.popen(openstackcmd + ' network show ' + network_name + ' |grep subnets').read().split('|')
289 if len(subnet_info) > 2 and subnet_info[1].strip() == 'subnets':
290 subnet_id = subnet_info[2].strip()
291 subnet_name = self.network_name_to_subnet_name(network_name)
292 cmd = ' '.join([openstackcmd, 'subnet set --name', subnet_name, subnet_id])
294 self.logger.info("Subnet name set to: " + subnet_name)
297 self.logger.error("Can't get subnet info from network name: " + network_name)
300 def is_node_in_aai(self, node_type, node_uuid):
302 search_node_type = None
303 if node_type == 'service':
304 search_node_type = 'service-instance'
305 key = 'service-instance-id'
306 elif node_type == 'vnf':
307 search_node_type = 'generic-vnf'
310 logging.error('Invalid node_type: ' + node_type)
313 url = 'https://{0}:{1}/aai/v11/search/nodes-query?search-node-type={2}&filter={3}:EQUALS:{4}'.format(
314 self.hosts['aai-inst1'], self.aai_query_port, search_node_type, key, node_uuid)
316 headers = {'Content-Type': 'application/json', 'Accept': 'application/json', 'X-FromAppID': 'vCPE-Robot', 'X-TransactionId': 'get_aai_subscr'}
317 requests.packages.urllib3.disable_warnings()
318 r = requests.get(url, headers=headers, auth=self.aai_userpass, verify=False)
320 self.logger.debug('aai query: ' + url)
321 self.logger.debug('aai response:\n' + json.dumps(response, indent=4, sort_keys=True))
322 return 'result-data' in response
325 def extract_ip_from_str(net_addr, net_addr_len, sz):
327 :param net_addr: e.g. 10.5.12.0
328 :param net_addr_len: e.g. 24
330 :return: the first IP address matching the network, e.g. 10.5.12.3
332 network = ipaddress.ip_network(unicode('{0}/{1}'.format(net_addr, net_addr_len)), strict=False)
333 ip_list = re.findall(r'[0-9]+(?:\.[0-9]+){3}', sz)
335 this_net = ipaddress.ip_network(unicode('{0}/{1}'.format(ip, net_addr_len)), strict=False)
336 if this_net == network:
340 def get_pod_node_oam_ip(self, pod):
342 :Assuming kubectl is available and configured by default config (~/.kube/config)
343 :param pod: pod name substring, e.g. 'sdnc-sdnc-0'
344 :return pod's cluster node oam ip (10.0.0.0/16)
347 config.load_kube_config()
348 api = client.CoreV1Api()
349 kslogger = logging.getLogger('kubernetes')
350 kslogger.setLevel(logging.INFO)
351 res = api.list_pod_for_all_namespaces()
353 if pod in i.metadata.name:
354 self.logger.debug("found {0}\t{1}\t{2}".format(i.metadata.name, i.status.host_ip, i.spec.node_name))
355 ret = i.status.host_ip
359 ret = raw_input("Enter sdnc-sdnc-0 pod cluster node OAM IP address(10.0.0.0/16): ")
362 def get_pod_node_public_ip(self, pod):
364 :Assuming kubectl is available and configured by default config (~/.kube/config)
365 :param pod: pod name substring, e.g. 'sdnc-sdnc-0'
366 :return pod's cluster node public ip (i.e. 10.12.0.0/16)
369 config.load_kube_config()
370 api = client.CoreV1Api()
371 kslogger = logging.getLogger('kubernetes')
372 kslogger.setLevel(logging.INFO)
373 res = api.list_pod_for_all_namespaces()
375 if pod in i.metadata.name:
376 ret = self.get_vm_public_ip_by_nova(i.spec.node_name)
377 self.logger.debug("found node {0} public ip: {1}".format(i.spec.node_name, ret))
381 ret = raw_input("Enter sdnc-sdnc-0 pod cluster node public IP address(i.e. 10.12.0.0/16): ")
384 def get_vm_public_ip_by_nova(self, vm):
386 This method uses openstack nova api to retrieve vm public ip
390 subnet = IPNetwork('{0}/{1}'.format(self.external_net_addr, self.external_net_prefix_len))
391 nova = openstackclient.Client(2, self.cloud['--os-username'], self.cloud['--os-password'], self.cloud['--os-tenant-id'], self.cloud['--os-auth-url'])
392 for i in nova.servers.list():
394 for k, v in i.networks.items():
396 if IPAddress(ip) in subnet:
400 def get_vm_ip(self, keywords, net_addr=None, net_addr_len=None):
402 :param keywords: list of keywords to search for vm, e.g. ['bng', 'gmux', 'brg']
403 :param net_addr: e.g. 10.12.5.0
404 :param net_addr_len: e.g. 24
405 :return: dictionary {keyword: ip}
408 net_addr = self.external_net_addr
411 net_addr_len = self.external_net_prefix_len
413 param = ' '.join([k + ' ' + v for k, v in self.cloud.items() if 'identity' not in k])
414 openstackcmd = 'nova ' + param + ' list'
415 self.logger.debug(openstackcmd)
417 results = os.popen(openstackcmd).read()
418 all_vm_ip_dict = self.extract_vm_ip_as_dict(results, net_addr, net_addr_len)
419 latest_vm_list = self.remove_old_vms(all_vm_ip_dict.keys(), self.cpe_vm_prefix)
420 latest_vm_ip_dict = {vm: all_vm_ip_dict[vm] for vm in latest_vm_list}
421 ip_dict = self.select_subset_vm_ip(latest_vm_ip_dict, keywords)
423 ip_dict.update(self.get_oom_onap_vm_ip(keywords))
425 if len(ip_dict) != len(keywords):
426 self.logger.error('Cannot find all desired IP addresses for %s.', keywords)
427 self.logger.error(json.dumps(ip_dict, indent=4, sort_keys=True))
428 self.logger.error('Temporarily continue.. remember to check back vcpecommon.py line: 396')
432 def get_oom_onap_vm_ip(self, keywords):
434 onap_vm_list = set(['sdc', 'so', 'sdnc', 'aai-inst1', 'robot', self.dcae_ves_collector_name])
436 if vm in onap_vm_list:
437 vm_ip[vm] = self.oom_so_sdnc_aai_ip
440 def extract_vm_ip_as_dict(self, novalist_results, net_addr, net_addr_len):
442 for line in novalist_results.split('\n'):
443 fields = line.split('|')
447 ip = self.extract_ip_from_str(net_addr, net_addr_len, ip_info)
448 vm_ip_dict[vm_name] = ip
452 def remove_old_vms(self, vm_list, prefix):
454 For vms with format name_timestamp, only keep the one with the latest timestamp.
456 zdcpe1cpe01brgemu01_201805222148 (drop this)
457 zdcpe1cpe01brgemu01_201805222229 (keep this)
458 zdcpe1cpe01gw01_201805162201
461 same_type_vm_dict = {}
463 fields = vm.split('_')
464 if vm.startswith(prefix) and len(fields) == 2 and len(fields[-1]) == len('201805222148') and fields[-1].isdigit():
465 if vm > same_type_vm_dict.get(fields[0], '0'):
466 same_type_vm_dict[fields[0]] = vm
468 new_vm_list.append(vm)
470 new_vm_list.extend(same_type_vm_dict.values())
473 def select_subset_vm_ip(self, all_vm_ip_dict, vm_name_keyword_list):
475 for keyword in vm_name_keyword_list:
476 for vm, ip in all_vm_ip_dict.items():
478 vm_ip_dict[keyword] = ip
482 def del_vgmux_ves_mode(self):
483 url = self.vpp_ves_url.format(self.hosts['mux']) + '/mode'
484 r = requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
485 self.logger.debug('%s', r)
487 def del_vgmux_ves_collector(self):
488 url = self.vpp_ves_url.format(self.hosts['mux']) + '/config'
489 r = requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
490 self.logger.debug('%s', r)
492 def set_vgmux_ves_collector(self ):
493 url = self.vpp_ves_url.format(self.hosts['mux'])
495 {'server-addr': self.hosts[self.dcae_ves_collector_name],
496 'server-port': '30235' if self.oom_mode else '8081',
497 'read-interval': '10',
501 r = requests.post(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass, json=data)
502 self.logger.debug('%s', r)
504 def set_vgmux_packet_loss_rate(self, lossrate, vg_vnf_instance_name):
505 url = self.vpp_ves_url.format(self.hosts['mux'])
507 {"working-mode": "demo",
508 "base-packet-loss": str(lossrate),
509 "source-name": vg_vnf_instance_name
512 r = requests.post(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass, json=data)
513 self.logger.debug('%s', r)
515 # return all the VxLAN interface names of BRG or vGMUX based on the IP address
516 def get_vxlan_interfaces(self, ip, print_info=False):
517 url = self.vpp_inf_url.format(ip)
518 self.logger.debug('url is this: %s', url)
519 r = requests.get(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
520 data = r.json()['interfaces']['interface']
523 if 'name' in inf and 'type' in inf and inf['type'] == 'v3po:vxlan-tunnel':
524 print(json.dumps(inf, indent=4, sort_keys=True))
526 return [inf['name'] for inf in data if 'name' in inf and 'type' in inf and inf['type'] == 'v3po:vxlan-tunnel']
528 # delete all VxLAN interfaces of each hosts
529 def delete_vxlan_interfaces(self, host_dic):
530 for host, ip in host_dic.items():
532 self.logger.info('{0}: Getting VxLAN interfaces'.format(host))
533 inf_list = self.get_vxlan_interfaces(ip)
537 self.logger.info("{0}: Deleting VxLAN crossconnect {1}".format(host, inf))
538 url = self.vpp_inf_url.format(ip) + '/interface/' + inf + '/v3po:l2'
539 requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
544 self.logger.info("{0}: Deleting VxLAN interface {1}".format(host, inf))
545 url = self.vpp_inf_url.format(ip) + '/interface/' + inf
546 requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
548 if len(self.get_vxlan_interfaces(ip)) > 0:
549 self.logger.error("Error deleting VxLAN from {0}, try to restart the VM, IP is {1}.".format(host, ip))
553 self.logger.info("{0}: no VxLAN interface found, nothing to delete".format(host))
557 def save_object(obj, filepathname):
558 with open(filepathname, 'wb') as fout:
559 pickle.dump(obj, fout)
562 def load_object(filepathname):
563 with open(filepathname, 'rb') as fin:
564 return pickle.load(fin)
567 def increase_ip_address_or_vni_in_template(vnf_template_file, vnf_parameter_name_list):
568 with open(vnf_template_file) as json_input:
569 json_data = json.load(json_input)
570 param_list = json_data['VNF-API:input']['VNF-API:vnf-topology-information']['VNF-API:vnf-parameters']
571 for param in param_list:
572 if param['vnf-parameter-name'] in vnf_parameter_name_list:
573 ipaddr_or_vni = param['vnf-parameter-value'].split('.')
574 number = int(ipaddr_or_vni[-1])
579 ipaddr_or_vni[-1] = str(number)
580 param['vnf-parameter-value'] = '.'.join(ipaddr_or_vni)
582 assert json_data is not None
583 with open(vnf_template_file, 'w') as json_output:
584 json.dump(json_data, json_output, indent=4, sort_keys=True)
586 def save_preload_data(self, preload_data):
587 self.save_object(preload_data, self.preload_dict_file)
589 def load_preload_data(self):
590 return self.load_object(self.preload_dict_file)
592 def save_vgmux_vnf_name(self, vgmux_vnf_name):
593 self.save_object(vgmux_vnf_name, self.vgmux_vnf_name_file)
595 def load_vgmux_vnf_name(self):
596 return self.load_object(self.vgmux_vnf_name_file)