From 13811c08f816d24af65518a56523bf3964eab9fb Mon Sep 17 00:00:00 2001 From: Sebastian Dahlgren Date: Thu, 19 Jul 2018 08:42:34 +0200 Subject: [PATCH] Revert "Porting to boto3 and explicitly sending AllowReassociation=False" --- aws_ec2_assign_elastic_ip/__init__.py | 76 ++++++++++++--------------- requirements.txt | 3 +- setup.py | 6 +-- 3 files changed, 35 insertions(+), 50 deletions(-) diff --git a/aws_ec2_assign_elastic_ip/__init__.py b/aws_ec2_assign_elastic_ip/__init__.py index 68ba9ea..3e46357 100644 --- a/aws_ec2_assign_elastic_ip/__init__.py +++ b/aws_ec2_assign_elastic_ip/__init__.py @@ -8,9 +8,10 @@ else: import os.path as ospath +import boto.utils from netaddr import IPNetwork, AddrFormatError, AddrConversionError -from boto3 import resource, client -from ec2_metadata import ec2_metadata +from boto.ec2 import connect_to_region +from boto.utils import get_instance_metadata from aws_ec2_assign_elastic_ip.command_line_options import ARGS as args @@ -22,38 +23,36 @@ region = args.region -if not region: - region = ec2_metadata.region +# Fetch instance metadata +metadata = get_instance_metadata(timeout=1, num_retries=1) +if metadata: + try: + region = metadata['placement']['availability-zone'][:-1] + except KeyError: + pass # Connect to AWS EC2 if args.access_key or args.secret_key: # Use command line credentials - ec2_resource = resource('ec2', - region_name=region, - aws_access_key_id=args.access_key, - aws_secret_access_key=args.secret_key) - ec2_client = client('ec2', - region_name=region, + connection = connect_to_region( + region, aws_access_key_id=args.access_key, aws_secret_access_key=args.secret_key) else: # Use environment vars or global boto configuration or instance metadata - ec2_resource = resource('ec2', region_name=region) - ec2_client = client('ec2', region_name=region) - + connection = connect_to_region(region) logger.info('Connected to AWS EC2 in {0}'.format(region)) def main(): """ Main function """ # Get our instance name - instance_id = ec2_metadata.instance_id + instance_id = boto.utils.get_instance_metadata()['instance-id'] # Check if the instance already has an Elastic IP # If so, exit if _has_associated_address(instance_id): - logger.warning( - '{0} is already assigned an Elastic IP. Exiting.'.format( + logger.warning('{0} is already assigned an Elastic IP. Exiting.'.format( instance_id)) sys.exit(0) @@ -76,7 +75,7 @@ def _assign_address(instance_id, address): :type instance_id: str :param instance_id: Instance ID - :type address: EC2.VpcAddress or EC2.ClassicAddress + :type address: boto.ec2.address :param address: Elastic IP address :returns: None """ @@ -87,15 +86,14 @@ def _assign_address(instance_id, address): try: if address.domain == 'standard': # EC2 classic association - address.associate( - InstanceId=instance_id, - AllowReassociation=False) + connection.associate_address( + instance_id, + public_ip=address.public_ip) else: # EC2 VPC association - address.associate( - AllocationId=address.allocation_id, - InstanceId=instance_id, - AllowReassociation=False) + connection.associate_address( + instance_id, + allocation_id=address.allocation_id) except Exception as error: logger.error('Failed to associate {0} with {1}. Reason: {2}'.format( instance_id, address.public_ip, error)) @@ -108,40 +106,34 @@ def _assign_address(instance_id, address): def _get_unassociated_address(): """ Return the first unassociated EIP we can find - :returns: EC2.VpcAddress or EC2.ClassicAddress or None + :returns: boto.ec2.address or None """ eip = None - for address in ec2_client.describe_addresses().get('Addresses', []): + for address in connection.get_all_addresses(): # Check if the address is associated - if address.get('InstanceId'): + if address.instance_id: logger.debug('{0} is already associated with {1}'.format( - address.get('PublicIp', ''), address.get('InstanceId', ''))) + address.public_ip, address.instance_id)) continue # Check if the address is attached to an ENI - if address.get('NetworkInterfaceId'): + if address.network_interface_id: logger.debug('{0} is already attached to {1}'.format( - address.get('PublicIp', ''), - address.get('NetworkInterfaceId', ''))) + address.public_ip, address.network_interface_id)) continue # Check if the address is in the valid IP's list - if _is_valid(address.get('PublicIp')): + if _is_valid(address.public_ip): logger.debug('{0} is unassociated and OK for us to take'.format( - address.get('PublicIp', ''))) - - if (address.get('Domain') == 'vpc'): - eip = ec2_resource.VpcAddress(address.get('AllocationId')) - else: - eip = ec2_resource.ClassicAddress(address.get('AllocationId')) - + address.public_ip)) + eip = address break else: logger.debug( '{0} is unassociated, but not in the valid IPs list'.format( - address.get('PublicIp', ''))) + address.public_ip, address.instance_id)) if not eip: logger.error('No unassociated Elastic IP found!') @@ -156,9 +148,7 @@ def _has_associated_address(instance_id): :param instance_id: Instances ID :returns: bool -- True if the instance has an Elastic IP associated """ - if ec2_client.describe_addresses( - Filters=[{'Name':'instance-id', 'Values':[instance_id]}]).get('Addresses'): - + if connection.get_all_addresses(filters={'instance-id': instance_id}): return True return False diff --git a/requirements.txt b/requirements.txt index 7d65fec..f532ab0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,2 @@ +boto>=2.29.1 netaddr>=0.7.12 -boto3>=1.7.51 -ec2-metadata>=1.6.0 diff --git a/setup.py b/setup.py index ef45f1f..12c1e33 100644 --- a/setup.py +++ b/setup.py @@ -24,11 +24,7 @@ scripts=['aws-ec2-assign-elastic-ip'], include_package_data=True, zip_safe=False, - install_requires=[ - 'boto3 >= 1.7.51', - 'netaddr >= 0.7.12', - 'ec2-metadata >= 1.6.0' - ], + install_requires=['boto >= 2.36.0', 'netaddr >= 0.7.12'], classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Console',