provider.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. """Provider implementation based on boto library for AWS-compatible clouds."""
  2. import logging as log
  3. import boto3
  4. try:
  5. # These are installed only for the case of a dev instance
  6. import responses
  7. from moto import mock_ec2
  8. from moto import mock_s3
  9. except ImportError:
  10. log.debug('[aws provider] moto library not available!')
  11. from cloudbridge.cloud.base import BaseCloudProvider
  12. from cloudbridge.cloud.base.helpers import get_env
  13. from cloudbridge.cloud.interfaces import TestMockHelperMixin
  14. from .services import AWSComputeService
  15. from .services import AWSNetworkingService
  16. from .services import AWSSecurityService
  17. from .services import AWSStorageService
  18. class AWSCloudProvider(BaseCloudProvider):
  19. '''AWS cloud provider interface'''
  20. PROVIDER_ID = 'aws'
  21. AWS_INSTANCE_DATA_DEFAULT_URL = "http://cloudve.org/cb-aws-vmtypes.json"
  22. def __init__(self, config):
  23. super(AWSCloudProvider, self).__init__(config)
  24. # Initialize cloud connection fields
  25. # These are passed as-is to Boto
  26. self.region_name = self._get_config_value('aws_region_name',
  27. 'us-east-1')
  28. self.session_cfg = {
  29. 'aws_access_key_id': self._get_config_value(
  30. 'aws_access_key', get_env('AWS_ACCESS_KEY', None)),
  31. 'aws_secret_access_key': self._get_config_value(
  32. 'aws_secret_key', get_env('AWS_SECRET_KEY', None)),
  33. 'aws_session_token': self._get_config_value(
  34. 'aws_session_token', None)
  35. }
  36. self.ec2_cfg = {
  37. 'use_ssl': self._get_config_value('ec2_is_secure', True),
  38. 'verify': self._get_config_value('ec2_validate_certs', True),
  39. 'endpoint_url': self._get_config_value('ec2_endpoint_url', None)
  40. }
  41. self.s3_cfg = {
  42. 'use_ssl': self._get_config_value('s3_is_secure', True),
  43. 'verify': self._get_config_value('s3_validate_certs', True),
  44. 'endpoint_url': self._get_config_value('s3_endpoint_url', None)
  45. }
  46. # service connections, lazily initialized
  47. self._session = None
  48. self._ec2_conn = None
  49. self._vpc_conn = None
  50. self._s3_conn = None
  51. # Initialize provider services
  52. self._compute = AWSComputeService(self)
  53. self._networking = AWSNetworkingService(self)
  54. self._security = AWSSecurityService(self)
  55. self._storage = AWSStorageService(self)
  56. @property
  57. def session(self):
  58. '''Get a low-level session object or create one if needed'''
  59. if not self._session:
  60. if self.config.debug_mode:
  61. boto3.set_stream_logger(level=log.DEBUG)
  62. self._session = boto3.session.Session(
  63. region_name=self.region_name, **self.session_cfg)
  64. return self._session
  65. @property
  66. def ec2_conn(self):
  67. if not self._ec2_conn:
  68. self._ec2_conn = self._connect_ec2()
  69. return self._ec2_conn
  70. @property
  71. def s3_conn(self):
  72. if not self._s3_conn:
  73. self._s3_conn = self._connect_s3()
  74. return self._s3_conn
  75. @property
  76. def compute(self):
  77. return self._compute
  78. @property
  79. def networking(self):
  80. return self._networking
  81. @property
  82. def security(self):
  83. return self._security
  84. @property
  85. def storage(self):
  86. return self._storage
  87. def _connect_ec2(self):
  88. """
  89. Get a boto ec2 connection object.
  90. """
  91. return self._connect_ec2_region(region_name=self.region_name)
  92. def _connect_ec2_region(self, region_name=None):
  93. '''Get an EC2 resource object'''
  94. return self.session.resource(
  95. 'ec2', region_name=region_name, **self.ec2_cfg)
  96. def _connect_s3(self):
  97. '''Get an S3 resource object'''
  98. return self.session.resource(
  99. 's3', region_name=self.region_name, **self.s3_cfg)
  100. class MockAWSCloudProvider(AWSCloudProvider, TestMockHelperMixin):
  101. def __init__(self, config):
  102. super(MockAWSCloudProvider, self).__init__(config)
  103. def setUpMock(self):
  104. """
  105. Let Moto take over all socket communications
  106. """
  107. self.ec2mock = mock_ec2()
  108. self.ec2mock.start()
  109. self.s3mock = mock_s3()
  110. self.s3mock.start()
  111. responses.add(
  112. responses.GET,
  113. self.AWS_INSTANCE_DATA_DEFAULT_URL,
  114. body=u"""
  115. [
  116. {
  117. "family": "General Purpose",
  118. "enhanced_networking": false,
  119. "vCPU": 1,
  120. "generation": "current",
  121. "ebs_iops": 0,
  122. "network_performance": "Low",
  123. "ebs_throughput": 0,
  124. "vpc": {
  125. "ips_per_eni": 2,
  126. "max_enis": 2
  127. },
  128. "arch": [
  129. "x86_64"
  130. ],
  131. "linux_virtualization_types": [
  132. "HVM"
  133. ],
  134. "ebs_optimized": false,
  135. "storage": null,
  136. "max_bandwidth": 0,
  137. "instance_type": "t2.nano",
  138. "ECU": "variable",
  139. "memory": 0.5,
  140. "ebs_max_bandwidth": 0
  141. }
  142. ]
  143. """)
  144. def tearDownMock(self):
  145. """
  146. Stop Moto intercepting all socket communications
  147. """
  148. self.s3mock.stop()
  149. self.ec2mock.stop()