#!/bin/bash
#
# pdns-tools
# https://git.stack-source.com/msb/pdns-tools
# Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

# load include file
source $(dirname $0)/pdns.sh

help()
{
  echo "Add new zone to DNS"
  echo ""
  echo "usage: $thisfilename -z <zone> [-m <master>] [-t <type>]  [-a <account>] [-w <comment>] [-b] [-h]"
  echo ""
  echo "  -h            Print this help."
  echo "  -z <zone>     Zone (domain name) to add."
  echo "  -m <master>   IP address of master, if this zone is of type SLAVE."
  echo "  -t <type>     Defaults to NATIVE. Can also be MASTER or SLAVE. If type is SLAVE be sure to set master IP."
  echo "  -a <account>  Account that controls this zones. For tying in to Control Panel or other custom admins."
  echo "  -w <comment>  Write an optional comment/note. Will be associated with the SOA Resource Record."
  echo "  -b            Bare - create zone without any Resource Records. Normally a default set of RR are created."
}

pdns:getoptions "$@"

# check for zone
if [[ -z $zone ]]; then
  echo "zone is required"
  exit 1
fi

# first query to see if zone already exists
zone_status=$(/usr/bin/curl --silent --output /dev/null --write-out "%{http_code}" -H "X-API-Key: $api_key" "$api_base_url/zones/$zone?rrsets=false")

if [[ $zone_status = 200 ]]; then
  echo Zone $zone already exists.
  exit 1
elif [[ $zone_status = 404 ]]; then

  # zone does not exist, create new zone now

  # generate serial
  serial=$(date +%Y%m%d00)

  # set type (kind). NATIVE (default), MASTER or SLAVE
  if [[ -n $type ]]; then
    kind=$type
  else
    kind="NATIVE"
  fi

  # zone
  data='{'

  if [[ -n $account ]]; then
    data="$data\"account\":\"$account\","
  fi
  data="$data\"name\":\"$zone.\","
  data="$data\"kind\":\"$kind\","
  if [[ -n $master ]]; then
    data="$data\"masters\":[\"$master\"],"
  fi
  data="$data\"serial\":\"$serial\","
  data="$data\"nameservers\":[],"
  data="$data\"rrsets\":["

  # create SOA
  data="$data{"
  data="$data\"name\":\"${zone}.\","
  data="$data\"type\":\"SOA\","
  data="$data\"ttl\":${zone_defaults_ttl},"
  data="$data\"records\":["
  data="$data{"
  data="$data\"content\":\"$zone_default_ns. $zone_defaults_mbox. $serial $zone_defaults_refresh $zone_defaults_retry $zone_defaults_expire $zone_defaults_minimum\"",
  data="$data\"disabled\":false"
  data="$data}"
  data="$data]"

  # if set add comment, gets associated with SOA
  if [[ -n $comment ]]; then
    # set account to hostname if not specified with -a option
    if [[ -z $account ]]; then
      account=$(/usr/bin/hostname -f)
    fi
    data="$data,\"comments\":[{\"content\":\"$comment\",\"account\":\"$account\"}]"
  fi

  if [[ -n $bare ]]; then
    # do not add default records
    data="$data}"
  else
    # add default records
    data="$data},"

    # get number of default records to add
    default_records_count=${#default_records[@]}
    records_count=0

    # add default records
    for record in "${default_records[@]}"; do

      records_count=$((records_count+1))

      # replace @ with zone
      record=$(echo ${record} | sed -e "s/@/$zone/g")

      # turn record row info in to array
      orig_ifs="$IFS"
      IFS='|'
      read -r -a recordArray <<< "$record"
      IFS="$orig_ifs"

      # extract record info from array
      rr_name=${recordArray[0]}
      rr_type=${recordArray[1]}
      rr_content=${recordArray[2]}

      # munge data as needed
      if pdns::validate_domain $rr_content; then
        rr_content="$rr_content."
      fi
      if [[ $rr_type = TXT ]]; then
        rr_content="\\\"$rr_content\\\""
      fi
      if [[ $rr_type = MX ]]; then
        rr_content="$rr_content."
      fi

      # add record
      data="$data{"
      data="$data\"name\":\"${rr_name}.\","
      data="$data\"type\":\"${rr_type}\","
      data="$data\"ttl\":${zone_defaults_ttl},"
      data="$data\"records\":["
      data="$data{"
      data="$data\"content\":\"${rr_content}\"",
      data="$data\"disabled\":false"
      data="$data}"
      data="$data]"

      if [[ $records_count = $default_records_count ]]; then
        data="$data}"
      else
        data="$data},"
      fi

    done

  fi

  # close out data
  data="$data]}"

  # add zone
  zone_status=$(/usr/bin/curl --silent --request POST --output /dev/null --write-out "%{http_code}" --header "X-API-Key: $api_key" --data "$data" "$api_base_url/zones")

  if [[ $zone_status = 201 ]]; then
    echo Success. Zone $zone created.
    exit 0
  else
    echo Error. http response adding zone $zone was: $zone_status
    exit 1
  fi

else
  echo Unexpected http response checking for Zone $zone: $zone_status
  exit 1
fi