Changes in openmano_schemas for OSM R1
[osm/RO.git] / vimconn.py
1 # -*- coding: utf-8 -*-
2
3 ##
4 # Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
5 # This file is part of openmano
6 # All Rights Reserved.
7 #
8 # Licensed under the Apache License, Version 2.0 (the "License"); you may
9 # not use this file except in compliance with the License. You may obtain
10 # a copy of the License at
11 #
12 # http://www.apache.org/licenses/LICENSE-2.0
13 #
14 # Unless required by applicable law or agreed to in writing, software
15 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17 # License for the specific language governing permissions and limitations
18 # under the License.
19 #
20 # For those usages not covered by the Apache License, Version 2.0 please
21 # contact with: nfvlabs@tid.es
22 ##
23
24 '''
25 vimconn implement an Abstract class for the vim connector plugins
26 with the definition of the method to be implemented.
27 '''
28 __author__="Alfonso Tierno"
29 __date__ ="$16-oct-2015 11:09:29$"
30
31 import logging
32
33 #Error variables
34 HTTP_Bad_Request = 400
35 HTTP_Unauthorized = 401
36 HTTP_Not_Found = 404
37 HTTP_Method_Not_Allowed = 405
38 HTTP_Request_Timeout = 408
39 HTTP_Conflict = 409
40 HTTP_Not_Implemented = 501
41 HTTP_Service_Unavailable = 503
42 HTTP_Internal_Server_Error = 500
43
44 class vimconnException(Exception):
45 '''Common and base class Exception for all vimconnector exceptions'''
46 def __init__(self, message, http_code=HTTP_Bad_Request):
47 Exception.__init__(self, message)
48 self.http_code = http_code
49
50 class vimconnConnectionException(vimconnException):
51 '''Connectivity error with the VIM'''
52 def __init__(self, message, http_code=HTTP_Service_Unavailable):
53 vimconnException.__init__(self, message, http_code)
54
55 class vimconnUnexpectedResponse(vimconnException):
56 '''Get an wrong response from VIM'''
57 def __init__(self, message, http_code=HTTP_Service_Unavailable):
58 vimconnException.__init__(self, message, http_code)
59
60 class vimconnAuthException(vimconnException):
61 '''Invalid credentials or authorization to perform this action over the VIM'''
62 def __init__(self, message, http_code=HTTP_Unauthorized):
63 vimconnException.__init__(self, message, http_code)
64
65 class vimconnNotFoundException(vimconnException):
66 '''The item is not found at VIM'''
67 def __init__(self, message, http_code=HTTP_Not_Found):
68 vimconnException.__init__(self, message, http_code)
69
70 class vimconnConflictException(vimconnException):
71 '''There is a conflict, e.g. more item found than one'''
72 def __init__(self, message, http_code=HTTP_Conflict):
73 vimconnException.__init__(self, message, http_code)
74
75 class vimconnNotImplemented(vimconnException):
76 '''The method is not implemented by the connected'''
77 def __init__(self, message, http_code=HTTP_Not_Implemented):
78 vimconnException.__init__(self, message, http_code)
79
80 class vimconnector():
81 '''Abstract base class for all the VIM connector plugins
82 These plugins must implement a vimconnector class derived from this
83 and all these methods
84 '''
85 def __init__(self, uuid, name, tenant_id, tenant_name, url, url_admin=None, user=None, passwd=None, log_level="ERROR", config={}):
86 self.id = uuid
87 self.name = name
88 self.url = url
89 self.url_admin = url_admin
90 self.tenant_id = tenant_id
91 self.tenant_name = tenant_name
92 self.user = user
93 self.passwd = passwd
94 self.config = config
95 self.logger = logging.getLogger('mano.vim')
96 self.logger.setLevel( getattr(logging, log_level) )
97 if not self.url_admin: #try to use normal url
98 self.url_admin = self.url
99
100 def __getitem__(self,index):
101 if index=='tenant_id':
102 return self.tenant_id
103 if index=='tenant_name':
104 return self.tenant_name
105 elif index=='id':
106 return self.id
107 elif index=='name':
108 return self.name
109 elif index=='user':
110 return self.user
111 elif index=='passwd':
112 return self.passwd
113 elif index=='url':
114 return self.url
115 elif index=='url_admin':
116 return self.url_admin
117 elif index=="config":
118 return self.config
119 else:
120 raise KeyError("Invalid key '%s'" %str(index))
121
122 def __setitem__(self,index, value):
123 if index=='tenant_id':
124 self.tenant_id = value
125 if index=='tenant_name':
126 self.tenant_name = value
127 elif index=='id':
128 self.id = value
129 elif index=='name':
130 self.name = value
131 elif index=='user':
132 self.user = value
133 elif index=='passwd':
134 self.passwd = value
135 elif index=='url':
136 self.url = value
137 elif index=='url_admin':
138 self.url_admin = value
139 else:
140 raise KeyError("Invalid key '%s'" %str(index))
141
142 def new_tenant(self,tenant_name,tenant_description):
143 '''Adds a new tenant to VIM with this name and description,
144 returns the tenant identifier'''
145 raise vimconnNotImplemented( "Should have implemented this" )
146
147 def delete_tenant(self,tenant_id,):
148 '''Delete a tenant from VIM'''
149 '''Returns the tenant identifier'''
150 raise vimconnNotImplemented( "Should have implemented this" )
151
152 def get_tenant_list(self, filter_dict={}):
153 '''Obtain tenants of VIM
154 filter_dict can contain the following keys:
155 name: filter by tenant name
156 id: filter by tenant uuid/id
157 <other VIM specific>
158 Returns the tenant list of dictionaries:
159 [{'name':'<name>, 'id':'<id>, ...}, ...]
160 '''
161 raise vimconnNotImplemented( "Should have implemented this" )
162
163 def new_network(self,net_name, net_type, shared=False):
164 '''Adds a tenant network to VIM
165 net_type can be 'bridge','data'.'ptp'. TODO: this need to be revised
166 shared is a boolean
167 Returns the network identifier'''
168 raise vimconnNotImplemented( "Should have implemented this" )
169
170 def get_network_list(self, filter_dict={}):
171 '''Obtain tenant networks of VIM
172 Filter_dict can be:
173 name: network name
174 id: network uuid
175 shared: boolean
176 tenant_id: tenant
177 admin_state_up: boolean
178 status: 'ACTIVE'
179 Returns the network list of dictionaries:
180 [{<the fields at Filter_dict plus some VIM specific>}, ...]
181 List can be empty
182 '''
183 raise vimconnNotImplemented( "Should have implemented this" )
184
185 def get_network(self, net_id):
186 '''Obtain network details of net_id VIM network'
187 Return a dict with the fields at filter_dict (see get_network_list) plus some VIM specific>}, ...]'''
188 raise vimconnNotImplemented( "Should have implemented this" )
189
190 def delete_network(self, net_id):
191 '''Deletes a tenant network from VIM, provide the network id.
192 Returns the network identifier or raise an exception'''
193 raise vimconnNotImplemented( "Should have implemented this" )
194
195 def refresh_nets_status(self, net_list):
196 '''Get the status of the networks
197 Params: the list of network identifiers
198 Returns a dictionary with:
199 net_id: #VIM id of this network
200 status: #Mandatory. Text with one of:
201 # DELETED (not found at vim)
202 # VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
203 # OTHER (Vim reported other status not understood)
204 # ERROR (VIM indicates an ERROR status)
205 # ACTIVE, INACTIVE, DOWN (admin down),
206 # BUILD (on building process)
207 #
208 error_msg: #Text with VIM error message, if any. Or the VIM connection ERROR
209 vim_info: #Text with plain information obtained from vim (yaml.safe_dump)
210
211 '''
212 raise vimconnNotImplemented( "Should have implemented this" )
213
214 def get_flavor(self, flavor_id):
215 '''Obtain flavor details from the VIM
216 Returns the flavor dict details {'id':<>, 'name':<>, other vim specific } #TODO to concrete
217 '''
218 raise vimconnNotImplemented( "Should have implemented this" )
219
220 def new_flavor(self, flavor_data):
221 '''Adds a tenant flavor to VIM
222 flavor_data contains a dictionary with information, keys:
223 name: flavor name
224 ram: memory (cloud type) in MBytes
225 vpcus: cpus (cloud type)
226 extended: EPA parameters
227 - numas: #items requested in same NUMA
228 memory: number of 1G huge pages memory
229 paired-threads|cores|threads: number of paired hyperthreads, complete cores OR individual threads
230 interfaces: # passthrough(PT) or SRIOV interfaces attached to this numa
231 - name: interface name
232 dedicated: yes|no|yes:sriov; for PT, SRIOV or only one SRIOV for the physical NIC
233 bandwidth: X Gbps; requested guarantee bandwidth
234 vpci: requested virtual PCI address
235 disk: disk size
236 is_public:
237
238
239
240 #TODO to concrete
241 Returns the flavor identifier'''
242 raise vimconnNotImplemented( "Should have implemented this" )
243
244 def delete_flavor(self, flavor_id):
245 '''Deletes a tenant flavor from VIM identify by its id
246 Returns the used id or raise an exception'''
247 raise vimconnNotImplemented( "Should have implemented this" )
248
249 def new_image(self,image_dict):
250 '''
251 Adds a tenant image to VIM
252 Returns:
253 200, image-id if the image is created
254 <0, message if there is an error
255 '''
256 raise vimconnNotImplemented( "Should have implemented this" )
257
258 def delete_image(self, image_id):
259 '''Deletes a tenant image from VIM'''
260 '''Returns the HTTP response code and a message indicating details of the success or fail'''
261 raise vimconnNotImplemented( "Should have implemented this" )
262
263 def get_image_id_from_path(self, path):
264 '''Get the image id from image path in the VIM database'''
265 '''Returns:
266 0,"Image not found" if there are no images with that path
267 1,image-id if there is one image with that path
268 <0,message if there was an error (Image not found, error contacting VIM, more than 1 image with that path, etc.)
269 '''
270 raise vimconnNotImplemented( "Should have implemented this" )
271
272 def new_vminstance(self,name,description,start,image_id,flavor_id,net_list):
273 '''Adds a VM instance to VIM
274 Params:
275 start: indicates if VM must start or boot in pause mode. Ignored
276 image_id,flavor_id: image and flavor uuid
277 net_list: list of interfaces, each one is a dictionary with:
278 name:
279 net_id: network uuid to connect
280 vpci: virtual vcpi to assign
281 model: interface model, virtio, e2000, ...
282 mac_address:
283 use: 'data', 'bridge', 'mgmt'
284 type: 'virtual', 'PF', 'VF', 'VFnotShared'
285 vim_id: filled/added by this function
286 #TODO ip, security groups
287 Returns >=0, the instance identifier
288 <0, error_text
289 '''
290 raise vimconnNotImplemented( "Should have implemented this" )
291
292 def get_vminstance(self,vm_id):
293 '''Returns the VM instance information from VIM'''
294 raise vimconnNotImplemented( "Should have implemented this" )
295
296 def delete_vminstance(self, vm_id):
297 '''Removes a VM instance from VIM'''
298 '''Returns the instance identifier'''
299 raise vimconnNotImplemented( "Should have implemented this" )
300
301 def refresh_vms_status(self, vm_list):
302 '''Get the status of the virtual machines and their interfaces/ports
303 Params: the list of VM identifiers
304 Returns a dictionary with:
305 vm_id: #VIM id of this Virtual Machine
306 status: #Mandatory. Text with one of:
307 # DELETED (not found at vim)
308 # VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
309 # OTHER (Vim reported other status not understood)
310 # ERROR (VIM indicates an ERROR status)
311 # ACTIVE, PAUSED, SUSPENDED, INACTIVE (not running),
312 # CREATING (on building process), ERROR
313 # ACTIVE:NoMgmtIP (Active but any of its interface has an IP address
314 #
315 error_msg: #Text with VIM error message, if any. Or the VIM connection ERROR
316 vim_info: #Text with plain information obtained from vim (yaml.safe_dump)
317 interfaces:
318 - vim_info: #Text with plain information obtained from vim (yaml.safe_dump)
319 mac_address: #Text format XX:XX:XX:XX:XX:XX
320 vim_net_id: #network id where this interface is connected
321 vim_interface_id: #interface/port VIM id
322 ip_address: #null, or text with IPv4, IPv6 address
323 '''
324 raise vimconnNotImplemented( "Should have implemented this" )
325
326 def action_vminstance(self, vm_id, action_dict):
327 '''Send and action over a VM instance from VIM
328 Returns the vm_id if the action was successfully sent to the VIM'''
329 raise vimconnNotImplemented( "Should have implemented this" )
330
331 def get_vminstance_console(self,vm_id, console_type="vnc"):
332 '''
333 Get a console for the virtual machine
334 Params:
335 vm_id: uuid of the VM
336 console_type, can be:
337 "novnc" (by default), "xvpvnc" for VNC types,
338 "rdp-html5" for RDP types, "spice-html5" for SPICE types
339 Returns dict with the console parameters:
340 protocol: ssh, ftp, http, https, ...
341 server: usually ip address
342 port: the http, ssh, ... port
343 suffix: extra text, e.g. the http path and query string
344 '''
345 raise vimconnNotImplemented( "Should have implemented this" )
346
347 #NOT USED METHODS in current version
348
349 def host_vim2gui(self, host, server_dict):
350 '''Transform host dictionary from VIM format to GUI format,
351 and append to the server_dict
352 '''
353 raise vimconnNotImplemented( "Should have implemented this" )
354
355 def get_hosts_info(self):
356 '''Get the information of deployed hosts
357 Returns the hosts content'''
358 raise vimconnNotImplemented( "Should have implemented this" )
359
360 def get_hosts(self, vim_tenant):
361 '''Get the hosts and deployed instances
362 Returns the hosts content'''
363 raise vimconnNotImplemented( "Should have implemented this" )
364
365 def get_processor_rankings(self):
366 '''Get the processor rankings in the VIM database'''
367 raise vimconnNotImplemented( "Should have implemented this" )
368
369 def new_host(self, host_data):
370 '''Adds a new host to VIM'''
371 '''Returns status code of the VIM response'''
372 raise vimconnNotImplemented( "Should have implemented this" )
373
374 def new_external_port(self, port_data):
375 '''Adds a external port to VIM'''
376 '''Returns the port identifier'''
377 raise vimconnNotImplemented( "Should have implemented this" )
378
379 def new_external_network(self,net_name,net_type):
380 '''Adds a external network to VIM (shared)'''
381 '''Returns the network identifier'''
382 raise vimconnNotImplemented( "Should have implemented this" )
383
384 def connect_port_network(self, port_id, network_id, admin=False):
385 '''Connects a external port to a network'''
386 '''Returns status code of the VIM response'''
387 raise vimconnNotImplemented( "Should have implemented this" )
388
389 def new_vminstancefromJSON(self, vm_data):
390 '''Adds a VM instance to VIM'''
391 '''Returns the instance identifier'''
392 raise vimconnNotImplemented( "Should have implemented this" )
393