blob: 0213183e81881a4c9c3534eb4202ebf4e1625cf0 [file] [log] [blame]
Kang Xi11d278c2018-04-06 16:56:04 -04001import json
2import logging
3import os
4import pickle
5import re
6import sys
7
8import ipaddress
9import mysql.connector
10import requests
11import commands
12import time
13
14
15class VcpeCommon:
16 #############################################################################################
17 # Start: configurations that you must change for a new ONAP installation
18 external_net_addr = '10.12.0.0'
19 external_net_prefix_len = 16
20 #############################################################################################
21 # set the openstack cloud access credentials here
22 cloud = {
23 '--os-auth-url': 'http://10.12.25.2:5000',
Kang Xi268b74d2018-05-23 15:53:42 -040024 '--os-username': 'kxi',
Kang Xi11d278c2018-04-06 16:56:04 -040025 '--os-user-domain-id': 'default',
26 '--os-project-domain-id': 'default',
Kang Xi268b74d2018-05-23 15:53:42 -040027 '--os-tenant-id': '1e097c6713e74fd7ac8e4295e605ee1e',
Kang Xi11d278c2018-04-06 16:56:04 -040028 '--os-region-name': 'RegionOne',
Kang Xi268b74d2018-05-23 15:53:42 -040029 '--os-password': 'n3JhGMGuDzD8',
30 '--os-project-domain-name': 'Integration-SB-07',
Kang Xi11d278c2018-04-06 16:56:04 -040031 '--os-identity-api-version': '3'
32 }
33
34 common_preload_config = {
Kang Xi268b74d2018-05-23 15:53:42 -040035 'oam_onap_net': 'oam_onap_lAky',
36 'oam_onap_subnet': 'oam_onap_lAky',
Kang Xi11d278c2018-04-06 16:56:04 -040037 'public_net': 'external',
38 'public_net_id': '971040b2-7059-49dc-b220-4fab50cb2ad4'
39 }
40 # End: configurations that you must change for a new ONAP installation
41 #############################################################################################
42
43 template_variable_symbol = '${'
Kang Xi6c762392018-05-30 09:27:34 -040044 cpe_vm_prefix = 'zdcpe'
Kang Xi11d278c2018-04-06 16:56:04 -040045 #############################################################################################
46 # preloading network config
47 # key=network role
48 # value = [subnet_start_ip, subnet_gateway_ip]
49 preload_network_config = {
50 'cpe_public': ['10.2.0.2', '10.2.0.1'],
51 'cpe_signal': ['10.4.0.2', '10.4.0.1'],
52 'brg_bng': ['10.3.0.2', '10.3.0.1'],
53 'bng_mux': ['10.1.0.10', '10.1.0.1'],
54 'mux_gw': ['10.5.0.10', '10.5.0.1']
55 }
56
Kang Xi268b74d2018-05-23 15:53:42 -040057 dcae_ves_collector_name = 'dcae-bootstrap'
Kang Xi11d278c2018-04-06 16:56:04 -040058 global_subscriber_id = 'SDN-ETHERNET-INTERNET'
Kang Xi268b74d2018-05-23 15:53:42 -040059 project_name = 'Project-Demonstration'
60 owning_entity_id = '520cc603-a3c4-4ec2-9ef4-ca70facd79c0'
61 owning_entity_name = 'OE-Demonstration'
Kang Xi11d278c2018-04-06 16:56:04 -040062
63 def __init__(self, extra_host_names=None):
64 self.logger = logging.getLogger(__name__)
65 self.logger.info('Initializing configuration')
66
Kang Xi268b74d2018-05-23 15:53:42 -040067 self.host_names = ['so', 'sdnc', 'robot', 'aai-inst1', self.dcae_ves_collector_name]
Kang Xi11d278c2018-04-06 16:56:04 -040068 if extra_host_names:
69 self.host_names.extend(extra_host_names)
70 # get IP addresses
71 self.hosts = self.get_vm_ip(self.host_names, self.external_net_addr, self.external_net_prefix_len)
72 # this is the keyword used to name vgw stack, must not be used in other stacks
73 self.vgw_name_keyword = 'base_vcpe_vgw'
74 self.svc_instance_uuid_file = '__var/svc_instance_uuid'
75 self.preload_dict_file = '__var/preload_dict'
76 self.vgmux_vnf_name_file = '__var/vgmux_vnf_name'
77 self.product_family_id = 'f9457e8c-4afd-45da-9389-46acd9bf5116'
78 self.custom_product_family_id = 'a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb'
79 self.instance_name_prefix = {
80 'service': 'vcpe_svc',
81 'network': 'vcpe_net',
82 'vnf': 'vcpe_vnf',
83 'vfmodule': 'vcpe_vfmodule'
84 }
85 self.aai_userpass = 'AAI', 'AAI'
86 self.pub_key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKXDgoo3+WOqcUG8/5uUbk81+yczgwC4Y8ywTmuQqbNxlY1oQ0YxdMUqUnhitSXs5S/yRuAVOYHwGg2mCs20oAINrP+mxBI544AMIb9itPjCtgqtE2EWo6MmnFGbHB4Sx3XioE7F4VPsh7japsIwzOjbrQe+Mua1TGQ5d4nfEOQaaglXLLPFfuc7WbhbJbK6Q7rHqZfRcOwAMXgDoBqlyqKeiKwnumddo2RyNT8ljYmvB6buz7KnMinzo7qB0uktVT05FH9Rg0CTWH5norlG5qXgP2aukL0gk1ph8iAt7uYLf1ktp+LJI2gaF6L0/qli9EmVCSLr1uJ38Q8CBflhkh'
87 self.os_tenant_id = self.cloud['--os-tenant-id']
88 self.os_region_name = self.cloud['--os-region-name']
89 self.common_preload_config['pub_key'] = self.pub_key
90 self.sniro_url = 'http://' + self.hosts['robot'] + ':8080/__admin/mappings'
91 self.sniro_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
Kang Xi268b74d2018-05-23 15:53:42 -040092 self.homing_solution = 'sniro' # value is either 'sniro' or 'oof'
93# self.homing_solution = 'oof'
94 self.customer_location_used_by_oof = {
95 "customerLatitude": "32.897480",
96 "customerLongitude": "-97.040443",
97 "customerName": "some_company"
98 }
Kang Xi11d278c2018-04-06 16:56:04 -040099
100 #############################################################################################
101 # SDNC urls
102 self.sdnc_userpass = 'admin', 'Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U'
103 self.sdnc_db_name = 'sdnctl'
104 self.sdnc_db_user = 'sdnctl'
105 self.sdnc_db_pass = 'gamma'
Kang Xi268b74d2018-05-23 15:53:42 -0400106 self.sdnc_db_port = '32774'
Kang Xi11d278c2018-04-06 16:56:04 -0400107 self.sdnc_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
108 self.sdnc_preload_network_url = 'http://' + self.hosts['sdnc'] + \
109 ':8282/restconf/operations/VNF-API:preload-network-topology-operation'
110 self.sdnc_preload_vnf_url = 'http://' + self.hosts['sdnc'] + \
111 ':8282/restconf/operations/VNF-API:preload-vnf-topology-operation'
112 self.sdnc_ar_cleanup_url = 'http://' + self.hosts['sdnc'] + ':8282/restconf/config/GENERIC-RESOURCE-API:'
113
114 #############################################################################################
115 # SO urls, note: do NOT add a '/' at the end of the url
116 self.so_req_api_url = {'v4': 'http://' + self.hosts['so'] + ':8080/ecomp/mso/infra/serviceInstances/v4',
117 'v5': 'http://' + self.hosts['so'] + ':8080/ecomp/mso/infra/serviceInstances/v5'}
Kang Xi268b74d2018-05-23 15:53:42 -0400118 self.so_check_progress_api_url = 'http://' + self.hosts['so'] + ':8080/ecomp/mso/infra/orchestrationRequests/v5'
Kang Xi11d278c2018-04-06 16:56:04 -0400119 self.so_userpass = 'InfraPortalClient', 'password1$'
120 self.so_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
121 self.so_db_name = 'mso_catalog'
122 self.so_db_user = 'root'
123 self.so_db_pass = 'password'
Kang Xi6c762392018-05-30 09:27:34 -0400124 self.so_db_port = '32769'
Kang Xi11d278c2018-04-06 16:56:04 -0400125
126 self.vpp_inf_url = 'http://{0}:8183/restconf/config/ietf-interfaces:interfaces'
127 self.vpp_api_headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
128 self.vpp_api_userpass = ('admin', 'admin')
129 self.vpp_ves_url= 'http://{0}:8183/restconf/config/vesagent:vesagent'
130
131 def headbridge(self, openstack_stack_name, svc_instance_uuid):
132 """
133 Add vserver information to AAI
134 """
135 self.logger.info('Adding vServer information to AAI for {0}'.format(openstack_stack_name))
136 cmd = '/opt/demo.sh heatbridge {0} {1} vCPE'.format(openstack_stack_name, svc_instance_uuid)
137 ret = commands.getstatusoutput("ssh -i onap_dev root@{0} '{1}'".format(self.hosts['robot'], cmd))
138 self.logger.debug('%s', ret)
139
140 def get_brg_mac_from_sdnc(self):
141 """
Kang Xi6c762392018-05-30 09:27:34 -0400142 Check table DHCP_MAP in the SDNC DB. Find the newly instantiated BRG MAC address.
143 Note that there might be multiple BRGs, the most recently instantiated BRG always has the largest IP address.
Kang Xi11d278c2018-04-06 16:56:04 -0400144 """
145 cnx = mysql.connector.connect(user=self.sdnc_db_user, password=self.sdnc_db_pass, database=self.sdnc_db_name,
146 host=self.hosts['sdnc'], port=self.sdnc_db_port)
147 cursor = cnx.cursor()
148 query = "SELECT * from DHCP_MAP"
149 cursor.execute(query)
150
151 self.logger.debug('DHCP_MAP table in SDNC')
Kang Xi6c762392018-05-30 09:27:34 -0400152 mac_recent = None
153 host = -1
Kang Xi11d278c2018-04-06 16:56:04 -0400154 for mac, ip in cursor:
Kang Xi11d278c2018-04-06 16:56:04 -0400155 self.logger.debug(mac + ':' + ip)
Kang Xi6c762392018-05-30 09:27:34 -0400156 this_host = int(ip.split('.')[-1])
157 if host < this_host:
158 host = this_host
159 mac_recent = mac
Kang Xi11d278c2018-04-06 16:56:04 -0400160
161 cnx.close()
162
Kang Xi6c762392018-05-30 09:27:34 -0400163 assert mac_recent
164 return mac_recent
Kang Xi11d278c2018-04-06 16:56:04 -0400165
Kang Xi6c762392018-05-30 09:27:34 -0400166 def execute_cmds_sdnc_db(self, cmds):
167 self.execute_cmds_db(cmds, self.sdnc_db_user, self.sdnc_db_pass, self.sdnc_db_name,
168 self.hosts['sdnc'], self.sdnc_db_port)
Kang Xi11d278c2018-04-06 16:56:04 -0400169
Kang Xi6c762392018-05-30 09:27:34 -0400170 def execute_cmds_so_db(self, cmds):
171 self.execute_cmds_db(cmds, self.so_db_user, self.so_db_pass, self.so_db_name,
172 self.hosts['so'], self.so_db_port)
173
174 def execute_cmds_db(self, cmds, dbuser, dbpass, dbname, host, port):
175 cnx = mysql.connector.connect(user=dbuser, password=dbpass, database=dbname, host=host, port=port)
Kang Xi11d278c2018-04-06 16:56:04 -0400176 cursor = cnx.cursor()
177 for cmd in cmds:
178 self.logger.debug(cmd)
179 cursor.execute(cmd)
180 self.logger.debug('%s', cursor)
181 cnx.commit()
182 cursor.close()
183 cnx.close()
184
185 def find_file(self, file_name_keyword, file_ext, search_dir):
186 """
187 :param file_name_keyword: keyword used to look for the csar file, case insensitive matching, e.g, infra
188 :param file_ext: e.g., csar, json
189 :param search_dir path to search
190 :return: path name of the file
191 """
192 file_name_keyword = file_name_keyword.lower()
193 file_ext = file_ext.lower()
194 if not file_ext.startswith('.'):
195 file_ext = '.' + file_ext
196
197 filenamepath = None
198 for file_name in os.listdir(search_dir):
199 file_name_lower = file_name.lower()
200 if file_name_keyword in file_name_lower and file_name_lower.endswith(file_ext):
201 if filenamepath:
202 self.logger.error('Multiple files found for *{0}*.{1} in '
203 'directory {2}'.format(file_name_keyword, file_ext, search_dir))
204 sys.exit()
205 filenamepath = os.path.abspath(os.path.join(search_dir, file_name))
206
207 if filenamepath:
208 return filenamepath
209 else:
210 self.logger.error("Cannot find *{0}*{1} in directory {2}".format(file_name_keyword, file_ext, search_dir))
211 sys.exit()
212
213 @staticmethod
214 def network_name_to_subnet_name(network_name):
215 """
216 :param network_name: example: vcpe_net_cpe_signal_201711281221
217 :return: vcpe_net_cpe_signal_subnet_201711281221
218 """
219 fields = network_name.split('_')
220 fields.insert(-1, 'subnet')
221 return '_'.join(fields)
222
223 def set_network_name(self, network_name):
224 param = ' '.join([k + ' ' + v for k, v in self.cloud.items()])
225 openstackcmd = 'openstack ' + param
226 cmd = ' '.join([openstackcmd, 'network set --name', network_name, 'ONAP-NW1'])
227 os.popen(cmd)
228
229 def set_subnet_name(self, network_name):
230 """
231 Example: network_name = vcpe_net_cpe_signal_201711281221
232 set subnet name to vcpe_net_cpe_signal_subnet_201711281221
233 :return:
234 """
235 param = ' '.join([k + ' ' + v for k, v in self.cloud.items()])
236 openstackcmd = 'openstack ' + param
237
238 # expected results: | subnets | subnet_id |
239 subnet_info = os.popen(openstackcmd + ' network show ' + network_name + ' |grep subnets').read().split('|')
240 if len(subnet_info) > 2 and subnet_info[1].strip() == 'subnets':
241 subnet_id = subnet_info[2].strip()
242 subnet_name = self.network_name_to_subnet_name(network_name)
243 cmd = ' '.join([openstackcmd, 'subnet set --name', subnet_name, subnet_id])
244 os.popen(cmd)
245 self.logger.info("Subnet name set to: " + subnet_name)
246 return True
247 else:
248 self.logger.error("Can't get subnet info from network name: " + network_name)
249 return False
250
251 def is_node_in_aai(self, node_type, node_uuid):
252 key = None
253 search_node_type = None
254 if node_type == 'service':
255 search_node_type = 'service-instance'
256 key = 'service-instance-id'
257 elif node_type == 'vnf':
258 search_node_type = 'generic-vnf'
259 key = 'vnf-id'
260 else:
261 logging.error('Invalid node_type: ' + node_type)
262 sys.exit()
263
264 url = 'https://{0}:8443/aai/v11/search/nodes-query?search-node-type={1}&filter={2}:EQUALS:{3}'.format(
265 self.hosts['aai-inst1'], search_node_type, key, node_uuid)
266
Kang Xi268b74d2018-05-23 15:53:42 -0400267 headers = {'Content-Type': 'application/json', 'Accept': 'application/json', 'X-FromAppID': 'vCPE-Robot', 'X-TransactionId': 'get_aai_subscr'}
Kang Xi11d278c2018-04-06 16:56:04 -0400268 requests.packages.urllib3.disable_warnings()
269 r = requests.get(url, headers=headers, auth=self.aai_userpass, verify=False)
270 response = r.json()
271 self.logger.debug('aai query: ' + url)
272 self.logger.debug('aai response:\n' + json.dumps(response, indent=4, sort_keys=True))
273 return 'result-data' in response
274
275 @staticmethod
276 def extract_ip_from_str(net_addr, net_addr_len, sz):
277 """
278 :param net_addr: e.g. 10.5.12.0
279 :param net_addr_len: e.g. 24
280 :param sz: a string
281 :return: the first IP address matching the network, e.g. 10.5.12.3
282 """
283 network = ipaddress.ip_network(unicode('{0}/{1}'.format(net_addr, net_addr_len)), strict=False)
284 ip_list = re.findall(r'[0-9]+(?:\.[0-9]+){3}', sz)
285 for ip in ip_list:
286 this_net = ipaddress.ip_network(unicode('{0}/{1}'.format(ip, net_addr_len)), strict=False)
287 if this_net == network:
288 return str(ip)
289 return None
290
291 def get_vm_ip(self, keywords, net_addr=None, net_addr_len=None):
292 """
293 :param keywords: list of keywords to search for vm, e.g. ['bng', 'gmux', 'brg']
294 :param net_addr: e.g. 10.12.5.0
295 :param net_addr_len: e.g. 24
296 :return: dictionary {keyword: ip}
297 """
298 if not net_addr:
299 net_addr = self.external_net_addr
300
301 if not net_addr_len:
302 net_addr_len = self.external_net_prefix_len
303
304 param = ' '.join([k + ' ' + v for k, v in self.cloud.items() if 'identity' not in k])
305 openstackcmd = 'nova ' + param + ' list'
306 self.logger.debug(openstackcmd)
307
Kang Xi11d278c2018-04-06 16:56:04 -0400308 results = os.popen(openstackcmd).read()
Kang Xi6c762392018-05-30 09:27:34 -0400309 all_vm_ip_dict = self.extract_vm_ip_as_dict(results, net_addr, net_addr_len)
310 latest_vm_list = self.remove_old_vms(all_vm_ip_dict.keys(), self.cpe_vm_prefix)
311 latest_vm_ip_dict = {vm: all_vm_ip_dict[vm] for vm in latest_vm_list}
312 ip_dict = self.select_subset_vm_ip(latest_vm_ip_dict, keywords)
313
Kang Xi11d278c2018-04-06 16:56:04 -0400314 if len(ip_dict) != len(keywords):
315 self.logger.error('Cannot find all desired IP addresses for %s.', keywords)
316 self.logger.error(json.dumps(ip_dict, indent=4, sort_keys=True))
Kang Xi268b74d2018-05-23 15:53:42 -0400317 self.logger.error('Temporarily continue.. remember to check back vcpecommon.py line: 316')
318# sys.exit()
Kang Xi11d278c2018-04-06 16:56:04 -0400319 return ip_dict
320
Kang Xi6c762392018-05-30 09:27:34 -0400321 def extract_vm_ip_as_dict(self, novalist_results, net_addr, net_addr_len):
322 vm_ip_dict = {}
323 for line in novalist_results.split('\n'):
324 fields = line.split('|')
325 if len(fields) == 8:
326 vm_name = fields[2]
327 ip_info = fields[-2]
328 ip = self.extract_ip_from_str(net_addr, net_addr_len, ip_info)
329 vm_ip_dict[vm_name] = ip
330
331 return vm_ip_dict
332
333 def remove_old_vms(self, vm_list, prefix):
334 """
335 For vms with format name_timestamp, only keep the one with the latest timestamp.
336 E.g.,
337 zdcpe1cpe01brgemu01_201805222148 (drop this)
338 zdcpe1cpe01brgemu01_201805222229 (keep this)
339 zdcpe1cpe01gw01_201805162201
340 """
341 new_vm_list = []
342 same_type_vm_dict = {}
343 for vm in vm_list:
344 fields = vm.split('_')
345 if vm.startswith(prefix) and len(fields) == 2 and len(fields[-1]) == len('201805222148') and fields[-1].isdigit():
346 if vm > same_type_vm_dict.get(fields[0], '0'):
347 same_type_vm_dict[fields[0]] = vm
348 else:
349 new_vm_list.append(vm)
350
351 new_vm_list.extend(same_type_vm_dict.values())
352 return new_vm_list
353
354 def select_subset_vm_ip(self, all_vm_ip_dict, vm_name_keyword_list):
355 vm_ip_dict = {}
356 for keyword in vm_name_keyword_list:
357 for vm, ip in all_vm_ip_dict.items():
358 if keyword in vm:
359 vm_ip_dict[keyword] = ip
360 break
361 return vm_ip_dict
362
Kang Xi11d278c2018-04-06 16:56:04 -0400363 def del_vgmux_ves_mode(self):
364 url = self.vpp_ves_url.format(self.hosts['mux']) + '/mode'
365 r = requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
366 self.logger.debug('%s', r)
367
368 def del_vgmux_ves_collector(self):
369 url = self.vpp_ves_url.format(self.hosts['mux']) + '/config'
370 r = requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
371 self.logger.debug('%s', r)
372
373 def set_vgmux_ves_collector(self ):
374 url = self.vpp_ves_url.format(self.hosts['mux'])
375 data = {'config':
Kang Xi268b74d2018-05-23 15:53:42 -0400376 {'server-addr': self.hosts[self.dcae_ves_collector_name],
377 'server-port': '8081',
Kang Xi11d278c2018-04-06 16:56:04 -0400378 'read-interval': '10',
379 'is-add':'1'
380 }
381 }
382 r = requests.post(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass, json=data)
383 self.logger.debug('%s', r)
384
385 def set_vgmux_packet_loss_rate(self, lossrate, vg_vnf_instance_name):
386 url = self.vpp_ves_url.format(self.hosts['mux'])
387 data = {"mode":
388 {"working-mode": "demo",
389 "base-packet-loss": str(lossrate),
390 "source-name": vg_vnf_instance_name
391 }
392 }
393 r = requests.post(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass, json=data)
394 self.logger.debug('%s', r)
395
396 # return all the VxLAN interface names of BRG or vGMUX based on the IP address
397 def get_vxlan_interfaces(self, ip, print_info=False):
398 url = self.vpp_inf_url.format(ip)
399 self.logger.debug('url is this: %s', url)
400 r = requests.get(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
401 data = r.json()['interfaces']['interface']
402 if print_info:
403 for inf in data:
404 if 'name' in inf and 'type' in inf and inf['type'] == 'v3po:vxlan-tunnel':
405 print(json.dumps(inf, indent=4, sort_keys=True))
406
407 return [inf['name'] for inf in data if 'name' in inf and 'type' in inf and inf['type'] == 'v3po:vxlan-tunnel']
408
409 # delete all VxLAN interfaces of each hosts
410 def delete_vxlan_interfaces(self, host_dic):
411 for host, ip in host_dic.items():
412 deleted = False
413 self.logger.info('{0}: Getting VxLAN interfaces'.format(host))
414 inf_list = self.get_vxlan_interfaces(ip)
415 for inf in inf_list:
416 deleted = True
417 time.sleep(2)
418 self.logger.info("{0}: Deleting VxLAN crossconnect {1}".format(host, inf))
419 url = self.vpp_inf_url.format(ip) + '/interface/' + inf + '/v3po:l2'
420 requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
421
422 for inf in inf_list:
423 deleted = True
424 time.sleep(2)
425 self.logger.info("{0}: Deleting VxLAN interface {1}".format(host, inf))
426 url = self.vpp_inf_url.format(ip) + '/interface/' + inf
427 requests.delete(url, headers=self.vpp_api_headers, auth=self.vpp_api_userpass)
428
429 if len(self.get_vxlan_interfaces(ip)) > 0:
430 self.logger.error("Error deleting VxLAN from {0}, try to restart the VM, IP is {1}.".format(host, ip))
431 return False
432
433 if not deleted:
434 self.logger.info("{0}: no VxLAN interface found, nothing to delete".format(host))
435 return True
436
437 @staticmethod
438 def save_object(obj, filepathname):
439 with open(filepathname, 'wb') as fout:
440 pickle.dump(obj, fout)
441
442 @staticmethod
443 def load_object(filepathname):
444 with open(filepathname, 'rb') as fin:
445 return pickle.load(fin)
446
Kang Xi6c762392018-05-30 09:27:34 -0400447 @staticmethod
448 def increase_ip_address_or_vni_in_template(vnf_template_file, vnf_parameter_name_list):
449 with open(vnf_template_file) as json_input:
450 json_data = json.load(json_input)
451 param_list = json_data['VNF-API:input']['VNF-API:vnf-topology-information']['VNF-API:vnf-parameters']
452 for param in param_list:
453 if param['vnf-parameter-name'] in vnf_parameter_name_list:
454 ipaddr_or_vni = param['vnf-parameter-value'].split('.')
455 number = int(ipaddr_or_vni[-1])
456 if 254 == number:
457 number = 10
458 else:
459 number = number + 1
460 ipaddr_or_vni[-1] = str(number)
461 param['vnf-parameter-value'] = '.'.join(ipaddr_or_vni)
462
463 assert json_data is not None
464 with open(vnf_template_file, 'w') as json_output:
465 json.dump(json_data, json_output, indent=4, sort_keys=True)
466
Kang Xi11d278c2018-04-06 16:56:04 -0400467 def save_preload_data(self, preload_data):
468 self.save_object(preload_data, self.preload_dict_file)
469
470 def load_preload_data(self):
471 return self.load_object(self.preload_dict_file)
472
473 def save_vgmux_vnf_name(self, vgmux_vnf_name):
474 self.save_object(vgmux_vnf_name, self.vgmux_vnf_name_file)
475
476 def load_vgmux_vnf_name(self):
477 return self.load_object(self.vgmux_vnf_name_file)
478