Repository: boto/boto

Issue:
Route Tables: update describe_route_tables to support additional route types (VPC peering connection, NIC)
Routes can be created to network interfaces and VPC peering connections, however these routes are not reflected properly in the DescribeRouteTables response.

Doc here:
- http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeRouteTables.html

...however, the doc does not provide actual examples of the AWS response for these routes.

As such, I've repro'ed both route types and captured the AWS response XML here:

```
import boto, boto.vpc
conn = boto.vpc.connect_to_region('us-west-1')

vpc1 = conn.create_vpc("10.0.0.0/16");
vpc2 = conn.create_vpc("11.0.0.0/16");
route_table1 = conn.get_all_route_tables(filters={'association.main':'true','vpc-id':vpc1.id})[0]

# PCX route
vpc_pcx = conn.create_vpc_peering_connection(vpc1.id, vpc2.id)
conn.create_route(route_table1.id, "11.0.0.0/16", vpc_peering_connection_id=vpc_pcx.id)

# NIC route
subnet = conn.create_subnet(vpc1.id, "10.0.0.0/18")
eni = conn.create_network_interface(subnet.id)
conn.create_route(route_table1.id, "10.0.0.0/15", interface_id=eni.id)

# Describe route table
In [21]: route_table1 = conn.get_all_route_tables(filters={'association.main':'true','vpc-id':vpc1.id})[0]
2014-09-09 23:11:07,715 boto [DEBUG]:Method: GET
2014-09-09 23:11:07,715 boto [DEBUG]:Path: /
2014-09-09 23:11:07,715 boto [DEBUG]:Data: 
2014-09-09 23:11:07,715 boto [DEBUG]:Headers: {}
2014-09-09 23:11:07,715 boto [DEBUG]:Host: ec2.us-west-1.amazonaws.com
2014-09-09 23:11:07,716 boto [DEBUG]:Port: 443
2014-09-09 23:11:07,716 boto [DEBUG]:Params: {'Filter.1.Name': 'association.main', 'Filter.2.Value.1': u'vpc-3f658b5a', 'Action': 'DescribeRouteTables', 'Version': '2014-05-01', 'Filter.2.Name': 'vpc-id', 'Filter.1.Value.1': 'true'}
2014-09-09 23:11:07,716 boto [DEBUG]:Token: None
2014-09-09 23:11:07,717 boto [DEBUG]:using _calc_signature_2
2014-09-09 23:11:07,717 boto [DEBUG]:query string: AWSAccessKeyId=AKIAI7ZA6HB42ZXF3LOA&Action=DescribeRouteTables&Filter.1.Name=association.main&Filter.1.Value.1=true&Filter.2.Name=vpc-id&Filter.2.Value.1=vpc-3f658b5a&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2014-09-09T23%3A11%3A07Z&Version=2014-05-01
2014-09-09 23:11:07,718 boto [DEBUG]:string_to_sign: GET
ec2.us-west-1.amazonaws.com
/
AWSAccessKeyId=AKIAI7ZA6HB42ZXF3LOA&Action=DescribeRouteTables&Filter.1.Name=association.main&Filter.1.Value.1=true&Filter.2.Name=vpc-id&Filter.2.Value.1=vpc-3f658b5a&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2014-09-09T23%3A11%3A07Z&Version=2014-05-01
2014-09-09 23:11:07,718 boto [DEBUG]:len(b64)=44
2014-09-09 23:11:07,718 boto [DEBUG]:base64 encoded digest: qAcNssrx85LkIJIUymuvM7dB1v527ogS8PGrsicg1f4=
2014-09-09 23:11:07,718 boto [DEBUG]:query_string: AWSAccessKeyId=AKIAI7ZA6HB42ZXF3LOA&Action=DescribeRouteTables&Filter.1.Name=association.main&Filter.1.Value.1=true&Filter.2.Name=vpc-id&Filter.2.Value.1=vpc-3f658b5a&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2014-09-09T23%3A11%3A07Z&Version=2014-05-01 Signature: qAcNssrx85LkIJIUymuvM7dB1v527ogS8PGrsicg1f4=
2014-09-09 23:11:07,718 boto [DEBUG]:Final headers: {'Content-Length': 0, 'Host': 'ec2.us-west-1.amazonaws.com', 'User-Agent': 'Boto/2.32.1 Python/2.6.5 Linux/2.6.32-45-server'}
2014-09-09 23:11:07,840 boto [DEBUG]:Response headers: [('transfer-encoding', 'chunked'), ('vary', 'Accept-Encoding'), ('server', 'AmazonEC2'), ('content-type', 'text/xml;charset=UTF-8'), ('date', 'Tue, 09 Sep 2014 23:11:07 GMT')]
2014-09-09 23:11:07,840 boto [DEBUG]:<?xml version="1.0" encoding="UTF-8"?>
<DescribeRouteTablesResponse xmlns="http://ec2.amazonaws.com/doc/2014-05-01/">
    <requestId>e22ff1da-fb06-4e0f-bda6-8555c18f0af6</requestId>
    <routeTableSet>
        <item>
            <routeTableId>rtb-a754bcc2</routeTableId>
            <vpcId>vpc-3f658b5a</vpcId>
            <routeSet>
                <item>
                    <destinationCidrBlock>10.0.0.0/16</destinationCidrBlock>
                    <gatewayId>local</gatewayId>
                    <state>active</state>
                    <origin>CreateRouteTable</origin>
                </item>
                <item>
                    <destinationCidrBlock>11.0.0.0/16</destinationCidrBlock>
                    <vpcPeeringConnectionId>pcx-efc52b86</vpcPeeringConnectionId>
                    <state>blackhole</state>
                    <origin>CreateRoute</origin>
                </item>
                <item>
                    <destinationCidrBlock>10.0.0.0/15</destinationCidrBlock>
                    <networkInterfaceId>eni-884ec1d1</networkInterfaceId>
                    <state>blackhole</state>
                    <origin>CreateRoute</origin>
                </item>
            </routeSet>
            <associationSet>
                <item>
                    <routeTableAssociationId>rtbassoc-111ef574</routeTableAssociationId>
                    <routeTableId>rtb-a754bcc2</routeTableId>
                    <main>true</main>
                </item>
            </associationSet>
            <propagatingVgwSet/>
            <tagSet/>
        </item>
    </routeTableSet>
</DescribeRouteTablesResponse>
```



Discussion:

Resolving patch:
diff --git a/boto/vpc/routetable.py b/boto/vpc/routetable.py
--- a/boto/vpc/routetable.py
+++ b/boto/vpc/routetable.py
@@ -67,6 +67,8 @@ def __init__(self, connection=None):
         self.destination_cidr_block = None
         self.gateway_id = None
         self.instance_id = None
+        self.interface_id = None
+        self.vpc_peering_connection_id = None
         self.state = None
 
     def __repr__(self):
@@ -82,6 +84,10 @@ def endElement(self, name, value, connection):
             self.gateway_id = value
         elif name == 'instanceId':
             self.instance_id = value
+        elif name == 'networkInterfaceId':
+            self.interface_id = value
+        elif name == 'vpcPeeringConnectionId':
+            self.vpc_peering_connection_id = value
         elif name == 'state':
             self.state = value
 


Test patch:
diff --git a/tests/unit/vpc/test_routetable.py b/tests/unit/vpc/test_routetable.py
--- a/tests/unit/vpc/test_routetable.py
+++ b/tests/unit/vpc/test_routetable.py
@@ -48,6 +48,18 @@ def default_body(self):
                            <gatewayId>igw-eaad4883</gatewayId>
                            <state>active</state>
                         </item>
+                        <item>
+                            <destinationCidrBlock>10.0.0.0/21</destinationCidrBlock>
+                            <networkInterfaceId>eni-884ec1d1</networkInterfaceId>
+                            <state>blackhole</state>
+                            <origin>CreateRoute</origin>
+                        </item>
+                        <item>
+                            <destinationCidrBlock>11.0.0.0/22</destinationCidrBlock>
+                            <vpcPeeringConnectionId>pcx-efc52b86</vpcPeeringConnectionId>
+                            <state>blackhole</state>
+                            <origin>CreateRoute</origin>
+                        </item>
                      </routeSet>
                      <associationSet>
                         <item>
@@ -88,13 +100,19 @@ def test_get_all_route_tables(self):
         self.assertIsNone(api_response[0].associations[0].subnet_id)
         self.assertEquals(api_response[0].associations[0].main, True)
         self.assertEquals(api_response[1].id, 'rtb-f9ad4890')
-        self.assertEquals(len(api_response[1].routes), 2)
+        self.assertEquals(len(api_response[1].routes), 4)
         self.assertEquals(api_response[1].routes[0].destination_cidr_block, '10.0.0.0/22')
         self.assertEquals(api_response[1].routes[0].gateway_id, 'local')
         self.assertEquals(api_response[1].routes[0].state, 'active')
         self.assertEquals(api_response[1].routes[1].destination_cidr_block, '0.0.0.0/0')
         self.assertEquals(api_response[1].routes[1].gateway_id, 'igw-eaad4883')
         self.assertEquals(api_response[1].routes[1].state, 'active')
+        self.assertEquals(api_response[1].routes[2].destination_cidr_block, '10.0.0.0/21')
+        self.assertEquals(api_response[1].routes[2].interface_id, 'eni-884ec1d1')
+        self.assertEquals(api_response[1].routes[2].state, 'blackhole')
+        self.assertEquals(api_response[1].routes[3].destination_cidr_block, '11.0.0.0/22')
+        self.assertEquals(api_response[1].routes[3].vpc_peering_connection_id, 'pcx-efc52b86')
+        self.assertEquals(api_response[1].routes[3].state, 'blackhole')
         self.assertEquals(len(api_response[1].associations), 1)
         self.assertEquals(api_response[1].associations[0].id, 'rtbassoc-faad4893')
         self.assertEquals(api_response[1].associations[0].route_table_id, 'rtb-f9ad4890')