# Configure the bind9 pool backend

# Enable with:
# DESIGNATE_BACKEND_DRIVER=bind9

# Dependencies:
# ``functions`` file
# ``designate`` configuration

# install_designate_backend - install any external requirements
# configure_designate_backend - make configuration changes, including those to other services
# init_designate_backend - initialize databases, etc.
# start_designate_backend - start any external services
# stop_designate_backend - stop any external services
# cleanup_designate_backend - remove transient data and cache

# Save trace setting
DP_BIND9_XTRACE=$(set +o | grep xtrace)
set +o xtrace

# Defaults
# --------
BIND_SERVICE_NAME=bind9
BIND_CFG_DIR=/etc/bind
BIND_VAR_DIR=/var/cache/bind
BIND_CFG_FILE=$BIND_CFG_DIR/named.conf.options
BIND_USER=bind
BIND_GROUP=bind
DESIGNATE_SERVICE_PORT_RNDC=${DESIGNATE_SERVICE_PORT_RNDC:-953}

if is_fedora; then
    BIND_SERVICE_NAME=named
    BIND_CFG_DIR=/etc/named
    BIND_CFG_FILE=/etc/named.conf
    BIND_VAR_DIR=/var/named
    BIND_USER=named
    BIND_GROUP=named
fi

# Entry Points
# ------------

# install_designate_backend - install any external requirements
function install_designate_backend {
    if is_ubuntu; then
        install_package bind9
    elif is_fedora; then
        install_package bind
    fi

    # The user that designate runs as needs to be member of **$BIND_GROUP** group.
    # The designate bind9 backend needs read/write access to $BIND_VAR_DIR
    if ! getent group $BIND_GROUP >/dev/null; then
        sudo groupadd $BIND_GROUP
    fi
    add_user_to_group $STACK_USER $BIND_GROUP
    if [[ ! -d $BIND_CFG_DIR ]]; then
        sudo mkdir -p $BIND_CFG_DIR
        sudo chown $BIND_USER:$BIND_GROUP $BIND_CFG_DIR
    fi

    sudo chown -R $BIND_USER:$BIND_GROUP $BIND_CFG_DIR $BIND_VAR_DIR
    sudo chmod -R g+r $BIND_CFG_DIR
    sudo chmod -R g+rw $BIND_VAR_DIR

    # Customize Bind9 apparmor profile if installed
    if [[ -d /etc/apparmor.d ]]; then
        sudo tee /etc/apparmor.d/local/usr.sbin.named > /dev/null << EOF
$DESIGNATE_STATE_PATH/bind9/** rw,
EOF
        restart_service apparmor || :
    fi
}

# configure_designate_backend - make configuration changes, including those to other services
function configure_designate_backend {
    # Generate Designate pool.yaml file
    sudo tee $DESIGNATE_CONF_DIR/pools.yaml > /dev/null <<EOF
---
- name: default
  description: DevStack BIND Pool
  attributes: {}

  ns_records:
    - hostname: $DESIGNATE_DEFAULT_NS_RECORD
      priority: 1

  nameservers:
    - host: $(ipv6_unquote $DESIGNATE_SERVICE_HOST)
      port: $DESIGNATE_SERVICE_PORT_DNS

EOF

    if [[ "$DESIGNATE_USE_CATALOG_ZONES" == "True" ]]; then
        sudo tee -a $DESIGNATE_CONF_DIR/pools.yaml > /dev/null <<EOF
  targets:
    - type: fake
      description: BIND Instance

      masters:
        - host: $(ipv6_unquote $DESIGNATE_SERVICE_HOST)
          port: $DESIGNATE_SERVICE_PORT_MDNS

      options:
        host: $HOST_IP
        port: $DESIGNATE_SERVICE_PORT_DNS
EOF
    else
        sudo tee -a $DESIGNATE_CONF_DIR/pools.yaml > /dev/null <<EOF
  targets:
    - type: bind9
      description: BIND Instance

      masters:
        - host: $(ipv6_unquote $DESIGNATE_SERVICE_HOST)
          port: $DESIGNATE_SERVICE_PORT_MDNS

      options:
        host: $(ipv6_unquote $DESIGNATE_SERVICE_HOST)
        port: $DESIGNATE_SERVICE_PORT_DNS
        rndc_host: $(ipv6_unquote $DESIGNATE_SERVICE_HOST)
        rndc_port: $DESIGNATE_SERVICE_PORT_RNDC
        rndc_config_file: $BIND_CFG_DIR/rndc.conf
        rndc_key_file: $BIND_CFG_DIR/rndc.key
        clean_zonefile: true
EOF
    fi

    if [[ "$DESIGNATE_USE_CATALOG_ZONES" == "True" ]]; then
        sudo tee -a $DESIGNATE_CONF_DIR/pools.yaml > /dev/null <<EOF
  catalog_zone:
      catalog_zone_fqdn: default-pool.test.
      catalog_zone_refresh: 60
#      # TSIG secret and algorithm to use for securing AXFRs for catalog zones.
#      catalog_zone_tsig_key: SomeSecretKey
#      catalog_zone_tsig_algorithm: hmac-sha512
EOF
    fi

    sudo chown $STACK_USER $BIND_CFG_DIR

    # create rndc key and config
    sudo rndc-confgen -a -c $BIND_CFG_DIR/rndc.key
    sudo chown $BIND_USER:$BIND_GROUP $BIND_CFG_DIR/rndc.key
    sudo chmod g+r $BIND_CFG_DIR/rndc.key

    # Configure Bind
    sudo tee $BIND_CFG_FILE > /dev/null <<EOF
include "$BIND_CFG_DIR/rndc.key";

controls {
    inet $(ipv6_unquote $DESIGNATE_SERVICE_HOST) port $DESIGNATE_SERVICE_PORT_RNDC allow { $(ipv6_unquote $DESIGNATE_SERVICE_HOST); } keys { "rndc-key"; };
};
EOF

    # TODO (johnsom) Remove once designate can create the catalog zone
    #                automatically.
    # Add options based on if catalog zones are being used
    if [[ "$DESIGNATE_USE_CATALOG_ZONES" == "True" ]]; then
        sudo tee -a $BIND_CFG_FILE > /dev/null <<EOF
options {
    directory "$BIND_VAR_DIR";
    allow-new-zones yes;
    dnssec-validation auto;
    auth-nxdomain no;    # conform to RFC1035
    listen-on port $DESIGNATE_SERVICE_PORT_DNS { $HOST_IP; };
    listen-on-v6 port $DESIGNATE_SERVICE_PORT_DNS { $HOST_IPV6; };
    recursion no;
    minimal-responses yes;
    catalog-zones {
        zone "default-pool.test"
            default-primaries { $DESIGNATE_SERVICE_HOST port $DESIGNATE_SERVICE_PORT_MDNS;}
            in-memory no;
    };
};

zone "default-pool.test" {
    type secondary;
    primaries { $DESIGNATE_SERVICE_HOST port $DESIGNATE_SERVICE_PORT_MDNS;};
};
EOF
    else
        sudo tee -a $BIND_CFG_FILE > /dev/null <<EOF
options {
    directory "$BIND_VAR_DIR";
    allow-new-zones yes;
    dnssec-validation auto;
    auth-nxdomain no;    # conform to RFC1035
    listen-on port $DESIGNATE_SERVICE_PORT_DNS { $HOST_IP; };
    listen-on-v6 port $DESIGNATE_SERVICE_PORT_DNS { $HOST_IPV6; };
    recursion no;
    minimal-responses yes;
};
EOF
    fi

    # Configure RNDC
    sudo tee $BIND_CFG_DIR/rndc.conf > /dev/null << EOF
include "$BIND_CFG_DIR/rndc.key";

options {
    default-key "rndc-key";
    default-server $(ipv6_unquote $DESIGNATE_SERVICE_HOST);
    default-port $DESIGNATE_SERVICE_PORT_RNDC;
};
EOF

    sudo chown $BIND_USER:$BIND_GROUP $BIND_CFG_FILE $BIND_CFG_DIR/rndc.conf
    sudo chmod g+r $BIND_CFG_FILE $BIND_CFG_DIR/rndc.conf

    restart_service $BIND_SERVICE_NAME
}

# init_designate_backend - initialize databases, etc.
function init_designate_backend {
    :
}

# start_designate_backend - start any external services
function start_designate_backend {
    start_service $BIND_SERVICE_NAME
}

# stop_designate_backend - stop any external services
function stop_designate_backend {
    stop_service $BIND_SERVICE_NAME
}

# cleanup_designate_backend - remove transient data and cache
function cleanup_designate_backend {
    sudo sh -c "rm -rf $BIND_VAR_DIR/*.nzf"
    sudo sh -c "rm -rf $BIND_VAR_DIR/slave.*"
    sudo rm -f $BIND_CFG_DIR/rndc.key
}

# Restore xtrace
$DP_BIND9_XTRACE
