-
Notifications
You must be signed in to change notification settings - Fork 23.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added optional region parameter. Fail if you specify an ELB that doesn'... #3728
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,7 +25,7 @@ description: | |
if state=absent is passed as an argument. | ||
- Will be marked changed when called only if there are ELBs found to operate on. | ||
version_added: "1.2" | ||
requirements: [ "boto" ] | ||
requirements: [ "boto", "urllib2" ] | ||
author: John Jarvis | ||
options: | ||
state: | ||
|
@@ -53,6 +53,11 @@ options: | |
- AWS Access API key | ||
required: false | ||
default: None | ||
ec2_region: | ||
description: | ||
- AWS region of your load balancer. If not set then the region in which | ||
this module is running will be used. | ||
required: false | ||
|
||
""" | ||
|
||
|
@@ -81,23 +86,41 @@ import time | |
import sys | ||
import os | ||
|
||
AWS_REGIONS = ['ap-northeast-1', | ||
'ap-southeast-1', | ||
'ap-southeast-2', | ||
'eu-west-1', | ||
'sa-east-1', | ||
'us-east-1', | ||
'us-west-1', | ||
'us-west-2'] | ||
|
||
try: | ||
import boto | ||
import boto.ec2.elb | ||
from boto.regioninfo import RegionInfo | ||
except ImportError: | ||
print "failed=True msg='boto required for this module'" | ||
sys.exit(1) | ||
|
||
try: | ||
import urllib2 | ||
except ImportError: | ||
print "failed=True msg='urllib2 required for this module'" | ||
sys.exit(1) | ||
|
||
class ElbManager: | ||
"""Handles EC2 instance ELB registration and de-registration""" | ||
|
||
def __init__(self, module, instance_id=None, ec2_elbs=None, | ||
ec2_access_key=None, ec2_secret_key=None): | ||
ec2_access_key=None, ec2_secret_key=None, ec2_region=None): | ||
self.ec2_access_key = ec2_access_key | ||
self.ec2_secret_key = ec2_secret_key | ||
self.module = module | ||
self.instance_id = instance_id | ||
self.ec2_region = ec2_region | ||
self.lbs = self._get_instance_lbs(ec2_elbs) | ||
|
||
# if there are no ELBs to operate on | ||
# there will be no changes made | ||
if len(self.lbs) > 0: | ||
|
@@ -121,6 +144,17 @@ class ElbManager: | |
lb.register_instances([self.instance_id]) | ||
self._await_elb_instance_state(lb, 'InService') | ||
|
||
def exists(self, lbtest): | ||
""" Verify that the named ELB actually exists """ | ||
|
||
found = False | ||
for lb in self.lbs: | ||
if lb.name == lbtest: | ||
found=True | ||
break | ||
return found | ||
|
||
|
||
def _await_elb_instance_state(self, lb, awaited_state): | ||
"""Wait for an ELB to change state | ||
lb: load balancer | ||
|
@@ -140,9 +174,12 @@ class ElbManager: | |
are attached to self.instance_id""" | ||
|
||
try: | ||
elb = boto.connect_elb(self.ec2_access_key, self.ec2_secret_key) | ||
endpoint="elasticloadbalancing.%s.amazonaws.com" % self.ec2_region | ||
connect_region = RegionInfo(name=self.ec2_region, endpoint=endpoint) | ||
elb = boto.ec2.elb.ELBConnection(self.ec2_access_key, self.ec2_secret_key, region=connect_region) | ||
except boto.exception.NoAuthHandlerFound, e: | ||
self.module.fail_json(msg=str(e)) | ||
|
||
elbs = elb.get_all_load_balancers() | ||
|
||
if ec2_elbs: | ||
|
@@ -165,13 +202,15 @@ def main(): | |
instance_id={'required': True}, | ||
ec2_elbs={'default': None, 'required': False}, | ||
ec2_secret_key={'default': None, 'aliases': ['EC2_SECRET_KEY']}, | ||
ec2_access_key={'default': None, 'aliases': ['EC2_ACCESS_KEY']} | ||
ec2_access_key={'default': None, 'aliases': ['EC2_ACCESS_KEY']}, | ||
ec2_region={'default': None, 'required': False, 'choices':AWS_REGIONS} | ||
) | ||
) | ||
|
||
ec2_secret_key = module.params['ec2_secret_key'] | ||
ec2_access_key = module.params['ec2_access_key'] | ||
ec2_elbs = module.params['ec2_elbs'] | ||
ec2_region = module.params['ec2_region'] | ||
|
||
if module.params['state'] == 'present' and 'ec2_elbs' not in module.params: | ||
module.fail_json(msg="ELBs are required for registration") | ||
|
@@ -181,9 +220,28 @@ def main(): | |
if not ec2_access_key and 'EC2_ACCESS_KEY' in os.environ: | ||
ec2_access_key = os.environ['EC2_ACCESS_KEY'] | ||
|
||
if not ec2_region and 'EC2_REGION' in os.environ: | ||
ec2_region = os.environ['EC2_REGION'] | ||
|
||
if not ec2_region: | ||
response = urllib2.urlopen('http://169.254.169.254/latest/meta-data/placement/availability-zone') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The docs all previously referred to this being a local action, so calls to AWS that can only be made from an instance don't make sense in that context? How will this behave if the controlling node isn't on ec2? will this throw an exception? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, agreed and mentioned the same to Bruce in the other ticket, he'll make We also need to keep endpoint connection open outside of regions for
|
||
az = response.read() | ||
for r in AWS_REGIONS: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. elb_regions is a function in boto that should be used instead of another variable that will need to be maintained externally to boto? |
||
if az.startswith(r): | ||
ec2_region = r | ||
break | ||
|
||
if not ec2_region: | ||
module.fail_json(msg = str("ec2_region not specified and unable to determine region from AWS.")) | ||
|
||
instance_id = module.params['instance_id'] | ||
elb_man = ElbManager(module, instance_id, ec2_elbs, ec2_access_key, | ||
ec2_secret_key) | ||
ec2_secret_key, ec2_region=ec2_region) | ||
|
||
for elb in [ ec2_elbs ]: | ||
if not elb_man.exists(elb): | ||
str="ELB %s does not exist" % elb | ||
module.fail_json(msg=str) | ||
|
||
if module.params['state'] == 'present': | ||
elb_man.register() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you use the elb regions needing endpoint hostnames goes away too