provider.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. """
  2. Provider implementation based on openstack python client for OpenStack
  3. compatible clouds.
  4. """
  5. import os
  6. from cinderclient import client as cinder_client
  7. from keystoneclient import client as keystone_client
  8. from keystoneclient import session
  9. from keystoneclient.auth.identity import Password
  10. from neutronclient.v2_0 import client as neutron_client
  11. from novaclient import client as nova_client
  12. from novaclient import shell as nova_shell
  13. from swiftclient import client as swift_client
  14. from cloudbridge.cloud.base import BaseCloudProvider
  15. from .services import OpenStackBlockStoreService
  16. from .services import OpenStackComputeService
  17. from .services import OpenStackNetworkService
  18. from .services import OpenStackObjectStoreService
  19. from .services import OpenStackSecurityService
  20. class OpenStackCloudProvider(BaseCloudProvider):
  21. PROVIDER_ID = 'openstack'
  22. def __init__(self, config):
  23. super(OpenStackCloudProvider, self).__init__(config)
  24. # Initialize cloud connection fields
  25. self.username = self._get_config_value(
  26. 'os_username', os.environ.get('OS_USERNAME', None))
  27. self.password = self._get_config_value(
  28. 'os_password', os.environ.get('OS_PASSWORD', None))
  29. self.tenant_name = self._get_config_value(
  30. 'os_tenant_name', os.environ.get('OS_TENANT_NAME', None))
  31. self.auth_url = self._get_config_value(
  32. 'os_auth_url', os.environ.get('OS_AUTH_URL', None))
  33. self.region_name = self._get_config_value(
  34. 'os_region_name', os.environ.get('OS_REGION_NAME', None))
  35. # Allow individual service connections to have their own values but
  36. # default to a the ones defined above.
  37. self.swift_username = self._get_config_value(
  38. 'os_swift_username',
  39. os.environ.get('OS_SWIFT_USERNAME', self.username))
  40. self.swift_password = self._get_config_value(
  41. 'os_swift_password',
  42. os.environ.get('OS_SWIFT_PASSWORD', self.password))
  43. self.swift_tenant_name = self._get_config_value(
  44. 'os_swift_tenant_name',
  45. os.environ.get('OS_SWIFT_TENANT_NAME', self.tenant_name))
  46. self.swift_auth_url = self._get_config_value(
  47. 'os_swift_auth_url',
  48. os.environ.get('OS_SWIFT_AUTH_URL', self.auth_url))
  49. self.swift_region_name = self._get_config_value(
  50. 'os_swift_region_name',
  51. os.environ.get('OS_SWIFT_REGION_NAME', self.region_name))
  52. # service connections, lazily initialized
  53. self._nova = None
  54. self._keystone = None
  55. self._glance = None
  56. self._cinder = None
  57. self._swift = None
  58. self._neutron = None
  59. # Initialize provider services
  60. self._compute = OpenStackComputeService(self)
  61. self._network = OpenStackNetworkService(self)
  62. self._security = OpenStackSecurityService(self)
  63. self._block_store = OpenStackBlockStoreService(self)
  64. self._object_store = OpenStackObjectStoreService(self)
  65. @property
  66. def nova(self):
  67. if not self._nova:
  68. self._nova = self._connect_nova()
  69. return self._nova
  70. @property
  71. def keystone(self):
  72. if not self._keystone:
  73. self._keystone = self._connect_keystone()
  74. return self._keystone
  75. # @property
  76. # def glance(self):
  77. # if not self._glance:
  78. # self._glance = self._connect_glance()
  79. # return self._glance
  80. @property
  81. def cinder(self):
  82. if not self._cinder:
  83. self._cinder = self._connect_cinder()
  84. return self._cinder
  85. @property
  86. def swift(self):
  87. if not self._swift:
  88. self._swift = self._connect_swift()
  89. return self._swift
  90. @property
  91. def neutron(self):
  92. if not self._neutron:
  93. self._neutron = self._connect_neutron()
  94. return self._neutron
  95. @property
  96. def compute(self):
  97. return self._compute
  98. @property
  99. def network(self):
  100. return self._network
  101. @property
  102. def security(self):
  103. return self._security
  104. @property
  105. def block_store(self):
  106. return self._block_store
  107. @property
  108. def object_store(self):
  109. return self._object_store
  110. def _connect_nova(self):
  111. """
  112. Get an openstack nova client object for the given cloud.
  113. """
  114. api_version = self._get_config_value(
  115. 'os_compute_api_version',
  116. os.environ.get('OS_COMPUTE_API_VERSION', 2))
  117. service_name = self._get_config_value(
  118. 'nova_service_name',
  119. os.environ.get('NOVA_SERVICE_NAME', None))
  120. if self.config.debug_mode:
  121. nova_shell.OpenStackComputeShell().setup_debugging(True)
  122. return nova_client.Client(
  123. api_version, username=self.username, api_key=self.password,
  124. project_id=self.tenant_name, auth_url=self.auth_url,
  125. region_name=self.region_name, service_name=service_name,
  126. http_log_debug=True if self.config.debug_mode else False)
  127. def _connect_keystone(self):
  128. """
  129. Get an openstack keystone client object for the given cloud.
  130. """
  131. auth = Password(self.auth_url, username=self.username,
  132. password=self.password, tenant_name=self.tenant_name)
  133. # Wow, the internal keystoneV2 implementation is terribly buggy. It
  134. # needs both a separate Session object and the username, password again
  135. # for things to work correctly. Plus, a manual call to authenticate()
  136. # is also required if the service catalogue needs to be queried
  137. keystone = keystone_client.Client(
  138. session=session.Session(auth=auth),
  139. auth_url=self.auth_url,
  140. username=self.username,
  141. password=self.password,
  142. tenant_name=self.tenant_name,
  143. region_name=self.region_name)
  144. keystone.authenticate()
  145. return keystone
  146. def _connect_cinder(self):
  147. """
  148. Get an openstack cinder client object for the given cloud.
  149. """
  150. api_version = self._get_config_value(
  151. 'os_volume_api_version',
  152. os.environ.get('OS_VOLUME_API_VERSION', 2))
  153. return cinder_client.Client(
  154. api_version, username=self.username, api_key=self.password,
  155. project_id=self.tenant_name, auth_url=self.auth_url)
  156. # def _connect_glance(self):
  157. # """
  158. # Get an openstack glance client object for the given cloud.
  159. # """
  160. # api_version = self._get_config_value(
  161. # 'os_image_api_version',
  162. # os.environ.get('OS_IMAGE_API_VERSION', 1))
  163. #
  164. # return glance_client.Client(version=api_version,
  165. # session=self.keystone.session)
  166. def _connect_swift(self):
  167. """
  168. Get an openstack swift client object for the given cloud.
  169. """
  170. os_options = {'region_name': self.swift_region_name}
  171. return swift_client.Connection(
  172. authurl=self.swift_auth_url, auth_version='2',
  173. user=self.swift_username, key=self.swift_password,
  174. tenant_name=self.swift_tenant_name,
  175. os_options=os_options)
  176. def _connect_neutron(self):
  177. """
  178. Get an OpenStack Neutron (networking) client object for the given
  179. cloud.
  180. """
  181. return neutron_client.Client(
  182. username=self.username, password=self.password,
  183. tenant_name=self.tenant_name, auth_url=self.auth_url)