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 network_list(List) : A List of network_ids. A port will be created in these networks
534 port_list (List) : A List of port-ids. These ports will be added to VM.
535 metadata (dict) : A dictionary of arbitrary key-value pairs associated with VM/server
536 userdata (string) : A script which shall be executed during first boot of the VM
537 availability_zone (string) : A name of the availability zone where instance should be launched
538 scheduler_hints (string) : Openstack scheduler_hints to be passed to nova scheduler
541 server_id (string): UUID of the VM/server created
545 if 'network_list' in kwargs
:
546 for network_id
in kwargs
['network_list']:
547 nics
.append({'net-id': network_id
})
549 if 'port_list' in kwargs
:
550 for port_id
in kwargs
['port_list']:
551 nics
.append({'port-id': port_id
})
553 nvconn
= self
._get
_nova
_connection
()
556 server
= nvconn
.servers
.create(kwargs
['name'],
559 meta
= kwargs
['metadata'],
561 reservation_id
= None,
564 userdata
= kwargs
['userdata'],
565 security_groups
= kwargs
['security_groups'],
566 availability_zone
= kwargs
['availability_zone'],
567 block_device_mapping
= None,
569 scheduler_hints
= kwargs
['scheduler_hints'],
571 except Exception as e
:
572 logger
.info("OpenstackDriver: Create Server operation failed. Exception: %s" %(str(e
)))
574 return server
.to_dict()['id']
576 def server_delete(self
, server_id
):
578 Deletes a server identified by server_id
581 server_id (string): UUID of the server to be deleted
585 nvconn
= self
._get
_nova
_connection
()
587 nvconn
.servers
.delete(server_id
)
588 except Exception as e
:
589 logger
.error("OpenstackDriver: Delete server operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
592 def server_start(self
, server_id
):
594 Starts a server identified by server_id
597 server_id (string): UUID of the server to be started
601 nvconn
= self
._get
_nova
_connection
()
603 nvconn
.servers
.start(server_id
)
604 except Exception as e
:
605 logger
.error("OpenstackDriver: Start Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
608 def server_stop(self
, server_id
):
611 server_id (string): UUID of the server to be stopped
615 nvconn
= self
._get
_nova
_connection
()
617 nvconn
.servers
.stop(server_id
)
618 except Exception as e
:
619 logger
.error("OpenstackDriver: Stop Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
622 def server_pause(self
, server_id
):
625 server_id (string): UUID of the server to be paused
629 nvconn
= self
._get
_nova
_connection
()
631 nvconn
.servers
.pause(server_id
)
632 except Exception as e
:
633 logger
.error("OpenstackDriver: Pause Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
636 def server_unpause(self
, server_id
):
639 server_id (string): UUID of the server to be unpaused
643 nvconn
= self
._get
_nova
_connection
()
645 nvconn
.servers
.unpause(server_id
)
646 except Exception as e
:
647 logger
.error("OpenstackDriver: Resume Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
651 def server_suspend(self
, server_id
):
654 server_id (string): UUID of the server to be suspended
658 nvconn
= self
._get
_nova
_connection
()
660 nvconn
.servers
.suspend(server_id
)
661 except Exception as e
:
662 logger
.error("OpenstackDriver: Suspend Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
665 def server_resume(self
, server_id
):
668 server_id (string): UUID of the server to be resumed
672 nvconn
= self
._get
_nova
_connection
()
674 nvconn
.servers
.resume(server_id
)
675 except Exception as e
:
676 logger
.error("OpenstackDriver: Resume Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
679 def server_reboot(self
, server_id
, reboot_type
):
682 server_id (string) : UUID of the server to be rebooted
688 nvconn
= self
._get
_nova
_connection
()
690 nvconn
.servers
.reboot(server_id
, reboot_type
)
691 except Exception as e
:
692 logger
.error("OpenstackDriver: Reboot Server operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
695 def server_console(self
, server_id
, console_type
= 'novnc'):
698 server_id (string) : UUID of the server to be rebooted
699 console_type(string):
703 A dictionary object response for console information
705 nvconn
= self
._get
_nova
_connection
()
707 console_info
= nvconn
.servers
.get_vnc_console(server_id
, console_type
)
708 except Exception as e
:
709 logger
.error("OpenstackDriver: Server Get-Console operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
713 def server_rebuild(self
, server_id
, image_id
):
716 server_id (string) : UUID of the server to be rebooted
717 image_id (string) : UUID of the image to use
721 nvconn
= self
._get
_nova
_connection
()
723 nvconn
.servers
.rebuild(server_id
, image_id
)
724 except Exception as e
:
725 logger
.error("OpenstackDriver: Rebuild Server operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
729 def server_add_port(self
, server_id
, port_id
):
732 server_id (string): UUID of the server
733 port_id (string): UUID of the port to be attached
737 nvconn
= self
._get
_nova
_connection
()
739 nvconn
.servers
.interface_attach(server_id
,
743 except Exception as e
:
744 logger
.error("OpenstackDriver: Server Port Add operation failed for server_id : %s, port_id : %s. Exception: %s" %(server_id
, port_id
, str(e
)))
747 def server_delete_port(self
, server_id
, port_id
):
750 server_id (string): UUID of the server
751 port_id (string): UUID of the port to be deleted
755 nvconn
= self
._get
_nova
_connection
()
757 nvconn
.servers
.interface_detach(server_id
, port_id
)
758 except Exception as e
:
759 logger
.error("OpenstackDriver: Server Port Delete operation failed for server_id : %s, port_id : %s. Exception: %s" %(server_id
, port_id
, str(e
)))
762 def floating_ip_list(self
):
767 List of objects of floating IP nova class (novaclient.v2.floating_ips.FloatingIP)
769 nvconn
= self
._get
_nova
_connection
()
771 ip_list
= nvconn
.floating_ips
.list()
772 except Exception as e
:
773 logger
.error("OpenstackDriver: Floating IP List operation failed. Exception: %s" %str
(e
))
778 def floating_ip_create(self
, pool
):
781 pool (string): Name of the pool (optional)
783 An object of floating IP nova class (novaclient.v2.floating_ips.FloatingIP)
785 nvconn
= self
._get
_nova
_connection
()
787 floating_ip
= nvconn
.floating_ips
.create(pool
)
788 except Exception as e
:
789 logger
.error("OpenstackDriver: Floating IP Create operation failed. Exception: %s" %str
(e
))
794 def floating_ip_delete(self
, floating_ip
):
797 floating_ip: An object of floating IP nova class (novaclient.v2.floating_ips.FloatingIP)
801 nvconn
= self
._get
_nova
_connection
()
803 floating_ip
= nvconn
.floating_ips
.delete(floating_ip
)
804 except Exception as e
:
805 logger
.error("OpenstackDriver: Floating IP Delete operation failed. Exception: %s" %str
(e
))
808 def floating_ip_assign(self
, server_id
, floating_ip
, fixed_ip
):
811 server_id (string) : UUID of the server
812 floating_ip (string): IP address string for floating-ip
813 fixed_ip (string) : IP address string for the fixed-ip with which floating ip will be associated
817 nvconn
= self
._get
_nova
_connection
()
819 nvconn
.servers
.add_floating_ip(server_id
, floating_ip
, fixed_ip
)
820 except Exception as e
:
821 logger
.error("OpenstackDriver: Assign Floating IP operation failed. Exception: %s" %str
(e
))
824 def floating_ip_release(self
, server_id
, floating_ip
):
827 server_id (string) : UUID of the server
828 floating_ip (string): IP address string for floating-ip
832 nvconn
= self
._get
_nova
_connection
()
834 nvconn
.servers
.remove_floating_ip(server_id
, floating_ip
)
835 except Exception as e
:
836 logger
.error("OpenstackDriver: Release Floating IP operation failed. Exception: %s" %str
(e
))
839 def group_list(self
):
841 List of Server Affinity and Anti-Affinity Groups
846 List of dictionary objects where dictionary is representation of class (novaclient.v2.server_groups.ServerGroup)
848 nvconn
= self
._get
_nova
_connection
()
850 group_list
= nvconn
.server_groups
.list()
851 except Exception as e
:
852 logger
.error("OpenstackDriver: Server Group List operation failed. Exception: %s" %str
(e
))
855 group_info
= [ group
.to_dict() for group
in group_list
]
860 class NovaDriverV2(NovaDriver
):
862 Driver class for novaclient V2 APIs
864 def __init__(self
, ks_drv
):
866 Constructor for NovaDriver
867 Arguments: KeystoneDriver class object
869 super(NovaDriverV2
, self
).__init
__(ks_drv
, 'compute', '2.0')
871 class NovaDriverV21(NovaDriver
):
873 Driver class for novaclient V2 APIs
875 def __init__(self
, ks_drv
):
877 Constructor for NovaDriver
878 Arguments: KeystoneDriver class object
880 super(NovaDriverV21
, self
).__init
__(ks_drv
, 'computev21', '2.1')
882 class GlanceDriver(object):
884 Driver for openstack glance-client
886 def __init__(self
, ks_drv
, service_name
, version
):
888 Constructor for GlanceDriver
889 Arguments: KeystoneDriver class object
892 self
._service
_name
= service_name
893 self
._version
= version
895 def _get_glance_credentials(self
):
897 Returns a dictionary of kwargs required to instantiate python-glanceclient class
902 A dictionary object of arguments
905 creds
['version'] = self
._version
906 creds
['endpoint'] = self
.ks_drv
.get_service_endpoint(self
._service
_name
, 'publicURL')
907 creds
['token'] = self
.ks_drv
.get_auth_token()
908 creds
['insecure'] = self
.ks_drv
.get_security_mode()
911 def _get_glance_connection(self
):
913 Returns a object of class python-glanceclient
915 if not hasattr(self
, '_glance_connection'):
916 self
._glance
_connection
= glclient
.Client(**self
._get
_glance
_credentials
())
918 # Reinitialize if auth_token is no longer valid
919 if not self
.ks_drv
.is_auth_token_valid():
920 self
._glance
_connection
= glclient
.Client(**self
._get
_glance
_credentials
())
921 return self
._glance
_connection
923 def image_list(self
):
925 Returns list of dictionaries. Each dictionary contains attributes associated with
930 Returns: List of dictionaries.
932 glconn
= self
._get
_glance
_connection
()
935 image_info
= glconn
.images
.list()
936 except Exception as e
:
937 logger
.error("OpenstackDriver: List Image operation failed. Exception: %s" %(str(e
)))
939 images
= [ img
for img
in image_info
]
942 def image_create(self
, **kwargs
):
946 A dictionary of kwargs with following keys
948 'name'(string) : Name of the image
949 'location'(string) : URL (http://....) where image is located
950 'disk_format'(string) : Disk format
951 Possible values are 'ami', 'ari', 'aki', 'vhd', 'vmdk', 'raw', 'qcow2', 'vdi', 'iso'
952 'container_format'(string): Container format
953 Possible values are 'ami', 'ari', 'aki', 'bare', 'ovf'
954 'tags' : A list of user tags
955 'checksum' : The image md5 checksum
958 image_id (string) : UUID of the image
961 glconn
= self
._get
_glance
_connection
()
963 image
= glconn
.images
.create(**kwargs
)
964 except Exception as e
:
965 logger
.error("OpenstackDriver: Create Image operation failed. Exception: %s" %(str(e
)))
970 def image_upload(self
, image_id
, fd
):
975 image_id: UUID of the image
976 fd : File descriptor for the image file
979 glconn
= self
._get
_glance
_connection
()
981 glconn
.images
.upload(image_id
, fd
)
982 except Exception as e
:
983 logger
.error("OpenstackDriver: Image upload operation failed. Exception: %s" %(str(e
)))
986 def image_add_location(self
, image_id
, location
, metadata
):
988 Add image URL location
991 image_id : UUID of the image
992 location : http URL for the image
996 glconn
= self
._get
_glance
_connection
()
998 image
= glconn
.images
.add_location(image_id
, location
, metadata
)
999 except Exception as e
:
1000 logger
.error("OpenstackDriver: Image location add operation failed. Exception: %s" %(str(e
)))
1003 def image_update(self
):
1006 def image_delete(self
, image_id
):
1011 image_id: UUID of the image
1016 assert image_id
== self
._image
_get
(image_id
)['id']
1017 glconn
= self
._get
_glance
_connection
()
1019 glconn
.images
.delete(image_id
)
1020 except Exception as e
:
1021 logger
.error("OpenstackDriver: Delete Image operation failed for image_id : %s. Exception: %s" %(image_id
, str(e
)))
1025 def _image_get(self
, image_id
):
1027 Returns a dictionary object of VM image attributes
1030 image_id (string): UUID of the image
1033 A dictionary of the image attributes
1035 glconn
= self
._get
_glance
_connection
()
1037 image
= glconn
.images
.get(image_id
)
1038 except GlanceException
.HTTPBadRequest
:
1039 # RIFT-14241: The get image request occasionally returns the below message. Retry in case of bad request exception.
1040 # Error code 400.: Message: Bad request syntax ('0').: Error code explanation: 400 = Bad request syntax or unsupported method. (HTTP 400)
1041 logger
.warning("OpenstackDriver: Got bad request response during get_image request. Retrying.")
1042 image
= glconn
.images
.get(image_id
)
1043 except Exception as e
:
1044 logger
.error("OpenstackDriver: Get Image operation failed for image_id : %s. Exception: %s" %(image_id
, str(e
)))
1049 def image_get(self
, image_id
):
1051 Returns a dictionary object of VM image attributes
1054 image_id (string): UUID of the image
1057 A dictionary of the image attributes
1059 return self
._image
_get
(image_id
)
1061 class GlanceDriverV2(GlanceDriver
):
1063 Driver for openstack glance-client V2
1065 def __init__(self
, ks_drv
):
1066 super(GlanceDriverV2
, self
).__init
__(ks_drv
, 'image', 2)
1068 class NeutronDriver(object):
1070 Driver for openstack neutron neutron-client
1072 def __init__(self
, ks_drv
, service_name
, version
):
1074 Constructor for NeutronDriver
1075 Arguments: KeystoneDriver class object
1077 self
.ks_drv
= ks_drv
1078 self
._service
_name
= service_name
1079 self
._version
= version
1081 def _get_neutron_credentials(self
):
1083 Returns a dictionary of kwargs required to instantiate python-neutronclient class
1086 Dictionary of kwargs
1089 creds
['api_version'] = self
._version
1090 creds
['endpoint_url'] = self
.ks_drv
.get_service_endpoint(self
._service
_name
, 'publicURL')
1091 creds
['token'] = self
.ks_drv
.get_auth_token()
1092 creds
['tenant_name'] = self
.ks_drv
.get_tenant_name()
1093 creds
['insecure'] = self
.ks_drv
.get_security_mode()
1096 def _get_neutron_connection(self
):
1098 Returns an object of class python-neutronclient
1100 if not hasattr(self
, '_neutron_connection'):
1101 self
._neutron
_connection
= ntclient
.Client(**self
._get
_neutron
_credentials
())
1103 # Reinitialize if auth_token is no longer valid
1104 if not self
.ks_drv
.is_auth_token_valid():
1105 self
._neutron
_connection
= ntclient
.Client(**self
._get
_neutron
_credentials
())
1106 return self
._neutron
_connection
1108 def network_list(self
):
1110 Returns list of dictionaries. Each dictionary contains the attributes for a network
1116 A list of dictionaries
1119 ntconn
= self
._get
_neutron
_connection
()
1121 networks
= ntconn
.list_networks()
1122 except Exception as e
:
1123 logger
.error("OpenstackDriver: List Network operation failed. Exception: %s" %(str(e
)))
1125 return networks
['networks']
1127 def network_create(self
, **kwargs
):
1129 Creates a new network for the project
1132 A dictionary with following key-values
1134 name (string) : Name of the network
1135 admin_state_up(Boolean) : True/False (Defaults: True)
1136 external_router(Boolean) : Connectivity with external router. True/False (Defaults: False)
1137 shared(Boolean) : Shared among tenants. True/False (Defaults: False)
1138 physical_network(string) : The physical network where this network object is implemented (optional).
1139 network_type : The type of physical network that maps to this network resource (optional).
1140 Possible values are: 'flat', 'vlan', 'vxlan', 'gre'
1141 segmentation_id : An isolated segment on the physical network. The network_type attribute
1142 defines the segmentation model. For example, if the network_type value
1143 is vlan, this ID is a vlan identifier. If the network_type value is gre,
1144 this ID is a gre key.
1147 params
= {'network':
1148 {'name' : kwargs
['name'],
1149 'admin_state_up' : kwargs
['admin_state_up'],
1150 'tenant_id' : self
.ks_drv
.get_tenant_id(),
1151 'shared' : kwargs
['shared'],
1152 #'port_security_enabled': port_security_enabled,
1153 'router:external' : kwargs
['external_router']}}
1155 if 'physical_network' in kwargs
:
1156 params
['network']['provider:physical_network'] = kwargs
['physical_network']
1157 if 'network_type' in kwargs
:
1158 params
['network']['provider:network_type'] = kwargs
['network_type']
1159 if 'segmentation_id' in kwargs
:
1160 params
['network']['provider:segmentation_id'] = kwargs
['segmentation_id']
1162 ntconn
= self
._get
_neutron
_connection
()
1164 logger
.debug("Calling neutron create_network() with params: %s", str(params
))
1165 net
= ntconn
.create_network(params
)
1166 except Exception as e
:
1167 logger
.error("OpenstackDriver: Create Network operation failed. Exception: %s" %(str(e
)))
1169 logger
.debug("Got create_network response from neutron connection: %s", str(net
))
1170 network_id
= net
['network']['id']
1172 raise Exception("Empty network id returned from create_network. (params: %s)" % str(params
))
1176 def network_delete(self
, network_id
):
1178 Deletes a network identified by network_id
1181 network_id (string): UUID of the network
1185 assert network_id
== self
._network
_get
(network_id
)['id']
1186 ntconn
= self
._get
_neutron
_connection
()
1188 ntconn
.delete_network(network_id
)
1189 except Exception as e
:
1190 logger
.error("OpenstackDriver: Delete Network operation failed. Exception: %s" %(str(e
)))
1193 def _network_get(self
, network_id
):
1195 Returns a dictionary object describing the attributes of the network
1198 network_id (string): UUID of the network
1201 A dictionary object of the network attributes
1203 ntconn
= self
._get
_neutron
_connection
()
1204 network
= ntconn
.list_networks(id = network_id
)['networks']
1206 raise NeutronException
.NotFound("Network with id %s not found"%(network_id))
1210 def network_get(self
, network_id
):
1212 Returns a dictionary object describing the attributes of the network
1215 network_id (string): UUID of the network
1218 A dictionary object of the network attributes
1220 return self
._network
_get
(network_id
)
1222 def subnet_create(self
, **kwargs
):
1224 Creates a subnet on the network
1227 A dictionary with following key value pairs
1229 network_id(string) : UUID of the network where subnet needs to be created
1230 subnet_cidr(string) : IPv4 address prefix (e.g. '1.1.1.0/24') for the subnet
1231 ip_version (integer): 4 for IPv4 and 6 for IPv6
1236 subnet_id (string): UUID of the created subnet
1239 params
['network_id'] = kwargs
['network_id']
1240 params
['ip_version'] = kwargs
['ip_version']
1242 # if params['ip_version'] == 6:
1243 # assert 0, "IPv6 is not supported"
1245 if 'subnetpool_id' in kwargs
:
1246 params
['subnetpool_id'] = kwargs
['subnetpool_id']
1248 params
['cidr'] = kwargs
['cidr']
1250 if 'gateway_ip' in kwargs
:
1251 params
['gateway_ip'] = kwargs
['gateway_ip']
1253 params
['gateway_ip'] = None
1255 if 'dhcp_params' in kwargs
:
1256 params
['enable_dhcp'] = kwargs
['dhcp_params']['enable_dhcp']
1257 if 'start_address' in kwargs
['dhcp_params'] and 'count' in kwargs
['dhcp_params']:
1258 end_address
= (ipaddress
.IPv4Address(kwargs
['dhcp_params']['start_address']) + kwargs
['dhcp_params']['count']).compressed
1259 params
['allocation_pools'] = [ {'start': kwargs
['dhcp_params']['start_address'] ,
1260 'end' : end_address
} ]
1262 if 'dns_server' in kwargs
:
1263 params
['dns_nameservers'] = []
1264 for server
in kwargs
['dns_server']:
1265 params
['dns_nameservers'].append(server
)
1267 ntconn
= self
._get
_neutron
_connection
()
1269 subnet
= ntconn
.create_subnet({'subnets': [params
]})
1270 except Exception as e
:
1271 logger
.error("OpenstackDriver: Create Subnet operation failed. Exception: %s" %(str(e
)))
1274 return subnet
['subnets'][0]['id']
1276 def subnet_list(self
):
1278 Returns a list of dictionaries. Each dictionary contains attributes describing the subnet
1283 A dictionary of the objects of subnet attributes
1285 ntconn
= self
._get
_neutron
_connection
()
1287 subnets
= ntconn
.list_subnets()['subnets']
1288 except Exception as e
:
1289 logger
.error("OpenstackDriver: List Subnet operation failed. Exception: %s" %(str(e
)))
1293 def _subnet_get(self
, subnet_id
):
1295 Returns a dictionary object describing the attributes of a subnet.
1298 subnet_id (string): UUID of the subnet
1301 A dictionary object of the subnet attributes
1303 ntconn
= self
._get
_neutron
_connection
()
1304 subnets
= ntconn
.list_subnets(id=subnet_id
)
1305 if not subnets
['subnets']:
1306 logger
.error("OpenstackDriver: Get subnet operation failed for subnet_id: %s" %(subnet_id))
1307 #raise NeutronException.NotFound("Could not find subnet_id %s" %(subnet_id))
1310 return subnets
['subnets'][0]
1312 def subnet_get(self
, subnet_id
):
1314 Returns a dictionary object describing the attributes of a subnet.
1317 subnet_id (string): UUID of the subnet
1320 A dictionary object of the subnet attributes
1322 return self
._subnet
_get
(subnet_id
)
1324 def subnet_delete(self
, subnet_id
):
1326 Deletes a subnet identified by subnet_id
1329 subnet_id (string): UUID of the subnet to be deleted
1333 ntconn
= self
._get
_neutron
_connection
()
1334 assert subnet_id
== self
._subnet
_get
(self
,subnet_id
)
1336 ntconn
.delete_subnet(subnet_id
)
1337 except Exception as e
:
1338 logger
.error("OpenstackDriver: Delete Subnet operation failed for subnet_id : %s. Exception: %s" %(subnet_id
, str(e
)))
1341 def port_list(self
, **kwargs
):
1343 Returns a list of dictionaries. Each dictionary contains attributes describing the port
1346 kwargs (dictionary): A dictionary for filters for port_list operation
1349 A dictionary of the objects of port attributes
1353 ntconn
= self
._get
_neutron
_connection
()
1355 kwargs
['tenant_id'] = self
.ks_drv
.get_tenant_id()
1358 ports
= ntconn
.list_ports(**kwargs
)
1359 except Exception as e
:
1360 logger
.info("OpenstackDriver: List Port operation failed. Exception: %s" %(str(e
)))
1362 return ports
['ports']
1364 def port_create(self
, **kwargs
):
1366 Create a port in network
1369 A dictionary of following
1371 name (string) : Name of the port
1372 network_id(string) : UUID of the network_id identifying the network to which port belongs
1373 subnet_id(string) : UUID of the subnet_id from which IP-address will be assigned to port
1374 vnic_type(string) : Possible values are "normal", "direct", "macvtap"
1377 port_id (string) : UUID of the port
1381 "admin_state_up" : kwargs
['admin_state_up'],
1382 "name" : kwargs
['name'],
1383 "network_id" : kwargs
['network_id'],
1384 "fixed_ips" : [ {"subnet_id": kwargs
['subnet_id']}],
1385 "binding:vnic_type" : kwargs
['port_type']}}
1387 ntconn
= self
._get
_neutron
_connection
()
1389 port
= ntconn
.create_port(params
)
1390 except Exception as e
:
1391 logger
.error("OpenstackDriver: Port Create operation failed. Exception: %s" %(str(e
)))
1393 return port
['port']['id']
1395 def _port_get(self
, port_id
):
1397 Returns a dictionary object describing the attributes of the port
1400 port_id (string): UUID of the port
1403 A dictionary object of the port attributes
1405 ntconn
= self
._get
_neutron
_connection
()
1406 port
= ntconn
.list_ports(id=port_id
)['ports']
1408 raise NeutronException
.NotFound("Could not find port_id %s" %(port_id))
1411 def port_get(self
, port_id
):
1413 Returns a dictionary object describing the attributes of the port
1416 port_id (string): UUID of the port
1419 A dictionary object of the port attributes
1421 return self
._port
_get
(port_id
)
1423 def port_delete(self
, port_id
):
1425 Deletes a port identified by port_id
1428 port_id (string) : UUID of the port
1432 assert port_id
== self
._port
_get
(port_id
)['id']
1433 ntconn
= self
._get
_neutron
_connection
()
1435 ntconn
.delete_port(port_id
)
1436 except Exception as e
:
1437 logger
.error("Port Delete operation failed for port_id : %s. Exception: %s" %(port_id
, str(e
)))
1440 def security_group_list(self
):
1442 Returns a list of dictionaries. Each dictionary contains attributes describing the security group
1448 A dictionary of the objects of security group attributes
1450 ntconn
= self
._get
_neutron
_connection
()
1452 group_list
= ntconn
.list_security_groups(tenant_id
=self
.ks_drv
.get_tenant_id())
1453 except Exception as e
:
1454 logger
.error("List Security group operation, Exception: %s" %(str(e
)))
1457 if 'security_groups' in group_list
:
1458 return group_list
['security_groups']
1462 def subnetpool_list(self
, **kwargs
):
1464 Returns a list of dictionaries. Each dictionary contains attributes describing a subnet prefix pool
1470 A dictionary of the objects of subnet prefix pool
1472 ntconn
= self
._get
_neutron
_connection
()
1474 pool_list
= ntconn
.list_subnetpools(**kwargs
)
1475 except Exception as e
:
1476 logger
.error("List SubnetPool operation, Exception: %s" %(str(e
)))
1479 if 'subnetpools' in pool_list
:
1480 return pool_list
['subnetpools']
1484 class NeutronDriverV2(NeutronDriver
):
1486 Driver for openstack neutron neutron-client v2
1488 def __init__(self
, ks_drv
):
1490 Constructor for NeutronDriver
1491 Arguments: KeystoneDriver class object
1493 super(NeutronDriverV2
, self
).__init
__(ks_drv
, 'network', '2.0')
1497 class CeilometerDriver(object):
1499 Driver for openstack ceilometer client
1502 def __init__(self
, ks_drv
, service_name
, version
):
1504 Constructor for CeilometerDriver
1505 Arguments: KeystoneDriver class object
1507 self
.ks_drv
= ks_drv
1508 self
._service
_name
= service_name
1509 self
._version
= version
1514 """The version of the ceilometer client used by the driver"""
1515 return self
._version
1519 """The instance of ceilometer client used by the driver"""
1520 if self
._client
is None or not self
.ks_drv
.is_auth_token_valid():
1521 self
._client
= ceilo_client
.Client(**self
.credentials
)
1526 def auth_token(self
):
1527 """The authorization token for the ceilometer client"""
1529 return self
.ks_drv
.get_auth_token()
1530 except KeystoneExceptions
.EndpointNotFound
as e
:
1531 logger
.error("OpenstackDriver: unable to get authorization token for ceilometer. Exception: %s" %(str(e
)))
1535 def security_mode(self
):
1536 """The security mode for the ceilometer client"""
1538 return self
.ks_drv
.get_security_mode()
1539 except KeystoneExceptions
.EndpointNotFound
as e
:
1540 logger
.error("OpenstackDriver: unable to get security mode for ceilometer. Exception: %s" %(str(e
)))
1545 """The service endpoint for the ceilometer client"""
1547 return self
.ks_drv
.get_service_endpoint(self
._service
_name
, "publicURL")
1548 except KeystoneExceptions
.EndpointNotFound
as e
:
1549 logger
.error("OpenstackDriver: unable to get endpoint for ceilometer. Exception: %s" %(str(e
)))
1553 def credentials(self
):
1554 """A dictionary of credentials for the ceilometer client"""
1556 version
=self
.version
,
1557 endpoint
=self
.endpoint
,
1558 token
=self
.auth_token
,
1559 insecure
=self
.security_mode
,
1564 """A list of the available meters"""
1566 return self
.client
.meters
.list()
1567 except Exception as e
:
1568 logger
.error("OpenstackDriver: List meters operation failed. Exception: %s" %(str(e
)))
1573 """The ceilometer client alarms manager"""
1574 return self
.client
.alarms
1576 def query_samples(self
, vim_instance_id
, counter_name
, limit
=1):
1577 """Returns a list of samples
1580 vim_instance_id - the ID of the VIM that the samples are from
1581 counter_name - the counter that the samples will come from
1582 limit - a limit on the number of samples to return
1590 filter = json
.dumps({
1592 {"=": {"resource": vim_instance_id
}},
1593 {"=": {"counter_name": counter_name
}}
1596 result
= self
.client
.query_samples
.query(filter=filter, limit
=limit
)
1597 return result
[-limit
:]
1599 except Exception as e
:
1605 class CeilometerDriverV2(CeilometerDriver
):
1607 Driver for openstack ceilometer ceilometer-client
1609 def __init__(self
, ks_drv
):
1611 Constructor for CeilometerDriver
1612 Arguments: CeilometerDriver class object
1614 super(CeilometerDriverV2
, self
).__init
__(ks_drv
, 'metering', '2')
1616 class OpenstackDriver(object):
1618 Driver for openstack nova, neutron, glance, keystone, swift, cinder services
1620 def __init__(self
, username
, password
, auth_url
, tenant_name
, mgmt_network
= None, cert_validate
= False):
1622 OpenstackDriver Driver constructor
1624 username (string) : Username for project/tenant.
1625 password (string) : Password
1626 auth_url (string) : Keystone Authentication URL.
1627 tenant_name (string) : Openstack project name
1628 mgmt_network(string, optional) : Management network name. Each VM created with this cloud-account will
1629 have a default interface into management network.
1630 cert_validate (boolean, optional) : In case of SSL/TLS connection if certificate validation is required or not.
1633 insecure
= not cert_validate
1634 if auth_url
.find('/v3') != -1:
1635 self
.ks_drv
= KeystoneDriverV3(username
, password
, auth_url
, tenant_name
, insecure
)
1636 self
.glance_drv
= GlanceDriverV2(self
.ks_drv
)
1637 self
.nova_drv
= NovaDriverV21(self
.ks_drv
)
1638 self
.neutron_drv
= NeutronDriverV2(self
.ks_drv
)
1639 self
.ceilo_drv
= CeilometerDriverV2(self
.ks_drv
)
1640 elif auth_url
.find('/v2') != -1:
1641 self
.ks_drv
= KeystoneDriverV2(username
, password
, auth_url
, tenant_name
, insecure
)
1642 self
.glance_drv
= GlanceDriverV2(self
.ks_drv
)
1643 self
.nova_drv
= NovaDriverV2(self
.ks_drv
)
1644 self
.neutron_drv
= NeutronDriverV2(self
.ks_drv
)
1645 self
.ceilo_drv
= CeilometerDriverV2(self
.ks_drv
)
1647 logger
.error("Could not identity the version information for openstack service endpoints. Auth_URL should contain \"/v2\" or \"/v3\" string in it")
1648 raise NotImplementedError("Auth URL is wrong or invalid. Only Keystone v2 & v3 supported")
1650 if mgmt_network
!= None:
1651 self
._mgmt
_network
= mgmt_network
1655 ntconn
= self
.neutron_drv
._get
_neutron
_connection
()
1656 networks
= ntconn
.list_networks()
1657 except (KeystoneExceptions
.Unauthorized
, KeystoneExceptions
.AuthorizationFailure
) as e
:
1659 except Exception as e
:
1660 logger
.error("OpenstackDriver: List Network operation failed. Exception: %s" %(str(e
)))
1663 network_list
= [ network
for network
in networks
['networks'] if network
['name'] == mgmt_network
]
1665 if not network_list
:
1666 raise NeutronException
.NotFound("Could not find network %s" %(mgmt_network))
1667 self
._mgmt
_network
_id
= network_list
[0]['id']
1669 def validate_account_creds(self
):
1671 ksconn
= self
.ks_drv
._get
_keystone
_connection
()
1672 except KeystoneExceptions
.AuthorizationFailure
as e
:
1673 logger
.error("OpenstackDriver: Unable to authenticate or validate the existing credentials. Exception: %s" %(str(e
)))
1674 raise ValidationError("Invalid Credentials: "+ str(e
))
1675 except Exception as e
:
1676 logger
.error("OpenstackDriver: Could not connect to Openstack. Exception: %s" %(str(e
)))
1677 raise ValidationError("Connection Error: "+ str(e
))
1679 def get_mgmt_network_id(self
):
1680 return self
._mgmt
_network
_id
1682 def glance_image_create(self
, **kwargs
):
1683 if not 'disk_format' in kwargs
:
1684 kwargs
['disk_format'] = 'qcow2'
1685 if not 'container_format' in kwargs
:
1686 kwargs
['container_format'] = 'bare'
1687 if not 'min_disk' in kwargs
:
1688 kwargs
['min_disk'] = 0
1689 if not 'min_ram' in kwargs
:
1690 kwargs
['min_ram'] = 0
1691 return self
.glance_drv
.image_create(**kwargs
)
1693 def glance_image_upload(self
, image_id
, fd
):
1694 self
.glance_drv
.image_upload(image_id
, fd
)
1696 def glance_image_add_location(self
, image_id
, location
):
1697 self
.glance_drv
.image_add_location(image_id
, location
)
1699 def glance_image_delete(self
, image_id
):
1700 self
.glance_drv
.image_delete(image_id
)
1702 def glance_image_list(self
):
1703 return self
.glance_drv
.image_list()
1705 def glance_image_get(self
, image_id
):
1706 return self
.glance_drv
.image_get(image_id
)
1709 def nova_flavor_list(self
):
1710 return self
.nova_drv
.flavor_list()
1712 def nova_flavor_create(self
, name
, ram
, vcpus
, disk
, epa_specs
):
1713 extra_specs
= epa_specs
if epa_specs
else {}
1714 return self
.nova_drv
.flavor_create(name
,
1718 extra_specs
= extra_specs
)
1720 def nova_flavor_delete(self
, flavor_id
):
1721 self
.nova_drv
.flavor_delete(flavor_id
)
1723 def nova_flavor_get(self
, flavor_id
):
1724 return self
.nova_drv
.flavor_get(flavor_id
)
1726 def nova_server_create(self
, **kwargs
):
1727 assert kwargs
['flavor_id'] == self
.nova_drv
.flavor_get(kwargs
['flavor_id'])['id']
1728 image
= self
.glance_drv
.image_get(kwargs
['image_id'])
1729 if image
['status'] != 'active':
1730 raise GlanceException
.NotFound("Image with image_id: %s not found in active state. Current State: %s" %(image
['id'], image
['status']))
1732 # if 'network_list' in kwargs:
1733 # kwargs['network_list'].append(self._mgmt_network_id)
1735 # kwargs['network_list'] = [self._mgmt_network_id]
1737 if 'security_groups' not in kwargs
:
1738 nvconn
= self
.nova_drv
._get
_nova
_connection
()
1739 sec_groups
= nvconn
.security_groups
.list()
1741 ## Should we add VM in all availability security_groups ???
1742 kwargs
['security_groups'] = [x
.name
for x
in sec_groups
]
1744 kwargs
['security_groups'] = None
1746 return self
.nova_drv
.server_create(**kwargs
)
1748 def nova_server_add_port(self
, server_id
, port_id
):
1749 self
.nova_drv
.server_add_port(server_id
, port_id
)
1751 def nova_server_delete_port(self
, server_id
, port_id
):
1752 self
.nova_drv
.server_delete_port(server_id
, port_id
)
1754 def nova_server_start(self
, server_id
):
1755 self
.nova_drv
.server_start(server_id
)
1757 def nova_server_stop(self
, server_id
):
1758 self
.nova_drv
.server_stop(server_id
)
1760 def nova_server_delete(self
, server_id
):
1761 self
.nova_drv
.server_delete(server_id
)
1763 def nova_server_reboot(self
, server_id
):
1764 self
.nova_drv
.server_reboot(server_id
, reboot_type
='HARD')
1766 def nova_server_rebuild(self
, server_id
, image_id
):
1767 self
.nova_drv
.server_rebuild(server_id
, image_id
)
1769 def nova_floating_ip_list(self
):
1770 return self
.nova_drv
.floating_ip_list()
1772 def nova_floating_ip_create(self
, pool
= None):
1773 return self
.nova_drv
.floating_ip_create(pool
)
1775 def nova_floating_ip_delete(self
, floating_ip
):
1776 self
.nova_drv
.floating_ip_delete(floating_ip
)
1778 def nova_floating_ip_assign(self
, server_id
, floating_ip
, fixed_ip
):
1779 self
.nova_drv
.floating_ip_assign(server_id
, floating_ip
, fixed_ip
)
1781 def nova_floating_ip_release(self
, server_id
, floating_ip
):
1782 self
.nova_drv
.floating_ip_release(server_id
, floating_ip
)
1784 def nova_server_list(self
):
1785 return self
.nova_drv
.server_list()
1787 def nova_server_get(self
, server_id
):
1788 return self
.nova_drv
.server_get(server_id
)
1790 def nova_server_console(self
, server_id
):
1791 return self
.nova_drv
.server_console(server_id
)
1793 def nova_server_group_list(self
):
1794 return self
.nova_drv
.group_list()
1796 def neutron_network_list(self
):
1797 return self
.neutron_drv
.network_list()
1799 def neutron_network_get(self
, network_id
):
1800 return self
.neutron_drv
.network_get(network_id
)
1802 def neutron_network_create(self
, **kwargs
):
1803 return self
.neutron_drv
.network_create(**kwargs
)
1805 def neutron_network_delete(self
, network_id
):
1806 self
.neutron_drv
.network_delete(network_id
)
1808 def neutron_subnet_list(self
):
1809 return self
.neutron_drv
.subnet_list()
1811 def neutron_subnet_get(self
, subnet_id
):
1812 return self
.neutron_drv
.subnet_get(subnet_id
)
1814 def neutron_subnet_create(self
, **kwargs
):
1815 return self
.neutron_drv
.subnet_create(**kwargs
)
1817 def netruon_subnet_delete(self
, subnet_id
):
1818 self
.neutron_drv
.subnet_delete(subnet_id
)
1820 def neutron_subnetpool_list(self
):
1821 return self
.neutron_drv
.subnetpool_list()
1823 def netruon_subnetpool_by_name(self
, pool_name
):
1824 pool_list
= self
.neutron_drv
.subnetpool_list(**{'name': pool_name
})
1830 def neutron_port_list(self
, **kwargs
):
1831 return self
.neutron_drv
.port_list(**kwargs
)
1833 def neutron_port_get(self
, port_id
):
1834 return self
.neutron_drv
.port_get(port_id
)
1836 def neutron_port_create(self
, **kwargs
):
1837 subnets
= [subnet
for subnet
in self
.neutron_drv
.subnet_list() if subnet
['network_id'] == kwargs
['network_id']]
1838 assert len(subnets
) == 1
1839 kwargs
['subnet_id'] = subnets
[0]['id']
1840 if not 'admin_state_up' in kwargs
:
1841 kwargs
['admin_state_up'] = True
1842 port_id
= self
.neutron_drv
.port_create(**kwargs
)
1844 if 'vm_id' in kwargs
:
1845 self
.nova_server_add_port(kwargs
['vm_id'], port_id
)
1848 def neutron_security_group_list(self
):
1849 return self
.neutron_drv
.security_group_list()
1851 def neutron_security_group_by_name(self
, group_name
):
1852 group_list
= self
.neutron_drv
.security_group_list()
1853 groups
= [group
for group
in group_list
if group
['name'] == group_name
]
1859 def neutron_port_delete(self
, port_id
):
1860 self
.neutron_drv
.port_delete(port_id
)
1862 def ceilo_meter_endpoint(self
):
1863 return self
.ceilo_drv
.endpoint
1865 def ceilo_meter_list(self
):
1866 return self
.ceilo_drv
.meters
1868 def ceilo_nfvi_metrics(self
, vim_id
):
1869 """Returns a dict of NFVI metrics for a given VM
1872 vim_id - the VIM ID of the VM to retrieve the metrics for
1875 A dict of NFVI metrics
1878 def query_latest_sample(counter_name
):
1880 filter = json
.dumps({
1882 {"=": {"resource": vim_id
}},
1883 {"=": {"counter_name": counter_name
}}
1886 orderby
= json
.dumps([{"timestamp": "DESC"}])
1887 result
= self
.ceilo_drv
.client
.query_samples
.query(
1897 except Exception as e
:
1898 logger
.error("Got exception while querying ceilometer, exception details:%s " %str
(e
))
1902 memory_usage
= query_latest_sample("memory.usage")
1903 disk_usage
= query_latest_sample("disk.usage")
1904 cpu_util
= query_latest_sample("cpu_util")
1908 if memory_usage
is not None:
1909 memory_usage
.volume
= 1e6
* memory_usage
.volume
1910 metrics
["memory_usage"] = memory_usage
.to_dict()
1912 if disk_usage
is not None:
1913 metrics
["disk_usage"] = disk_usage
.to_dict()
1915 if cpu_util
is not None:
1916 metrics
["cpu_util"] = cpu_util
.to_dict()
1920 def ceilo_alarm_list(self
):
1921 """Returns a list of ceilometer alarms"""
1922 return self
.ceilo_drv
.client
.alarms
.list()
1924 def ceilo_alarm_create(self
,
1937 """Create a new Alarm
1940 name - the name of the alarm
1941 meter - the name of the meter to measure
1942 statistic - the type of statistic used to trigger the alarm
1943 ('avg', 'min', 'max', 'count', 'sum')
1944 operation - the relational operator that, combined with the
1945 threshold value, determines when the alarm is
1946 triggered ('lt', 'le', 'eq', 'ge', 'gt')
1947 threshold - the value of the statistic that will trigger the
1949 period - the duration (seconds) over which to evaluate the
1951 evaluations - the number of samples of the meter statistic to
1952 collect when evaluating the threshold
1953 severity - a measure of the urgency or importance of the alarm
1954 ('low', 'moderate', 'critical')
1955 repeat - a flag that indicates whether the alarm should be
1956 triggered once (False) or repeatedly while the alarm
1957 condition is true (True)
1958 enabled - a flag that indicates whether the alarm is enabled
1959 (True) or disabled (False)
1960 actions - a dict specifying the URLs for webhooks. The dict can
1961 have up to 3 keys: 'insufficient_data', 'alarm',
1962 'ok'. Each key is associated with a list of URLs to
1963 webhooks that will be invoked when one of the 3
1965 kwargs - an arbitrary dict of keyword arguments that are
1966 passed to the ceilometer client
1969 ok_actions
= actions
.get('ok') if actions
is not None else None
1970 alarm_actions
= actions
.get('alarm') if actions
is not None else None
1971 insufficient_data_actions
= actions
.get('insufficient_data') if actions
is not None else None
1973 return self
.ceilo_drv
.client
.alarms
.create(
1976 statistic
=statistic
,
1977 comparison_operator
=operation
,
1978 threshold
=threshold
,
1980 evaluation_periods
=evaluations
,
1982 repeat_actions
=repeat
,
1984 ok_actions
=ok_actions
,
1985 alarm_actions
=alarm_actions
,
1986 insufficient_data_actions
=insufficient_data_actions
,
1990 def ceilo_alarm_update(self
, alarm_id
, **kwargs
):
1991 """Updates an existing alarm
1994 alarm_id - the identifier of the alarm to update
1995 kwargs - a dict of the alarm attributes to update
1998 return self
.ceilo_drv
.client
.alarms
.update(alarm_id
, **kwargs
)
2000 def ceilo_alarm_delete(self
, alarm_id
):
2001 self
.ceilo_drv
.client
.alarms
.delete(alarm_id
)