瀏覽代碼

Add router.subnets property

Enis Afgan 7 年之前
父節點
當前提交
cf5b6de9d7

+ 10 - 0
cloudbridge/cloud/interfaces/resources.py

@@ -1289,6 +1289,16 @@ class Router(LabeledCloudResource):
         """
         """
         pass
         pass
 
 
+    @abstractproperty
+    def subnets(self):
+        """
+        List of subnets attached to this router.
+
+        :rtype: ``list`` of :class:`.Subnet` objects
+        :return: A list of subnets associated with this router.
+        """
+        pass
+
     @abstractmethod
     @abstractmethod
     def attach_gateway(self, gateway):
     def attach_gateway(self, gateway):
         """
         """

+ 1 - 1
cloudbridge/cloud/interfaces/services.py

@@ -816,7 +816,7 @@ class RouterService(PageableObjectMixin, CloudService):
         """
         """
         Searches for a router by a given list of attributes.
         Searches for a router by a given list of attributes.
 
 
-        Supported attributes: name, label
+        Supported attributes: label
 
 
         :rtype: List of ``object`` of :class:`.Router`
         :rtype: List of ``object`` of :class:`.Router`
         :return: A list of Router objects matching the supplied attributes.
         :return: A list of Router objects matching the supplied attributes.

+ 5 - 0
cloudbridge/cloud/providers/aws/resources.py

@@ -1221,6 +1221,11 @@ class AWSRouter(BaseRouter):
             a.delete()
             a.delete()
         self.refresh()
         self.refresh()
 
 
+    @property
+    def subnets(self):
+        return [AWSSubnet(self._provider, rta.subnet)
+                for rta in self._route_table.associations if rta.subnet]
+
     def attach_gateway(self, gateway):
     def attach_gateway(self, gateway):
         gw_id = (gateway.id if isinstance(gateway, AWSInternetGateway)
         gw_id = (gateway.id if isinstance(gateway, AWSInternetGateway)
                  else gateway)
                  else gateway)

+ 8 - 1
cloudbridge/cloud/providers/azure/resources.py

@@ -1142,7 +1142,7 @@ class AzureSubnet(BaseSubnet):
     @property
     @property
     def tag_name(self):
     def tag_name(self):
         if not self._tag_name:
         if not self._tag_name:
-            self._tag_name = 'SubnetLabel_' + self._subnet.name
+            self._tag_name = 'SubnetLabel_{0}'.format(self._subnet.name)
         return self._tag_name
         return self._tag_name
 
 
     @property
     @property
@@ -1697,6 +1697,13 @@ class AzureRouter(BaseRouter):
                                          self.resource_id)
                                          self.resource_id)
         self.refresh()
         self.refresh()
 
 
+    @property
+    def subnets(self):
+        if self._route_table.subnets:
+            return [AzureSubnet(self._provider, sn)
+                    for sn in self._route_table.subnets]
+        return []
+
     def detach_subnet(self, subnet):
     def detach_subnet(self, subnet):
         self._provider.azure_client. \
         self._provider.azure_client. \
             detach_subnet_to_route_table(subnet.id,
             detach_subnet_to_route_table(subnet.id,

+ 16 - 3
cloudbridge/cloud/providers/openstack/resources.py

@@ -403,9 +403,9 @@ class OpenStackInstance(BaseInstance):
         Extract (one) subnet id associated with this instance.
         Extract (one) subnet id associated with this instance.
 
 
         In OpenStack, instances are associated with ports instead of
         In OpenStack, instances are associated with ports instead of
-        instances so we need to dig through several connections to retrieve
-        the subnet_id. Further, there can potentially be several ports
-        connected to to different subnets. This implementation retrieves one
+        subnets so we need to dig through several connections to retrieve
+        the subnet_id. Further, there can potentially be several ports each
+        connected to different subnets. This implementation retrieves one
         subnet, the one corresponding to port associated with the first
         subnet, the one corresponding to port associated with the first
         private IP associated with the instance.
         private IP associated with the instance.
         """
         """
@@ -1123,6 +1123,19 @@ class OpenStackRouter(BaseRouter):
             return True
             return True
         return False
         return False
 
 
+    @property
+    def subnets(self):
+        # A router and a subnet are linked via a port, so traverse all ports
+        # to find a list of subnets associated with the current router.
+        subnets = []
+        for prt in self._provider.neutron.list_ports().get('ports'):
+            if prt.get('device_id') == self.id and \
+               prt.get('device_owner') == 'network:router_interface':
+                for fixed_ip in prt.get('fixed_ips'):
+                    subnets.append(self._provider.networking.subnets.get(
+                        fixed_ip.get('subnet_id')))
+        return subnets
+
     def attach_gateway(self, gateway):
     def attach_gateway(self, gateway):
         self._provider.neutron.add_gateway_router(
         self._provider.neutron.add_gateway_router(
             self.id, {'network_id': gateway.id})
             self.id, {'network_id': gateway.id})

+ 8 - 0
test/test_network_service.py

@@ -200,7 +200,15 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
 #                 "Router {0} should not be assoc. with a network {1}".format(
 #                 "Router {0} should not be assoc. with a network {1}".format(
 #                     router.id, router.network_id))
 #                     router.id, router.network_id))
 
 
+            self.assertTrue(
+                len(router.subnets) == 0,
+                "No subnet should be attached to router {1}".format(sn, router)
+            )
             router.attach_subnet(sn)
             router.attach_subnet(sn)
+            self.assertTrue(
+                len(router.subnets) == 1,
+                "Subnet {0} not attached to router {1}".format(sn, router)
+            )
             gteway = net.gateways.get_or_create_inet_gateway()
             gteway = net.gateways.get_or_create_inet_gateway()
             router.attach_gateway(gteway)
             router.attach_gateway(gteway)
             # TODO: add a check for routes after that's been implemented
             # TODO: add a check for routes after that's been implemented