diff --git a/aliases b/aliases index 3dcccdb..ef1674d 100644 --- a/aliases +++ b/aliases @@ -198,6 +198,8 @@ alias private-dns-zone-record-sets='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma priv alias private-dns-zones='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma private-dns-zones' alias private-endpoint-custom-dns-configs='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma private-endpoint-custom-dns-configs' alias private-endpoints='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma private-endpoints' +alias r53-zone-records='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma r53-zone-records' +alias r53-zones='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma r53-zones' alias rds-db-clusters='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma rds-db-clusters' alias rds-db-instances='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma rds-db-instances' alias region-each='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma region-each' diff --git a/docs/command-reference.md b/docs/command-reference.md index 0a132dd..72840a8 100644 --- a/docs/command-reference.md +++ b/docs/command-reference.md @@ -976,6 +976,9 @@ List CloudFormation stack for asg(s) List scaling activities for Autoscaling Group(s) +azure.azcli + + ## azure-commands @@ -1375,9 +1378,6 @@ List dns resolvers in a VNet -azure.azcli - - ## backup-commands @@ -2044,6 +2044,58 @@ EXAMPLE: +### r53-zones + +List Route53 Hosted Zones + + $ r53-zones + /hostedzone/Z3333333333333 5 NotPrivateZone bash-my-aws.org. + /hostedzone/Z5555555555555 2 NotPrivateZone bash-my-universe.com. + /hostedzone/Z4444444444444 3 NotPrivateZone bashmyaws.org. + /hostedzone/Z1111111111111 3 NotPrivateZone bash-my-aws.com. + /hostedzone/Z2222222222222 3 NotPrivateZone bashmyaws.com. +SUPPORTED OPTION FLAGS: + '-P|--private' + '-p|--public' + + RATIONALE: + Sometimes you can find the undesirable situation of the same domain name + being used for both public and private zones. This enables differentiation + + '-x|--exact' + + RATIONALE + The default behaviour matches a given domain and its subdomains e.g: + 'r53-zones contoso.com' would match contoso.com, prod.contoso.com, internal.contoso.com etc + 'r53-zones --exact contoso.com' matches only contoso.com + + +### r53-zone-records + +List Records in a Route53 Hosted Zone +NOTE: AWS alias records are shown with a fake TTL of 86400. + + $ r53-zones bash-my-aws.org + /hostedzone/ZJ6ZCG2UD6OKX 5 NotPrivateZone bash-my-aws.org. + + $ r53-zones bash-my-aws.org | r53-zone-records + bash-my-aws.org. 900 SOA ns-1549.awsdns-01.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400 + bash-my-aws.org. 300 NS ns-1464.awsdns-55.org. + bash-my-aws.org. 300 A 185.199.108.153 + bash-my-aws.org. 300 A 185.199.109.153 + bash-my-aws.org. 300 TXT "google-site-verification=RbKejqu95y4Q78BkWnjaiM0rl6SYugtTdVLexK35b2k" + lb.bash-my-aws.org. 86400 ALIAS dualstack.lb-bmaorg-12345.us-east-1.elb.amazonaws.com +SUPPORTED OPTIONS: +--type [Required: type] + RATIONALE: + This allows robust filtering by record type + + EXAMPLE: + $ r53-zones bash-my-aws.org | r53-zone-records --type A + bash-my-aws.org. 300 A 185.199.108.153 + bash-my-aws.org. 300 A 185.199.109.153 + + ## s3-commands diff --git a/functions b/functions index 4d4cd43..bd0e705 100644 --- a/functions +++ b/functions @@ -198,6 +198,8 @@ private-dns-zone-record-sets private-dns-zones private-endpoint-custom-dns-configs private-endpoints +r53-zone-records +r53-zones rds-db-clusters rds-db-instances region diff --git a/lib/route53-functions b/lib/route53-functions index fb64136..87c28e0 100644 --- a/lib/route53-functions +++ b/lib/route53-functions @@ -82,3 +82,131 @@ hosted-zone-delete() { --id "$zone_id" done } + +r53-zones(){ + + # List Route53 Hosted Zones + # + # $ r53-zones + # /hostedzone/Z3333333333333 5 NotPrivateZone bash-my-aws.org. + # /hostedzone/Z5555555555555 2 NotPrivateZone bash-my-universe.com. + # /hostedzone/Z4444444444444 3 NotPrivateZone bashmyaws.org. + # /hostedzone/Z1111111111111 3 NotPrivateZone bash-my-aws.com. + # /hostedzone/Z2222222222222 3 NotPrivateZone bashmyaws.com. + + # SUPPORTED OPTION FLAGS: + + # '-P|--private' + # '-p|--public' + # + # RATIONALE: + # Sometimes you can find the undesirable situation of the same domain name + # being used for both public and private zones. This enables differentiation + # + # '-x|--exact' + # + # RATIONALE + # The default behaviour matches a given domain and its subdomains e.g: + # 'r53-zones contoso.com' would match contoso.com, prod.contoso.com, internal.contoso.com etc + # 'r53-zones --exact contoso.com' matches only contoso.com + + local ids filters query_filter filter_parts exact_match zone_name joined + filter_parts=() + exact_match="" + zone_name="" + + while (( $# > 0 )); do + case "$1" in + (-P|--private) filter_parts+=("Config.PrivateZone == \`true\`"); shift 1 ;; + (-p|--public) filter_parts+=("Config.PrivateZone == \`false\`"); shift 1 ;; + (-x|--exact) exact_match=true; shift 1 ;; + (*) break ;; + esac + done + + ids=$(skim-stdin) + + if [[ -n "${exact_match}" && -n "${1}" ]]; then + zone_name="${1}" + [[ "${zone_name}" != *. ]] && zone_name="${zone_name}." + filter_parts+=("Name == '${zone_name}'") + shift 1 + fi + + filters=$(__bma_read_filters "$@") + + [[ -n "${ids}" ]] && filter_parts+=("contains(['${ids// /"','"}'], Id)") + + if (( ${#filter_parts[@]} > 0 )); then + joined=$(printf -- '%s && ' "${filter_parts[@]}") + query_filter="?${joined% && }" + fi + + aws route53 list-hosted-zones \ + --output text \ + --query " + HostedZones[${query_filter}].[ + Id, + ResourceRecordSetCount, + (Config.PrivateZone && 'PrivateZone') || 'NotPrivateZone', + Name + ]" | + sort -k 4 | + grep -E -- "${filters}" | + columnise +} + +r53-zone-records(){ + + # List Records in a Route53 Hosted Zone + # NOTE: AWS alias records are shown with a fake TTL of 86400. + # + # $ r53-zones bash-my-aws.org + # /hostedzone/ZJ6ZCG2UD6OKX 5 NotPrivateZone bash-my-aws.org. + # + # $ r53-zones bash-my-aws.org | r53-zone-records + # bash-my-aws.org. 900 SOA ns-1549.awsdns-01.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400 + # bash-my-aws.org. 300 NS ns-1464.awsdns-55.org. + # bash-my-aws.org. 300 A 185.199.108.153 + # bash-my-aws.org. 300 A 185.199.109.153 + # bash-my-aws.org. 300 TXT "google-site-verification=RbKejqu95y4Q78BkWnjaiM0rl6SYugtTdVLexK35b2k" + # lb.bash-my-aws.org. 86400 ALIAS dualstack.lb-bmaorg-12345.us-east-1.elb.amazonaws.com + + # SUPPORTED OPTIONS: + + # --type [Required: type] + # RATIONALE: + # This allows robust filtering by record type + # + # EXAMPLE: + # $ r53-zones bash-my-aws.org | r53-zone-records --type A + # bash-my-aws.org. 300 A 185.199.108.153 + # bash-my-aws.org. 300 A 185.199.109.153 + + local record_type hosted_zone_id jq_script + + case "${1}" in + (--type) + record_type="${2}" + shift 2 + ;; + esac + + hosted_zone_id="$(skim-stdin "${@}")" + [[ -z "${hosted_zone_id}" ]] && __bma_usage "r53-zone-records" && return 1 + + read -r -d '' jq_script <<'EOF' + .ResourceRecordSets[] | + select(.Type == $record_type or $record_type == "") | + if .AliasTarget then + "\(.Name)\t86400\tALIAS\t\(.AliasTarget.DNSName)\n" + else + "\(.Name)\t\(.TTL)\t\(.Type)\t\(.ResourceRecords[].Value)\n" + end +EOF + + aws route53 list-resource-record-sets --hosted-zone-id "${hosted_zone_id}" --output json | + jq -jr --arg record_type "${record_type}" "${jq_script}" | + columnise +} +