Permalink
Browse files

First pass at ec2 module tests

  • Loading branch information...
1 parent 2a38378 commit b589bf1d2e100f18bc89e0915eb3fc60d5628cf3 @jlaska jlaska committed Feb 24, 2014
Showing with 1,012 additions and 4 deletions.
  1. +1 −0 .gitignore
  2. +15 −1 test/integration/Makefile
  3. +13 −3 test/integration/amazon.yml
  4. +79 −0 test/integration/cleanup_ec2.py
  5. +3 −0 test/integration/group_vars/amazon
  6. +3 −0 test/integration/host_vars/testhost
  7. +2 −0 test/integration/inventory
  8. +119 −0 test/integration/roles/setup_ec2/tasks/common.yml
  9. +55 −0 test/integration/roles/setup_ec2/tasks/main.yml
  10. +38 −0 test/integration/roles/test_ec2/README.md
  11. +2 −0 test/integration/roles/test_ec2/defaults/main.yml
  12. +2 −0 test/integration/roles/test_ec2/handlers/main.yml
  13. +3 −0 test/integration/roles/test_ec2/meta/main.yml
  14. +2 −0 test/integration/roles/test_ec2/tasks/main.yml
  15. +2 −0 test/integration/roles/test_ec2/vars/main.yml
  16. +2 −0 test/integration/roles/test_ec2_ami/defaults/main.yml
  17. +3 −0 test/integration/roles/test_ec2_ami/meta/main.yml
  18. +2 −0 test/integration/roles/test_ec2_ami/tasks/main.yml
  19. +2 −0 test/integration/roles/test_ec2_ami/vars/main.yml
  20. +2 −0 test/integration/roles/test_ec2_eip/defaults/main.yml
  21. +3 −0 test/integration/roles/test_ec2_eip/meta/main.yml
  22. +2 −0 test/integration/roles/test_ec2_eip/tasks/main.yml
  23. +2 −0 test/integration/roles/test_ec2_eip/vars/main.yml
  24. +2 −0 test/integration/roles/test_ec2_elb/defaults/main.yml
  25. +3 −0 test/integration/roles/test_ec2_elb/meta/main.yml
  26. +2 −0 test/integration/roles/test_ec2_elb/tasks/main.yml
  27. +2 −0 test/integration/roles/test_ec2_elb/vars/main.yml
  28. +2 −0 test/integration/roles/test_ec2_elb_lb/defaults/main.yml
  29. +3 −0 test/integration/roles/test_ec2_elb_lb/meta/main.yml
  30. +2 −0 test/integration/roles/test_ec2_elb_lb/tasks/main.yml
  31. +2 −0 test/integration/roles/test_ec2_elb_lb/vars/main.yml
  32. +2 −0 test/integration/roles/test_ec2_facts/defaults/main.yml
  33. +3 −0 test/integration/roles/test_ec2_facts/meta/main.yml
  34. +2 −0 test/integration/roles/test_ec2_facts/tasks/main.yml
  35. +2 −0 test/integration/roles/test_ec2_facts/vars/main.yml
  36. +5 −0 test/integration/roles/test_ec2_group/defaults/main.yml
  37. +3 −0 test/integration/roles/test_ec2_group/meta/main.yml
  38. +250 −0 test/integration/roles/test_ec2_group/tasks/main.yml
  39. +3 −0 test/integration/roles/test_ec2_key/defaults/main.yml
  40. +3 −0 test/integration/roles/test_ec2_key/meta/main.yml
  41. +337 −0 test/integration/roles/test_ec2_key/tasks/main.yml
  42. +2 −0 test/integration/roles/test_ec2_tag/defaults/main.yml
  43. +3 −0 test/integration/roles/test_ec2_tag/meta/main.yml
  44. +2 −0 test/integration/roles/test_ec2_tag/tasks/main.yml
  45. +2 −0 test/integration/roles/test_ec2_tag/vars/main.yml
  46. +2 −0 test/integration/roles/test_ec2_vol/defaults/main.yml
  47. +3 −0 test/integration/roles/test_ec2_vol/meta/main.yml
  48. +2 −0 test/integration/roles/test_ec2_vol/tasks/main.yml
  49. +2 −0 test/integration/roles/test_ec2_vol/vars/main.yml
  50. +2 −0 test/integration/roles/test_ec2_vpc/defaults/main.yml
  51. +3 −0 test/integration/roles/test_ec2_vpc/meta/main.yml
  52. +2 −0 test/integration/roles/test_ec2_vpc/tasks/main.yml
  53. +2 −0 test/integration/roles/test_ec2_vpc/vars/main.yml
View
@@ -38,3 +38,4 @@ debian/
# Vim swap files
*.swp
*.swo
+credentials.yml
View
@@ -1,4 +1,4 @@
-all: non_destructive destructive check_mode test_hash # amazon rackspace
+all: non_destructive destructive check_mode test_hash
non_destructive:
ansible-playbook non_destructive.yml -i inventory -e @integration_config.yml -v $(TEST_FLAGS)
@@ -12,3 +12,17 @@ check_mode:
test_hash:
ANSIBLE_HASH_BEHAVIOUR=replace ansible-playbook test_hash.yml -i inventory -v -e '{"test_hash":{"extra_args":"this is an extra arg"}}'
ANSIBLE_HASH_BEHAVIOUR=merge ansible-playbook test_hash.yml -i inventory -v -e '{"test_hash":{"extra_args":"this is an extra arg"}}'
+
+cloud: amazon rackspace
+
+credentials.yml:
+ @echo "No credentials.yml file found. A file named 'credentials.yml' is needed to provide credentials needed to run cloud tests."
+ @exit 1
+
+amazon: credentials.yml
+ ansible-playbook amazon.yml -i inventory -e @integration_config.yml -e @credentials.yml -v $(TEST_FLAGS)
+ @# FIXME - Cleanup won't run if the previous tests fail
+ python cleanup_ec2.py -y
+
+rackspace: credentials.yml
+ ansible-playbook rackspace.yml -i inventory -e @integration_config.yml -e @credentials.yml -v $(TEST_FLAGS)
@@ -1,4 +1,14 @@
- hosts: testhost
- gather_facts: True
- roles: []
-
+ gather_facts: true
+ roles:
+ - { role: test_ec2_key, tags: test_ec2_key }
+ - { role: test_ec2_group, tags: test_ec2_group }
+ #- { role: test_ec2_vpc, tags: test_ec2_vpc }
+ #- { role: test_ec2_vol, tags: test_ec2_vol }
+ #- { role: test_ec2_tag, tags: test_ec2_tag }
+ #- { role: test_ec2_facts, tags: test_ec2_facts }
+ #- { role: test_ec2_elb_lb, tags: test_ec2_elb_lb }
+ #- { role: test_ec2_eip, tags: test_ec2_eip }
+ #- { role: test_ec2_elb, tags: test_ec2_elb }
+ #- { role: test_ec2_ami, tags: test_ec2_ami }
+ #- { role: test_ec2, tags: test_ec2 }
@@ -0,0 +1,79 @@
+'''
+Find and delete AWS resources matching the provided --match string. Unless
+--yes|-y is provided, the prompt for confirmation prior to deleting resources.
+Please use caution, you can easily delete you're *ENTIRE* EC2 infrastructure.
+'''
+
+import os
+import re
+import sys
+import boto
+import optparse
+import yaml
+
+def delete_aws_resources(get_func, attr, opts):
+ for item in get_func():
+ val = getattr(item, attr)
+ if re.search(opts.match_re, val):
+ prompt_and_delete("Delete object with %s=%s? [y/n]: " % (attr, val), opts.assumeyes)
+
+def prompt_and_delete(prompt, assumeyes):
+ while not assumeyes:
+ assumeyes = raw_input(prompt)
+ obj.delete()
+
+def parse_args():
+ # Load details from credentials.yml
+ default_aws_access_key = os.environ.get('AWS_ACCESS_KEY', None)
+ default_aws_secret_key = os.environ.get('AWS_SECRET_KEY', None)
+ if os.path.isfile('credentials.yml'):
+ credentials = yaml.load(open('credentials.yml', 'r'))
+
+ if default_aws_access_key is None:
+ default_aws_access_key = credentials['ec2_access_key']
+ if default_aws_secret_key is None:
+ default_aws_secret_key = credentials['ec2_secret_key']
+
+ parser = optparse.OptionParser(usage="%s [options]" % (sys.argv[0],),
+ description=__doc__)
+ parser.add_option("--access",
+ action="store", dest="ec2_access_key",
+ default=default_aws_access_key,
+ help="Amazon ec2 access id. Can use EC2_ACCESS_KEY environment variable, or a values from credentials.yml.")
+ parser.add_option("--secret",
+ action="store", dest="ec2_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.")
+ parser.add_option("--credentials", "-c",
+ action="store", dest="credential_file",
+ default="credentials.yml",
+ help="YAML file to read cloud credentials (default: %default)")
+ parser.add_option("--yes", "-y",
+ action="store_true", dest="assumeyes",
+ default=False,
+ help="Don't prompt for confirmation")
+ parser.add_option("--match",
+ action="store", dest="match_re",
+ default="^ansible-testing-",
+ help="Regular expression used to find AWS resources (default: %default)")
+
+ (opts, args) = parser.parse_args()
+ for required in ['ec2_access_key', 'ec2_secret_key']:
+ if getattr(opts, required) is None:
+ parser.error("Missing required parameter: --%s" % required)
+
+ return (opts, args)
+
+if __name__ == '__main__':
+
+ (opts, args) = parse_args()
+
+ # Connect to AWS
+ aws = boto.connect_ec2(aws_access_key_id=opts.ec2_access_key,
+ aws_secret_access_key=opts.ec2_secret_key)
+
+ # Delete matching keys
+ delete_aws_resources(aws.get_all_key_pairs, 'name', opts)
+
+ # Delete matching groups
+ delete_aws_resources(aws.get_all_security_groups, 'name', opts)
@@ -0,0 +1,3 @@
+---
+ec2_url: ec2.amazonaws.com
+ec2_region: us-east-1
@@ -5,3 +5,6 @@ d: 4
role_var_beats_inventory: 'should_not_see_this'
test_hash:
host_vars_testhost: "this is in host_vars/testhost"
+
+# Support execution from within a virtualenv
+ansible_python_interpreter: ${VIRTUAL_ENV-/usr}/bin/python
@@ -25,3 +25,5 @@ groups_tree_var=3000
grandparent_var=2000
overridden_in_parent=2000
+[amazon:children]
+local
@@ -0,0 +1,119 @@
+---
+
+# ============================================================
+- name: test with no parameters
+ action: "{{module_name}}"
+ register: result
+ ignore_errors: true
+
+- name: assert failure when called with no parameters
+ assert:
+ that:
+ - 'result.failed'
+ - 'result.msg == "missing required arguments: name"'
+
+# ============================================================
+- name: test with only name
+ action: "{{module_name}} name={{ec2_key_name}}"
+ register: result
+ ignore_errors: true
+
+- name: assert failure when called with only 'name'
+ assert:
+ that:
+ - 'result.failed'
+ - 'result.msg == "Either region or ec2_url must be specified"'
+
+# ============================================================
+- name: test invalid region parameter
+ action: "{{module_name}} name='{{ec2_key_name}}' 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:")'
+
+# ============================================================
+- name: test valid region parameter
+ action: "{{module_name}} name='{{ec2_key_name}}' 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.")'
+
+# ============================================================
+- name: test environment variable EC2_REGION
+ action: "{{module_name}} name='{{ec2_key_name}}'"
+ environment:
+ EC2_REGION: '{{ec2_region}}'
+ register: result
+ ignore_errors: true
+
+- name: assert environment variable EC2_REGION
+ assert:
+ that:
+ - 'result.failed'
+ - 'result.msg.startswith("No handler was ready to authenticate.")'
+
+# ============================================================
+- name: test invalid ec2_url parameter
+ action: "{{module_name}} name='{{ec2_key_name}}'"
+ 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.")'
+
+# ============================================================
+- name: test valid ec2_url parameter
+ action: "{{module_name}} name='{{ec2_key_name}}'"
+ 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.")'
+
+# ============================================================
+- name: test credentials from environment
+ action: "{{module_name}} name='{{ec2_key_name}}'"
+ environment:
+ EC2_REGION: '{{ec2_region}}'
+ EC2_ACCESS_KEY: bogus_access_key
+ EC2_SECRET_KEY: bogus_secret_key
+ register: result
+ ignore_errors: true
+
+- name: assert ec2_key with valid ec2_url
+ assert:
+ that:
+ - 'result.failed'
+ - '"EC2ResponseError: 401 Unauthorized" in result.msg'
+
+# ============================================================
+- name: test credential parameters
+ action: "{{module_name}} name='{{ec2_key_name}}' ec2_region='{{ec2_region}}' ec2_access_key=bogus_access_key ec2_secret_key=bogus_secret_key"
+ register: result
+ ignore_errors: true
+
+- name: assert credential parameters
+ assert:
+ that:
+ - 'result.failed'
+ - '"EC2ResponseError: 401 Unauthorized" in result.msg'
@@ -0,0 +1,55 @@
+# common setup tasks for ec2 module tests
+# (c) 2014, James Laska <jlaska@ansible.com>
+
+# 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 <http://www.gnu.org/licenses/>.
+
+- name: generate random string
+ shell: python -c "import string,random; print ''.join(random.choice(string.ascii_lowercase) for _ in xrange(8));"
+ register: random_string
+ tags:
+ - prepare
+
+- name: create random file
+ shell: mktemp /tmp/id_rsa.XXXXXX
+ register: sshkey
+ tags:
+ - prepare
+
+- name: generate sshkey
+ shell: echo 'y' | ssh-keygen -P '' -f {{sshkey.stdout}}
+ tags:
+ - prepare
+
+- name: record key_material
+ command: cat {{sshkey.stdout}}.pub
+ register: key_material
+ tags:
+ - prepare
+
+- name: record fingerprint
+ shell: ssh-keygen -lf {{sshkey.stdout}}.pub | awk '{print $2}'
+ register: fingerprint
+ tags:
+ - prepare
+
+- name: set facts for future roles
+ set_fact:
+ random_string: '{{random_string.stdout}}'
+ sshkey: '{{sshkey.stdout}}'
+ key_material: '{{key_material.stdout}}'
+ fingerprint: '{{fingerprint.stdout}}'
+ tags:
+ - prepare
@@ -0,0 +1,38 @@
+Role Name
+========
+
+A brief description of the role goes here.
+
+Requirements
+------------
+
+Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
+
+Role Variables
+--------------
+
+A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
+
+Dependencies
+------------
+
+A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
+
+Example Playbook
+-------------------------
+
+Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
+
+ - hosts: servers
+ roles:
+ - { role: username.rolename, x: 42 }
+
+License
+-------
+
+BSD
+
+Author Information
+------------------
+
+An optional section for the role authors to include contact information, or a website (HTML is not allowed).
@@ -0,0 +1,2 @@
+---
+# defaults file for test_ec2
@@ -0,0 +1,2 @@
+---
+# handlers file for test_ec2
@@ -0,0 +1,3 @@
+dependencies:
+ - prepare_tests
+
@@ -0,0 +1,2 @@
+---
+# tasks file for test_ec2
@@ -0,0 +1,2 @@
+---
+# vars file for test_ec2
@@ -0,0 +1,2 @@
+---
+# defaults file for test_ec2_ami
@@ -0,0 +1,3 @@
+dependencies:
+ - prepare_tests
+
@@ -0,0 +1,2 @@
+---
+# tasks file for test_ec2_ami
@@ -0,0 +1,2 @@
+---
+# vars file for test_ec2_ami
@@ -0,0 +1,2 @@
+---
+# defaults file for test_ec2_eip
@@ -0,0 +1,3 @@
+dependencies:
+ - prepare_tests
+
@@ -0,0 +1,2 @@
+---
+# tasks file for test_ec2_eip
Oops, something went wrong.

0 comments on commit b589bf1

Please sign in to comment.