From 9f0ee40b42f491421e582066c8b82ea95d0cf769 Mon Sep 17 00:00:00 2001 From: Robert Estelle Date: Thu, 13 Nov 2014 18:57:00 -0500 Subject: [PATCH 1/4] Add ec2_vpc_igw module. --- cloud/amazon/ec2_vpc_igw.py | 189 ++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 cloud/amazon/ec2_vpc_igw.py diff --git a/cloud/amazon/ec2_vpc_igw.py b/cloud/amazon/ec2_vpc_igw.py new file mode 100644 index 00000000000..1c5bf9dea1c --- /dev/null +++ b/cloud/amazon/ec2_vpc_igw.py @@ -0,0 +1,189 @@ +#!/usr/bin/python +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +DOCUMENTATION = ''' +--- +module: ec2_vpc_igw +short_description: configure AWS virtual private clouds +description: + - Create or terminates AWS internat gateway in a virtual private cloud. ''' +'''This module has a dependency on python-boto. +version_added: "1.8" +options: + vpc_id: + description: + - "The VPC ID for which to create or remove the Internet Gateway." + required: true + state: + description: + - Create or terminate the IGW + required: true + default: present + aliases: [] + region: + description: + - region in which the resource exists. + required: false + default: null + aliases: ['aws_region', 'ec2_region'] + aws_secret_key: + description: + - AWS secret key. If not set then the value of the AWS_SECRET_KEY''' +''' environment variable is used. + required: false + default: None + aliases: ['ec2_secret_key', 'secret_key' ] + aws_access_key: + description: + - AWS access key. If not set then the value of the AWS_ACCESS_KEY''' +''' environment variable is used. + required: false + default: None + aliases: ['ec2_access_key', 'access_key' ] + validate_certs: + description: + - When set to "no", SSL certificates will not be validated for boto''' +''' versions >= 2.6.0. + required: false + default: "yes" + choices: ["yes", "no"] + aliases: [] + version_added: "1.5" + +requirements: [ "boto" ] +author: Robert Estelle +''' + +EXAMPLES = ''' +# Note: None of these examples set aws_access_key, aws_secret_key, or region. +# It is assumed that their matching environment variables are set. + +# Ensure that the VPC has an Internet Gateway. +# The Internet Gateway ID is can be accessed via {{igw.gateway_id}} for use +# in setting up NATs etc. + local_action: + module: ec2_vpc_igw + vpc_id: {{vpc.vpc_id}} + region: {{vpc.vpc.region}} + state: present + register: igw +''' + + +import sys + +try: + import boto.ec2 + import boto.vpc + from boto.exception import EC2ResponseError +except ImportError: + print "failed=True msg='boto required for this module'" + sys.exit(1) + + +class IGWExcepton(Exception): + pass + + +def ensure_igw_absent(vpc_conn, vpc_id, check_mode): + igws = vpc_conn.get_all_internet_gateways( + filters={'attachment.vpc-id': vpc_id}) + + if not igws: + return {'changed': False} + + if check_mode: + return {'changed': True} + + for igw in igws: + try: + vpc_conn.detach_internet_gateway(igw.id, vpc_id) + vpc_conn.delete_internet_gateway(igw.id) + except EC2ResponseError as e: + raise IGWExcepton('Unable to delete Internet Gateway, error: {0}' + .format(e)) + + return {'changed': True} + + +def ensure_igw_present(vpc_conn, vpc_id, check_mode): + igws = vpc_conn.get_all_internet_gateways( + filters={'attachment.vpc-id': vpc_id}) + + if len(igws) > 1: + raise IGWExcepton( + 'EC2 returned more than one Internet Gateway for VPC {0}, aborting' + .format(vpc_id)) + + if igws: + return {'changed': False, 'gateway_id': igws[0].id} + else: + if check_mode: + return {'changed': True, 'gateway_id': None} + + try: + igw = vpc_conn.create_internet_gateway() + vpc_conn.attach_internet_gateway(igw.id, vpc_id) + return {'changed': True, 'gateway_id': igw.id} + except EC2ResponseError as e: + raise IGWExcepton('Unable to create Internet Gateway, error: {0}' + .format(e)) + + +def main(): + argument_spec = ec2_argument_spec() + argument_spec.update({ + 'vpc_id': {'required': True}, + 'state': {'choices': ['present', 'absent'], 'default': 'present'}, + }) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + ec2_url, aws_access_key, aws_secret_key, region = get_ec2_creds(module) + if not region: + module.fail_json(msg='Region must be specified') + + try: + vpc_conn = boto.vpc.connect_to_region( + region, + aws_access_key_id=aws_access_key, + aws_secret_access_key=aws_secret_key + ) + except boto.exception.NoAuthHandlerFound as e: + module.fail_json(msg=str(e)) + + vpc_id = module.params.get('vpc_id') + state = module.params.get('state', 'present') + + try: + if state == 'present': + result = ensure_igw_present(vpc_conn, vpc_id, + check_mode=module.check_mode) + elif state == 'absent': + result = ensure_igw_absent(vpc_conn, vpc_id, + check_mode=module.check_mode) + except IGWExcepton as e: + module.fail_json(msg=str(e)) + + module.exit_json(**result) + +from ansible.module_utils.basic import * # noqa +from ansible.module_utils.ec2 import * # noqa + +if __name__ == '__main__': + main() From 829759fba7f392e5998e5508faa2c30b85249ea2 Mon Sep 17 00:00:00 2001 From: Robert Estelle Date: Mon, 1 Dec 2014 16:01:46 -0500 Subject: [PATCH 2/4] ec2_vpc_igw - Exit with fail_json when boto is unavailable. --- cloud/amazon/ec2_vpc_igw.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cloud/amazon/ec2_vpc_igw.py b/cloud/amazon/ec2_vpc_igw.py index 1c5bf9dea1c..7276157bd56 100644 --- a/cloud/amazon/ec2_vpc_igw.py +++ b/cloud/amazon/ec2_vpc_igw.py @@ -83,15 +83,17 @@ EXAMPLES = ''' ''' -import sys +import sys # noqa try: import boto.ec2 import boto.vpc from boto.exception import EC2ResponseError + HAS_BOTO = True except ImportError: - print "failed=True msg='boto required for this module'" - sys.exit(1) + HAS_BOTO = False + if __name__ != '__main__': + raise class IGWExcepton(Exception): @@ -153,6 +155,8 @@ def main(): argument_spec=argument_spec, supports_check_mode=True, ) + if not HAS_BOTO: + module.fail_json(msg='boto is required for this module') ec2_url, aws_access_key, aws_secret_key, region = get_ec2_creds(module) if not region: From 6b32b95252c582a1687d98e435f5e33726c8a59d Mon Sep 17 00:00:00 2001 From: Robert Estelle Date: Mon, 1 Dec 2014 16:02:09 -0500 Subject: [PATCH 3/4] ec2_vpc_igw - Rename IGWException to AnsibleIGWException. --- cloud/amazon/ec2_vpc_igw.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cloud/amazon/ec2_vpc_igw.py b/cloud/amazon/ec2_vpc_igw.py index 7276157bd56..cbac94528d2 100644 --- a/cloud/amazon/ec2_vpc_igw.py +++ b/cloud/amazon/ec2_vpc_igw.py @@ -96,7 +96,7 @@ except ImportError: raise -class IGWExcepton(Exception): +class AnsibleIGWException(Exception): pass @@ -115,8 +115,8 @@ def ensure_igw_absent(vpc_conn, vpc_id, check_mode): vpc_conn.detach_internet_gateway(igw.id, vpc_id) vpc_conn.delete_internet_gateway(igw.id) except EC2ResponseError as e: - raise IGWExcepton('Unable to delete Internet Gateway, error: {0}' - .format(e)) + raise AnsibleIGWException( + 'Unable to delete Internet Gateway, error: {0}'.format(e)) return {'changed': True} @@ -126,7 +126,7 @@ def ensure_igw_present(vpc_conn, vpc_id, check_mode): filters={'attachment.vpc-id': vpc_id}) if len(igws) > 1: - raise IGWExcepton( + raise AnsibleIGWException( 'EC2 returned more than one Internet Gateway for VPC {0}, aborting' .format(vpc_id)) @@ -141,8 +141,8 @@ def ensure_igw_present(vpc_conn, vpc_id, check_mode): vpc_conn.attach_internet_gateway(igw.id, vpc_id) return {'changed': True, 'gateway_id': igw.id} except EC2ResponseError as e: - raise IGWExcepton('Unable to create Internet Gateway, error: {0}' - .format(e)) + raise AnsibleIGWException( + 'Unable to create Internet Gateway, error: {0}'.format(e)) def main(): @@ -181,7 +181,7 @@ def main(): elif state == 'absent': result = ensure_igw_absent(vpc_conn, vpc_id, check_mode=module.check_mode) - except IGWExcepton as e: + except AnsibleIGWException as e: module.fail_json(msg=str(e)) module.exit_json(**result) From c21eebdd7b40f76a5e9d6d60102773e597f096a6 Mon Sep 17 00:00:00 2001 From: Rob White Date: Sun, 14 Jun 2015 16:31:31 +1000 Subject: [PATCH 4/4] Updated documentation and added boto profile support. --- cloud/amazon/ec2_vpc_igw.py | 94 ++++++++++++------------------------- 1 file changed, 30 insertions(+), 64 deletions(-) diff --git a/cloud/amazon/ec2_vpc_igw.py b/cloud/amazon/ec2_vpc_igw.py index cbac94528d2..63be48248ef 100644 --- a/cloud/amazon/ec2_vpc_igw.py +++ b/cloud/amazon/ec2_vpc_igw.py @@ -1,75 +1,42 @@ #!/usr/bin/python -# This file is part of Ansible # -# Ansible is free software: you can redistribute it and/or modify +# This is a free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # -# Ansible is distributed in the hope that it will be useful, +# This Ansible library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . +# along with this library. If not, see . DOCUMENTATION = ''' --- module: ec2_vpc_igw -short_description: configure AWS virtual private clouds +short_description: Manage an AWS VPC Internet gateway description: - - Create or terminates AWS internat gateway in a virtual private cloud. ''' -'''This module has a dependency on python-boto. -version_added: "1.8" + - Manage an AWS VPC Internet gateway +version_added: "2.0" +author: Robert Estelle, @erydo options: vpc_id: description: - - "The VPC ID for which to create or remove the Internet Gateway." + - The VPC ID for the VPC in which to manage the Internet Gateway. required: true + default: null state: description: - Create or terminate the IGW - required: true + required: false default: present - aliases: [] - region: - description: - - region in which the resource exists. - required: false - default: null - aliases: ['aws_region', 'ec2_region'] - aws_secret_key: - description: - - AWS secret key. If not set then the value of the AWS_SECRET_KEY''' -''' environment variable is used. - required: false - default: None - aliases: ['ec2_secret_key', 'secret_key' ] - aws_access_key: - description: - - AWS access key. If not set then the value of the AWS_ACCESS_KEY''' -''' environment variable is used. - required: false - default: None - aliases: ['ec2_access_key', 'access_key' ] - validate_certs: - description: - - When set to "no", SSL certificates will not be validated for boto''' -''' versions >= 2.6.0. - required: false - default: "yes" - choices: ["yes", "no"] - aliases: [] - version_added: "1.5" - -requirements: [ "boto" ] -author: Robert Estelle +extends_documentation_fragment: aws ''' EXAMPLES = ''' -# Note: None of these examples set aws_access_key, aws_secret_key, or region. -# It is assumed that their matching environment variables are set. +# Note: These examples do not set authentication details, see the AWS Guide for details. # Ensure that the VPC has an Internet Gateway. # The Internet Gateway ID is can be accessed via {{igw.gateway_id}} for use @@ -147,40 +114,39 @@ def ensure_igw_present(vpc_conn, vpc_id, check_mode): def main(): argument_spec = ec2_argument_spec() - argument_spec.update({ - 'vpc_id': {'required': True}, - 'state': {'choices': ['present', 'absent'], 'default': 'present'}, - }) + argument_spec.update( + dict( + vpc_id = dict(required=True), + state = dict(choices=['present', 'absent'], default='present') + ) + ) + module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) + if not HAS_BOTO: module.fail_json(msg='boto is required for this module') - ec2_url, aws_access_key, aws_secret_key, region = get_ec2_creds(module) - if not region: - module.fail_json(msg='Region must be specified') + region, ec2_url, aws_connect_params = get_aws_connection_info(module) - try: - vpc_conn = boto.vpc.connect_to_region( - region, - aws_access_key_id=aws_access_key, - aws_secret_access_key=aws_secret_key - ) - except boto.exception.NoAuthHandlerFound as e: - module.fail_json(msg=str(e)) + if region: + try: + connection = connect_to_aws(boto.ec2, region, **aws_connect_params) + except (boto.exception.NoAuthHandlerFound, StandardError), e: + module.fail_json(msg=str(e)) + else: + module.fail_json(msg="region must be specified") vpc_id = module.params.get('vpc_id') state = module.params.get('state', 'present') try: if state == 'present': - result = ensure_igw_present(vpc_conn, vpc_id, - check_mode=module.check_mode) + result = ensure_igw_present(connection, vpc_id, check_mode=module.check_mode) elif state == 'absent': - result = ensure_igw_absent(vpc_conn, vpc_id, - check_mode=module.check_mode) + result = ensure_igw_absent(connection, vpc_id, check_mode=module.check_mode) except AnsibleIGWException as e: module.fail_json(msg=str(e))