From f72aea5ec478207d9941c4eea1b5938045b2b5b2 Mon Sep 17 00:00:00 2001 From: Rawiri Blundell Date: Mon, 9 Feb 2026 11:15:46 +1300 Subject: [PATCH 1/3] lib/route53-functions: Add r53-zones and r53-zone-records functions. Introduce use of r53 namespace. --- lib/route53-functions | 118 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/lib/route53-functions b/lib/route53-functions index fb64136..c026355 100644 --- a/lib/route53-functions +++ b/lib/route53-functions @@ -82,3 +82,121 @@ 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 + + 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 + + aws route53 list-resource-record-sets --hosted-zone-id "${hosted_zone_id}" --output json | + jq -jr --arg record_type "${record_type}" '.ResourceRecordSets[] | select(.Type == $record_type or $record_type == "") | "\(.Name)\t\(.TTL)\t\(.Type)\t\(.ResourceRecords[]?.Value)\n"' | + columnise +} + From 0d824fdaa81fbd0a0888e3d9a87036fa32b31f10 Mon Sep 17 00:00:00 2001 From: Rawiri Blundell Date: Mon, 9 Feb 2026 11:16:37 +1300 Subject: [PATCH 2/3] aliases, functions, docs/command-reference.md: Regenerate with scripts/build --- aliases | 2 ++ docs/command-reference.md | 58 +++++++++++++++++++++++++++++++++++++-- functions | 2 ++ 3 files changed, 59 insertions(+), 3 deletions(-) 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 From 138f2d3ad33316971ec411c312e2d6ae66b2af9a Mon Sep 17 00:00:00 2001 From: Rawiri Blundell Date: Mon, 9 Feb 2026 15:36:57 +1300 Subject: [PATCH 3/3] lib/route53-functions: Correct handling for ALIAS records. Usage note: '--type A' will show all A-types including A aliases. '--type ALIAS' won't return results. Aliases can be post-filtered with e.g. '| grep -v ALIAS' --- lib/route53-functions | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/route53-functions b/lib/route53-functions index c026355..87c28e0 100644 --- a/lib/route53-functions +++ b/lib/route53-functions @@ -183,7 +183,7 @@ r53-zone-records(){ # 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 + local record_type hosted_zone_id jq_script case "${1}" in (--type) @@ -195,8 +195,18 @@ r53-zone-records(){ 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}" '.ResourceRecordSets[] | select(.Type == $record_type or $record_type == "") | "\(.Name)\t\(.TTL)\t\(.Type)\t\(.ResourceRecords[]?.Value)\n"' | + jq -jr --arg record_type "${record_type}" "${jq_script}" | columnise }