blob: b06f04ea064c2c99ceca8757d27dcd44a81477e9 [file] [log] [blame]
tierno7edb6752016-03-21 17:37:52 +01001# -*- 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'''
25vimconn 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
tiernoae4a8d12016-07-08 12:30:39 +020031import logging
32
tierno7edb6752016-03-21 17:37:52 +010033#Error variables
34HTTP_Bad_Request = 400
35HTTP_Unauthorized = 401
36HTTP_Not_Found = 404
37HTTP_Method_Not_Allowed = 405
38HTTP_Request_Timeout = 408
39HTTP_Conflict = 409
tiernoae4a8d12016-07-08 12:30:39 +020040HTTP_Not_Implemented = 501
tierno7edb6752016-03-21 17:37:52 +010041HTTP_Service_Unavailable = 503
42HTTP_Internal_Server_Error = 500
43
tiernoae4a8d12016-07-08 12:30:39 +020044class 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
50class 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
55class 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
60class 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
65class 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
70class 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
75class 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)
tierno7edb6752016-03-21 17:37:52 +010079
80class vimconnector():
81 '''Abstract base class for all the VIM connector plugins
tiernoae4a8d12016-07-08 12:30:39 +020082 These plugins must implement a vimconnector class derived from this
tierno7edb6752016-03-21 17:37:52 +010083 and all these methods
84 '''
tiernoae4a8d12016-07-08 12:30:39 +020085 def __init__(self, uuid, name, tenant_id, tenant_name, url, url_admin=None, user=None, passwd=None, log_level="ERROR", config={}):
tierno7edb6752016-03-21 17:37:52 +010086 self.id = uuid
87 self.name = name
88 self.url = url
89 self.url_admin = url_admin
tierno392f2852016-05-13 12:28:55 +020090 self.tenant_id = tenant_id
91 self.tenant_name = tenant_name
tierno7edb6752016-03-21 17:37:52 +010092 self.user = user
93 self.passwd = passwd
94 self.config = config
tiernoae4a8d12016-07-08 12:30:39 +020095 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
tierno7edb6752016-03-21 17:37:52 +010099
100 def __getitem__(self,index):
tierno392f2852016-05-13 12:28:55 +0200101 if index=='tenant_id':
102 return self.tenant_id
103 if index=='tenant_name':
104 return self.tenant_name
tierno7edb6752016-03-21 17:37:52 +0100105 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):
tierno392f2852016-05-13 12:28:55 +0200123 if index=='tenant_id':
124 self.tenant_id = value
125 if index=='tenant_name':
126 self.tenant_name = value
tierno7edb6752016-03-21 17:37:52 +0100127 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))
tierno7edb6752016-03-21 17:37:52 +0100141
142 def new_tenant(self,tenant_name,tenant_description):
tiernoae4a8d12016-07-08 12:30:39 +0200143 '''Adds a new tenant to VIM with this name and description,
144 returns the tenant identifier'''
145 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100146
147 def delete_tenant(self,tenant_id,):
148 '''Delete a tenant from VIM'''
149 '''Returns the tenant identifier'''
tiernoae4a8d12016-07-08 12:30:39 +0200150 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100151
tiernoae4a8d12016-07-08 12:30:39 +0200152 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" )
tierno7edb6752016-03-21 17:37:52 +0100169
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'
tiernoae4a8d12016-07-08 12:30:39 +0200179 Returns the network list of dictionaries:
180 [{<the fields at Filter_dict plus some VIM specific>}, ...]
181 List can be empty
tierno7edb6752016-03-21 17:37:52 +0100182 '''
tiernoae4a8d12016-07-08 12:30:39 +0200183 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100184
tiernoae4a8d12016-07-08 12:30:39 +0200185 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" )
tierno7edb6752016-03-21 17:37:52 +0100189
tiernoae4a8d12016-07-08 12:30:39 +0200190 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" )
tierno7edb6752016-03-21 17:37:52 +0100194
tiernoae4a8d12016-07-08 12:30:39 +0200195 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)
tierno7edb6752016-03-21 17:37:52 +0100210
tiernoae4a8d12016-07-08 12:30:39 +0200211 '''
212 raise vimconnNotImplemented( "Should have implemented this" )
213
214 def get_flavor(self, flavor_id):
tierno7edb6752016-03-21 17:37:52 +0100215 '''Obtain flavor details from the VIM
tiernoae4a8d12016-07-08 12:30:39 +0200216 Returns the flavor dict details {'id':<>, 'name':<>, other vim specific } #TODO to concrete
tierno7edb6752016-03-21 17:37:52 +0100217 '''
tiernoae4a8d12016-07-08 12:30:39 +0200218 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100219
tiernoae4a8d12016-07-08 12:30:39 +0200220 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" )
tierno7edb6752016-03-21 17:37:52 +0100243
tiernoae4a8d12016-07-08 12:30:39 +0200244 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" )
tierno7edb6752016-03-21 17:37:52 +0100248
tiernoae4a8d12016-07-08 12:30:39 +0200249 def new_image(self,image_dict):
tierno7edb6752016-03-21 17:37:52 +0100250 '''
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 '''
tiernoae4a8d12016-07-08 12:30:39 +0200256 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100257
tiernoae4a8d12016-07-08 12:30:39 +0200258 def delete_image(self, image_id):
tierno7edb6752016-03-21 17:37:52 +0100259 '''Deletes a tenant image from VIM'''
260 '''Returns the HTTP response code and a message indicating details of the success or fail'''
tiernoae4a8d12016-07-08 12:30:39 +0200261 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100262
tiernoae4a8d12016-07-08 12:30:39 +0200263 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):
tierno7edb6752016-03-21 17:37:52 +0100273 '''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 '''
tiernoae4a8d12016-07-08 12:30:39 +0200290 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100291
tiernoae4a8d12016-07-08 12:30:39 +0200292 def get_vminstance(self,vm_id):
tierno7edb6752016-03-21 17:37:52 +0100293 '''Returns the VM instance information from VIM'''
tiernoae4a8d12016-07-08 12:30:39 +0200294 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100295
tiernoae4a8d12016-07-08 12:30:39 +0200296 def delete_vminstance(self, vm_id):
tierno7edb6752016-03-21 17:37:52 +0100297 '''Removes a VM instance from VIM'''
298 '''Returns the instance identifier'''
tiernoae4a8d12016-07-08 12:30:39 +0200299 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100300
tiernoae4a8d12016-07-08 12:30:39 +0200301 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
tierno7edb6752016-03-21 17:37:52 +0100323 '''
tiernoae4a8d12016-07-08 12:30:39 +0200324 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100325
tiernoae4a8d12016-07-08 12:30:39 +0200326 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" )
tierno7edb6752016-03-21 17:37:52 +0100346
tiernoae4a8d12016-07-08 12:30:39 +0200347#NOT USED METHODS in current version
348
tierno7edb6752016-03-21 17:37:52 +0100349 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 '''
tiernoae4a8d12016-07-08 12:30:39 +0200353 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100354
355 def get_hosts_info(self):
356 '''Get the information of deployed hosts
357 Returns the hosts content'''
tiernoae4a8d12016-07-08 12:30:39 +0200358 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100359
360 def get_hosts(self, vim_tenant):
361 '''Get the hosts and deployed instances
362 Returns the hosts content'''
tiernoae4a8d12016-07-08 12:30:39 +0200363 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100364
365 def get_processor_rankings(self):
366 '''Get the processor rankings in the VIM database'''
tiernoae4a8d12016-07-08 12:30:39 +0200367 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100368
tiernoae4a8d12016-07-08 12:30:39 +0200369 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" )
tierno7edb6752016-03-21 17:37:52 +0100378
tiernoae4a8d12016-07-08 12:30:39 +0200379 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" )
tierno7edb6752016-03-21 17:37:52 +0100393