Last active
August 29, 2025 17:36
-
-
Save neuhaus/9f26a85f426d32e9d05c6db9eadc2db2 to your computer and use it in GitHub Desktop.
retrieve all domain zones from IONOS using the API and convert them into bind zone files.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Check if API key is provided | |
| if [ -z "$IONOS_API_KEY" ]; then | |
| echo "Error: IONOS_API_KEY environment variable must be set" | |
| exit 1 | |
| fi | |
| # Base API URL | |
| API_BASE="https://api.hosting.ionos.com/dns/v1" | |
| # Function to convert records to BIND zone format | |
| convert_zone_to_bind() { | |
| local zone_name="$1" | |
| local records="$2" | |
| local output_file="${zone_name}.zone" | |
| # Generate zone file header | |
| cat > "$output_file" << EOL | |
| \$ORIGIN ${zone_name}. | |
| \$TTL 3600 | |
| @ IN SOA ns1.${zone_name}. hostmaster.${zone_name}. ( | |
| $(date +%Y%m%d%H) ; Serial | |
| 3600 ; Refresh | |
| 1800 ; Retry | |
| 604800 ; Expire | |
| 86400 ) ; Minimum TTL | |
| ; Nameservers | |
| @ IN NS ns1.${zone_name}. | |
| @ IN NS ns2.${zone_name}. | |
| EOL | |
| # Process each record | |
| echo "$records" | jq -c '.[]' | while read -r record; do | |
| local name=$(echo "$record" | jq -r '.name') | |
| local type=$(echo "$record" | jq -r '.type') | |
| local content=$(echo "$record" | jq -r '.content') | |
| local ttl=$(echo "$record" | jq -r '.ttl // 3600') | |
| local prio=$(echo "$record" | jq -r '.prio // ""') | |
| # Strip zone name from the record name if present | |
| name="${name%%.$zone_name}" | |
| # Convert record types to BIND format | |
| case "$type" in | |
| A) | |
| echo "${name:-@} IN A $content" >> "$output_file" | |
| ;; | |
| AAAA) | |
| echo "${name:-@} IN AAAA $content" >> "$output_file" | |
| ;; | |
| CNAME) | |
| echo "${name:-@} IN CNAME $content." >> "$output_file" | |
| ;; | |
| MX) | |
| echo "${name:-@} IN MX $prio $content." >> "$output_file" | |
| ;; | |
| NS) | |
| echo "${name:-@} IN NS $content." >> "$output_file" | |
| ;; | |
| TXT) | |
| echo "${name:-@} IN TXT $content" >> "$output_file" | |
| ;; | |
| SRV) | |
| # SRV record format: _service._protocol.name TTL class SRV priority weight port target | |
| echo "$name IN SRV $prio 1 $(echo "$content" | cut -d' ' -f2-)" >> "$output_file" | |
| ;; | |
| CAA) | |
| echo "${name:-@} IN CAA $content" >> "$output_file" | |
| ;; | |
| esac | |
| done | |
| echo "Generated zone file for $zone_name: $output_file" | |
| } | |
| # Retrieve list of zones | |
| zones=$(curl -s -X GET "$API_BASE/zones" \ | |
| -H "X-API-Key: $IONOS_API_KEY" \ | |
| -H "Accept: application/json") | |
| # Process each zone | |
| echo "$zones" | jq -c '.[]' | while read -r zone; do | |
| zone_id=$(echo "$zone" | jq -r '.id') | |
| zone_name=$(echo "$zone" | jq -r '.name') | |
| # Retrieve zone details with all records | |
| zone_details=$(curl -s -X GET "$API_BASE/zones/$zone_id" \ | |
| -H "X-API-Key: $IONOS_API_KEY" \ | |
| -H "Accept: application/json") | |
| # Extract and convert records | |
| records=$(echo "$zone_details" | jq '.records') | |
| convert_zone_to_bind "$zone_name" "$records" | |
| done |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the feedback. While i haven't had this issue, i've added the trailing dot to NS, CNAME and NS records in the script. SRV records are a bit more tricky so i leave that as an exercise for the reader.