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 Exception as e
:
127 logger
.error("OpenstackDriver: Service Catalog discovery operation failed for service_type: %s, endpoint_type: %s. Exception: %s" %(service_type
, endpoint_type
, str(e
)))
129 return service_endpoint
132 def get_raw_token(self
):
134 Returns a valid raw_auth_token string
136 Returns (string): raw_auth_token string
138 ksconn
= self
._get
_keystone
_connection
()
140 raw_token
= ksconn
.get_raw_token_from_identity_service(auth_url
= self
._auth
_url
,
141 token
= self
.get_auth_token())
142 except KeystoneExceptions
.AuthorizationFailure
as e
:
143 logger
.error("OpenstackDriver: get_raw_token_from_identity_service Failure. Exception: %s" %(str(e
)))
146 except Exception as e
:
147 logger
.error("OpenstackDriver: Could not retrieve raw_token. Exception: %s" %(str(e
)))
151 def get_tenant_id(self
):
153 Returns tenant_id for the project/tenant. Tenant name is provided during
156 Returns (string): Tenant ID
158 ksconn
= self
._get
_keystone
_connection
()
159 return ksconn
.tenant_id
161 def get_security_mode(self
):
163 Returns certificate_validation policy in case of SSL/TLS connection.
164 This policy is provided during class instantiation
167 The boolean returned are designed to match the python-client class instantiation ("insecure") value.
168 for nova/neutron/glance/keystone clients
170 True: No certificate validation required -- Insecure mode
171 False: Certificate validation required -- Secure mode
173 return self
._insecure
175 def tenant_list(self
):
177 Returns list of tenants
181 def tenant_create(self
, name
):
187 def tenant_delete(self
, tenant_id
):
189 Deletes a tenant identified by tenant_id
193 def roles_list(self
):
196 def roles_create(self
):
199 def roles_delete(self
):
202 class KeystoneDriverV2(KeystoneDriver
):
204 Driver class for keystoneclient V2 APIs
206 def __init__(self
, username
, password
, auth_url
,tenant_name
, insecure
):
208 Constructor for KeystoneDriverV3 class
210 username (string) : Username
211 password (string) : Password
212 auth_url (string) : Authentication URL
213 tenant_name(string): Tenant Name
217 self
._username
= username
218 self
._password
= password
219 self
._auth
_url
= auth_url
220 self
._tenant
_name
= tenant_name
221 self
._insecure
= insecure
222 super(KeystoneDriverV2
, self
).__init
__(ksclientv2
.Client
)
224 def _get_keystone_credentials(self
):
226 Returns the dictionary of kwargs required to instantiate python-keystoneclient class
229 #creds['user_domain'] = self._domain_name
230 creds
['username'] = self
._username
231 creds
['password'] = self
._password
232 creds
['auth_url'] = self
._auth
_url
233 creds
['tenant_name'] = self
._tenant
_name
234 creds
['insecure'] = self
.get_security_mode()
237 def get_auth_token(self
):
239 Returns a valid auth_token
241 Returns (string): auth_token string
243 ksconn
= self
._get
_keystone
_connection
()
244 return ksconn
.auth_token
246 def is_auth_token_valid(self
):
248 Performs validity on auth_token
252 True/False (Boolean): (auth_token is valid or auth_token is invalid)
254 ksconn
= self
._get
_keystone
_connection
()
255 result
= super(KeystoneDriverV2
, self
).is_auth_token_valid(ksconn
.auth_ref
['token']['expires'],
256 "%Y-%m-%dT%H:%M:%SZ")
260 class KeystoneDriverV3(KeystoneDriver
):
262 Driver class for keystoneclient V3 APIs
264 def __init__(self
, username
, password
, auth_url
,tenant_name
, insecure
):
266 Constructor for KeystoneDriverV3 class
268 username (string) : Username
269 password (string) : Password
270 auth_url (string) : Authentication URL
271 tenant_name(string): Tenant Name
275 self
._username
= username
276 self
._password
= password
277 self
._auth
_url
= auth_url
278 self
._tenant
_name
= tenant_name
279 self
._insecure
= insecure
280 super(KeystoneDriverV3
, self
).__init
__(ksclientv3
.Client
)
282 def _get_keystone_credentials(self
):
284 Returns the dictionary of kwargs required to instantiate python-keystoneclient class
287 #creds['user_domain'] = self._domain_name
288 creds
['username'] = self
._username
289 creds
['password'] = self
._password
290 creds
['auth_url'] = self
._auth
_url
291 creds
['project_name'] = self
._tenant
_name
292 creds
['insecure'] = self
._insecure
295 def get_auth_token(self
):
297 Returns a valid auth_token
299 Returns (string): auth_token string
301 ksconn
= self
._get
_keystone
_connection
()
302 return ksconn
.auth_ref
['auth_token']
304 def is_auth_token_valid(self
):
306 Performs validity on auth_token
310 True/False (Boolean): (auth_token is valid or auth_token is invalid)
312 ksconn
= self
._get
_keystone
_connection
()
313 result
= super(KeystoneDriverV3
, self
).is_auth_token_valid(ksconn
.auth_ref
['expires_at'],
314 "%Y-%m-%dT%H:%M:%S.%fZ")
317 class NovaDriver(object):
319 Driver for openstack nova_client
321 def __init__(self
, ks_drv
, service_name
, version
):
323 Constructor for NovaDriver
324 Arguments: KeystoneDriver class object
327 self
._service
_name
= service_name
328 self
._version
= version
330 def _get_nova_credentials(self
):
332 Returns a dictionary of kwargs required to instantiate python-novaclient class
335 creds
['version'] = self
._version
336 creds
['bypass_url'] = self
.ks_drv
.get_service_endpoint(self
._service
_name
, "publicURL")
337 creds
['username'] = self
.ks_drv
.get_username()
338 creds
['project_id'] = self
.ks_drv
.get_tenant_name()
339 creds
['auth_token'] = self
.ks_drv
.get_auth_token()
340 creds
['insecure'] = self
.ks_drv
.get_security_mode()
343 def _get_nova_connection(self
):
345 Returns an object of class python-novaclient
347 if not hasattr(self
, '_nova_connection'):
348 self
._nova
_connection
= nova_client
.Client(**self
._get
_nova
_credentials
())
350 # Reinitialize if auth_token is no longer valid
351 if not self
.ks_drv
.is_auth_token_valid():
352 self
._nova
_connection
= nova_client
.Client(**self
._get
_nova
_credentials
())
353 return self
._nova
_connection
355 def _flavor_get(self
, flavor_id
):
357 Get flavor by flavor_id
359 flavor_id(string): UUID of flavor_id
362 dictionary of flavor parameters
364 nvconn
= self
._get
_nova
_connection
()
366 flavor
= nvconn
.flavors
.get(flavor_id
)
367 except Exception as e
:
368 logger
.info("OpenstackDriver: Did not find flavor with flavor_id : %s. Exception: %s"%(flavor_id
, str(e
)))
372 extra_specs
= flavor
.get_keys()
373 except Exception as e
:
374 logger
.info("OpenstackDriver: Could not get the EPA attributes for flavor with flavor_id : %s. Exception: %s"%(flavor_id
, str(e
)))
377 response
= flavor
.to_dict()
378 assert 'extra_specs' not in response
, "Key extra_specs present as flavor attribute"
379 response
['extra_specs'] = extra_specs
382 def flavor_get(self
, flavor_id
):
384 Get flavor by flavor_id
386 flavor_id(string): UUID of flavor_id
389 dictionary of flavor parameters
391 return self
._flavor
_get
(flavor_id
)
393 def flavor_list(self
):
395 Returns list of all flavors (dictionary per flavor)
400 A list of dictionaries. Each dictionary contains attributes for a single flavor instance
404 nvconn
= self
._get
_nova
_connection
()
406 flavors
= nvconn
.flavors
.list()
407 except Exception as e
:
408 logger
.error("OpenstackDriver: List Flavor operation failed. Exception: %s"%(str(e
)))
411 flavor_info
= [ self
.flavor_get(flv
.id) for flv
in flavors
]
414 def flavor_create(self
, name
, ram
, vcpu
, disk
, extra_specs
):
419 name (string): Name of the new flavor
420 ram (int) : Memory in MB
421 vcpus (int) : Number of VCPUs
422 disk (int) : Secondary storage size in GB
423 extra_specs (dictionary): EPA attributes dictionary
426 flavor_id (string): UUID of flavor created
428 nvconn
= self
._get
_nova
_connection
()
430 flavor
= nvconn
.flavors
.create(name
= name
,
439 except Exception as e
:
440 logger
.error("OpenstackDriver: Create Flavor operation failed. Exception: %s"%(str(e
)))
445 flavor
.set_keys(extra_specs
)
446 except Exception as e
:
447 logger
.error("OpenstackDriver: Set Key operation failed for flavor: %s. Exception: %s" %(flavor
.id, str(e
)))
451 def flavor_delete(self
, flavor_id
):
453 Deletes a flavor identified by flavor_id
456 flavor_id (string): UUID of flavor to be deleted
460 assert flavor_id
== self
._flavor
_get
(flavor_id
)['id']
461 nvconn
= self
._get
_nova
_connection
()
463 nvconn
.flavors
.delete(flavor_id
)
464 except Exception as e
:
465 logger
.error("OpenstackDriver: Delete flavor operation failed for flavor: %s. Exception: %s" %(flavor_id
, str(e
)))
469 def server_list(self
):
471 Returns a list of available VMs for the project
476 A list of dictionaries. Each dictionary contains attributes associated
481 nvconn
= self
._get
_nova
_connection
()
483 servers
= nvconn
.servers
.list()
484 except Exception as e
:
485 logger
.error("OpenstackDriver: List Server operation failed. Exception: %s" %(str(e
)))
487 server_info
= [ server
.to_dict() for server
in servers
]
490 def _nova_server_get(self
, server_id
):
492 Returns a dictionary of attributes associated with VM identified by service_id
495 server_id (string): UUID of the VM/server for which information is requested
498 A dictionary object with attributes associated with VM identified by server_id
500 nvconn
= self
._get
_nova
_connection
()
502 server
= nvconn
.servers
.get(server
= server_id
)
503 except Exception as e
:
504 logger
.info("OpenstackDriver: Get Server operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
507 return server
.to_dict()
509 def server_get(self
, server_id
):
511 Returns a dictionary of attributes associated with VM identified by service_id
514 server_id (string): UUID of the VM/server for which information is requested
517 A dictionary object with attributes associated with VM identified by server_id
519 return self
._nova
_server
_get
(server_id
)
521 def server_create(self
, **kwargs
):
523 Creates a new VM/server instance
526 A dictionary of following key-value pairs
528 server_name(string) : Name of the VM/Server
529 flavor_id (string) : UUID of the flavor to be used for VM
530 image_id (string) : UUID of the image to be used VM/Server instance
531 network_list(List) : A List of network_ids. A port will be created in these networks
532 port_list (List) : A List of port-ids. These ports will be added to VM.
533 metadata (dict) : A dictionary of arbitrary key-value pairs associated with VM/server
534 userdata (string) : A script which shall be executed during first boot of the VM
535 availability_zone (string) : A name of the availability zone where instance should be launched
536 scheduler_hints (string) : Openstack scheduler_hints to be passed to nova scheduler
539 server_id (string): UUID of the VM/server created
543 if 'network_list' in kwargs
:
544 for network_id
in kwargs
['network_list']:
545 nics
.append({'net-id': network_id
})
547 if 'port_list' in kwargs
:
548 for port_id
in kwargs
['port_list']:
549 nics
.append({'port-id': port_id
})
551 nvconn
= self
._get
_nova
_connection
()
554 server
= nvconn
.servers
.create(kwargs
['name'],
557 meta
= kwargs
['metadata'],
559 reservation_id
= None,
562 userdata
= kwargs
['userdata'],
563 security_groups
= kwargs
['security_groups'],
564 availability_zone
= kwargs
['availability_zone'],
565 block_device_mapping
= None,
567 scheduler_hints
= kwargs
['scheduler_hints'],
569 except Exception as e
:
570 logger
.info("OpenstackDriver: Create Server operation failed. Exception: %s" %(str(e
)))
572 return server
.to_dict()['id']
574 def server_delete(self
, server_id
):
576 Deletes a server identified by server_id
579 server_id (string): UUID of the server to be deleted
583 nvconn
= self
._get
_nova
_connection
()
585 nvconn
.servers
.delete(server_id
)
586 except Exception as e
:
587 logger
.error("OpenstackDriver: Delete server operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
590 def server_start(self
, server_id
):
592 Starts a server identified by server_id
595 server_id (string): UUID of the server to be started
599 nvconn
= self
._get
_nova
_connection
()
601 nvconn
.servers
.start(server_id
)
602 except Exception as e
:
603 logger
.error("OpenstackDriver: Start Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
606 def server_stop(self
, server_id
):
609 server_id (string): UUID of the server to be stopped
613 nvconn
= self
._get
_nova
_connection
()
615 nvconn
.servers
.stop(server_id
)
616 except Exception as e
:
617 logger
.error("OpenstackDriver: Stop Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
620 def server_pause(self
, server_id
):
623 server_id (string): UUID of the server to be paused
627 nvconn
= self
._get
_nova
_connection
()
629 nvconn
.servers
.pause(server_id
)
630 except Exception as e
:
631 logger
.error("OpenstackDriver: Pause Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
634 def server_unpause(self
, server_id
):
637 server_id (string): UUID of the server to be unpaused
641 nvconn
= self
._get
_nova
_connection
()
643 nvconn
.servers
.unpause(server_id
)
644 except Exception as e
:
645 logger
.error("OpenstackDriver: Resume Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
649 def server_suspend(self
, server_id
):
652 server_id (string): UUID of the server to be suspended
656 nvconn
= self
._get
_nova
_connection
()
658 nvconn
.servers
.suspend(server_id
)
659 except Exception as e
:
660 logger
.error("OpenstackDriver: Suspend Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
663 def server_resume(self
, server_id
):
666 server_id (string): UUID of the server to be resumed
670 nvconn
= self
._get
_nova
_connection
()
672 nvconn
.servers
.resume(server_id
)
673 except Exception as e
:
674 logger
.error("OpenstackDriver: Resume Server operation failed for server_id : %s. Exception: %s" %(server_id
, str(e
)))
677 def server_reboot(self
, server_id
, reboot_type
):
680 server_id (string) : UUID of the server to be rebooted
686 nvconn
= self
._get
_nova
_connection
()
688 nvconn
.servers
.reboot(server_id
, reboot_type
)
689 except Exception as e
:
690 logger
.error("OpenstackDriver: Reboot Server operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
693 def server_console(self
, server_id
, console_type
= 'novnc'):
696 server_id (string) : UUID of the server to be rebooted
697 console_type(string):
701 A dictionary object response for console information
703 nvconn
= self
._get
_nova
_connection
()
705 console_info
= nvconn
.servers
.get_vnc_console(server_id
, console_type
)
706 except Exception as e
:
707 logger
.error("OpenstackDriver: Server Get-Console operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
711 def server_rebuild(self
, server_id
, image_id
):
714 server_id (string) : UUID of the server to be rebooted
715 image_id (string) : UUID of the image to use
719 nvconn
= self
._get
_nova
_connection
()
721 nvconn
.servers
.rebuild(server_id
, image_id
)
722 except Exception as e
:
723 logger
.error("OpenstackDriver: Rebuild Server operation failed for server_id: %s. Exception: %s" %(server_id
, str(e
)))
727 def server_add_port(self
, server_id
, port_id
):
730 server_id (string): UUID of the server
731 port_id (string): UUID of the port to be attached
735 nvconn
= self
._get
_nova
_connection
()
737 nvconn
.servers
.interface_attach(server_id
,
741 except Exception as e
:
742 logger
.error("OpenstackDriver: Server Port Add operation failed for server_id : %s, port_id : %s. Exception: %s" %(server_id
, port_id
, str(e
)))
745 def server_delete_port(self
, server_id
, port_id
):
748 server_id (string): UUID of the server
749 port_id (string): UUID of the port to be deleted
753 nvconn
= self
._get
_nova
_connection
()
755 nvconn
.servers
.interface_detach(server_id
, port_id
)
756 except Exception as e
:
757 logger
.error("OpenstackDriver: Server Port Delete operation failed for server_id : %s, port_id : %s. Exception: %s" %(server_id
, port_id
, str(e
)))
760 def floating_ip_list(self
):
765 List of objects of floating IP nova class (novaclient.v2.floating_ips.FloatingIP)
767 nvconn
= self
._get
_nova
_connection
()
769 ip_list
= nvconn
.floating_ips
.list()
770 except Exception as e
:
771 logger
.error("OpenstackDriver: Floating IP List operation failed. Exception: %s" %str
(e
))
776 def floating_ip_create(self
, pool
):
779 pool (string): Name of the pool (optional)
781 An object of floating IP nova class (novaclient.v2.floating_ips.FloatingIP)
783 nvconn
= self
._get
_nova
_connection
()
785 floating_ip
= nvconn
.floating_ips
.create(pool
)
786 except Exception as e
:
787 logger
.error("OpenstackDriver: Floating IP Create operation failed. Exception: %s" %str
(e
))
792 def floating_ip_delete(self
, floating_ip
):
795 floating_ip: An object of floating IP nova class (novaclient.v2.floating_ips.FloatingIP)
799 nvconn
= self
._get
_nova
_connection
()
801 floating_ip
= nvconn
.floating_ips
.delete(floating_ip
)
802 except Exception as e
:
803 logger
.error("OpenstackDriver: Floating IP Delete operation failed. Exception: %s" %str
(e
))
806 def floating_ip_assign(self
, server_id
, floating_ip
, fixed_ip
):
809 server_id (string) : UUID of the server
810 floating_ip (string): IP address string for floating-ip
811 fixed_ip (string) : IP address string for the fixed-ip with which floating ip will be associated
815 nvconn
= self
._get
_nova
_connection
()
817 nvconn
.servers
.add_floating_ip(server_id
, floating_ip
, fixed_ip
)
818 except Exception as e
:
819 logger
.error("OpenstackDriver: Assign Floating IP operation failed. Exception: %s" %str
(e
))
822 def floating_ip_release(self
, server_id
, floating_ip
):
825 server_id (string) : UUID of the server
826 floating_ip (string): IP address string for floating-ip
830 nvconn
= self
._get
_nova
_connection
()
832 nvconn
.servers
.remove_floating_ip(server_id
, floating_ip
)
833 except Exception as e
:
834 logger
.error("OpenstackDriver: Release Floating IP operation failed. Exception: %s" %str
(e
))
837 def group_list(self
):
839 List of Server Affinity and Anti-Affinity Groups
844 List of dictionary objects where dictionary is representation of class (novaclient.v2.server_groups.ServerGroup)
846 nvconn
= self
._get
_nova
_connection
()
848 group_list
= nvconn
.server_groups
.list()
849 except Exception as e
:
850 logger
.error("OpenstackDriver: Server Group List operation failed. Exception: %s" %str
(e
))
853 group_info
= [ group
.to_dict() for group
in group_list
]
858 class NovaDriverV2(NovaDriver
):
860 Driver class for novaclient V2 APIs
862 def __init__(self
, ks_drv
):
864 Constructor for NovaDriver
865 Arguments: KeystoneDriver class object
867 super(NovaDriverV2
, self
).__init
__(ks_drv
, 'compute', '2.0')
869 class NovaDriverV21(NovaDriver
):
871 Driver class for novaclient V2 APIs
873 def __init__(self
, ks_drv
):
875 Constructor for NovaDriver
876 Arguments: KeystoneDriver class object
878 super(NovaDriverV21
, self
).__init
__(ks_drv
, 'computev21', '2.1')
880 class GlanceDriver(object):
882 Driver for openstack glance-client
884 def __init__(self
, ks_drv
, service_name
, version
):
886 Constructor for GlanceDriver
887 Arguments: KeystoneDriver class object
890 self
._service
_name
= service_name
891 self
._version
= version
893 def _get_glance_credentials(self
):
895 Returns a dictionary of kwargs required to instantiate python-glanceclient class
900 A dictionary object of arguments
903 creds
['version'] = self
._version
904 creds
['endpoint'] = self
.ks_drv
.get_service_endpoint(self
._service
_name
, 'publicURL')
905 creds
['token'] = self
.ks_drv
.get_auth_token()
906 creds
['insecure'] = self
.ks_drv
.get_security_mode()
909 def _get_glance_connection(self
):
911 Returns a object of class python-glanceclient
913 if not hasattr(self
, '_glance_connection'):
914 self
._glance
_connection
= glclient
.Client(**self
._get
_glance
_credentials
())
916 # Reinitialize if auth_token is no longer valid
917 if not self
.ks_drv
.is_auth_token_valid():
918 self
._glance
_connection
= glclient
.Client(**self
._get
_glance
_credentials
())
919 return self
._glance
_connection
921 def image_list(self
):
923 Returns list of dictionaries. Each dictionary contains attributes associated with
928 Returns: List of dictionaries.
930 glconn
= self
._get
_glance
_connection
()
933 image_info
= glconn
.images
.list()
934 except Exception as e
:
935 logger
.error("OpenstackDriver: List Image operation failed. Exception: %s" %(str(e
)))
937 images
= [ img
for img
in image_info
]
940 def image_create(self
, **kwargs
):
944 A dictionary of kwargs with following keys
946 'name'(string) : Name of the image
947 'location'(string) : URL (http://....) where image is located
948 'disk_format'(string) : Disk format
949 Possible values are 'ami', 'ari', 'aki', 'vhd', 'vmdk', 'raw', 'qcow2', 'vdi', 'iso'
950 'container_format'(string): Container format
951 Possible values are 'ami', 'ari', 'aki', 'bare', 'ovf'
952 'tags' : A list of user tags
953 'checksum' : The image md5 checksum
956 image_id (string) : UUID of the image
959 glconn
= self
._get
_glance
_connection
()
961 image
= glconn
.images
.create(**kwargs
)
962 except Exception as e
:
963 logger
.error("OpenstackDriver: Create Image operation failed. Exception: %s" %(str(e
)))
968 def image_upload(self
, image_id
, fd
):
973 image_id: UUID of the image
974 fd : File descriptor for the image file
977 glconn
= self
._get
_glance
_connection
()
979 glconn
.images
.upload(image_id
, fd
)
980 except Exception as e
:
981 logger
.error("OpenstackDriver: Image upload operation failed. Exception: %s" %(str(e
)))
984 def image_add_location(self
, image_id
, location
, metadata
):
986 Add image URL location
989 image_id : UUID of the image
990 location : http URL for the image
994 glconn
= self
._get
_glance
_connection
()
996 image
= glconn
.images
.add_location(image_id
, location
, metadata
)
997 except Exception as e
:
998 logger
.error("OpenstackDriver: Image location add operation failed. Exception: %s" %(str(e
)))
1001 def image_update(self
):
1004 def image_delete(self
, image_id
):
1009 image_id: UUID of the image
1014 assert image_id
== self
._image
_get
(image_id
)['id']
1015 glconn
= self
._get
_glance
_connection
()
1017 glconn
.images
.delete(image_id
)
1018 except Exception as e
:
1019 logger
.error("OpenstackDriver: Delete Image operation failed for image_id : %s. Exception: %s" %(image_id
, str(e
)))
1023 def _image_get(self
, image_id
):
1025 Returns a dictionary object of VM image attributes
1028 image_id (string): UUID of the image
1031 A dictionary of the image attributes
1033 glconn
= self
._get
_glance
_connection
()
1035 image
= glconn
.images
.get(image_id
)
1036 except GlanceException
.HTTPBadRequest
:
1037 # RIFT-14241: The get image request occasionally returns the below message. Retry in case of bad request exception.
1038 # Error code 400.: Message: Bad request syntax ('0').: Error code explanation: 400 = Bad request syntax or unsupported method. (HTTP 400)
1039 logger
.warning("OpenstackDriver: Got bad request response during get_image request. Retrying.")
1040 image
= glconn
.images
.get(image_id
)
1041 except Exception as e
:
1042 logger
.error("OpenstackDriver: Get 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 return self
._image
_get
(image_id
)
1059 class GlanceDriverV2(GlanceDriver
):
1061 Driver for openstack glance-client V2
1063 def __init__(self
, ks_drv
):
1064 super(GlanceDriverV2
, self
).__init
__(ks_drv
, 'image', 2)
1066 class NeutronDriver(object):
1068 Driver for openstack neutron neutron-client
1070 def __init__(self
, ks_drv
, service_name
, version
):
1072 Constructor for NeutronDriver
1073 Arguments: KeystoneDriver class object
1075 self
.ks_drv
= ks_drv
1076 self
._service
_name
= service_name
1077 self
._version
= version
1079 def _get_neutron_credentials(self
):
1081 Returns a dictionary of kwargs required to instantiate python-neutronclient class
1084 Dictionary of kwargs
1087 creds
['api_version'] = self
._version
1088 creds
['endpoint_url'] = self
.ks_drv
.get_service_endpoint(self
._service
_name
, 'publicURL')
1089 creds
['token'] = self
.ks_drv
.get_auth_token()
1090 creds
['tenant_name'] = self
.ks_drv
.get_tenant_name()
1091 creds
['insecure'] = self
.ks_drv
.get_security_mode()
1094 def _get_neutron_connection(self
):
1096 Returns an object of class python-neutronclient
1098 if not hasattr(self
, '_neutron_connection'):
1099 self
._neutron
_connection
= ntclient
.Client(**self
._get
_neutron
_credentials
())
1101 # Reinitialize if auth_token is no longer valid
1102 if not self
.ks_drv
.is_auth_token_valid():
1103 self
._neutron
_connection
= ntclient
.Client(**self
._get
_neutron
_credentials
())
1104 return self
._neutron
_connection
1106 def network_list(self
):
1108 Returns list of dictionaries. Each dictionary contains the attributes for a network
1114 A list of dictionaries
1117 ntconn
= self
._get
_neutron
_connection
()
1119 networks
= ntconn
.list_networks()
1120 except Exception as e
:
1121 logger
.error("OpenstackDriver: List Network operation failed. Exception: %s" %(str(e
)))
1123 return networks
['networks']
1125 def network_create(self
, **kwargs
):
1127 Creates a new network for the project
1130 A dictionary with following key-values
1132 name (string) : Name of the network
1133 admin_state_up(Boolean) : True/False (Defaults: True)
1134 external_router(Boolean) : Connectivity with external router. True/False (Defaults: False)
1135 shared(Boolean) : Shared among tenants. True/False (Defaults: False)
1136 physical_network(string) : The physical network where this network object is implemented (optional).
1137 network_type : The type of physical network that maps to this network resource (optional).
1138 Possible values are: 'flat', 'vlan', 'vxlan', 'gre'
1139 segmentation_id : An isolated segment on the physical network. The network_type attribute
1140 defines the segmentation model. For example, if the network_type value
1141 is vlan, this ID is a vlan identifier. If the network_type value is gre,
1142 this ID is a gre key.
1145 params
= {'network':
1146 {'name' : kwargs
['name'],
1147 'admin_state_up' : kwargs
['admin_state_up'],
1148 'tenant_id' : self
.ks_drv
.get_tenant_id(),
1149 'shared' : kwargs
['shared'],
1150 #'port_security_enabled': port_security_enabled,
1151 'router:external' : kwargs
['external_router']}}
1153 if 'physical_network' in kwargs
:
1154 params
['network']['provider:physical_network'] = kwargs
['physical_network']
1155 if 'network_type' in kwargs
:
1156 params
['network']['provider:network_type'] = kwargs
['network_type']
1157 if 'segmentation_id' in kwargs
:
1158 params
['network']['provider:segmentation_id'] = kwargs
['segmentation_id']
1160 ntconn
= self
._get
_neutron
_connection
()
1162 logger
.debug("Calling neutron create_network() with params: %s", str(params
))
1163 net
= ntconn
.create_network(params
)
1164 except Exception as e
:
1165 logger
.error("OpenstackDriver: Create Network operation failed. Exception: %s" %(str(e
)))
1167 logger
.debug("Got create_network response from neutron connection: %s", str(net
))
1168 network_id
= net
['network']['id']
1170 raise Exception("Empty network id returned from create_network. (params: %s)" % str(params
))
1174 def network_delete(self
, network_id
):
1176 Deletes a network identified by network_id
1179 network_id (string): UUID of the network
1183 assert network_id
== self
._network
_get
(network_id
)['id']
1184 ntconn
= self
._get
_neutron
_connection
()
1186 ntconn
.delete_network(network_id
)
1187 except Exception as e
:
1188 logger
.error("OpenstackDriver: Delete Network operation failed. Exception: %s" %(str(e
)))
1191 def _network_get(self
, network_id
):
1193 Returns a dictionary object describing the attributes of the network
1196 network_id (string): UUID of the network
1199 A dictionary object of the network attributes
1201 ntconn
= self
._get
_neutron
_connection
()
1202 network
= ntconn
.list_networks(id = network_id
)['networks']
1204 raise NeutronException
.NotFound("Network with id %s not found"%(network_id))
1208 def network_get(self
, network_id
):
1210 Returns a dictionary object describing the attributes of the network
1213 network_id (string): UUID of the network
1216 A dictionary object of the network attributes
1218 return self
._network
_get
(network_id
)
1220 def subnet_create(self
, **kwargs
):
1222 Creates a subnet on the network
1225 A dictionary with following key value pairs
1227 network_id(string) : UUID of the network where subnet needs to be created
1228 subnet_cidr(string) : IPv4 address prefix (e.g. '1.1.1.0/24') for the subnet
1229 ip_version (integer): 4 for IPv4 and 6 for IPv6
1234 subnet_id (string): UUID of the created subnet
1237 params
['network_id'] = kwargs
['network_id']
1238 params
['ip_version'] = kwargs
['ip_version']
1240 # if params['ip_version'] == 6:
1241 # assert 0, "IPv6 is not supported"
1243 if 'subnetpool_id' in kwargs
:
1244 params
['subnetpool_id'] = kwargs
['subnetpool_id']
1246 params
['cidr'] = kwargs
['cidr']
1248 if 'gateway_ip' in kwargs
:
1249 params
['gateway_ip'] = kwargs
['gateway_ip']
1251 params
['gateway_ip'] = None
1253 if 'dhcp_params' in kwargs
:
1254 params
['enable_dhcp'] = kwargs
['dhcp_params']['enable_dhcp']
1255 if 'start_address' in kwargs
['dhcp_params'] and 'count' in kwargs
['dhcp_params']:
1256 end_address
= (ipaddress
.IPv4Address(kwargs
['dhcp_params']['start_address']) + kwargs
['dhcp_params']['count']).compressed
1257 params
['allocation_pools'] = [ {'start': kwargs
['dhcp_params']['start_address'] ,
1258 'end' : end_address
} ]
1260 if 'dns_server' in kwargs
:
1261 params
['dns_nameservers'] = []
1262 for server
in kwargs
['dns_server']:
1263 params
['dns_nameservers'].append(server
)
1265 ntconn
= self
._get
_neutron
_connection
()
1267 subnet
= ntconn
.create_subnet({'subnets': [params
]})
1268 except Exception as e
:
1269 logger
.error("OpenstackDriver: Create Subnet operation failed. Exception: %s" %(str(e
)))
1272 return subnet
['subnets'][0]['id']
1274 def subnet_list(self
):
1276 Returns a list of dictionaries. Each dictionary contains attributes describing the subnet
1281 A dictionary of the objects of subnet attributes
1283 ntconn
= self
._get
_neutron
_connection
()
1285 subnets
= ntconn
.list_subnets()['subnets']
1286 except Exception as e
:
1287 logger
.error("OpenstackDriver: List Subnet operation failed. Exception: %s" %(str(e
)))
1291 def _subnet_get(self
, subnet_id
):
1293 Returns a dictionary object describing the attributes of a subnet.
1296 subnet_id (string): UUID of the subnet
1299 A dictionary object of the subnet attributes
1301 ntconn
= self
._get
_neutron
_connection
()
1302 subnets
= ntconn
.list_subnets(id=subnet_id
)
1303 if not subnets
['subnets']:
1304 logger
.error("OpenstackDriver: Get subnet operation failed for subnet_id: %s" %(subnet_id))
1305 #raise NeutronException.NotFound("Could not find subnet_id %s" %(subnet_id))
1308 return subnets
['subnets'][0]
1310 def subnet_get(self
, subnet_id
):
1312 Returns a dictionary object describing the attributes of a subnet.
1315 subnet_id (string): UUID of the subnet
1318 A dictionary object of the subnet attributes
1320 return self
._subnet
_get
(subnet_id
)
1322 def subnet_delete(self
, subnet_id
):
1324 Deletes a subnet identified by subnet_id
1327 subnet_id (string): UUID of the subnet to be deleted
1331 ntconn
= self
._get
_neutron
_connection
()
1332 assert subnet_id
== self
._subnet
_get
(self
,subnet_id
)
1334 ntconn
.delete_subnet(subnet_id
)
1335 except Exception as e
:
1336 logger
.error("OpenstackDriver: Delete Subnet operation failed for subnet_id : %s. Exception: %s" %(subnet_id
, str(e
)))
1339 def port_list(self
, **kwargs
):
1341 Returns a list of dictionaries. Each dictionary contains attributes describing the port
1344 kwargs (dictionary): A dictionary for filters for port_list operation
1347 A dictionary of the objects of port attributes
1351 ntconn
= self
._get
_neutron
_connection
()
1353 kwargs
['tenant_id'] = self
.ks_drv
.get_tenant_id()
1356 ports
= ntconn
.list_ports(**kwargs
)
1357 except Exception as e
:
1358 logger
.info("OpenstackDriver: List Port operation failed. Exception: %s" %(str(e
)))
1360 return ports
['ports']
1362 def port_create(self
, **kwargs
):
1364 Create a port in network
1367 A dictionary of following
1369 name (string) : Name of the port
1370 network_id(string) : UUID of the network_id identifying the network to which port belongs
1371 subnet_id(string) : UUID of the subnet_id from which IP-address will be assigned to port
1372 vnic_type(string) : Possible values are "normal", "direct", "macvtap"
1375 port_id (string) : UUID of the port
1379 "admin_state_up" : kwargs
['admin_state_up'],
1380 "name" : kwargs
['name'],
1381 "network_id" : kwargs
['network_id'],
1382 "fixed_ips" : [ {"subnet_id": kwargs
['subnet_id']}],
1383 "binding:vnic_type" : kwargs
['port_type']}}
1385 ntconn
= self
._get
_neutron
_connection
()
1387 port
= ntconn
.create_port(params
)
1388 except Exception as e
:
1389 logger
.error("OpenstackDriver: Port Create operation failed. Exception: %s" %(str(e
)))
1391 return port
['port']['id']
1393 def _port_get(self
, port_id
):
1395 Returns a dictionary object describing the attributes of the port
1398 port_id (string): UUID of the port
1401 A dictionary object of the port attributes
1403 ntconn
= self
._get
_neutron
_connection
()
1404 port
= ntconn
.list_ports(id=port_id
)['ports']
1406 raise NeutronException
.NotFound("Could not find port_id %s" %(port_id))
1409 def port_get(self
, port_id
):
1411 Returns a dictionary object describing the attributes of the port
1414 port_id (string): UUID of the port
1417 A dictionary object of the port attributes
1419 return self
._port
_get
(port_id
)
1421 def port_delete(self
, port_id
):
1423 Deletes a port identified by port_id
1426 port_id (string) : UUID of the port
1430 assert port_id
== self
._port
_get
(port_id
)['id']
1431 ntconn
= self
._get
_neutron
_connection
()
1433 ntconn
.delete_port(port_id
)
1434 except Exception as e
:
1435 logger
.error("Port Delete operation failed for port_id : %s. Exception: %s" %(port_id
, str(e
)))
1438 def security_group_list(self
):
1440 Returns a list of dictionaries. Each dictionary contains attributes describing the security group
1446 A dictionary of the objects of security group attributes
1448 ntconn
= self
._get
_neutron
_connection
()
1450 group_list
= ntconn
.list_security_groups(tenant_id
=self
.ks_drv
.get_tenant_id())
1451 except Exception as e
:
1452 logger
.error("List Security group operation, Exception: %s" %(str(e
)))
1455 if 'security_groups' in group_list
:
1456 return group_list
['security_groups']
1460 def subnetpool_list(self
, **kwargs
):
1462 Returns a list of dictionaries. Each dictionary contains attributes describing a subnet prefix pool
1468 A dictionary of the objects of subnet prefix pool
1470 ntconn
= self
._get
_neutron
_connection
()
1472 pool_list
= ntconn
.list_subnetpools(**kwargs
)
1473 except Exception as e
:
1474 logger
.error("List SubnetPool operation, Exception: %s" %(str(e
)))
1477 if 'subnetpools' in pool_list
:
1478 return pool_list
['subnetpools']
1482 class NeutronDriverV2(NeutronDriver
):
1484 Driver for openstack neutron neutron-client v2
1486 def __init__(self
, ks_drv
):
1488 Constructor for NeutronDriver
1489 Arguments: KeystoneDriver class object
1491 super(NeutronDriverV2
, self
).__init
__(ks_drv
, 'network', '2.0')
1495 class CeilometerDriver(object):
1497 Driver for openstack ceilometer client
1500 def __init__(self
, ks_drv
, service_name
, version
):
1502 Constructor for CeilometerDriver
1503 Arguments: KeystoneDriver class object
1505 self
.ks_drv
= ks_drv
1506 self
._service
_name
= service_name
1507 self
._version
= version
1512 """The version of the ceilometer client used by the driver"""
1513 return self
._version
1517 """The instance of ceilometer client used by the driver"""
1518 if self
._client
is None or not self
.ks_drv
.is_auth_token_valid():
1519 self
._client
= ceilo_client
.Client(**self
.credentials
)
1524 def auth_token(self
):
1525 """The authorization token for the ceilometer client"""
1527 return self
.ks_drv
.get_auth_token()
1528 except KeystoneExceptions
.EndpointNotFound
as e
:
1529 logger
.error("OpenstackDriver: unable to get authorization token for ceilometer. Exception: %s" %(str(e
)))
1533 def security_mode(self
):
1534 """The security mode for the ceilometer client"""
1536 return self
.ks_drv
.get_security_mode()
1537 except KeystoneExceptions
.EndpointNotFound
as e
:
1538 logger
.error("OpenstackDriver: unable to get security mode for ceilometer. Exception: %s" %(str(e
)))
1543 """The service endpoint for the ceilometer client"""
1545 return self
.ks_drv
.get_service_endpoint(self
._service
_name
, "publicURL")
1546 except KeystoneExceptions
.EndpointNotFound
as e
:
1547 logger
.error("OpenstackDriver: unable to get endpoint for ceilometer. Exception: %s" %(str(e
)))
1551 def credentials(self
):
1552 """A dictionary of credentials for the ceilometer client"""
1554 version
=self
.version
,
1555 endpoint
=self
.endpoint
,
1556 token
=self
.auth_token
,
1557 insecure
=self
.security_mode
,
1562 """A list of the available meters"""
1564 return self
.client
.meters
.list()
1565 except Exception as e
:
1566 logger
.error("OpenstackDriver: List meters operation failed. Exception: %s" %(str(e
)))
1571 """The ceilometer client alarms manager"""
1572 return self
.client
.alarms
1574 def query_samples(self
, vim_instance_id
, counter_name
, limit
=1):
1575 """Returns a list of samples
1578 vim_instance_id - the ID of the VIM that the samples are from
1579 counter_name - the counter that the samples will come from
1580 limit - a limit on the number of samples to return
1588 filter = json
.dumps({
1590 {"=": {"resource": vim_instance_id
}},
1591 {"=": {"counter_name": counter_name
}}
1594 result
= self
.client
.query_samples
.query(filter=filter, limit
=limit
)
1595 return result
[-limit
:]
1597 except Exception as e
:
1603 class CeilometerDriverV2(CeilometerDriver
):
1605 Driver for openstack ceilometer ceilometer-client
1607 def __init__(self
, ks_drv
):
1609 Constructor for CeilometerDriver
1610 Arguments: CeilometerDriver class object
1612 super(CeilometerDriverV2
, self
).__init
__(ks_drv
, 'metering', '2')
1614 class OpenstackDriver(object):
1616 Driver for openstack nova, neutron, glance, keystone, swift, cinder services
1618 def __init__(self
, username
, password
, auth_url
, tenant_name
, mgmt_network
= None, cert_validate
= False):
1620 OpenstackDriver Driver constructor
1622 username (string) : Username for project/tenant.
1623 password (string) : Password
1624 auth_url (string) : Keystone Authentication URL.
1625 tenant_name (string) : Openstack project name
1626 mgmt_network(string, optional) : Management network name. Each VM created with this cloud-account will
1627 have a default interface into management network.
1628 cert_validate (boolean, optional) : In case of SSL/TLS connection if certificate validation is required or not.
1631 insecure
= not cert_validate
1632 if auth_url
.find('/v3') != -1:
1633 self
.ks_drv
= KeystoneDriverV3(username
, password
, auth_url
, tenant_name
, insecure
)
1634 self
.glance_drv
= GlanceDriverV2(self
.ks_drv
)
1635 self
.nova_drv
= NovaDriverV21(self
.ks_drv
)
1636 self
.neutron_drv
= NeutronDriverV2(self
.ks_drv
)
1637 self
.ceilo_drv
= CeilometerDriverV2(self
.ks_drv
)
1638 elif auth_url
.find('/v2') != -1:
1639 self
.ks_drv
= KeystoneDriverV2(username
, password
, auth_url
, tenant_name
, insecure
)
1640 self
.glance_drv
= GlanceDriverV2(self
.ks_drv
)
1641 self
.nova_drv
= NovaDriverV2(self
.ks_drv
)
1642 self
.neutron_drv
= NeutronDriverV2(self
.ks_drv
)
1643 self
.ceilo_drv
= CeilometerDriverV2(self
.ks_drv
)
1645 logger
.error("Could not identity the version information for openstack service endpoints. Auth_URL should contain \"/v2\" or \"/v3\" string in it")
1646 raise NotImplementedError("Auth URL is wrong or invalid. Only Keystone v2 & v3 supported")
1648 if mgmt_network
!= None:
1649 self
._mgmt
_network
= mgmt_network
1653 ntconn
= self
.neutron_drv
._get
_neutron
_connection
()
1654 networks
= ntconn
.list_networks()
1655 except Exception as e
:
1656 logger
.error("OpenstackDriver: List Network operation failed. Exception: %s" %(str(e
)))
1659 network_list
= [ network
for network
in networks
['networks'] if network
['name'] == mgmt_network
]
1661 if not network_list
:
1662 raise NeutronException
.NotFound("Could not find network %s" %(mgmt_network))
1663 self
._mgmt
_network
_id
= network_list
[0]['id']
1665 def validate_account_creds(self
):
1667 ksconn
= self
.ks_drv
._get
_keystone
_connection
()
1668 except KeystoneExceptions
.AuthorizationFailure
as e
:
1669 logger
.error("OpenstackDriver: Unable to authenticate or validate the existing credentials. Exception: %s" %(str(e
)))
1670 raise ValidationError("Invalid Credentials: "+ str(e
))
1671 except Exception as e
:
1672 logger
.error("OpenstackDriver: Could not connect to Openstack. Exception: %s" %(str(e
)))
1673 raise ValidationError("Connection Error: "+ str(e
))
1675 def get_mgmt_network_id(self
):
1676 return self
._mgmt
_network
_id
1678 def glance_image_create(self
, **kwargs
):
1679 if not 'disk_format' in kwargs
:
1680 kwargs
['disk_format'] = 'qcow2'
1681 if not 'container_format' in kwargs
:
1682 kwargs
['container_format'] = 'bare'
1683 if not 'min_disk' in kwargs
:
1684 kwargs
['min_disk'] = 0
1685 if not 'min_ram' in kwargs
:
1686 kwargs
['min_ram'] = 0
1687 return self
.glance_drv
.image_create(**kwargs
)
1689 def glance_image_upload(self
, image_id
, fd
):
1690 self
.glance_drv
.image_upload(image_id
, fd
)
1692 def glance_image_add_location(self
, image_id
, location
):
1693 self
.glance_drv
.image_add_location(image_id
, location
)
1695 def glance_image_delete(self
, image_id
):
1696 self
.glance_drv
.image_delete(image_id
)
1698 def glance_image_list(self
):
1699 return self
.glance_drv
.image_list()
1701 def glance_image_get(self
, image_id
):
1702 return self
.glance_drv
.image_get(image_id
)
1705 def nova_flavor_list(self
):
1706 return self
.nova_drv
.flavor_list()
1708 def nova_flavor_create(self
, name
, ram
, vcpus
, disk
, epa_specs
):
1709 extra_specs
= epa_specs
if epa_specs
else {}
1710 return self
.nova_drv
.flavor_create(name
,
1714 extra_specs
= extra_specs
)
1716 def nova_flavor_delete(self
, flavor_id
):
1717 self
.nova_drv
.flavor_delete(flavor_id
)
1719 def nova_flavor_get(self
, flavor_id
):
1720 return self
.nova_drv
.flavor_get(flavor_id
)
1722 def nova_server_create(self
, **kwargs
):
1723 assert kwargs
['flavor_id'] == self
.nova_drv
.flavor_get(kwargs
['flavor_id'])['id']
1724 image
= self
.glance_drv
.image_get(kwargs
['image_id'])
1725 if image
['status'] != 'active':
1726 raise GlanceException
.NotFound("Image with image_id: %s not found in active state. Current State: %s" %(image
['id'], image
['status']))
1728 # if 'network_list' in kwargs:
1729 # kwargs['network_list'].append(self._mgmt_network_id)
1731 # kwargs['network_list'] = [self._mgmt_network_id]
1733 if 'security_groups' not in kwargs
:
1734 nvconn
= self
.nova_drv
._get
_nova
_connection
()
1735 sec_groups
= nvconn
.security_groups
.list()
1737 ## Should we add VM in all availability security_groups ???
1738 kwargs
['security_groups'] = [x
.name
for x
in sec_groups
]
1740 kwargs
['security_groups'] = None
1742 return self
.nova_drv
.server_create(**kwargs
)
1744 def nova_server_add_port(self
, server_id
, port_id
):
1745 self
.nova_drv
.server_add_port(server_id
, port_id
)
1747 def nova_server_delete_port(self
, server_id
, port_id
):
1748 self
.nova_drv
.server_delete_port(server_id
, port_id
)
1750 def nova_server_start(self
, server_id
):
1751 self
.nova_drv
.server_start(server_id
)
1753 def nova_server_stop(self
, server_id
):
1754 self
.nova_drv
.server_stop(server_id
)
1756 def nova_server_delete(self
, server_id
):
1757 self
.nova_drv
.server_delete(server_id
)
1759 def nova_server_reboot(self
, server_id
):
1760 self
.nova_drv
.server_reboot(server_id
, reboot_type
='HARD')
1762 def nova_server_rebuild(self
, server_id
, image_id
):
1763 self
.nova_drv
.server_rebuild(server_id
, image_id
)
1765 def nova_floating_ip_list(self
):
1766 return self
.nova_drv
.floating_ip_list()
1768 def nova_floating_ip_create(self
, pool
= None):
1769 return self
.nova_drv
.floating_ip_create(pool
)
1771 def nova_floating_ip_delete(self
, floating_ip
):
1772 self
.nova_drv
.floating_ip_delete(floating_ip
)
1774 def nova_floating_ip_assign(self
, server_id
, floating_ip
, fixed_ip
):
1775 self
.nova_drv
.floating_ip_assign(server_id
, floating_ip
, fixed_ip
)
1777 def nova_floating_ip_release(self
, server_id
, floating_ip
):
1778 self
.nova_drv
.floating_ip_release(server_id
, floating_ip
)
1780 def nova_server_list(self
):
1781 return self
.nova_drv
.server_list()
1783 def nova_server_get(self
, server_id
):
1784 return self
.nova_drv
.server_get(server_id
)
1786 def nova_server_console(self
, server_id
):
1787 return self
.nova_drv
.server_console(server_id
)
1789 def nova_server_group_list(self
):
1790 return self
.nova_drv
.group_list()
1792 def neutron_network_list(self
):
1793 return self
.neutron_drv
.network_list()
1795 def neutron_network_get(self
, network_id
):
1796 return self
.neutron_drv
.network_get(network_id
)
1798 def neutron_network_create(self
, **kwargs
):
1799 return self
.neutron_drv
.network_create(**kwargs
)
1801 def neutron_network_delete(self
, network_id
):
1802 self
.neutron_drv
.network_delete(network_id
)
1804 def neutron_subnet_list(self
):
1805 return self
.neutron_drv
.subnet_list()
1807 def neutron_subnet_get(self
, subnet_id
):
1808 return self
.neutron_drv
.subnet_get(subnet_id
)
1810 def neutron_subnet_create(self
, **kwargs
):
1811 return self
.neutron_drv
.subnet_create(**kwargs
)
1813 def netruon_subnet_delete(self
, subnet_id
):
1814 self
.neutron_drv
.subnet_delete(subnet_id
)
1816 def neutron_subnetpool_list(self
):
1817 return self
.neutron_drv
.subnetpool_list()
1819 def netruon_subnetpool_by_name(self
, pool_name
):
1820 pool_list
= self
.neutron_drv
.subnetpool_list(**{'name': pool_name
})
1826 def neutron_port_list(self
, **kwargs
):
1827 return self
.neutron_drv
.port_list(**kwargs
)
1829 def neutron_port_get(self
, port_id
):
1830 return self
.neutron_drv
.port_get(port_id
)
1832 def neutron_port_create(self
, **kwargs
):
1833 subnets
= [subnet
for subnet
in self
.neutron_drv
.subnet_list() if subnet
['network_id'] == kwargs
['network_id']]
1834 assert len(subnets
) == 1
1835 kwargs
['subnet_id'] = subnets
[0]['id']
1836 if not 'admin_state_up' in kwargs
:
1837 kwargs
['admin_state_up'] = True
1838 port_id
= self
.neutron_drv
.port_create(**kwargs
)
1840 if 'vm_id' in kwargs
:
1841 self
.nova_server_add_port(kwargs
['vm_id'], port_id
)
1844 def neutron_security_group_list(self
):
1845 return self
.neutron_drv
.security_group_list()
1847 def neutron_security_group_by_name(self
, group_name
):
1848 group_list
= self
.neutron_drv
.security_group_list()
1849 groups
= [group
for group
in group_list
if group
['name'] == group_name
]
1855 def neutron_port_delete(self
, port_id
):
1856 self
.neutron_drv
.port_delete(port_id
)
1858 def ceilo_meter_endpoint(self
):
1859 return self
.ceilo_drv
.endpoint
1861 def ceilo_meter_list(self
):
1862 return self
.ceilo_drv
.meters
1864 def ceilo_nfvi_metrics(self
, vim_id
):
1865 """Returns a dict of NFVI metrics for a given VM
1868 vim_id - the VIM ID of the VM to retrieve the metrics for
1871 A dict of NFVI metrics
1874 def query_latest_sample(counter_name
):
1876 filter = json
.dumps({
1878 {"=": {"resource": vim_id
}},
1879 {"=": {"counter_name": counter_name
}}
1882 orderby
= json
.dumps([{"timestamp": "DESC"}])
1883 result
= self
.ceilo_drv
.client
.query_samples
.query(
1893 except Exception as e
:
1894 logger
.error("Got exception while querying ceilometer, exception details:%s " %str
(e
))
1898 memory_usage
= query_latest_sample("memory.usage")
1899 disk_usage
= query_latest_sample("disk.usage")
1900 cpu_util
= query_latest_sample("cpu_util")
1904 if memory_usage
is not None:
1905 memory_usage
.volume
= 1e6
* memory_usage
.volume
1906 metrics
["memory_usage"] = memory_usage
.to_dict()
1908 if disk_usage
is not None:
1909 metrics
["disk_usage"] = disk_usage
.to_dict()
1911 if cpu_util
is not None:
1912 metrics
["cpu_util"] = cpu_util
.to_dict()
1916 def ceilo_alarm_list(self
):
1917 """Returns a list of ceilometer alarms"""
1918 return self
.ceilo_drv
.client
.alarms
.list()
1920 def ceilo_alarm_create(self
,
1933 """Create a new Alarm
1936 name - the name of the alarm
1937 meter - the name of the meter to measure
1938 statistic - the type of statistic used to trigger the alarm
1939 ('avg', 'min', 'max', 'count', 'sum')
1940 operation - the relational operator that, combined with the
1941 threshold value, determines when the alarm is
1942 triggered ('lt', 'le', 'eq', 'ge', 'gt')
1943 threshold - the value of the statistic that will trigger the
1945 period - the duration (seconds) over which to evaluate the
1947 evaluations - the number of samples of the meter statistic to
1948 collect when evaluating the threshold
1949 severity - a measure of the urgency or importance of the alarm
1950 ('low', 'moderate', 'critical')
1951 repeat - a flag that indicates whether the alarm should be
1952 triggered once (False) or repeatedly while the alarm
1953 condition is true (True)
1954 enabled - a flag that indicates whether the alarm is enabled
1955 (True) or disabled (False)
1956 actions - a dict specifying the URLs for webhooks. The dict can
1957 have up to 3 keys: 'insufficient_data', 'alarm',
1958 'ok'. Each key is associated with a list of URLs to
1959 webhooks that will be invoked when one of the 3
1961 kwargs - an arbitrary dict of keyword arguments that are
1962 passed to the ceilometer client
1965 ok_actions
= actions
.get('ok') if actions
is not None else None
1966 alarm_actions
= actions
.get('alarm') if actions
is not None else None
1967 insufficient_data_actions
= actions
.get('insufficient_data') if actions
is not None else None
1969 return self
.ceilo_drv
.client
.alarms
.create(
1972 statistic
=statistic
,
1973 comparison_operator
=operation
,
1974 threshold
=threshold
,
1976 evaluation_periods
=evaluations
,
1978 repeat_actions
=repeat
,
1980 ok_actions
=ok_actions
,
1981 alarm_actions
=alarm_actions
,
1982 insufficient_data_actions
=insufficient_data_actions
,
1986 def ceilo_alarm_update(self
, alarm_id
, **kwargs
):
1987 """Updates an existing alarm
1990 alarm_id - the identifier of the alarm to update
1991 kwargs - a dict of the alarm attributes to update
1994 return self
.ceilo_drv
.client
.alarms
.update(alarm_id
, **kwargs
)
1996 def ceilo_alarm_delete(self
, alarm_id
):
1997 self
.ceilo_drv
.client
.alarms
.delete(alarm_id
)