ec2_eip integration tests.

This commit is contained in:
James Martin 2014-04-17 14:32:02 -04:00
parent a37a84243b
commit 8a21f226b5
4 changed files with 491 additions and 5 deletions

View file

@ -48,7 +48,7 @@ $(CREDENTIALS_FILE):
@exit 1 @exit 1
amazon: $(CREDENTIALS_FILE) amazon: $(CREDENTIALS_FILE)
ansible-playbook amazon.yml -i $(INVENTORY) -e @$(VARS_FILE) $(CREDENTIALS_ARG) -e "resource_prefix=$(CLOUD_RESOURCE_PREFIX)" -v $(TEST_FLAGS) ; \ BOTO_CONFIG=/dev/null ansible-playbook amazon.yml -i $(INVENTORY) -e @$(VARS_FILE) $(CREDENTIALS_ARG) -e "resource_prefix=$(CLOUD_RESOURCE_PREFIX)" -v $(TEST_FLAGS) ; \
RC=$$? ; \ RC=$$? ; \
CLOUD_RESOURCE_PREFIX="$(CLOUD_RESOURCE_PREFIX)" make amazon_cleanup ; \ CLOUD_RESOURCE_PREFIX="$(CLOUD_RESOURCE_PREFIX)" make amazon_cleanup ; \
exit $$RC; exit $$RC;

View file

@ -10,6 +10,7 @@ import sys
import boto import boto
import optparse import optparse
import yaml import yaml
import os.path
def delete_aws_resources(get_func, attr, opts): def delete_aws_resources(get_func, attr, opts):
for item in get_func(): for item in get_func():
@ -17,13 +18,36 @@ def delete_aws_resources(get_func, attr, opts):
if re.search(opts.match_re, val): if re.search(opts.match_re, val):
prompt_and_delete(item, "Delete matching %s? [y/n]: " % (item,), opts.assumeyes) prompt_and_delete(item, "Delete matching %s? [y/n]: " % (item,), opts.assumeyes)
def delete_aws_eips(get_func, attr, opts):
# the file might not be there if the integration test wasn't run
try:
eip_log = open(opts.eip_log, 'r').read().splitlines()
except IOError:
print opts.eip_log, 'not found.'
return
for item in get_func():
val = getattr(item, attr)
if val in eip_log:
prompt_and_delete(item, "Delete matching %s? [y/n]: " % (item,), opts.assumeyes)
def delete_aws_instances(reservation, opts):
for list in reservation:
for item in list.instances:
prompt_and_delete(item, "Delete matching %s? [y/n]: " % (item,), opts.assumeyes)
def prompt_and_delete(item, prompt, assumeyes): def prompt_and_delete(item, prompt, assumeyes):
if not assumeyes: if not assumeyes:
assumeyes = raw_input(prompt).lower() == 'y' assumeyes = raw_input(prompt).lower() == 'y'
assert hasattr(item, 'delete'), "Class <%s> has no delete attribute" % item.__class__ assert hasattr(item, 'delete') or hasattr(item, 'terminate') , "Class <%s> has no delete or terminate attribute" % item.__class__
if assumeyes: if assumeyes:
item.delete() if hasattr(item, 'delete'):
print ("Deleted %s" % item) item.delete()
print ("Deleted %s" % item)
if hasattr(item, 'terminate'):
item.terminate()
print ("Terminated %s" % item)
def parse_args(): def parse_args():
# Load details from credentials.yml # Load details from credentials.yml
@ -47,6 +71,14 @@ def parse_args():
action="store", dest="ec2_secret_key", action="store", dest="ec2_secret_key",
default=default_aws_secret_key, default=default_aws_secret_key,
help="Amazon ec2 secret key. Can use EC2_SECRET_KEY environment variable, or a values from credentials.yml.") help="Amazon ec2 secret key. Can use EC2_SECRET_KEY environment variable, or a values from credentials.yml.")
parser.add_option("--eip-log",
action="store", dest="eip_log",
default = None,
help = "Path to log of EIPs created during test.")
parser.add_option("--integration-config",
action="store", dest="int_config",
default = "integration_config.yml",
help = "path to integration config")
parser.add_option("--credentials", "-c", parser.add_option("--credentials", "-c",
action="store", dest="credential_file", action="store", dest="credential_file",
default="credentials.yml", default="credentials.yml",
@ -65,12 +97,18 @@ def parse_args():
if getattr(opts, required) is None: if getattr(opts, required) is None:
parser.error("Missing required parameter: --%s" % required) parser.error("Missing required parameter: --%s" % required)
return (opts, args) return (opts, args)
if __name__ == '__main__': if __name__ == '__main__':
(opts, args) = parse_args() (opts, args) = parse_args()
int_config = yaml.load(open(opts.int_config).read())
if not opts.eip_log:
output_dir = os.path.expanduser(int_config["output_dir"])
opts.eip_log = output_dir + '/' + opts.match_re.replace('^','') + '-eip_integration_tests.log'
# Connect to AWS # Connect to AWS
aws = boto.connect_ec2(aws_access_key_id=opts.ec2_access_key, aws = boto.connect_ec2(aws_access_key_id=opts.ec2_access_key,
aws_secret_access_key=opts.ec2_secret_key) aws_secret_access_key=opts.ec2_secret_key)
@ -81,5 +119,13 @@ if __name__ == '__main__':
# Delete matching groups # Delete matching groups
delete_aws_resources(aws.get_all_security_groups, 'name', opts) delete_aws_resources(aws.get_all_security_groups, 'name', opts)
# Delete recorded EIPs
delete_aws_eips(aws.get_all_addresses, 'public_ip', opts)
# Delete temporary instances
filters = {"tag:Name":opts.match_re.replace('^',''), "instance-state-name": ['running', 'pending', 'stopped' ]}
delete_aws_instances(aws.get_all_instances(filters=filters), opts)
except KeyboardInterrupt, e: except KeyboardInterrupt, e:
print "\nExiting on user command." print "\nExiting on user command."

View file

@ -1,2 +1,3 @@
--- ---
# defaults file for test_ec2_eip # defaults file for test_ec2_eip
tag_prefix: '{{resource_prefix}}'

View file

@ -1,2 +1,441 @@
--- ---
# tasks file for test_ec2_eip # __Test Info__
# EIPs are a scarce resource. AWS only assigns 5 per account
# by default. This test tries to only use 1 at a time.
# one t1.micro instance will also be provisioned.
# tests require setting of variables eip_ec2_keyname and
# eip_ec2_image .
# __Test Outline__
#
# __ec2_eip__
# create test instance
# create EIP
# assign allocated ip to instance_id
# disassociate EIP associated with instance
# re-use existing EIP with instance
# deactivate EIP
# provision EIP with instance_id
# create VPC EIP
# re-use exiting VPC EIP with instance
# __ec2-common__
# test environment variable EC2_REGION
# deactivate EIP
# test with no parameters
# test with only instance_id
# test invalid region parameter
# test valid region parameter
# test invalid ec2_url parameter
# test valid ec2_url parameter
# test credentials from environment
# test credential parameters
# ============================================================
# create test instance
- name: create test instance
local_action:
module: ec2
key_name: "{{ eip_ec2_keyname }}"
region: "{{ ec2_region }}"
instance_type: t1.micro
image: "{{ eip_ec2_image }}"
wait: yes
instance_tags:
Name: "{{ tag_prefix }}"
ansible_ec2_eip_integration_test: foo
exact_count: 1
count_tag: "ansible_ec2_eip_integration_test"
ec2_access_key: "{{ ec2_access_key }}"
ec2_secret_key: "{{ ec2_secret_key }}"
register: output
- name: set instance id fact
set_fact: instance_id={{ output.instances[0].id }}
# eip allocated:0 assigned:0
# ============================================================
# create EIP
- name: create EIP
ec2_eip: region={{ ec2_region }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
register: result
- name: set eip fact
set_fact: eip={{ result.public_ip }}
- name: write ip to list for cleanup script
shell: echo {{ eip }} >> {{ output_dir }}/{{ tag_prefix }}-eip_integration_tests.log
- name: assert EIP created
assert:
that:
- '"failed" not in result'
# eip allocated:1 assigned:0
# ============================================================
# assign allocated ip to instance_id
- name: assign allocated ip to instance_id
ec2_eip:
reuse_existing_ip_allowed=yes
instance_id={{ instance_id }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
public_ip={{ eip }}
region={{ ec2_region }}
register: result
- name: assert new EIP was assigned
assert:
that:
- '"failed" not in result'
- '"public_ip" in result'
# eip allocated:1 assigned:1
# ============================================================
# disassociate EIP associated with instance
- name: disassociate EIP associated with instance
ec2_eip: state=absent public_ip={{ eip }} region={{ ec2_region }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
instance_id={{ instance_id }}
register: result
- name: assert success disassociate EIP associated with instance
assert:
that:
- '"failed" not in result'
# eip allocated:1 assigned:0
# ============================================================
# re-use existing EIP with instance
- name: re-use existing EIP with instance
ec2_eip:
reuse_existing_ip_allowed=yes
instance_id={{ instance_id }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
region={{ ec2_region }}
register: result
- name: assert new EIP was assigned
assert:
that:
- '"failed" not in result'
- '"public_ip" in result'
- name: disassociate EIP associated with instance
ec2_eip: state=absent public_ip={{ eip }} region={{ ec2_region }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
instance_id={{ instance_id }}
# eip allocated:1 assigned:1
# ============================================================
# deactivate EIP
- name: deactivate EIP
ec2_eip: state=absent public_ip={{ eip }} region={{ ec2_region }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
register: result
- name: assert EIP deactivated
assert:
that:
- '"failed" not in result'
# eip allocated:0 assigned:0
# ============================================================
# provision EIP with instance_id
- name: provision EIP with instance_id
ec2_eip:
instance_id={{ instance_id }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
region={{ ec2_region }}
register: result
- name: set eip fact
set_fact: eip={{ result.public_ip }}
- name: write ip to list for cleanup script
shell: echo {{ eip }} >> {{ output_dir }}/{{ tag_prefix }}-eip_integration_tests.log
- name: assert provision EIP with instance_id
assert:
that:
- '"failed" not in result'
- '"public_ip" in result'
- name: disassociate EIP associated with instance
ec2_eip: state=absent public_ip={{ eip }} region={{ ec2_region }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
instance_id={{ instance_id }}
- name: deactivate EIP
ec2_eip: state=absent public_ip={{ eip }} region={{ ec2_region }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
# eip allocated:0 assigned:0
# ============================================================
# create VPC EIP
- name: create VPC EIP
ec2_eip: in_vpc=yes region={{ ec2_region }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
register: result
- name: set eip fact
set_fact: eip={{ result.public_ip }}
- name: write ip to list for cleanup script
shell: echo {{ eip }} >> {{ output_dir }}/{{ tag_prefix }}-eip_integration_tests.log
- name: assert VPC EIP creation
assert:
that:
- '"failed" not in result'
- '"public_ip" in result'
# eip allocated:1 assigned:0
# ============================================================
# re-use existing VPC EIP with instance
- name: re-use existing EIP with instance
ec2_eip:
in_vpc=yes
reuse_existing_ip_allowed=yes
instance_id={{ instance_id }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
region={{ ec2_region }}
register: result
- name: assert new EIP was assigned
assert:
that:
- '"failed" not in result'
- '"public_ip" in result'
- name: disassociate EIP associated with instance
ec2_eip: state=absent public_ip={{ eip }} region={{ ec2_region }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
instance_id={{ instance_id }}
- name: deactivate EIP
ec2_eip: state=absent public_ip={{ eip }} region={{ ec2_region }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
# eip allocated:0 assigned:0
# ============================================================
- name: test environment variable EC2_REGION
ec2_eip:
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
environment:
EC2_REGION: "{{ ec2_region }}"
register: result
- name: set eip fact
set_fact: eip={{ result.public_ip }}
- name: write ip to list for cleanup script
shell: echo {{ eip }} >> {{ output_dir }}/{{ tag_prefix }}-eip_integration_tests.log
- name: assert environment variable EC2_REGION
assert:
that:
- '"failed" not in result'
- '"public_ip" in result'
- name: deactivate EIP
ec2_eip: state=absent public_ip={{ eip }} region={{ ec2_region }}
ec2_access_key={{ ec2_access_key }}
ec2_secret_key={{ ec2_secret_key }}
# eip allocated:0 assigned:0
# ============================================================
- name: test with no parameters
ec2_eip:
register: result
ignore_errors: true
- name: assert failure when called with no parameters
assert:
that:
- 'result.failed'
- 'result.msg == "Either region or ec2_url must be specified"'
# eip allocated:0 assigned:0
# ============================================================
- name: test with only instance_id
ec2_eip:
instance_id=i-12345
register: result
ignore_errors: true
- name: assert failure when called with only 'instance_id'
assert:
that:
- 'result.failed'
- 'result.msg == "Either region or ec2_url must be specified"'
# eip allocated:0 assigned:0
# ============================================================
- name: test invalid region parameter
ec2_eip:
instance_id={{ instance_id }}
region='asdf querty 1234'
register: result
ignore_errors: true
- name: assert invalid region parameter
assert:
that:
- 'result.failed'
- 'result.msg.startswith("value of region must be one of:")'
# eip allocated:0 assigned:0
# ============================================================
- name: test valid region parameter
ec2_eip:
instance_id={{ instance_id }}
region={{ ec2_region }}
register: result
ignore_errors: true
- name: assert valid region parameter
assert:
that:
- 'result.failed'
- 'result.msg.startswith("No handler was ready to authenticate.")'
# eip allocated:0 assigned:0
# ============================================================
- name: test invalid ec2_url parameter
ec2_eip:
instance_id={{ instance_id }}
reuse_existing_ip_allowed=yes
environment:
EC2_URL: bogus.example.com
register: result
ignore_errors: true
- name: assert invalid ec2_url parameter
assert:
that:
- 'result.failed'
- 'result.msg.startswith("No handler was ready to authenticate.")'
# eip allocated:0 assigned:0
# ============================================================
- name: test valid ec2_url parameter
ec2_eip:
instance_id={{ instance_id }}
reuse_existing_ip_allowed=yes
environment:
EC2_URL: '{{ec2_url}}'
register: result
ignore_errors: true
- name: assert valid ec2_url parameter
assert:
that:
- 'result.failed'
- 'result.msg.startswith("No handler was ready to authenticate.")'
# eip allocated:0 assigned:0
# ============================================================
- name: test credentials from environment
ec2_eip:
region={{ ec2_region }}
instance_id={{ instance_id }}
environment:
EC2_ACCESS_KEY: bogus_access_key
EC2_SECRET_KEY: bogus_secret_key
register: result
ignore_errors: true
- name: assert credentials from environment
assert:
that:
- 'result.failed'
- '"EC2ResponseError: 401 Unauthorized" in result.msg'
# eip allocated:0 assigned:0
# ============================================================
- name: test credential parameters
ec2_eip: region={{ ec2_region }}
register: result
ignore_errors: true
- name: assert credential parameters
assert:
that:
- 'result.failed'
- '"Check your credentials" in result.msg'
# eip allocated:0 assigned:0