baizhang 10 лет назад
Родитель
Сommit
f4adfab0e6

+ 2 - 0
cloudbridge/cloud/providers/gce/provider.py

@@ -41,6 +41,8 @@ class GCECloudProvider(BaseCloudProvider):
                 self.credentials_dict = json.load(creds_file)
                 self.credentials_dict = json.load(creds_file)
         self.default_zone = self._get_config_value(
         self.default_zone = self._get_config_value(
             'gce_default_zone', os.environ.get('GCE_DEFAULT_ZONE'))
             'gce_default_zone', os.environ.get('GCE_DEFAULT_ZONE'))
+        self.region_name = self._get_config_value(
+            'gce_region_name', 'us-central1')
 
 
         # service connections, lazily initialized
         # service connections, lazily initialized
         self._gce_compute = None
         self._gce_compute = None

+ 74 - 0
cloudbridge/cloud/providers/gce/resources.py

@@ -3,6 +3,8 @@ DataTypes used by this provider
 """
 """
 from cloudbridge.cloud.base.resources import BaseInstanceType
 from cloudbridge.cloud.base.resources import BaseInstanceType
 from cloudbridge.cloud.base.resources import BaseKeyPair
 from cloudbridge.cloud.base.resources import BaseKeyPair
+from cloudbridge.cloud.base.resources import BasePlacementZone
+from cloudbridge.cloud.base.resources import BaseRegion
 
 
 
 
 class GCEKeyPair(BaseKeyPair):
 class GCEKeyPair(BaseKeyPair):
@@ -88,3 +90,75 @@ class GCEInstanceType(BaseInstanceType):
                 if key not in ['id', 'name', 'kind', 'guestCpus', 'memoryMb',
                 if key not in ['id', 'name', 'kind', 'guestCpus', 'memoryMb',
                                'maximumPersistentDisksSizeGb',
                                'maximumPersistentDisksSizeGb',
                                'maximumPersistentDisks']}
                                'maximumPersistentDisks']}
+
+
+class GCEPlacementZone(BasePlacementZone):
+
+    def __init__(self, provider, zone, region):
+        super(GCEPlacementZone, self).__init__(provider)
+        if isinstance(zone, GCEPlacementZone):
+            # pylint:disable=protected-access
+            self._gce_zone = zone._gce_zone
+            self._gce_region = zone._gce_region
+        else:
+            self._gce_zone = zone
+            self._gce_region = region
+
+    @property
+    def id(self):
+        """
+        Get the zone id
+        :rtype: ``str``
+        :return: ID for this zone as returned by the cloud middleware.
+        """
+        return self._gce_zone
+
+    @property
+    def name(self):
+        """
+        Get the zone name.
+        :rtype: ``str``
+        :return: Name for this zone as returned by the cloud middleware.
+        """
+        return self._gce_zone
+
+    @property
+    def region_name(self):
+        """
+        Get the region that this zone belongs to.
+        :rtype: ``str``
+        :return: Name of this zone's region as returned by the cloud middleware
+        """
+        return self._gce_region
+
+
+class GCERegion(BaseRegion):
+
+    def __init__(self, provider, gce_region):
+        super(GCERegion, self).__init__(provider)
+        self._gce_region = gce_region
+
+    @property
+    def id(self):
+        # In GCE API, region has an 'id' property, whose values are '1220',
+        # '1100', '1000', '1230', etc. Here we use 'name' property (such
+        # as 'asia-east1', 'europe-west1', 'us-central1', 'us-east1') as
+        # 'id' to represent the region for the consistency with AWS
+        # implementation and ease of use.
+        return self._gce_region['name']
+
+    @property
+    def name(self):
+        return self._gce_region['name']
+
+    @property
+    def zones(self):
+        """
+        Accesss information about placement zones within this region.
+        """
+        zones_response = self._provider.gce_compute.zones().list(
+            project=self._provider.project_name).execute()
+        zones = [zone for zone in zones_response['items']
+                 if zone['region'] == self._gce_region['selfLink']]
+        return [GCEPlacementZone(self._provider, zone['name'], self.name)
+                for zone in zones]

+ 38 - 2
cloudbridge/cloud/providers/gce/services.py

@@ -2,17 +2,19 @@ from cloudbridge.cloud.base.resources import ClientPagedResultList
 from cloudbridge.cloud.base.services import BaseComputeService
 from cloudbridge.cloud.base.services import BaseComputeService
 from cloudbridge.cloud.base.services import BaseInstanceTypesService
 from cloudbridge.cloud.base.services import BaseInstanceTypesService
 from cloudbridge.cloud.base.services import BaseKeyPairService
 from cloudbridge.cloud.base.services import BaseKeyPairService
+from cloudbridge.cloud.base.services import BaseRegionService
 from cloudbridge.cloud.base.services import BaseSecurityGroupService
 from cloudbridge.cloud.base.services import BaseSecurityGroupService
 from cloudbridge.cloud.base.services import BaseSecurityService
 from cloudbridge.cloud.base.services import BaseSecurityService
 from cloudbridge.cloud.providers.gce import helpers
 from cloudbridge.cloud.providers.gce import helpers
 from collections import namedtuple
 from collections import namedtuple
 import hashlib
 import hashlib
-
+import googleapiclient
 
 
 from retrying import retry
 from retrying import retry
 
 
 from .resources import GCEInstanceType
 from .resources import GCEInstanceType
 from .resources import GCEKeyPair
 from .resources import GCEKeyPair
+from .resources import GCERegion
 
 
 
 
 class GCESecurityService(BaseSecurityService):
 class GCESecurityService(BaseSecurityService):
@@ -232,11 +234,45 @@ class GCEInstanceTypesService(BaseInstanceTypesService):
                                      limit=limit, marker=marker)
                                      limit=limit, marker=marker)
 
 
 
 
+class GCERegionService(BaseRegionService):
+
+    def __init__(self, provider):
+        super(GCERegionService, self).__init__(provider)
+
+    def get(self, region_id):
+        try:
+            region = self.provider.gce_compute \
+                                  .regions() \
+                                  .get(project=self.provider.project_name,
+                                       region=region_id) \
+                                  .execute()
+        # Handle the case when region_id is not valid
+        except googleapiclient.errors.HttpError:
+            return None
+        if region:
+            return GCERegion(self.provider, region)
+        else:
+            return None
+
+    def list(self, limit=None, marker=None):
+        regions_response = self.provider.gce_compute.regions().list(
+            project=self.provider.project_name).execute()
+        regions = [GCERegion(self.provider, region)
+                   for region in regions_response['items']]
+        return ClientPagedResultList(self.provider, regions,
+                                     limit=limit, marker=marker)
+
+    @property
+    def current(self):
+        return self.get(self.provider.region_name)
+
+
 class GCEComputeService(BaseComputeService):
 class GCEComputeService(BaseComputeService):
     # TODO: implement GCEComputeService
     # TODO: implement GCEComputeService
     def __init__(self, provider):
     def __init__(self, provider):
         super(GCEComputeService, self).__init__(provider)
         super(GCEComputeService, self).__init__(provider)
         self._instance_type_svc = GCEInstanceTypesService(self.provider)
         self._instance_type_svc = GCEInstanceTypesService(self.provider)
+        self._region_svc = GCERegionService(self.provider)
 
 
     @property
     @property
     def images(self):
     def images(self):
@@ -252,4 +288,4 @@ class GCEComputeService(BaseComputeService):
 
 
     @property
     @property
     def regions(self):
     def regions(self):
-        raise NotImplementedError("To be implemented")
+        return self._region_svc