1 # Copyright 2016 ZTE Corporation.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
19 from neutronclient.common.exceptions import NeutronClientException
20 from neutronclient.common.exceptions import NetworkNotFoundClient
21 from neutronclient.common.exceptions import NotFound as SubnetNotFound
23 from lcm.pub.nfvi.vim.api.openstack import neutronbase
24 from lcm.pub.nfvi.vim.lib.syscomm import fun_name
25 from lcm.pub.nfvi.vim.api.openstack import project
26 from lcm.pub.nfvi.vim import const
27 from lcm.pub.nfvi.vim.lib.vimexception import VimException
29 logger = logging.getLogger(__name__)
32 def query_net(auth_info, net_id):
33 neutron = neutronbase.get_neutron_default(fun_name(), auth_info)
36 net = neutron.show_network(net_id)["network"]
37 keystone = auth_info["keystone"]
38 tenant = keystone.tenants.get(tenant_id=net["tenant_id"])
39 except NetworkNotFoundClient as e:
40 logger.warn("NetworkNotFoundClient: %s", e.message)
45 "status": net["status"],
46 "admin_state_up": net["admin_state_up"],
47 "network_type": net["provider:network_type"],
48 "physical_network": net["provider:physical_network"],
49 "segmentation_id": net["provider:segmentation_id"],
50 "tenant_id": net["tenant_id"],
51 "tenant_name": tenant.name,
52 "subnets": net["subnets"],
53 "shared": net["shared"],
54 "router_external": net["router:external"]}
58 def query_nets(auth_info):
59 neutron = neutronbase.get_neutron_default(fun_name(), auth_info)
60 keystone = auth_info["keystone"]
62 tenants = keystone.tenants.list()
63 for tenant in tenants:
64 tenants_map[tenant.id] = tenant.name
66 nets = neutron.list_networks()
67 return [0, {"networks": [{
70 "status": net["status"],
71 "admin_state_up": net["admin_state_up"],
72 "network_type": net["provider:network_type"],
73 "physical_network": net["provider:physical_network"],
74 "segmentation_id": net["provider:segmentation_id"],
75 "tenant_id": net["tenant_id"],
76 "tenant_name": tenants_map[net["tenant_id"]] if net["tenant_id"] in tenants_map else "unknown",
77 "subnets": net["subnets"],
78 "shared": net["shared"],
79 "router_external": net["router:external"]
80 } for net in nets["networks"]]}]
83 def query_subnet(auth_info, subnet_id):
84 neutron = neutronbase.get_neutron_default(fun_name(), auth_info)
87 subnet_info = neutron.show_subnet(subnet_id)["subnet"]
88 except SubnetNotFound as e:
89 logger.warn("SubnetNotFound: %s", e.message)
92 ret[1]["id"] = subnet_id
93 ret[1]["name"] = subnet_info["name"]
95 ret[1]["ip_version"] = subnet_info["ip_version"]
96 ret[1]["cidr"] = subnet_info["cidr"]
97 ret[1]["allocation_pools"] = subnet_info["allocation_pools"]
98 ret[1]["enable_dhcp"] = subnet_info["enable_dhcp"]
99 ret[1]["gateway_ip"] = subnet_info["gateway_ip"]
100 ret[1]["host_routes"] = subnet_info["host_routes"]
101 ret[1]["dns_nameservers"] = subnet_info["dns_nameservers"]
105 def query_port(auth_info, port_id):
106 neutron = neutronbase.get_neutron_default(fun_name(), auth_info)
109 port_info = neutron.show_port(port_id)["port"]
110 except NeutronClientException as e:
111 logger.warn("NeutronClientException: %s", e.message)
112 return [2, e.message]
114 ret[1]["id"] = port_id
115 ret[1]["name"] = port_info["name"]
116 ret[1]["network_id"] = port_info["network_id"]
117 ret[1]["tenant_id"] = port_info["tenant_id"]
118 if "fixed_ips" in port_info and port_info["fixed_ips"]:
119 ret[1]["ip"] = port_info["fixed_ips"][0]["ip_address"]
120 ret[1]["subnet_id"] = port_info["fixed_ips"][0]["subnet_id"]
123 ret[1]["subnet_id"] = ""
124 ret[1]["mac_address"] = port_info["mac_address"]
125 ret[1]["status"] = port_info["status"]
126 ret[1]["admin_state_up"] = port_info["admin_state_up"]
127 ret[1]["device_id"] = port_info["device_id"]
131 def get_subnet_id(neutron, data, network_id):
133 if "subnet_name" in data and data["subnet_name"]:
134 all_subnets = neutron.list_subnets()
135 filter_subnets = [subnet for subnet in all_subnets["subnets"] if subnet["name"] == data["subnet_name"] and
136 subnet["network_id"] == network_id]
137 count_filter_subnets = len(filter_subnets)
138 if 1 > count_filter_subnets:
139 logger.error("Subnet name(%s) does not exist" % data["subnet_name"])
140 raise VimException("Subnet name(%s) does not exist" % data["subnet_name"])
141 if 1 < count_filter_subnets:
142 for subnet in filter_subnets:
143 logger.error("subnet_id=%s", subnet["id"])
144 raise VimException("%d subnet(%s) exist in network(%s)"
145 % (count_filter_subnets, data["subnet_name"], data["network_name"]))
146 subnet_id = filter_subnets[0]['id']
148 subnets = neutron.list_subnets()
149 filter_subnets = [subnet for subnet in subnets["subnets"] if subnet["network_id"] == network_id]
151 subnet_id = filter_subnets[0]["id"]
155 def create_port(auth_info, data):
156 tenant_id = project.get_tenant_id(fun_name(), auth_info, data["tenant_name"])
158 neutron_admin = neutronbase.get_neutron_default(fun_name(), auth_info)
159 all_nets = neutron_admin.list_networks()
160 filter_nets = [net for net in all_nets['networks'] if net['name'] == data["network_name"]]
161 sel_nets = [net for net in filter_nets if net['tenant_id'] == tenant_id or
162 (net['tenant_id'] != tenant_id and net['shared'])]
163 count_sel_nets = len(sel_nets)
164 if 1 > count_sel_nets:
165 logger.error("Network(%s) does not exist" % data["network_name"])
166 raise VimException("Network(%s) does not exist" % data["network_name"])
167 if 1 < count_sel_nets:
169 logger.error("net_id=%s", net["id"])
170 raise VimException("%d networks(%s) exist in tenant(%s)"
171 % (count_sel_nets, data["network_name"], data["tenant_name"]))
172 network_id = sel_nets[0]['id']
173 if tenant_id != sel_nets[0]['tenant_id']:
174 neutron = neutronbase.get_neutron_by_tenant_id(fun_name(), auth_info, sel_nets[0]['tenant_id'])
176 neutron = neutronbase.get_neutron(fun_name(), auth_info, data["tenant_name"])
179 subnet_id = get_subnet_id(neutron_admin, data, network_id)
183 ports = neutron.list_ports()
184 sel_ports = [port for port in ports['ports'] if port['tenant_id'] == tenant_id and
185 port['network_id'] == network_id]
187 for port in sel_ports:
188 if port['name'] == data["port_name"] and port['fixed_ips']:
189 for fixed_ip in port['fixed_ips']:
190 if fixed_ip['subnet_id'] == subnet_id:
191 filter_ports.append(port)
193 count_filter_ports = len(filter_ports)
194 if 1 < count_filter_ports:
195 for port in filter_ports:
196 logger.error("port_id=%s", port["id"])
197 raise VimException("%d port(%s) exist in subnet(%s)"
198 % (count_filter_ports, data["port_name"], data["subnet_name"]))
199 if 1 == len(filter_ports):
200 logger.debug("Port(%s) is exist!" % data["port_name"])
201 port_data = {'status': filter_ports[0]['status'],
202 'id': filter_ports[0]['id'],
203 'name': filter_ports[0]['name'],
204 'network_id': filter_ports[0]['network_id'],
205 const.RES_TYPE_KEY: const.RES_TYPE_EXIST}
206 return [0, port_data]
211 'name': data["port_name"],
212 'admin_state_up': True,
213 'network_id': network_id,
214 'security_groups': [],
215 'tenant_id': tenant_id
218 if "mac_address" in data and data["mac_address"]:
219 create_param['port']['mac_address'] = data["mac_address"]
220 if "vnic_type" in data and data["vnic_type"]:
221 create_param['port']['binding:vnic_type'] = data["vnic_type"]
222 if "bandwidth" in data and data["bandwidth"]:
223 create_param['port']['bandwidth'] = int(data["bandwidth"])
224 if "bond" in data and data["bond"]:
225 create_param['port']['bond'] = int(data["bond"])
226 if "macbond" in data and data["macbond"]:
227 if 'mac_address' in create_param['port']:
228 create_param['port']['mac_address'] += (',' + data["macbond"])
230 create_param['port']['mac_address'] = data["macbond"]
231 if "ip" in data and data["ip"]:
233 create_param['port']['fixed_ips'] = [{"subnet_id": subnet_id, "ip_address": data["ip"]}]
235 if "allowed_address_pairs" in data and data["allowed_address_pairs"]:
236 create_param['port']['allowed_address_pairs'] = data["allowed_address_pairs"]
237 logger.info("[%s]call neutron.create_port(%s)" % (fun_name(), str(create_param)))
240 port_created = neutron.create_port(create_param)
241 except NeutronClientException as ex:
242 logger.info("create_port exception: %s, %s", str(sys.exc_info()), ex.message)
243 create_param['port'].pop('security_groups')
244 if 'allowed_address_pairs' in create_param['port']:
245 create_param['port'].pop('allowed_address_pairs')
246 logger.info("[%s]recall neutron.create_port(%s)" % (fun_name(), str(create_param)))
247 port_created = neutron.create_port(create_param)
249 port_data = {'status': port_created['port']['status'],
250 'id': port_created['port']['id'],
251 'name': port_created['port']['name'],
252 'network_id': port_created['port']['network_id'],
253 const.RES_TYPE_KEY: const.RES_TYPE_NEW}
254 return [0, port_data]
257 def create_network(auth_info, data):
258 neutron = neutronbase.get_neutron(fun_name(), auth_info, data["tenant"])
259 tenant_id = project.get_tenant_id(fun_name(), auth_info, data["tenant"])
261 neutron_admin = neutronbase.get_neutron_default(fun_name(), auth_info)
262 all_nets = neutron_admin.list_networks()
263 filter_nets = [net for net in all_nets['networks'] if net['name'] == data["network_name"]]
264 sel_nets = [net for net in filter_nets if net['tenant_id'] == tenant_id or
265 (net['tenant_id'] != tenant_id and net['shared'])]
266 count_sel_nets = len(sel_nets)
267 if 1 < count_sel_nets:
268 for sel_net in sel_nets:
269 logger.info("net_id=%s, net_tenant_id=%s", sel_net["id"], sel_net['tenant_id'])
270 raise VimException("Already %d networks are found with name %s" % (count_sel_nets, data["network_name"]))
274 if sel_nets[0]['tenant_id'] != tenant_id:
275 neutron = neutronbase.get_neutron_by_tenant_id(fun_name(), auth_info, sel_nets[0]['tenant_id'])
276 all_subnets = neutron_admin.list_subnets()
277 filter_subnets = [subnet for subnet in all_subnets["subnets"] if subnet["network_id"] == sel_nets[0]["id"]]
279 "status": sel_nets[0]["status"],
280 "id": sel_nets[0]["id"],
281 "name": data["network_name"],
282 "provider:segmentation_id": sel_nets[0]["provider:segmentation_id"],
283 "provider:network_type": sel_nets[0]["provider:network_type"],
284 const.RES_TYPE_KEY: const.RES_TYPE_EXIST,
288 "name": subnet["name"],
289 const.RES_TYPE_KEY: const.RES_TYPE_EXIST
290 }for subnet in filter_subnets
296 'name': data["network_name"],
297 'admin_state_up': True,
298 'tenant_id': tenant_id,
299 'shared': "shared" in data and int(data["shared"]) == const.SHARED_NET}}
300 if "mtu" in data and int(data["mtu"]) != const.DEFAULT_MTU:
301 create_params['network']['mtu'] = int(data["mtu"])
302 if "vlan_transparent" in data and int(data["vlan_transparent"]) == const.SUPPORT_VLAN_TRANSPARENT:
303 create_params['network']['vlan-transparent'] = True
304 if "network_type" in data and data['network_type']:
305 create_params['network']['provider:network_type'] = data['network_type']
306 if "segmentation_id" in data and data['segmentation_id']:
307 create_params['network']['provider:segmentation_id'] = int(data['segmentation_id'])
308 if "physical_network" in data and data['physical_network']:
309 create_params['network']['provider:physical_network'] = data['physical_network']
311 logger.info("[%s]call neutron.create_network(%s)" % (fun_name(), str(create_params)))
312 network_created = neutron.create_network(create_params)
313 network_data = {"status": network_created['network']['status'],
314 "id": network_created['network']['id'],
315 "name": data["network_name"],
316 "provider:segmentation_id": network_created['network']['provider:segmentation_id'],
317 "provider:network_type": network_created['network']['provider:network_type'],
318 const.RES_TYPE_KEY: const.RES_TYPE_NEW,
322 exist_subnet_names = [subnet["name"] for subnet in network_data["subnet_list"]]
323 need_rollback, ret_error = False, None
324 if "subnet_list" in data and data["subnet_list"]:
325 for subnet_data in data["subnet_list"]:
326 if subnet_data["subnet_name"] in exist_subnet_names:
328 ret = create_subnet(neutron, network_data["id"], subnet_data)
330 need_rollback, ret_error = True, ret
332 network_data["subnet_list"].append(ret[1])
334 # rollback when failed to create subnet
336 rollback(neutron_admin, network_data)
339 return [0, network_data]
342 def create_subnet(neutron, network_id, data):
343 all_subnets = neutron.list_subnets()
344 filter_subnets = [subnet for subnet in all_subnets["subnets"]
345 if subnet["network_id"] == network_id and subnet["name"] == data["subnet_name"]]
348 "id": filter_subnets[0]["id"],
349 "name": data["subnet_name"],
350 const.RES_TYPE_KEY: const.RES_TYPE_EXIST
355 'network_id': network_id,
356 'name': data["subnet_name"],
357 'cidr': data["cidr"],
358 'ip_version': int(data["ip_version"]) if "ip_version" in data else const.IPV4, }}
359 create_params["subnet"]["enable_dhcp"] = ("enable_dhcp" in data and
360 int(data["enable_dhcp"]) == const.ENABLE_DHCP)
361 if "gateway_ip" in data and data["gateway_ip"]:
362 create_params["subnet"]["gateway_ip"] = data["gateway_ip"]
364 create_params["subnet"]["gateway_ip"] = None
365 if "dns_nameservers" in data and data["dns_nameservers"]:
366 create_params["subnet"]["dns_nameservers"] = data["dns_nameservers"]
367 if "allocation_pools" in data and data["allocation_pools"]:
368 create_params["subnet"]["allocation_pools"] = data["allocation_pools"]
369 if "host_routes" in data and data["host_routes"]:
370 create_params["subnet"]["host_routes"] = data["host_routes"]
372 logger.info("[%s]call neutron.create_subnet(%s)" % (fun_name(), str(create_params)))
373 subnet_created = neutron.create_subnet(create_params)
374 return [0, {"id": subnet_created["subnet"]["id"],
375 "name": data["subnet_name"],
376 const.RES_TYPE_KEY: const.RES_TYPE_NEW}]
377 except Exception as ex:
378 logger.error(traceback.format_exc())
379 logger.error(str(sys.exc_info()))
380 return [1, ex.message if ex.message else str(sys.exc_info())]
383 def rollback(neutron, network_data):
384 for subnet_data in network_data["subnet_list"]:
385 if subnet_data[const.RES_TYPE_KEY] == const.RES_TYPE_NEW:
387 logger.info("[%s]call neutron.delete_subnet(%s)" % (fun_name(), subnet_data["id"]))
388 neutron.delete_subnet(subnet_data["subnet_id"])
390 logger.error("[%s]%s", fun_name(), str(sys.exc_info()))
392 if network_data and network_data[const.RES_TYPE_KEY] == const.RES_TYPE_NEW:
394 logger.info("[%s]call neutron.delete_network(%s)" % (fun_name(), network_data["id"]))
395 neutron.delete_network(network_data["id"])
397 logger.error("[%s]%s", fun_name(), str(sys.exc_info()))
400 def delete_network(auth_info, network_id):
401 neutron = neutronbase.get_neutron_default(fun_name(), auth_info)
403 neutron.delete_network(network_id)
404 except Exception as ex:
405 logger.error(traceback.format_exc())
406 msg = ex.message if ex.message else str(sys.exc_info())
408 if 404 == ex.status_code:
409 return [0, ex.message]
410 return [1, "Vim exception."]
411 return [0, "Network(%s) is deleted" % network_id]
414 def delete_subnet(auth_info, subnet_id):
415 neutron = neutronbase.get_neutron_default(fun_name(), auth_info)
417 neutron.delete_subnet(subnet_id)
418 except NeutronClientException as e:
419 logger.warn("[%s]NetworkNotFoundClient: %s", fun_name(), e.message)
420 return [0, e.message]
421 return [0, "Subnet(%s) is deleted" % subnet_id]
424 def delete_port(auth_info, port_id):
425 neutron = neutronbase.get_neutron_default(fun_name(), auth_info)
427 neutron.delete_port(port_id)
428 except NeutronClientException as e:
429 logger.warn("[%s]NeutronClientException: %s", fun_name(), e.message)
430 return [0, e.message]
431 return [0, "Port(%s) is deleted" % port_id]