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