blob: b5f8b07084c378365741461e3882202c9ed6a016 [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 '''
tiernofe789902016-09-29 14:20:44 +000085 def __init__(self, uuid, name, tenant_id, tenant_name, url, url_admin=None, user=None, passwd=None, log_level=None, config={}):
tiernofb1987b2016-11-15 17:35:06 +000086 """Constructor of VIM
87 "uuid": id asigned to this VIM
88 "name": name assigned to this VIM, can be used for logging
89 "tenant_id", tenant_name: VIM tenant to be used
90 "url_admin": optional, url used for administrative tasks
91 "user", "passwd": credentials of the VIM user
92 "log_level": if must use a different log_level than the general one
93 "config": dictionary with extra VIM information. This contains a consolidate version of general VIM config at create
94 and particular VIM config at attach
95 Returns can raise an exception if some check is done and fails
96 """
tierno7edb6752016-03-21 17:37:52 +010097 self.id = uuid
98 self.name = name
99 self.url = url
100 self.url_admin = url_admin
tierno392f2852016-05-13 12:28:55 +0200101 self.tenant_id = tenant_id
102 self.tenant_name = tenant_name
tierno7edb6752016-03-21 17:37:52 +0100103 self.user = user
104 self.passwd = passwd
105 self.config = config
tierno73ad9e42016-09-12 18:11:11 +0200106 self.logger = logging.getLogger('openmano.vim')
tiernofe789902016-09-29 14:20:44 +0000107 if log_level:
108 self.logger.setLevel( getattr(logging, log_level) )
tiernoae4a8d12016-07-08 12:30:39 +0200109 if not self.url_admin: #try to use normal url
110 self.url_admin = self.url
tierno7edb6752016-03-21 17:37:52 +0100111
112 def __getitem__(self,index):
tierno392f2852016-05-13 12:28:55 +0200113 if index=='tenant_id':
114 return self.tenant_id
115 if index=='tenant_name':
116 return self.tenant_name
tierno7edb6752016-03-21 17:37:52 +0100117 elif index=='id':
118 return self.id
119 elif index=='name':
120 return self.name
121 elif index=='user':
122 return self.user
123 elif index=='passwd':
124 return self.passwd
125 elif index=='url':
126 return self.url
127 elif index=='url_admin':
128 return self.url_admin
129 elif index=="config":
130 return self.config
131 else:
132 raise KeyError("Invalid key '%s'" %str(index))
133
134 def __setitem__(self,index, value):
tierno392f2852016-05-13 12:28:55 +0200135 if index=='tenant_id':
136 self.tenant_id = value
137 if index=='tenant_name':
138 self.tenant_name = value
tierno7edb6752016-03-21 17:37:52 +0100139 elif index=='id':
140 self.id = value
141 elif index=='name':
142 self.name = value
143 elif index=='user':
144 self.user = value
145 elif index=='passwd':
146 self.passwd = value
147 elif index=='url':
148 self.url = value
149 elif index=='url_admin':
150 self.url_admin = value
151 else:
152 raise KeyError("Invalid key '%s'" %str(index))
tierno7edb6752016-03-21 17:37:52 +0100153
154 def new_tenant(self,tenant_name,tenant_description):
tiernofb1987b2016-11-15 17:35:06 +0000155 """Adds a new tenant to VIM with this name and description, this is done using admin_url if provided
156 "tenant_name": string max lenght 64
157 "tenant_description": string max length 256
158 returns the tenant identifier or raise exception
159 """
tiernoae4a8d12016-07-08 12:30:39 +0200160 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100161
162 def delete_tenant(self,tenant_id,):
tiernofb1987b2016-11-15 17:35:06 +0000163 """Delete a tenant from VIM
164 tenant_id: returned VIM tenant_id on "new_tenant"
165 Returns None on success. Raises and exception of failure. If tenant is not found raises vimconnNotFoundException
166 """
tiernoae4a8d12016-07-08 12:30:39 +0200167 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100168
tiernoae4a8d12016-07-08 12:30:39 +0200169 def get_tenant_list(self, filter_dict={}):
170 '''Obtain tenants of VIM
tiernofb1987b2016-11-15 17:35:06 +0000171 filter_dict dictionary that can contain the following keys:
tiernoae4a8d12016-07-08 12:30:39 +0200172 name: filter by tenant name
173 id: filter by tenant uuid/id
174 <other VIM specific>
tiernofb1987b2016-11-15 17:35:06 +0000175 Returns the tenant list of dictionaries, and empty list if no tenant match all the filers:
tiernoae4a8d12016-07-08 12:30:39 +0200176 [{'name':'<name>, 'id':'<id>, ...}, ...]
177 '''
178 raise vimconnNotImplemented( "Should have implemented this" )
179
garciadeblas9f8456e2016-09-05 05:02:59 +0200180 def new_network(self,net_name, net_type, ip_profile=None, shared=False):
tiernofb1987b2016-11-15 17:35:06 +0000181 """Adds a tenant network to VIM
garciadeblas9f8456e2016-09-05 05:02:59 +0200182 net_name is the name
183 net_type can be 'bridge','data'.'ptp'. TODO: this need to be revised
tiernofb1987b2016-11-15 17:35:06 +0000184 ip_profile is a dict containing the IP parameters of the network
185 "ip-version": {"type":"string", "enum":["IPv4","IPv6"]},
186 "subnet-address": ip_prefix_schema,
187 "gateway-address": ip_schema,
188 "dns-address": ip_schema,
189 "dhcp": dhcp_schema
190
tiernoae4a8d12016-07-08 12:30:39 +0200191 shared is a boolean
tiernofb1987b2016-11-15 17:35:06 +0000192 Returns the network identifier on success or raises and exeption on failure
193 """
tiernoae4a8d12016-07-08 12:30:39 +0200194 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100195
196 def get_network_list(self, filter_dict={}):
197 '''Obtain tenant networks of VIM
198 Filter_dict can be:
199 name: network name
200 id: network uuid
201 shared: boolean
202 tenant_id: tenant
203 admin_state_up: boolean
204 status: 'ACTIVE'
tiernoae4a8d12016-07-08 12:30:39 +0200205 Returns the network list of dictionaries:
206 [{<the fields at Filter_dict plus some VIM specific>}, ...]
207 List can be empty
tierno7edb6752016-03-21 17:37:52 +0100208 '''
tiernoae4a8d12016-07-08 12:30:39 +0200209 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100210
tiernoae4a8d12016-07-08 12:30:39 +0200211 def get_network(self, net_id):
212 '''Obtain network details of net_id VIM network'
213 Return a dict with the fields at filter_dict (see get_network_list) plus some VIM specific>}, ...]'''
214 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100215
tiernoae4a8d12016-07-08 12:30:39 +0200216 def delete_network(self, net_id):
217 '''Deletes a tenant network from VIM, provide the network id.
218 Returns the network identifier or raise an exception'''
219 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100220
tiernoae4a8d12016-07-08 12:30:39 +0200221 def refresh_nets_status(self, net_list):
222 '''Get the status of the networks
223 Params: the list of network identifiers
224 Returns a dictionary with:
225 net_id: #VIM id of this network
226 status: #Mandatory. Text with one of:
227 # DELETED (not found at vim)
228 # VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
229 # OTHER (Vim reported other status not understood)
230 # ERROR (VIM indicates an ERROR status)
231 # ACTIVE, INACTIVE, DOWN (admin down),
232 # BUILD (on building process)
233 #
234 error_msg: #Text with VIM error message, if any. Or the VIM connection ERROR
235 vim_info: #Text with plain information obtained from vim (yaml.safe_dump)
tierno7edb6752016-03-21 17:37:52 +0100236
tiernoae4a8d12016-07-08 12:30:39 +0200237 '''
238 raise vimconnNotImplemented( "Should have implemented this" )
239
240 def get_flavor(self, flavor_id):
tierno7edb6752016-03-21 17:37:52 +0100241 '''Obtain flavor details from the VIM
tiernoae4a8d12016-07-08 12:30:39 +0200242 Returns the flavor dict details {'id':<>, 'name':<>, other vim specific } #TODO to concrete
tierno7edb6752016-03-21 17:37:52 +0100243 '''
tiernoae4a8d12016-07-08 12:30:39 +0200244 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100245
tiernoae4a8d12016-07-08 12:30:39 +0200246 def new_flavor(self, flavor_data):
247 '''Adds a tenant flavor to VIM
248 flavor_data contains a dictionary with information, keys:
249 name: flavor name
250 ram: memory (cloud type) in MBytes
251 vpcus: cpus (cloud type)
252 extended: EPA parameters
253 - numas: #items requested in same NUMA
254 memory: number of 1G huge pages memory
255 paired-threads|cores|threads: number of paired hyperthreads, complete cores OR individual threads
256 interfaces: # passthrough(PT) or SRIOV interfaces attached to this numa
257 - name: interface name
258 dedicated: yes|no|yes:sriov; for PT, SRIOV or only one SRIOV for the physical NIC
259 bandwidth: X Gbps; requested guarantee bandwidth
260 vpci: requested virtual PCI address
261 disk: disk size
262 is_public:
263
264
265
266 #TODO to concrete
267 Returns the flavor identifier'''
268 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100269
tiernoae4a8d12016-07-08 12:30:39 +0200270 def delete_flavor(self, flavor_id):
271 '''Deletes a tenant flavor from VIM identify by its id
272 Returns the used id or raise an exception'''
273 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100274
tiernoae4a8d12016-07-08 12:30:39 +0200275 def new_image(self,image_dict):
tierno7edb6752016-03-21 17:37:52 +0100276 '''
277 Adds a tenant image to VIM
278 Returns:
279 200, image-id if the image is created
280 <0, message if there is an error
281 '''
tiernoae4a8d12016-07-08 12:30:39 +0200282 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100283
tiernoae4a8d12016-07-08 12:30:39 +0200284 def delete_image(self, image_id):
tierno7edb6752016-03-21 17:37:52 +0100285 '''Deletes a tenant image from VIM'''
286 '''Returns the HTTP response code and a message indicating details of the success or fail'''
tiernoae4a8d12016-07-08 12:30:39 +0200287 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100288
tiernoae4a8d12016-07-08 12:30:39 +0200289 def get_image_id_from_path(self, path):
garciadeblasb69fa9f2016-09-28 12:04:10 +0200290 '''Get the image id from image path in the VIM database. Returns the image_id'''
tiernoae4a8d12016-07-08 12:30:39 +0200291 raise vimconnNotImplemented( "Should have implemented this" )
292
garciadeblasb69fa9f2016-09-28 12:04:10 +0200293 def get_image_list(self, filter_dict={}):
294 '''Obtain tenant images from VIM
295 Filter_dict can be:
296 name: image name
297 id: image uuid
298 checksum: image checksum
299 location: image path
300 Returns the image list of dictionaries:
301 [{<the fields at Filter_dict plus some VIM specific>}, ...]
302 List can be empty
303 '''
304 raise vimconnNotImplemented( "Should have implemented this" )
305
tiernoa4e1a6e2016-08-31 14:19:40 +0200306 def new_vminstance(self,name,description,start,image_id,flavor_id,net_list,cloud_config=None):
tierno7edb6752016-03-21 17:37:52 +0100307 '''Adds a VM instance to VIM
308 Params:
309 start: indicates if VM must start or boot in pause mode. Ignored
310 image_id,flavor_id: image and flavor uuid
311 net_list: list of interfaces, each one is a dictionary with:
312 name:
313 net_id: network uuid to connect
314 vpci: virtual vcpi to assign
315 model: interface model, virtio, e2000, ...
316 mac_address:
317 use: 'data', 'bridge', 'mgmt'
318 type: 'virtual', 'PF', 'VF', 'VFnotShared'
319 vim_id: filled/added by this function
tiernoa4e1a6e2016-08-31 14:19:40 +0200320 cloud_config: can be a text script to be passed directly to cloud-init,
321 or an object to inject users and ssh keys with format:
322 key-pairs: [] list of keys to install to the default user
323 users: [{ name, key-pairs: []}] list of users to add with their key-pair
tierno7edb6752016-03-21 17:37:52 +0100324 #TODO ip, security groups
325 Returns >=0, the instance identifier
326 <0, error_text
327 '''
tiernoae4a8d12016-07-08 12:30:39 +0200328 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100329
tiernoae4a8d12016-07-08 12:30:39 +0200330 def get_vminstance(self,vm_id):
tierno7edb6752016-03-21 17:37:52 +0100331 '''Returns the VM instance information from VIM'''
tiernoae4a8d12016-07-08 12:30:39 +0200332 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100333
tiernoae4a8d12016-07-08 12:30:39 +0200334 def delete_vminstance(self, vm_id):
tierno7edb6752016-03-21 17:37:52 +0100335 '''Removes a VM instance from VIM'''
336 '''Returns the instance identifier'''
tiernoae4a8d12016-07-08 12:30:39 +0200337 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100338
tiernoae4a8d12016-07-08 12:30:39 +0200339 def refresh_vms_status(self, vm_list):
340 '''Get the status of the virtual machines and their interfaces/ports
341 Params: the list of VM identifiers
342 Returns a dictionary with:
343 vm_id: #VIM id of this Virtual Machine
344 status: #Mandatory. Text with one of:
345 # DELETED (not found at vim)
346 # VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
347 # OTHER (Vim reported other status not understood)
348 # ERROR (VIM indicates an ERROR status)
349 # ACTIVE, PAUSED, SUSPENDED, INACTIVE (not running),
350 # CREATING (on building process), ERROR
351 # ACTIVE:NoMgmtIP (Active but any of its interface has an IP address
352 #
353 error_msg: #Text with VIM error message, if any. Or the VIM connection ERROR
354 vim_info: #Text with plain information obtained from vim (yaml.safe_dump)
355 interfaces:
356 - vim_info: #Text with plain information obtained from vim (yaml.safe_dump)
357 mac_address: #Text format XX:XX:XX:XX:XX:XX
358 vim_net_id: #network id where this interface is connected
359 vim_interface_id: #interface/port VIM id
360 ip_address: #null, or text with IPv4, IPv6 address
tierno7edb6752016-03-21 17:37:52 +0100361 '''
tiernoae4a8d12016-07-08 12:30:39 +0200362 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100363
tiernoae4a8d12016-07-08 12:30:39 +0200364 def action_vminstance(self, vm_id, action_dict):
365 '''Send and action over a VM instance from VIM
366 Returns the vm_id if the action was successfully sent to the VIM'''
367 raise vimconnNotImplemented( "Should have implemented this" )
368
369 def get_vminstance_console(self,vm_id, console_type="vnc"):
370 '''
371 Get a console for the virtual machine
372 Params:
373 vm_id: uuid of the VM
374 console_type, can be:
375 "novnc" (by default), "xvpvnc" for VNC types,
376 "rdp-html5" for RDP types, "spice-html5" for SPICE types
377 Returns dict with the console parameters:
378 protocol: ssh, ftp, http, https, ...
379 server: usually ip address
380 port: the http, ssh, ... port
381 suffix: extra text, e.g. the http path and query string
382 '''
383 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100384
tiernoae4a8d12016-07-08 12:30:39 +0200385#NOT USED METHODS in current version
386
tierno7edb6752016-03-21 17:37:52 +0100387 def host_vim2gui(self, host, server_dict):
388 '''Transform host dictionary from VIM format to GUI format,
389 and append to the server_dict
390 '''
tiernoae4a8d12016-07-08 12:30:39 +0200391 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100392
393 def get_hosts_info(self):
394 '''Get the information of deployed hosts
395 Returns the hosts content'''
tiernoae4a8d12016-07-08 12:30:39 +0200396 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100397
398 def get_hosts(self, vim_tenant):
399 '''Get the hosts and deployed instances
400 Returns the hosts content'''
tiernoae4a8d12016-07-08 12:30:39 +0200401 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100402
403 def get_processor_rankings(self):
404 '''Get the processor rankings in the VIM database'''
tiernoae4a8d12016-07-08 12:30:39 +0200405 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100406
tiernoae4a8d12016-07-08 12:30:39 +0200407 def new_host(self, host_data):
408 '''Adds a new host to VIM'''
409 '''Returns status code of the VIM response'''
410 raise vimconnNotImplemented( "Should have implemented this" )
411
412 def new_external_port(self, port_data):
413 '''Adds a external port to VIM'''
414 '''Returns the port identifier'''
415 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100416
tiernoae4a8d12016-07-08 12:30:39 +0200417 def new_external_network(self,net_name,net_type):
418 '''Adds a external network to VIM (shared)'''
419 '''Returns the network identifier'''
420 raise vimconnNotImplemented( "Should have implemented this" )
421
422 def connect_port_network(self, port_id, network_id, admin=False):
423 '''Connects a external port to a network'''
424 '''Returns status code of the VIM response'''
425 raise vimconnNotImplemented( "Should have implemented this" )
426
427 def new_vminstancefromJSON(self, vm_data):
428 '''Adds a VM instance to VIM'''
429 '''Returns the instance identifier'''
430 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100431