diff --git a/CHANGELOG.md b/CHANGELOG.md index 0aa4dcc..797f957 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -118,3 +118,16 @@ * 1.0.2 -- 2023-04-22 - add alllow assume role in (a) org and (b) to remote role r-inf-dynamic-reoute53-actions + +## Release 2.x + +* 2.0.0 -- 2023-04-28 + - code 2.0.0 + - use sessions + - make assume role call to remote account where PHZ is defined + - add dns entries to the DDB item, so that on stop/terminate we delete only what was added + - add flags: noforward, noptr, noheritage, nocname + - add data: boc:dns:ptrname + - add detection of a runnign EMR cluster with aws:elasticmapreduce: job-flow-id (cluster) and instance-group-role and use this to + set an alias defined in boc:dns:cname ({friendlyname}.master), but if it is a cluser node, only use the cname if it is master. If + it is not a cluster, set the cname diff --git a/code/ddns-lambda.py b/code/ddns-lambda.py index 18bef86..0d6654d 100755 --- a/code/ddns-lambda.py +++ b/code/ddns-lambda.py @@ -73,7 +73,7 @@ LOGGER = logging.getLogger() account_id = None region = None -VERSION = '1.2.0b90' +VERSION = '2.0.0rc2' # Read Env variables DEBUG_LOG_LEVEL = os.environ.get('DebugLogLevel', 'INFO') @@ -996,44 +996,7 @@ def lambda_handler( nodelete_dns_data.append(entry) dns_data = nodelete_dns_data -# # Process and delete A record and associated TXT record -# process_response = process_delete_records( -# route53, -# instance_id, -# zone_data_forward.zone_id, -# final_private_hostname, -# zone_data_forward.name, -# 'A', -# private_ip, -# heritage_value -# ) -# -# # only true if existing delete_records and the delete_success from the subroutine is true -# delete_records = delete_records and process_response['delete_success'] -# # append to the lsit -# caller_response = caller_response + process_response['msg'] -# count[f"delete_success.{process_response.get('delete_success')}"] += 1 -# -# if not flags['noreverse']: -# # Process and delete PTR record and associated TXT record -# process_response = process_delete_records( -# route53, -# instance_id, -# zone_data_reverse.zone_id, -# tag_data['ptr_entry'].hostname, -# tag_data['ptr_entry'].zonename, -# 'PTR', -# final_private_dns_name, -# heritage_value -# ) -# # only true if existing delete_records and the delete_success from the subroutine is true -# delete_records = delete_records and process_response['delete_success'] -# # append to the lsit -# caller_response = caller_response + process_response['msg'] -# count[f"delete_success.{process_response.get('delete_success')}"] += 1 - # Process the CNAME record only if it has passed the check -# if tag_data['option_cname'].valid: if cf_hostname: LOGGER.debug( f"cname record is valid - creating CNAME record host {cf_hostname} zone {cf_zonename}: {lineno()}") @@ -1048,8 +1011,8 @@ def lambda_handler( # create CNAME record in private zone if state == 'running': - try: - if not flags['nocname'] and (all([emr_status.is_cluster, emr_status.is_master]) or not emr_status.is_cluster): + if not flags['nocname'] and (all([emr_status.is_cluster, emr_status.is_master]) or not emr_status.is_cluster): + try: LOGGER.debug(f"cname_host_name: {cf_hostname} {lineno()}") LOGGER.debug(f"cname_domain_suffix: {cf_zonename} {lineno()}") LOGGER.debug(f"cname_domain_suffix_id: {cf_zonename_id} {lineno()}") @@ -1084,12 +1047,11 @@ def lambda_handler( caller_response.append('Failed to create ' + append_msg) LOGGER.error('Failed to create CNAME record: %s', create_response) - except BaseException as err: - LOGGER.error("instance: %s, unexpected error. %s\n", - instance_id, str(err) + lineno()) + except BaseException as err: + LOGGER.error("instance: %s, unexpected error. %s\n", + instance_id, str(err) + lineno()) - try: - if not flags['noheritage'] and not flags['nocname'] and (all([emr_status.is_cluster, emr_status.is_master]) or not emr_status.is_cluster): + try: if len(heritage) > 0: cf_hostname_txt = TXT_RR_PREFIX + '.' + cf_hostname LOGGER.debug( @@ -1121,28 +1083,14 @@ def lambda_handler( LOGGER.error( f"Failed to create TXT for CNAME record: {create_response}") - except BaseException as err: - LOGGER.error( - f"instance: {instance_id}, unexpected error: {err} {lineno()}") + except BaseException as err: + LOGGER.error( + f"instance: {instance_id}, unexpected error: {err} {lineno()}") + else: + if emr_status.is_cluster: + LOGGER.info( + f"instance {instance_id}: is_cluster && not is_master cluster_id {emr_status.cluster_id} NOT setting CNAME {cf_hostname} in zone {cf_zonename} {lineno()}") -# # not running, so process delete CNAME and associated TXT record -# else: -# # Process and delete CNAME record and associated TXT record -# process_response = process_delete_records( -# route53, -# instance_id, -# cname_domain_suffix_id, -# cname_host_name, -# cname_domain_suffix, -# 'CNAME', -# final_private_dns_name, -# heritage_value -# ) -# -# # only true if existing delete_records and the delete_success from the subroutine is true -# delete_records = delete_records and process_response['delete_success'] -# # append to the lsit -# caller_response = caller_response + process_response['msg'] # # update ddb entry to include dns entries written to be able to delete them properly if state == 'running': @@ -1180,7 +1128,6 @@ def lambda_handler( caller_response.insert(0, 'Successfully created recordsets') LOGGER.info(f"dns_data records written:\n{pformat(dns_data)}") -# put_instance_dns_data_item(dynamodb_client, DDBNAME, instance_id, dns_data) count['end'] = datetime.datetime.now() count['elapsed_ms'] = (count['end'] - count['start']).total_seconds() * 1000.0 @@ -1188,16 +1135,7 @@ def lambda_handler( ' '.join([f"{c}={count[c]}" for c in sorted(count.keys())])) return caller_response - -# def put_instance_dns_data_item(dynamodb_client, DDBNAME, instance_id, dns): -# dns_list = [dict(d._asdict()) for d in dns] -# dns_info = json.dumps(dns_list, default=json_serial) -# dns_info = json.dumps(dns_list) -## -# LOGGER.debug(f"put dns data into {instance_id}/dns: {str(dns_info)}: {lineno()}") -# put_item_in_dynamodb_table(dynamodb_client, DDBNAME, f'{instance_id}/dns', dns_info) -# LOGGER.debug(f"done putting dns item in dynamo table {lineno()}") -# return +# end lambda_handler def get_cname_from_tags(tags): @@ -1252,17 +1190,6 @@ def get_instances(client, instance_id): return instance_data -# def list_hosted_zones(client): -# """ -# Get route53 hosted zones -# :param client: -# :return: -# """ -# try: -# return client.list_hosted_zones() -# except ClientError as err: -# LOGGER.info("unexpected error. %s\n", str(err) + lineno()) - def new_list_hosted_zones(client, instance_id): """ @@ -3117,7 +3044,9 @@ def tags_to_dict(tags): :return dict(string): flag settings in defaultdict for controlling which names are registered and when """ - tag_dict = {tag['Key'].lstrip().rstrip(): tag['Value'] for tag in tags} + tag_dict = {} + if len(tags) > 0: + tag_dict = {tag.get('Key', '').lstrip().rstrip(): tag.get('Value', '') for tag in tags} return tag_dict @@ -3134,7 +3063,8 @@ def process_tags_flags(tags): :return dict(string): flag settings in defaultdict for controlling which names are registered and when """ - tag_dict = {tag['Key'].lstrip().lower(): tag['Value'].lower() for tag in tags} +# tag_dict = {tag['Key'].lstrip().lower(): tag['Value'].lower() for tag in tags} + tag_dict = {k.lower(): v.lower() for k, v in tags_to_dict(tags)} flags_dict = defaultdict(lambda: False) flags = tag_dict.get(TAGKEY_FLAGS.lower(), '').split(',') for flag in flags: @@ -3171,7 +3101,8 @@ def process_tags_option_cname(tags): : return tuple(bool, str, str): true | false if vaid, hostname, domainname """ - tag_dict = {tag['Key'].lstrip().lower(): tag['Value'] for tag in tags} +# tag_dict = {tag['Key'].lstrip().lower(): tag['Value'] for tag in tags} + tag_dict = {k.lower(): v for k, v in tags_to_dict(tags)} # value = tag_dict.get(TAGKEY_CNAME.lower(), '').split(',') # need additional work to handle a comma-separated list value = tag_dict.get(TAGKEY_CNAME.lower(), '') @@ -3186,7 +3117,8 @@ def process_tags_option_zone(tags): : return tuple(bool, str, str): true | false if vaid, hostname, domainname """ - tag_dict = {tag['Key'].lstrip().lower(): tag['Value'] for tag in tags} +# tag_dict = {tag['Key'].lstrip().lower(): tag['Value'] for tag in tags} + tag_dict = {k.lower(): v for k, v in tags_to_dict(tags)} value = tag_dict.get(TAGKEY_ZONE.lower(), '') return process_tags_value(value) @@ -3199,7 +3131,8 @@ def process_tags_option_name(tags): : return: """ - tag_dict = {tag['Key'].lstrip().lower(): tag['Value'] for tag in tags} +# tag_dict = {tag['Key'].lstrip().lower(): tag['Value'] for tag in tags} + tag_dict = {k.lower(): v for k, v in tags_to_dict(tags)} value = tag_dict.get(TAGKEY_HOSTNAME.lower(), '') return process_tags_value(value) @@ -3218,7 +3151,8 @@ def process_tags_option_ptrname(tags): : return: """ - tag_dict = {tag['Key'].lstrip().lower(): tag['Value'] for tag in tags} +# tag_dict = {tag['Key'].lstrip().lower(): tag['Value'] for tag in tags} + tag_dict = {k.lower(): v for k, v in tags_to_dict(tags)} value = tag_dict.get(TAGKEY_PTRNAME.lower(), '') return process_tags_value(value) @@ -3231,7 +3165,8 @@ def process_tags_name(tags): : return: """ - tag_dict = {tag['Key'].lstrip().lower(): tag['Value'] for tag in tags} +# tag_dict = {tag['Key'].lstrip().lower(): tag['Value'] for tag in tags} + tag_dict = {k.lower(): v for k, v in tags_to_dict(tags)} value = tag_dict.get('name', '') return process_tags_value(value) diff --git a/code/ddns-lambda.zip b/code/ddns-lambda.zip index 8e84052..63919ef 100644 Binary files a/code/ddns-lambda.zip and b/code/ddns-lambda.zip differ diff --git a/version.tf b/version.tf index 02c6357..6b49608 100644 --- a/version.tf +++ b/version.tf @@ -1,3 +1,3 @@ locals { - _module_version = "1.0.2" + _module_version = "2.0.0" }