1# Copyright (c) 2009 Mitch Garnaat http://garnaat.org/
2#
3# Permission is hereby granted, free of charge, to any person obtaining a
4# copy of this software and associated documentation files (the
5# "Software"), to deal in the Software without restriction, including
6# without limitation the rights to use, copy, modify, merge, publish, dis-
7# tribute, sublicense, and/or sell copies of the Software, and to permit
8# persons to whom the Software is furnished to do so, subject to the fol-
9# lowing conditions:
10#
11# The above copyright notice and this permission notice shall be included
12# in all copies or substantial portions of the Software.
13#
14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20# IN THE SOFTWARE.
21
22"""
23Represents a connection to the EC2 service.
24"""
25
26from boto.ec2.connection import EC2Connection
27from boto.resultset import ResultSet
28from boto.vpc.vpc import VPC
29from boto.vpc.customergateway import CustomerGateway
30from boto.vpc.networkacl import NetworkAcl
31from boto.vpc.routetable import RouteTable
32from boto.vpc.internetgateway import InternetGateway
33from boto.vpc.vpngateway import VpnGateway, Attachment
34from boto.vpc.dhcpoptions import DhcpOptions
35from boto.vpc.subnet import Subnet
36from boto.vpc.vpnconnection import VpnConnection
37from boto.vpc.vpc_peering_connection import VpcPeeringConnection
38from boto.ec2 import RegionData
39from boto.regioninfo import RegionInfo, get_regions
40
41
42def regions(**kw_params):
43    """
44    Get all available regions for the EC2 service.
45    You may pass any of the arguments accepted by the VPCConnection
46    object's constructor as keyword arguments and they will be
47    passed along to the VPCConnection object.
48
49    :rtype: list
50    :return: A list of :class:`boto.ec2.regioninfo.RegionInfo`
51    """
52    return get_regions('ec2', connection_cls=VPCConnection)
53
54
55def connect_to_region(region_name, **kw_params):
56    """
57    Given a valid region name, return a
58    :class:`boto.vpc.VPCConnection`.
59    Any additional parameters after the region_name are passed on to
60    the connect method of the region object.
61
62    :type: str
63    :param region_name: The name of the region to connect to.
64
65    :rtype: :class:`boto.vpc.VPCConnection` or ``None``
66    :return: A connection to the given region, or None if an invalid region
67             name is given
68    """
69    for region in regions(**kw_params):
70        if region.name == region_name:
71            return region.connect(**kw_params)
72    return None
73
74
75class VPCConnection(EC2Connection):
76
77    # VPC methods
78
79    def get_all_vpcs(self, vpc_ids=None, filters=None, dry_run=False):
80        """
81        Retrieve information about your VPCs.  You can filter results to
82        return information only about those VPCs that match your search
83        parameters.  Otherwise, all VPCs associated with your account
84        are returned.
85
86        :type vpc_ids: list
87        :param vpc_ids: A list of strings with the desired VPC ID's
88
89        :type filters: list of tuples or dict
90        :param filters: A list of tuples or dict containing filters.  Each tuple
91            or dict item consists of a filter key and a filter value.
92            Possible filter keys are:
93
94            * *state* - a list of states of the VPC (pending or available)
95            * *cidrBlock* - a list CIDR blocks of the VPC
96            * *dhcpOptionsId* - a list of IDs of a set of DHCP options
97
98        :type dry_run: bool
99        :param dry_run: Set to True if the operation should not actually run.
100
101        :rtype: list
102        :return: A list of :class:`boto.vpc.vpc.VPC`
103        """
104        params = {}
105        if vpc_ids:
106            self.build_list_params(params, vpc_ids, 'VpcId')
107        if filters:
108            self.build_filter_params(params, filters)
109        if dry_run:
110            params['DryRun'] = 'true'
111        return self.get_list('DescribeVpcs', params, [('item', VPC)])
112
113    def create_vpc(self, cidr_block, instance_tenancy=None, dry_run=False):
114        """
115        Create a new Virtual Private Cloud.
116
117        :type cidr_block: str
118        :param cidr_block: A valid CIDR block
119
120        :type instance_tenancy: str
121        :param instance_tenancy: The supported tenancy options for instances
122            launched into the VPC. Valid values are 'default' and 'dedicated'.
123
124        :type dry_run: bool
125        :param dry_run: Set to True if the operation should not actually run.
126
127        :rtype: The newly created VPC
128        :return: A :class:`boto.vpc.vpc.VPC` object
129        """
130        params = {'CidrBlock': cidr_block}
131        if instance_tenancy:
132            params['InstanceTenancy'] = instance_tenancy
133        if dry_run:
134            params['DryRun'] = 'true'
135        return self.get_object('CreateVpc', params, VPC)
136
137    def delete_vpc(self, vpc_id, dry_run=False):
138        """
139        Delete a Virtual Private Cloud.
140
141        :type vpc_id: str
142        :param vpc_id: The ID of the vpc to be deleted.
143
144        :type dry_run: bool
145        :param dry_run: Set to True if the operation should not actually run.
146
147        :rtype: bool
148        :return: True if successful
149        """
150        params = {'VpcId': vpc_id}
151        if dry_run:
152            params['DryRun'] = 'true'
153        return self.get_status('DeleteVpc', params)
154
155    def modify_vpc_attribute(self, vpc_id,
156                             enable_dns_support=None,
157                             enable_dns_hostnames=None, dry_run=False):
158        """
159        Modifies the specified attribute of the specified VPC.
160        You can only modify one attribute at a time.
161
162        :type vpc_id: str
163        :param vpc_id: The ID of the vpc to be deleted.
164
165        :type enable_dns_support: bool
166        :param enable_dns_support: Specifies whether the DNS server
167            provided by Amazon is enabled for the VPC.
168
169        :type enable_dns_hostnames: bool
170        :param enable_dns_hostnames: Specifies whether DNS hostnames are
171            provided for the instances launched in this VPC. You can only
172            set this attribute to ``true`` if EnableDnsSupport
173            is also ``true``.
174
175        :type dry_run: bool
176        :param dry_run: Set to True if the operation should not actually run.
177
178        """
179        params = {'VpcId': vpc_id}
180        if enable_dns_support is not None:
181            if enable_dns_support:
182                params['EnableDnsSupport.Value'] = 'true'
183            else:
184                params['EnableDnsSupport.Value'] = 'false'
185        if enable_dns_hostnames is not None:
186            if enable_dns_hostnames:
187                params['EnableDnsHostnames.Value'] = 'true'
188            else:
189                params['EnableDnsHostnames.Value'] = 'false'
190        if dry_run:
191            params['DryRun'] = 'true'
192        return self.get_status('ModifyVpcAttribute', params)
193
194    # Route Tables
195
196    def get_all_route_tables(self, route_table_ids=None, filters=None,
197                             dry_run=False):
198        """
199        Retrieve information about your routing tables. You can filter results
200        to return information only about those route tables that match your
201        search parameters. Otherwise, all route tables associated with your
202        account are returned.
203
204        :type route_table_ids: list
205        :param route_table_ids: A list of strings with the desired route table
206                                IDs.
207
208        :type filters: list of tuples or dict
209        :param filters: A list of tuples or dict containing filters. Each tuple
210                        or dict item consists of a filter key and a filter value.
211
212        :type dry_run: bool
213        :param dry_run: Set to True if the operation should not actually run.
214
215        :rtype: list
216        :return: A list of :class:`boto.vpc.routetable.RouteTable`
217        """
218        params = {}
219        if route_table_ids:
220            self.build_list_params(params, route_table_ids, "RouteTableId")
221        if filters:
222            self.build_filter_params(params, filters)
223        if dry_run:
224            params['DryRun'] = 'true'
225        return self.get_list('DescribeRouteTables', params,
226                             [('item', RouteTable)])
227
228    def associate_route_table(self, route_table_id, subnet_id, dry_run=False):
229        """
230        Associates a route table with a specific subnet.
231
232        :type route_table_id: str
233        :param route_table_id: The ID of the route table to associate.
234
235        :type subnet_id: str
236        :param subnet_id: The ID of the subnet to associate with.
237
238        :type dry_run: bool
239        :param dry_run: Set to True if the operation should not actually run.
240
241        :rtype: str
242        :return: The ID of the association created
243        """
244        params = {
245            'RouteTableId': route_table_id,
246            'SubnetId': subnet_id
247        }
248        if dry_run:
249            params['DryRun'] = 'true'
250        result = self.get_object('AssociateRouteTable', params, ResultSet)
251        return result.associationId
252
253    def disassociate_route_table(self, association_id, dry_run=False):
254        """
255        Removes an association from a route table. This will cause all subnets
256        that would've used this association to now use the main routing
257        association instead.
258
259        :type association_id: str
260        :param association_id: The ID of the association to disassociate.
261
262        :type dry_run: bool
263        :param dry_run: Set to True if the operation should not actually run.
264
265        :rtype: bool
266        :return: True if successful
267        """
268        params = {'AssociationId': association_id}
269        if dry_run:
270            params['DryRun'] = 'true'
271        return self.get_status('DisassociateRouteTable', params)
272
273    def create_route_table(self, vpc_id, dry_run=False):
274        """
275        Creates a new route table.
276
277        :type vpc_id: str
278        :param vpc_id: The VPC ID to associate this route table with.
279
280        :type dry_run: bool
281        :param dry_run: Set to True if the operation should not actually run.
282
283        :rtype: The newly created route table
284        :return: A :class:`boto.vpc.routetable.RouteTable` object
285        """
286        params = {'VpcId': vpc_id}
287        if dry_run:
288            params['DryRun'] = 'true'
289        return self.get_object('CreateRouteTable', params, RouteTable)
290
291    def delete_route_table(self, route_table_id, dry_run=False):
292        """
293        Delete a route table.
294
295        :type route_table_id: str
296        :param route_table_id: The ID of the route table to delete.
297
298        :type dry_run: bool
299        :param dry_run: Set to True if the operation should not actually run.
300
301        :rtype: bool
302        :return: True if successful
303        """
304        params = {'RouteTableId': route_table_id}
305        if dry_run:
306            params['DryRun'] = 'true'
307        return self.get_status('DeleteRouteTable', params)
308
309    def _replace_route_table_association(self, association_id,
310                                        route_table_id, dry_run=False):
311        """
312        Helper function for replace_route_table_association and
313        replace_route_table_association_with_assoc. Should not be used directly.
314
315        :type association_id: str
316        :param association_id: The ID of the existing association to replace.
317
318        :type route_table_id: str
319        :param route_table_id: The route table to ID to be used in the
320            association.
321
322        :type dry_run: bool
323        :param dry_run: Set to True if the operation should not actually run.
324
325        :rtype: ResultSet
326        :return: ResultSet of Amazon resposne
327        """
328        params = {
329            'AssociationId': association_id,
330            'RouteTableId': route_table_id
331        }
332        if dry_run:
333            params['DryRun'] = 'true'
334        return self.get_object('ReplaceRouteTableAssociation', params,
335                               ResultSet)
336
337    def replace_route_table_assocation(self, association_id,
338                                       route_table_id, dry_run=False):
339        """
340        Replaces a route association with a new route table.  This can be
341        used to replace the 'main' route table by using the main route
342        table association instead of the more common subnet type
343        association.
344
345        NOTE: It may be better to use replace_route_table_association_with_assoc
346        instead of this function; this function does not return the new
347        association ID. This function is retained for backwards compatibility.
348
349
350        :type association_id: str
351        :param association_id: The ID of the existing association to replace.
352
353        :type route_table_id: str
354        :param route_table_id: The route table to ID to be used in the
355            association.
356
357        :type dry_run: bool
358        :param dry_run: Set to True if the operation should not actually run.
359
360        :rtype: bool
361        :return: True if successful
362        """
363        return self._replace_route_table_association(
364            association_id, route_table_id, dry_run=dry_run).status
365
366    def replace_route_table_association_with_assoc(self, association_id,
367                                                   route_table_id,
368                                                   dry_run=False):
369        """
370        Replaces a route association with a new route table.  This can be
371        used to replace the 'main' route table by using the main route
372        table association instead of the more common subnet type
373        association. Returns the new association ID.
374
375        :type association_id: str
376        :param association_id: The ID of the existing association to replace.
377
378        :type route_table_id: str
379        :param route_table_id: The route table to ID to be used in the
380            association.
381
382        :type dry_run: bool
383        :param dry_run: Set to True if the operation should not actually run.
384
385        :rtype: str
386        :return: New association ID
387        """
388        return self._replace_route_table_association(
389            association_id, route_table_id, dry_run=dry_run).newAssociationId
390
391    def create_route(self, route_table_id, destination_cidr_block,
392                     gateway_id=None, instance_id=None, interface_id=None,
393                     vpc_peering_connection_id=None,
394                     dry_run=False):
395        """
396        Creates a new route in the route table within a VPC. The route's target
397        can be either a gateway attached to the VPC or a NAT instance in the
398        VPC.
399
400        :type route_table_id: str
401        :param route_table_id: The ID of the route table for the route.
402
403        :type destination_cidr_block: str
404        :param destination_cidr_block: The CIDR address block used for the
405                                       destination match.
406
407        :type gateway_id: str
408        :param gateway_id: The ID of the gateway attached to your VPC.
409
410        :type instance_id: str
411        :param instance_id: The ID of a NAT instance in your VPC.
412
413        :type interface_id: str
414        :param interface_id: Allows routing to network interface attachments.
415
416        :type vpc_peering_connection_id: str
417        :param vpc_peering_connection_id: Allows routing to VPC peering
418                                          connection.
419
420        :type dry_run: bool
421        :param dry_run: Set to True if the operation should not actually run.
422
423        :rtype: bool
424        :return: True if successful
425        """
426        params = {
427            'RouteTableId': route_table_id,
428            'DestinationCidrBlock': destination_cidr_block
429        }
430
431        if gateway_id is not None:
432            params['GatewayId'] = gateway_id
433        elif instance_id is not None:
434            params['InstanceId'] = instance_id
435        elif interface_id is not None:
436            params['NetworkInterfaceId'] = interface_id
437        elif vpc_peering_connection_id is not None:
438            params['VpcPeeringConnectionId'] = vpc_peering_connection_id
439        if dry_run:
440            params['DryRun'] = 'true'
441
442        return self.get_status('CreateRoute', params)
443
444    def replace_route(self, route_table_id, destination_cidr_block,
445                      gateway_id=None, instance_id=None, interface_id=None,
446                      vpc_peering_connection_id=None,
447                      dry_run=False):
448        """
449        Replaces an existing route within a route table in a VPC.
450
451        :type route_table_id: str
452        :param route_table_id: The ID of the route table for the route.
453
454        :type destination_cidr_block: str
455        :param destination_cidr_block: The CIDR address block used for the
456                                       destination match.
457
458        :type gateway_id: str
459        :param gateway_id: The ID of the gateway attached to your VPC.
460
461        :type instance_id: str
462        :param instance_id: The ID of a NAT instance in your VPC.
463
464        :type interface_id: str
465        :param interface_id: Allows routing to network interface attachments.
466
467        :type vpc_peering_connection_id: str
468        :param vpc_peering_connection_id: Allows routing to VPC peering
469                                          connection.
470
471        :type dry_run: bool
472        :param dry_run: Set to True if the operation should not actually run.
473
474        :rtype: bool
475        :return: True if successful
476        """
477        params = {
478            'RouteTableId': route_table_id,
479            'DestinationCidrBlock': destination_cidr_block
480        }
481
482        if gateway_id is not None:
483            params['GatewayId'] = gateway_id
484        elif instance_id is not None:
485            params['InstanceId'] = instance_id
486        elif interface_id is not None:
487            params['NetworkInterfaceId'] = interface_id
488        elif vpc_peering_connection_id is not None:
489            params['VpcPeeringConnectionId'] = vpc_peering_connection_id
490        if dry_run:
491            params['DryRun'] = 'true'
492
493        return self.get_status('ReplaceRoute', params)
494
495    def delete_route(self, route_table_id, destination_cidr_block,
496                     dry_run=False):
497        """
498        Deletes a route from a route table within a VPC.
499
500        :type route_table_id: str
501        :param route_table_id: The ID of the route table with the route.
502
503        :type destination_cidr_block: str
504        :param destination_cidr_block: The CIDR address block used for
505                                       destination match.
506
507        :type dry_run: bool
508        :param dry_run: Set to True if the operation should not actually run.
509
510        :rtype: bool
511        :return: True if successful
512        """
513        params = {
514            'RouteTableId': route_table_id,
515            'DestinationCidrBlock': destination_cidr_block
516        }
517        if dry_run:
518            params['DryRun'] = 'true'
519        return self.get_status('DeleteRoute', params)
520
521    #Network ACLs
522
523    def get_all_network_acls(self, network_acl_ids=None, filters=None):
524        """
525        Retrieve information about your network acls. You can filter results
526        to return information only about those network acls that match your
527        search parameters. Otherwise, all network acls associated with your
528        account are returned.
529
530        :type network_acl_ids: list
531        :param network_acl_ids: A list of strings with the desired network ACL
532                                IDs.
533
534        :type filters: list of tuples or dict
535        :param filters: A list of tuples or dict containing filters. Each tuple
536                        or dict item consists of a filter key and a filter value.
537
538        :rtype: list
539        :return: A list of :class:`boto.vpc.networkacl.NetworkAcl`
540        """
541        params = {}
542        if network_acl_ids:
543            self.build_list_params(params, network_acl_ids, "NetworkAclId")
544        if filters:
545            self.build_filter_params(params, filters)
546        return self.get_list('DescribeNetworkAcls', params,
547                             [('item', NetworkAcl)])
548
549    def associate_network_acl(self, network_acl_id, subnet_id):
550        """
551        Associates a network acl with a specific subnet.
552
553        :type network_acl_id: str
554        :param network_acl_id: The ID of the network ACL to associate.
555
556        :type subnet_id: str
557        :param subnet_id: The ID of the subnet to associate with.
558
559        :rtype: str
560        :return: The ID of the association created
561        """
562
563        acl = self.get_all_network_acls(filters=[('association.subnet-id', subnet_id)])[0]
564        association = [ association for association in acl.associations if association.subnet_id == subnet_id ][0]
565
566        params = {
567            'AssociationId': association.id,
568            'NetworkAclId': network_acl_id
569        }
570
571        result = self.get_object('ReplaceNetworkAclAssociation', params, ResultSet)
572        return result.newAssociationId
573
574    def disassociate_network_acl(self, subnet_id, vpc_id=None):
575        """
576        Figures out what the default ACL is for the VPC, and associates
577        current network ACL with the default.
578
579        :type subnet_id: str
580        :param subnet_id: The ID of the subnet to which the ACL belongs.
581
582        :type vpc_id: str
583        :param vpc_id: The ID of the VPC to which the ACL/subnet belongs. Queries EC2 if omitted.
584
585        :rtype: str
586        :return: The ID of the association created
587        """
588        if not vpc_id:
589            vpc_id = self.get_all_subnets([subnet_id])[0].vpc_id
590        acls = self.get_all_network_acls(filters=[('vpc-id', vpc_id), ('default', 'true')])
591        default_acl_id = acls[0].id
592
593        return self.associate_network_acl(default_acl_id, subnet_id)
594
595    def create_network_acl(self, vpc_id):
596        """
597        Creates a new network ACL.
598
599        :type vpc_id: str
600        :param vpc_id: The VPC ID to associate this network ACL with.
601
602        :rtype: The newly created network ACL
603        :return: A :class:`boto.vpc.networkacl.NetworkAcl` object
604        """
605        params = {'VpcId': vpc_id}
606        return self.get_object('CreateNetworkAcl', params, NetworkAcl)
607
608    def delete_network_acl(self, network_acl_id):
609        """
610        Delete a network ACL
611
612        :type network_acl_id: str
613        :param network_acl_id: The ID of the network_acl to delete.
614
615        :rtype: bool
616        :return: True if successful
617        """
618        params = {'NetworkAclId': network_acl_id}
619        return self.get_status('DeleteNetworkAcl', params)
620
621    def create_network_acl_entry(self, network_acl_id, rule_number, protocol, rule_action,
622                                 cidr_block, egress=None, icmp_code=None, icmp_type=None,
623                                 port_range_from=None, port_range_to=None):
624        """
625        Creates a new network ACL entry in a network ACL within a VPC.
626
627        :type network_acl_id: str
628        :param network_acl_id: The ID of the network ACL for this network ACL entry.
629
630        :type rule_number: int
631        :param rule_number: The rule number to assign to the entry (for example, 100).
632
633        :type protocol: int
634        :param protocol: Valid values: -1 or a protocol number
635        (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)
636
637        :type rule_action: str
638        :param rule_action: Indicates whether to allow or deny traffic that matches the rule.
639
640        :type cidr_block: str
641        :param cidr_block: The CIDR range to allow or deny, in CIDR notation (for example,
642        172.16.0.0/24).
643
644        :type egress: bool
645        :param egress: Indicates whether this rule applies to egress traffic from the subnet (true)
646        or ingress traffic to the subnet (false).
647
648        :type icmp_type: int
649        :param icmp_type: For the ICMP protocol, the ICMP type. You can use -1 to specify
650         all ICMP types.
651
652        :type icmp_code: int
653        :param icmp_code: For the ICMP protocol, the ICMP code. You can use -1 to specify
654        all ICMP codes for the given ICMP type.
655
656        :type port_range_from: int
657        :param port_range_from: The first port in the range.
658
659        :type port_range_to: int
660        :param port_range_to: The last port in the range.
661
662
663        :rtype: bool
664        :return: True if successful
665        """
666        params = {
667            'NetworkAclId': network_acl_id,
668            'RuleNumber': rule_number,
669            'Protocol': protocol,
670            'RuleAction': rule_action,
671            'CidrBlock': cidr_block
672        }
673
674        if egress is not None:
675            if isinstance(egress, bool):
676                egress = str(egress).lower()
677            params['Egress'] = egress
678        if icmp_code is not None:
679            params['Icmp.Code'] = icmp_code
680        if icmp_type is not None:
681            params['Icmp.Type'] = icmp_type
682        if port_range_from is not None:
683            params['PortRange.From'] = port_range_from
684        if port_range_to is not None:
685            params['PortRange.To'] = port_range_to
686
687        return self.get_status('CreateNetworkAclEntry', params)
688
689    def replace_network_acl_entry(self, network_acl_id, rule_number, protocol, rule_action,
690                                  cidr_block, egress=None, icmp_code=None, icmp_type=None,
691                                  port_range_from=None, port_range_to=None):
692        """
693        Creates a new network ACL entry in a network ACL within a VPC.
694
695        :type network_acl_id: str
696        :param network_acl_id: The ID of the network ACL for the id you want to replace
697
698        :type rule_number: int
699        :param rule_number: The rule number that you want to replace(for example, 100).
700
701        :type protocol: int
702        :param protocol: Valid values: -1 or a protocol number
703        (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)
704
705        :type rule_action: str
706        :param rule_action: Indicates whether to allow or deny traffic that matches the rule.
707
708        :type cidr_block: str
709        :param cidr_block: The CIDR range to allow or deny, in CIDR notation (for example,
710        172.16.0.0/24).
711
712        :type egress: bool
713        :param egress: Indicates whether this rule applies to egress traffic from the subnet (true)
714        or ingress traffic to the subnet (false).
715
716        :type icmp_type: int
717        :param icmp_type: For the ICMP protocol, the ICMP type. You can use -1 to specify
718         all ICMP types.
719
720        :type icmp_code: int
721        :param icmp_code: For the ICMP protocol, the ICMP code. You can use -1 to specify
722        all ICMP codes for the given ICMP type.
723
724        :type port_range_from: int
725        :param port_range_from: The first port in the range.
726
727        :type port_range_to: int
728        :param port_range_to: The last port in the range.
729
730
731        :rtype: bool
732        :return: True if successful
733        """
734        params = {
735            'NetworkAclId': network_acl_id,
736            'RuleNumber': rule_number,
737            'Protocol': protocol,
738            'RuleAction': rule_action,
739            'CidrBlock': cidr_block
740        }
741
742        if egress is not None:
743            if isinstance(egress, bool):
744                egress = str(egress).lower()
745            params['Egress'] = egress
746        if icmp_code is not None:
747            params['Icmp.Code'] = icmp_code
748        if icmp_type is not None:
749            params['Icmp.Type'] = icmp_type
750        if port_range_from is not None:
751            params['PortRange.From'] = port_range_from
752        if port_range_to is not None:
753            params['PortRange.To'] = port_range_to
754
755        return self.get_status('ReplaceNetworkAclEntry', params)
756
757    def delete_network_acl_entry(self, network_acl_id, rule_number, egress=None):
758        """
759        Deletes a network ACL entry from a network ACL within a VPC.
760
761        :type network_acl_id: str
762        :param network_acl_id: The ID of the network ACL with the network ACL entry.
763
764        :type rule_number: int
765        :param rule_number: The rule number for the entry to delete.
766
767        :type egress: bool
768        :param egress: Specifies whether the rule to delete is an egress rule (true)
769        or ingress rule (false).
770
771        :rtype: bool
772        :return: True if successful
773        """
774        params = {
775            'NetworkAclId': network_acl_id,
776            'RuleNumber': rule_number
777        }
778
779        if egress is not None:
780            if isinstance(egress, bool):
781                egress = str(egress).lower()
782            params['Egress'] = egress
783
784        return self.get_status('DeleteNetworkAclEntry', params)
785
786    # Internet Gateways
787
788    def get_all_internet_gateways(self, internet_gateway_ids=None,
789                                  filters=None, dry_run=False):
790        """
791        Get a list of internet gateways. You can filter results to return information
792        about only those gateways that you're interested in.
793
794        :type internet_gateway_ids: list
795        :param internet_gateway_ids: A list of strings with the desired gateway IDs.
796
797        :type filters: list of tuples or dict
798        :param filters: A list of tuples or dict containing filters.  Each tuple
799                        or dict item consists of a filter key and a filter value.
800
801        :type dry_run: bool
802        :param dry_run: Set to True if the operation should not actually run.
803
804        """
805        params = {}
806
807        if internet_gateway_ids:
808            self.build_list_params(params, internet_gateway_ids,
809                                   'InternetGatewayId')
810        if filters:
811            self.build_filter_params(params, filters)
812        if dry_run:
813            params['DryRun'] = 'true'
814        return self.get_list('DescribeInternetGateways', params,
815                             [('item', InternetGateway)])
816
817    def create_internet_gateway(self, dry_run=False):
818        """
819        Creates an internet gateway for VPC.
820
821        :type dry_run: bool
822        :param dry_run: Set to True if the operation should not actually run.
823
824        :rtype: Newly created internet gateway.
825        :return: `boto.vpc.internetgateway.InternetGateway`
826        """
827        params = {}
828        if dry_run:
829            params['DryRun'] = 'true'
830        return self.get_object('CreateInternetGateway', params, InternetGateway)
831
832    def delete_internet_gateway(self, internet_gateway_id, dry_run=False):
833        """
834        Deletes an internet gateway from the VPC.
835
836        :type internet_gateway_id: str
837        :param internet_gateway_id: The ID of the internet gateway to delete.
838
839        :type dry_run: bool
840        :param dry_run: Set to True if the operation should not actually run.
841
842        :rtype: Bool
843        :return: True if successful
844        """
845        params = {'InternetGatewayId': internet_gateway_id}
846        if dry_run:
847            params['DryRun'] = 'true'
848        return self.get_status('DeleteInternetGateway', params)
849
850    def attach_internet_gateway(self, internet_gateway_id, vpc_id,
851                                dry_run=False):
852        """
853        Attach an internet gateway to a specific VPC.
854
855        :type internet_gateway_id: str
856        :param internet_gateway_id: The ID of the internet gateway to attach.
857
858        :type vpc_id: str
859        :param vpc_id: The ID of the VPC to attach to.
860
861        :type dry_run: bool
862        :param dry_run: Set to True if the operation should not actually run.
863
864        :rtype: Bool
865        :return: True if successful
866        """
867        params = {
868            'InternetGatewayId': internet_gateway_id,
869            'VpcId': vpc_id
870        }
871        if dry_run:
872            params['DryRun'] = 'true'
873        return self.get_status('AttachInternetGateway', params)
874
875    def detach_internet_gateway(self, internet_gateway_id, vpc_id,
876                                dry_run=False):
877        """
878        Detach an internet gateway from a specific VPC.
879
880        :type internet_gateway_id: str
881        :param internet_gateway_id: The ID of the internet gateway to detach.
882
883        :type vpc_id: str
884        :param vpc_id: The ID of the VPC to attach to.
885
886        :type dry_run: bool
887        :param dry_run: Set to True if the operation should not actually run.
888
889        :rtype: Bool
890        :return: True if successful
891        """
892        params = {
893            'InternetGatewayId': internet_gateway_id,
894            'VpcId': vpc_id
895        }
896        if dry_run:
897            params['DryRun'] = 'true'
898        return self.get_status('DetachInternetGateway', params)
899
900    # Customer Gateways
901
902    def get_all_customer_gateways(self, customer_gateway_ids=None,
903                                  filters=None, dry_run=False):
904        """
905        Retrieve information about your CustomerGateways.  You can filter
906        results to return information only about those CustomerGateways that
907        match your search parameters.  Otherwise, all CustomerGateways
908        associated with your account are returned.
909
910        :type customer_gateway_ids: list
911        :param customer_gateway_ids: A list of strings with the desired
912            CustomerGateway ID's.
913
914        :type filters: list of tuples or dict
915        :param filters: A list of tuples or dict containing filters.  Each tuple
916                        or dict item consists of a filter key and a filter value.
917                        Possible filter keys are:
918
919                         - *state*, the state of the CustomerGateway
920                           (pending,available,deleting,deleted)
921                         - *type*, the type of customer gateway (ipsec.1)
922                         - *ipAddress* the IP address of customer gateway's
923                           internet-routable external inteface
924
925        :type dry_run: bool
926        :param dry_run: Set to True if the operation should not actually run.
927
928        :rtype: list
929        :return: A list of :class:`boto.vpc.customergateway.CustomerGateway`
930        """
931        params = {}
932        if customer_gateway_ids:
933            self.build_list_params(params, customer_gateway_ids,
934                                   'CustomerGatewayId')
935        if filters:
936            self.build_filter_params(params, filters)
937
938        if dry_run:
939            params['DryRun'] = 'true'
940
941        return self.get_list('DescribeCustomerGateways', params,
942                             [('item', CustomerGateway)])
943
944    def create_customer_gateway(self, type, ip_address, bgp_asn, dry_run=False):
945        """
946        Create a new Customer Gateway
947
948        :type type: str
949        :param type: Type of VPN Connection.  Only valid value currently is 'ipsec.1'
950
951        :type ip_address: str
952        :param ip_address: Internet-routable IP address for customer's gateway.
953                           Must be a static address.
954
955        :type bgp_asn: int
956        :param bgp_asn: Customer gateway's Border Gateway Protocol (BGP)
957                        Autonomous System Number (ASN)
958
959        :type dry_run: bool
960        :param dry_run: Set to True if the operation should not actually run.
961
962        :rtype: The newly created CustomerGateway
963        :return: A :class:`boto.vpc.customergateway.CustomerGateway` object
964        """
965        params = {'Type': type,
966                  'IpAddress': ip_address,
967                  'BgpAsn': bgp_asn}
968        if dry_run:
969            params['DryRun'] = 'true'
970        return self.get_object('CreateCustomerGateway', params, CustomerGateway)
971
972    def delete_customer_gateway(self, customer_gateway_id, dry_run=False):
973        """
974        Delete a Customer Gateway.
975
976        :type customer_gateway_id: str
977        :param customer_gateway_id: The ID of the customer_gateway to be deleted.
978
979        :type dry_run: bool
980        :param dry_run: Set to True if the operation should not actually run.
981
982        :rtype: bool
983        :return: True if successful
984        """
985        params = {'CustomerGatewayId': customer_gateway_id}
986        if dry_run:
987            params['DryRun'] = 'true'
988        return self.get_status('DeleteCustomerGateway', params)
989
990    # VPN Gateways
991
992    def get_all_vpn_gateways(self, vpn_gateway_ids=None, filters=None,
993                             dry_run=False):
994        """
995        Retrieve information about your VpnGateways.  You can filter results to
996        return information only about those VpnGateways that match your search
997        parameters.  Otherwise, all VpnGateways associated with your account
998        are returned.
999
1000        :type vpn_gateway_ids: list
1001        :param vpn_gateway_ids: A list of strings with the desired VpnGateway ID's
1002
1003        :type filters: list of tuples or dict
1004        :param filters: A list of tuples or dict containing filters.  Each tuple
1005                        or dict item consists of a filter key and a filter value.
1006                        Possible filter keys are:
1007
1008                        - *state*, a list of states of the VpnGateway
1009                          (pending,available,deleting,deleted)
1010                        - *type*, a list types of customer gateway (ipsec.1)
1011                        - *availabilityZone*, a list of  Availability zones the
1012                          VPN gateway is in.
1013
1014        :type dry_run: bool
1015        :param dry_run: Set to True if the operation should not actually run.
1016
1017        :rtype: list
1018        :return: A list of :class:`boto.vpc.customergateway.VpnGateway`
1019        """
1020        params = {}
1021        if vpn_gateway_ids:
1022            self.build_list_params(params, vpn_gateway_ids, 'VpnGatewayId')
1023        if filters:
1024            self.build_filter_params(params, filters)
1025        if dry_run:
1026            params['DryRun'] = 'true'
1027        return self.get_list('DescribeVpnGateways', params,
1028                             [('item', VpnGateway)])
1029
1030    def create_vpn_gateway(self, type, availability_zone=None, dry_run=False):
1031        """
1032        Create a new Vpn Gateway
1033
1034        :type type: str
1035        :param type: Type of VPN Connection.  Only valid value currently is 'ipsec.1'
1036
1037        :type availability_zone: str
1038        :param availability_zone: The Availability Zone where you want the VPN gateway.
1039
1040        :type dry_run: bool
1041        :param dry_run: Set to True if the operation should not actually run.
1042
1043        :rtype: The newly created VpnGateway
1044        :return: A :class:`boto.vpc.vpngateway.VpnGateway` object
1045        """
1046        params = {'Type': type}
1047        if availability_zone:
1048            params['AvailabilityZone'] = availability_zone
1049        if dry_run:
1050            params['DryRun'] = 'true'
1051        return self.get_object('CreateVpnGateway', params, VpnGateway)
1052
1053    def delete_vpn_gateway(self, vpn_gateway_id, dry_run=False):
1054        """
1055        Delete a Vpn Gateway.
1056
1057        :type vpn_gateway_id: str
1058        :param vpn_gateway_id: The ID of the vpn_gateway to be deleted.
1059
1060        :type dry_run: bool
1061        :param dry_run: Set to True if the operation should not actually run.
1062
1063        :rtype: bool
1064        :return: True if successful
1065        """
1066        params = {'VpnGatewayId': vpn_gateway_id}
1067        if dry_run:
1068            params['DryRun'] = 'true'
1069        return self.get_status('DeleteVpnGateway', params)
1070
1071    def attach_vpn_gateway(self, vpn_gateway_id, vpc_id, dry_run=False):
1072        """
1073        Attaches a VPN gateway to a VPC.
1074
1075        :type vpn_gateway_id: str
1076        :param vpn_gateway_id: The ID of the vpn_gateway to attach
1077
1078        :type vpc_id: str
1079        :param vpc_id: The ID of the VPC you want to attach the gateway to.
1080
1081        :type dry_run: bool
1082        :param dry_run: Set to True if the operation should not actually run.
1083
1084        :rtype: An attachment
1085        :return: a :class:`boto.vpc.vpngateway.Attachment`
1086        """
1087        params = {'VpnGatewayId': vpn_gateway_id,
1088                  'VpcId': vpc_id}
1089        if dry_run:
1090            params['DryRun'] = 'true'
1091        return self.get_object('AttachVpnGateway', params, Attachment)
1092
1093    def detach_vpn_gateway(self, vpn_gateway_id, vpc_id, dry_run=False):
1094        """
1095        Detaches a VPN gateway from a VPC.
1096
1097        :type vpn_gateway_id: str
1098        :param vpn_gateway_id: The ID of the vpn_gateway to detach
1099
1100        :type vpc_id: str
1101        :param vpc_id: The ID of the VPC you want to detach the gateway from.
1102
1103        :type dry_run: bool
1104        :param dry_run: Set to True if the operation should not actually run.
1105
1106        :rtype: bool
1107        :return: True if successful
1108        """
1109        params = {'VpnGatewayId': vpn_gateway_id,
1110                  'VpcId': vpc_id}
1111        if dry_run:
1112            params['DryRun'] = 'true'
1113        return self.get_status('DetachVpnGateway', params)
1114
1115    # Subnets
1116
1117    def get_all_subnets(self, subnet_ids=None, filters=None, dry_run=False):
1118        """
1119        Retrieve information about your Subnets.  You can filter results to
1120        return information only about those Subnets that match your search
1121        parameters.  Otherwise, all Subnets associated with your account
1122        are returned.
1123
1124        :type subnet_ids: list
1125        :param subnet_ids: A list of strings with the desired Subnet ID's
1126
1127        :type filters: list of tuples or dict
1128        :param filters: A list of tuples or dict containing filters.  Each tuple
1129                        or dict item consists of a filter key and a filter value.
1130                        Possible filter keys are:
1131
1132                        - *state*, a list of states of the Subnet
1133                          (pending,available)
1134                        - *vpcId*, a list of IDs of the VPC that the subnet is in.
1135                        - *cidrBlock*, a list of CIDR blocks of the subnet
1136                        - *availabilityZone*, list of the Availability Zones
1137                          the subnet is in.
1138
1139
1140        :type dry_run: bool
1141        :param dry_run: Set to True if the operation should not actually run.
1142
1143        :rtype: list
1144        :return: A list of :class:`boto.vpc.subnet.Subnet`
1145        """
1146        params = {}
1147        if subnet_ids:
1148            self.build_list_params(params, subnet_ids, 'SubnetId')
1149        if filters:
1150            self.build_filter_params(params, filters)
1151        if dry_run:
1152            params['DryRun'] = 'true'
1153        return self.get_list('DescribeSubnets', params, [('item', Subnet)])
1154
1155    def create_subnet(self, vpc_id, cidr_block, availability_zone=None,
1156                      dry_run=False):
1157        """
1158        Create a new Subnet
1159
1160        :type vpc_id: str
1161        :param vpc_id: The ID of the VPC where you want to create the subnet.
1162
1163        :type cidr_block: str
1164        :param cidr_block: The CIDR block you want the subnet to cover.
1165
1166        :type availability_zone: str
1167        :param availability_zone: The AZ you want the subnet in
1168
1169        :type dry_run: bool
1170        :param dry_run: Set to True if the operation should not actually run.
1171
1172        :rtype: The newly created Subnet
1173        :return: A :class:`boto.vpc.customergateway.Subnet` object
1174        """
1175        params = {'VpcId': vpc_id,
1176                  'CidrBlock': cidr_block}
1177        if availability_zone:
1178            params['AvailabilityZone'] = availability_zone
1179        if dry_run:
1180            params['DryRun'] = 'true'
1181        return self.get_object('CreateSubnet', params, Subnet)
1182
1183    def delete_subnet(self, subnet_id, dry_run=False):
1184        """
1185        Delete a subnet.
1186
1187        :type subnet_id: str
1188        :param subnet_id: The ID of the subnet to be deleted.
1189
1190        :type dry_run: bool
1191        :param dry_run: Set to True if the operation should not actually run.
1192
1193        :rtype: bool
1194        :return: True if successful
1195        """
1196        params = {'SubnetId': subnet_id}
1197        if dry_run:
1198            params['DryRun'] = 'true'
1199        return self.get_status('DeleteSubnet', params)
1200
1201    # DHCP Options
1202
1203    def get_all_dhcp_options(self, dhcp_options_ids=None, filters=None, dry_run=False):
1204        """
1205        Retrieve information about your DhcpOptions.
1206
1207        :type dhcp_options_ids: list
1208        :param dhcp_options_ids: A list of strings with the desired DhcpOption ID's
1209
1210        :type filters: list of tuples or dict
1211        :param filters: A list of tuples or dict containing filters.  Each tuple
1212            or dict item consists of a filter key and a filter value.
1213
1214        :type dry_run: bool
1215        :param dry_run: Set to True if the operation should not actually run.
1216
1217        :rtype: list
1218        :return: A list of :class:`boto.vpc.dhcpoptions.DhcpOptions`
1219        """
1220        params = {}
1221        if dhcp_options_ids:
1222            self.build_list_params(params, dhcp_options_ids, 'DhcpOptionsId')
1223        if filters:
1224            self.build_filter_params(params, filters)
1225        if dry_run:
1226            params['DryRun'] = 'true'
1227        return self.get_list('DescribeDhcpOptions', params,
1228                             [('item', DhcpOptions)])
1229
1230    def create_dhcp_options(self, domain_name=None, domain_name_servers=None,
1231                            ntp_servers=None, netbios_name_servers=None,
1232                            netbios_node_type=None, dry_run=False):
1233        """
1234        Create a new DhcpOption
1235
1236        This corresponds to
1237        http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateDhcpOptions.html
1238
1239        :type domain_name: str
1240        :param domain_name: A domain name of your choice (for example,
1241            example.com)
1242
1243        :type domain_name_servers: list of strings
1244        :param domain_name_servers: The IP address of a domain name server. You
1245            can specify up to four addresses.
1246
1247        :type ntp_servers: list of strings
1248        :param ntp_servers: The IP address of a Network Time Protocol (NTP)
1249            server. You can specify up to four addresses.
1250
1251        :type netbios_name_servers: list of strings
1252        :param netbios_name_servers: The IP address of a NetBIOS name server.
1253            You can specify up to four addresses.
1254
1255        :type netbios_node_type: str
1256        :param netbios_node_type: The NetBIOS node type (1, 2, 4, or 8). For
1257            more information about the values, see RFC 2132. We recommend you
1258            only use 2 at this time (broadcast and multicast are currently not
1259            supported).
1260
1261        :type dry_run: bool
1262        :param dry_run: Set to True if the operation should not actually run.
1263
1264        :rtype: The newly created DhcpOption
1265        :return: A :class:`boto.vpc.customergateway.DhcpOption` object
1266        """
1267
1268        key_counter = 1
1269        params = {}
1270
1271        def insert_option(params, name, value):
1272            params['DhcpConfiguration.%d.Key' % (key_counter,)] = name
1273            if isinstance(value, (list, tuple)):
1274                for idx, value in enumerate(value, 1):
1275                    key_name = 'DhcpConfiguration.%d.Value.%d' % (
1276                        key_counter, idx)
1277                    params[key_name] = value
1278            else:
1279                key_name = 'DhcpConfiguration.%d.Value.1' % (key_counter,)
1280                params[key_name] = value
1281
1282            return key_counter + 1
1283
1284        if domain_name:
1285            key_counter = insert_option(params,
1286                                        'domain-name', domain_name)
1287        if domain_name_servers:
1288            key_counter = insert_option(params,
1289                                        'domain-name-servers', domain_name_servers)
1290        if ntp_servers:
1291            key_counter = insert_option(params,
1292                                        'ntp-servers', ntp_servers)
1293        if netbios_name_servers:
1294            key_counter = insert_option(params,
1295                                        'netbios-name-servers', netbios_name_servers)
1296        if netbios_node_type:
1297            key_counter = insert_option(params,
1298                                        'netbios-node-type', netbios_node_type)
1299        if dry_run:
1300            params['DryRun'] = 'true'
1301
1302        return self.get_object('CreateDhcpOptions', params, DhcpOptions)
1303
1304    def delete_dhcp_options(self, dhcp_options_id, dry_run=False):
1305        """
1306        Delete a DHCP Options
1307
1308        :type dhcp_options_id: str
1309        :param dhcp_options_id: The ID of the DHCP Options to be deleted.
1310
1311        :type dry_run: bool
1312        :param dry_run: Set to True if the operation should not actually run.
1313
1314        :rtype: bool
1315        :return: True if successful
1316        """
1317        params = {'DhcpOptionsId': dhcp_options_id}
1318        if dry_run:
1319            params['DryRun'] = 'true'
1320        return self.get_status('DeleteDhcpOptions', params)
1321
1322    def associate_dhcp_options(self, dhcp_options_id, vpc_id, dry_run=False):
1323        """
1324        Associate a set of Dhcp Options with a VPC.
1325
1326        :type dhcp_options_id: str
1327        :param dhcp_options_id: The ID of the Dhcp Options
1328
1329        :type vpc_id: str
1330        :param vpc_id: The ID of the VPC.
1331
1332        :type dry_run: bool
1333        :param dry_run: Set to True if the operation should not actually run.
1334
1335        :rtype: bool
1336        :return: True if successful
1337        """
1338        params = {'DhcpOptionsId': dhcp_options_id,
1339                  'VpcId': vpc_id}
1340        if dry_run:
1341            params['DryRun'] = 'true'
1342        return self.get_status('AssociateDhcpOptions', params)
1343
1344    # VPN Connection
1345
1346    def get_all_vpn_connections(self, vpn_connection_ids=None, filters=None,
1347                                dry_run=False):
1348        """
1349        Retrieve information about your VPN_CONNECTIONs.  You can filter results to
1350        return information only about those VPN_CONNECTIONs that match your search
1351        parameters.  Otherwise, all VPN_CONNECTIONs associated with your account
1352        are returned.
1353
1354        :type vpn_connection_ids: list
1355        :param vpn_connection_ids: A list of strings with the desired VPN_CONNECTION ID's
1356
1357        :type filters: list of tuples or dict
1358        :param filters: A list of tuples or dict containing filters.  Each tuple
1359                        or dict item consists of a filter key and a filter value.
1360                        Possible filter keys are:
1361
1362                        - *state*, a list of states of the VPN_CONNECTION
1363                          pending,available,deleting,deleted
1364                        - *type*, a list of types of connection, currently 'ipsec.1'
1365                        - *customerGatewayId*, a list of IDs of the customer gateway
1366                          associated with the VPN
1367                        - *vpnGatewayId*, a list of IDs of the VPN gateway associated
1368                          with the VPN connection
1369
1370        :type dry_run: bool
1371        :param dry_run: Set to True if the operation should not actually run.
1372
1373        :rtype: list
1374        :return: A list of :class:`boto.vpn_connection.vpnconnection.VpnConnection`
1375        """
1376        params = {}
1377        if vpn_connection_ids:
1378            self.build_list_params(params, vpn_connection_ids,
1379                                   'VpnConnectionId')
1380        if filters:
1381            self.build_filter_params(params, filters)
1382        if dry_run:
1383            params['DryRun'] = 'true'
1384        return self.get_list('DescribeVpnConnections', params,
1385                             [('item', VpnConnection)])
1386
1387    def create_vpn_connection(self, type, customer_gateway_id, vpn_gateway_id,
1388                              static_routes_only=None, dry_run=False):
1389        """
1390        Create a new VPN Connection.
1391
1392        :type type: str
1393        :param type: The type of VPN Connection.  Currently only 'ipsec.1'
1394                     is supported
1395
1396        :type customer_gateway_id: str
1397        :param customer_gateway_id: The ID of the customer gateway.
1398
1399        :type vpn_gateway_id: str
1400        :param vpn_gateway_id: The ID of the VPN gateway.
1401
1402        :type static_routes_only: bool
1403        :param static_routes_only: Indicates whether the VPN connection
1404        requires static routes. If you are creating a VPN connection
1405        for a device that does not support BGP, you must specify true.
1406
1407        :type dry_run: bool
1408        :param dry_run: Set to True if the operation should not actually run.
1409
1410        :rtype: The newly created VpnConnection
1411        :return: A :class:`boto.vpc.vpnconnection.VpnConnection` object
1412        """
1413        params = {'Type': type,
1414                  'CustomerGatewayId': customer_gateway_id,
1415                  'VpnGatewayId': vpn_gateway_id}
1416        if static_routes_only is not None:
1417            if isinstance(static_routes_only, bool):
1418                static_routes_only = str(static_routes_only).lower()
1419            params['Options.StaticRoutesOnly'] = static_routes_only
1420        if dry_run:
1421            params['DryRun'] = 'true'
1422        return self.get_object('CreateVpnConnection', params, VpnConnection)
1423
1424    def delete_vpn_connection(self, vpn_connection_id, dry_run=False):
1425        """
1426        Delete a VPN Connection.
1427
1428        :type vpn_connection_id: str
1429        :param vpn_connection_id: The ID of the vpn_connection to be deleted.
1430
1431        :type dry_run: bool
1432        :param dry_run: Set to True if the operation should not actually run.
1433
1434        :rtype: bool
1435        :return: True if successful
1436        """
1437        params = {'VpnConnectionId': vpn_connection_id}
1438        if dry_run:
1439            params['DryRun'] = 'true'
1440        return self.get_status('DeleteVpnConnection', params)
1441
1442    def disable_vgw_route_propagation(self, route_table_id, gateway_id,
1443                                      dry_run=False):
1444        """
1445        Disables a virtual private gateway (VGW) from propagating routes to the
1446        routing tables of an Amazon VPC.
1447
1448        :type route_table_id: str
1449        :param route_table_id: The ID of the routing table.
1450
1451        :type gateway_id: str
1452        :param gateway_id: The ID of the virtual private gateway.
1453
1454        :type dry_run: bool
1455        :param dry_run: Set to True if the operation should not actually run.
1456
1457        :rtype: bool
1458        :return: True if successful
1459        """
1460        params = {
1461            'RouteTableId': route_table_id,
1462            'GatewayId': gateway_id,
1463        }
1464        if dry_run:
1465            params['DryRun'] = 'true'
1466        return self.get_status('DisableVgwRoutePropagation', params)
1467
1468    def enable_vgw_route_propagation(self, route_table_id, gateway_id,
1469                                     dry_run=False):
1470        """
1471        Enables a virtual private gateway (VGW) to propagate routes to the
1472        routing tables of an Amazon VPC.
1473
1474        :type route_table_id: str
1475        :param route_table_id: The ID of the routing table.
1476
1477        :type gateway_id: str
1478        :param gateway_id: The ID of the virtual private gateway.
1479
1480        :type dry_run: bool
1481        :param dry_run: Set to True if the operation should not actually run.
1482
1483        :rtype: bool
1484        :return: True if successful
1485        """
1486        params = {
1487            'RouteTableId': route_table_id,
1488            'GatewayId': gateway_id,
1489        }
1490        if dry_run:
1491            params['DryRun'] = 'true'
1492        return self.get_status('EnableVgwRoutePropagation', params)
1493
1494    def create_vpn_connection_route(self, destination_cidr_block,
1495                                    vpn_connection_id, dry_run=False):
1496        """
1497        Creates a new static route associated with a VPN connection between an
1498        existing virtual private gateway and a VPN customer gateway. The static
1499        route allows traffic to be routed from the virtual private gateway to
1500        the VPN customer gateway.
1501
1502        :type destination_cidr_block: str
1503        :param destination_cidr_block: The CIDR block associated with the local
1504            subnet of the customer data center.
1505
1506        :type vpn_connection_id: str
1507        :param vpn_connection_id: The ID of the VPN connection.
1508
1509        :type dry_run: bool
1510        :param dry_run: Set to True if the operation should not actually run.
1511
1512        :rtype: bool
1513        :return: True if successful
1514        """
1515        params = {
1516            'DestinationCidrBlock': destination_cidr_block,
1517            'VpnConnectionId': vpn_connection_id,
1518        }
1519        if dry_run:
1520            params['DryRun'] = 'true'
1521        return self.get_status('CreateVpnConnectionRoute', params)
1522
1523    def delete_vpn_connection_route(self, destination_cidr_block,
1524                                    vpn_connection_id, dry_run=False):
1525        """
1526        Deletes a static route associated with a VPN connection between an
1527        existing virtual private gateway and a VPN customer gateway. The static
1528        route allows traffic to be routed from the virtual private gateway to
1529        the VPN customer gateway.
1530
1531        :type destination_cidr_block: str
1532        :param destination_cidr_block: The CIDR block associated with the local
1533            subnet of the customer data center.
1534
1535        :type vpn_connection_id: str
1536        :param vpn_connection_id: The ID of the VPN connection.
1537
1538        :type dry_run: bool
1539        :param dry_run: Set to True if the operation should not actually run.
1540
1541        :rtype: bool
1542        :return: True if successful
1543        """
1544        params = {
1545            'DestinationCidrBlock': destination_cidr_block,
1546            'VpnConnectionId': vpn_connection_id,
1547        }
1548        if dry_run:
1549            params['DryRun'] = 'true'
1550        return self.get_status('DeleteVpnConnectionRoute', params)
1551
1552    def get_all_vpc_peering_connections(self, vpc_peering_connection_ids=None,
1553                                        filters=None, dry_run=False):
1554        """
1555        Retrieve information about your VPC peering connections. You
1556        can filter results to return information only about those VPC
1557        peering connections that match your search parameters.
1558        Otherwise, all VPC peering connections associated with your
1559        account are returned.
1560
1561        :type vpc_peering_connection_ids: list
1562        :param vpc_peering_connection_ids: A list of strings with the desired VPC
1563            peering connection ID's
1564
1565        :type filters: list of tuples
1566        :param filters: A list of tuples containing filters. Each tuple
1567            consists of a filter key and a filter value.
1568            Possible filter keys are:
1569
1570            * *accepter-vpc-info.cidr-block* - The CIDR block of the peer VPC.
1571            * *accepter-vpc-info.owner-id* - The AWS account ID of the owner
1572                of the peer VPC.
1573            * *accepter-vpc-info.vpc-id* - The ID of the peer VPC.
1574            * *expiration-time* - The expiration date and time for the VPC
1575                peering connection.
1576            * *requester-vpc-info.cidr-block* - The CIDR block of the
1577                requester's VPC.
1578            * *requester-vpc-info.owner-id* - The AWS account ID of the
1579                owner of the requester VPC.
1580            * *requester-vpc-info.vpc-id* - The ID of the requester VPC.
1581            * *status-code* - The status of the VPC peering connection.
1582            * *status-message* - A message that provides more information
1583                about the status of the VPC peering connection, if applicable.
1584
1585        :type dry_run: bool
1586        :param dry_run: Set to True if the operation should not actually run.
1587
1588        :rtype: list
1589        :return: A list of :class:`boto.vpc.vpc.VPC`
1590        """
1591        params = {}
1592        if vpc_peering_connection_ids:
1593            self.build_list_params(params, vpc_peering_connection_ids, 'VpcPeeringConnectionId')
1594        if filters:
1595            self.build_filter_params(params, dict(filters))
1596        if dry_run:
1597            params['DryRun'] = 'true'
1598        return self.get_list('DescribeVpcPeeringConnections', params, [('item', VpcPeeringConnection)])
1599
1600    def create_vpc_peering_connection(self, vpc_id, peer_vpc_id,
1601                                      peer_owner_id=None, dry_run=False):
1602        """
1603        Create a new VPN Peering connection.
1604
1605        :type vpc_id: str
1606        :param vpc_id: The ID of the requester VPC.
1607
1608        :type peer_vpc_id: str
1609        :param vpc_peer_id: The ID of the VPC with which you are creating the peering connection.
1610
1611        :type peer_owner_id: str
1612        :param peer_owner_id: The AWS account ID of the owner of the peer VPC.
1613
1614        :rtype: The newly created VpcPeeringConnection
1615        :return: A :class:`boto.vpc.vpc_peering_connection.VpcPeeringConnection` object
1616        """
1617        params = {'VpcId': vpc_id,
1618                  'PeerVpcId': peer_vpc_id }
1619        if peer_owner_id is not None:
1620            params['PeerOwnerId'] = peer_owner_id
1621        if dry_run:
1622            params['DryRun'] = 'true'
1623
1624        return self.get_object('CreateVpcPeeringConnection', params,
1625                               VpcPeeringConnection)
1626
1627    def delete_vpc_peering_connection(self, vpc_peering_connection_id, dry_run=False):
1628        """
1629        Deletes a VPC peering connection. Either the owner of the requester
1630        VPC or the owner of the peer VPC can delete the VPC peering connection
1631        if it's in the active state. The owner of the requester VPC can delete
1632        a VPC peering connection in the pending-acceptance state.
1633
1634        :type vpc_peering_connection_id: str
1635        :param vpc_peering_connection_id: The ID of the VPC peering connection.
1636
1637        :rtype: bool
1638        :return: True if successful
1639        """
1640        params = {
1641            'VpcPeeringConnectionId': vpc_peering_connection_id
1642        }
1643
1644        if dry_run:
1645            params['DryRun'] = 'true'
1646        return self.get_status('DeleteVpcPeeringConnection', params)
1647
1648    def reject_vpc_peering_connection(self, vpc_peering_connection_id, dry_run=False):
1649        """
1650        Rejects a VPC peering connection request. The VPC peering connection
1651        must be in the pending-acceptance state.
1652
1653        :type vpc_peering_connection_id: str
1654        :param vpc_peering_connection_id: The ID of the VPC peering connection.
1655
1656        :rtype: bool
1657        :return: True if successful
1658        """
1659        params = {
1660            'VpcPeeringConnectionId': vpc_peering_connection_id
1661        }
1662
1663        if dry_run:
1664            params['DryRun'] = 'true'
1665        return self.get_status('RejectVpcPeeringConnection', params)
1666
1667    def accept_vpc_peering_connection(self, vpc_peering_connection_id, dry_run=False):
1668        """
1669        Acceptss a VPC peering connection request. The VPC peering connection
1670        must be in the pending-acceptance state.
1671
1672        :type vpc_peering_connection_id: str
1673        :param vpc_peering_connection_id: The ID of the VPC peering connection.
1674
1675        :rtype: Accepted VpcPeeringConnection
1676        :return: A :class:`boto.vpc.vpc_peering_connection.VpcPeeringConnection` object
1677        """
1678        params = {
1679            'VpcPeeringConnectionId': vpc_peering_connection_id
1680        }
1681
1682        if dry_run:
1683            params['DryRun'] = 'true'
1684
1685        return self.get_object('AcceptVpcPeeringConnection', params,
1686                               VpcPeeringConnection)
1687
1688    def get_all_classic_link_vpcs(self, vpc_ids=None, filters=None,
1689                                   dry_run=False):
1690        """
1691        Describes the ClassicLink status of one or more VPCs.
1692
1693        :type vpc_ids: list
1694        :param vpc_ids: A list of strings with the desired VPC ID's
1695
1696        :type dry_run: bool
1697        :param dry_run: Set to True if the operation should not actually run.
1698
1699        :type filters: list of tuples or dict
1700        :param filters: A list of tuples or dict containing filters. Each tuple
1701            or dict item consists of a filter key and a filter value.
1702
1703        :rtype: list
1704        :return: A list of :class:`boto.vpc.vpc.VPC`
1705        """
1706        params = {}
1707        if vpc_ids:
1708            self.build_list_params(params, vpc_ids, 'VpcId')
1709        if filters:
1710            self.build_filter_params(params, filters)
1711        if dry_run:
1712            params['DryRun'] = 'true'
1713        return self.get_list('DescribeVpcClassicLink', params, [('item', VPC)],
1714                             verb='POST')
1715
1716    def attach_classic_link_vpc(self, vpc_id, instance_id, groups,
1717                                dry_run=False):
1718        """
1719        Links  an EC2-Classic instance to a ClassicLink-enabled VPC through one
1720        or more of the VPC's security groups. You cannot link an EC2-Classic
1721        instance to more than one VPC at a time. You can only link an instance
1722        that's in the running state. An instance is automatically unlinked from
1723        a VPC when it's stopped. You can link it to the VPC again when you
1724        restart it.
1725
1726        After you've linked an instance, you cannot  change  the VPC security
1727        groups  that are associated with it. To change the security groups, you
1728        must first unlink the instance, and then link it again.
1729
1730        Linking your instance to a VPC is sometimes referred  to  as  attaching
1731        your instance.
1732
1733        :type vpc_id: str
1734        :param vpc_id: The ID of a ClassicLink-enabled VPC.
1735
1736        :type intance_id: str
1737        :param instance_is: The ID of a ClassicLink-enabled VPC.
1738
1739        :tye groups: list
1740        :param groups: The ID of one or more of the VPC's security groups.
1741            You cannot specify security groups from a different VPC. The
1742            members of the list can be
1743            :class:`boto.ec2.securitygroup.SecurityGroup` objects or
1744            strings of the id's of the security groups.
1745
1746        :type dry_run: bool
1747        :param dry_run: Set to True if the operation should not actually run.
1748
1749        :rtype: bool
1750        :return: True if successful
1751        """
1752        params = {'VpcId': vpc_id, 'InstanceId': instance_id}
1753        if dry_run:
1754            params['DryRun'] = 'true'
1755        l = []
1756        for group in groups:
1757            if hasattr(group, 'id'):
1758                l.append(group.id)
1759            else:
1760                l.append(group)
1761        self.build_list_params(params, l, 'SecurityGroupId')
1762        return self.get_status('AttachClassicLinkVpc', params)
1763
1764    def detach_classic_link_vpc(self, vpc_id, instance_id, dry_run=False):
1765        """
1766        Unlinks a linked EC2-Classic instance from a VPC. After the instance
1767        has been unlinked, the VPC security groups are no longer associated
1768        with it. An instance is automatically unlinked from a VPC when
1769        it's stopped.
1770
1771        :type vpc_id: str
1772        :param vpc_id: The ID of the instance to unlink from the VPC.
1773
1774        :type intance_id: str
1775        :param instance_is: The ID of the VPC to which the instance is linked.
1776
1777        :type dry_run: bool
1778        :param dry_run: Set to True if the operation should not actually run.
1779
1780        :rtype: bool
1781        :return: True if successful
1782        """
1783        params = {'VpcId': vpc_id, 'InstanceId': instance_id}
1784        if dry_run:
1785            params['DryRun'] = 'true'
1786        return self.get_status('DetachClassicLinkVpc', params)
1787
1788    def disable_vpc_classic_link(self, vpc_id, dry_run=False):
1789        """
1790        Disables  ClassicLink  for  a VPC. You cannot disable ClassicLink for a
1791        VPC that has EC2-Classic instances linked to it.
1792
1793        :type vpc_id: str
1794        :param vpc_id: The ID of the VPC.
1795
1796        :type dry_run: bool
1797        :param dry_run: Set to True if the operation should not actually run.
1798
1799        :rtype: bool
1800        :return: True if successful
1801        """
1802        params = {'VpcId': vpc_id}
1803        if dry_run:
1804            params['DryRun'] = 'true'
1805        return self.get_status('DisableVpcClassicLink', params)
1806
1807    def enable_vpc_classic_link(self, vpc_id, dry_run=False):
1808        """
1809        Enables a VPC for ClassicLink. You can then link EC2-Classic instances
1810        to your ClassicLink-enabled VPC to allow communication over private IP
1811        addresses. You cannot enable your VPC for ClassicLink if any of your
1812        VPC's route tables have existing routes for address ranges within the
1813        10.0.0.0/8 IP address range, excluding local routes for VPCs in the
1814        10.0.0.0/16 and 10.1.0.0/16 IP address ranges.
1815
1816        :type vpc_id: str
1817        :param vpc_id: The ID of the VPC.
1818
1819        :type dry_run: bool
1820        :param dry_run: Set to True if the operation should not actually run.
1821
1822        :rtype: bool
1823        :return: True if successful
1824        """
1825        params = {'VpcId': vpc_id}
1826        if dry_run:
1827            params['DryRun'] = 'true'
1828        return self.get_status('EnableVpcClassicLink', params)
1829