diff --git a/hacking/aws_config/testing_policies/compute-policy.json b/hacking/aws_config/testing_policies/compute-policy.json index e21f9dda7a7..b644d195f88 100644 --- a/hacking/aws_config/testing_policies/compute-policy.json +++ b/hacking/aws_config/testing_policies/compute-policy.json @@ -42,6 +42,8 @@ "ec2:AssociateVpcCidrBlock", "ec2:AssociateSubnetCidrBlock", "ec2:AttachInternetGateway", + "ec2:AttachVpnGateway", + "ec2:CreateCustomerGateway", "ec2:CreateDhcpOptions", "ec2:CreateImage", "ec2:CreateInternetGateway", @@ -54,6 +56,9 @@ "ec2:CreateSubnet", "ec2:CreateTags", "ec2:CreateVpc", + "ec2:CreateVpnConnection", + "ec2:CreateVpnGateway", + "ec2:DeleteCustomerGateway", "ec2:DeleteDhcpOptions", "ec2:DeleteInternetGateway", "ec2:DeleteKeyPair", @@ -64,9 +69,11 @@ "ec2:DeleteSubnet", "ec2:DeleteTags", "ec2:DeleteVpc", - "ec2:DeleteTags", + "ec2:DeleteVpnConnection", + "ec2:DeleteVpnGateway", "ec2:DeregisterImage", "ec2:DetachInternetGateway", + "ec2:DetachVpnGateway", "ec2:Describe*", "ec2:DisassociateAddress", "ec2:DisassociateRouteTable", diff --git a/lib/ansible/modules/cloud/amazon/ec2_vpc_vpn_facts.py b/lib/ansible/modules/cloud/amazon/ec2_vpc_vpn_facts.py new file mode 100644 index 00000000000..21d54fa84d1 --- /dev/null +++ b/lib/ansible/modules/cloud/amazon/ec2_vpc_vpn_facts.py @@ -0,0 +1,208 @@ +#!/usr/bin/python +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'metadata_version': '1.1'} + + +DOCUMENTATION = ''' +--- +module: ec2_vpc_vpn_facts +short_description: Gather facts about VPN Connections in AWS. +description: + - Gather facts about VPN Connections in AWS. +version_added: "2.6" +requirements: [ boto3 ] +author: Madhura Naniwadekar(@Madhura-CSI) +options: + filters: + description: + - A dict of filters to apply. Each dict item consists of a filter key and a filter value. + See U(http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeVpnConnections.html) for possible filters. + required: false + vpn_connection_ids: + description: + - Get details of a specific VPN connections using vpn connection ID/IDs. This value should be provided as a list. + required: false +extends_documentation_fragment: + - aws + - ec2 +''' + +EXAMPLES = ''' +# # Note: These examples do not set authentication details, see the AWS Guide for details. +- name: Gather facts about all vpn connections + ec2_vpc_vpn_facts: + +- name: Gather facts about a filtered list of vpn connections, based on tags + ec2_vpc_vpn_facts: + filters: + "tag:Name": test-connection + register: vpn_conn_facts + +- name: Gather facts about vpn connections by specifying connection IDs. + ec2_vpc_vpn_facts: + filters: + vpn-gateway-id: vgw-cbe66beb + register: vpn_conn_facts +''' + +RETURN = ''' +vpn_connections: + description: List of one or more VPN Connections. + returned: always + type: complex + contains: + category: + description: The category of the VPN connection. + returned: always + type: string + sample: VPN + customer_gatway_configuration: + description: The configuration information for the VPN connection's customer gateway (in the native XML format). + returned: always + type: string + customer_gateway_id: + description: The ID of the customer gateway at your end of the VPN connection. + returned: always + type: string + sample: cgw-17a53c37 + options: + description: The VPN connection options. + returned: always + type: dict + sample: { + "static_routes_only": false + } + routes: + description: List of static routes associated with the VPN connection. + returned: always + type: complex + contains: + destination_cidr_block: + description: The CIDR block associated with the local subnet of the customer data center. + returned: always + type: string + sample: 10.0.0.0/16 + state: + description: The current state of the static route. + returned: always + type: string + sample: available + state: + description: The current state of the VPN connection. + returned: always + type: string + sample: available + tags: + description: Any tags assigned to the VPN connection. + returned: always + type: dict + sample: { + "Name": "test-conn" + } + type: + description: The type of VPN connection. + returned: always + type: string + sample: ipsec.1 + vgw_telemetry: + description: Information about the VPN tunnel. + returned: always + type: complex + contains: + accepted_route_count: + description: The number of accepted routes. + returned: always + type: int + sample: 0 + last_status_change: + description: The date and time of the last change in status. + returned: always + type: datetime + sample: 2018-02-09T14:35:27+00:00 + outside_ip_address: + description: The Internet-routable IP address of the virtual private gateway's outside interface. + returned: always + type: string + sample: 13.127.79.191 + status: + description: The status of the VPN tunnel. + returned: always + type: string + sample: DOWN + status_message: + description: If an error occurs, a description of the error. + returned: always + type: string + sample: IPSEC IS DOWN + vpn_connection_id: + description: The ID of the VPN connection. + returned: always + type: string + sample: vpn-f700d5c0 + vpn_gateway_id: + description: The ID of the virtual private gateway at the AWS side of the VPN connection. + returned: always + type: string + sample: vgw-cbe56bfb +''' + +import json +try: + from botocore.exceptions import ClientError, BotoCoreError +except ImportError: + pass # caught by AnsibleAWSModule + +from ansible.module_utils.aws.core import AnsibleAWSModule +from ansible.module_utils.ec2 import (ansible_dict_to_boto3_filter_list, ec2_argument_spec, + boto3_conn, boto3_tag_list_to_ansible_dict, camel_dict_to_snake_dict) + + +def date_handler(obj): + return obj.isoformat() if hasattr(obj, 'isoformat') else obj + + +def list_vpn_connections(connection, module): + params = dict() + + params['Filters'] = ansible_dict_to_boto3_filter_list(module.params.get('filters')) + params['VpnConnectionIds'] = module.params.get('vpn_connection_ids') + + try: + result = json.loads(json.dumps(connection.describe_vpn_connections(**params), default=date_handler)) + except ValueError as e: + module.fail_json_aws(e, msg="Cannot validate JSON data") + except (ClientError, BotoCoreError) as e: + module.fail_json_aws(e, msg="Could not describe customer gateways") + snaked_vpn_connections = [camel_dict_to_snake_dict(vpn_connection) for vpn_connection in result['VpnConnections']] + if snaked_vpn_connections: + for vpn_connection in snaked_vpn_connections: + vpn_connection['tags'] = boto3_tag_list_to_ansible_dict(vpn_connection.get('tags', [])) + module.exit_json(changed=False, vpn_connections=snaked_vpn_connections) + + +def main(): + + argument_spec = ec2_argument_spec() + argument_spec.update( + dict( + vpn_connection_ids=dict(default=[], type='list'), + filters=dict(default={}, type='dict') + ) + ) + + module = AnsibleAWSModule(argument_spec=argument_spec, + mutually_exclusive=[['vpn_connection_ids', 'filters']], + supports_check_mode=True) + + connection = module.client('ec2') + + list_vpn_connections(connection, module) + + +if __name__ == '__main__': + main() diff --git a/test/integration/targets/ec2_vpc_vpn_facts/aliases b/test/integration/targets/ec2_vpc_vpn_facts/aliases new file mode 100644 index 00000000000..d6ae2f116bc --- /dev/null +++ b/test/integration/targets/ec2_vpc_vpn_facts/aliases @@ -0,0 +1,2 @@ +cloud/aws +posix/ci/cloud/group4/aws diff --git a/test/integration/targets/ec2_vpc_vpn_facts/tasks/main.yml b/test/integration/targets/ec2_vpc_vpn_facts/tasks/main.yml new file mode 100644 index 00000000000..8163d52446a --- /dev/null +++ b/test/integration/targets/ec2_vpc_vpn_facts/tasks/main.yml @@ -0,0 +1,124 @@ +--- +- block: + + # ============================================================ + - name: set up aws connection info + set_fact: + aws_connection_info: &aws_connection_info + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token }}" + region: "{{ aws_region }}" + no_log: yes + + # ============================================================ + - name: create a VPC + ec2_vpc_net: + name: "{{ resource_prefix }}-vpc" + state: present + cidr_block: "10.0.0.0/26" + <<: *aws_connection_info + tags: + Name: "{{ resource_prefix }}-vpc" + Description: "Created by ansible-test" + register: vpc_result + + - name: create vpn gateway and attach it to vpc + ec2_vpc_vgw: + state: present + vpc_id: '{{ vpc_result.vpc.id }}' + name: "{{ resource_prefix }}-vgw" + <<: *aws_connection_info + register: vgw + + - name: create customer gateway + ec2_customer_gateway: + bgp_asn: 12345 + ip_address: 1.2.3.4 + name: testcgw + <<: *aws_connection_info + register: cgw + + - name: create vpn connection, with customer gateway + ec2_vpc_vpn: + customer_gateway_id: '{{ cgw.gateway.customer_gateway.customer_gateway_id }}' + vpn_gateway_id: '{{ vgw.vgw.id }}' + state: present + <<: *aws_connection_info + register: vpn + + # ============================================================ + - name: test success with no parameters + ec2_vpc_vpn_facts: + <<: *aws_connection_info + register: result + + - name: assert success with no parameters + assert: + that: + - 'result.changed == false' + - 'result.vpn_connections != []' + + - name: test success with customer gateway id as a filter + ec2_vpc_vpn_facts: + filters: + customer-gateway-id: '{{ cgw.gateway.customer_gateway.customer_gateway_id }}' + vpn-connection-id: '{{ vpn.vpn_connection_id }}' + <<: *aws_connection_info + register: result + + - name: assert success with customer gateway id as filter + assert: + that: + - 'result.changed == false' + - 'result.vpn_connections != []' + + # ============================================================ + always: + + - name: delete vpn connection + ec2_vpc_vpn: + state: absent + vpn_connection_id: '{{ vpn.vpn_connection_id }}' + <<: *aws_connection_info + register: result + retries: 10 + delay: 3 + until: result is not failed + ignore_errors: true + + - name: delete customer gateway + ec2_customer_gateway: + state: absent + ip_address: 1.2.3.4 + name: testcgw + bgp_asn: 12345 + <<: *aws_connection_info + register: result + retries: 10 + delay: 3 + until: result is not failed + ignore_errors: true + + - name: delete vpn gateway + ec2_vpc_vgw: + state: absent + vpn_gateway_id: '{{ vgw.vgw.id }}' + <<: *aws_connection_info + register: result + retries: 10 + delay: 3 + until: result is not failed + ignore_errors: true + + - name: delete vpc + ec2_vpc_net: + name: "{{ resource_prefix }}-vpc" + state: absent + cidr_block: "10.0.0.0/26" + <<: *aws_connection_info + register: result + retries: 10 + delay: 3 + until: result is not failed + ignore_errors: true