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.default_zone = self._get_config_value(
             '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
         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 BaseKeyPair
+from cloudbridge.cloud.base.resources import BasePlacementZone
+from cloudbridge.cloud.base.resources import BaseRegion
 
 
 class GCEKeyPair(BaseKeyPair):
@@ -88,3 +90,75 @@ class GCEInstanceType(BaseInstanceType):
                 if key not in ['id', 'name', 'kind', 'guestCpus', 'memoryMb',
                                'maximumPersistentDisksSizeGb',
                                '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 BaseInstanceTypesService
 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 BaseSecurityService
 from cloudbridge.cloud.providers.gce import helpers
 from collections import namedtuple
 import hashlib
-
+import googleapiclient
 
 from retrying import retry
 
 from .resources import GCEInstanceType
 from .resources import GCEKeyPair
+from .resources import GCERegion
 
 
 class GCESecurityService(BaseSecurityService):
@@ -232,11 +234,45 @@ class GCEInstanceTypesService(BaseInstanceTypesService):
                                      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):
     # TODO: implement GCEComputeService
     def __init__(self, provider):
         super(GCEComputeService, self).__init__(provider)
         self._instance_type_svc = GCEInstanceTypesService(self.provider)
+        self._region_svc = GCERegionService(self.provider)
 
     @property
     def images(self):
@@ -252,4 +288,4 @@ class GCEComputeService(BaseComputeService):
 
     @property
     def regions(self):
-        raise NotImplementedError("To be implemented")
+        return self._region_svc