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 ip_address(string) : Static IP address to assign to the port
1397 vnic_type(string) : Possible values are "normal", "direct", "macvtap"
1400 port_id (string) : UUID of the port
1402 NOTE: Either subnet_id or ip_address need to be specified.
1406 "admin_state_up" : kwargs
['admin_state_up'],
1407 "name" : kwargs
['name'],
1408 "network_id" : kwargs
['network_id'],
1409 "binding:vnic_type" : kwargs
['port_type']}}
1411 if 'ip_address' in kwargs
:
1412 params
["port"]["fixed_ips"] = [{"ip_address": kwargs
['ip_address']}]
1414 params
["port"]["fixed_ips"] = [{"subnet_id": kwargs
['subnet_id']}]
1416 logger
.debug("Port create params: {}".format(params
))
1418 ntconn
= self
._get
_neutron
_connection
()
1420 port
= ntconn
.create_port(params
)
1421 except Exception as e
:
1422 logger
.error("OpenstackDriver: Port Create operation failed. Exception: %s" %(str(e
)))
1424 return port
['port']['id']
1426 def _port_get(self
, port_id
):
1428 Returns a dictionary object describing the attributes of the port
1431 port_id (string): UUID of the port
1434 A dictionary object of the port attributes
1436 ntconn
= self
._get
_neutron
_connection
()
1437 port
= ntconn
.list_ports(id=port_id
)['ports']
1439 raise NeutronException
.NotFound("Could not find port_id %s" %(port_id))
1442 def port_get(self
, port_id
):
1444 Returns a dictionary object describing the attributes of the port
1447 port_id (string): UUID of the port
1450 A dictionary object of the port attributes
1452 return self
._port
_get
(port_id
)
1454 def port_delete(self
, port_id
):
1456 Deletes a port identified by port_id
1459 port_id (string) : UUID of the port
1463 assert port_id
== self
._port
_get
(port_id
)['id']
1464 ntconn
= self
._get
_neutron
_connection
()
1466 ntconn
.delete_port(port_id
)
1467 except Exception as e
:
1468 logger
.error("Port Delete operation failed for port_id : %s. Exception: %s" %(port_id
, str(e
)))
1471 def security_group_list(self
):
1473 Returns a list of dictionaries. Each dictionary contains attributes describing the security group
1479 A dictionary of the objects of security group attributes
1481 ntconn
= self
._get
_neutron
_connection
()
1483 group_list
= ntconn
.list_security_groups(tenant_id
=self
.ks_drv
.get_tenant_id())
1484 except Exception as e
:
1485 logger
.error("List Security group operation, Exception: %s" %(str(e
)))
1488 if 'security_groups' in group_list
:
1489 return group_list
['security_groups']
1493 def subnetpool_list(self
, **kwargs
):
1495 Returns a list of dictionaries. Each dictionary contains attributes describing a subnet prefix pool
1501 A dictionary of the objects of subnet prefix pool
1503 ntconn
= self
._get
_neutron
_connection
()
1505 pool_list
= ntconn
.list_subnetpools(**kwargs
)
1506 except Exception as e
:
1507 logger
.error("List SubnetPool operation, Exception: %s" %(str(e
)))
1510 if 'subnetpools' in pool_list
:
1511 return pool_list
['subnetpools']
1515 class NeutronDriverV2(NeutronDriver
):
1517 Driver for openstack neutron neutron-client v2
1519 def __init__(self
, ks_drv
):
1521 Constructor for NeutronDriver
1522 Arguments: KeystoneDriver class object
1524 super(NeutronDriverV2
, self
).__init
__(ks_drv
, 'network', '2.0')
1528 class CeilometerDriver(object):
1530 Driver for openstack ceilometer client
1533 def __init__(self
, ks_drv
, service_name
, version
):
1535 Constructor for CeilometerDriver
1536 Arguments: KeystoneDriver class object
1538 self
.ks_drv
= ks_drv
1539 self
._service
_name
= service_name
1540 self
._version
= version
1545 """The version of the ceilometer client used by the driver"""
1546 return self
._version
1550 """The instance of ceilometer client used by the driver"""
1551 if self
._client
is None or not self
.ks_drv
.is_auth_token_valid():
1552 self
._client
= ceilo_client
.Client(**self
.credentials
)
1557 def auth_token(self
):
1558 """The authorization token for the ceilometer client"""
1560 return self
.ks_drv
.get_auth_token()
1561 except KeystoneExceptions
.EndpointNotFound
as e
:
1562 logger
.error("OpenstackDriver: unable to get authorization token for ceilometer. Exception: %s" %(str(e
)))
1566 def security_mode(self
):
1567 """The security mode for the ceilometer client"""
1569 return self
.ks_drv
.get_security_mode()
1570 except KeystoneExceptions
.EndpointNotFound
as e
:
1571 logger
.error("OpenstackDriver: unable to get security mode for ceilometer. Exception: %s" %(str(e
)))
1576 """The service endpoint for the ceilometer client"""
1578 return self
.ks_drv
.get_service_endpoint(self
._service
_name
, "publicURL")
1579 except KeystoneExceptions
.EndpointNotFound
as e
:
1580 logger
.error("OpenstackDriver: unable to get endpoint for ceilometer. Exception: %s" %(str(e
)))
1584 def credentials(self
):
1585 """A dictionary of credentials for the ceilometer client"""
1587 version
=self
.version
,
1588 endpoint
=self
.endpoint
,
1589 token
=self
.auth_token
,
1590 insecure
=self
.security_mode
,
1595 """A list of the available meters"""
1597 return self
.client
.meters
.list()
1598 except Exception as e
:
1599 logger
.error("OpenstackDriver: List meters operation failed. Exception: %s" %(str(e
)))
1604 """The ceilometer client alarms manager"""
1605 return self
.client
.alarms
1607 def query_samples(self
, vim_instance_id
, counter_name
, limit
=1):
1608 """Returns a list of samples
1611 vim_instance_id - the ID of the VIM that the samples are from
1612 counter_name - the counter that the samples will come from
1613 limit - a limit on the number of samples to return
1621 filter = json
.dumps({
1623 {"=": {"resource": vim_instance_id
}},
1624 {"=": {"counter_name": counter_name
}}
1627 result
= self
.client
.query_samples
.query(filter=filter, limit
=limit
)
1628 return result
[-limit
:]
1630 except Exception as e
:
1636 class CeilometerDriverV2(CeilometerDriver
):
1638 Driver for openstack ceilometer ceilometer-client
1640 def __init__(self
, ks_drv
):
1642 Constructor for CeilometerDriver
1643 Arguments: CeilometerDriver class object
1645 super(CeilometerDriverV2
, self
).__init
__(ks_drv
, 'metering', '2')
1647 class OpenstackDriver(object):
1649 Driver for openstack nova, neutron, glance, keystone, swift, cinder services
1651 def __init__(self
, username
, password
, auth_url
, tenant_name
, mgmt_network
= None, cert_validate
= False):
1653 OpenstackDriver Driver constructor
1655 username (string) : Username for project/tenant.
1656 password (string) : Password
1657 auth_url (string) : Keystone Authentication URL.
1658 tenant_name (string) : Openstack project name
1659 mgmt_network(string, optional) : Management network name. Each VM created with this cloud-account will
1660 have a default interface into management network.
1661 cert_validate (boolean, optional) : In case of SSL/TLS connection if certificate validation is required or not.
1664 insecure
= not cert_validate
1665 if auth_url
.find('/v3') != -1:
1666 self
.ks_drv
= KeystoneDriverV3(username
, password
, auth_url
, tenant_name
, insecure
)
1667 self
.glance_drv
= GlanceDriverV2(self
.ks_drv
)
1668 self
.nova_drv
= NovaDriverV21(self
.ks_drv
)
1669 self
.neutron_drv
= NeutronDriverV2(self
.ks_drv
)
1670 self
.ceilo_drv
= CeilometerDriverV2(self
.ks_drv
)
1671 elif auth_url
.find('/v2') != -1:
1672 self
.ks_drv
= KeystoneDriverV2(username
, password
, auth_url
, tenant_name
, insecure
)
1673 self
.glance_drv
= GlanceDriverV2(self
.ks_drv
)
1674 self
.nova_drv
= NovaDriverV2(self
.ks_drv
)
1675 self
.neutron_drv
= NeutronDriverV2(self
.ks_drv
)
1676 self
.ceilo_drv
= CeilometerDriverV2(self
.ks_drv
)
1678 logger
.error("Could not identity the version information for openstack service endpoints. Auth_URL should contain \"/v2\" or \"/v3\" string in it")
1679 raise NotImplementedError("Auth URL is wrong or invalid. Only Keystone v2 & v3 supported")
1681 self
._mgmt
_network
_id
= None
1682 if mgmt_network
!= None:
1683 self
._mgmt
_network
= mgmt_network
1687 ntconn
= self
.neutron_drv
._get
_neutron
_connection
()
1688 networks
= ntconn
.list_networks()
1689 except (KeystoneExceptions
.Unauthorized
, KeystoneExceptions
.AuthorizationFailure
) as e
:
1691 except Exception as e
:
1692 logger
.error("OpenstackDriver: List Network operation failed. Exception: %s" %(str(e
)))
1695 network_list
= [ network
for network
in networks
['networks'] if network
['name'] == mgmt_network
]
1697 if not network_list
:
1698 raise NeutronException
.NotFound("Could not find network %s" %(mgmt_network))
1699 self
._mgmt
_network
_id
= network_list
[0]['id']
1701 def validate_account_creds(self
):
1703 ksconn
= self
.ks_drv
._get
_keystone
_connection
()
1704 except KeystoneExceptions
.AuthorizationFailure
as e
:
1705 logger
.error("OpenstackDriver: Unable to authenticate or validate the existing credentials. Exception: %s" %(str(e
)))
1706 raise ValidationError("Invalid Credentials: "+ str(e
))
1707 except Exception as e
:
1708 logger
.error("OpenstackDriver: Could not connect to Openstack. Exception: %s" %(str(e
)))
1709 raise ValidationError("Connection Error: "+ str(e
))
1711 def get_mgmt_network_id(self
):
1712 return self
._mgmt
_network
_id
1714 def glance_image_create(self
, **kwargs
):
1715 if not 'disk_format' in kwargs
:
1716 kwargs
['disk_format'] = 'qcow2'
1717 if not 'container_format' in kwargs
:
1718 kwargs
['container_format'] = 'bare'
1719 if not 'min_disk' in kwargs
:
1720 kwargs
['min_disk'] = 0
1721 if not 'min_ram' in kwargs
:
1722 kwargs
['min_ram'] = 0
1723 return self
.glance_drv
.image_create(**kwargs
)
1725 def glance_image_upload(self
, image_id
, fd
):
1726 self
.glance_drv
.image_upload(image_id
, fd
)
1728 def glance_image_add_location(self
, image_id
, location
):
1729 self
.glance_drv
.image_add_location(image_id
, location
)
1731 def glance_image_delete(self
, image_id
):
1732 self
.glance_drv
.image_delete(image_id
)
1734 def glance_image_list(self
):
1735 return self
.glance_drv
.image_list()
1737 def glance_image_get(self
, image_id
):
1738 return self
.glance_drv
.image_get(image_id
)
1741 def nova_flavor_list(self
):
1742 return self
.nova_drv
.flavor_list()
1744 def nova_flavor_create(self
, name
, ram
, vcpus
, disk
, epa_specs
):
1745 extra_specs
= epa_specs
if epa_specs
else {}
1746 return self
.nova_drv
.flavor_create(name
,
1750 extra_specs
= extra_specs
)
1752 def nova_flavor_delete(self
, flavor_id
):
1753 self
.nova_drv
.flavor_delete(flavor_id
)
1755 def nova_flavor_get(self
, flavor_id
):
1756 return self
.nova_drv
.flavor_get(flavor_id
)
1758 def nova_server_create(self
, **kwargs
):
1759 def _verify_image(image_id
):
1760 image
= self
.glance_drv
.image_get(image_id
)
1761 if image
['status'] != 'active':
1762 raise GlanceException
.NotFound("Image with image_id: %s not found in active state. Current State: %s" %(image
['id'], image
['status']))
1764 assert kwargs
['flavor_id'] == self
.nova_drv
.flavor_get(kwargs
['flavor_id'])['id']
1766 if kwargs
['block_device_mapping_v2'] is not None:
1767 for block_map
in kwargs
['block_device_mapping_v2']:
1768 if 'uuid' in block_map
:
1769 _verify_image(block_map
['uuid'])
1771 _verify_image(kwargs
['image_id'])
1773 # if 'network_list' in kwargs:
1774 # kwargs['network_list'].append(self._mgmt_network_id)
1776 # kwargs['network_list'] = [self._mgmt_network_id]
1778 if 'security_groups' not in kwargs
:
1779 nvconn
= self
.nova_drv
._get
_nova
_connection
()
1780 sec_groups
= nvconn
.security_groups
.list()
1782 ## Should we add VM in all availability security_groups ???
1783 kwargs
['security_groups'] = [x
.name
for x
in sec_groups
]
1785 kwargs
['security_groups'] = None
1787 return self
.nova_drv
.server_create(**kwargs
)
1789 def nova_server_add_port(self
, server_id
, port_id
):
1790 self
.nova_drv
.server_add_port(server_id
, port_id
)
1792 def nova_server_delete_port(self
, server_id
, port_id
):
1793 self
.nova_drv
.server_delete_port(server_id
, port_id
)
1795 def nova_server_start(self
, server_id
):
1796 self
.nova_drv
.server_start(server_id
)
1798 def nova_server_stop(self
, server_id
):
1799 self
.nova_drv
.server_stop(server_id
)
1801 def nova_server_delete(self
, server_id
):
1802 self
.nova_drv
.server_delete(server_id
)
1804 def nova_server_reboot(self
, server_id
):
1805 self
.nova_drv
.server_reboot(server_id
, reboot_type
='HARD')
1807 def nova_server_rebuild(self
, server_id
, image_id
):
1808 self
.nova_drv
.server_rebuild(server_id
, image_id
)
1810 def nova_floating_ip_list(self
):
1811 return self
.nova_drv
.floating_ip_list()
1813 def nova_floating_ip_create(self
, pool
= None):
1814 return self
.nova_drv
.floating_ip_create(pool
)
1816 def nova_floating_ip_delete(self
, floating_ip
):
1817 self
.nova_drv
.floating_ip_delete(floating_ip
)
1819 def nova_floating_ip_assign(self
, server_id
, floating_ip
, fixed_ip
):
1820 self
.nova_drv
.floating_ip_assign(server_id
, floating_ip
, fixed_ip
)
1822 def nova_floating_ip_release(self
, server_id
, floating_ip
):
1823 self
.nova_drv
.floating_ip_release(server_id
, floating_ip
)
1825 def nova_server_list(self
):
1826 return self
.nova_drv
.server_list()
1828 def nova_server_get(self
, server_id
):
1829 return self
.nova_drv
.server_get(server_id
)
1831 def nova_server_console(self
, server_id
):
1832 return self
.nova_drv
.server_console(server_id
)
1834 def nova_server_group_list(self
):
1835 return self
.nova_drv
.group_list()
1837 def nova_volume_list(self
, server_id
):
1838 return self
.nova_drv
.volume_list(server_id
)
1840 def neutron_network_list(self
):
1841 return self
.neutron_drv
.network_list()
1843 def neutron_network_get(self
, network_id
):
1844 return self
.neutron_drv
.network_get(network_id
)
1846 def neutron_network_by_name(self
, network_name
):
1847 networks
= self
.neutron_network_list()
1848 for network
in networks
:
1849 if network_name
== network
["name"]:
1853 def neutron_network_create(self
, **kwargs
):
1854 return self
.neutron_drv
.network_create(**kwargs
)
1856 def neutron_network_delete(self
, network_id
):
1857 self
.neutron_drv
.network_delete(network_id
)
1859 def neutron_subnet_list(self
):
1860 return self
.neutron_drv
.subnet_list()
1862 def neutron_subnet_get(self
, subnet_id
):
1863 return self
.neutron_drv
.subnet_get(subnet_id
)
1865 def neutron_subnet_create(self
, **kwargs
):
1866 return self
.neutron_drv
.subnet_create(**kwargs
)
1868 def netruon_subnet_delete(self
, subnet_id
):
1869 self
.neutron_drv
.subnet_delete(subnet_id
)
1871 def neutron_subnetpool_list(self
):
1872 return self
.neutron_drv
.subnetpool_list()
1874 def netruon_subnetpool_by_name(self
, pool_name
):
1875 pool_list
= self
.neutron_drv
.subnetpool_list(**{'name': pool_name
})
1881 def neutron_port_list(self
, **kwargs
):
1882 return self
.neutron_drv
.port_list(**kwargs
)
1884 def neutron_port_get(self
, port_id
):
1885 return self
.neutron_drv
.port_get(port_id
)
1887 def neutron_port_create(self
, **kwargs
):
1889 if 'ip_address' not in kwargs
:
1890 subnets
= [subnet
for subnet
in self
.neutron_drv
.subnet_list()
1891 if subnet
['network_id'] == kwargs
['network_id']]
1892 assert len(subnets
) == 1
1893 kwargs
['subnet_id'] = subnets
[0]['id']
1895 if not 'admin_state_up' in kwargs
:
1896 kwargs
['admin_state_up'] = True
1898 logger
.debug("Port create params: {}".
1900 port_id
= self
.neutron_drv
.port_create(**kwargs
)
1902 if 'vm_id' in kwargs
:
1903 self
.nova_server_add_port(kwargs
['vm_id'], port_id
)
1906 def neutron_security_group_list(self
):
1907 return self
.neutron_drv
.security_group_list()
1909 def neutron_security_group_by_name(self
, group_name
):
1910 group_list
= self
.neutron_drv
.security_group_list()
1911 groups
= [group
for group
in group_list
if group
['name'] == group_name
]
1917 def neutron_port_delete(self
, port_id
):
1918 self
.neutron_drv
.port_delete(port_id
)
1920 def ceilo_meter_endpoint(self
):
1921 return self
.ceilo_drv
.endpoint
1923 def ceilo_meter_list(self
):
1924 return self
.ceilo_drv
.meters
1926 def ceilo_nfvi_metrics(self
, vim_id
):
1927 """Returns a dict of NFVI metrics for a given VM
1930 vim_id - the VIM ID of the VM to retrieve the metrics for
1933 A dict of NFVI metrics
1936 def query_latest_sample(counter_name
):
1938 filter = json
.dumps({
1940 {"=": {"resource": vim_id
}},
1941 {"=": {"counter_name": counter_name
}}
1944 orderby
= json
.dumps([{"timestamp": "DESC"}])
1945 result
= self
.ceilo_drv
.client
.query_samples
.query(
1955 except Exception as e
:
1956 logger
.error("Got exception while querying ceilometer, exception details:%s " %str
(e
))
1960 memory_usage
= query_latest_sample("memory.usage")
1961 disk_usage
= query_latest_sample("disk.usage")
1962 cpu_util
= query_latest_sample("cpu_util")
1966 if memory_usage
is not None:
1967 memory_usage
.volume
= 1e6
* memory_usage
.volume
1968 metrics
["memory_usage"] = memory_usage
.to_dict()
1970 if disk_usage
is not None:
1971 metrics
["disk_usage"] = disk_usage
.to_dict()
1973 if cpu_util
is not None:
1974 metrics
["cpu_util"] = cpu_util
.to_dict()
1978 def ceilo_alarm_list(self
):
1979 """Returns a list of ceilometer alarms"""
1980 return self
.ceilo_drv
.client
.alarms
.list()
1982 def ceilo_alarm_create(self
,
1995 """Create a new Alarm
1998 name - the name of the alarm
1999 meter - the name of the meter to measure
2000 statistic - the type of statistic used to trigger the alarm
2001 ('avg', 'min', 'max', 'count', 'sum')
2002 operation - the relational operator that, combined with the
2003 threshold value, determines when the alarm is
2004 triggered ('lt', 'le', 'eq', 'ge', 'gt')
2005 threshold - the value of the statistic that will trigger the
2007 period - the duration (seconds) over which to evaluate the
2009 evaluations - the number of samples of the meter statistic to
2010 collect when evaluating the threshold
2011 severity - a measure of the urgency or importance of the alarm
2012 ('low', 'moderate', 'critical')
2013 repeat - a flag that indicates whether the alarm should be
2014 triggered once (False) or repeatedly while the alarm
2015 condition is true (True)
2016 enabled - a flag that indicates whether the alarm is enabled
2017 (True) or disabled (False)
2018 actions - a dict specifying the URLs for webhooks. The dict can
2019 have up to 3 keys: 'insufficient_data', 'alarm',
2020 'ok'. Each key is associated with a list of URLs to
2021 webhooks that will be invoked when one of the 3
2023 kwargs - an arbitrary dict of keyword arguments that are
2024 passed to the ceilometer client
2027 ok_actions
= actions
.get('ok') if actions
is not None else None
2028 alarm_actions
= actions
.get('alarm') if actions
is not None else None
2029 insufficient_data_actions
= actions
.get('insufficient_data') if actions
is not None else None
2031 return self
.ceilo_drv
.client
.alarms
.create(
2034 statistic
=statistic
,
2035 comparison_operator
=operation
,
2036 threshold
=threshold
,
2038 evaluation_periods
=evaluations
,
2040 repeat_actions
=repeat
,
2042 ok_actions
=ok_actions
,
2043 alarm_actions
=alarm_actions
,
2044 insufficient_data_actions
=insufficient_data_actions
,
2048 def ceilo_alarm_update(self
, alarm_id
, **kwargs
):
2049 """Updates an existing alarm
2052 alarm_id - the identifier of the alarm to update
2053 kwargs - a dict of the alarm attributes to update
2056 return self
.ceilo_drv
.client
.alarms
.update(alarm_id
, **kwargs
)
2058 def ceilo_alarm_delete(self
, alarm_id
):
2059 self
.ceilo_drv
.client
.alarms
.delete(alarm_id
)