4 # Copyright 2016 RIFT.IO Inc
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
23 from keystoneclient
import v3
as ksclientv3
24 from keystoneclient
.v2_0
import client
as ksclientv2
25 from novaclient
import client
as nova_client
26 from neutronclient
.neutron
import client
as ntclient
27 from glanceclient
.v2
import client
as glclient
28 from ceilometerclient
import client
as ceilo_client
31 import novaclient
.exceptions
as NovaException
32 import keystoneclient
.exceptions
as KeystoneExceptions
33 import neutronclient
.common
.exceptions
as NeutronException
34 import glanceclient
.exc
as GlanceException
36 logger
= logging
.getLogger('rwcal.openstack.drv')
37 logger
.setLevel(logging
.DEBUG
)
39 class ValidationError(Exception):
43 class KeystoneDriver(object):
45 Driver base-class for keystoneclient APIs
47 def __init__(self
, ksclient
):
49 Constructor for KeystoneDriver base class
53 self
.ksclient
= ksclient
55 def get_username(self
):
57 Returns the username associated with keystoneclient connection
61 def get_password(self
):
63 Returns the password associated with keystoneclient connection
67 def get_tenant_name(self
):
69 Returns the tenant name associated with keystoneclient connection
71 return self
._tenant
_name
73 def _get_keystone_connection(self
):
75 Returns object of class python-keystoneclient class
77 if not hasattr(self
, '_keystone_connection'):
78 self
._keystone
_connection
= self
.ksclient(**self
._get
_keystone
_credentials
())
79 return self
._keystone
_connection
81 def is_auth_token_valid(self
, token_expiry
, time_fmt
):
83 Performs validity on auth_token
85 token_expiry (string): Expiry time for token
86 time_fmt (string) : Format for expiry string in auth_ref
89 True/False (Boolean): (auth_token is valid or auth_token is invalid)
93 import dateutil
.parser
95 now
= datetime
.datetime
.timetuple(datetime
.datetime
.utcnow())
96 expires_at
= dateutil
.parser
.parse(token_expiry
)
97 t_now
= time
.mktime(now
)
98 t_expiry
= time
.mktime(expires_at
.timetuple())
100 if (t_expiry
<= t_now
) or ((t_expiry
- t_now
) < 300 ):
101 ### Token has expired or about to expire (5 minute)
102 delattr(self
, '_keystone_connection')
106 except Exception as e
:
107 logger
.error("Received except %s during auth_token validity check" %str
(e
))
108 logger
.info("Can not validate the auth_token. Assuming invalid")
112 def get_service_endpoint(self
, service_type
, endpoint_type
):
114 Returns requested type of endpoint for requested service type
116 service_type (string): Service Type (e.g. computev3, image, network)
117 endpoint_type(string): Endpoint Type (e.g. publicURL,adminURL,internalURL)
119 service_endpoint(string): Service endpoint string
121 endpoint_kwargs
= {'service_type' : service_type
,
122 'endpoint_type' : endpoint_type
}
124 ksconn
= self
._get
_keystone
_connection
()
125 service_endpoint
= ksconn
.service_catalog
.url_for(**endpoint_kwargs
)
126 except (KeystoneExceptions
.Unauthorized
, KeystoneExceptions
.AuthorizationFailure
) as e
:
128 except Exception as e
:
129 logger
.error("OpenstackDriver: Service Catalog discovery operation failed for service_type: %s, endpoint_type: %s. Exception: %s" %(service_type
, endpoint_type
, str(e
)))
131 return service_endpoint
134 def get_raw_token(self
):
136 Returns a valid raw_auth_token string
138 Returns (string): raw_auth_token string
140 ksconn
= self
._get
_keystone
_connection
()
142 raw_token
= ksconn
.get_raw_token_from_identity_service(auth_url
= self
._auth
_url
,
143 token
= self
.get_auth_token())
144 except KeystoneExceptions
.AuthorizationFailure
as e
:
145 logger
.error("OpenstackDriver: get_raw_token_from_identity_service Failure. Exception: %s" %(str(e
)))
148 except Exception as e
:
149 logger
.error("OpenstackDriver: Could not retrieve raw_token. Exception: %s" %(str(e
)))
153 def get_tenant_id(self
):
155 Returns tenant_id for the project/tenant. Tenant name is provided during
158 Returns (string): Tenant ID
160 ksconn
= self
._get
_keystone
_connection
()
161 return ksconn
.tenant_id
163 def get_security_mode(self
):
165 Returns certificate_validation policy in case of SSL/TLS connection.
166 This policy is provided during class instantiation
169 The boolean returned are designed to match the python-client class instantiation ("insecure") value.
170 for nova/neutron/glance/keystone clients
172 True: No certificate validation required -- Insecure mode
173 False: Certificate validation required -- Secure mode
175 return self
._insecure
177 def tenant_list(self
):
179 Returns list of tenants
183 def tenant_create(self
, name
):
189 def tenant_delete(self
, tenant_id
):
191 Deletes a tenant identified by tenant_id
195 def roles_list(self
):
198 def roles_create(self
):
201 def roles_delete(self
):
204 class KeystoneDriverV2(KeystoneDriver
):
206 Driver class for keystoneclient V2 APIs
208 def __init__(self
, username
, password
, auth_url
,tenant_name
, insecure
):
210 Constructor for KeystoneDriverV3 class
212 username (string) : Username
213 password (string) : Password
214 auth_url (string) : Authentication URL
215 tenant_name(string): Tenant Name
219 self
._username
= username
220 self
._password
= password
221 self
._auth
_url
= auth_url
222 self
._tenant
_name
= tenant_name
223 self
._insecure
= insecure
224 super(KeystoneDriverV2
, self
).__init
__(ksclientv2
.Client
)
226 def _get_keystone_credentials(self
):
228 Returns the dictionary of kwargs required to instantiate python-keystoneclient class
231 #creds['user_domain'] = self._domain_name
232 creds
['username'] = self
._username
233 creds
['password'] = self
._password
234 creds
['auth_url'] = self
._auth
_url
235 creds
['tenant_name'] = self
._tenant
_name
236 creds
['insecure'] = self
.get_security_mode()
239 def get_auth_token(self
):
241 Returns a valid auth_token
243 Returns (string): auth_token string
245 ksconn
= self
._get
_keystone
_connection
()
246 return ksconn
.auth_token
248 def is_auth_token_valid(self
):
250 Performs validity on auth_token
254 True/False (Boolean): (auth_token is valid or auth_token is invalid)
256 ksconn
= self
._get
_keystone
_connection
()
257 result
= super(KeystoneDriverV2
, self
).is_auth_token_valid(ksconn
.auth_ref
['token']['expires'],
258 "%Y-%m-%dT%H:%M:%SZ")
262 class KeystoneDriverV3(KeystoneDriver
):
264 Driver class for keystoneclient V3 APIs
266 def __init__(self
, username
, password
, auth_url
,tenant_name
, insecure
):
268 Constructor for KeystoneDriverV3 class
270 username (string) : Username
271 password (string) : Password
272 auth_url (string) : Authentication URL
273 tenant_name(string): Tenant Name
277 self
._username
= username
278 self
._password
= password
279 self
._auth
_url
= auth_url
280 self
._tenant
_name
= tenant_name
281 self
._insecure
= insecure
282 super(KeystoneDriverV3
, self
).__init
__(ksclientv3
.Client
)
284 def _get_keystone_credentials(self
):
286 Returns the dictionary of kwargs required to instantiate python-keystoneclient class
289 #creds['user_domain'] = self._domain_name
290 creds
['username'] = self
._username
291 creds
['password'] = self
._password
292 creds
['auth_url'] = self
._auth
_url
293 creds
['project_name'] = self
._tenant
_name
294 creds
['insecure'] = self
._insecure
297 def get_auth_token(self
):
299 Returns a valid auth_token
301 Returns (string): auth_token string
303 ksconn
= self
._get
_keystone
_connection
()
304 return ksconn
.auth_ref
['auth_token']
306 def is_auth_token_valid(self
):
308 Performs validity on auth_token
312 True/False (Boolean): (auth_token is valid or auth_token is invalid)
314 ksconn
= self
._get
_keystone
_connection
()
315 result
= super(KeystoneDriverV3
, self
).is_auth_token_valid(ksconn
.auth_ref
['expires_at'],
316 "%Y-%m-%dT%H:%M:%S.%fZ")
319 class NovaDriver(object):
321 Driver for openstack nova_client
323 def __init__(self
, ks_drv
, service_name
, version
):
325 Constructor for NovaDriver
326 Arguments: KeystoneDriver class object
329 self
._service
_name
= service_name
330 self
._version
= version
332 def _get_nova_credentials(self
):
334 Returns a dictionary of kwargs required to instantiate python-novaclient class
337 creds
['version'] = self
._version
338 creds
['bypass_url'] = self
.ks_drv
.get_service_endpoint(self
._service
_name
, "publicURL")
339 creds
['username'] = self
.ks_drv
.get_username()
340 creds
['project_id'] = self
.ks_drv
.get_tenant_name()
341 creds
['auth_token'] = self
.ks_drv
.get_auth_token()
342 creds
['insecure'] = self
.ks_drv
.get_security_mode()
345 def _get_nova_connection(self
):
347 Returns an object of class python-novaclient
349 if not hasattr(self
, '_nova_connection'):
350 self
._nova
_connection
= nova_client
.Client(**self
._get
_nova
_credentials
())
352 # Reinitialize if auth_token is no longer valid
353 if not self
.ks_drv
.is_auth_token_valid():
354 self
._nova
_connection
= nova_client
.Client(**self
._get
_nova
_credentials
())
355 return self
._nova
_connection
357 def _flavor_get(self
, flavor_id
):
359 Get flavor by flavor_id
361 flavor_id(string): UUID of flavor_id
364 dictionary of flavor parameters
366 nvconn
= self
._get
_nova
_connection
()
368 flavor
= nvconn
.flavors
.get(flavor_id
)
369 except Exception as e
:
370 logger
.info("OpenstackDriver: Did not find flavor with flavor_id : %s. Exception: %s"%(flavor_id
, str(e
)))
374 extra_specs
= flavor
.get_keys()
375 except Exception as e
:
376 logger
.info("OpenstackDriver: Could not get the EPA attributes for flavor with flavor_id : %s. Exception: %s"%(flavor_id
, str(e
)))
379 response
= flavor
.to_dict()
380 assert 'extra_specs' not in response
, "Key extra_specs present as flavor attribute"
381 response
['extra_specs'] = extra_specs
384 def flavor_get(self
, flavor_id
):
386 Get flavor by flavor_id
388 flavor_id(string): UUID of flavor_id
391 dictionary of flavor parameters
393 return self
._flavor
_get
(flavor_id
)
395 def flavor_list(self
):
397 Returns list of all flavors (dictionary per flavor)
402 A list of dictionaries. Each dictionary contains attributes for a single flavor instance
406 nvconn
= self
._get
_nova
_connection
()
408 flavors
= nvconn
.flavors
.list()
409 except Exception as e
:
410 logger
.error("OpenstackDriver: List Flavor operation failed. Exception: %s"%(str(e
)))
413 flavor_info
= [ self
.flavor_get(flv
.id) for flv
in flavors
]
416 def flavor_create(self
, name
, ram
, vcpu
, disk
, extra_specs
):
421 name (string): Name of the new flavor
422 ram (int) : Memory in MB
423 vcpus (int) : Number of VCPUs
424 disk (int) : Secondary storage size in GB
425 extra_specs (dictionary): EPA attributes dictionary
428 flavor_id (string): UUID of flavor created
430 nvconn
= self
._get
_nova
_connection
()
432 flavor
= nvconn
.flavors
.create(name
= name
,
441 except Exception as e
:
442 logger
.error("OpenstackDriver: Create Flavor operation failed. Exception: %s"%(str(e
)))
447 flavor
.set_keys(extra_specs
)
448 except Exception as e
:
449 logger
.error("OpenstackDriver: Set Key operation failed for flavor: %s. Exception: %s" %(flavor
.id, str(e
)))
453 def flavor_delete(self
, flavor_id
):
455 Deletes a flavor identified by flavor_id
458 flavor_id (string): UUID of flavor to be deleted
462 assert flavor_id
== self
._flavor
_get
(flavor_id
)['id']
463 nvconn
= self
._get
_nova
_connection
()
465 nvconn
.flavors
.delete(flavor_id
)
466 except Exception as e
:
467 logger
.error("OpenstackDriver: Delete flavor operation failed for flavor: %s. Exception: %s" %(flavor_id
, str(e
)))
471 def server_list(self
):
473 Returns a list of available VMs for the project
478 A list of dictionaries. Each dictionary contains attributes associated
483 nvconn
= self
._get
_nova
_connection
()
485 servers
= nvconn
.servers
.list()
486 except Exception as e
:
487 logger
.error("OpenstackDriver: List Server operation failed. Exception: %s" %(str(e
)))
489 server_info
= [ server
.to_dict() for server
in servers
]
492 def _nova_server_get(self
, server_id
):
494 Returns a dictionary of attributes associated with VM identified by service_id
497 server_id (string): UUID of the VM/server for which information is requested
500 A dictionary object with attributes associated with VM identified by server_id
502 nvconn
= self
._get
_nova
_connection
()
504 server
= nvconn
.servers
.get(server
= server_id
)
505 except Exception as e
:
506 logger
.info("OpenstackDriver: Get Server operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
509 return server
.to_dict()
511 def server_get(self
, server_id
):
513 Returns a dictionary of attributes associated with VM identified by service_id
516 server_id (string): UUID of the VM/server for which information is requested
519 A dictionary object with attributes associated with VM identified by server_id
521 return self
._nova
_server
_get
(server_id
)
523 def server_create(self
, **kwargs
):
525 Creates a new VM/server instance
528 A dictionary of following key-value pairs
530 server_name(string) : Name of the VM/Server
531 flavor_id (string) : UUID of the flavor to be used for VM
532 image_id (string) : UUID of the image to be used VM/Server instance,
533 This could be None if volumes (with images) are being used
534 network_list(List) : A List of network_ids. A port will be created in these networks
535 port_list (List) : A List of port-ids. These ports will be added to VM.
536 metadata (dict) : A dictionary of arbitrary key-value pairs associated with VM/server
537 userdata (string) : A script which shall be executed during first boot of the VM
538 availability_zone (string) : A name of the availability zone where instance should be launched
539 scheduler_hints (string) : Openstack scheduler_hints to be passed to nova scheduler
542 server_id (string): UUID of the VM/server created
546 if 'network_list' in kwargs
:
547 for network_id
in kwargs
['network_list']:
548 nics
.append({'net-id': network_id
})
550 if 'port_list' in kwargs
:
551 for port_id
in kwargs
['port_list']:
552 nics
.append({'port-id': port_id
})
554 nvconn
= self
._get
_nova
_connection
()
558 server
= nvconn
.servers
.create(kwargs
['name'],
561 meta
= kwargs
['metadata'],
563 reservation_id
= None,
566 userdata
= kwargs
['userdata'],
567 security_groups
= kwargs
['security_groups'],
568 availability_zone
= kwargs
['availability_zone'],
569 block_device_mapping_v2
= kwargs
['block_device_mapping_v2'],
571 scheduler_hints
= kwargs
['scheduler_hints'],
573 except Exception as e
:
574 logger
.info("OpenstackDriver: Create Server operation failed. Exception: %s" %(str(e
)))
576 return server
.to_dict()['id']
578 def server_delete(self
, server_id
):
580 Deletes a server identified by server_id
583 server_id (string): UUID of the server to be deleted
587 nvconn
= self
._get
_nova
_connection
()
589 nvconn
.servers
.delete(server_id
)
590 except Exception as e
:
591 logger
.error("OpenstackDriver: Delete server operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
594 def server_start(self
, server_id
):
596 Starts a server identified by server_id
599 server_id (string): UUID of the server to be started
603 nvconn
= self
._get
_nova
_connection
()
605 nvconn
.servers
.start(server_id
)
606 except Exception as e
:
607 logger
.error("OpenstackDriver: Start Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
610 def server_stop(self
, server_id
):
613 server_id (string): UUID of the server to be stopped
617 nvconn
= self
._get
_nova
_connection
()
619 nvconn
.servers
.stop(server_id
)
620 except Exception as e
:
621 logger
.error("OpenstackDriver: Stop Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
624 def server_pause(self
, server_id
):
627 server_id (string): UUID of the server to be paused
631 nvconn
= self
._get
_nova
_connection
()
633 nvconn
.servers
.pause(server_id
)
634 except Exception as e
:
635 logger
.error("OpenstackDriver: Pause Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
638 def server_unpause(self
, server_id
):
641 server_id (string): UUID of the server to be unpaused
645 nvconn
= self
._get
_nova
_connection
()
647 nvconn
.servers
.unpause(server_id
)
648 except Exception as e
:
649 logger
.error("OpenstackDriver: Resume Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
653 def server_suspend(self
, server_id
):
656 server_id (string): UUID of the server to be suspended
660 nvconn
= self
._get
_nova
_connection
()
662 nvconn
.servers
.suspend(server_id
)
663 except Exception as e
:
664 logger
.error("OpenstackDriver: Suspend Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
667 def server_resume(self
, server_id
):
670 server_id (string): UUID of the server to be resumed
674 nvconn
= self
._get
_nova
_connection
()
676 nvconn
.servers
.resume(server_id
)
677 except Exception as e
:
678 logger
.error("OpenstackDriver: Resume Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
681 def server_reboot(self
, server_id
, reboot_type
):
684 server_id (string) : UUID of the server to be rebooted
690 nvconn
= self
._get
_nova
_connection
()
692 nvconn
.servers
.reboot(server_id
, reboot_type
)
693 except Exception as e
:
694 logger
.error("OpenstackDriver: Reboot Server operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
697 def server_console(self
, server_id
, console_type
= 'novnc'):
700 server_id (string) : UUID of the server to be rebooted
701 console_type(string):
705 A dictionary object response for console information
707 nvconn
= self
._get
_nova
_connection
()
709 console_info
= nvconn
.servers
.get_vnc_console(server_id
, console_type
)
710 except Exception as e
:
711 logger
.error("OpenstackDriver: Server Get-Console operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
715 def server_rebuild(self
, server_id
, image_id
):
718 server_id (string) : UUID of the server to be rebooted
719 image_id (string) : UUID of the image to use
723 nvconn
= self
._get
_nova
_connection
()
725 nvconn
.servers
.rebuild(server_id
, image_id
)
726 except Exception as e
:
727 logger
.error("OpenstackDriver: Rebuild Server operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
731 def server_add_port(self
, server_id
, port_id
):
734 server_id (string): UUID of the server
735 port_id (string): UUID of the port to be attached
739 nvconn
= self
._get
_nova
_connection
()
741 nvconn
.servers
.interface_attach(server_id
,
745 except Exception as e
:
746 logger
.error("OpenstackDriver: Server Port Add operation failed for server_id : %s, port_id : %s. Exception: %s" %(server_id
, port_id
, str(e
)))
749 def server_delete_port(self
, server_id
, port_id
):
752 server_id (string): UUID of the server
753 port_id (string): UUID of the port to be deleted
757 nvconn
= self
._get
_nova
_connection
()
759 nvconn
.servers
.interface_detach(server_id
, port_id
)
760 except Exception as e
:
761 logger
.error("OpenstackDriver: Server Port Delete operation failed for server_id : %s, port_id : %s. Exception: %s" %(server_id
, port_id
, str(e
)))
764 def floating_ip_list(self
):
769 List of objects of floating IP nova class (novaclient.v2.floating_ips.FloatingIP)
771 nvconn
= self
._get
_nova
_connection
()
773 ip_list
= nvconn
.floating_ips
.list()
774 except Exception as e
:
775 logger
.error("OpenstackDriver: Floating IP List operation failed. Exception: %s" %str
(e
))
780 def floating_ip_create(self
, pool
):
783 pool (string): Name of the pool (optional)
785 An object of floating IP nova class (novaclient.v2.floating_ips.FloatingIP)
787 nvconn
= self
._get
_nova
_connection
()
789 floating_ip
= nvconn
.floating_ips
.create(pool
)
790 except Exception as e
:
791 logger
.error("OpenstackDriver: Floating IP Create operation failed. Exception: %s" %str
(e
))
796 def floating_ip_delete(self
, floating_ip
):
799 floating_ip: An object of floating IP nova class (novaclient.v2.floating_ips.FloatingIP)
803 nvconn
= self
._get
_nova
_connection
()
805 floating_ip
= nvconn
.floating_ips
.delete(floating_ip
)
806 except Exception as e
:
807 logger
.error("OpenstackDriver: Floating IP Delete operation failed. Exception: %s" %str
(e
))
810 def floating_ip_assign(self
, server_id
, floating_ip
, fixed_ip
):
813 server_id (string) : UUID of the server
814 floating_ip (string): IP address string for floating-ip
815 fixed_ip (string) : IP address string for the fixed-ip with which floating ip will be associated
819 nvconn
= self
._get
_nova
_connection
()
821 nvconn
.servers
.add_floating_ip(server_id
, floating_ip
, fixed_ip
)
822 except Exception as e
:
823 logger
.error("OpenstackDriver: Assign Floating IP operation failed. Exception: %s" %str
(e
))
826 def floating_ip_release(self
, server_id
, floating_ip
):
829 server_id (string) : UUID of the server
830 floating_ip (string): IP address string for floating-ip
834 nvconn
= self
._get
_nova
_connection
()
836 nvconn
.servers
.remove_floating_ip(server_id
, floating_ip
)
837 except Exception as e
:
838 logger
.error("OpenstackDriver: Release Floating IP operation failed. Exception: %s" %str
(e
))
841 def volume_list(self
, server_id
):
843 List of volumes attached to the server
848 List of dictionary objects where dictionary is representation of class (novaclient.v2.volumes.Volume)
850 nvconn
= self
._get
_nova
_connection
()
852 volumes
= nvconn
.volumes
.get_server_volumes(server_id
=server_id
)
853 except Exception as e
:
854 logger
.error("OpenstackDriver: Get volume information failed. Exception: %s" %str
(e
))
857 volume_info
= [v
.to_dict() for v
in volumes
]
861 def group_list(self
):
863 List of Server Affinity and Anti-Affinity Groups
868 List of dictionary objects where dictionary is representation of class (novaclient.v2.server_groups.ServerGroup)
870 nvconn
= self
._get
_nova
_connection
()
872 group_list
= nvconn
.server_groups
.list()
873 except Exception as e
:
874 logger
.error("OpenstackDriver: Server Group List operation failed. Exception: %s" %str
(e
))
877 group_info
= [ group
.to_dict() for group
in group_list
]
882 class NovaDriverV2(NovaDriver
):
884 Driver class for novaclient V2 APIs
886 def __init__(self
, ks_drv
):
888 Constructor for NovaDriver
889 Arguments: KeystoneDriver class object
891 super(NovaDriverV2
, self
).__init
__(ks_drv
, 'compute', '2.0')
893 class NovaDriverV21(NovaDriver
):
895 Driver class for novaclient V2 APIs
897 def __init__(self
, ks_drv
):
899 Constructor for NovaDriver
900 Arguments: KeystoneDriver class object
902 super(NovaDriverV21
, self
).__init
__(ks_drv
, 'computev21', '2.1')
904 class GlanceDriver(object):
906 Driver for openstack glance-client
908 def __init__(self
, ks_drv
, service_name
, version
):
910 Constructor for GlanceDriver
911 Arguments: KeystoneDriver class object
914 self
._service
_name
= service_name
915 self
._version
= version
917 def _get_glance_credentials(self
):
919 Returns a dictionary of kwargs required to instantiate python-glanceclient class
924 A dictionary object of arguments
927 creds
['version'] = self
._version
928 creds
['endpoint'] = self
.ks_drv
.get_service_endpoint(self
._service
_name
, 'publicURL')
929 creds
['token'] = self
.ks_drv
.get_auth_token()
930 creds
['insecure'] = self
.ks_drv
.get_security_mode()
933 def _get_glance_connection(self
):
935 Returns a object of class python-glanceclient
937 if not hasattr(self
, '_glance_connection'):
938 self
._glance
_connection
= glclient
.Client(**self
._get
_glance
_credentials
())
940 # Reinitialize if auth_token is no longer valid
941 if not self
.ks_drv
.is_auth_token_valid():
942 self
._glance
_connection
= glclient
.Client(**self
._get
_glance
_credentials
())
943 return self
._glance
_connection
945 def image_list(self
):
947 Returns list of dictionaries. Each dictionary contains attributes associated with
952 Returns: List of dictionaries.
954 glconn
= self
._get
_glance
_connection
()
957 image_info
= glconn
.images
.list()
958 except Exception as e
:
959 logger
.error("OpenstackDriver: List Image operation failed. Exception: %s" %(str(e
)))
961 images
= [ img
for img
in image_info
]
964 def image_create(self
, **kwargs
):
968 A dictionary of kwargs with following keys
970 'name'(string) : Name of the image
971 'location'(string) : URL (http://....) where image is located
972 'disk_format'(string) : Disk format
973 Possible values are 'ami', 'ari', 'aki', 'vhd', 'vmdk', 'raw', 'qcow2', 'vdi', 'iso'
974 'container_format'(string): Container format
975 Possible values are 'ami', 'ari', 'aki', 'bare', 'ovf'
976 'tags' : A list of user tags
977 'checksum' : The image md5 checksum
980 image_id (string) : UUID of the image
983 glconn
= self
._get
_glance
_connection
()
985 image
= glconn
.images
.create(**kwargs
)
986 except Exception as e
:
987 logger
.error("OpenstackDriver: Create Image operation failed. Exception: %s" %(str(e
)))
992 def image_upload(self
, image_id
, fd
):
997 image_id: UUID of the image
998 fd : File descriptor for the image file
1001 glconn
= self
._get
_glance
_connection
()
1003 glconn
.images
.upload(image_id
, fd
)
1004 except Exception as e
:
1005 logger
.error("OpenstackDriver: Image upload operation failed. Exception: %s" %(str(e
)))
1008 def image_add_location(self
, image_id
, location
, metadata
):
1010 Add image URL location
1013 image_id : UUID of the image
1014 location : http URL for the image
1018 glconn
= self
._get
_glance
_connection
()
1020 image
= glconn
.images
.add_location(image_id
, location
, metadata
)
1021 except Exception as e
:
1022 logger
.error("OpenstackDriver: Image location add operation failed. Exception: %s" %(str(e
)))
1025 def image_update(self
):
1028 def image_delete(self
, image_id
):
1033 image_id: UUID of the image
1038 assert image_id
== self
._image
_get
(image_id
)['id']
1039 glconn
= self
._get
_glance
_connection
()
1041 glconn
.images
.delete(image_id
)
1042 except Exception as e
:
1043 logger
.error("OpenstackDriver: Delete Image operation failed for image_id : %s. Exception: %s" %(image_id
, str(e
)))
1047 def _image_get(self
, image_id
):
1049 Returns a dictionary object of VM image attributes
1052 image_id (string): UUID of the image
1055 A dictionary of the image attributes
1057 glconn
= self
._get
_glance
_connection
()
1059 image
= glconn
.images
.get(image_id
)
1060 except GlanceException
.HTTPBadRequest
:
1061 # RIFT-14241: The get image request occasionally returns the below message. Retry in case of bad request exception.
1062 # Error code 400.: Message: Bad request syntax ('0').: Error code explanation: 400 = Bad request syntax or unsupported method. (HTTP 400)
1063 logger
.warning("OpenstackDriver: Got bad request response during get_image request. Retrying.")
1064 image
= glconn
.images
.get(image_id
)
1065 except Exception as e
:
1066 logger
.error("OpenstackDriver: Get Image operation failed for image_id : %s. Exception: %s" %(image_id
, str(e
)))
1071 def image_get(self
, image_id
):
1073 Returns a dictionary object of VM image attributes
1076 image_id (string): UUID of the image
1079 A dictionary of the image attributes
1081 return self
._image
_get
(image_id
)
1083 class GlanceDriverV2(GlanceDriver
):
1085 Driver for openstack glance-client V2
1087 def __init__(self
, ks_drv
):
1088 super(GlanceDriverV2
, self
).__init
__(ks_drv
, 'image', 2)
1090 class NeutronDriver(object):
1092 Driver for openstack neutron neutron-client
1094 def __init__(self
, ks_drv
, service_name
, version
):
1096 Constructor for NeutronDriver
1097 Arguments: KeystoneDriver class object
1099 self
.ks_drv
= ks_drv
1100 self
._service
_name
= service_name
1101 self
._version
= version
1103 def _get_neutron_credentials(self
):
1105 Returns a dictionary of kwargs required to instantiate python-neutronclient class
1108 Dictionary of kwargs
1111 creds
['api_version'] = self
._version
1112 creds
['endpoint_url'] = self
.ks_drv
.get_service_endpoint(self
._service
_name
, 'publicURL')
1113 creds
['token'] = self
.ks_drv
.get_auth_token()
1114 creds
['tenant_name'] = self
.ks_drv
.get_tenant_name()
1115 creds
['insecure'] = self
.ks_drv
.get_security_mode()
1118 def _get_neutron_connection(self
):
1120 Returns an object of class python-neutronclient
1122 if not hasattr(self
, '_neutron_connection'):
1123 self
._neutron
_connection
= ntclient
.Client(**self
._get
_neutron
_credentials
())
1125 # Reinitialize if auth_token is no longer valid
1126 if not self
.ks_drv
.is_auth_token_valid():
1127 self
._neutron
_connection
= ntclient
.Client(**self
._get
_neutron
_credentials
())
1128 return self
._neutron
_connection
1130 def network_list(self
):
1132 Returns list of dictionaries. Each dictionary contains the attributes for a network
1138 A list of dictionaries
1141 ntconn
= self
._get
_neutron
_connection
()
1143 networks
= ntconn
.list_networks()
1144 except Exception as e
:
1145 logger
.error("OpenstackDriver: List Network operation failed. Exception: %s" %(str(e
)))
1147 return networks
['networks']
1149 def network_create(self
, **kwargs
):
1151 Creates a new network for the project
1154 A dictionary with following key-values
1156 name (string) : Name of the network
1157 admin_state_up(Boolean) : True/False (Defaults: True)
1158 external_router(Boolean) : Connectivity with external router. True/False (Defaults: False)
1159 shared(Boolean) : Shared among tenants. True/False (Defaults: False)
1160 physical_network(string) : The physical network where this network object is implemented (optional).
1161 network_type : The type of physical network that maps to this network resource (optional).
1162 Possible values are: 'flat', 'vlan', 'vxlan', 'gre'
1163 segmentation_id : An isolated segment on the physical network. The network_type attribute
1164 defines the segmentation model. For example, if the network_type value
1165 is vlan, this ID is a vlan identifier. If the network_type value is gre,
1166 this ID is a gre key.
1169 params
= {'network':
1170 {'name' : kwargs
['name'],
1171 'admin_state_up' : kwargs
['admin_state_up'],
1172 'tenant_id' : self
.ks_drv
.get_tenant_id(),
1173 'shared' : kwargs
['shared'],
1174 #'port_security_enabled': port_security_enabled,
1175 'router:external' : kwargs
['external_router']}}
1177 if 'physical_network' in kwargs
:
1178 params
['network']['provider:physical_network'] = kwargs
['physical_network']
1179 if 'network_type' in kwargs
:
1180 params
['network']['provider:network_type'] = kwargs
['network_type']
1181 if 'segmentation_id' in kwargs
:
1182 params
['network']['provider:segmentation_id'] = kwargs
['segmentation_id']
1184 ntconn
= self
._get
_neutron
_connection
()
1186 logger
.debug("Calling neutron create_network() with params: %s", str(params
))
1187 net
= ntconn
.create_network(params
)
1188 except Exception as e
:
1189 logger
.error("OpenstackDriver: Create Network operation failed. Exception: %s" %(str(e
)))
1191 logger
.debug("Got create_network response from neutron connection: %s", str(net
))
1192 network_id
= net
['network']['id']
1194 raise Exception("Empty network id returned from create_network. (params: %s)" % str(params
))
1198 def network_delete(self
, network_id
):
1200 Deletes a network identified by network_id
1203 network_id (string): UUID of the network
1207 assert network_id
== self
._network
_get
(network_id
)['id']
1208 ntconn
= self
._get
_neutron
_connection
()
1210 ntconn
.delete_network(network_id
)
1211 except Exception as e
:
1212 logger
.error("OpenstackDriver: Delete Network operation failed. Exception: %s" %(str(e
)))
1215 def _network_get(self
, network_id
):
1217 Returns a dictionary object describing the attributes of the network
1220 network_id (string): UUID of the network
1223 A dictionary object of the network attributes
1225 ntconn
= self
._get
_neutron
_connection
()
1226 network
= ntconn
.list_networks(id = network_id
)['networks']
1228 raise NeutronException
.NotFound("Network with id %s not found"%(network_id))
1232 def network_get(self
, network_id
):
1234 Returns a dictionary object describing the attributes of the network
1237 network_id (string): UUID of the network
1240 A dictionary object of the network attributes
1242 return self
._network
_get
(network_id
)
1244 def subnet_create(self
, **kwargs
):
1246 Creates a subnet on the network
1249 A dictionary with following key value pairs
1251 network_id(string) : UUID of the network where subnet needs to be created
1252 subnet_cidr(string) : IPv4 address prefix (e.g. '1.1.1.0/24') for the subnet
1253 ip_version (integer): 4 for IPv4 and 6 for IPv6
1258 subnet_id (string): UUID of the created subnet
1261 params
['network_id'] = kwargs
['network_id']
1262 params
['ip_version'] = kwargs
['ip_version']
1264 # if params['ip_version'] == 6:
1265 # assert 0, "IPv6 is not supported"
1267 if 'subnetpool_id' in kwargs
:
1268 params
['subnetpool_id'] = kwargs
['subnetpool_id']
1270 params
['cidr'] = kwargs
['cidr']
1272 if 'gateway_ip' in kwargs
:
1273 params
['gateway_ip'] = kwargs
['gateway_ip']
1275 params
['gateway_ip'] = None
1277 if 'dhcp_params' in kwargs
:
1278 params
['enable_dhcp'] = kwargs
['dhcp_params']['enable_dhcp']
1279 if 'start_address' in kwargs
['dhcp_params'] and 'count' in kwargs
['dhcp_params']:
1280 end_address
= (ipaddress
.IPv4Address(kwargs
['dhcp_params']['start_address']) + kwargs
['dhcp_params']['count']).compressed
1281 params
['allocation_pools'] = [ {'start': kwargs
['dhcp_params']['start_address'] ,
1282 'end' : end_address
} ]
1284 if 'dns_server' in kwargs
:
1285 params
['dns_nameservers'] = []
1286 for server
in kwargs
['dns_server']:
1287 params
['dns_nameservers'].append(server
)
1289 ntconn
= self
._get
_neutron
_connection
()
1291 subnet
= ntconn
.create_subnet({'subnets': [params
]})
1292 except Exception as e
:
1293 logger
.error("OpenstackDriver: Create Subnet operation failed. Exception: %s" %(str(e
)))
1296 return subnet
['subnets'][0]['id']
1298 def subnet_list(self
):
1300 Returns a list of dictionaries. Each dictionary contains attributes describing the subnet
1305 A dictionary of the objects of subnet attributes
1307 ntconn
= self
._get
_neutron
_connection
()
1309 subnets
= ntconn
.list_subnets()['subnets']
1310 except Exception as e
:
1311 logger
.error("OpenstackDriver: List Subnet operation failed. Exception: %s" %(str(e
)))
1315 def _subnet_get(self
, subnet_id
):
1317 Returns a dictionary object describing the attributes of a subnet.
1320 subnet_id (string): UUID of the subnet
1323 A dictionary object of the subnet attributes
1325 ntconn
= self
._get
_neutron
_connection
()
1326 subnets
= ntconn
.list_subnets(id=subnet_id
)
1327 if not subnets
['subnets']:
1328 logger
.error("OpenstackDriver: Get subnet operation failed for subnet_id: %s" %(subnet_id))
1329 #raise NeutronException.NotFound("Could not find subnet_id %s" %(subnet_id))
1332 return subnets
['subnets'][0]
1334 def subnet_get(self
, subnet_id
):
1336 Returns a dictionary object describing the attributes of a subnet.
1339 subnet_id (string): UUID of the subnet
1342 A dictionary object of the subnet attributes
1344 return self
._subnet
_get
(subnet_id
)
1346 def subnet_delete(self
, subnet_id
):
1348 Deletes a subnet identified by subnet_id
1351 subnet_id (string): UUID of the subnet to be deleted
1355 ntconn
= self
._get
_neutron
_connection
()
1356 assert subnet_id
== self
._subnet
_get
(self
,subnet_id
)
1358 ntconn
.delete_subnet(subnet_id
)
1359 except Exception as e
:
1360 logger
.error("OpenstackDriver: Delete Subnet operation failed for subnet_id : %s. Exception: %s" %(subnet_id
, str(e
)))
1363 def port_list(self
, **kwargs
):
1365 Returns a list of dictionaries. Each dictionary contains attributes describing the port
1368 kwargs (dictionary): A dictionary for filters for port_list operation
1371 A dictionary of the objects of port attributes
1375 ntconn
= self
._get
_neutron
_connection
()
1377 kwargs
['tenant_id'] = self
.ks_drv
.get_tenant_id()
1380 ports
= ntconn
.list_ports(**kwargs
)
1381 except Exception as e
:
1382 logger
.info("OpenstackDriver: List Port operation failed. Exception: %s" %(str(e
)))
1384 return ports
['ports']
1386 def port_create(self
, **kwargs
):
1388 Create a port in network
1391 A dictionary of following
1393 name (string) : Name of the port
1394 network_id(string) : UUID of the network_id identifying the network to which port belongs
1395 subnet_id(string) : UUID of the subnet_id from which IP-address will be assigned to port
1396 vnic_type(string) : Possible values are "normal", "direct", "macvtap"
1399 port_id (string) : UUID of the port
1403 "admin_state_up" : kwargs
['admin_state_up'],
1404 "name" : kwargs
['name'],
1405 "network_id" : kwargs
['network_id'],
1406 "fixed_ips" : [ {"subnet_id": kwargs
['subnet_id']}],
1407 "binding:vnic_type" : kwargs
['port_type']}}
1409 ntconn
= self
._get
_neutron
_connection
()
1411 port
= ntconn
.create_port(params
)
1412 except Exception as e
:
1413 logger
.error("OpenstackDriver: Port Create operation failed. Exception: %s" %(str(e
)))
1415 return port
['port']['id']
1417 def _port_get(self
, port_id
):
1419 Returns a dictionary object describing the attributes of the port
1422 port_id (string): UUID of the port
1425 A dictionary object of the port attributes
1427 ntconn
= self
._get
_neutron
_connection
()
1428 port
= ntconn
.list_ports(id=port_id
)['ports']
1430 raise NeutronException
.NotFound("Could not find port_id %s" %(port_id))
1433 def port_get(self
, port_id
):
1435 Returns a dictionary object describing the attributes of the port
1438 port_id (string): UUID of the port
1441 A dictionary object of the port attributes
1443 return self
._port
_get
(port_id
)
1445 def port_delete(self
, port_id
):
1447 Deletes a port identified by port_id
1450 port_id (string) : UUID of the port
1454 assert port_id
== self
._port
_get
(port_id
)['id']
1455 ntconn
= self
._get
_neutron
_connection
()
1457 ntconn
.delete_port(port_id
)
1458 except Exception as e
:
1459 logger
.error("Port Delete operation failed for port_id : %s. Exception: %s" %(port_id
, str(e
)))
1462 def security_group_list(self
):
1464 Returns a list of dictionaries. Each dictionary contains attributes describing the security group
1470 A dictionary of the objects of security group attributes
1472 ntconn
= self
._get
_neutron
_connection
()
1474 group_list
= ntconn
.list_security_groups(tenant_id
=self
.ks_drv
.get_tenant_id())
1475 except Exception as e
:
1476 logger
.error("List Security group operation, Exception: %s" %(str(e
)))
1479 if 'security_groups' in group_list
:
1480 return group_list
['security_groups']
1484 def subnetpool_list(self
, **kwargs
):
1486 Returns a list of dictionaries. Each dictionary contains attributes describing a subnet prefix pool
1492 A dictionary of the objects of subnet prefix pool
1494 ntconn
= self
._get
_neutron
_connection
()
1496 pool_list
= ntconn
.list_subnetpools(**kwargs
)
1497 except Exception as e
:
1498 logger
.error("List SubnetPool operation, Exception: %s" %(str(e
)))
1501 if 'subnetpools' in pool_list
:
1502 return pool_list
['subnetpools']
1506 class NeutronDriverV2(NeutronDriver
):
1508 Driver for openstack neutron neutron-client v2
1510 def __init__(self
, ks_drv
):
1512 Constructor for NeutronDriver
1513 Arguments: KeystoneDriver class object
1515 super(NeutronDriverV2
, self
).__init
__(ks_drv
, 'network', '2.0')
1519 class CeilometerDriver(object):
1521 Driver for openstack ceilometer client
1524 def __init__(self
, ks_drv
, service_name
, version
):
1526 Constructor for CeilometerDriver
1527 Arguments: KeystoneDriver class object
1529 self
.ks_drv
= ks_drv
1530 self
._service
_name
= service_name
1531 self
._version
= version
1536 """The version of the ceilometer client used by the driver"""
1537 return self
._version
1541 """The instance of ceilometer client used by the driver"""
1542 if self
._client
is None or not self
.ks_drv
.is_auth_token_valid():
1543 self
._client
= ceilo_client
.Client(**self
.credentials
)
1548 def auth_token(self
):
1549 """The authorization token for the ceilometer client"""
1551 return self
.ks_drv
.get_auth_token()
1552 except KeystoneExceptions
.EndpointNotFound
as e
:
1553 logger
.error("OpenstackDriver: unable to get authorization token for ceilometer. Exception: %s" %(str(e
)))
1557 def security_mode(self
):
1558 """The security mode for the ceilometer client"""
1560 return self
.ks_drv
.get_security_mode()
1561 except KeystoneExceptions
.EndpointNotFound
as e
:
1562 logger
.error("OpenstackDriver: unable to get security mode for ceilometer. Exception: %s" %(str(e
)))
1567 """The service endpoint for the ceilometer client"""
1569 return self
.ks_drv
.get_service_endpoint(self
._service
_name
, "publicURL")
1570 except KeystoneExceptions
.EndpointNotFound
as e
:
1571 logger
.error("OpenstackDriver: unable to get endpoint for ceilometer. Exception: %s" %(str(e
)))
1575 def credentials(self
):
1576 """A dictionary of credentials for the ceilometer client"""
1578 version
=self
.version
,
1579 endpoint
=self
.endpoint
,
1580 token
=self
.auth_token
,
1581 insecure
=self
.security_mode
,
1586 """A list of the available meters"""
1588 return self
.client
.meters
.list()
1589 except Exception as e
:
1590 logger
.error("OpenstackDriver: List meters operation failed. Exception: %s" %(str(e
)))
1595 """The ceilometer client alarms manager"""
1596 return self
.client
.alarms
1598 def query_samples(self
, vim_instance_id
, counter_name
, limit
=1):
1599 """Returns a list of samples
1602 vim_instance_id - the ID of the VIM that the samples are from
1603 counter_name - the counter that the samples will come from
1604 limit - a limit on the number of samples to return
1612 filter = json
.dumps({
1614 {"=": {"resource": vim_instance_id
}},
1615 {"=": {"counter_name": counter_name
}}
1618 result
= self
.client
.query_samples
.query(filter=filter, limit
=limit
)
1619 return result
[-limit
:]
1621 except Exception as e
:
1627 class CeilometerDriverV2(CeilometerDriver
):
1629 Driver for openstack ceilometer ceilometer-client
1631 def __init__(self
, ks_drv
):
1633 Constructor for CeilometerDriver
1634 Arguments: CeilometerDriver class object
1636 super(CeilometerDriverV2
, self
).__init
__(ks_drv
, 'metering', '2')
1638 class OpenstackDriver(object):
1640 Driver for openstack nova, neutron, glance, keystone, swift, cinder services
1642 def __init__(self
, username
, password
, auth_url
, tenant_name
, mgmt_network
= None, cert_validate
= False):
1644 OpenstackDriver Driver constructor
1646 username (string) : Username for project/tenant.
1647 password (string) : Password
1648 auth_url (string) : Keystone Authentication URL.
1649 tenant_name (string) : Openstack project name
1650 mgmt_network(string, optional) : Management network name. Each VM created with this cloud-account will
1651 have a default interface into management network.
1652 cert_validate (boolean, optional) : In case of SSL/TLS connection if certificate validation is required or not.
1655 insecure
= not cert_validate
1656 if auth_url
.find('/v3') != -1:
1657 self
.ks_drv
= KeystoneDriverV3(username
, password
, auth_url
, tenant_name
, insecure
)
1658 self
.glance_drv
= GlanceDriverV2(self
.ks_drv
)
1659 self
.nova_drv
= NovaDriverV21(self
.ks_drv
)
1660 self
.neutron_drv
= NeutronDriverV2(self
.ks_drv
)
1661 self
.ceilo_drv
= CeilometerDriverV2(self
.ks_drv
)
1662 elif auth_url
.find('/v2') != -1:
1663 self
.ks_drv
= KeystoneDriverV2(username
, password
, auth_url
, tenant_name
, insecure
)
1664 self
.glance_drv
= GlanceDriverV2(self
.ks_drv
)
1665 self
.nova_drv
= NovaDriverV2(self
.ks_drv
)
1666 self
.neutron_drv
= NeutronDriverV2(self
.ks_drv
)
1667 self
.ceilo_drv
= CeilometerDriverV2(self
.ks_drv
)
1669 logger
.error("Could not identity the version information for openstack service endpoints. Auth_URL should contain \"/v2\" or \"/v3\" string in it")
1670 raise NotImplementedError("Auth URL is wrong or invalid. Only Keystone v2 & v3 supported")
1672 self
._mgmt
_network
_id
= None
1673 if mgmt_network
!= None:
1674 self
._mgmt
_network
= mgmt_network
1678 ntconn
= self
.neutron_drv
._get
_neutron
_connection
()
1679 networks
= ntconn
.list_networks()
1680 except (KeystoneExceptions
.Unauthorized
, KeystoneExceptions
.AuthorizationFailure
) as e
:
1682 except Exception as e
:
1683 logger
.error("OpenstackDriver: List Network operation failed. Exception: %s" %(str(e
)))
1686 network_list
= [ network
for network
in networks
['networks'] if network
['name'] == mgmt_network
]
1688 if not network_list
:
1689 raise NeutronException
.NotFound("Could not find network %s" %(mgmt_network))
1690 self
._mgmt
_network
_id
= network_list
[0]['id']
1692 def validate_account_creds(self
):
1694 ksconn
= self
.ks_drv
._get
_keystone
_connection
()
1695 except KeystoneExceptions
.AuthorizationFailure
as e
:
1696 logger
.error("OpenstackDriver: Unable to authenticate or validate the existing credentials. Exception: %s" %(str(e
)))
1697 raise ValidationError("Invalid Credentials: "+ str(e
))
1698 except Exception as e
:
1699 logger
.error("OpenstackDriver: Could not connect to Openstack. Exception: %s" %(str(e
)))
1700 raise ValidationError("Connection Error: "+ str(e
))
1702 def get_mgmt_network_id(self
):
1703 return self
._mgmt
_network
_id
1705 def glance_image_create(self
, **kwargs
):
1706 if not 'disk_format' in kwargs
:
1707 kwargs
['disk_format'] = 'qcow2'
1708 if not 'container_format' in kwargs
:
1709 kwargs
['container_format'] = 'bare'
1710 if not 'min_disk' in kwargs
:
1711 kwargs
['min_disk'] = 0
1712 if not 'min_ram' in kwargs
:
1713 kwargs
['min_ram'] = 0
1714 return self
.glance_drv
.image_create(**kwargs
)
1716 def glance_image_upload(self
, image_id
, fd
):
1717 self
.glance_drv
.image_upload(image_id
, fd
)
1719 def glance_image_add_location(self
, image_id
, location
):
1720 self
.glance_drv
.image_add_location(image_id
, location
)
1722 def glance_image_delete(self
, image_id
):
1723 self
.glance_drv
.image_delete(image_id
)
1725 def glance_image_list(self
):
1726 return self
.glance_drv
.image_list()
1728 def glance_image_get(self
, image_id
):
1729 return self
.glance_drv
.image_get(image_id
)
1732 def nova_flavor_list(self
):
1733 return self
.nova_drv
.flavor_list()
1735 def nova_flavor_create(self
, name
, ram
, vcpus
, disk
, epa_specs
):
1736 extra_specs
= epa_specs
if epa_specs
else {}
1737 return self
.nova_drv
.flavor_create(name
,
1741 extra_specs
= extra_specs
)
1743 def nova_flavor_delete(self
, flavor_id
):
1744 self
.nova_drv
.flavor_delete(flavor_id
)
1746 def nova_flavor_get(self
, flavor_id
):
1747 return self
.nova_drv
.flavor_get(flavor_id
)
1749 def nova_server_create(self
, **kwargs
):
1750 def _verify_image(image_id
):
1751 image
= self
.glance_drv
.image_get(image_id
)
1752 if image
['status'] != 'active':
1753 raise GlanceException
.NotFound("Image with image_id: %s not found in active state. Current State: %s" %(image
['id'], image
['status']))
1755 assert kwargs
['flavor_id'] == self
.nova_drv
.flavor_get(kwargs
['flavor_id'])['id']
1757 if kwargs
['block_device_mapping_v2'] is not None:
1758 for block_map
in kwargs
['block_device_mapping_v2']:
1759 if 'uuid' in block_map
:
1760 _verify_image(block_map
['uuid'])
1762 _verify_image(kwargs
['image_id'])
1764 # if 'network_list' in kwargs:
1765 # kwargs['network_list'].append(self._mgmt_network_id)
1767 # kwargs['network_list'] = [self._mgmt_network_id]
1769 if 'security_groups' not in kwargs
:
1770 nvconn
= self
.nova_drv
._get
_nova
_connection
()
1771 sec_groups
= nvconn
.security_groups
.list()
1773 ## Should we add VM in all availability security_groups ???
1774 kwargs
['security_groups'] = [x
.name
for x
in sec_groups
]
1776 kwargs
['security_groups'] = None
1778 return self
.nova_drv
.server_create(**kwargs
)
1780 def nova_server_add_port(self
, server_id
, port_id
):
1781 self
.nova_drv
.server_add_port(server_id
, port_id
)
1783 def nova_server_delete_port(self
, server_id
, port_id
):
1784 self
.nova_drv
.server_delete_port(server_id
, port_id
)
1786 def nova_server_start(self
, server_id
):
1787 self
.nova_drv
.server_start(server_id
)
1789 def nova_server_stop(self
, server_id
):
1790 self
.nova_drv
.server_stop(server_id
)
1792 def nova_server_delete(self
, server_id
):
1793 self
.nova_drv
.server_delete(server_id
)
1795 def nova_server_reboot(self
, server_id
):
1796 self
.nova_drv
.server_reboot(server_id
, reboot_type
='HARD')
1798 def nova_server_rebuild(self
, server_id
, image_id
):
1799 self
.nova_drv
.server_rebuild(server_id
, image_id
)
1801 def nova_floating_ip_list(self
):
1802 return self
.nova_drv
.floating_ip_list()
1804 def nova_floating_ip_create(self
, pool
= None):
1805 return self
.nova_drv
.floating_ip_create(pool
)
1807 def nova_floating_ip_delete(self
, floating_ip
):
1808 self
.nova_drv
.floating_ip_delete(floating_ip
)
1810 def nova_floating_ip_assign(self
, server_id
, floating_ip
, fixed_ip
):
1811 self
.nova_drv
.floating_ip_assign(server_id
, floating_ip
, fixed_ip
)
1813 def nova_floating_ip_release(self
, server_id
, floating_ip
):
1814 self
.nova_drv
.floating_ip_release(server_id
, floating_ip
)
1816 def nova_server_list(self
):
1817 return self
.nova_drv
.server_list()
1819 def nova_server_get(self
, server_id
):
1820 return self
.nova_drv
.server_get(server_id
)
1822 def nova_server_console(self
, server_id
):
1823 return self
.nova_drv
.server_console(server_id
)
1825 def nova_server_group_list(self
):
1826 return self
.nova_drv
.group_list()
1828 def nova_volume_list(self
, server_id
):
1829 return self
.nova_drv
.volume_list(server_id
)
1831 def neutron_network_list(self
):
1832 return self
.neutron_drv
.network_list()
1834 def neutron_network_get(self
, network_id
):
1835 return self
.neutron_drv
.network_get(network_id
)
1837 def neutron_network_create(self
, **kwargs
):
1838 return self
.neutron_drv
.network_create(**kwargs
)
1840 def neutron_network_delete(self
, network_id
):
1841 self
.neutron_drv
.network_delete(network_id
)
1843 def neutron_subnet_list(self
):
1844 return self
.neutron_drv
.subnet_list()
1846 def neutron_subnet_get(self
, subnet_id
):
1847 return self
.neutron_drv
.subnet_get(subnet_id
)
1849 def neutron_subnet_create(self
, **kwargs
):
1850 return self
.neutron_drv
.subnet_create(**kwargs
)
1852 def netruon_subnet_delete(self
, subnet_id
):
1853 self
.neutron_drv
.subnet_delete(subnet_id
)
1855 def neutron_subnetpool_list(self
):
1856 return self
.neutron_drv
.subnetpool_list()
1858 def netruon_subnetpool_by_name(self
, pool_name
):
1859 pool_list
= self
.neutron_drv
.subnetpool_list(**{'name': pool_name
})
1865 def neutron_port_list(self
, **kwargs
):
1866 return self
.neutron_drv
.port_list(**kwargs
)
1868 def neutron_port_get(self
, port_id
):
1869 return self
.neutron_drv
.port_get(port_id
)
1871 def neutron_port_create(self
, **kwargs
):
1872 subnets
= [subnet
for subnet
in self
.neutron_drv
.subnet_list() if subnet
['network_id'] == kwargs
['network_id']]
1873 assert len(subnets
) == 1
1874 kwargs
['subnet_id'] = subnets
[0]['id']
1875 if not 'admin_state_up' in kwargs
:
1876 kwargs
['admin_state_up'] = True
1877 port_id
= self
.neutron_drv
.port_create(**kwargs
)
1879 if 'vm_id' in kwargs
:
1880 self
.nova_server_add_port(kwargs
['vm_id'], port_id
)
1883 def neutron_security_group_list(self
):
1884 return self
.neutron_drv
.security_group_list()
1886 def neutron_security_group_by_name(self
, group_name
):
1887 group_list
= self
.neutron_drv
.security_group_list()
1888 groups
= [group
for group
in group_list
if group
['name'] == group_name
]
1894 def neutron_port_delete(self
, port_id
):
1895 self
.neutron_drv
.port_delete(port_id
)
1897 def ceilo_meter_endpoint(self
):
1898 return self
.ceilo_drv
.endpoint
1900 def ceilo_meter_list(self
):
1901 return self
.ceilo_drv
.meters
1903 def ceilo_nfvi_metrics(self
, vim_id
):
1904 """Returns a dict of NFVI metrics for a given VM
1907 vim_id - the VIM ID of the VM to retrieve the metrics for
1910 A dict of NFVI metrics
1913 def query_latest_sample(counter_name
):
1915 filter = json
.dumps({
1917 {"=": {"resource": vim_id
}},
1918 {"=": {"counter_name": counter_name
}}
1921 orderby
= json
.dumps([{"timestamp": "DESC"}])
1922 result
= self
.ceilo_drv
.client
.query_samples
.query(
1932 except Exception as e
:
1933 logger
.error("Got exception while querying ceilometer, exception details:%s " %str
(e
))
1937 memory_usage
= query_latest_sample("memory.usage")
1938 disk_usage
= query_latest_sample("disk.usage")
1939 cpu_util
= query_latest_sample("cpu_util")
1943 if memory_usage
is not None:
1944 memory_usage
.volume
= 1e6
* memory_usage
.volume
1945 metrics
["memory_usage"] = memory_usage
.to_dict()
1947 if disk_usage
is not None:
1948 metrics
["disk_usage"] = disk_usage
.to_dict()
1950 if cpu_util
is not None:
1951 metrics
["cpu_util"] = cpu_util
.to_dict()
1955 def ceilo_alarm_list(self
):
1956 """Returns a list of ceilometer alarms"""
1957 return self
.ceilo_drv
.client
.alarms
.list()
1959 def ceilo_alarm_create(self
,
1972 """Create a new Alarm
1975 name - the name of the alarm
1976 meter - the name of the meter to measure
1977 statistic - the type of statistic used to trigger the alarm
1978 ('avg', 'min', 'max', 'count', 'sum')
1979 operation - the relational operator that, combined with the
1980 threshold value, determines when the alarm is
1981 triggered ('lt', 'le', 'eq', 'ge', 'gt')
1982 threshold - the value of the statistic that will trigger the
1984 period - the duration (seconds) over which to evaluate the
1986 evaluations - the number of samples of the meter statistic to
1987 collect when evaluating the threshold
1988 severity - a measure of the urgency or importance of the alarm
1989 ('low', 'moderate', 'critical')
1990 repeat - a flag that indicates whether the alarm should be
1991 triggered once (False) or repeatedly while the alarm
1992 condition is true (True)
1993 enabled - a flag that indicates whether the alarm is enabled
1994 (True) or disabled (False)
1995 actions - a dict specifying the URLs for webhooks. The dict can
1996 have up to 3 keys: 'insufficient_data', 'alarm',
1997 'ok'. Each key is associated with a list of URLs to
1998 webhooks that will be invoked when one of the 3
2000 kwargs - an arbitrary dict of keyword arguments that are
2001 passed to the ceilometer client
2004 ok_actions
= actions
.get('ok') if actions
is not None else None
2005 alarm_actions
= actions
.get('alarm') if actions
is not None else None
2006 insufficient_data_actions
= actions
.get('insufficient_data') if actions
is not None else None
2008 return self
.ceilo_drv
.client
.alarms
.create(
2011 statistic
=statistic
,
2012 comparison_operator
=operation
,
2013 threshold
=threshold
,
2015 evaluation_periods
=evaluations
,
2017 repeat_actions
=repeat
,
2019 ok_actions
=ok_actions
,
2020 alarm_actions
=alarm_actions
,
2021 insufficient_data_actions
=insufficient_data_actions
,
2025 def ceilo_alarm_update(self
, alarm_id
, **kwargs
):
2026 """Updates an existing alarm
2029 alarm_id - the identifier of the alarm to update
2030 kwargs - a dict of the alarm attributes to update
2033 return self
.ceilo_drv
.client
.alarms
.update(alarm_id
, **kwargs
)
2035 def ceilo_alarm_delete(self
, alarm_id
):
2036 self
.ceilo_drv
.client
.alarms
.delete(alarm_id
)