f3bdd30afceaa140726a657d073f2cb5a789dde0
[vfc/nfvo/lcm.git] / lcm / pub / nfvi / vim / api / multivim / api.py
1 # Copyright 2017 ZTE Corporation.
2 #
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
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14 import json
15 import logging
16
17 from lcm.pub.nfvi.vim.lib.vimexception import VimException
18 from lcm.pub.utils.restcall import req_by_msb
19 from lcm.pub.nfvi.vim import const
20
21 logger = logging.getLogger(__name__)
22
23 VIM_DRIVER_BASE_URL = "openoapi/multivim/v1"
24
25 def call(vim_id, tenant_id, res, method, data=''):
26     if data and not isinstance(data, (str, unicode)):
27         data = json.JSONEncoder().encode(data)
28     url = "{base_url}/{vim_id}{tenant_id}/{res}".format(
29         base_url=VIM_DRIVER_BASE_URL, 
30         vim_id=vim_id,
31         tenant_id="/" + tenant_id if tenant_id else "",
32         res=res)
33     ret = req_by_msb(url, method, data)
34     if ret[0] > 0:
35         raise VimException(ret[1], ret[2])
36     return json.JSONDecoder().decode(ret[1]) if ret[1] else {}
37
38 ######################################################################
39
40 def create_image(vim_id, tenant_id, data):
41     return call(vim_id, tenant_id, "images", "POST", data)
42
43 def delete_image(vim_id, tenant_id, image_id):
44     return call(vim_id, tenant_id, "images/%s" % image_id, "DELETE")
45     
46 def get_image(vim_id, tenant_id, image_id):
47     return call(vim_id, tenant_id, "images/%s" % image_id, "GET")
48     
49 def list_image(vim_id, tenant_id):
50     return call(vim_id, tenant_id, "images", "GET")
51
52 ######################################################################
53
54 def create_network(vim_id, tenant_id, data):
55     return call(vim_id, tenant_id, "networks", "POST", data)
56
57 def delete_network(vim_id, tenant_id, network_id):
58     return call(vim_id, tenant_id, "networks/%s" % network_id, "DELETE")
59     
60 def get_network(vim_id, tenant_id, network_id):
61     return call(vim_id, tenant_id, "networks/%s" % network_id, "GET")
62     
63 def list_network(vim_id, tenant_id):
64     return call(vim_id, tenant_id, "networks", "GET")
65
66 ######################################################################
67
68 def create_subnet(vim_id, tenant_id, data):
69     return call(vim_id, tenant_id, "subnets", "POST", data)
70
71 def delete_subnet(vim_id, tenant_id, subnet_id):
72     return call(vim_id, tenant_id, "subnets/%s" % subnet_id, "DELETE")
73     
74 def get_subnet(vim_id, tenant_id, subnet_id):
75     return call(vim_id, tenant_id, "subnets/%s" % subnet_id, "GET")
76     
77 def list_subnet(vim_id, tenant_id):
78     return call(vim_id, tenant_id, "subnets", "GET")
79
80 ######################################################################
81
82 def create_port(vim_id, tenant_id, data):
83     return call(vim_id, tenant_id, "ports", "POST", data)
84
85 def delete_port(vim_id, tenant_id, port_id):
86     return call(vim_id, tenant_id, "ports/%s" % port_id, "DELETE")
87     
88 def get_port(vim_id, tenant_id, port_id):
89     return call(vim_id, tenant_id, "ports/%s" % port_id, "GET")
90     
91 def list_port(vim_id, tenant_id):
92     return call(vim_id, tenant_id, "ports", "GET")
93
94 ######################################################################
95
96 def create_flavor(vim_id, tenant_id, data):
97     return call(vim_id, tenant_id, "flavors", "POST", data)
98
99 def delete_flavor(vim_id, tenant_id, flavor_id):
100     return call(vim_id, tenant_id, "flavors/%s" % flavor_id, "DELETE")
101     
102 def get_flavor(vim_id, tenant_id, flavor_id):
103     return call(vim_id, tenant_id, "flavors/%s" % flavor_id, "GET")
104     
105 def list_flavor(vim_id, tenant_id):
106     return call(vim_id, tenant_id, "flavors", "GET")
107
108 ######################################################################
109
110 def create_vm(vim_id, tenant_id, data):
111     return call(vim_id, tenant_id, "servers", "POST", data)
112
113 def delete_vm(vim_id, tenant_id, vm_id):
114     return call(vim_id, tenant_id, "servers/%s" % vm_id, "DELETE")
115     
116 def get_vm(vim_id, tenant_id, vm_id):
117     return call(vim_id, tenant_id, "servers/%s" % vm_id, "GET")
118     
119 def list_vm(vim_id, tenant_id):
120     return call(vim_id, tenant_id, "servers", "GET")
121
122 ######################################################################
123
124 def create_volume(vim_id, tenant_id, data):
125     return call(vim_id, tenant_id, "volumes", "POST", data)
126
127 def delete_volume(vim_id, tenant_id, volume_id):
128     return call(vim_id, tenant_id, "volumes/%s" % volume_id, "DELETE")
129     
130 def get_volume(vim_id, tenant_id, volume_id):
131     return call(vim_id, tenant_id, "volumes/%s" % volume_id, "GET")
132     
133 def list_volume(vim_id, tenant_id):
134     return call(vim_id, tenant_id, "volumes", "GET")
135
136 ######################################################################
137
138 def list_tenant(vim_id, tenant_name=""):
139     res = "tenants"
140     if tenant_name:
141         res = "%s?name=%s" % (res, tenant_name)
142     return call(vim_id, "", res, "GET")
143
144 ######################################################################
145
146
147 class MultiVimApi:
148
149     def login(self, connect_info):
150         self.vim_id = connect_info["vimid"]
151         self.tenant_name = connect_info["tenant"]
152         tenants = list_tenant(self.vim_id)
153         for tenant in tenants["tenants"]:
154             if self.tenant_name == tenant["name"]:
155                 self.tenant_id = tenant["id"]
156                 return [0, connect_info]
157         raise VimException(1, "Tenant(%s) not exist" % self.tenant_name)
158
159     def query_net(self, auth_info, net_id):
160         net = get_network(self.vim_id, self.tenant_id, net_id)
161         return [0, {
162             "id": net.get("id", ""),
163             "name": net.get("name", ""),
164             "status": net.get("status", ""),
165             "admin_state_up": net.get("admin_state_up", True),
166             "network_type": net.get("networkType", ""),
167             "physical_network": net.get("physicalNetwork", ""),
168             "segmentation_id": net.get("segmentationId", ""),
169             "tenant_id": self.tenant_id,
170             "tenant_name": self.tenant_name,
171             "subnets": net.get("subnets", []),
172             "shared": net.get("shared", True),
173             "router_external": net.get("routerExternal", "")
174         }]
175
176     def query_nets(self, auth_info):
177         nets = list_network(self.vim_id, self.tenant_id)
178         return [0, {"networks": [{
179             "id": net.get("id", ""),
180             "name": net.get("name", ""),
181             "status": net.get("status", ""),
182             "admin_state_up": net.get("admin_state_up", True),
183             "network_type": net.get("networkType", ""),
184             "physical_network": net.get("physicalNetwork", ""),
185             "segmentation_id": net.get("segmentationId", ""),
186             "tenant_id": self.tenant_id,
187             "tenant_name": self.tenant_name,
188             "subnets": net.get("subnets", []),
189             "shared": net.get("shared", True),
190             "router_external": net.get("routerExternal", "")
191         } for net in nets["networks"]]}]      
192
193     def query_subnet(self, auth_info, subnet_id):
194         subnet_info = get_subnet(self.vim_id, self.tenant_id, subnet_id)
195         ret = [0, {}]
196         ret[1]["id"] = subnet_id
197         ret[1]["name"] = subnet_info.get("name", "")
198         ret[1]["status"] = ""
199         ret[1]["ip_version"] = subnet_info.get("ipVersion", 4)
200         ret[1]["cidr"] = subnet_info.get("cidr", "")
201         ret[1]["allocation_pools"] = subnet_info.get("allocationPools", [])
202         ret[1]["enable_dhcp"] = subnet_info.get("enableDhcp", False)
203         ret[1]["gateway_ip"] = subnet_info.get("gatewayIp", "")
204         ret[1]["host_routes"] = subnet_info.get("hostRoutes", [])
205         ret[1]["dns_nameservers"] = subnet_info.get("dnsNameservers", [])
206         return ret
207
208     def query_port(self, auth_info, port_id):
209         port_info = get_port(self.vim_id, self.tenant_id, port_id)
210         ret = [0, {}]
211         ret[1]["id"] = port_id
212         ret[1]["name"] = port_info.get("name", "")
213         ret[1]["network_id"] = port_info.get("networkId", "")
214         ret[1]["tenant_id"] = self.tenant_id,
215         ret[1]["ip"] = port_info.get("ip", "")
216         ret[1]["subnet_id"] = port_info.get("subnetId", "")
217         ret[1]["mac_address"] = port_info.get("macAddress", "")
218         ret[1]["status"] = port_info.get("status", "")
219         ret[1]["admin_state_up"] = port_info.get("admin_state_up", True)
220         ret[1]["device_id"] = port_info.get("device_id", "")
221         return ret
222
223     def create_port(self, auth_info, data):
224         return [0, data]
225
226     def delete_port(self, auth_info, port_id):
227         return [0, ""]
228
229     def create_image(self, auth_info, data):
230         image_data = {
231             "name": data["image_name"],
232             "imagePath": data["image_url"],
233             "imageType": data["image_type"],
234             "containerFormat": "bare",
235             "visibility": "public",
236             "properties": [] 
237         }
238         image = create_image(self.vim_id, self.tenant_id, image_data)
239         return [0, {
240             "id": image["id"], 
241             "name": image["name"], 
242             const.RES_TYPE_KEY: image["returnCode"]}]
243
244     def get_image(self, auth_info, image_id):
245         image = get_image(self.vim_id, self.tenant_id, image_id)
246         return [0, {
247             "id": image["id"], 
248             "name": image["name"], 
249             "size": image["size"], 
250             "status": image["status"]}]      
251
252     def get_images(self, auth_info):
253         images = list_image(self.vim_id, self.tenant_id)
254         return [0, {"image_list": [{
255             "id": img["id"], 
256             "name": img["name"], 
257             "size": img["size"], 
258             "status": img["status"]
259             } for img in images["images"]]}]
260
261     def delete_image(self, auth_info, image_id):
262         return [0, ""]
263
264     def create_network(self, auth_info, data):
265         net_data = {
266             "name": data["network_name"],
267             "shared": True,
268             "networkType": data["network_type"]
269         }
270         if "physical_network" in data and data['physical_network']:
271             net_data["physicalNetwork"] = data['physical_network']
272         if "vlan_transparent" in data and data["vlan_transparent"]: 
273             net_data["vlanTransparent"] = data["vlan_transparent"]
274         if "segmentation_id" in data and data['segmentation_id']:
275             net_data["segmentationId"] = data["segmentation_id"]
276         if "routerExternal" in data and data['routerExternal']:
277             net_data["routerExternal"] = data["routerExternal"]
278         net = create_network(self.vim_id, self.tenant_id, net_data)
279         network_id = net["id"]
280         ret_net = {
281             "status": net.get("status", ""),
282             "id": network_id,
283             "name": net.get("name", ""),
284             "provider:segmentation_id": net.get("segmentationId", ""),
285             "provider:network_type": net.get("networkType", ""),
286             const.RES_TYPE_KEY: net["returnCode"],
287             "subnet_list": []
288         }
289         if "subnet_list" in data and data["subnet_list"]:
290             subnet = data["subnet_list"][0]           
291             subnet_data = {
292                 "networkId": network_id,
293                 "name": subnet["subnet_name"],
294                 "cidr": subnet["cidr"],
295                 "ipVersion": const.IPV4,
296                 "enableDhcp": False           
297             }
298             if "ip_version" in subnet and subnet["ip_version"]:
299                 subnet_data["ipVersion"] = int(subnet["ip_version"])
300             if "enable_dhcp" in subnet and subnet["enable_dhcp"]:
301                 subnet_data["enableDhcp"] = int(subnet["enable_dhcp"]) == const.ENABLE_DHCP
302             if "gateway_ip" in subnet and subnet["gateway_ip"]:
303                 subnet_data["gatewayIp"] = subnet["gateway_ip"]
304             if "dns_nameservers" in subnet and subnet["dns_nameservers"]:
305                 subnet_data["dnsNameservers"] = subnet["dns_nameservers"]
306             if "allocation_pools" in subnet and subnet["allocation_pools"]:
307                 subnet_data["allocationPools"] = subnet["allocation_pools"]
308             if "host_routes" in subnet and subnet["host_routes"]:
309                 subnet_data["hostRoutes"] = subnet["host_routes"]
310             subnet_create = create_subnet(self.vim_id, self.tenant_id, subnet_data)
311             ret_net["subnet_list"].append({
312                 "id": subnet_create["id"],
313                 "name": subnet_create["name"],
314                 const.RES_TYPE_KEY: net["returnCode"]})
315         return [0, ret_net]
316
317     def delete_network(self, auth_info, network_id):
318         return delete_network(self.vim_id, self.tenant_id, network_id)
319
320     def delete_subnet(self, auth_info, subnet_id):
321         return delete_subnet(self.vim_id, self.tenant_id, subnet_id)