Procházet zdrojové kódy

Modify GCEInstance security_groups based on review comments.

baizhang před 9 roky
rodič
revize
8c0fdd13f6

+ 17 - 13
cloudbridge/cloud/providers/gce/resources.py

@@ -746,7 +746,8 @@ class GCEInstance(BaseInstance):
         # In GCE, the name of the instance is provided by the client when
         # In GCE, the name of the instance is provided by the client when
         # initially creating the resource. The name cannot be changed after
         # initially creating the resource. The name cannot be changed after
         # the instance is created.
         # the instance is created.
-        raise NotImplementedError("Not implemented by this provider.")
+        cb.log.warning("Setting instance name after it is created is not "
+                       "supported by this provider.")
 
 
     @property
     @property
     def public_ips(self):
     def public_ips(self):
@@ -871,19 +872,18 @@ class GCEInstance(BaseInstance):
         """
         """
         Get the security groups associated with this instance.
         Get the security groups associated with this instance.
         """
         """
-        sg_service = self._provider.security.security_groups
-        sg_names = [sg.name for sg in sg_service.list()]
-        tags = self._gce_instance['tags']['items']
-        if len(tags) == 0 or len(sg_names) == 0:
+        network_url = self._gce_instance.get('networkInterfaces')[0].get(
+            'network')
+        network_name = GCEFirewallsDelegate.network_name(
+            {'network': network_url})
+        if 'items' not in self._gce_instance['tags']:
             return []
             return []
-        common_tags = set(sg_names) & set(tags)
-        # We have a list of the security group names, now get the
-        # GCESecurityGroup objects.
-        sgs = []
-        for tag in common_tags:
-            result = sg_service.find(tag)
-            if len(result) > 0:
-                sgs.append(result[0])
+        tags = self._gce_instance['tags']['items']
+        # Tags are mapped to non-empty security groups under the instance
+        # network. Unmatched tags are ignored.
+        sgs = (self._provider.security
+               .security_groups.find_by_network_and_tags(
+                   network_name, tags))
         return sgs
         return sgs
 
 
     @property
     @property
@@ -943,6 +943,10 @@ class GCENetwork(BaseNetwork):
         super(GCENetwork, self).__init__(provider)
         super(GCENetwork, self).__init__(provider)
         self._network = network
         self._network = network
 
 
+    @property
+    def resource_url(self):
+        return self._network['selfLink']
+
     @property
     @property
     def id(self):
     def id(self):
         return self._network['id']
         return self._network['id']

+ 26 - 7
cloudbridge/cloud/providers/gce/services.py

@@ -240,6 +240,23 @@ class GCESecurityGroupService(BaseSecurityGroupService):
     def delete(self, group_id):
     def delete(self, group_id):
         return self._delegate.delete_tag_network_with_id(group_id)
         return self._delegate.delete_tag_network_with_id(group_id)
 
 
+    def find_by_network_and_tags(self, network_name, tags):
+        """
+        Finds non-empty security groups by network name and security group
+        names (tags). If no matching security group is found, an empty list
+        is returned.
+        """
+        security_groups = []
+        for tag, net_name in self._delegate.tag_networks:
+            if network_name != net_name:
+                continue
+            if tag not in tags:
+                continue
+            network = self.provider.network.get_by_name(net_name)
+            security_groups.append(
+                GCESecurityGroup(self._delegate, tag, network))
+        return security_groups
+
 
 
 class GCEInstanceTypesService(BaseInstanceTypesService):
 class GCEInstanceTypesService(BaseInstanceTypesService):
 
 
@@ -410,16 +427,20 @@ class GCEInstanceService(BaseInstanceService):
     def __init__(self, provider):
     def __init__(self, provider):
         super(GCEInstanceService, self).__init__(provider)
         super(GCEInstanceService, self).__init__(provider)
 
 
-    def create(self, name, image, instance_type, zone=None,
+    def create(self, name, image, instance_type, network=None, zone=None,
                key_pair=None, security_groups=None, user_data=None,
                key_pair=None, security_groups=None, user_data=None,
-               launch_config=None,
-               **kwargs):
+               launch_config=None, **kwargs):
         """
         """
         Creates a new virtual machine instance.
         Creates a new virtual machine instance.
         """
         """
         if not zone:
         if not zone:
             zone = self.provider.default_zone
             zone = self.provider.default_zone
         if not launch_config:
         if not launch_config:
+            if network:
+                network_url = (network.resource_url
+                               if isinstance(network, Network) else network)
+            else:
+                network_url = 'global/networks/default'
             config = {
             config = {
                 'name': name,
                 'name': name,
                 'machineType': instance_type.resource_url,
                 'machineType': instance_type.resource_url,
@@ -430,14 +451,12 @@ class GCEInstanceService(BaseInstanceService):
                            }
                            }
                        }],
                        }],
                 'networkInterfaces': [
                 'networkInterfaces': [
-                    {'network': 'global/networks/default',
+                    {'network': network_url,
                      'accessConfigs': [{'type': 'ONE_TO_ONE_NAT',
                      'accessConfigs': [{'type': 'ONE_TO_ONE_NAT',
                                         'name': 'External NAT'}]
                                         'name': 'External NAT'}]
                  }],
                  }],
             }
             }
-            if (security_groups and
-                isinstance(security_groups, list) and
-                len(security_groups) > 0):
+            if security_groups and isinstance(security_groups, list):
                 sg_names = []
                 sg_names = []
                 if isinstance(security_groups[0], SecurityGroup):
                 if isinstance(security_groups[0], SecurityGroup):
                     sg_names = [sg.name for sg in security_groups]
                     sg_names = [sg.name for sg in security_groups]