blob: cd529de82d211dc51089ab1ce119b3497c14eda4 [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={}):
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
tierno73ad9e42016-09-12 18:11:11 +020095 self.logger = logging.getLogger('openmano.vim')
tiernofe789902016-09-29 14:20:44 +000096 if log_level:
97 self.logger.setLevel( getattr(logging, log_level) )
tiernoae4a8d12016-07-08 12:30:39 +020098 if not self.url_admin: #try to use normal url
99 self.url_admin = self.url
tierno7edb6752016-03-21 17:37:52 +0100100
101 def __getitem__(self,index):
tierno392f2852016-05-13 12:28:55 +0200102 if index=='tenant_id':
103 return self.tenant_id
104 if index=='tenant_name':
105 return self.tenant_name
tierno7edb6752016-03-21 17:37:52 +0100106 elif index=='id':
107 return self.id
108 elif index=='name':
109 return self.name
110 elif index=='user':
111 return self.user
112 elif index=='passwd':
113 return self.passwd
114 elif index=='url':
115 return self.url
116 elif index=='url_admin':
117 return self.url_admin
118 elif index=="config":
119 return self.config
120 else:
121 raise KeyError("Invalid key '%s'" %str(index))
122
123 def __setitem__(self,index, value):
tierno392f2852016-05-13 12:28:55 +0200124 if index=='tenant_id':
125 self.tenant_id = value
126 if index=='tenant_name':
127 self.tenant_name = value
tierno7edb6752016-03-21 17:37:52 +0100128 elif index=='id':
129 self.id = value
130 elif index=='name':
131 self.name = value
132 elif index=='user':
133 self.user = value
134 elif index=='passwd':
135 self.passwd = value
136 elif index=='url':
137 self.url = value
138 elif index=='url_admin':
139 self.url_admin = value
140 else:
141 raise KeyError("Invalid key '%s'" %str(index))
tierno7edb6752016-03-21 17:37:52 +0100142
143 def new_tenant(self,tenant_name,tenant_description):
tiernoae4a8d12016-07-08 12:30:39 +0200144 '''Adds a new tenant to VIM with this name and description,
145 returns the tenant identifier'''
146 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100147
148 def delete_tenant(self,tenant_id,):
149 '''Delete a tenant from VIM'''
150 '''Returns the tenant identifier'''
tiernoae4a8d12016-07-08 12:30:39 +0200151 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100152
tiernoae4a8d12016-07-08 12:30:39 +0200153 def get_tenant_list(self, filter_dict={}):
154 '''Obtain tenants of VIM
155 filter_dict can contain the following keys:
156 name: filter by tenant name
157 id: filter by tenant uuid/id
158 <other VIM specific>
159 Returns the tenant list of dictionaries:
160 [{'name':'<name>, 'id':'<id>, ...}, ...]
161 '''
162 raise vimconnNotImplemented( "Should have implemented this" )
163
garciadeblas9f8456e2016-09-05 05:02:59 +0200164 def new_network(self,net_name, net_type, ip_profile=None, shared=False):
tiernoae4a8d12016-07-08 12:30:39 +0200165 '''Adds a tenant network to VIM
garciadeblas9f8456e2016-09-05 05:02:59 +0200166 net_name is the name
167 net_type can be 'bridge','data'.'ptp'. TODO: this need to be revised
168 ip_profile is a dict containing the IP parameters of the network
tiernoae4a8d12016-07-08 12:30:39 +0200169 shared is a boolean
170 Returns the network identifier'''
171 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100172
173 def get_network_list(self, filter_dict={}):
174 '''Obtain tenant networks of VIM
175 Filter_dict can be:
176 name: network name
177 id: network uuid
178 shared: boolean
179 tenant_id: tenant
180 admin_state_up: boolean
181 status: 'ACTIVE'
tiernoae4a8d12016-07-08 12:30:39 +0200182 Returns the network list of dictionaries:
183 [{<the fields at Filter_dict plus some VIM specific>}, ...]
184 List can be empty
tierno7edb6752016-03-21 17:37:52 +0100185 '''
tiernoae4a8d12016-07-08 12:30:39 +0200186 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100187
tiernoae4a8d12016-07-08 12:30:39 +0200188 def get_network(self, net_id):
189 '''Obtain network details of net_id VIM network'
190 Return a dict with the fields at filter_dict (see get_network_list) plus some VIM specific>}, ...]'''
191 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100192
tiernoae4a8d12016-07-08 12:30:39 +0200193 def delete_network(self, net_id):
194 '''Deletes a tenant network from VIM, provide the network id.
195 Returns the network identifier or raise an exception'''
196 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100197
tiernoae4a8d12016-07-08 12:30:39 +0200198 def refresh_nets_status(self, net_list):
199 '''Get the status of the networks
200 Params: the list of network identifiers
201 Returns a dictionary with:
202 net_id: #VIM id of this network
203 status: #Mandatory. Text with one of:
204 # DELETED (not found at vim)
205 # VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
206 # OTHER (Vim reported other status not understood)
207 # ERROR (VIM indicates an ERROR status)
208 # ACTIVE, INACTIVE, DOWN (admin down),
209 # BUILD (on building process)
210 #
211 error_msg: #Text with VIM error message, if any. Or the VIM connection ERROR
212 vim_info: #Text with plain information obtained from vim (yaml.safe_dump)
tierno7edb6752016-03-21 17:37:52 +0100213
tiernoae4a8d12016-07-08 12:30:39 +0200214 '''
215 raise vimconnNotImplemented( "Should have implemented this" )
216
217 def get_flavor(self, flavor_id):
tierno7edb6752016-03-21 17:37:52 +0100218 '''Obtain flavor details from the VIM
tiernoae4a8d12016-07-08 12:30:39 +0200219 Returns the flavor dict details {'id':<>, 'name':<>, other vim specific } #TODO to concrete
tierno7edb6752016-03-21 17:37:52 +0100220 '''
tiernoae4a8d12016-07-08 12:30:39 +0200221 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100222
tiernoae4a8d12016-07-08 12:30:39 +0200223 def new_flavor(self, flavor_data):
224 '''Adds a tenant flavor to VIM
225 flavor_data contains a dictionary with information, keys:
226 name: flavor name
227 ram: memory (cloud type) in MBytes
228 vpcus: cpus (cloud type)
229 extended: EPA parameters
230 - numas: #items requested in same NUMA
231 memory: number of 1G huge pages memory
232 paired-threads|cores|threads: number of paired hyperthreads, complete cores OR individual threads
233 interfaces: # passthrough(PT) or SRIOV interfaces attached to this numa
234 - name: interface name
235 dedicated: yes|no|yes:sriov; for PT, SRIOV or only one SRIOV for the physical NIC
236 bandwidth: X Gbps; requested guarantee bandwidth
237 vpci: requested virtual PCI address
238 disk: disk size
239 is_public:
240
241
242
243 #TODO to concrete
244 Returns the flavor identifier'''
245 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100246
tiernoae4a8d12016-07-08 12:30:39 +0200247 def delete_flavor(self, flavor_id):
248 '''Deletes a tenant flavor from VIM identify by its id
249 Returns the used id or raise an exception'''
250 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100251
tiernoae4a8d12016-07-08 12:30:39 +0200252 def new_image(self,image_dict):
tierno7edb6752016-03-21 17:37:52 +0100253 '''
254 Adds a tenant image to VIM
255 Returns:
256 200, image-id if the image is created
257 <0, message if there is an error
258 '''
tiernoae4a8d12016-07-08 12:30:39 +0200259 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100260
tiernoae4a8d12016-07-08 12:30:39 +0200261 def delete_image(self, image_id):
tierno7edb6752016-03-21 17:37:52 +0100262 '''Deletes a tenant image from VIM'''
263 '''Returns the HTTP response code and a message indicating details of the success or fail'''
tiernoae4a8d12016-07-08 12:30:39 +0200264 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100265
tiernoae4a8d12016-07-08 12:30:39 +0200266 def get_image_id_from_path(self, path):
garciadeblasb69fa9f2016-09-28 12:04:10 +0200267 '''Get the image id from image path in the VIM database. Returns the image_id'''
tiernoae4a8d12016-07-08 12:30:39 +0200268 raise vimconnNotImplemented( "Should have implemented this" )
269
garciadeblasb69fa9f2016-09-28 12:04:10 +0200270 def get_image_list(self, filter_dict={}):
271 '''Obtain tenant images from VIM
272 Filter_dict can be:
273 name: image name
274 id: image uuid
275 checksum: image checksum
276 location: image path
277 Returns the image list of dictionaries:
278 [{<the fields at Filter_dict plus some VIM specific>}, ...]
279 List can be empty
280 '''
281 raise vimconnNotImplemented( "Should have implemented this" )
282
tiernoa4e1a6e2016-08-31 14:19:40 +0200283 def new_vminstance(self,name,description,start,image_id,flavor_id,net_list,cloud_config=None):
tierno7edb6752016-03-21 17:37:52 +0100284 '''Adds a VM instance to VIM
285 Params:
286 start: indicates if VM must start or boot in pause mode. Ignored
287 image_id,flavor_id: image and flavor uuid
288 net_list: list of interfaces, each one is a dictionary with:
289 name:
290 net_id: network uuid to connect
291 vpci: virtual vcpi to assign
292 model: interface model, virtio, e2000, ...
293 mac_address:
294 use: 'data', 'bridge', 'mgmt'
295 type: 'virtual', 'PF', 'VF', 'VFnotShared'
296 vim_id: filled/added by this function
tiernoa4e1a6e2016-08-31 14:19:40 +0200297 cloud_config: can be a text script to be passed directly to cloud-init,
298 or an object to inject users and ssh keys with format:
299 key-pairs: [] list of keys to install to the default user
300 users: [{ name, key-pairs: []}] list of users to add with their key-pair
tierno7edb6752016-03-21 17:37:52 +0100301 #TODO ip, security groups
302 Returns >=0, the instance identifier
303 <0, error_text
304 '''
tiernoae4a8d12016-07-08 12:30:39 +0200305 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100306
tiernoae4a8d12016-07-08 12:30:39 +0200307 def get_vminstance(self,vm_id):
tierno7edb6752016-03-21 17:37:52 +0100308 '''Returns the VM instance information from VIM'''
tiernoae4a8d12016-07-08 12:30:39 +0200309 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100310
tiernoae4a8d12016-07-08 12:30:39 +0200311 def delete_vminstance(self, vm_id):
tierno7edb6752016-03-21 17:37:52 +0100312 '''Removes a VM instance from VIM'''
313 '''Returns the instance identifier'''
tiernoae4a8d12016-07-08 12:30:39 +0200314 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100315
tiernoae4a8d12016-07-08 12:30:39 +0200316 def refresh_vms_status(self, vm_list):
317 '''Get the status of the virtual machines and their interfaces/ports
318 Params: the list of VM identifiers
319 Returns a dictionary with:
320 vm_id: #VIM id of this Virtual Machine
321 status: #Mandatory. Text with one of:
322 # DELETED (not found at vim)
323 # VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
324 # OTHER (Vim reported other status not understood)
325 # ERROR (VIM indicates an ERROR status)
326 # ACTIVE, PAUSED, SUSPENDED, INACTIVE (not running),
327 # CREATING (on building process), ERROR
328 # ACTIVE:NoMgmtIP (Active but any of its interface has an IP address
329 #
330 error_msg: #Text with VIM error message, if any. Or the VIM connection ERROR
331 vim_info: #Text with plain information obtained from vim (yaml.safe_dump)
332 interfaces:
333 - vim_info: #Text with plain information obtained from vim (yaml.safe_dump)
334 mac_address: #Text format XX:XX:XX:XX:XX:XX
335 vim_net_id: #network id where this interface is connected
336 vim_interface_id: #interface/port VIM id
337 ip_address: #null, or text with IPv4, IPv6 address
tierno7edb6752016-03-21 17:37:52 +0100338 '''
tiernoae4a8d12016-07-08 12:30:39 +0200339 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100340
tiernoae4a8d12016-07-08 12:30:39 +0200341 def action_vminstance(self, vm_id, action_dict):
342 '''Send and action over a VM instance from VIM
343 Returns the vm_id if the action was successfully sent to the VIM'''
344 raise vimconnNotImplemented( "Should have implemented this" )
345
346 def get_vminstance_console(self,vm_id, console_type="vnc"):
347 '''
348 Get a console for the virtual machine
349 Params:
350 vm_id: uuid of the VM
351 console_type, can be:
352 "novnc" (by default), "xvpvnc" for VNC types,
353 "rdp-html5" for RDP types, "spice-html5" for SPICE types
354 Returns dict with the console parameters:
355 protocol: ssh, ftp, http, https, ...
356 server: usually ip address
357 port: the http, ssh, ... port
358 suffix: extra text, e.g. the http path and query string
359 '''
360 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100361
tiernoae4a8d12016-07-08 12:30:39 +0200362#NOT USED METHODS in current version
363
tierno7edb6752016-03-21 17:37:52 +0100364 def host_vim2gui(self, host, server_dict):
365 '''Transform host dictionary from VIM format to GUI format,
366 and append to the server_dict
367 '''
tiernoae4a8d12016-07-08 12:30:39 +0200368 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100369
370 def get_hosts_info(self):
371 '''Get the information of deployed hosts
372 Returns the hosts content'''
tiernoae4a8d12016-07-08 12:30:39 +0200373 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100374
375 def get_hosts(self, vim_tenant):
376 '''Get the hosts and deployed instances
377 Returns the hosts content'''
tiernoae4a8d12016-07-08 12:30:39 +0200378 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100379
380 def get_processor_rankings(self):
381 '''Get the processor rankings in the VIM database'''
tiernoae4a8d12016-07-08 12:30:39 +0200382 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100383
tiernoae4a8d12016-07-08 12:30:39 +0200384 def new_host(self, host_data):
385 '''Adds a new host to VIM'''
386 '''Returns status code of the VIM response'''
387 raise vimconnNotImplemented( "Should have implemented this" )
388
389 def new_external_port(self, port_data):
390 '''Adds a external port to VIM'''
391 '''Returns the port identifier'''
392 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100393
tiernoae4a8d12016-07-08 12:30:39 +0200394 def new_external_network(self,net_name,net_type):
395 '''Adds a external network to VIM (shared)'''
396 '''Returns the network identifier'''
397 raise vimconnNotImplemented( "Should have implemented this" )
398
399 def connect_port_network(self, port_id, network_id, admin=False):
400 '''Connects a external port to a network'''
401 '''Returns status code of the VIM response'''
402 raise vimconnNotImplemented( "Should have implemented this" )
403
404 def new_vminstancefromJSON(self, vm_data):
405 '''Adds a VM instance to VIM'''
406 '''Returns the instance identifier'''
407 raise vimconnNotImplemented( "Should have implemented this" )
tierno7edb6752016-03-21 17:37:52 +0100408