[ec2_vpc_vgw] [ec2_vpc_vpn] stabilize modules for PR 35983 (#38666)

* Stabilize ec2_vpc_vgw and ec2_vpc_vpn so tests for ec2_vpc_vpn_facts in PR 35983 can be run in CI

* Add updated placebo recordings

* ensure find_vgw uses the virtual gateway id if available

Add AWSRetry.jittered_backoff to attach_vpn_gateway to deal with errors when attaching a new VPC directly after detaching

Add integrations tests for ec2_vpc_vgw

* Sort VPN Gateways by ID
This commit is contained in:
Sloane Hertel 2018-05-03 14:19:19 -04:00 committed by GitHub
parent 923a81e9e5
commit 923f676836
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
297 changed files with 17113 additions and 5006 deletions

View file

@ -112,8 +112,9 @@ try:
except ImportError:
HAS_BOTO3 = False
from ansible.module_utils.aws.waiters import get_waiter
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ec2 import HAS_BOTO3, boto3_conn, ec2_argument_spec, get_aws_connection_info
from ansible.module_utils.ec2 import HAS_BOTO3, boto3_conn, ec2_argument_spec, get_aws_connection_info, AWSRetry
from ansible.module_utils._text import to_native
@ -164,7 +165,7 @@ def attach_vgw(client, module, vpn_gateway_id):
params['VpcId'] = module.params.get('vpc_id')
try:
response = client.attach_vpn_gateway(VpnGatewayId=vpn_gateway_id, VpcId=params['VpcId'])
response = AWSRetry.jittered_backoff()(client.attach_vpn_gateway)(VpnGatewayId=vpn_gateway_id, VpcId=params['VpcId'])
except botocore.exceptions.ClientError as e:
module.fail_json(msg=to_native(e), exception=traceback.format_exc())
@ -205,6 +206,14 @@ def create_vgw(client, module):
try:
response = client.create_vpn_gateway(Type=params['Type'])
get_waiter(
client, 'vpn_gateway_exists'
).wait(
VpnGatewayIds=[response['VpnGateway']['VpnGatewayId']]
)
except botocore.exceptions.WaiterError as e:
module.fail_json(msg="Failed to wait for Vpn Gateway {0} to be available".format(response['VpnGateway']['VpnGatewayId']),
exception=traceback.format_exc())
except botocore.exceptions.ClientError as e:
module.fail_json(msg=to_native(e), exception=traceback.format_exc())
@ -329,37 +338,21 @@ def find_vpc(client, module):
def find_vgw(client, module, vpn_gateway_id=None):
params = dict()
params['Name'] = module.params.get('name')
params['Type'] = module.params.get('type')
params['State'] = module.params.get('state')
if params['State'] == 'present':
try:
response = client.describe_vpn_gateways(Filters=[
{'Name': 'type', 'Values': [params['Type']]},
{'Name': 'tag:Name', 'Values': [params['Name']]}
])
except botocore.exceptions.ClientError as e:
module.fail_json(msg=to_native(e), exception=traceback.format_exc())
if vpn_gateway_id:
params['VpnGatewayIds'] = vpn_gateway_id
else:
if vpn_gateway_id:
try:
response = client.describe_vpn_gateways(VpnGatewayIds=vpn_gateway_id)
except botocore.exceptions.ClientError as e:
module.fail_json(msg=to_native(e), exception=traceback.format_exc())
params['Filters'] = [
{'Name': 'type', 'Values': [module.params.get('type')]},
{'Name': 'tag:Name', 'Values': [module.params.get('name')]},
]
if module.params.get('state') == 'present':
params['Filters'].append({'Name': 'state', 'Values': ['pending', 'available']})
try:
response = client.describe_vpn_gateways(**params)
except botocore.exceptions.ClientError as e:
module.fail_json(msg=to_native(e), exception=traceback.format_exc())
else:
try:
response = client.describe_vpn_gateways(Filters=[
{'Name': 'type', 'Values': [params['Type']]},
{'Name': 'tag:Name', 'Values': [params['Name']]}
])
except botocore.exceptions.ClientError as e:
module.fail_json(msg=to_native(e), exception=traceback.format_exc())
result = response['VpnGateways']
return result
return sorted(response['VpnGateways'], key=lambda k: k['VpnGatewayId'])
def ensure_vgw_present(client, module):
@ -376,40 +369,33 @@ def ensure_vgw_present(client, module):
params['Tags'] = module.params.get('tags')
params['VpnGatewayIds'] = module.params.get('vpn_gateway_id')
# Check that a name argument has been supplied.
if not module.params.get('name'):
module.fail_json(msg='A name is required when a status of \'present\' is suppled')
# check that the vpc_id exists. If not, an exception is thrown
if params['VpcId']:
vpc = find_vpc(client, module)
# check if a gateway matching our module args already exists
existing_vgw = find_vgw(client, module)
if existing_vgw != [] and existing_vgw[0]['State'] != 'deleted':
if existing_vgw != []:
vpn_gateway_id = existing_vgw[0]['VpnGatewayId']
vgw, changed = check_tags(client, module, existing_vgw, vpn_gateway_id)
# if a vpc_id was provided, check if it exists and if it's attached
if params['VpcId']:
# check that the vpc_id exists. If not, an exception is thrown
vpc = find_vpc(client, module)
current_vpc_attachments = existing_vgw[0]['VpcAttachments']
if current_vpc_attachments != [] and current_vpc_attachments[0]['State'] == 'attached':
if current_vpc_attachments[0]['VpcId'] == params['VpcId'] and current_vpc_attachments[0]['State'] == 'attached':
changed = False
else:
if current_vpc_attachments[0]['VpcId'] != params['VpcId'] or current_vpc_attachments[0]['State'] != 'attached':
# detach the existing vpc from the virtual gateway
vpc_to_detach = current_vpc_attachments[0]['VpcId']
detach_vgw(client, module, vpn_gateway_id, vpc_to_detach)
time.sleep(5)
attached_vgw = attach_vgw(client, module, vpn_gateway_id)
vgw = find_vgw(client, module, [vpn_gateway_id])
changed = True
else:
# attach the vgw to the supplied vpc
attached_vgw = attach_vgw(client, module, vpn_gateway_id)
vgw = find_vgw(client, module, [vpn_gateway_id])
changed = True
# if params['VpcId'] is not provided, check the vgw is attached to a vpc. if so, detach it.
@ -423,8 +409,6 @@ def ensure_vgw_present(client, module):
detach_vgw(client, module, vpn_gateway_id, vpc_to_detach)
changed = True
vgw = find_vgw(client, module, [vpn_gateway_id])
else:
# create a new vgw
new_vgw = create_vgw(client, module)
@ -434,15 +418,13 @@ def ensure_vgw_present(client, module):
# tag the new virtual gateway
create_tags(client, module, vpn_gateway_id)
# return current state of the vgw
vgw = find_vgw(client, module, [vpn_gateway_id])
# if a vpc-id was supplied, attempt to attach it to the vgw
if params['VpcId']:
attached_vgw = attach_vgw(client, module, vpn_gateway_id)
changed = True
vgw = find_vgw(client, module, [vpn_gateway_id])
# return current state of the vgw
vgw = find_vgw(client, module, [vpn_gateway_id])
result = get_vgw_info(vgw)
return changed, result
@ -549,7 +531,8 @@ def main():
tags=dict(default=None, required=False, type='dict', aliases=['resource_tags']),
)
)
module = AnsibleModule(argument_spec=argument_spec)
module = AnsibleModule(argument_spec=argument_spec,
required_if=[['state', 'present', ['name']]])
if not HAS_BOTO3:
module.fail_json(msg='json and boto3 is required.')