Просмотр исходного кода

adding router/subnet/route support

Joshua Cornutt 9 лет назад
Родитель
Сommit
ebdd531d3b

+ 44 - 35
cloudbridge/cloud/providers/aws/resources.py

@@ -935,7 +935,10 @@ class AWSNetwork(BaseNetwork):
 
         .. note:: the network must have a (case sensitive) tag ``Name``
         """
-        return self._vpc.tags.get('Name')
+        for tag in self._vpc.tags or list():
+            if tag.get('Key') == 'Name':
+                return tag.get('Value')
+        return None
 
     @name.setter
     # pylint:disable=arguments-differ
@@ -943,7 +946,7 @@ class AWSNetwork(BaseNetwork):
         """
         Set the network name.
         """
-        self._vpc.add_tag('Name', value)
+        self._vpc.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
 
     @property
     def external(self):
@@ -956,7 +959,7 @@ class AWSNetwork(BaseNetwork):
     @property
     def state(self):
         return AWSNetwork._NETWORK_STATE_MAP.get(
-            self._vpc.update(), NetworkState.UNKNOWN)
+            self._vpc.state, NetworkState.UNKNOWN)
 
     @property
     def cidr_block(self):
@@ -966,16 +969,14 @@ class AWSNetwork(BaseNetwork):
         return self._vpc.delete()
 
     def subnets(self):
-        flter = {'vpc-id': self.id}
-        subnets = self._provider.vpc_conn.get_all_subnets(filters=flter)
-        return [AWSSubnet(self._provider, subnet) for subnet in subnets]
+        return [AWSSubnet(self._provider, x) for x in self._vpc.subnets.all()]
 
     def create_subnet(self, cidr_block, name=None):
-        subnet = self._provider.vpc_conn.create_subnet(self.id, cidr_block)
-        cb_subnet = AWSSubnet(self._provider, subnet)
-        if name:
-            cb_subnet.name = name
-        return cb_subnet
+        subnet = AWSSubnet(
+            self._provider,
+            self._vpc.create_subnet(CidrBlock=cidr_block))
+        subnet.name = name
+        return subnet
 
     def refresh(self):
         """
@@ -1002,7 +1003,10 @@ class AWSSubnet(BaseSubnet):
 
         .. note:: the subnet must have a (case sensitive) tag ``Name``
         """
-        return self._subnet.tags.get('Name')
+        for tag in self._subnet.tags or list():
+            if tag.get('Key') == 'Name':
+                return tag.get('Value')
+        return None
 
     @name.setter
     # pylint:disable=arguments-differ
@@ -1010,7 +1014,7 @@ class AWSSubnet(BaseSubnet):
         """
         Set the subnet name.
         """
-        self._subnet.add_tag('Name', value)
+        self._subnet.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
 
     @property
     def cidr_block(self):
@@ -1021,7 +1025,7 @@ class AWSSubnet(BaseSubnet):
         return self._subnet.vpc_id
 
     def delete(self):
-        return self._provider.vpc_conn.delete_subnet(subnet_id=self.id)
+        return self._subnet.delete()
 
 
 class AWSFloatingIP(BaseFloatingIP):
@@ -1046,7 +1050,7 @@ class AWSFloatingIP(BaseFloatingIP):
         return True if self._ip.instance_id else False
 
     def delete(self):
-        return self._ip.delete()
+        return self._ip.release()
 
 
 class AWSRouter(BaseRouter):
@@ -1070,9 +1074,14 @@ class AWSRouter(BaseRouter):
         :rtype: :class:`boto.vpc.routetable.RouteTable`
         :return: A RouteTable object.
         """
-        sn = self._provider.vpc_conn.get_all_subnets([subnet_id])[0]
-        return self._provider.vpc_conn.get_all_route_tables(
-            filters={'vpc-id': sn.vpc_id})[0]
+        return self._provider.ec2_conn.route_tables.filter(
+            Filters=[{
+                'Name': 'vpc-id',
+                'Values': [
+                    self._provider.ec2_conn.Subnet(subnet_id).vpc_id
+                ]
+            }]
+        )[0]
 
     @property
     def id(self):
@@ -1085,7 +1094,10 @@ class AWSRouter(BaseRouter):
 
         .. note:: the router must have a (case sensitive) tag ``Name``
         """
-        return self._router.tags.get('Name')
+        for tag in self._router.tags or list():
+            if tag.get('Key') == 'Name':
+                return tag.get('Value')
+        return None
 
     @name.setter
     # pylint:disable=arguments-differ
@@ -1093,36 +1105,33 @@ class AWSRouter(BaseRouter):
         """
         Set the router name.
         """
-        self._router.add_tag('Name', value)
+        self._router.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
 
     def refresh(self):
-        self._router = self._provider.vpc_conn.get_all_internet_gateways(
-            [self.id])[0]
+        self._router.reload()
 
     @property
     def state(self):
         self.refresh()  # Explicitly refresh the local object
         if self._router.attachments and \
-           self._router.attachments[0].state == 'available':
+           self._router.attachments[0]['State'] == 'available':
             return RouterState.ATTACHED
         return RouterState.DETACHED
 
     @property
     def network_id(self):
         if self.state == RouterState.ATTACHED:
-            return self._router.attachments[0].vpc_id
+            return self._router.attachments[0]['VpcId']
         return None
 
     def delete(self):
-        return self._provider._vpc_conn.delete_internet_gateway(self.id)
+        return self._router.delete()
 
     def attach_network(self, network_id):
-        return self._provider.vpc_conn.attach_internet_gateway(
-            self.id, network_id)
+        return self._router.attach_to_vpc(VpcId=network_id)
 
     def detach_network(self):
-        return self._provider.vpc_conn.detach_internet_gateway(
-            self.id, self.network_id)
+        return self._router.detach_from_vpc(VpcId=network_id)
 
     def add_route(self, subnet_id):
         """
@@ -1136,9 +1145,9 @@ class AWSRouter(BaseRouter):
         Further, only a single route can be added, targeting the Internet
         (i.e., destination CIDR block ``0.0.0.0/0``).
         """
-        rt = self._route_table(subnet_id)
-        return self._provider.vpc_conn.create_route(
-            rt.id, self._ROUTE_CIDR, self.id)
+        return self._route_table(subnet_id).create_route(
+            DestinationCidrBlock=self._ROUTE_CIDR,
+            GatewayId=self.id)
 
     def remove_route(self, subnet_id):
         """
@@ -1146,9 +1155,9 @@ class AWSRouter(BaseRouter):
 
         .. seealso:: ``add_route`` method
         """
-        rt = self._route_table(subnet_id)
-        return self._provider.vpc_conn.delete_route(rt.id, self._ROUTE_CIDR)
-
+        for route in self._route_table(subnet_id).routes or list():
+            if route.gateway_id == self.id:
+                route.delete()
 
 class AWSLaunchConfig(BaseLaunchConfig):
 

+ 47 - 41
cloudbridge/cloud/providers/aws/services.py

@@ -737,18 +737,33 @@ class AWSNetworkService(BaseNetworkService):
     def __init__(self, provider):
         super(AWSNetworkService, self).__init__(provider)
         self._subnet_svc = AWSSubnetService(self.provider)
+        self.iface = EC2ServiceFilter(self.provider,
+                                      'vpcs', AWSNetwork)
+        self.iface_vips = EC2ServiceFilter(self.provider,
+                                           'vpc_addresses', AWSFloatingIP)
+        self.iface_igws = EC2ServiceFilter(self.provider,
+                                           'internet_gateways', AWSRouter)
 
-    def get(self, network_id):
-        network = self.provider.vpc_conn.get_all_vpcs(vpc_ids=[network_id])
-        if network:
-            return AWSNetwork(self.provider, network[0])
-        return None
+    def get(self, nid):
+        """Returns a network given its ID"""
+        return self.iface.get(nid, 'vpc-id')
 
     def list(self, limit=None, marker=None):
-        networks = [AWSNetwork(self.provider, network)
-                    for network in self.provider.vpc_conn.get_all_vpcs()]
-        return ClientPagedResultList(self.provider, networks,
-                                     limit=limit, marker=marker)
+        """List all networks associated with this account"""
+        return self.iface.list(limit=limit, marker=marker)
+
+    def find(self, name, limit=None, marker=None):
+        """Searches for a network by name"""
+        return self.iface.find(name, 'tag:Name', limit=limit, marker=marker)
+
+    def floating_ips(self, network_id=None):
+        return [
+            x for x in self.iface_vips.list()
+            if not network_id or x.network_interface_id == network_id
+        ]
+
+    def routers(self):
+        return self.iface_igws.list()
 
     def create(self, name=None):
         # AWS requried CIDR block to be specified when creating a network
@@ -765,21 +780,10 @@ class AWSNetworkService(BaseNetworkService):
     def subnets(self):
         return self._subnet_svc
 
-    def floating_ips(self, network_id=None):
-        fltrs = None
-        if network_id:
-            fltrs = {'network-interface-id': network_id}
-        al = self.provider.vpc_conn.get_all_addresses(filters=fltrs)
-        return [AWSFloatingIP(self.provider, a) for a in al]
-
     def create_floating_ip(self):
         ip = self.provider.ec2_conn.allocate_address(domain='vpc')
         return AWSFloatingIP(self.provider, ip)
 
-    def routers(self):
-        routers = self.provider.vpc_conn.get_all_internet_gateways()
-        return [AWSRouter(self.provider, r) for r in routers]
-
     def create_router(self, name=None):
         router = self.provider.vpc_conn.create_internet_gateway()
         cb_router = AWSRouter(self.provider, router)
@@ -793,31 +797,33 @@ class AWSSubnetService(BaseSubnetService):
 
     def __init__(self, provider):
         super(AWSSubnetService, self).__init__(provider)
+        self.iface = EC2ServiceFilter(self.provider,
+                                      'subnets', AWSSubnet)
+
+    def get(self, snid):
+        """Returns a subnet given its ID"""
+        return self.iface.get(snid, 'subnet-id')
+
+    def list(self, network=None, limit=None, marker=None):
+        """List all subnets associated with this account"""
+        network_id = network.id if isinstance(network, AWSNetwork) else network
+        return [
+            x for x in self.iface.list(limit=limit, marker=marker)
+            if not network_id or x.network_id == network_id
+        ]
 
-    def get(self, subnet_id):
-        subnets = self.provider.vpc_conn.get_all_subnets([subnet_id])
-        if subnets:
-            return AWSSubnet(self.provider, subnets[0])
-        return None
-
-    def list(self, network=None):
-        fltr = None
-        if network:
-            network_id = (network.id if isinstance(network, AWSNetwork) else
-                          network)
-            fltr = {'vpc-id': network_id}
-        subnets = self.provider.vpc_conn.get_all_subnets(filters=fltr)
-        return [AWSSubnet(self.provider, subnet) for subnet in subnets]
+    def find(self, name, limit=None, marker=None):
+        """Searches for a subnet by name"""
+        return self.iface.find(name, 'tag:Name', limit=limit, marker=marker)
 
     def create(self, network, cidr_block, name=None):
         network_id = network.id if isinstance(network, AWSNetwork) else network
-        subnet = self.provider.vpc_conn.create_subnet(network_id, cidr_block)
-        cb_subnet = AWSSubnet(self.provider, subnet)
-        if name:
-            time.sleep(2)  # The subnet does not always get created in time
-            cb_subnet.name = name
-        return cb_subnet
+        res = self.iface.create('create_subnet',
+                                VpcId=network_id,
+                                CidrBlock=cidr_block)
+        res.name = name
+        return res
 
     def delete(self, subnet):
         subnet_id = subnet.id if isinstance(subnet, AWSSubnet) else subnet
-        return self.provider.vpc_conn.delete_subnet(subnet_id=subnet_id)
+        return self.iface.delete(subnet_id, 'subnet-id')