diff --git a/code/ddns-lambda.py b/code/ddns-lambda.py index af0cdfa..38f1a34 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.0b88' +VERSION = '1.2.0b89' # Read Env variables DEBUG_LOG_LEVEL = os.environ.get('DebugLogLevel', 'INFO') @@ -632,12 +632,14 @@ def lambda_handler( # associated with the VPC. If so, it will set the zone name to be used later. has_dhcp_dns_zone_associated_vpc = False + dhcp_zone_id = None if dhcp_zone is not None: LOGGER.debug("configuration dhcp_zone: %s", str(dhcp_zone) + lineno()) if dhcp_zone in phz_collection_by_vpc: private_hosted_zone_name = dhcp_zone private_hosted_zone_item = phz_collection_by_vpc[private_hosted_zone_name] + dhcp_zone_id = private_hosted_zone_item['zone_id'] has_dhcp_dns_zone_associated_vpc = True LOGGER.debug("by_vpc.private_hosted_zone_name dhcp_zone: %s found, item: %s", str(private_hosted_zone_name) + lineno(), private_hosted_zone_item) @@ -653,19 +655,31 @@ def lambda_handler( LOGGER.debug("New flags structure: %s", str(pformat(flags)) + lineno()) LOGGER.info("Options flags: " + ' '.join([f"{x}={flags[x]}" for x in flags])) + hostname_tuple = namedtuple( + 'Hostname', ['zone_exists', 'valid', 'hostname', 'zonename', 'zone_id', 'name']) tag_data = {} - tag_data_fields = ['defined', 'valid', 'hostname', 'zonename'] - tag_data_tuple = namedtuple('TagData', tag_data_fields) - tag_data['option_cname'] = tag_data_tuple(*process_tags_option_cname(tags)) - tag_data['option_zone'] = tag_data_tuple(*process_tags_option_zone(tags)) - tag_data['option_name'] = tag_data_tuple(*process_tags_option_name(tags)) - tag_data['option_ptrname'] = tag_data_tuple(*process_tags_option_ptrname(tags)) - tag_data['dhcp_options'] = tag_data_tuple(True, - has_dhcp_dns_zone_associated_vpc, None, private_hosted_zone_name) - tag_data['ptr_entry'] = tag_data_tuple( - True, True, reversed_entry, reversed_lookup_zone) - tag_data['name'] = tag_data_tuple(*process_tags_name(tags)) - LOGGER.debug("New tag_data structure: %s", str(pformat(tag_data)) + lineno()) +# tag_data_fields = ['defined', 'valid', 'hostname', 'zonename'] +# tag_data_tuple = namedtuple('TagData', tag_data_fields) +# tag_data['option_cname'] = tag_data_tuple(*process_tags_option_cname(tags)) +# tag_data['option_zone'] = tag_data_tuple(*process_tags_option_zone(tags)) +# tag_data['option_name'] = tag_data_tuple(*process_tags_option_name(tags)) +# tag_data['option_ptrname'] = tag_data_tuple(*process_tags_option_ptrname(tags)) +# tag_data['dhcp_options'] = tag_data_tuple(True, +# has_dhcp_dns_zone_associated_vpc, None, private_hosted_zone_name) +# tag_data['ptr_entry'] = tag_data_tuple( +# True, True, reversed_entry, reversed_lookup_zone) +# tag_data['name'] = tag_data_tuple(*process_tags_name(tags)) + + tag_data['option_cname'] = process_tags_option_cname(tags) + tag_data['option_zone'] = process_tags_option_zone(tags) + tag_data['option_name'] = process_tags_option_name(tags) + tag_data['option_ptrname'] = process_tags_option_ptrname(tags) +# tag_data['dhcp_options'] = hostname_tuple(has_dhcp_dns_zone_associated_vpc, False, None, private_hosted_zone_name, dhcp_zone_id, private_hosted_zone_name ) + tag_data['dhcp_options'] = process_tags_value(dhcp_zone) + tag_data['ptr_entry'] = process_tags_value(reversed_entry) + tag_data['name'] = process_tags_name(tags) + + LOGGER.info("New tag_data structure: %s", str(pformat(tag_data)) + lineno()) emr_status = discover_emr_cluster(tags_dict) LOGGER.info(f"discover_emr instance: {instance_id} result {emr_status}") @@ -3132,12 +3146,13 @@ def process_tags_value(name): :return tuple(bool,str,str): true|false if vaid, hostname, domainname """ - if name != '': - return (True,) + parse_hostname_to_components(name) + return parse_hostname_to_components(name) +# if name != '': +# return (True,) + parse_hostname_to_components(name) # components = parse_hostname_to_components(name) # if components: # return (True, components[0], components[1]) - return (name != '', False, name, None) +# return (name != '', False, name, None) def process_tags_option_cname(tags): @@ -3260,24 +3275,46 @@ def parse_hostname_to_components(name): the Name, boc:dns:cname or boc:dns:name tags contain myhost.db.common.edl.census.gov, and the zone is common.edl.census.gov, simply checking at the first dot (host==myhost, domain==db.common.edl.census.gov) will fail. This will go through the list of PHZs found for the VPC for each of the possible domains, and return the name components if a match is found. - That returned name/zone shoudl be used for all settings. If the zone is not found it will parse into first part before dot, remainder. + That returned name/zone should be used for all settings. If the zone is not found it will parse into first part before dot, remainder. + + This returns: + - zone_exists: if the PHZ is found associated to this VPC + - valid: the name conists of a hostname + domainname, where the domainname is > 1 item (alias.db is not valid, alias.db.zone is valid, though not really) + - hostname: hostname part of name. If not valid, it is the whole name passed in + - zonename: the domain part of the name. If not valid, it will be None + - zone_id: if zone exists, the zone id + - name: the original name from the arguments :param str name: FQDN to parse and find existing defined PHZ - :return (bool,str,str): Tuple containing found-PHZ (True|False), hostname components (may include dot) and domain name for which a PHZ exists. None is returned if not found. + :return namedtuple: Tuple, see above """ global phz_collection_by_vpc + + hostname_tuple = namedtuple( + 'Hostname', ['zone_exists', 'valid', 'hostname', 'zonename', 'zone_id', 'name']) + + if name == '' or name == None: + return hostname_tuple(False, False, None, None, None, None) names = name.rstrip('.').split('.') for i in range(len(names)): host = '.'.join(names[0:i]) domain = '.'.join(names[i:]) + '.' - if phz_collection_by_vpc.get(domain): - return (True, host, domain) - host = names[0] - domain = '.'.join(names[1:]) + '.' + item = phz_collection_by_vpc.get(domain) + if item: + return hostname_tuple(True, True, host, domain, item['zone_id'], name) LOGGER.info( f"No PHZ found for any domain components of {name} associated with this vpc, returing host {host} domain {domain}: {lineno()}") - return (False, host, domain) + if len(names) > 2: + host = names[0] + domain = '.'.join(names[1:]) + '.' + LOGGER.debug( + f"zone does not exist but name {name} appears to be a legal domain (>2 components) setting hostname {host} and zone {domain}: {lineno()}") + return hostname_tuple(False, True, host, domain, None, name) + else: + host = '.'.join(names) + '.' + domain = '' + return hostname_tuple(False, False, host, domain, None, name) def create_fqdn(host, zone): diff --git a/code/ddns-lambda.zip b/code/ddns-lambda.zip index bb95afc..5de9daf 100644 Binary files a/code/ddns-lambda.zip and b/code/ddns-lambda.zip differ