services.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. """
  2. Services implemented by this provider
  3. """
  4. from cinderclient.exceptions import NotFound as CinderNotFound
  5. from novaclient.exceptions import NotFound as NovaNotFound
  6. from cloudbridge.providers.base import BaseKeyPair
  7. from cloudbridge.providers.base import BaseSecurityGroup
  8. from cloudbridge.providers.interfaces import BlockStoreService
  9. from cloudbridge.providers.interfaces import ComputeService
  10. from cloudbridge.providers.interfaces import ImageService
  11. from cloudbridge.providers.interfaces import InstanceType
  12. from cloudbridge.providers.interfaces import InstanceTypesService
  13. from cloudbridge.providers.interfaces import KeyPair
  14. from cloudbridge.providers.interfaces import KeyPairService
  15. from cloudbridge.providers.interfaces import MachineImage
  16. from cloudbridge.providers.interfaces import PlacementZone
  17. from cloudbridge.providers.interfaces import SecurityGroup
  18. from cloudbridge.providers.interfaces import SecurityGroupService
  19. from cloudbridge.providers.interfaces import SecurityService
  20. from cloudbridge.providers.interfaces import SnapshotService
  21. from cloudbridge.providers.interfaces import VolumeService
  22. from .resources import OpenStackInstance
  23. from .resources import OpenStackInstanceType
  24. from .resources import OpenStackMachineImage
  25. from .resources import OpenStackRegion
  26. # from .resources import OpenStackSecurityGroup
  27. from .resources import OpenStackSnapshot
  28. from .resources import OpenStackVolume
  29. class OpenStackSecurityService(SecurityService):
  30. def __init__(self, provider):
  31. self.provider = provider
  32. # Initialize provider services
  33. self._key_pairs = OpenStackKeyPairService(provider)
  34. self._security_groups = OpenStackSecurityGroupService(provider)
  35. @property
  36. def key_pairs(self):
  37. """
  38. Provides access to key pairs for this provider.
  39. :rtype: ``object`` of :class:`.KeyPairService`
  40. :return: a KeyPairService object
  41. """
  42. return self._key_pairs
  43. @property
  44. def security_groups(self):
  45. """
  46. Provides access to security groups for this provider.
  47. :rtype: ``object`` of :class:`.SecurityGroupService`
  48. :return: a SecurityGroupService object
  49. """
  50. return self._security_groups
  51. class OpenStackKeyPairService(KeyPairService):
  52. def __init__(self, provider):
  53. self.provider = provider
  54. def list(self):
  55. """
  56. List all key pairs associated with this account.
  57. :rtype: ``list`` of :class:`.KeyPair`
  58. :return: list of KeyPair objects
  59. """
  60. key_pairs = self.provider.nova.keypairs.list()
  61. return [BaseKeyPair(kp.id) for kp in key_pairs]
  62. class OpenStackSecurityGroupService(SecurityGroupService):
  63. def __init__(self, provider):
  64. self.provider = provider
  65. def list(self):
  66. """
  67. List all security groups associated with this account.
  68. :rtype: ``list`` of :class:`.SecurityGroup`
  69. :return: list of SecurityGroup objects
  70. """
  71. groups = self.provider.nova.security_groups.list()
  72. return [BaseSecurityGroup(group.id, group.name, group.description)
  73. for group in groups]
  74. def create(self, name, description):
  75. """
  76. Create a new security group under the current account.
  77. :type name: str
  78. :param name: The name of the new security group.
  79. :type description: str
  80. :param description: The description of the new security group.
  81. :rtype: ``object`` of :class:`.SecurityGroup`
  82. :return: a SecurityGroup object
  83. """
  84. sg = self.provider.nova.security_groups.create(name, description)
  85. if sg:
  86. return BaseSecurityGroup(sg.id, name, description)
  87. return None
  88. def get(self, group_id):
  89. """
  90. Get a security group.
  91. :type group_id: str
  92. :param group_id: The security group to get by ID
  93. :rtype: :class:`SecurityGroup`
  94. :return: If found, return SecurityGroup object. Else, return ``None``.
  95. """
  96. sg = self.provider.nova.security_groups.get(group_id)
  97. if sg:
  98. return BaseSecurityGroup(sg.id, sg.name, sg.description)
  99. return None
  100. class OpenStackImageService(ImageService):
  101. def __init__(self, provider):
  102. self.provider = provider
  103. def get_image(self, image_id):
  104. """
  105. Returns an Image given its id
  106. """
  107. try:
  108. return OpenStackMachineImage(
  109. self.provider, self.provider.nova.images.get(image_id))
  110. except NovaNotFound:
  111. return None
  112. def find_image(self, name):
  113. """
  114. Searches for an image by a given list of attributes
  115. """
  116. raise NotImplementedError(
  117. 'find_image not implemented by this provider')
  118. def list_images(self):
  119. """
  120. List all images.
  121. """
  122. images = self.provider.nova.images.list()
  123. return [OpenStackMachineImage(self.provider, image)
  124. for image in images]
  125. class OpenStackInstanceTypesService(InstanceTypesService):
  126. def __init__(self, provider):
  127. self.provider = provider
  128. def list(self):
  129. return [OpenStackInstanceType(f)
  130. for f in self.provider.nova.flavors.list()]
  131. def find_by_name(self, name):
  132. return next(
  133. (itype for itype in self.list() if itype.name == name), None)
  134. class OpenStackBlockStoreService(BlockStoreService):
  135. def __init__(self, provider):
  136. self.provider = provider
  137. # Initialize provider services
  138. self._volumes = OpenStackVolumeService(self.provider)
  139. self._snapshots = OpenStackSnapshotService(self.provider)
  140. @property
  141. def volumes(self):
  142. return self._volumes
  143. @property
  144. def snapshots(self):
  145. return self._snapshots
  146. class OpenStackVolumeService(VolumeService):
  147. def __init__(self, provider):
  148. self.provider = provider
  149. def get_volume(self, volume_id):
  150. """
  151. Returns a volume given its id.
  152. """
  153. try:
  154. return OpenStackVolume(
  155. self.provider, self.provider.cinder.volumes.get(volume_id))
  156. except CinderNotFound:
  157. return None
  158. def find_volume(self, name):
  159. """
  160. Searches for a volume by a given list of attributes.
  161. """
  162. raise NotImplementedError(
  163. 'find_volume not implemented by this provider')
  164. def list_volumes(self):
  165. """
  166. List all volumes.
  167. """
  168. return [OpenStackVolume(self.provider, vol)
  169. for vol in self.provider.cinder.volumes.list()]
  170. def create_volume(self, name, size, zone, snapshot=None):
  171. """
  172. Creates a new volume.
  173. """
  174. zone_name = zone.name if isinstance(zone, PlacementZone) else zone
  175. snapshot_id = snapshot.snapshot_id if isinstance(
  176. zone, OpenStackSnapshot) and snapshot else snapshot
  177. os_vol = self.provider.cinder.volumes.create(
  178. size, name=name, availability_zone=zone_name,
  179. snapshot_id=snapshot_id)
  180. return OpenStackVolume(self.provider, os_vol)
  181. class OpenStackSnapshotService(SnapshotService):
  182. def __init__(self, provider):
  183. self.provider = provider
  184. def get_snapshot(self, snapshot_id):
  185. """
  186. Returns a snapshot given its id.
  187. """
  188. try:
  189. return OpenStackSnapshot(
  190. self.provider,
  191. self.provider.cinder.volume_snapshots.get(snapshot_id))
  192. except CinderNotFound:
  193. return None
  194. def find_snapshot(self, name):
  195. """
  196. Searches for a volume by a given list of attributes.
  197. """
  198. raise NotImplementedError(
  199. 'find_volume not implemented by this provider')
  200. def list_snapshots(self):
  201. """
  202. List all snapshot.
  203. """
  204. return [OpenStackSnapshot(self.provider, snap)
  205. for snap in self.provider.cinder.volume_snapshots.list()]
  206. def create_snapshot(self, name, volume, description=None):
  207. """
  208. Creates a new snapshot of a given volume.
  209. """
  210. volume_id = volume.volume_id if \
  211. isinstance(volume, OpenStackVolume) else volume
  212. os_snap = self.provider.cinder.volume_snapshots.create(
  213. volume_id, name=name,
  214. description=description)
  215. return OpenStackSnapshot(self.provider, os_snap)
  216. class OpenStackComputeService(ComputeService):
  217. def __init__(self, provider):
  218. self.provider = provider
  219. self.instance_types = OpenStackInstanceTypesService(self.provider)
  220. def create_instance(self, name, image, instance_type, zone=None,
  221. keypair=None, security_groups=None, user_data=None,
  222. block_device_mapping=None, network_interfaces=None,
  223. **kwargs):
  224. """
  225. Creates a new virtual machine instance.
  226. """
  227. image_id = image.image_id if isinstance(image, MachineImage) else image
  228. instance_size = instance_type.name if \
  229. isinstance(instance_type, InstanceType) else \
  230. self.instance_types.find_by_name(instance_type).id
  231. zone_name = zone.name if isinstance(zone, PlacementZone) else zone
  232. keypair_name = keypair.name if \
  233. isinstance(keypair, KeyPair) else keypair
  234. if security_groups:
  235. if isinstance(security_groups, list) and \
  236. isinstance(security_groups[0], SecurityGroup):
  237. security_groups_list = [sg.name for sg in security_groups]
  238. else:
  239. security_groups_list = security_groups
  240. else:
  241. security_groups_list = None
  242. os_instance = self.provider.nova.servers.create(
  243. name,
  244. image_id,
  245. instance_size,
  246. min_count=1,
  247. max_count=1,
  248. availability_zone=zone_name,
  249. key_name=keypair_name,
  250. security_groups=security_groups_list,
  251. userdata=user_data)
  252. return OpenStackInstance(self.provider, os_instance)
  253. def list_instances(self):
  254. """
  255. List all instances.
  256. """
  257. instances = self.provider.nova.servers.list()
  258. return [OpenStackInstance(self.provider, instance)
  259. for instance in instances]
  260. def list_regions(self):
  261. """
  262. List all data center regions.
  263. """
  264. # detailed must be set to ``False`` because the (default) ``True``
  265. # value requires Admin priviledges
  266. regions = self.provider.nova.availability_zones.list(detailed=False)
  267. return [OpenStackRegion(self.provider, region) for region in regions]
  268. def get_instance(self, instance_id):
  269. """
  270. Returns an instance given its id.
  271. """
  272. try:
  273. os_instance = self.provider.nova.servers.get(instance_id)
  274. return OpenStackInstance(self.provider, os_instance)
  275. except NovaNotFound:
  276. return None