Browse Source

[master] Merge branch 'trac3802'

Adds lease-dump to kea-admin.  While merging, additonal changes
were needed:

src/bin/admin/tests/mysql_tests.sh.in
 mysql_wipe() - functio was failing referential integrity checks
 due to new tables added in schema 3.0.  Was deleting all
 tables except "hosts".  This has been fixed.

Added src/bin/admin/scripts/mysql/lease_dump_3.0.sh
Thomas Markwalder 10 years ago
parent
commit
ffddc0bfd7

+ 11 - 10
src/bin/admin/admin-utils.sh

@@ -22,25 +22,26 @@
 #     more convenient to use if the script didn't parse db_user db_password
 #     and db_name.
 #
-# @todo: Catch mysql return code. I tried to use PIPESTATUS[X], but it doesn't
-# seem to work (or at least I don't know how to use it).
+# It saves mysql command exit status both to the env variable _ADMIN_STATUS
+# as well as returning it as $? to the caller.
+
 mysql_execute() {
     if [ $# -gt 1 ]; then
-        QUERY=$1
+        QUERY="$1"
         shift
-        _RESULT=`echo $QUERY | mysql -N -B $@`
+        mysql -N -B  $* -e "${QUERY}"
+        retcode=$?
     else
-        _RESULT=$(mysql -N -B --user=$db_user --password=$db_password -e "${1}" $db_name)
+        mysql -N -B --user=$db_user --password=$db_password -e "${1}" $db_name
+        retcode="$?"
     fi
+
+    return $retcode
 }
 
 mysql_version() {
     mysql_execute "SELECT CONCAT(version,\".\",minor) FROM schema_version" "$@"
-}
-
-mysql_version_print() {
-    mysql_version "$@"
-    printf "%s" $_RESULT
+    return $?
 }
 
 pgsql_execute() {

+ 225 - 7
src/bin/admin/kea-admin.in

@@ -33,6 +33,11 @@ db_user="keatest"
 db_password="keatest"
 db_name="keatest"
 
+# lease dump parameters
+dump_type=0
+dump_file=""
+dump_qry=""
+
 # Include utilities. Use installed version if available and
 # use build version if it isn't.
 if [ -e @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh ]; then
@@ -56,6 +61,7 @@ usage() {
     printf " - lease-version: Checks version of the existing lease database scheme. Useful\n"
     printf " -                for checking lease DB version when preparing for an upgrade.\n"
     printf " - lease-upgrade: Upgrades your lease database scheme\n"
+    printf " - lease-dump: Dump current leases to a CSV file\n"
     printf "\n"
     printf "BACKEND - one of the supported backends: memfile|mysql|pgsql\n"
     printf "\n"
@@ -65,6 +71,11 @@ usage() {
     printf " -p or --password pass - specifies a password when connecting to a database\n"
     printf " -n or --name database - specifies a database name to connect to\n"
     printf " -d or --directory - path to upgrade scripts (default: ${SCRIPTS_DIR_DEFAULT})\n"
+    printf "\n"
+    printf " Parameters specific to lease-dump:\n"
+    printf "     -4 to dump IPv4 leases to file\n"
+    printf "     -6 to dump IPv6 leases to file\n"
+    printf "     -o or --output - name of file to which leases will be dumped\n"
 }
 
 
@@ -133,8 +144,15 @@ mysql_init() {
     # We should not hide them as they may give hints to user what is wrong with
     # his setup.
     #
-    mysql_execute "SHOW TABLES;"
-    COUNT=`echo $_RESULT | wc -w`
+    RESULT=`mysql_execute "SHOW TABLES;"`
+    ERRCODE=$?
+    if [ $ERRCODE -ne  0 ]
+    then
+        log_error "mysql_init table query failed, mysql status = $ERRCODE"
+        exit 1
+    fi
+
+    COUNT=`echo $RESULT | wc -w`
     if [ $COUNT -gt 0 ]; then
         # Let't start with a new line. mysql could have printed something out.
         printf "\n"
@@ -150,7 +168,7 @@ mysql_init() {
 
     if [ "$ERRCODE" -eq 0 ]; then
         printf "Lease DB version reported after initialization: "
-        mysql_version_print
+        mysql_version
         printf "\n"
     fi
 
@@ -208,7 +226,7 @@ memfile_upgrade() {
 mysql_upgrade() {
 
     printf "Lease DB version reported before upgrade: "
-    mysql_version_print
+    mysql_version
     printf "\n"
 
     # Check if the scripts directory exists at all.
@@ -231,7 +249,7 @@ mysql_upgrade() {
     done
 
     printf "Lease DB version reported after upgrade: "
-    mysql_version_print
+    mysql_version
     printf "\n"
 }
 
@@ -266,6 +284,165 @@ pgsql_upgrade() {
     exit 0
 }
 
+# Utility function which tests if the given file exists and
+# if so notifies the user and provides them the opportunity
+# to abort the current command.
+check_file_overwrite () {
+    local file=$1
+    if [ -e ${file} ]
+    then
+        echo "Output file, $file, exists and will be overwritten."
+        echo "Do you wish to continue? (y/n)"
+        read ans
+        if [ ${ans} != "y" ]
+        then
+            echo "$command aborted by user."
+            exit 1
+        fi
+    fi
+}
+
+### Functions used for dump
+
+# Sets the global variable, dump_qry, to the schema-version specific
+# SQL text needed to dump the lease data for the current backend
+# and protocol
+get_dump_query() {
+    local version=$1
+
+    dump_qry=""
+    dump_sql_file="$scripts_dir/${backend}/lease_dump_$version.sh"
+    if [ ! -e $dump_sql_file ]
+    then
+        log_error "lease-dump: cannot access dump_sql_file: $dump_sql_file"
+        exit 1;
+    fi
+
+    # source in the dump file which defines the sql text we'll need
+    . $dump_sql_file
+    if [ $? -ne 0 ]
+    then
+        log_error "lease-dump: error sourcing dump_sql_file: $dump_sql_file"
+        exit 1
+    fi
+
+    # Construct the SQL text to dump the leases based on protocol type
+    case ${dump_type} in
+        4)
+            dump_qry="$lease4_dump_sql";
+            ;;
+        6)
+            dump_qry="$lease6_dump_sql";
+            ;;
+        *)
+            log_error "you must specify -4 or -6 for lease-dump"
+            usage
+            exit 1
+            ;;
+    esac
+
+    if [ "$dump_qry" = "" ]
+    then
+        log_error "lease-dump: dump query appears to be undefined"
+        exit 1
+    fi
+}
+
+memfile_dump() {
+    log_error "lease-dump is not supported for memfile"
+    exit 1
+}
+
+mysql_dump() {
+
+    # get the correct dump query
+    version=`mysql_version`
+    retcode=$?
+    if [ $retcode -ne 0 ]
+    then
+        log_error "lease-dump: mysql_version failed, exit code $retcode"
+        exit 1;
+    fi
+
+    # Fetch the correct SQL text. Note this function will exit
+    # if it fails.
+    get_dump_query $version
+
+    # Make sure they specified a file
+    if [ "$dump_file" = "" ]; then
+        log_error "you must specify an output file for lease-dump"
+        usage
+        exit 1
+
+    fi
+
+    # If output file exists, notify user, allow them a chance to bail
+    check_file_overwrite $dump_file
+
+    # Check the temp file too
+    tmp_file="$dump_file.tmp"
+    check_file_overwrite $tmp_file
+
+    # Run the sql to output tab-delimited lease data to a temp file.
+    # By using a temp file we can check for MySQL errors before using
+    # 'tr' to translate tabs to commas.  We do not use MySQL's output
+    # to file as that requires linux superuser privileges to execute
+    # the select.
+    mysql_execute "${dump_qry}" > $tmp_file
+    retcode=$?
+    if [ $retcode -ne 0 ]; then
+        log_error "lease-dump: mysql_execute failed, exit code $retcode";
+        exit 1
+    fi
+
+    # Now translate tabs to commas.
+    cat $tmp_file | tr '\t' ',' >$dump_file
+    if [ $? -ne 0 ]; then
+        log_error "lease-dump: reformatting failed";
+        exit 1
+    fi
+
+    # delete the tmp file on success
+    rm $tmp_file
+    echo lease$dump_type successfully dumped to $dump_file
+    exit 0
+}
+
+### Functions used for dump
+pgsql_dump() {
+
+    # @todo use pgsql_version once implemented. See #3883
+    version='1.0'
+    get_dump_query $version
+
+    # Make sure they specified a file
+    if [ "$dump_file" = "" ]; then
+        log_error "you must specify an output file for lease-dump"
+        usage
+        exit 1
+
+    fi
+
+    # If output file exists, notify user, allow them a chance to bail
+    check_file_overwrite $dump_file
+
+    # psql does not accept password as a parameter but will look in the environment
+    export PGPASSWORD=$db_password
+
+    # Call psql and redirect output to the dump file. We don't use psql "to csv"
+    # as it can only be run as db superuser.
+    echo "$dump_qry" | psql --set ON_ERROR_STOP=1 -t -q --user=$db_user --dbname=$db_name -w --no-align --field-separator=',' >$dump_file
+    retcode=$?
+
+    # Check for errors.
+    if [ $retcode -ne 0 ]; then
+        log_error "lease-dump: psql call failed, exit code: $retcode";
+        exit 1
+    fi
+
+    echo lease$dump_type successfully dumped to $dump_file
+    exit 0
+}
 
 ### Script starts here ###
 
@@ -276,7 +453,7 @@ if [ -z ${command} ]; then
     usage
     exit 1
 fi
-is_in_list "${command}" "lease-init lease-version lease-upgrade"
+is_in_list "${command}" "lease-init lease-version lease-upgrade lease-dump"
 if [ ${_inlist} -eq 0 ]; then
     log_error "invalid command: ${command}"
     exit 1
@@ -341,6 +518,34 @@ do
                 exit 1
             fi
             ;;
+        # specify DHCPv4 lease type
+        -4)
+            if [ $dump_type -eq 6 ]; then
+                log_error "you may not specify both -4 and -6"
+                usage
+                exit 1
+            fi
+            dump_type=4
+            ;;
+        # specify DHCPv6 lease type
+        -6)
+            if [ $dump_type -eq 4 ]; then
+                log_error "you may not specify both -4 and -6"
+                usage
+                exit 1
+            fi
+            dump_type=6
+            ;;
+        # specify output file, currently only used by lease dump
+        -o|--output)
+            shift
+            dump_file=${1}
+            if [ -z ${dump_file} ]; then
+                log_error "-o or --output requires a parameter"
+                usage
+                exit 1
+            fi
+            ;;
         *)
             log_error "invalid option: ${option}"
             usage
@@ -370,7 +575,7 @@ case ${command} in
                 memfile_version
                 ;;
             mysql)
-                mysql_version_print
+                mysql_version
                 printf "\n"
                 ;;
             pgsql)
@@ -391,6 +596,19 @@ case ${command} in
                 ;;
             esac
         ;;
+    lease-dump)
+        case ${backend} in
+            memfile)
+                memfile_dump
+                ;;
+            mysql)
+                mysql_dump
+                ;;
+            pgsql)
+                pgsql_dump
+                ;;
+            esac
+        ;;
 esac
 
 exit 0

+ 2 - 2
src/bin/admin/scripts/mysql/Makefile.am

@@ -1,6 +1,6 @@
 SUBDIRS = .
 
 sqlscriptsdir = ${datarootdir}/${PACKAGE_NAME}/scripts/mysql
-sqlscripts_DATA = dhcpdb_create.mysql upgrade_1.0_to_2.0.sh upgrade_2.0_to_3.0.sh
+sqlscripts_DATA = dhcpdb_create.mysql upgrade_1.0_to_2.0.sh upgrade_2.0_to_3.0.sh lease_dump_1.0.sh lease_dump_2.0.sh lease_dump_3.0.sh
 
-EXTRA_DIST = dhcpdb_create.mysql upgrade_1.0_to_2.0.sh upgrade_2.0_to_3.0.sh
+EXTRA_DIST = dhcpdb_create.mysql upgrade_1.0_to_2.0.sh upgrade_2.0_to_3.0.sh lease_dump_1.0.sh lease_dump_2.0.sh lease_dump_3.0.sh

+ 37 - 0
src/bin/admin/scripts/mysql/lease_dump_1.0.sh

@@ -0,0 +1,37 @@
+#!/bin/sh
+# Copyright (C) 2015  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Specifies the MySQL sql for schema-version 1.0 required to produce 
+# lease output that includes a header row containing column names,
+# followed by the lease data. The text is used in a single call 
+# to the mysql command line tool.
+
+# SQL for DHCPv4 leases
+lease4_dump_sql="\
+SELECT 'address', 'hwaddr', 'client_id', 'valid_lifetime', 'expire',\
+'subnet_id', 'fqdn_fwd', 'fqdn_rev', 'hostname';\
+SELECT INET_NTOA(address), IFNULL(HEX(hwaddr), ''), IFNULL(HEX(client_id), ''),\
+valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname from lease4"
+
+# SQL for DHCPv6 leases
+lease6_dump_sql="\
+SELECT 'address', 'duid', 'valid_lifetime', 'expire',\
+'subnet_id', 'pref_lifetime', 'lease_type', 'iaid', 'prefix_len', 'fqdn_fwd',\
+'fqdn_rev', 'hostname';\
+SELECT a.address, IFNULL(HEX(a.duid), ''), a.valid_lifetime,\
+a.expire, a.subnet_id, a.pref_lifetime, IFNULL(b.name, ''), a.iaid, a.prefix_len,\
+a.fqdn_fwd, a.fqdn_rev, hostname \
+FROM lease6 a left outer join lease6_types b on (a.lease_type = b.lease_type)"

+ 38 - 0
src/bin/admin/scripts/mysql/lease_dump_2.0.sh

@@ -0,0 +1,38 @@
+#!/bin/sh
+# Copyright (C) 2015  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Specifies the MySQL sql for schema-version 2.0 required to produce 
+# lease output that includes a header row containing column names,
+# followed by the lease data. The text is used in a single call 
+# to the mysql command line tool.
+
+# SQL for DHCPv4 leases
+lease4_dump_sql="\
+SELECT 'address', 'hwaddr', 'client_id', 'valid_lifetime', 'expire',\
+'subnet_id', 'fqdn_fwd', 'fqdn_rev', 'hostname';\
+SELECT INET_NTOA(address), IFNULL(HEX(hwaddr), ''), IFNULL(HEX(client_id), ''),\
+valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname from lease4"
+
+# SQL for DHCPv6 leases
+lease6_dump_sql="\
+SELECT 'address', 'duid', 'valid_lifetime', 'expire',\
+'subnet_id', 'pref_lifetime', 'lease_type', 'iaid', 'prefix_len', 'fqdn_fwd',\
+'fqdn_rev', 'hostname', 'hwaddr', 'hwtype', 'hwaddr_source';\
+SELECT a.address, IFNULL(HEX(a.duid), ''), a.valid_lifetime,\
+a.expire, a.subnet_id, a.pref_lifetime, IFNULL(b.name, ''), a.iaid, a.prefix_len,\
+a.fqdn_fwd, a.fqdn_rev, hostname, IFNULL(HEX(hwaddr), ''), IFNULL(hwtype, ''),\
+IFNULL(hwaddr_source, '') \
+FROM lease6 a left outer join lease6_types b on (a.lease_type = b.lease_type)"

+ 38 - 0
src/bin/admin/scripts/mysql/lease_dump_3.0.sh

@@ -0,0 +1,38 @@
+#!/bin/sh
+# Copyright (C) 2015  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Specifies the MySQL sql for schema-version 3.0 required to produce 
+# lease output that includes a header row containing column names,
+# followed by the lease data. The text is used in a single call 
+# to the mysql command line tool.
+
+# SQL for DHCPv4 leases
+lease4_dump_sql="\
+SELECT 'address', 'hwaddr', 'client_id', 'valid_lifetime', 'expire',\
+'subnet_id', 'fqdn_fwd', 'fqdn_rev', 'hostname';\
+SELECT INET_NTOA(address), IFNULL(HEX(hwaddr), ''), IFNULL(HEX(client_id), ''),\
+valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname from lease4"
+
+# SQL for DHCPv6 leases
+lease6_dump_sql="\
+SELECT 'address', 'duid', 'valid_lifetime', 'expire',\
+'subnet_id', 'pref_lifetime', 'lease_type', 'iaid', 'prefix_len', 'fqdn_fwd',\
+'fqdn_rev', 'hostname', 'hwaddr', 'hwtype', 'hwaddr_source';\
+SELECT a.address, IFNULL(HEX(a.duid), ''), a.valid_lifetime,\
+a.expire, a.subnet_id, a.pref_lifetime, IFNULL(b.name, ''), a.iaid, a.prefix_len,\
+a.fqdn_fwd, a.fqdn_rev, hostname, IFNULL(HEX(hwaddr), ''), IFNULL(hwtype, ''),\
+IFNULL(hwaddr_source, '') \
+FROM lease6 a left outer join lease6_types b on (a.lease_type = b.lease_type)"

+ 1 - 2
src/bin/admin/scripts/mysql/upgrade_1.0_to_2.0.sh.in

@@ -8,8 +8,7 @@ else
     . @abs_top_builddir@/src/bin/admin/admin-utils.sh
 fi
 
-mysql_version "$@"
-VERSION=$_RESULT
+VERSION=`mysql_version "$@"`
 
 if [ "$VERSION" != "1.0" ]; then
     printf "This script upgrades 1.0 to 2.0. Reported version is $VERSION. Skipping upgrade.\n"

+ 1 - 2
src/bin/admin/scripts/mysql/upgrade_2.0_to_3.0.sh.in

@@ -8,8 +8,7 @@ else
     . @abs_top_builddir@/src/bin/admin/admin-utils.sh
 fi
 
-mysql_version "$@"
-VERSION=$_RESULT
+VERSION=`mysql_version "$@"`
 
 if [ "$VERSION" != "2.0" ]; then
     printf "This script upgrades 2.0 to 3.0. Reported version is $VERSION. Skipping upgrade.\n"

+ 2 - 2
src/bin/admin/scripts/pgsql/Makefile.am

@@ -1,6 +1,6 @@
 SUBDIRS = .
 
 sqlscriptsdir = ${datarootdir}/${PACKAGE_NAME}/scripts/pgsql
-sqlscripts_DATA = dhcpdb_create.pgsql
+sqlscripts_DATA = dhcpdb_create.pgsql lease_dump_1.0.sh
 
-EXTRA_DIST = dhcpdb_create.pgsql
+EXTRA_DIST = dhcpdb_create.pgsql lease_dump_1.0.sh

+ 39 - 0
src/bin/admin/scripts/pgsql/lease_dump_1.0.sh

@@ -0,0 +1,39 @@
+#!/bin/sh
+# Copyright (C) 2015  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Specifies the PostgreSQL sql for schema-version 1.0 required to produce 
+# lease output that includes a header row containing column names,
+# followed by the lease data. The text is used in a single call 
+# to the mysql command line tool.
+
+# SQL for DHCPv4 leases
+lease4_dump_sql="\
+SELECT 'address', 'hwaddr', 'client_id', 'valid_lifetime', 'expire',\
+'subnet_id', 'fqdn_fwd', 'fqdn_rev', 'hostname';\
+SELECT ('0.0.0.0'::inet + address) AS address,\
+encode(hwaddr,'hex'), encode(client_id,'hex'), valid_lifetime,\
+expire, subnet_id, fqdn_fwd::int AS fqdn_fwd, fqdn_rev::int AS fqdn_rev,\
+hostname FROM lease4"
+
+# SQL for DHCPv6 leases
+lease6_dump_sql="\
+SELECT 'address', 'duid', 'valid_lifetime', 'expire',\
+'subnet_id', 'pref_lifetime', 'lease_type', 'iaid', 'prefix_len', 'fqdn_fwd',\
+'fqdn_rev', 'hostname';\
+SELECT a.address, encode(a.duid,'hex'), a.valid_lifetime,\
+a.expire, a.subnet_id, a.pref_lifetime, b.name, a.iaid, a.prefix_len,\
+a.fqdn_fwd, a.fqdn_rev, hostname \
+FROM lease6 a left outer join lease6_types b on (a.lease_type = b.lease_type)"

+ 4 - 0
src/bin/admin/tests/data/mysql.lease4_dump_test.reference.csv

@@ -0,0 +1,4 @@
+address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname
+0.0.0.10,3230,3330,40,0000-00-00 00:00:00,50,1,1,one.example.com
+0.0.0.11,,313233,40,0000-00-00 00:00:00,50,1,1,
+0.0.0.12,3232,,40,0000-00-00 00:00:00,50,1,1,three.example.com

+ 4 - 0
src/bin/admin/tests/data/mysql.lease6_dump_test.reference.csv

@@ -0,0 +1,4 @@
+address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,hwtype,hwaddr_source
+10,3230,30,0000-00-00 00:00:00,40,50,IA_TA,60,70,1,1,one.example.com,3830,90,100
+11,,30,0000-00-00 00:00:00,40,50,IA_TA,60,70,1,1,,3830,90,100
+12,3231,30,0000-00-00 00:00:00,40,50,IA_TA,60,70,1,1,three.example.com,3830,90,100

+ 163 - 37
src/bin/admin/tests/mysql_tests.sh.in

@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -28,7 +28,7 @@ else
 fi
 
 db_user="keatest"
-db_pass="keatest"
+db_password="keatest"
 db_name="keatest"
 
 # Set location of the kea-admin.
@@ -37,17 +37,26 @@ keaadmin=@abs_top_builddir@/src/bin/admin/kea-admin
 # Wipe all tables from the DB:
 mysql_wipe() {
     printf "Wiping whole database %s\n" $db_name
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
-SET @tables = NULL;
-SELECT GROUP_CONCAT(table_schema, '.', table_name) INTO @tables
-  FROM information_schema.tables
-  WHERE table_schema = 'keatest';
-
-SET @tables = CONCAT('DROP TABLE ', @tables);
-PREPARE stmt FROM @tables;
-EXECUTE stmt;
-DEALLOCATE PREPARE stmt;
-EOF
+
+    # First we build the list of drop table commands
+    # We don't bother with "cascade" because as of MySQL
+    # 5.1 it is only there to ease porting, it doesn't
+    # actually do anything.
+    qry="\
+SELECT CONCAT('DROP TABLE ', table_schema, '.', table_name, ';') \
+FROM information_schema.tables \
+WHERE table_schema = 'keatest';"
+
+    drop_sql=`mysql_execute "${qry}"`
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "mysql-wipe: table query failed, exit code %d, expected %d"
+
+    # We need to turn off referrential integrity checks so tables
+    # are dropped regardless of whether they are used in foreign keys.
+    # (This is what cascade would normally do)
+    mysql_execute "SET SESSION FOREIGN_KEY_CHECKS = 0;$drop_sql"
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "mysql-wipe: drop table sql failed, exit code %d, expected %d"
 }
 
 mysql_lease_init_test() {
@@ -57,42 +66,42 @@ mysql_lease_init_test() {
     mysql_wipe
 
     # Ok, now let's initalize the database
-    ${keaadmin} lease-init mysql -u $db_user -p $db_pass -n $db_name -d @abs_top_srcdir@/src/bin/admin/scripts
+    ${keaadmin} lease-init mysql -u $db_user -p $db_password -n $db_name -d @abs_top_srcdir@/src/bin/admin/scripts
     ERRCODE=$?
 
     assert_eq 0 $ERRCODE "kea-admin lease-init mysql returned non-zero status code %d, expected %d"
 
     # Ok, now let's check if the tables are indeed there.
     # First table: schema_version. Should have 2 columns: version and minor.
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT version, minor FROM schema_version;
 EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "schema_version table is missing or broken. (returned status code %d, expected %d)"
 
     # Second table: lease4
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT address, hwaddr, client_id, valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname FROM lease4;
 EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "lease4 table is missing or broken. (returned status code %d, expected %d)"
 
     # Third table: lease6
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT address, duid, valid_lifetime, expire, subnet_id, pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, hwaddr_source FROM lease6;
 EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "lease6 table is missing or broken. (returned status code %d, expected %d)"
 
     # Fourth table: lease6_types
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT lease_type, name FROM lease6_types;
 EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "lease6_types table is missing or broken. (returned status code %d, expected %d)"
 
     # Fifth table: lease_hwaddr_source
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT hwaddr_source, name FROM lease_hwaddr_source;
 EOF
     ERRCODE=$?
@@ -111,7 +120,7 @@ mysql_lease_version_test() {
     mysql_wipe
 
     # Ok, now let's create a version 1.7
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
 CREATE TABLE schema_version (
     version INT PRIMARY KEY NOT NULL,
     minor INT
@@ -119,7 +128,7 @@ CREATE TABLE schema_version (
 INSERT INTO schema_version VALUES (1, 7);
 EOF
 
-    version=$(${keaadmin} lease-version mysql -u $db_user -p $db_pass -n $db_name)
+    version=$(${keaadmin} lease-version mysql -u $db_user -p $db_password -n $db_name)
 
     assert_str_eq "1.7" ${version} "Expected kea-admin to return %s, returned value was %s"
 
@@ -136,42 +145,42 @@ mysql_host_reservation_init_test() {
     mysql_wipe
 
     # Ok, now let's initalize the database
-    ${keaadmin} lease-init mysql -u $db_user -p $db_pass -n $db_name -d @abs_top_srcdir@/src/bin/admin/scripts
+    ${keaadmin} lease-init mysql -u $db_user -p $db_password -n $db_name -d @abs_top_srcdir@/src/bin/admin/scripts
     ERRCODE=$?
 
     assert_eq 0 $ERRCODE "kea-admin lease-init mysql returned non-zero status code %d, expected %d"
 
     # Ok, now let's check if the tables are indeed there.
     # First table: schema_version. Should have 2 columns: version and minor.
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT version, minor FROM schema_version;
 EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "schema_version table is missing or broken. (returned status code %d, expected %d)"
 
     # Second table: hosts
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT host_id, dhcp_identifier, dhcp_identifier_type, dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, dhcp4_client_classes, dhcp6_client_classes FROM hosts;
 EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "hosts table is missing or broken. (returned status code %d, expected %d)"
 
     # Third table: ipv6_reservations
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT reservation_id, address, prefix_len, type, dhcp6_iaid, host_id FROM ipv6_reservations;
 EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "ipv6_reservations table is missing or broken. (returned status code %d, expected %d)"
 
     # Fourth table: dhcp4_options
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT option_id, code, value, formatted_value, space, persistent, dhcp_client_class, dhcp4_subnet_id, host_id FROM dhcp4_options;
 EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "dhcp4_options table is missing or broken. (returned status code %d, expected %d)"
 
     # Fifth table: dhcp6_options
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT option_id, code, value, formatted_value, space, persistent, dhcp_client_class, dhcp6_subnet_id, host_id FROM dhcp6_options;
 EOF
     ERRCODE=$?
@@ -191,15 +200,15 @@ mysql_upgrade_test() {
     mysql_wipe
 
     # Initialize database to scheme 1.0.
-    mysql -u$db_user -p$db_pass $db_name < @abs_top_srcdir@/src/bin/admin/tests/dhcpdb_create_1.0.mysql
+    mysql -u$db_user -p$db_password $db_name < @abs_top_srcdir@/src/bin/admin/tests/dhcpdb_create_1.0.mysql
 
     # Sanity check - verify that it reports version 1.0.
-    version=$(${keaadmin} lease-version mysql -u $db_user -p $db_pass -n $db_name -d @abs_top_srcdir@/src/bin/admin/scripts)
+    version=$(${keaadmin} lease-version mysql -u $db_user -p $db_password -n $db_name -d @abs_top_srcdir@/src/bin/admin/scripts)
 
     assert_str_eq "1.0" ${version} "Expected kea-admin to return %s, returned value was %s"
 
     # Ok, we have a 1.0 database. Let's upgrade it to 3.0
-    ${keaadmin} lease-upgrade mysql -u $db_user -p $db_pass -n $db_name -d @abs_top_srcdir@/src/bin/admin/scripts
+    ${keaadmin} lease-upgrade mysql -u $db_user -p $db_password -n $db_name -d @abs_top_srcdir@/src/bin/admin/scripts
     ERRCODE=$?
 
     assert_eq 0 $ERRCODE "kea-admin lease-upgrade mysql returned non-zero status code %d, expected %d"
@@ -207,42 +216,42 @@ mysql_upgrade_test() {
     # Let's check that the new tables are indeed there.
 
     #table: lease6 (upgrade 1.0 -> 2.0)
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT hwaddr, hwtype, hwaddr_source FROM lease6;
 EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "lease6 table not upgraded to 2.0 (returned status code %d, expected %d)"
 
     #table: lease_hwaddr_source (upgrade 1.0 -> 2.0)
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT hwaddr_source, name FROM lease_hwaddr_source;
 EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "lease_hwaddr_source table is missing or broken. (returned status code %d, expected %d)"
 
     #table: hosts (upgrade 2.0 -> 3.0)
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT host_id, dhcp_identifier, dhcp_identifier_type, dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, dhcp4_client_classes, dhcp6_client_classes FROM hosts;
 EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "hosts table is missing or broken. (returned status code %d, expected %d)"
 
     #table: ipv6_reservations (upgrade 2.0 -> 3.0)
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT reservation_id, address, prefix_len, type, dhcp6_iaid, host_id FROM ipv6_reservations;
 EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "ipv6_reservations table is missing or broken. (returned status code %d, expected %d)"
 
     #table: dhcp4_options (upgrade 2.0 -> 3.0)
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT option_id, code, value, formatted_value, space, persistent, dhcp_client_class, dhcp4_subnet_id, host_id FROM dhcp4_options;
 EOF
     ERRCODE=$?
     assert_eq 0 $ERRCODE "dhcp4_options table is missing or broken. (returned status code %d, expected %d)"
 
     #table: dhcp6_options (upgrade 2.0 -> 3.0)
-    mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 <<EOF
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
     SELECT option_id, code, value, formatted_value, space, persistent, dhcp_client_class, dhcp6_subnet_id, host_id FROM dhcp6_options;
 EOF
     ERRCODE=$?
@@ -250,7 +259,7 @@ EOF
 
 
     # Verify that it reports version 3.0.
-    version=$(${keaadmin} lease-version mysql -u $db_user -p $db_pass -n $db_name)
+    version=$(${keaadmin} lease-version mysql -u $db_user -p $db_password -n $db_name)
 
     assert_str_eq "3.0" ${version} "Expected kea-admin to return %s, returned value was %s"
 
@@ -260,7 +269,124 @@ EOF
     test_finish 0
 }
 
+mysql_lease4_dump_test() {
+    test_start "mysql.lease4_dump_test"
+
+    test_dir="@abs_top_srcdir@/src/bin/admin/tests"
+    script_dir="@abs_top_srcdir@/src/bin/admin/scripts"
+    output_file="$test_dir/data/lease4_dump_test.output.csv"
+    tmp_file="$test_dir/data/lease4_dump_test.output.csv.tmp"
+    ref_file="$test_dir/data/mysql.lease4_dump_test.reference.csv"
+
+    # wipe out any residuals from prior failed runs
+    if [ -e $output_file ]
+    then
+        rm $output_file
+    fi
+
+    if [ -e $tmp_file ]
+    then
+        rm $tmp_file
+    fi
+
+    # Let's wipe the whole database
+    mysql_wipe
+
+    # Ok, now let's initalize the database
+    ${keaadmin} lease-init mysql -u $db_user -p $db_password -n $db_name -d $script_dir
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "could not create database,  status code %d"
+
+    # Insert the reference record
+    insert_sql="\
+insert into lease4 values(10,20,30,40,0,50,1,1,\"one.example.com\");\
+insert into lease4 values(11,NULL,123,40,0,50,1,1,\"\");\
+insert into lease4 values(12,22,NULL,40,0,50,1,1,\"three.example.com\");"
+
+    mysql_execute "$insert_sql"
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "insert into lease4 failed, status code %d"
+
+    # Dump lease4 to output_file
+    ${keaadmin} lease-dump mysql -4 -u $db_user -p $db_password -n $db_name -d $script_dir -o $output_file
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "kea-admin lease-dump -4 failed,  status code %d"
+
+    # Compare the dump output to reference file, they should be identical
+    cmp -s $output_file  $ref_file
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "dump file does not match reference file"
+
+    # remove the output file
+    rm $output_file
+
+    # Let's wipe the whole database
+    mysql_wipe
+
+    test_finish 0
+}
+
+mysql_lease6_dump_test() {
+    test_start "mysql.lease6_dump_test"
+
+    test_dir="@abs_top_srcdir@/src/bin/admin/tests"
+    script_dir="@abs_top_srcdir@/src/bin/admin/scripts"
+    output_file="$test_dir/data/lease6_dump_test.output.csv"
+    tmp_file="$test_dir/data/lease6_dump_test.output.csv.tmp"
+    ref_file="$test_dir/data/mysql.lease6_dump_test.reference.csv"
+
+    # wipe out any residuals from prior failed runs
+    if [ -e $output_file ]
+    then
+        rm $output_file
+    fi
+
+    if [ -e $tmp_file ]
+    then
+        rm $tmp_file
+    fi
+
+    # Let's wipe the whole database
+    mysql_wipe
+
+    # Ok, now let's initalize the database
+    ${keaadmin} lease-init mysql -u $db_user -p $db_password -n $db_name -d $script_dir
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "could not create database,  status code %d"
+
+    # Insert the reference record
+    insert_sql="\
+insert into lease6 values(10,20,30,0,40,50,1,60,70,1,1,\"one.example.com\",80,90,100);\
+insert into lease6 values(11,NULL,30,0,40,50,1,60,70,1,1,\"\",80,90,100);\
+insert into lease6 values(12,21,30,0,40,50,1,60,70,1,1,\"three.example.com\",80,90,100);"
+
+    mysql_execute "$insert_sql"
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "insert into lease6 failed, status code %d"
+
+    # Dump lease4 to output_file
+    ${keaadmin} lease-dump mysql -6 -u $db_user -p $db_password -n $db_name -d $script_dir -o $output_file
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "kea-admin lease-dump -6 failed, status code %d"
+
+    # Compare the dump output to reference file, they should be identical
+    cmp -s $output_file  $ref_file
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "dump file does not match reference file"
+
+    # remove the output file
+    rm $output_file
+
+    # Let's wipe the whole database
+    mysql_wipe
+
+    test_finish 0
+}
+
+
 mysql_lease_init_test
 mysql_host_reservation_init_test
 mysql_lease_version_test
 mysql_upgrade_test
+mysql_lease4_dump_test
+mysql_lease6_dump_test