From 8694747558fcd1cbcda6c27f28946917a6a72ebf Mon Sep 17 00:00:00 2001 From: badra001 Date: Tue, 22 Feb 2022 13:20:12 -0500 Subject: [PATCH] add heritiage code --- code/ddns-lambda.py | 180 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 162 insertions(+), 18 deletions(-) diff --git a/code/ddns-lambda.py b/code/ddns-lambda.py index 309f630..76c7559 100755 --- a/code/ddns-lambda.py +++ b/code/ddns-lambda.py @@ -72,7 +72,7 @@ LOGGER = logging.getLogger() ACCOUNT = None REGION = None -VERSION = '0.0.13' +VERSION = '0.1.0' # Adjust the logging level [logging.INFO, logging.DEBUG, logging.WARNING, etc] LOGGER.setLevel(logging.DEBUG) @@ -86,6 +86,9 @@ DNS_RR_TTL = int(os.environ.get('DNS_RR_TimeToLive', '60')) DNS_RR_TTL = 60 if DNS_RR_TTL == 0 else DNS_RR_TTL TF_MODULE_VERSION = os.environ.get('tf_module_version', '(unknown)') +# for CNAMEs +TXT_RR_PREFIX = os.environ.get('HeritageTXTRecordPrefix', '_txt') +HERITAGE_TAG = os.environ.get('HeritageIdentifier', 'dynr53') print('Loading function v{} tf_module_version {}: {}'.format( VERSION, TF_MODULE_VERSION, datetime.datetime.now().time().isoformat())) @@ -132,12 +135,25 @@ def get_dynamodb_client(): print("Unexpected error: %s" % err) +def get_caller_account_id(): + """ + Get AWS Account ID from STS + :return str: AWS Account ID + """ + try: + return boto3.client('sts').get_caller_identity()['Account']) + except ClientError as err: + print("Unexpected error: %s" % err) + + def lambda_handler( event, context, - dynamodb_client=get_dynamodb_client(), - compute=get_ec2_client(), - route53=get_route53_client() + dynamodb_client = get_dynamodb_client(), + compute = get_ec2_client(), + route53 = get_route53_client() + + ): """ Check to see whether a DynamoDB table already exists. If not, create it. @@ -155,9 +171,9 @@ def lambda_handler( LOGGER.info("event: %s", str(event) + lineno()) LOGGER.info("context: %s", str(context) + lineno()) - caller_response = [] + caller_response=[] # Checking to make sure there is a dynamodb table named in the Env Variable - tables = list_tables(dynamodb_client) + tables=list_tables(dynamodb_client) LOGGER.info("tables: %s", str(tables)) if DDBNAME in tables['TableNames']: @@ -168,21 +184,23 @@ def lambda_handler( # Set variables # Get the state from the Event stream - state = event['detail']['state'] + state=event['detail']['state'] LOGGER.debug("instance state: %s", str(state) + lineno()) # Get the instance id, region, and tag collection - instance_id = event['detail']['instance-id'] + instance_id=event['detail']['instance-id'] LOGGER.debug("instance id: %s", str(instance_id) + lineno()) - region = event['region'] + region=event['region'] LOGGER.debug("region: %s", str(region) + lineno()) + account_id=get_caller_account_id() + LOGGER.debug("account_id: %s", str(account_id) + lineno()) # Only doing something if the state is running if state == 'running': LOGGER.debug("sleeping for maximum {} seconds {}".format(SLEEPTIME, lineno())) # wait increment and wait until maximum sleeptime - i = 1 + i=1 while i < SLEEPTIME: LOGGER.debug("waiting count: %s", str(i) + lineno()) time.sleep(1) @@ -190,12 +208,12 @@ def lambda_handler( try: # Get instance information - instance = get_instances(compute, instance_id) + instance=get_instances(compute, instance_id) - t_private_ip = instance['Reservations'][0]['Instances'][0]['PrivateIpAddress'] - t_private_dns_name = instance['Reservations'][0]['Instances'][0]['PrivateDnsName'] - t_subnet_id = instance['Reservations'][0]['Instances'][0]['SubnetId'] - t_vpc_id = instance['Reservations'][0]['Instances'][0]['VpcId'] + t_private_ip=instance['Reservations'][0]['Instances'][0]['PrivateIpAddress'] + t_private_dns_name=instance['Reservations'][0]['Instances'][0]['PrivateDnsName'] + t_subnet_id=instance['Reservations'][0]['Instances'][0]['SubnetId'] + t_vpc_id=instance['Reservations'][0]['Instances'][0]['VpcId'] # if key attributes are found, then break out of the loop if all([t_private_ip, t_private_dns_name, t_subnet_id, t_vpc_id]): @@ -211,9 +229,9 @@ def lambda_handler( # Remove null values from the response. You cannot save a dict/JSON # document in DynamoDB if it contains null values LOGGER.debug("instance: %s", str(instance) + lineno()) - instance = remove_empty_from_dict(instance) - instance_dump = json.dumps(instance, default=json_serial) - instance_attributes = json.loads(instance_dump) + instance=remove_empty_from_dict(instance) + instance_dump=json.dumps(instance, default = json_serial) + instance_attributes=json.loads(instance_dump) LOGGER.debug("instance_attributes: %s", str(instance_attributes) + lineno()) LOGGER.debug("trying to put instance information in " "dynamo table %s", str(instance_attributes) + lineno()) @@ -586,6 +604,17 @@ def lambda_handler( LOGGER.debug("valid_dns_zones:" " %s", str(valid_dns_zones) + lineno()) + # create the TXT heritage record + heritage = initialize_heritage(HERITAGE_TAG,VERSION, + { + 'instance_id': instance_id, + 'account_id': account_id, + 'region': region + } ) + add_heritage_item_timestamp(heritage,'create_time') + heritage_value = format_heritage(heritage) +# txt=format_heritage(h) + # Create OR Delete the A / PTR Record if state == 'running': # create the records @@ -608,6 +637,25 @@ def lambda_handler( ' with value: ' + str(private_ip)) + if len(heritage)>0: + LOGGER.debug("Creating heritage TXT resource records %s", lineno()) + create_resource_record( + route53, + final_hosted_zone_id, + final_private_hostname, + final_hosted_zone_name, + 'TXT', + heritage_value + ) + + caller_response.append('Created TXT record in zone id: ' + + str(final_hosted_zone_id) + + ' for hosted zone ' + + str(final_private_hostname) + '.' + + str(final_hosted_zone_name) + + ' with value: ' + + str(heritage_value)) + if reverse_zone_associated: create_resource_record( route53, @@ -625,6 +673,24 @@ def lambda_handler( 'in-addr.arpa with value: ' + str(final_private_dns_name)) + if len(heritage)>0: + create_resource_record( + route53, + reverse_lookup_zone_id, + reversed_ip_address, + 'in-addr.arpa', + 'TXT', + heritage_value + ) + + caller_response.append('Created TXT reverse record in zone id: ' + + str(reverse_lookup_zone_id) + + ' for hosted zone ' + + str(reversed_ip_address) + + 'in-addr.arpa with value: ' + + str(heritage_value)) + + except BaseException as err: LOGGER.info("unexpected error. %s\n", str(err) + lineno()) @@ -650,6 +716,26 @@ def lambda_handler( ' with value: ' + str(private_ip)) + if len(heritage)>0: + # pause 1 before deleting to avoid API limit + time.sleep(1) + delete_resource_record( + route53, + final_hosted_zone_id, + final_private_hostname, + final_hosted_zone_name, + 'TXT', + heritage_value + ) + + caller_response.append('Deleted TXT record in zone id: ' + + str(final_hosted_zone_id) + + ' for hosted zone ' + + str(final_private_hostname) + '.' + + str(final_hosted_zone_name) + + ' with value: ' + + str(heritage_value)) + # pause 1 before deleting to avoid API limit time.sleep(1) delete_resource_record( @@ -669,6 +755,26 @@ def lambda_handler( ' with value: ' + str(final_private_dns_name)) + if len(heritage)>0: + # pause 1 before deleting to avoid API limit + time.sleep(1) + delete_resource_record( + route53, + reverse_lookup_zone_id, + reversed_ip_address, + 'in-addr.arpa', + 'TXT', + heritage_value + ) + + caller_response.append('Deleted PTR record in zone id: ' + + str(reverse_lookup_zone_id) + + ' for hosted zone ' + + str(reversed_ip_address) + + str(private_dns_name) + + ' with value: ' + + str(heritage_value)) + except BaseException as err: LOGGER.debug("%s", str(err) + lineno()) @@ -708,6 +814,25 @@ def lambda_handler( ' with value: ' + str(final_private_dns_name)) + if len(heritage)>0: + create_resource_record( + route53, + cname_domain_suffix_id, + TXT_RR_PREFIX + '.' + cname_host_name, + cname_domain_suffix, + 'TXT', + heritage_value + ) + + caller_response.append('Created TXT for CNAME record in zone id: ' + + str(cname_domain_suffix_id) + + ' for hosted zone ' + + str(TXT_RR_PREFIX) + '.' + + str(cname_host_name) + '.' + + str(cname_domain_suffix) + + ' with value: ' + + str(heritage_value)) + except BaseException as err: LOGGER.debug("%s", str(err) + lineno()) else: @@ -733,6 +858,25 @@ def lambda_handler( ' with value: ' + str(final_private_dns_name)) + if len(heritage)>0: + delete_resource_record( + route53, + cname_domain_suffix_id, + TXT_RR_PREFIX + '.' + cname_host_name, + cname_domain_suffix, + 'TXT', + heritage_value + ) + + caller_response.append('Deleted TXT for CNAME record in zone id: ' + + str(cname_domain_suffix_id) + + ' for hosted zone ' + + str(TXT_RR_PREFIX) + '.' + + str(cname_host_name) + '.' + + str(cname_domain_suffix) + + ' with value: ' + + str(heritage_value)) + except BaseException as err: LOGGER.debug("%s", str(err) + lineno())