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 = ['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.sdnc_userpass = 'admin', 'Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U'
136 self.sdnc_db_name = 'sdnctl'
137 self.sdnc_db_user = 'sdnctl'
138 self.sdnc_db_pass = 'gamma'
139 self.sdnc_db_port = '32774'
140 self.sdnc_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
141 self.sdnc_preload_network_url = 'http://' + self.hosts['sdnc'] + \
142 ':' + self.sdnc_preloading_port + '/restconf/operations/VNF-API:preload-network-topology-operation'
143 self.sdnc_preload_vnf_url = 'http://' + self.hosts['sdnc'] + \
144 ':' + self.sdnc_preloading_port + '/restconf/operations/VNF-API:preload-vnf-topology-operation'
145 self.sdnc_preload_gra_url = 'http://' + self.hosts['sdnc'] + \
146 ':' + self.sdnc_preloading_port + '/restconf/operations/GENERIC-RESOURCE-API:preload-vf-module-topology-operation'
147 self.sdnc_ar_cleanup_url = 'http://' + self.hosts['sdnc'] + ':' + self.sdnc_preloading_port + \
148 '/restconf/config/GENERIC-RESOURCE-API:'
150 #############################################################################################
151 # SO urls, note: do NOT add a '/' at the end of the url
152 self.so_req_api_url = {'v4': 'http://' + self.hosts['so'] + ':' + self.so_nbi_port + '/onap/so/infra/serviceInstantiation/v7/serviceInstances',
153 'v5': 'http://' + self.hosts['so'] + ':' + self.so_nbi_port + '/onap/so/infra/serviceInstantiation/v7/serviceInstances'}
154 self.so_check_progress_api_url = 'http://' + self.hosts['so'] + ':' + self.so_nbi_port + '/onap/so/infra/orchestrationRequests/v6'
155 self.so_userpass = 'InfraPortalClient', 'password1$'
156 self.so_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
157 self.so_db_name = 'catalogdb'
158 self.so_db_user = 'root'
159 self.so_db_pass = 'password'
160 self.so_db_port = '30252' if self.oom_mode else '32769'
162 self.vpp_inf_url = 'http://{0}:8183/restconf/config/ietf-interfaces:interfaces'
163 self.vpp_api_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
164 self.vpp_api_userpass = ('admin', 'admin')
165 self.vpp_ves_url= 'http://{0}:8183/restconf/config/vesagent:vesagent'
167 def headbridge(self, openstack_stack_name, svc_instance_uuid):
169 Add vserver information to AAI
171 self.logger.info('Adding vServer information to AAI for {0}'.format(openstack_stack_name))
172 if not self.oom_mode:
173 cmd = '/opt/demo.sh heatbridge {0} {1} vCPE'.format(openstack_stack_name, svc_instance_uuid)
174 ret = commands.getstatusoutput("ssh -i onap_dev root@{0} '{1}'".format(self.hosts['robot'], cmd))
175 self.logger.debug('%s', ret)
177 print('To add vGMUX vserver info to AAI, do the following:')
178 print('- ssh to rancher')
180 print('- cd /root/oom/kubernetes/robot')
181 print('- ./demo-k8s.sh onap heatbridge {0} {1} vCPE'.format(openstack_stack_name, svc_instance_uuid))
183 def get_brg_mac_from_sdnc(self):
185 Check table DHCP_MAP in the SDNC DB. Find the newly instantiated BRG MAC address.
186 Note that there might be multiple BRGs, the most recently instantiated BRG always has the largest IP address.
188 cnx = mysql.connector.connect(user=self.sdnc_db_user, password=self.sdnc_db_pass, database=self.sdnc_db_name,
189 host=self.hosts['sdnc'], port=self.sdnc_db_port)
190 cursor = cnx.cursor()
191 query = "SELECT * from DHCP_MAP"
192 cursor.execute(query)
194 self.logger.debug('DHCP_MAP table in SDNC')
197 for mac, ip in cursor:
198 self.logger.debug(mac + ':' + ip)
199 this_host = int(ip.split('.')[-1])
209 def execute_cmds_sdnc_db(self, cmds):
210 self.execute_cmds_db(cmds, self.sdnc_db_user, self.sdnc_db_pass, self.sdnc_db_name,
211 self.hosts['sdnc'], self.sdnc_db_port)
213 def execute_cmds_so_db(self, cmds):
214 self.execute_cmds_db(cmds, self.so_db_user, self.so_db_pass, self.so_db_name,
215 self.hosts['so'], self.so_db_port)
217 def execute_cmds_db(self, cmds, dbuser, dbpass, dbname, host, port):
218 cnx = mysql.connector.connect(user=dbuser, password=dbpass, database=dbname, host=host, port=port)
219 cursor = cnx.cursor()
221 self.logger.debug(cmd)
223 self.logger.debug('%s', cursor)
228 def find_file(self, file_name_keyword, file_ext, search_dir):
230 :param file_name_keyword: keyword used to look for the csar file, case insensitive matching, e.g, infra
231 :param file_ext: e.g., csar, json
232 :param search_dir path to search
233 :return: path name of the file
235 file_name_keyword = file_name_keyword.lower()
236 file_ext = file_ext.lower()
237 if not file_ext.startswith('.'):
238 file_ext = '.' + file_ext
241 for file_name in os.listdir(search_dir):
242 file_name_lower = file_name.lower()
243 if file_name_keyword in file_name_lower and file_name_lower.endswith(file_ext):
245 self.logger.error('Multiple files found for *{0}*.{1} in '
246 'directory {2}'.format(file_name_keyword, file_ext, search_dir))
248 filenamepath = os.path.abspath(os.path.join(search_dir, file_name))
253 self.logger.error("Cannot find *{0}*{1} in directory {2}".format(file_name_keyword, file_ext, search_dir))
257 def network_name_to_subnet_name(network_name):
259 :param network_name: example: vcpe_net_cpe_signal_201711281221
260 :return: vcpe_net_cpe_signal_subnet_201711281221
262 fields = network_name.split('_')
263 fields.insert(-1, 'subnet')
264 return '_'.join(fields)
266 def set_network_name(self, network_name):
267 param = ' '.join([k + ' ' + v for k, v in self.cloud.items()])
268 openstackcmd = 'openstack ' + param
269 cmd = ' '.join([openstackcmd, 'network set --name', network_name, 'ONAP-NW1'])
272 def set_subnet_name(self, network_name):
274 Example: network_name = vcpe_net_cpe_signal_201711281221
275 set subnet name to vcpe_net_cpe_signal_subnet_201711281221
278 param = ' '.join([k + ' ' + v for k, v in self.cloud.items()])
279 openstackcmd = 'openstack ' + param
281 # expected results: | subnets | subnet_id |
282 subnet_info = os.popen(openstackcmd + ' network show ' + network_name + ' |grep subnets').read().split('|')
283 if len(subnet_info) > 2 and subnet_info[1].strip() == 'subnets':
284 subnet_id = subnet_info[2].strip()
285 subnet_name = self.network_name_to_subnet_name(network_name)
286 cmd = ' '.join([openstackcmd, 'subnet set --name', subnet_name, subnet_id])
288 self.logger.info("Subnet name set to: " + subnet_name)
291 self.logger.error("Can't get subnet info from network name: " + network_name)
294 def is_node_in_aai(self, node_type, node_uuid):
296 search_node_type = None
297 if node_type == 'service':
298 search_node_type = 'service-instance'
299 key = 'service-instance-id'
300 elif node_type == 'vnf':
301 search_node_type = 'generic-vnf'
304 logging.error('Invalid node_type: ' + node_type)
307 url = 'https://{0}:{1}/aai/v11/search/nodes-query?search-node-type={2}&filter={3}:EQUALS:{4}'.format(
308 self.hosts['aai-inst1'], self.aai_query_port, search_node_type, key, node_uuid)
310 headers = {'Content-Type': 'application/json', 'Accept': 'application/json', 'X-FromAppID': 'vCPE-Robot', 'X-TransactionId': 'get_aai_subscr'}
311 requests.packages.urllib3.disable_warnings()
312 r = requests.get(url, headers=headers, auth=self.aai_userpass, verify=False)
314 self.logger.debug('aai query: ' + url)
315 self.logger.debug('aai response:\n' + json.dumps(response, indent=4, sort_keys=True))
316 return 'result-data' in response
319 def extract_ip_from_str(net_addr, net_addr_len, sz):
321 :param net_addr: e.g. 10.5.12.0
322 :param net_addr_len: e.g. 24
324 :return: the first IP address matching the network, e.g. 10.5.12.3
326 network = ipaddress.ip_network(unicode('{0}/{1}'.format(net_addr, net_addr_len)), strict=False)
327 ip_list = re.findall(r'[0-9]+(?:\.[0-9]+){3}', sz)
329 this_net = ipaddress.ip_network(unicode('{0}/{1}'.format(ip, net_addr_len)), strict=False)
330 if this_net == network:
334 def get_pod_node_oam_ip(self, pod):
336 :Assuming kubectl is available and configured by default config (~/.kube/config)
337 :param pod: pod name substring, e.g. 'sdnc-sdnc-0'
338 :return pod's cluster node oam ip (10.0.0.0/16)
341 config.load_kube_config()
342 api = client.CoreV1Api()
343 kslogger = logging.getLogger('kubernetes')
344 kslogger.setLevel(logging.INFO)
345 res = api.list_pod_for_all_namespaces()
347 if pod in i.metadata.name:
348 self.logger.debug("found {0}\t{1}\t{2}".format(i.metadata.name, i.status.host_ip, i.spec.node_name))
349 ret = i.status.host_ip
353 ret = raw_input("Enter sdnc-sdnc-0 pod cluster node OAM IP address(10.0.0.0/16): ")
356 def get_pod_node_public_ip(self, pod):
358 :Assuming kubectl is available and configured by default config (~/.kube/config)
359 :param pod: pod name substring, e.g. 'sdnc-sdnc-0'
360 :return pod's cluster node public ip (i.e. 10.12.0.0/16)
363 config.load_kube_config()
364 api = client.CoreV1Api()
365 kslogger = logging.getLogger('kubernetes')
366 kslogger.setLevel(logging.INFO)
367 res = api.list_pod_for_all_namespaces()
369 if pod in i.metadata.name:
370 ret = self.get_vm_public_ip_by_nova(i.spec.node_name)
371 self.logger.debug("found node {0} public ip: {1}".format(i.spec.node_name, ret))
375 ret = raw_input("Enter sdnc-sdnc-0 pod cluster node public IP address(i.e. 10.12.0.0/16): ")
378 def get_vm_public_ip_by_nova(self, vm):
380 This method uses openstack nova api to retrieve vm public ip
384 subnet = IPNetwork('{0}/{1}'.format(self.external_net_addr, self.external_net_prefix_len))
385 nova = openstackclient.Client(2, self.cloud['--os-username'], self.cloud['--os-password'], self.cloud['--os-tenant-id'], self.cloud['--os-auth-url'])
386 for i in nova.servers.list():
388 for k, v in i.networks.items():
390 if IPAddress(ip) in subnet:
394 def get_vm_ip(self, keywords, net_addr=None, net_addr_len=None):
396 :param keywords: list of keywords to search for vm, e.g. ['bng', 'gmux', 'brg']
397 :param net_addr: e.g. 10.12.5.0
398 :param net_addr_len: e.g. 24
399 :return: dictionary {keyword: ip}
402 net_addr = self.external_net_addr
405 net_addr_len = self.external_net_prefix_len
407 param = ' '.join([k + ' ' + v for k, v in self.cloud.items() if 'identity' not in k])
408 openstackcmd = 'nova ' + param + ' list'
409 self.logger.debug(openstackcmd)
411 results = os.popen(openstackcmd).read()
412 all_vm_ip_dict = self.extract_vm_ip_as_dict(results, net_addr, net_addr_len)
413 latest_vm_list = self.remove_old_vms(all_vm_ip_dict.keys(), self.cpe_vm_prefix)
414 latest_vm_ip_dict = {vm: all_vm_ip_dict[vm] for vm in latest_vm_list}
415 ip_dict = self.select_subset_vm_ip(latest_vm_ip_dict, keywords)
417 ip_dict.update(self.get_oom_onap_vm_ip(keywords))
419 if len(ip_dict) != len(keywords):
420 self.logger.error('Cannot find all desired IP addresses for %s.', keywords)
421 self.logger.error(json.dumps(ip_dict, indent=4, sort_keys=True))
422 self.logger.error('Temporarily continue.. remember to check back vcpecommon.py line: 396')
426 def get_oom_onap_vm_ip(self, keywords):
428 onap_vm_list = set(['so', 'sdnc', 'aai-inst1', 'robot', self.dcae_ves_collector_name])
430 if vm in onap_vm_list:
431 vm_ip[vm] = self.oom_so_sdnc_aai_ip
434 def extract_vm_ip_as_dict(self, novalist_results, net_addr, net_addr_len):
436 for line in novalist_results.split('\n'):
437 fields = line.split('|')
441 ip = self.extract_ip_from_str(net_addr, net_addr_len, ip_info)
442 vm_ip_dict[vm_name] = ip
446 def remove_old_vms(self, vm_list, prefix):
448 For vms with format name_timestamp, only keep the one with the latest timestamp.
450 zdcpe1cpe01brgemu01_201805222148 (drop this)
451 zdcpe1cpe01brgemu01_201805222229 (keep this)
452 zdcpe1cpe01gw01_201805162201
455 same_type_vm_dict = {}
457 fields = vm.split('_')
458 if vm.startswith(prefix) and len(fields) == 2 and len(fields[-1]) == len('201805222148') and fields[-1].isdigit():
459 if vm > same_type_vm_dict.get(fields[0], '0'):
460 same_type_vm_dict[fields[0]] = vm
462 new_vm_list.append(vm)
464 new_vm_list.extend(same_type_vm_dict.values())
467 def select_subset_vm_ip(self, all_vm_ip_dict, vm_name_keyword_list):
469 for keyword in vm_name_keyword_list:
470 for vm, ip in all_vm_ip_dict.items():
472 vm_ip_dict[keyword] = ip
476 def del_vgmux_ves_mode(self):
477 url = self.vpp_ves_url.format(self.hosts['mux']) + '/mode'
478 r = requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
479 self.logger.debug('%s', r)
481 def del_vgmux_ves_collector(self):
482 url = self.vpp_ves_url.format(self.hosts['mux']) + '/config'
483 r = requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
484 self.logger.debug('%s', r)
486 def set_vgmux_ves_collector(self ):
487 url = self.vpp_ves_url.format(self.hosts['mux'])
489 {'server-addr': self.hosts[self.dcae_ves_collector_name],
490 'server-port': '30235' if self.oom_mode else '8081',
491 'read-interval': '10',
495 r = requests.post(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass, json=data)
496 self.logger.debug('%s', r)
498 def set_vgmux_packet_loss_rate(self, lossrate, vg_vnf_instance_name):
499 url = self.vpp_ves_url.format(self.hosts['mux'])
501 {"working-mode": "demo",
502 "base-packet-loss": str(lossrate),
503 "source-name": vg_vnf_instance_name
506 r = requests.post(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass, json=data)
507 self.logger.debug('%s', r)
509 # return all the VxLAN interface names of BRG or vGMUX based on the IP address
510 def get_vxlan_interfaces(self, ip, print_info=False):
511 url = self.vpp_inf_url.format(ip)
512 self.logger.debug('url is this: %s', url)
513 r = requests.get(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
514 data = r.json()['interfaces']['interface']
517 if 'name' in inf and 'type' in inf and inf['type'] == 'v3po:vxlan-tunnel':
518 print(json.dumps(inf, indent=4, sort_keys=True))
520 return [inf['name'] for inf in data if 'name' in inf and 'type' in inf and inf['type'] == 'v3po:vxlan-tunnel']
522 # delete all VxLAN interfaces of each hosts
523 def delete_vxlan_interfaces(self, host_dic):
524 for host, ip in host_dic.items():
526 self.logger.info('{0}: Getting VxLAN interfaces'.format(host))
527 inf_list = self.get_vxlan_interfaces(ip)
531 self.logger.info("{0}: Deleting VxLAN crossconnect {1}".format(host, inf))
532 url = self.vpp_inf_url.format(ip) + '/interface/' + inf + '/v3po:l2'
533 requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
538 self.logger.info("{0}: Deleting VxLAN interface {1}".format(host, inf))
539 url = self.vpp_inf_url.format(ip) + '/interface/' + inf
540 requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
542 if len(self.get_vxlan_interfaces(ip)) > 0:
543 self.logger.error("Error deleting VxLAN from {0}, try to restart the VM, IP is {1}.".format(host, ip))
547 self.logger.info("{0}: no VxLAN interface found, nothing to delete".format(host))
551 def save_object(obj, filepathname):
552 with open(filepathname, 'wb') as fout:
553 pickle.dump(obj, fout)
556 def load_object(filepathname):
557 with open(filepathname, 'rb') as fin:
558 return pickle.load(fin)
561 def increase_ip_address_or_vni_in_template(vnf_template_file, vnf_parameter_name_list):
562 with open(vnf_template_file) as json_input:
563 json_data = json.load(json_input)
564 param_list = json_data['VNF-API:input']['VNF-API:vnf-topology-information']['VNF-API:vnf-parameters']
565 for param in param_list:
566 if param['vnf-parameter-name'] in vnf_parameter_name_list:
567 ipaddr_or_vni = param['vnf-parameter-value'].split('.')
568 number = int(ipaddr_or_vni[-1])
573 ipaddr_or_vni[-1] = str(number)
574 param['vnf-parameter-value'] = '.'.join(ipaddr_or_vni)
576 assert json_data is not None
577 with open(vnf_template_file, 'w') as json_output:
578 json.dump(json_data, json_output, indent=4, sort_keys=True)
580 def save_preload_data(self, preload_data):
581 self.save_object(preload_data, self.preload_dict_file)
583 def load_preload_data(self):
584 return self.load_object(self.preload_dict_file)
586 def save_vgmux_vnf_name(self, vgmux_vnf_name):
587 self.save_object(vgmux_vnf_name, self.vgmux_vnf_name_file)
589 def load_vgmux_vnf_name(self):
590 return self.load_object(self.vgmux_vnf_name_file)