Adds integration tests for gce module.
This commit is contained in:
parent
b0556ab1fb
commit
2cc4a372c5
6 changed files with 224 additions and 0 deletions
|
@ -39,6 +39,9 @@ cloud_cleanup: amazon_cleanup rackspace_cleanup
|
|||
amazon_cleanup:
|
||||
python cleanup_ec2.py -y --match="^$(CLOUD_RESOURCE_PREFIX)"
|
||||
|
||||
gce_cleanup:
|
||||
python cleanup_gce.py -y --match="^$(CLOUD_RESOURCE_PREFIX)"
|
||||
|
||||
rackspace_cleanup:
|
||||
@echo "FIXME - cleanup_rax.py not yet implemented"
|
||||
@# python cleanup_rax.py -y --match="^$(CLOUD_RESOURCE_PREFIX)"
|
||||
|
@ -53,6 +56,12 @@ amazon: $(CREDENTIALS_FILE)
|
|||
CLOUD_RESOURCE_PREFIX="$(CLOUD_RESOURCE_PREFIX)" make amazon_cleanup ; \
|
||||
exit $$RC;
|
||||
|
||||
gce: $(CREDENTIALS_FILE)
|
||||
ansible-playbook gce.yml -i $(INVENTORY) -e @$(VARS_FILE) $(CREDENTIALS_ARG) -e "resource_prefix=$(CLOUD_RESOURCE_PREFIX)" -v $(TEST_FLAGS) ; \
|
||||
RC=$$? ; \
|
||||
CLOUD_RESOURCE_PREFIX="$(CLOUD_RESOURCE_PREFIX)" make gce_cleanup ; \
|
||||
exit $$RC;
|
||||
|
||||
rackspace: $(CREDENTIALS_FILE)
|
||||
ansible-playbook rackspace.yml -i $(INVENTORY) -e @$(VARS_FILE) $(CREDENTIALS_ARG) -e "resource_prefix=$(CLOUD_RESOURCE_PREFIX)" -v $(TEST_FLAGS) ; \
|
||||
RC=$$? ; \
|
||||
|
|
102
test/integration/cleanup_gce.py
Normal file
102
test/integration/cleanup_gce.py
Normal file
|
@ -0,0 +1,102 @@
|
|||
'''
|
||||
Find and delete GCE 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 your *ENTIRE* GCE infrastructure.
|
||||
'''
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import optparse
|
||||
import yaml
|
||||
|
||||
try:
|
||||
from libcloud.compute.types import Provider
|
||||
from libcloud.compute.providers import get_driver
|
||||
from libcloud.common.google import GoogleBaseError, QuotaExceededError, \
|
||||
ResourceExistsError, ResourceInUseError, ResourceNotFoundError
|
||||
_ = Provider.GCE
|
||||
except ImportError:
|
||||
print("failed=True " + \
|
||||
"msg='libcloud with GCE support (0.13.3+) required for this module'")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def delete_gce_resources(get_func, attr, opts):
|
||||
for item in get_func():
|
||||
val = getattr(item, attr)
|
||||
if re.search(opts.match_re, val, re.IGNORECASE):
|
||||
prompt_and_delete(item, "Delete matching %s? [y/n]: " % (item,), opts.assumeyes)
|
||||
|
||||
def prompt_and_delete(item, prompt, assumeyes):
|
||||
if not assumeyes:
|
||||
assumeyes = raw_input(prompt).lower() == 'y'
|
||||
assert hasattr(item, 'destroy'), "Class <%s> has no delete attribute" % item.__class__
|
||||
if assumeyes:
|
||||
item.destroy()
|
||||
print ("Deleted %s" % item)
|
||||
|
||||
def parse_args():
|
||||
default_service_account_email = None
|
||||
default_pem_file = None
|
||||
default_project_id = None
|
||||
|
||||
# Load details from credentials.yml
|
||||
if os.path.isfile('credentials.yml'):
|
||||
credentials = yaml.load(open('credentials.yml', 'r'))
|
||||
|
||||
if default_service_account_email is None:
|
||||
default_service_account_email = credentials['gce_service_account_email']
|
||||
if default_pem_file is None:
|
||||
default_pem_file = credentials['gce_pem_file']
|
||||
if default_project_id is None:
|
||||
default_project_id = credentials['gce_project_id']
|
||||
|
||||
parser = optparse.OptionParser(usage="%s [options]" % (sys.argv[0],),
|
||||
description=__doc__)
|
||||
parser.add_option("--service_account_email",
|
||||
action="store", dest="service_account_email",
|
||||
default=default_service_account_email,
|
||||
help="GCE service account email. Default is loaded from credentials.yml.")
|
||||
parser.add_option("--pem_file",
|
||||
action="store", dest="pem_file",
|
||||
default=default_pem_file,
|
||||
help="GCE client key. Default is loaded from credentials.yml.")
|
||||
parser.add_option("--project_id",
|
||||
action="store", dest="project_id",
|
||||
default=default_project_id,
|
||||
help="Google Cloud project ID. Default is loaded 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 GCE resources (default: %default)")
|
||||
|
||||
(opts, args) = parser.parse_args()
|
||||
for required in ['service_account_email', 'pem_file', 'project_id']:
|
||||
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 GCE
|
||||
gce_cls = get_driver(Provider.GCE)
|
||||
gce = gce_cls(
|
||||
opts.service_account_email, opts.pem_file, project=opts.project_id)
|
||||
|
||||
try:
|
||||
# Delete matching instances
|
||||
delete_gce_resources(gce.list_nodes, 'name', opts)
|
||||
except KeyboardInterrupt, e:
|
||||
print "\nExiting on user command."
|
|
@ -3,5 +3,10 @@
|
|||
ec2_access_key:
|
||||
ec2_secret_key:
|
||||
|
||||
# GCE Credentials
|
||||
service_account_email:
|
||||
pem_file:
|
||||
project_id:
|
||||
|
||||
# GITHUB SSH private key - a path to a SSH private key for use with github.com
|
||||
github_ssh_private_key: "{{ lookup('env','HOME') }}/.ssh/id_rsa"
|
||||
|
|
5
test/integration/gce.yml
Normal file
5
test/integration/gce.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
- hosts: testhost
|
||||
gather_facts: true
|
||||
roles:
|
||||
- { role: test_gce, tags: test_gce }
|
||||
# TODO: tests for gce_net, gce_pd, etc.
|
6
test/integration/roles/test_gce/defaults/main.yml
Normal file
6
test/integration/roles/test_gce/defaults/main.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
# defaults file for test_gce
|
||||
instance_name: "{{ resource_prefix|lower }}"
|
||||
service_account_email: "{{ gce_service_account_email }}"
|
||||
pem_file: "{{ gce_pem_file }}"
|
||||
project_id: "{{ gce_project_id }}"
|
97
test/integration/roles/test_gce/tasks/main.yml
Normal file
97
test/integration/roles/test_gce/tasks/main.yml
Normal file
|
@ -0,0 +1,97 @@
|
|||
# TODO: lots of attributes not covered: machine_type, zone, metadata, tags, etc.
|
||||
#
|
||||
# ============================================================
|
||||
- name: test with no parameters
|
||||
gce:
|
||||
register: result
|
||||
ignore_errors: true
|
||||
|
||||
- name: assert failure when called with no parameters
|
||||
assert:
|
||||
that:
|
||||
- 'result.failed'
|
||||
- 'result.msg == "Missing GCE connection parameters in libcloud secrets file."'
|
||||
|
||||
# ============================================================
|
||||
- name: test missing name
|
||||
gce:
|
||||
service_account_email: "{{ service_account_email }}"
|
||||
pem_file: "{{ pem_file }}"
|
||||
project_id: "{{ project_id }}"
|
||||
register: result
|
||||
ignore_errors: true
|
||||
|
||||
- name: assert failure when called with no parameters
|
||||
assert:
|
||||
that:
|
||||
- 'result.failed'
|
||||
- 'result.msg == "Must specify a \"name\" or \"instance_names\""'
|
||||
|
||||
# ============================================================
|
||||
- name: test state=present (expected changed=true)
|
||||
gce:
|
||||
name: "{{ instance_name }}"
|
||||
service_account_email: "{{ service_account_email }}"
|
||||
pem_file: "{{ pem_file }}"
|
||||
project_id: "{{ project_id }}"
|
||||
state: present
|
||||
register: result
|
||||
|
||||
- name: assert state=present (expected changed=true)
|
||||
assert:
|
||||
that:
|
||||
- 'result.changed'
|
||||
- 'result.name == "{{ instance_name }}"'
|
||||
- 'result.state == "present"'
|
||||
|
||||
# ============================================================
|
||||
- name: test state=present (expected changed=false)
|
||||
gce:
|
||||
name: "{{ instance_name }}"
|
||||
service_account_email: "{{ service_account_email }}"
|
||||
pem_file: "{{ pem_file }}"
|
||||
project_id: "{{ project_id }}"
|
||||
state: present
|
||||
register: result
|
||||
|
||||
- name: assert state=present (expected changed=false)
|
||||
assert:
|
||||
that:
|
||||
- 'not result.changed'
|
||||
- 'result.name == "{{ instance_name }}"'
|
||||
- 'result.state == "present"'
|
||||
|
||||
# ============================================================
|
||||
- name: test state=absent (expected changed=true)
|
||||
gce:
|
||||
name: "{{ instance_name }}"
|
||||
service_account_email: "{{ service_account_email }}"
|
||||
pem_file: "{{ pem_file }}"
|
||||
project_id: "{{ project_id }}"
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- name: assert state=absent (expected changed=true)
|
||||
assert:
|
||||
that:
|
||||
- 'result.changed'
|
||||
- 'result.name == "{{ instance_name }}"'
|
||||
- 'result.state == "absent"'
|
||||
|
||||
# ============================================================
|
||||
- name: test state=absent (expected changed=false)
|
||||
gce:
|
||||
name: "{{ instance_name }}"
|
||||
service_account_email: "{{ service_account_email }}"
|
||||
pem_file: "{{ pem_file }}"
|
||||
project_id: "{{ project_id }}"
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- name: assert state=absent (expected changed=false)
|
||||
assert:
|
||||
that:
|
||||
- 'not result.changed'
|
||||
- 'result.name == "{{ instance_name }}"'
|
||||
- 'result.state == "absent"'
|
||||
|
Loading…
Reference in a new issue