]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5584] Checkpoint: updated schema, code and partially tests
authorFrancis Dupont <fdupont@isc.org>
Thu, 21 Jun 2018 09:15:48 +0000 (11:15 +0200)
committerFrancis Dupont <fdupont@isc.org>
Thu, 21 Jun 2018 09:15:48 +0000 (11:15 +0200)
31 files changed:
configure.ac
src/lib/dhcpsrv/cql_connection.h
src/lib/dhcpsrv/cql_lease_mgr.cc
src/lib/dhcpsrv/csv_lease_file4.cc
src/lib/dhcpsrv/csv_lease_file4.h
src/lib/dhcpsrv/csv_lease_file6.cc
src/lib/dhcpsrv/csv_lease_file6.h
src/lib/dhcpsrv/lease.cc
src/lib/dhcpsrv/lease.h
src/lib/dhcpsrv/memfile_lease_mgr.h
src/lib/dhcpsrv/mysql_connection.h
src/lib/dhcpsrv/mysql_lease_mgr.cc
src/lib/dhcpsrv/pgsql_connection.h
src/lib/dhcpsrv/pgsql_lease_mgr.cc
src/lib/dhcpsrv/tests/csv_lease_file4_unittest.cc
src/lib/dhcpsrv/tests/csv_lease_file6_unittest.cc
src/lib/dhcpsrv/tests/lease_file_loader_unittest.cc
src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc
src/share/database/scripts/cql/Makefile.am
src/share/database/scripts/cql/dhcpdb_create.cql
src/share/database/scripts/cql/dhcpdb_drop.cql
src/share/database/scripts/cql/soft_wipe.cql
src/share/database/scripts/cql/upgrade_2.0_to_2.1.sh.in [new file with mode: 0644]
src/share/database/scripts/mysql/Makefile.am
src/share/database/scripts/mysql/dhcpdb_create.mysql
src/share/database/scripts/mysql/dhcpdb_drop.mysql
src/share/database/scripts/mysql/upgrade_6.0_to_6.1.sh.in [new file with mode: 0644]
src/share/database/scripts/pgsql/Makefile.am
src/share/database/scripts/pgsql/dhcpdb_create.pgsql
src/share/database/scripts/pgsql/dhcpdb_drop.pgsql
src/share/database/scripts/pgsql/upgrade_4.0_to_4.1.sh.in [new file with mode: 0644]

index 00842da9bce555bd029cebe8b204803d75cd4167..fa459cb1e83b1c6176213d3ca41abd26cb1716ca 100644 (file)
@@ -1492,6 +1492,7 @@ AC_CONFIG_FILES([Makefile
                  src/share/database/scripts/Makefile
                  src/share/database/scripts/cql/Makefile
                  src/share/database/scripts/cql/upgrade_1.0_to_2.0.sh
+                 src/share/database/scripts/cql/upgrade_2.0_to_2.1.sh
                  src/share/database/scripts/mysql/Makefile
                  src/share/database/scripts/mysql/upgrade_1.0_to_2.0.sh
                  src/share/database/scripts/mysql/upgrade_2.0_to_3.0.sh
@@ -1501,6 +1502,7 @@ AC_CONFIG_FILES([Makefile
                  src/share/database/scripts/mysql/upgrade_5.0_to_5.1.sh
                  src/share/database/scripts/mysql/upgrade_5.1_to_5.2.sh
                  src/share/database/scripts/mysql/upgrade_5.2_to_6.0.sh
+                 src/share/database/scripts/mysql/upgrade_6.0_to_6.1.sh
                  src/share/database/scripts/pgsql/Makefile
                  src/share/database/scripts/pgsql/upgrade_1.0_to_2.0.sh
                  src/share/database/scripts/pgsql/upgrade_2.0_to_3.0.sh
@@ -1508,6 +1510,7 @@ AC_CONFIG_FILES([Makefile
                  src/share/database/scripts/pgsql/upgrade_3.1_to_3.2.sh
                  src/share/database/scripts/pgsql/upgrade_3.2_to_3.3.sh
                  src/share/database/scripts/pgsql/upgrade_3.3_to_4.0.sh
+                 src/share/database/scripts/pgsql/upgrade_4.0_to_4.1.sh
                  tools/Makefile
                  tools/path_replacer.sh
 ])
index 68ae8336189e172ce85beec84f868496deb2daaa..53375961a5c4ae8a5f5bf68e62787ca907888f27 100644 (file)
@@ -1,3 +1,4 @@
+// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
 // Copyright (C) 2015-2017 Deutsche Telekom AG.
 //
 // Authors: Razvan Becheriu <razvan.becheriu@qualitance.com>
@@ -48,10 +49,10 @@ constexpr uint32_t CQL_DRIVER_VERSION_MAJOR = CASS_VERSION_MAJOR;
 constexpr uint32_t CQL_DRIVER_VERSION_MINOR = CASS_VERSION_MINOR;
 /// @}
 
-/// Define CQL schema version: 2.0
+/// Define CQL schema version: 2.1
 /// @{
 constexpr uint32_t CQL_SCHEMA_VERSION_MAJOR = 2u;
-constexpr uint32_t CQL_SCHEMA_VERSION_MINOR = 0u;
+constexpr uint32_t CQL_SCHEMA_VERSION_MINOR = 1u;
 /// @}
 
 /// @brief Defines a single statement or query
index a225585ab28cedfaca16f6f1324beaeb461ee8f5..36e867547f8d9886ee2d6ea0c5ca23e3b9957810 100644 (file)
@@ -1,3 +1,4 @@
+// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
 // Copyright (C) 2015-2018 Deutsche Telekom AG.
 //
 // Authors: Razvan Becheriu <razvan.becheriu@qualitance.com>
@@ -25,6 +26,7 @@
 
 #include <asiolink/io_address.h>
 
+using namespace isc::data;
 using isc::asiolink::IOAddress;
 
 namespace isc {
@@ -32,6 +34,7 @@ namespace dhcp {
 
 static constexpr size_t HOSTNAME_MAX_LEN = 255u;
 static constexpr size_t ADDRESS6_TEXT_MAX_LEN = 39u;
+static constexpr char NULL_USER_CONTEXT[] = "";
 
 /// @brief Common CQL and Lease Data Methods
 ///
@@ -47,7 +50,7 @@ public:
     CqlLeaseExchange(const CqlConnection &connection)
         : connection_(connection), valid_lifetime_(0), expire_(0),
           subnet_id_(0), fqdn_fwd_(cass_false), fqdn_rev_(cass_false),
-          state_(0) {
+          state_(0), user_context_(NULL_USER_CONTEXT) {
     }
 
     /// @brief Create BIND array to receive C++ data.
@@ -96,6 +99,9 @@ protected:
 
     /// @brief Lease state
     cass_int32_t state_;
+
+    /// @brief User context
+    std::string user_context_;
 };
 
 /// @brief Exchange Lease4 information between Kea and CQL
@@ -249,9 +255,9 @@ StatementMap CqlLease4Exchange::tagged_statements_{
      {INSERT_LEASE4,
       "INSERT INTO lease4( "
       "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
-      "fqdn_fwd, fqdn_rev, hostname, state "
+      "fqdn_fwd, fqdn_rev, hostname, state, user_context "
       ") VALUES ( "
-      "?, ?, ?, ?, ?, ?, ?, ?, ?, ? "
+      "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? "
       ") "
       "IF NOT EXISTS "}},
 
@@ -267,7 +273,8 @@ StatementMap CqlLease4Exchange::tagged_statements_{
       "fqdn_fwd = ?, "
       "fqdn_rev = ?, "
       "hostname = ?, "
-      "state = ? "
+      "state = ?, "
+      "user_context = ? "
       "WHERE address = ? "
       "IF EXISTS "}},
 
@@ -283,7 +290,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
      {GET_LEASE4_EXPIRE,
       "SELECT "
       "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
-      "fqdn_fwd, fqdn_rev, hostname, state "
+      "fqdn_fwd, fqdn_rev, hostname, state, user_context "
       "FROM lease4 "
       "WHERE state = ? "
       "AND expire < ? "
@@ -295,7 +302,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
       {GET_LEASE4,
        "SELECT "
        "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
-       "fqdn_fwd, fqdn_rev, hostname, state "
+       "fqdn_fwd, fqdn_rev, hostname, state, user_context "
        "FROM lease4 "}},
 
     // Gets an IPv4 lease with specified IPv4 address
@@ -303,7 +310,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
      {GET_LEASE4_ADDR,
       "SELECT "
       "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
-      "fqdn_fwd, fqdn_rev, hostname, state "
+      "fqdn_fwd, fqdn_rev, hostname, state, user_context "
       "FROM lease4 "
       "WHERE address = ? "}},
 
@@ -312,7 +319,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
      {GET_LEASE4_CLIENTID,
       "SELECT "
       "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
-      "fqdn_fwd, fqdn_rev, hostname, state "
+      "fqdn_fwd, fqdn_rev, hostname, state, user_context "
       "FROM lease4 "
       "WHERE client_id = ? "
       "ALLOW FILTERING "}},
@@ -322,7 +329,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
      {GET_LEASE4_CLIENTID_SUBID,
       "SELECT "
       "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
-      "fqdn_fwd, fqdn_rev, hostname, state "
+      "fqdn_fwd, fqdn_rev, hostname, state, user_context "
       "FROM lease4 "
       "WHERE client_id = ? "
       "AND subnet_id = ? "
@@ -333,7 +340,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
      {GET_LEASE4_HWADDR,
       "SELECT "
       "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
-      "fqdn_fwd, fqdn_rev, hostname, state "
+      "fqdn_fwd, fqdn_rev, hostname, state, user_context "
       "FROM lease4 "
       "WHERE hwaddr = ? "
       "ALLOW FILTERING "}},
@@ -343,7 +350,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
      {GET_LEASE4_HWADDR_SUBID,
       "SELECT "
       "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
-      "fqdn_fwd, fqdn_rev, hostname, state "
+      "fqdn_fwd, fqdn_rev, hostname, state, user_context "
       "FROM lease4 "
       "WHERE hwaddr = ? "
       "AND subnet_id = ? "
@@ -354,7 +361,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
       {GET_LEASE4_SUBID,
        "SELECT "
        "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
-       "fqdn_fwd, fqdn_rev, hostname, state "
+       "fqdn_fwd, fqdn_rev, hostname, state, user_context "
        "FROM lease4 "
        "WHERE subnet_id = ? "
        "ALLOW FILTERING "}}
@@ -437,6 +444,14 @@ CqlLease4Exchange::createBindForInsert(const Lease4Ptr &lease, AnyArray &data) {
         // state: int
         state_ = static_cast<cass_int32_t>(lease_->state_);
 
+        // user_context: text
+        ConstElementPtr ctx = lease_->getContext();
+        if (ctx) {
+            user_context_ = ctx->str();
+        } else {
+            user_context_ = NULL_USER_CONTEXT;
+        }
+
         // Start with a fresh array.
         data.clear();
         data.add(&address_);
@@ -449,6 +464,7 @@ CqlLease4Exchange::createBindForInsert(const Lease4Ptr &lease, AnyArray &data) {
         data.add(&fqdn_rev_);
         data.add(&hostname_);
         data.add(&state_);
+        data.add(&user_context_);
 
     } catch (const Exception &ex) {
         isc_throw(DbOperationError, "CqlLease4Exchange::createBindForInsert(): "
@@ -531,6 +547,14 @@ CqlLease4Exchange::createBindForUpdate(const Lease4Ptr &lease, AnyArray &data,
         // state: int
         state_ = static_cast<cass_int32_t>(lease_->state_);
 
+        // user_context: text
+        ConstElementPtr ctx = lease_->getContext();
+        if (ctx) {
+            user_context_ = ctx->str();
+        } else {
+            user_context_ = NULL_USER_CONTEXT;
+        }
+
         // Start with a fresh array.
         data.clear();
         data.add(&hwaddr_);
@@ -542,6 +566,7 @@ CqlLease4Exchange::createBindForUpdate(const Lease4Ptr &lease, AnyArray &data,
         data.add(&fqdn_rev_);
         data.add(&hostname_);
         data.add(&state_);
+        data.add(&user_context_);
         data.add(&address_);
 
     } catch (const Exception &ex) {
@@ -609,6 +634,9 @@ CqlLease4Exchange::createBindForSelect(AnyArray &data, StatementTag /* unused */
 
     // state: int
     data.add(&state_);
+
+    // user_context: text
+    data.add(&user_context_);
 }
 
 boost::any
@@ -645,6 +673,13 @@ CqlLease4Exchange::retrieve() {
 
         uint32_t addr4 = static_cast<uint32_t>(address_);
 
+        ConstElementPtr ctx;
+        if (!user_context_.empty()) {
+            ctx = Element::fromJSON(user_context_);
+            isc_throw(BadValue, "user context '" << user_context_
+                      << "' is not a JSON map");
+        }
+
         Lease4Ptr result(new Lease4(addr4, hwaddr, client_id_.data(),
                                     client_id_.size(), valid_lifetime_, 0, 0,
                                     cltt, subnet_id_, fqdn_fwd_, fqdn_rev_,
@@ -652,6 +687,10 @@ CqlLease4Exchange::retrieve() {
 
         result->state_ = state_;
 
+        if (ctx) {
+            result->setContext(ctx);
+        }
+
         return (result);
     } catch (const Exception &ex) {
         isc_throw(DbOperationError,
@@ -885,9 +924,9 @@ StatementMap CqlLease6Exchange::tagged_statements_ = {
       "INSERT INTO lease6("
       "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
       "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
-      "hwaddr_source, state "
+      "hwaddr_source, state, user_context "
       ") VALUES ("
-      "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?"
+      "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?"
       ") "
       "IF NOT EXISTS "}},
 
@@ -909,7 +948,8 @@ StatementMap CqlLease6Exchange::tagged_statements_ = {
       "hwaddr = ?, "
       "hwtype = ?, "
       "hwaddr_source = ?, "
-      "state = ? "
+      "state = ?, "
+      "user_context = ? "
       "WHERE address = ? "
       "IF EXISTS "}},
 
@@ -926,7 +966,7 @@ StatementMap CqlLease6Exchange::tagged_statements_ = {
       "SELECT "
       "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
       "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
-      "hwaddr_source, state "
+      "hwaddr_source, state, user_context "
       "FROM lease6 "
       "WHERE state = ? "
       "AND expire < ? "
@@ -939,7 +979,7 @@ StatementMap CqlLease6Exchange::tagged_statements_ = {
       "SELECT "
       "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
       "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
-      "hwaddr_source, state "
+      "hwaddr_source, state, user_context "
       "FROM lease6 "
       "WHERE address = ? "
       "AND lease_type = ? "
@@ -951,7 +991,7 @@ StatementMap CqlLease6Exchange::tagged_statements_ = {
       "SELECT "
       "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
       "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
-      "hwaddr_source, state "
+      "hwaddr_source, state, user_context "
       "FROM lease6 "
       "WHERE duid = ? AND iaid = ? "
       "AND lease_type = ? "
@@ -963,7 +1003,7 @@ StatementMap CqlLease6Exchange::tagged_statements_ = {
       "SELECT "
       "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
       "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
-      "hwaddr_source, state "
+      "hwaddr_source, state, user_context "
       "FROM lease6 "
       "WHERE duid = ? AND iaid = ? "
       "AND lease_type = ? "
@@ -1072,6 +1112,14 @@ CqlLease6Exchange::createBindForInsert(const Lease6Ptr &lease, AnyArray &data) {
         // state: int
         state_ = static_cast<cass_int32_t>(lease_->state_);
 
+        // user_context: text
+        ConstElementPtr ctx = lease_->getContext();
+        if (ctx) {
+            user_context_ = ctx->str();
+        } else {
+            user_context_ = NULL_USER_CONTEXT;
+        }
+
         // Start with a fresh array.
         data.clear();
 
@@ -1092,6 +1140,7 @@ CqlLease6Exchange::createBindForInsert(const Lease6Ptr &lease, AnyArray &data) {
         data.add(&hwtype_);
         data.add(&hwaddr_source_);
         data.add(&state_);
+        data.add(&user_context_);
 
     } catch (const Exception &ex) {
         isc_throw(DbOperationError, "CqlLease6Exchange::createBindForInsert(): "
@@ -1205,6 +1254,14 @@ CqlLease6Exchange::createBindForUpdate(const Lease6Ptr &lease, AnyArray &data,
         // state: int
         state_ = static_cast<cass_int32_t>(lease_->state_);
 
+        // user_context: text
+        ConstElementPtr ctx = lease_->getContext();
+        if (ctx) {
+            user_context_ = ctx->str();
+        } else {
+            user_context_ = NULL_USER_CONTEXT;
+        }
+
         // Start with a fresh array.
         data.clear();
 
@@ -1224,6 +1281,7 @@ CqlLease6Exchange::createBindForUpdate(const Lease6Ptr &lease, AnyArray &data,
         data.add(&hwtype_);
         data.add(&hwaddr_source_);
         data.add(&state_);
+        data.add(&user_context_);
         data.add(&address_);
 
     } catch (const Exception &ex) {
@@ -1309,6 +1367,9 @@ CqlLease6Exchange::createBindForSelect(AnyArray &data, StatementTag /* unused */
 
     // state: int
     data.add(&state_);
+
+    // user_context: text
+    data.add(&user_context_);
 }
 
 boost::any
@@ -1360,6 +1421,13 @@ CqlLease6Exchange::retrieve() {
             hwaddr->source_ = hwaddr_source_;
         }
 
+        ConstElementPtr ctx;
+        if (!user_context_.empty()) {
+            ctx = Element::fromJSON(user_context_);
+            isc_throw(BadValue, "user context '" << user_context_
+                      << "' is not a JSON map");
+        }
+
         // Create the lease and set the cltt (after converting from the
         // expire time retrieved from the database).
         Lease6Ptr result(
@@ -1373,6 +1441,10 @@ CqlLease6Exchange::retrieve() {
 
         result->state_ = state_;
 
+        if (ctx) {
+            result->setContext(ctx);
+        }
+
         return (result);
     } catch (const Exception &ex) {
         isc_throw(DbOperationError,
index 6f1d5d5335e0c78c4aa889f60ae2f64947f9b7ac..e54189f144dee37c63c366bab6b64f453e280d19 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -8,6 +8,7 @@
 #include <dhcpsrv/csv_lease_file4.h>
 
 using namespace isc::asiolink;
+using namespace isc::data;
 using namespace isc::util;
 
 namespace isc {
@@ -52,6 +53,10 @@ CSVLeaseFile4::append(const Lease4& lease) {
     row.writeAt(getColumnIndex("fqdn_rev"), lease.fqdn_rev_);
     row.writeAt(getColumnIndex("hostname"), lease.hostname_);
     row.writeAt(getColumnIndex("state"), lease.state_);
+    // User context is optional.
+    if (lease.getContext()) {
+        row.writeAt(getColumnIndex("user_context"), lease.getContext()->str());
+    }
 
     try {
         VersionedCSVFile::append(row);
@@ -103,6 +108,9 @@ CSVLeaseFile4::next(Lease4Ptr& lease) {
                       " valid for declined leases");
         }
 
+        // Get the user context (can be NULL).
+        ConstElementPtr ctx = readContext(row);
+
         lease.reset(new Lease4(readAddress(row),
                                HWAddrPtr(new HWAddr(hwaddr)),
                                client_id_vec.empty() ? NULL : &client_id_vec[0],
@@ -116,6 +124,10 @@ CSVLeaseFile4::next(Lease4Ptr& lease) {
                                readHostname(row)));
         lease->state_ = state;
 
+        if (ctx) {
+            lease->setContext(ctx);
+        }
+
     } catch (std::exception& ex) {
         // bump the read error count
         ++read_errs_;
@@ -145,6 +157,7 @@ CSVLeaseFile4::initColumns() {
     addColumn("fqdn_rev", "1.0");
     addColumn("hostname", "1.0");
     addColumn("state", "2.0", "0");
+    addColumn("user_context", "2.1");
     // Any file with less than hostname is invalid
     setMinimumValidColumns("hostname");
 }
@@ -217,5 +230,19 @@ CSVLeaseFile4::readState(const util::CSVRow& row) {
     return (state);
 }
 
+ConstElementPtr
+CSVLeaseFile4::readContext(const util::CSVRow& row) {
+    std::string user_context = row.readAt(getColumnIndex("user_context"));
+    if (user_context.empty()) {
+        return (ConstElementPtr());
+    }
+    ConstElementPtr ctx = Element::fromJSON(user_context);
+    if (!ctx || (ctx->getType() != Element::map)) {
+        isc_throw(isc::BadValue, "user context '" << user_context
+                  << "' is not a JSON map");
+    }
+    return (ctx);
+}
+
 } // end of namespace isc::dhcp
 } // end of namespace isc
index 2964580b44cae9db30fc6c1352028b38527fa059..ef5d2b4e68d65c3b4e74989202c92547e83bf674 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -95,6 +95,7 @@ private:
     /// - fqdn_rev
     /// - hostname
     /// - state
+    /// - user_context
     void initColumns();
 
     ///
@@ -151,6 +152,11 @@ private:
     ///
     /// @param row CSV file row holding lease information.
     uint32_t readState(const util::CSVRow& row);
+
+    /// @brief Reads lease user context from the CSV file row.
+    ///
+    /// @param row CSV file row holding lease information.
+    data::ConstElementPtr readContext(const util::CSVRow& row);
     //@}
 
 };
index c1f8cb474a233ab1382be372e512ee4cdbe81931..ea1d5f24549c0cb7bfb7a4cae7ff137d5d5f6b58 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -9,6 +9,7 @@
 #include <dhcpsrv/csv_lease_file6.h>
 
 using namespace isc::asiolink;
+using namespace isc::data;
 using namespace isc::util;
 
 namespace isc {
@@ -52,6 +53,10 @@ CSVLeaseFile6::append(const Lease6& lease) {
         row.writeAt(getColumnIndex("hwaddr"), lease.hwaddr_->toText(false));
     }
     row.writeAt(getColumnIndex("state"), lease.state_);
+    // User context is optional.
+    if (lease.getContext()) {
+        row.writeAt(getColumnIndex("user_context"), lease.getContext()->str());
+    }
     try {
         VersionedCSVFile::append(row);
     } catch (const std::exception&) {
@@ -99,6 +104,10 @@ CSVLeaseFile6::next(Lease6Ptr& lease) {
             isc_throw(isc::BadValue, "The Empty DUID is"
                       "only valid for declined leases");
         }
+        ConstElementPtr ctx = readContext(row);
+        if (ctx) {
+            lease->setContext(ctx);
+        }
     } catch (std::exception& ex) {
         // bump the read error count
         ++read_errs_;
@@ -132,7 +141,7 @@ CSVLeaseFile6::initColumns() {
     addColumn("hostname", "1.0");
     addColumn("hwaddr", "2.0");
     addColumn("state", "3.0", "0");
-
+    addColumn("user_context", "3.1");
     // Any file with less than hostname is invalid
     setMinimumValidColumns("hostname");
 }
@@ -244,5 +253,19 @@ CSVLeaseFile6::readState(const util::CSVRow& row) {
     return (state);
 }
 
+ConstElementPtr
+CSVLeaseFile6::readContext(const util::CSVRow& row) {
+    std::string user_context = row.readAt(getColumnIndex("user_context"));
+    if (user_context.empty()) {
+        return (ConstElementPtr());
+    }
+    ConstElementPtr ctx = Element::fromJSON(user_context);
+    if (!ctx || (ctx->getType() != Element::map)) {
+        isc_throw(isc::BadValue, "user context '" << user_context
+                  << "' is not a JSON map");
+    }
+    return (ctx);
+}
+
 } // end of namespace isc::dhcp
 } // end of namespace isc
index ac72b1c73eb0b1214da01a1cdd5ecf1d26baabcc..3fdd71fbffa4d6d5b6415c2be1fc3a49c8816585 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -98,6 +98,7 @@ private:
     /// - hostname
     /// - hwaddr
     /// - state
+    /// - user_context
     void initColumns();
 
     ///
@@ -175,6 +176,11 @@ private:
     ///
     /// @param row CSV file row holding lease information.
     uint32_t readState(const util::CSVRow& row);
+
+    /// @brief Reads lease user context from the CSV file row.
+    ///
+    /// @param row CSV file row holding lease information.
+    data::ConstElementPtr readContext(const util::CSVRow& row);
     //@}
 
 };
index 9f52c6603d3d4e5579a92a7604e52c59861b4542..b96613fe2d1443b9727ff710b7c15663e3389fe3 100644 (file)
@@ -251,6 +251,15 @@ Lease::fromElementCommon(const LeasePtr& lease, const data::ConstElementPtr& ele
     }
 
     lease->state_ = state->intValue();
+
+    // user context
+    ConstElementPtr ctx = element->get("user-context");
+    if (ctx) {
+        if (ctx->getType() != Element::map) {
+            isc_throw(BadValue, "user context is not a map");
+        }
+        lease->setContext(ctx);
+    }
 }
 
 Lease4::Lease4(const Lease4& other)
@@ -275,6 +284,10 @@ Lease4::Lease4(const Lease4& other)
         client_id_.reset();
 
     }
+
+    if (other.getContext()) {
+        setContext(other.getContext());
+    }
 }
 
 Lease4::Lease4(const isc::asiolink::IOAddress& address,
@@ -375,6 +388,10 @@ Lease4::operator=(const Lease4& other) {
         } else {
             client_id_.reset();
         }
+
+        if (other.getContext()) {
+            setContext(other.getContext());
+        }
     }
     return (*this);
 }
@@ -383,6 +400,7 @@ isc::data::ElementPtr
 Lease4::toElement() const {
     // Prepare the map
     ElementPtr map = Element::createMap();
+    contextToElement(map);
     map->set("ip-address", Element::create(addr_.toText()));
     map->set("subnet-id", Element::create(static_cast<long int>(subnet_id_)));
     map->set("hw-address", Element::create(hwaddr_->toText(false)));
@@ -526,6 +544,10 @@ Lease6::toText() const {
            << "Subnet ID:     " << subnet_id_ << "\n"
            << "State:         " << statesToText(state_) << "\n";
 
+    if (getContext()) {
+        stream << "User context:  " << getContext() << "\n";
+    }
+
     return (stream.str());
 }
 
@@ -543,6 +565,10 @@ Lease4::toText() const {
            << "Subnet ID:     " << subnet_id_ << "\n"
            << "State:         " << statesToText(state_) << "\n";
 
+    if (getContext()) {
+        stream << "User context:  " << getContext() << "\n";
+    }
+
     return (stream.str());
 }
 
@@ -560,7 +586,8 @@ Lease4::operator==(const Lease4& other) const {
             hostname_ == other.hostname_ &&
             fqdn_fwd_ == other.fqdn_fwd_ &&
             fqdn_rev_ == other.fqdn_rev_ &&
-            state_ == other.state_);
+            state_ == other.state_ &&
+            nullOrEqualValues(getContext(), other.getContext()));
 }
 
 bool
@@ -580,13 +607,15 @@ Lease6::operator==(const Lease6& other) const {
             hostname_ == other.hostname_ &&
             fqdn_fwd_ == other.fqdn_fwd_ &&
             fqdn_rev_ == other.fqdn_rev_ &&
-            state_ == other.state_);
+            state_ == other.state_ &&
+            nullOrEqualValues(getContext(), other.getContext()));
 }
 
 isc::data::ElementPtr
 Lease6::toElement() const {
     // Prepare the map
     ElementPtr map = Element::createMap();
+    contextToElement(map);
     map->set("ip-address", Element::create(addr_.toText()));
     map->set("type", Element::create(typeToText(type_)));
     if (type_ == Lease::TYPE_PD) {
index d8869b5af8a6a8c67dbdd282aca6e1acf1577b4f..8f241651d11d87079f91d2a6b846c301b39a2a92 100644 (file)
@@ -11,6 +11,7 @@
 #include <dhcp/duid.h>
 #include <dhcp/option.h>
 #include <dhcp/hwaddr.h>
+#include <cc/user_context.h>
 #include <cc/cfg_to_element.h>
 
 namespace isc {
@@ -31,7 +32,7 @@ typedef boost::shared_ptr<Lease> LeasePtr;
 ///
 /// This structure holds all information that is common between IPv4 and IPv6
 /// leases.
-struct Lease : public isc::data::CfgToElement {
+struct Lease : public UserContext, public isc::data::CfgToElement {
 
     /// @brief Type of lease or pool
     typedef enum {
index 3af59246a823197be8450036e07f3a46f2776737..2b7b5048c3b50e89f4d5104d8616e1c0f49dbcd0 100644 (file)
@@ -83,12 +83,13 @@ public:
     /// Version history:
     /// 1.0 - initial version (released in Kea 0.9)
     /// 2.0 - hwaddr column added (to be released in Kea 0.9.1)
+    /// 2.1 - user context column add (to be released in Kea 1.5)
     ///
     /// @{
     static const int MAJOR_VERSION = 2;
 
     /// Defines minor version of the memfile backend.
-    static const int MINOR_VERSION = 0;
+    static const int MINOR_VERSION = 1;
 
     /// @}
 
index b1d22d090b30f2f9a1fe5e472425948797479add..ac1584b980b56ebc71894d9713e8eb205ec23e4e 100644 (file)
@@ -41,7 +41,7 @@ extern const int MLM_MYSQL_FETCH_FAILURE;
 /// @name Current database schema version values.
 //@{
 const uint32_t MYSQL_SCHEMA_VERSION_MAJOR = 6;
-const uint32_t MYSQL_SCHEMA_VERSION_MINOR = 0;
+const uint32_t MYSQL_SCHEMA_VERSION_MINOR = 1;
 
 //@}
 
index 93593e9054cf64bb05423cbec4101b81293eca6e..59b0ea04d40e108571f6855975b7aba025f1284b 100644 (file)
@@ -26,6 +26,7 @@
 
 using namespace isc;
 using namespace isc::dhcp;
+using namespace isc::data;
 using namespace std;
 
 /// @file
@@ -84,6 +85,9 @@ const size_t HOSTNAME_MAX_LEN = 255;
 /// colon separators.
 const size_t ADDRESS6_TEXT_MAX_LEN = 39;
 
+/// @brief Maximum length of user context.
+const size_t USER_CONTEXT_MAX_LEN = 8192;
+
 boost::array<TaggedStatement, MySqlLeaseMgr::NUM_STATEMENTS>
 tagged_statements = { {
     {MySqlLeaseMgr::DELETE_LEASE4,
@@ -100,55 +104,55 @@ tagged_statements = { {
                     "SELECT address, hwaddr, client_id, "
                         "valid_lifetime, expire, subnet_id, "
                         "fqdn_fwd, fqdn_rev, hostname, "
-                        "state "
+                        "state, user_context "
                             "FROM lease4"},
     {MySqlLeaseMgr::GET_LEASE4_ADDR,
                     "SELECT address, hwaddr, client_id, "
                         "valid_lifetime, expire, subnet_id, "
                         "fqdn_fwd, fqdn_rev, hostname, "
-                        "state "
+                        "state, user_context "
                             "FROM lease4 "
                             "WHERE address = ?"},
     {MySqlLeaseMgr::GET_LEASE4_CLIENTID,
                     "SELECT address, hwaddr, client_id, "
                         "valid_lifetime, expire, subnet_id, "
                         "fqdn_fwd, fqdn_rev, hostname, "
-                        "state "
+                        "state, user_context "
                             "FROM lease4 "
                             "WHERE client_id = ?"},
     {MySqlLeaseMgr::GET_LEASE4_CLIENTID_SUBID,
                     "SELECT address, hwaddr, client_id, "
                         "valid_lifetime, expire, subnet_id, "
                         "fqdn_fwd, fqdn_rev, hostname, "
-                        "state "
+                        "state, user_context "
                             "FROM lease4 "
                             "WHERE client_id = ? AND subnet_id = ?"},
     {MySqlLeaseMgr::GET_LEASE4_HWADDR,
                     "SELECT address, hwaddr, client_id, "
                         "valid_lifetime, expire, subnet_id, "
                         "fqdn_fwd, fqdn_rev, hostname, "
-                        "state "
+                        "state, user_context "
                             "FROM lease4 "
                             "WHERE hwaddr = ?"},
     {MySqlLeaseMgr::GET_LEASE4_HWADDR_SUBID,
                     "SELECT address, hwaddr, client_id, "
                         "valid_lifetime, expire, subnet_id, "
                         "fqdn_fwd, fqdn_rev, hostname, "
-                        "state "
+                        "state, user_context "
                             "FROM lease4 "
                             "WHERE hwaddr = ? AND subnet_id = ?"},
     {MySqlLeaseMgr::GET_LEASE4_SUBID,
                     "SELECT address, hwaddr, client_id, "
                         "valid_lifetime, expire, subnet_id, "
                         "fqdn_fwd, fqdn_rev, hostname, "
-                        "state "
+                        "state, user_context "
                             "FROM lease4 "
                             "WHERE subnet_id = ?"},
     {MySqlLeaseMgr::GET_LEASE4_EXPIRE,
                     "SELECT address, hwaddr, client_id, "
                         "valid_lifetime, expire, subnet_id, "
                         "fqdn_fwd, fqdn_rev, hostname, "
-                        "state "
+                        "state, user_context "
                             "FROM lease4 "
                             "WHERE state != ? AND expire < ? "
                             "ORDER BY expire ASC "
@@ -159,7 +163,7 @@ tagged_statements = { {
                         "lease_type, iaid, prefix_len, "
                         "fqdn_fwd, fqdn_rev, hostname, "
                         "hwaddr, hwtype, hwaddr_source, "
-                        "state "
+                        "state, user_context "
                             "FROM lease6"},
     {MySqlLeaseMgr::GET_LEASE6_ADDR,
                     "SELECT address, duid, valid_lifetime, "
@@ -167,7 +171,7 @@ tagged_statements = { {
                         "lease_type, iaid, prefix_len, "
                         "fqdn_fwd, fqdn_rev, hostname, "
                         "hwaddr, hwtype, hwaddr_source, "
-                        "state "
+                        "state, user_context "
                             "FROM lease6 "
                             "WHERE address = ? AND lease_type = ?"},
     {MySqlLeaseMgr::GET_LEASE6_DUID_IAID,
@@ -176,7 +180,7 @@ tagged_statements = { {
                         "lease_type, iaid, prefix_len, "
                         "fqdn_fwd, fqdn_rev, hostname, "
                         "hwaddr, hwtype, hwaddr_source, "
-                        "state "
+                        "state, user_context "
                             "FROM lease6 "
                             "WHERE duid = ? AND iaid = ? AND lease_type = ?"},
     {MySqlLeaseMgr::GET_LEASE6_DUID_IAID_SUBID,
@@ -185,7 +189,7 @@ tagged_statements = { {
                         "lease_type, iaid, prefix_len, "
                         "fqdn_fwd, fqdn_rev, hostname, "
                         "hwaddr, hwtype, hwaddr_source, "
-                        "state "
+                        "state, user_context "
                             "FROM lease6 "
                             "WHERE duid = ? AND iaid = ? AND subnet_id = ? "
                             "AND lease_type = ?"},
@@ -195,7 +199,7 @@ tagged_statements = { {
                         "lease_type, iaid, prefix_len, "
                         "fqdn_fwd, fqdn_rev, hostname, "
                         "hwaddr, hwtype, hwaddr_source, "
-                        "state "
+                        "state, user_context "
                             "FROM lease6 "
                             "WHERE subnet_id = ?"},
     {MySqlLeaseMgr::GET_LEASE6_EXPIRE,
@@ -204,7 +208,7 @@ tagged_statements = { {
                         "lease_type, iaid, prefix_len, "
                         "fqdn_fwd, fqdn_rev, hostname, "
                         "hwaddr, hwtype, hwaddr_source, "
-                        "state "
+                        "state, user_context "
                             "FROM lease6 "
                             "WHERE state != ? AND expire < ? "
                             "ORDER BY expire ASC "
@@ -213,22 +217,22 @@ tagged_statements = { {
                     "INSERT INTO lease4(address, hwaddr, client_id, "
                         "valid_lifetime, expire, subnet_id, "
                         "fqdn_fwd, fqdn_rev, hostname, "
-                        "state) "
-                            "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"},
+                        "state, user_context) "
+                            "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"},
     {MySqlLeaseMgr::INSERT_LEASE6,
                     "INSERT INTO lease6(address, duid, valid_lifetime, "
                         "expire, subnet_id, pref_lifetime, "
                         "lease_type, iaid, prefix_len, "
                         "fqdn_fwd, fqdn_rev, hostname, "
                         "hwaddr, hwtype, hwaddr_source, "
-                        "state) "
-                            "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"},
+                        "state, user_context) "
+                            "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"},
     {MySqlLeaseMgr::UPDATE_LEASE4,
                     "UPDATE lease4 SET address = ?, hwaddr = ?, "
                         "client_id = ?, valid_lifetime = ?, expire = ?, "
                         "subnet_id = ?, fqdn_fwd = ?, fqdn_rev = ?, "
                         "hostname = ?, "
-                        "state = ? "
+                        "state = ?, user_context = ? "
                             "WHERE address = ?"},
     {MySqlLeaseMgr::UPDATE_LEASE6,
                     "UPDATE lease6 SET address = ?, duid = ?, "
@@ -236,7 +240,7 @@ tagged_statements = { {
                         "pref_lifetime = ?, lease_type = ?, iaid = ?, "
                         "prefix_len = ?, fqdn_fwd = ?, fqdn_rev = ?, "
                         "hostname = ?, hwaddr = ?, hwtype = ?, hwaddr_source = ?, "
-                        "state = ? "
+                        "state = ?, user_context = ? "
                             "WHERE address = ?"},
     {MySqlLeaseMgr::ALL_LEASE4_STATS,
      "SELECT subnet_id, state, leases as state_count"
@@ -355,7 +359,7 @@ public:
 
 class MySqlLease4Exchange : public MySqlLeaseExchange {
     /// @brief Set number of database columns for this lease structure
-    static const size_t LEASE_COLUMNS = 10;
+    static const size_t LEASE_COLUMNS = 11;
 
 public:
     /// @brief Constructor
@@ -366,10 +370,12 @@ public:
                             client_id_length_(0), client_id_null_(MLM_FALSE),
                             subnet_id_(0), valid_lifetime_(0),
                             fqdn_fwd_(false), fqdn_rev_(false), hostname_length_(0),
-                            state_(0) {
+                            state_(0), user_context_length_(0),
+                            user_context_null_(MLM_FALSE) {
         memset(hwaddr_buffer_, 0, sizeof(hwaddr_buffer_));
         memset(client_id_buffer_, 0, sizeof(client_id_buffer_));
         memset(hostname_buffer_, 0, sizeof(hostname_buffer_));
+        memset(user_context_, 0, sizeof(user_context_));
         std::fill(&error_[0], &error_[LEASE_COLUMNS], MLM_FALSE);
 
         // Set the column names (for error messages)
@@ -383,7 +389,8 @@ public:
         columns_[7] = "fqdn_rev";
         columns_[8] = "hostname";
         columns_[9] = "state";
-        BOOST_STATIC_ASSERT(9 < LEASE_COLUMNS);
+        columns_[10] = "user_context";
+        BOOST_STATIC_ASSERT(10 < LEASE_COLUMNS);
     }
 
     /// @brief Create MYSQL_BIND objects for Lease4 Pointer
@@ -521,11 +528,25 @@ public:
             // bind_[9].is_null = &MLM_FALSE; // commented out for performance
                                               // reasons, see memset() above
 
+            // user_context: text
+            ConstElementPtr ctx = lease->getContext();
+            if (ctx) {
+                bind_[10].buffer_type = MYSQL_TYPE_STRING;
+                string ctx_txt = ctx->str();
+                strncpy(user_context_, ctx_txt.c_str(), USER_CONTEXT_MAX_LEN - 1);
+                bind_[10].buffer = user_context_;
+                bind_[10].buffer_length = ctx_txt.length();
+                // bind_[10].is_null = &MLM_FALSE; // commented out for performance
+                                                   // reasons, see memset() above
+            } else {
+                bind_[10].buffer_type = MYSQL_TYPE_NULL;
+            }
+
             // Add the error flags
             setErrorIndicators(bind_, error_, LEASE_COLUMNS);
 
             // .. and check that we have the numbers correct at compile time.
-            BOOST_STATIC_ASSERT(9 < LEASE_COLUMNS);
+            BOOST_STATIC_ASSERT(10 < LEASE_COLUMNS);
 
         } catch (const std::exception& ex) {
             isc_throw(DbOperationError,
@@ -630,11 +651,20 @@ public:
         // bind_[9].is_null = &MLM_FALSE; // commented out for performance
                                           // reasons, see memset() above
 
+        // user_context: text null
+        user_context_null_ = MLM_FALSE;
+        user_context_length_ = sizeof(user_context_);
+        bind_[10].buffer_type = MYSQL_TYPE_STRING;
+        bind_[10].buffer = reinterpret_cast<char*>(user_context_);
+        bind_[10].buffer_length = user_context_length_;
+        bind_[10].length= &user_context_length_;
+        bind_[10].is_null = &user_context_null_;
+
         // Add the error flags
         setErrorIndicators(bind_, error_, LEASE_COLUMNS);
 
         // .. and check that we have the numbers correct at compile time.
-        BOOST_STATIC_ASSERT(9 < LEASE_COLUMNS);
+        BOOST_STATIC_ASSERT(10 < LEASE_COLUMNS);
 
         // Add the data to the vector.  Note the end element is one after the
         // end of the array.
@@ -671,6 +701,23 @@ public:
             hwaddr.reset(new HWAddr(hwaddr_buffer_, hwaddr_length_, HTYPE_ETHER));
         }
 
+        // Convert user_context to string as well.
+        std::string user_context;
+        if (user_context_null_ == MLM_FALSE) {
+            user_context_[user_context_length_] = '\0';
+            user_context.assign(user_context_);
+        }
+
+        // Set the user context if there is one.
+        ConstElementPtr ctx;
+        if (!user_context.empty()) {
+            ctx = Element::fromJSON(user_context);
+            if (!ctx || (ctx->getType() != Element::map)) {
+                isc_throw(BadValue, "user context '" << user_context
+                          << "' is not a JSON map");
+            }
+        }
+
         // note that T1 and T2 are not stored
         Lease4Ptr lease(new Lease4(addr4_, hwaddr,
                                      client_id_buffer_, client_id_length_,
@@ -680,6 +727,10 @@ public:
         // Set state.
         lease->state_ = state_;
 
+        if (ctx) {
+            lease->setContext(ctx);
+        }
+
         return (lease);
     }
 
@@ -723,6 +774,9 @@ private:
     char                   hostname_buffer_[HOSTNAME_MAX_LEN]; ///< Client hostname
     unsigned long          hostname_length_;           ///< Client hostname length
     uint32_t               state_;                     ///< Lease state
+    char                   user_context_[USER_CONTEXT_MAX_LEN]; ///< User context
+    unsigned long          user_context_length_;       ///< User context length
+    my_bool                user_context_null_;         ///< Is user context null?
 };
 
 /// @brief Exchange MySQL and Lease6 Data
@@ -740,7 +794,7 @@ private:
 
 class MySqlLease6Exchange : public MySqlLeaseExchange {
     /// @brief Set number of database columns for this lease structure
-    static const size_t LEASE_COLUMNS = 16;
+    static const size_t LEASE_COLUMNS = 17;
 
 public:
     /// @brief Constructor
@@ -753,11 +807,13 @@ public:
                             fqdn_fwd_(false), fqdn_rev_(false),
                             hostname_length_(0), hwaddr_length_(0),
                             hwaddr_null_(MLM_FALSE), hwtype_(0), hwaddr_source_(0),
-                            state_(0) {
+                            state_(0), user_context_length_(0),
+                            user_context_null_(MLM_FALSE) {
         memset(addr6_buffer_, 0, sizeof(addr6_buffer_));
         memset(duid_buffer_, 0, sizeof(duid_buffer_));
         memset(hostname_buffer_, 0, sizeof(hostname_buffer_));
         memset(hwaddr_buffer_, 0, sizeof(hwaddr_buffer_));
+        memset(user_context_, 0, sizeof(user_context_));
         std::fill(&error_[0], &error_[LEASE_COLUMNS], MLM_FALSE);
 
         // Set the column names (for error messages)
@@ -777,7 +833,8 @@ public:
         columns_[13] = "hwtype";
         columns_[14] = "hwaddr_source";
         columns_[15] = "state";
-        BOOST_STATIC_ASSERT(15 < LEASE_COLUMNS);
+        columns_[16] = "user_context";
+        BOOST_STATIC_ASSERT(16 < LEASE_COLUMNS);
     }
 
     /// @brief Create MYSQL_BIND objects for Lease6 Pointer
@@ -990,11 +1047,25 @@ public:
             // bind_[15].is_null = &MLM_FALSE; // commented out for performance
                                                // reasons, see memset() above
 
+            // user_context: text
+            ConstElementPtr ctx = lease->getContext();
+            if (ctx) {
+                bind_[16].buffer_type = MYSQL_TYPE_STRING;
+                string ctx_txt = ctx->str();
+                strncpy(user_context_, ctx_txt.c_str(), USER_CONTEXT_MAX_LEN - 1);
+                bind_[16].buffer = user_context_;
+                bind_[16].buffer_length = ctx_txt.length();
+                // bind_[16].is_null = &MLM_FALSE; // commented out for performance
+                                                   // reasons, see memset() above
+            } else {
+                bind_[16].buffer_type = MYSQL_TYPE_NULL;
+            }
+
             // Add the error flags
             setErrorIndicators(bind_, error_, LEASE_COLUMNS);
 
             // .. and check that we have the numbers correct at compile time.
-            BOOST_STATIC_ASSERT(15 < LEASE_COLUMNS);
+            BOOST_STATIC_ASSERT(16 < LEASE_COLUMNS);
 
         } catch (const std::exception& ex) {
             isc_throw(DbOperationError,
@@ -1143,11 +1214,20 @@ public:
         // bind_[15].is_null = &MLM_FALSE; // commented out for performance
                                            // reasons, see memset() above
 
+        // user_context: text null
+        user_context_null_ = MLM_FALSE;
+        user_context_length_ = sizeof(user_context_);
+        bind_[16].buffer_type = MYSQL_TYPE_STRING;
+        bind_[16].buffer = reinterpret_cast<char*>(user_context_);
+        bind_[16].buffer_length = user_context_length_;
+        bind_[16].length= &user_context_length_;
+        bind_[16].is_null = &user_context_null_;
+
         // Add the error flags
         setErrorIndicators(bind_, error_, LEASE_COLUMNS);
 
         // .. and check that we have the numbers correct at compile time.
-        BOOST_STATIC_ASSERT(15 < LEASE_COLUMNS);
+        BOOST_STATIC_ASSERT(16 < LEASE_COLUMNS);
 
         // Add the data to the vector.  Note the end element is one after the
         // end of the array.
@@ -1210,6 +1290,23 @@ public:
             hwaddr->source_ = hwaddr_source_;
         }
 
+        // Convert user_context to string as well.
+        std::string user_context;
+        if (user_context_null_ == MLM_FALSE) {
+            user_context_[user_context_length_] = '\0';
+            user_context.assign(user_context_);
+        }
+
+        // Set the user context if there is one.
+        ConstElementPtr ctx;
+        if (!user_context.empty()) {
+            ctx = Element::fromJSON(user_context);
+            if (!ctx || (ctx->getType() != Element::map)) {
+                isc_throw(BadValue, "user context '" << user_context
+                          << "' is not a JSON map");
+            }
+        }
+
         // Create the lease and set the cltt (after converting from the
         // expire time retrieved from the database).
         Lease6Ptr result(new Lease6(type, addr, duid_ptr, iaid_,
@@ -1223,6 +1320,10 @@ public:
         // Set state.
         result->state_ = state_;
 
+        if (ctx) {
+            result->setContext(ctx);
+        }
+
         return (result);
     }
 
@@ -1273,6 +1374,9 @@ private:
     uint16_t               hwtype_;                    ///< Hardware type
     uint32_t               hwaddr_source_;             ///< Source of the hardware address
     uint32_t               state_;                     ///< Lease state.
+    char                   user_context_[USER_CONTEXT_MAX_LEN]; ///< User context
+    unsigned long          user_context_length_;       ///< User context length
+    my_bool                user_context_null_;         ///< Is user context null?
 };
 
 /// @brief MySql derivation of the statistical lease data query
index 659c131942aaf397c0b22231c4d3fd1d8c7ec4de..f7a50def68b54b7ccd1612fe9a58f1b13674e369 100644 (file)
@@ -17,9 +17,9 @@
 namespace isc {
 namespace dhcp {
 
-/// @brief Define PostgreSQL backend version: 4.0
+/// @brief Define PostgreSQL backend version: 4.1
 const uint32_t PG_SCHEMA_VERSION_MAJOR = 4;
-const uint32_t PG_SCHEMA_VERSION_MINOR = 0;
+const uint32_t PG_SCHEMA_VERSION_MINOR = 1;
 
 // Maximum number of parameters that can be used a statement
 // @todo This allows us to use an initializer list (since we can't
index f6e2a1843400d07627130a60d4db885e063f8e37..ac652c02bc9ea62c0374b7d67f584256028b949f 100644 (file)
@@ -22,6 +22,7 @@
 
 using namespace isc;
 using namespace isc::dhcp;
+using namespace isc::data;
 using namespace std;
 
 namespace {
@@ -58,7 +59,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT address, hwaddr, client_id, "
         "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
         "fqdn_fwd, fqdn_rev, hostname, "
-        "state "
+        "state, user_context "
       "FROM lease4"},
 
     // GET_LEASE4_ADDR
@@ -67,7 +68,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT address, hwaddr, client_id, "
         "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
         "fqdn_fwd, fqdn_rev, hostname, "
-        "state "
+        "state, user_context "
       "FROM lease4 "
       "WHERE address = $1"},
 
@@ -77,7 +78,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT address, hwaddr, client_id, "
         "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
         "fqdn_fwd, fqdn_rev, hostname, "
-        "state "
+        "state, user_context "
       "FROM lease4 "
       "WHERE client_id = $1"},
 
@@ -87,7 +88,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT address, hwaddr, client_id, "
         "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
         "fqdn_fwd, fqdn_rev, hostname, "
-        "state "
+        "state, user_context "
       "FROM lease4 "
       "WHERE client_id = $1 AND subnet_id = $2"},
 
@@ -97,7 +98,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT address, hwaddr, client_id, "
         "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
         "fqdn_fwd, fqdn_rev, hostname, "
-        "state "
+        "state, user_context "
       "FROM lease4 "
       "WHERE hwaddr = $1"},
 
@@ -107,7 +108,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT address, hwaddr, client_id, "
         "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
         "fqdn_fwd, fqdn_rev, hostname, "
-        "state "
+        "state, user_context "
       "FROM lease4 "
       "WHERE hwaddr = $1 AND subnet_id = $2"},
 
@@ -117,7 +118,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT address, hwaddr, client_id, "
         "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
         "fqdn_fwd, fqdn_rev, hostname, "
-      "state "
+      "state, user_context "
       "FROM lease4 "
       "WHERE subnet_id = $1"},
 
@@ -127,7 +128,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT address, hwaddr, client_id, "
         "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
         "fqdn_fwd, fqdn_rev, hostname, "
-        "state "
+        "state, user_context "
       "FROM lease4 "
       "WHERE state != $1 AND expire < $2 "
       "ORDER BY expire "
@@ -140,7 +141,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
         "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
         "hwaddr, hwtype, hwaddr_source, "
-        "state "
+        "state, user_context "
       "FROM lease6"},
 
     // GET_LEASE6_ADDR
@@ -150,7 +151,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
         "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
         "hwaddr, hwtype, hwaddr_source, "
-        "state "
+        "state, user_context "
       "FROM lease6 "
       "WHERE address = $1 AND lease_type = $2"},
 
@@ -161,7 +162,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
         "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
         "hwaddr, hwtype, hwaddr_source, "
-        "state "
+        "state, user_context "
       "FROM lease6 "
       "WHERE duid = $1 AND iaid = $2 AND lease_type = $3"},
 
@@ -172,7 +173,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
         "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
         "hwaddr, hwtype, hwaddr_source, "
-        "state "
+        "state, user_context "
       "FROM lease6 "
       "WHERE lease_type = $1 "
         "AND duid = $2 AND iaid = $3 AND subnet_id = $4"},
@@ -184,7 +185,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
         "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
         "hwaddr, hwtype, hwaddr_source, "
-        "state "
+        "state, user_context "
       "FROM lease6 "
       "WHERE subnet_id = $1"},
 
@@ -196,56 +197,56 @@ PgSqlTaggedStatement tagged_statements[] = {
         "lease_type, iaid, prefix_len, "
         "fqdn_fwd, fqdn_rev, hostname, "
         "hwaddr, hwtype, hwaddr_source, "
-        "state "
+        "state, user_context "
       "FROM lease6 "
       "WHERE state != $1 AND expire < $2 "
       "ORDER BY expire "
       "LIMIT $3"},
 
     // INSERT_LEASE4
-    { 10, { OID_INT8, OID_BYTEA, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
-            OID_BOOL, OID_BOOL, OID_VARCHAR, OID_INT8 },
+    { 11, { OID_INT8, OID_BYTEA, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
+            OID_BOOL, OID_BOOL, OID_VARCHAR, OID_INT8, OID_TEXT },
       "insert_lease4",
       "INSERT INTO lease4(address, hwaddr, client_id, "
         "valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, "
-        "state) "
-      "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)"},
+        "state, user_context) "
+      "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)"},
 
     // INSERT_LEASE6
-    { 16, { OID_VARCHAR, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
+    { 17, { OID_VARCHAR, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
             OID_INT8, OID_INT2, OID_INT8, OID_INT2, OID_BOOL, OID_BOOL,
-            OID_VARCHAR, OID_BYTEA, OID_INT2, OID_INT2, OID_INT8 },
+            OID_VARCHAR, OID_BYTEA, OID_INT2, OID_INT2, OID_INT8, OID_TEXT },
       "insert_lease6",
       "INSERT INTO lease6(address, duid, valid_lifetime, "
         "expire, subnet_id, pref_lifetime, "
         "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
         "hwaddr, hwtype, hwaddr_source, "
-        "state) "
-      "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)"},
+        "state, user_context) "
+      "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)"},
 
     // UPDATE_LEASE4
-    { 11, { OID_INT8, OID_BYTEA, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
-            OID_BOOL, OID_BOOL, OID_VARCHAR, OID_INT8, OID_INT8 },
+    { 12, { OID_INT8, OID_BYTEA, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
+            OID_BOOL, OID_BOOL, OID_VARCHAR, OID_INT8, OID_TEXT, OID_INT8 },
       "update_lease4",
       "UPDATE lease4 SET address = $1, hwaddr = $2, "
         "client_id = $3, valid_lifetime = $4, expire = $5, "
         "subnet_id = $6, fqdn_fwd = $7, fqdn_rev = $8, hostname = $9, "
-        "state = $10 "
-      "WHERE address = $11"},
+        "state = $10, user_context = $11 "
+      "WHERE address = $12"},
 
     // UPDATE_LEASE6
-    { 17, { OID_VARCHAR, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8, OID_INT8,
+    { 18, { OID_VARCHAR, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8, OID_INT8,
             OID_INT2, OID_INT8, OID_INT2, OID_BOOL, OID_BOOL, OID_VARCHAR,
             OID_BYTEA, OID_INT2, OID_INT2,
-            OID_INT8, OID_VARCHAR },
+            OID_INT8, OID_TEXT, OID_VARCHAR },
       "update_lease6",
       "UPDATE lease6 SET address = $1, duid = $2, "
         "valid_lifetime = $3, expire = $4, subnet_id = $5, "
         "pref_lifetime = $6, lease_type = $7, iaid = $8, "
         "prefix_len = $9, fqdn_fwd = $10, fqdn_rev = $11, hostname = $12, "
         "hwaddr = $13, hwtype = $14, hwaddr_source = $15, "
-        "state = $16 "
-      "WHERE address = $17"},
+        "state = $16, user_context = $17 "
+      "WHERE address = $18"},
     // ALL_LEASE4_STATS
     { 0, { OID_NONE },
       "all_lease4_stats",
@@ -309,7 +310,7 @@ public:
         : addr_str_(""), valid_lifetime_(0), valid_lifetime_str_(""),
           expire_(0), expire_str_(""), subnet_id_(0), subnet_id_str_(""),
           cltt_(0), fqdn_fwd_(false), fqdn_rev_(false), hostname_(""),
-          state_str_("") {
+          state_str_(""), user_context_("") {
     }
 
     virtual ~PgSqlLeaseExchange(){}
@@ -329,6 +330,7 @@ protected:
     bool                   fqdn_rev_;
     std::string            hostname_;
     std::string            state_str_;
+    std::string            user_context_;
     //@}
 };
 
@@ -350,8 +352,9 @@ private:
     static const size_t FQDN_REV_COL = 7;
     static const size_t HOSTNAME_COL = 8;
     static const size_t STATE_COL = 9;
+    static const size_t USER_CONTEXT_COL = 10;
     /// @brief Number of columns in the table holding DHCPv4 leases.
-    static const size_t LEASE_COLUMNS = 10;
+    static const size_t LEASE_COLUMNS = 11;
 
 public:
 
@@ -376,6 +379,7 @@ public:
         columns_.push_back("fqdn_rev");
         columns_.push_back("hostname");
         columns_.push_back("state");
+        columns_.push_back("user_context");
     }
 
     /// @brief Creates the bind array for sending Lease4 data to the database.
@@ -441,6 +445,14 @@ public:
             state_str_ = boost::lexical_cast<std::string>(lease->state_);
             bind_array.add(state_str_);
 
+            ConstElementPtr ctx = lease->getContext();
+            if (ctx) {
+                user_context_ = ctx->str();
+            } else {
+                user_context_ = "";
+            }
+            bind_array.add(user_context_);
+
         } catch (const std::exception& ex) {
             isc_throw(DbOperationError,
                       "Could not create bind array from Lease4: "
@@ -487,6 +499,16 @@ public:
             HWAddrPtr hwaddr(new HWAddr(hwaddr_buffer_, hwaddr_length_,
                                         HTYPE_ETHER));
 
+            user_context_ = getRawColumnValue(r, row, USER_CONTEXT_COL);
+            ConstElementPtr ctx;
+            if (!user_context_.empty()) {
+                ctx = Element::fromJSON(user_context_);
+                if (!ctx || (ctx->getType() != Element::map)) {
+                    isc_throw(BadValue, "user context '" << user_context_
+                              << "' is not a JSON map");
+                }
+            }
+
             Lease4Ptr result(new Lease4(addr4_, hwaddr,
                                          client_id_buffer_, client_id_length_,
                                          valid_lifetime_, 0, 0, cltt_,
@@ -495,6 +517,10 @@ public:
 
             result->state_ = state;
 
+            if (ctx) {
+                result->setContext(ctx);
+            }
+
             return (result);
         } catch (const std::exception& ex) {
             isc_throw(DbOperationError,
@@ -543,9 +569,10 @@ private:
     static const int HWTYPE_COL = 13;
     static const int HWADDR_SOURCE_COL = 14;
     static const int STATE_COL = 15;
+    static const size_t USER_CONTEXT_COL = 16;
     //@}
     /// @brief Number of columns in the table holding DHCPv6 leases.
-    static const size_t LEASE_COLUMNS = 16;
+    static const size_t LEASE_COLUMNS = 17;
 
 public:
     PgSqlLease6Exchange()
@@ -574,6 +601,7 @@ public:
         columns_.push_back("hwtype");
         columns_.push_back("hwaddr_source");
         columns_.push_back("state");
+        columns_.push_back("user_context");
     }
 
     /// @brief Creates the bind array for sending Lease6 data to the database.
@@ -670,6 +698,14 @@ public:
             state_str_ = boost::lexical_cast<std::string>(lease->state_);
             bind_array.add(state_str_);
 
+            ConstElementPtr ctx = lease->getContext();
+            if (ctx) {
+                user_context_ = ctx->str();
+            } else {
+                user_context_ = "";
+            }
+            bind_array.add(user_context_);
+
         } catch (const std::exception& ex) {
             isc_throw(DbOperationError,
                       "Could not create bind array from Lease6: "
@@ -743,6 +779,16 @@ public:
             uint32_t state;
             getColumnValue(r, row , STATE_COL, state);
 
+            user_context_ = getRawColumnValue(r, row, USER_CONTEXT_COL);
+            ConstElementPtr ctx;
+            if (!user_context_.empty()) {
+                ctx = Element::fromJSON(user_context_);
+                if (!ctx || (ctx->getType() != Element::map)) {
+                    isc_throw(BadValue, "user context '" << user_context_
+                              << "' is not a JSON map");
+                }
+            }
+
             Lease6Ptr result(new Lease6(lease_type_, addr, duid_ptr,
                                         iaid_u_.uval_, pref_lifetime_,
                                         valid_lifetime_, 0, 0,
@@ -752,6 +798,10 @@ public:
 
             result->state_ = state;
 
+            if (ctx) {
+                result->setContext(ctx);
+            }
+
             return (result);
         } catch (const std::exception& ex) {
             isc_throw(DbOperationError,
index a36d448999924a3c2f067e0b02642e3017174d40..bac7f143e756abba9ae4200b5eb1faf7ee3701e2 100644 (file)
@@ -100,12 +100,12 @@ CSVLeaseFile4Test::absolutePath(const std::string& filename) {
 void
 CSVLeaseFile4Test::writeSampleFile() const {
     io_.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
-                  "fqdn_fwd,fqdn_rev,hostname,state\n"
+                  "fqdn_fwd,fqdn_rev,hostname,state,user_context\n"
                   "192.0.2.1,06:07:08:09:0a:bc,,200,200,8,1,1,"
-                  "host.example.com,0\n"
-                  "192.0.2.1,,a:11:01:04,200,200,8,1,1,host.example.com,0\n"
+                  "host.example.com,0,\n"
+                  "192.0.2.1,,a:11:01:04,200,200,8,1,1,host.example.com,0,\n"
                   "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,100,100,7,"
-                  "0,0,,1\n");
+                  "0,0,,1,\n");
 }
 
 // This test checks the capability to read and parse leases from the file.
@@ -231,10 +231,11 @@ TEST_F(CSVLeaseFile4Test, recreate) {
     lf.close();
     // Check that the contents of the csv file are correct.
     EXPECT_EQ("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
-              "fqdn_fwd,fqdn_rev,hostname,state\n"
-              "192.0.3.2,00:01:02:03:04:05,,200,200,8,1,1,host.example.com,2\n"
+              "fqdn_fwd,fqdn_rev,hostname,state,user_context\n"
+              "192.0.3.2,00:01:02:03:04:05,,200,200,8,1,1,host.example.com,"
+              "2,\n"
               "192.0.3.10,0d:0e:0a:0d:0b:0e:0e:0f,01:02:03:04,100,100,7,0,"
-              "0,,0\n",
+              "0,,0,\n",
               io_.readFile());
 }
 
@@ -341,7 +342,7 @@ TEST_F(CSVLeaseFile4Test, tooFewHeaderColumns) {
 TEST_F(CSVLeaseFile4Test, invalidHeaderColumn) {
     // Create 1.0 file
     io_.writeFile("address,hwaddr,BOGUS,valid_lifetime,expire,subnet_id,"
-                  "fqdn_fwd,fqdn_rev,hostname,state\n");
+                  "fqdn_fwd,fqdn_rev,hostname,state,user_context\n");
 
     // Open the lease file.
     CSVLeaseFile4 lf(filename_);
@@ -353,10 +354,10 @@ TEST_F(CSVLeaseFile4Test, invalidHeaderColumn) {
 TEST_F(CSVLeaseFile4Test, downGrade) {
     // Create 2.0 PLUS a column file
     io_.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
-                  "fqdn_fwd,fqdn_rev,hostname,state,FUTURE_COL\n"
+                  "fqdn_fwd,fqdn_rev,hostname,state,user_context,FUTURE_COL\n"
 
                   "192.0.2.3,06:07:08:09:3a:bc,,200,200,8,1,1,"
-                  "three.example.com,2,BOGUS\n");
+                  "three.example.com,2,,BOGUS\n");
 
     // Lease file should open and report as needing downgrade.
     CSVLeaseFile4 lf(filename_);
@@ -390,9 +391,9 @@ TEST_F(CSVLeaseFile4Test, downGrade) {
 // if they are in the declined state.
 TEST_F(CSVLeaseFile4Test, declinedLeaseTest) {
     io_.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
-                  "fqdn_fwd,fqdn_rev,hostname,state\n"
-                  "192.0.2.1,,,200,200,8,1,1,host.example.com,0\n"
-                  "192.0.2.1,,,200,200,8,1,1,host.example.com,1\n");
+                  "fqdn_fwd,fqdn_rev,hostname,state,user_context\n"
+                  "192.0.2.1,,,200,200,8,1,1,host.example.com,0,\n"
+                  "192.0.2.1,,,200,200,8,1,1,host.example.com,1,\n");
 
     CSVLeaseFile4 lf(filename_);
     ASSERT_NO_THROW(lf.open());
index a8c3b8d473964744c2e5da25670a03833ac88985..f35798d70b4cdd29116430550ffce82a2fd27823 100644 (file)
@@ -100,14 +100,14 @@ void
 CSVLeaseFile6Test::writeSampleFile() const {
     io_.writeFile("address,duid,valid_lifetime,expire,subnet_id,"
                   "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
-                  "fqdn_rev,hostname,hwaddr,state\n"
+                  "fqdn_rev,hostname,hwaddr,state,user_context\n"
                   "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
-                  "200,200,8,100,0,7,0,1,1,host.example.com,,1\n"
-                  "2001:db8:1::1,,200,200,8,100,0,7,0,1,1,host.example.com,,1\n"
+                  "200,200,8,100,0,7,0,1,1,host.example.com,,1,\n"
+                  "2001:db8:1::1,,200,200,8,100,0,7,0,1,1,host.example.com,,1,\n"
                   "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,300,300,6,150,"
-                  "0,8,0,0,0,,,1\n"
+                  "0,8,0,0,0,,,1,\n"
                   "3000:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,0,200,8,0,2,"
-                  "16,64,0,0,,,1\n");
+                  "16,64,0,0,,,1,\n");
 }
 
 // This test checks the capability to read and parse leases from the file.
@@ -268,13 +268,13 @@ TEST_F(CSVLeaseFile6Test, recreate) {
 
     EXPECT_EQ("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
               "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
-              "state\n"
+              "state,user_context\n"
               "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
-              "200,200,8,100,0,7,128,1,1,host.example.com,,0\n"
+              "200,200,8,100,0,7,128,1,1,host.example.com,,0,\n"
               "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05"
-              ",300,300,6,150,0,8,128,0,0,,,0\n"
+              ",300,300,6,150,0,8,128,0,0,,,0,\n"
               "3000:1:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
-              "300,300,10,150,2,7,64,0,0,,,0\n",
+              "300,300,10,150,2,7,64,0,0,,,0,\n",
               io_.readFile());
 }
 
@@ -395,7 +395,7 @@ TEST_F(CSVLeaseFile6Test, tooFewHeaderColumns) {
 TEST_F(CSVLeaseFile6Test, invalidHeaderColumn) {
     io_.writeFile("address,BOGUS,valid_lifetime,expire,subnet_id,pref_lifetime,"
               "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
-              "hwaddr,state\n");
+              "hwaddr,state,user_context\n");
 
     // Open should fail.
     CSVLeaseFile6 lf(filename_);
@@ -410,11 +410,11 @@ TEST_F(CSVLeaseFile6Test, downGrade) {
              // schema 1.0 header
               "address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
               "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
-              "hwaddr,state,FUTURE_COL\n"
+              "hwaddr,state,user_context,FUTURE_COL\n"
 
               // schema 3.0 record - has hwaddr and state
               "2001:db8:1::3,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:03,"
-              "200,200,8,100,0,7,0,1,1,three.example.com,0a:0b:0c:0d:0e,1,"
+              "200,200,8,100,0,7,0,1,1,three.example.com,0a:0b:0c:0d:0e,1,,"
               "BOGUS\n");
 
     // Open should succeed in the event someone is downgrading.
@@ -457,13 +457,13 @@ TEST_F(CSVLeaseFile6Test, downGrade) {
 TEST_F(CSVLeaseFile6Test, declinedLeaseTest) {
     io_.writeFile("address,duid,valid_lifetime,expire,subnet_id,"
                   "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
-                  "fqdn_rev,hostname,hwaddr,state\n"
+                  "fqdn_rev,hostname,hwaddr,state,user_context\n"
                   "2001:db8:1::1,00,"
-                  "200,200,8,100,0,7,0,1,1,host.example.com,,0\n"
+                  "200,200,8,100,0,7,0,1,1,host.example.com,,0,\n"
                   "2001:db8:1::1,,"
-                  "200,200,8,100,0,7,0,1,1,host.example.com,,0\n"
+                  "200,200,8,100,0,7,0,1,1,host.example.com,,0,\n"
                   "2001:db8:1::1,00,"
-                  "200,200,8,100,0,7,0,1,1,host.example.com,,1\n");
+                  "200,200,8,100,0,7,0,1,1,host.example.com,,1,\n");
 
     CSVLeaseFile6 lf(filename_);
     ASSERT_NO_THROW(lf.open());
index e84dbb03f85bb0d04f5537c33e1fefcd7ae8b863..4ac5165df09171b6a5ce4e82911eec9d95621d40 100644 (file)
@@ -143,11 +143,11 @@ protected:
     /// @brief Sets up the header strings
     virtual void SetUp() {
         v4_hdr_ = "address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
-                  "fqdn_fwd,fqdn_rev,hostname,state\n";
+                  "fqdn_fwd,fqdn_rev,hostname,state,user_context\n";
 
         v6_hdr_ = "address,duid,valid_lifetime,expire,subnet_id,"
                   "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
-                  "fqdn_rev,hostname,hwaddr,state\n";
+                  "fqdn_rev,hostname,hwaddr,state,user_context\n";
     }
 };
 
@@ -171,17 +171,17 @@ LeaseFileLoaderTest::absolutePath(const std::string& filename) {
 TEST_F(LeaseFileLoaderTest, loadWrite4) {
     std::string test_str;
     std::string a_1 = "192.0.2.1,06:07:08:09:0a:bc,,"
-                      "200,200,8,1,1,host.example.com,1\n";
+                      "200,200,8,1,1,host.example.com,1,\n";
     std::string a_2 = "192.0.2.1,06:07:08:09:0a:bc,,"
-                      "200,500,8,1,1,host.example.com,1\n";
+                      "200,500,8,1,1,host.example.com,1,\n";
 
     std::string b_1 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
-                      "100,100,7,0,0,,1\n";
+                      "100,100,7,0,0,,1,\n";
     std::string b_2 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
-                      "100,135,7,0,0,,1\n";
+                      "100,135,7,0,0,,1,\n";
 
     std::string c_1 = "192.0.2.3,,a:11:01:04,"
-                      "200,200,8,1,1,host.example.com,0\n";
+                      "200,200,8,1,1,host.example.com,0,\n";
 
     // Create lease file with leases for 192.0.2.1, 192.0.3.15. The lease
     // entry for the 192.0.2.3 is invalid (lacks HW address) and should
@@ -242,14 +242,14 @@ TEST_F(LeaseFileLoaderTest, loadWrite4) {
 TEST_F(LeaseFileLoaderTest, loadWrite4LeaseRemove) {
     std::string test_str;
     std::string a_1 = "192.0.2.1,06:07:08:09:0a:bc,,"
-                      "200,200,8,1,1,host.example.com,1\n";
+                      "200,200,8,1,1,host.example.com,1,\n";
     std::string a_2 = "192.0.2.1,06:07:08:09:0a:bc,,"
-                      "0,500,8,1,1,host.example.com,1\n";
+                      "0,500,8,1,1,host.example.com,1,\n";
 
     std::string b_1 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
-                      "100,100,7,0,0,,1\n";
+                      "100,100,7,0,0,,1,\n";
     std::string b_2 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
-                      "100,135,7,0,0,,1\n";
+                      "100,135,7,0,0,,1,\n";
 
 
     // Create lease file in which one of the entries for 192.0.2.1
@@ -297,19 +297,19 @@ TEST_F(LeaseFileLoaderTest, loadWrite4LeaseRemove) {
 TEST_F(LeaseFileLoaderTest, loadWrite6) {
     std::string test_str;
     std::string a_1 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
-                      "200,200,8,100,0,7,0,1,1,host.example.com,,1\n";
+                      "200,200,8,100,0,7,0,1,1,host.example.com,,1,\n";
     std::string a_2 = "2001:db8:1::1,,"
-                      "200,200,8,100,0,7,0,1,1,host.example.com,,1\n";
+                      "200,200,8,100,0,7,0,1,1,host.example.com,,1,\n";
     std::string a_3 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
-                      "200,400,8,100,0,7,0,1,1,host.example.com,,1\n";
+                      "200,400,8,100,0,7,0,1,1,host.example.com,,1,\n";
 
     std::string b_1 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
-                      "300,300,6,150,0,8,0,0,0,,,1\n";
+                      "300,300,6,150,0,8,0,0,0,,,1,\n";
     std::string b_2 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
-                      "300,800,6,150,0,8,0,0,0,,,1\n";
+                      "300,800,6,150,0,8,0,0,0,,,1,\n";
 
     std::string c_1 = "3000:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
-                      "100,200,8,0,2,16,64,0,0,,,1\n";
+                      "100,200,8,0,2,16,64,0,0,,,1,\n";
 
 
 
@@ -371,14 +371,14 @@ TEST_F(LeaseFileLoaderTest, loadWrite6) {
 TEST_F(LeaseFileLoaderTest, loadWrite6LeaseRemove) {
     std::string test_str;
     std::string a_1 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
-                      "200,200,8,100,0,7,0,1,1,host.example.com,,1\n";
+                      "200,200,8,100,0,7,0,1,1,host.example.com,,1,\n";
     std::string a_2 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
-                      "0,400,8,100,0,7,0,1,1,host.example.com,,1\n";
+                      "0,400,8,100,0,7,0,1,1,host.example.com,,1,\n";
 
     std::string b_1 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
-                      "300,300,6,150,0,8,0,0,0,,,1\n";
+                      "300,300,6,150,0,8,0,0,0,,,1,\n";
     std::string b_2 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
-                      "300,800,6,150,0,8,0,0,0,,,1\n";
+                      "300,800,6,150,0,8,0,0,0,,,1,\n";
 
     // Create lease file in which one of the entries for the 2001:db8:1::1
     // has valid lifetime set to 0, in which case the lease should be
@@ -423,13 +423,14 @@ TEST_F(LeaseFileLoaderTest, loadWrite6LeaseRemove) {
 TEST_F(LeaseFileLoaderTest, loadMaxErrors) {
     std::string test_str;
     std::string a_1 = "192.0.2.1,06:07:08:09:0a:bc,,"
-                      "200,200,8,1,1,host.example.com,1\n";
+                      "200,200,8,1,1,host.example.com,1,\n";
     std::string a_2 = "192.0.2.1,06:07:08:09:0a:bc,,"
-                      "200,500,8,1,1,host.example.com,1\n";
+                      "200,500,8,1,1,host.example.com,1,\n";
 
-    std::string b_1 = "192.0.2.3,,a:11:01:04,200,200,8,1,1,host.example.com,0\n";
+    std::string b_1 = "192.0.2.3,,a:11:01:04,200,200,8,1,1,host.example.com,"
+                      "0,\n";
 
-    std::string c_1 = "192.0.2.10,01:02:03:04:05:06,,200,300,8,1,1,,1\n";
+    std::string c_1 = "192.0.2.10,01:02:03:04:05:06,,200,300,8,1,1,,1,\n";
 
     // Create a lease file for which there is a number of invalid
     // entries.  b_1 is invalid and gets used multiple times.
@@ -493,8 +494,8 @@ TEST_F(LeaseFileLoaderTest, loadMaxErrors) {
 // and comparing that with the expected value.
 TEST_F(LeaseFileLoaderTest, loadWriteLeaseWithZeroLifetime) {
     std::string test_str;
-    std::string a_1 = "192.0.2.1,06:07:08:09:0a:bc,,200,200,8,1,1,,1\n";
-    std::string b_2 = "192.0.2.3,06:07:08:09:0a:bd,,0,200,8,1,1,,1\n";
+    std::string a_1 = "192.0.2.1,06:07:08:09:0a:bc,,200,200,8,1,1,,1,\n";
+    std::string b_2 = "192.0.2.3,06:07:08:09:0a:bd,,0,200,8,1,1,,1,\n";
 
     // Create lease file. The second lease has a valid lifetime of 0.
     test_str = v4_hdr_ + a_1 + b_2;
index 84735a9e116a9c7a9d84dad2afe2b906d82bdf5f..3b99cedbe472a6e7e3933f8de54aa02fc88fb42a 100644 (file)
@@ -498,20 +498,20 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCleanup4) {
     // stored.
     std::string new_file_contents =
         "address,hwaddr,client_id,valid_lifetime,expire,"
-        "subnet_id,fqdn_fwd,fqdn_rev,hostname,state\n";
+        "subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context\n";
 
     // This string contains the contents of the lease file with exactly
     // one lease, but two entries. One of the entries should be removed
     // as a result of lease file cleanup.
     std::string current_file_contents = new_file_contents +
-        "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1\n"
-        "192.0.2.2,02:02:02:02:02:02,,200,800,8,1,1,,1\n";
+        "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1,\n"
+        "192.0.2.2,02:02:02:02:02:02,,200,800,8,1,1,,1,\n";
     LeaseFileIO current_file(getLeaseFilePath("leasefile4_0.csv"));
     current_file.writeFile(current_file_contents);
 
     std::string previous_file_contents = new_file_contents +
-        "192.0.2.3,03:03:03:03:03:03,,200,200,8,1,1,,1\n"
-        "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,,1\n";
+        "192.0.2.3,03:03:03:03:03:03,,200,200,8,1,1,,1,\n"
+        "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,,1,\n";
     LeaseFileIO previous_file(getLeaseFilePath("leasefile4_0.csv.2"));
     previous_file.writeFile(previous_file_contents);
 
@@ -548,15 +548,15 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCleanup4) {
     ASSERT_NO_THROW(lease_mgr->addLease(new_lease));
 
     std::string updated_file_contents = new_file_contents +
-        "192.0.2.45,00:00:00:00:00:00,,100,100,1,0,0,,0\n";
+        "192.0.2.45,00:00:00:00:00:00,,100,100,1,0,0,,0,\n";
     EXPECT_EQ(updated_file_contents, current_file.readFile());
 
     // This string contains the contents of the lease file we
     // expect after the LFC run.  It has two leases with one
     // entry each.
     std::string result_file_contents = new_file_contents +
-        "192.0.2.2,02:02:02:02:02:02,,200,800,8,1,1,,1\n"
-        "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,,1\n";
+        "192.0.2.2,02:02:02:02:02:02,,200,800,8,1,1,,1,\n"
+        "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,,1,\n";
 
     // The LFC should have created a file with the two leases and moved it
     // to leasefile4_0.csv.2
@@ -575,24 +575,24 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCleanup6) {
     std::string new_file_contents =
         "address,duid,valid_lifetime,expire,subnet_id,"
         "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
-        "fqdn_rev,hostname,hwaddr,state\n";
+        "fqdn_rev,hostname,hwaddr,state,user_context\n";
 
     // This string contains the contents of the lease file with exactly
     // one lease, but two entries. One of the entries should be removed
     // as a result of lease file cleanup.
     std::string current_file_contents = new_file_contents +
         "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,200,"
-        "8,100,0,7,0,1,1,,,1\n"
+        "8,100,0,7,0,1,1,,,1,\n"
         "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
-        "8,100,0,7,0,1,1,,,1\n";
+        "8,100,0,7,0,1,1,,,1,\n";
     LeaseFileIO current_file(getLeaseFilePath("leasefile6_0.csv"));
     current_file.writeFile(current_file_contents);
 
     std::string previous_file_contents = new_file_contents +
         "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,200,"
-        "8,100,0,7,0,1,1,,,1\n"
+        "8,100,0,7,0,1,1,,,1,\n"
         "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
-        "8,100,0,7,0,1,1,,,1\n";
+        "8,100,0,7,0,1,1,,,1,\n";
     LeaseFileIO previous_file(getLeaseFilePath("leasefile6_0.csv.2"));
     previous_file.writeFile(previous_file_contents);
 
@@ -631,7 +631,7 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCleanup6) {
 
     std::string update_file_contents = new_file_contents +
         "3000::1,00:00:00:00:00:00:00:00:00:00:00:00:00,400,"
-        "400,2,300,0,123,128,0,0,,,0\n";
+        "400,2,300,0,123,128,0,0,,,0,\n";
     EXPECT_EQ(update_file_contents, current_file.readFile());
 
     // This string contains the contents of the lease file we
@@ -639,9 +639,9 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCleanup6) {
     // entry each.
     std::string result_file_contents = new_file_contents +
         "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
-        "8,100,0,7,0,1,1,,,1\n"
+        "8,100,0,7,0,1,1,,,1,\n"
         "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
-        "8,100,0,7,0,1,1,,,1\n";
+        "8,100,0,7,0,1,1,,,1,\n";
 
     // The LFC should have created a file with the two leases and moved it
     // to leasefile6_0.csv.2
@@ -659,11 +659,11 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCleanupStartFail) {
     // stored.
     std::string new_file_contents =
         "address,hwaddr,client_id,valid_lifetime,expire,"
-        "subnet_id,fqdn_fwd,fqdn_rev,hostname,state\n";
+        "subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context\n";
 
     // Create the lease file to be used by the backend.
     std::string current_file_contents = new_file_contents +
-        "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1\n";
+        "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1,\n";
     LeaseFileIO current_file(getLeaseFilePath("leasefile4_0.csv"));
     current_file.writeFile(current_file_contents);
 
@@ -700,15 +700,15 @@ TEST_F(MemfileLeaseMgrTest, leaseFileFinish) {
     std::string new_file_contents =
         "address,duid,valid_lifetime,expire,subnet_id,"
         "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
-        "fqdn_rev,hostname,hwaddr,state\n";
+        "fqdn_rev,hostname,hwaddr,state,user_context\n";
 
     // This string contains the contents of the current lease file.
     // It should not be moved.
     std::string current_file_contents = new_file_contents +
         "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,200,"
-        "8,100,0,7,0,1,1,,,1\n"
+        "8,100,0,7,0,1,1,,,1,\n"
         "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
-        "8,100,0,7,0,1,1,,,1\n";
+        "8,100,0,7,0,1,1,,,1,\n";
     LeaseFileIO current_file(getLeaseFilePath("leasefile6_0.csv"));
     current_file.writeFile(current_file_contents);
 
@@ -716,7 +716,7 @@ TEST_F(MemfileLeaseMgrTest, leaseFileFinish) {
     // be moved to the previous file.
     std::string finish_file_contents = new_file_contents +
         "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
-        "8,100,0,7,0,1,1,,,1\n";
+        "8,100,0,7,0,1,1,,,1,\n";
     LeaseFileIO finish_file(getLeaseFilePath("leasefile6_0.csv.completed"));
     finish_file.writeFile(finish_file_contents);
 
@@ -763,15 +763,15 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCopy) {
     std::string new_file_contents =
         "address,duid,valid_lifetime,expire,subnet_id,"
         "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
-        "fqdn_rev,hostname,hwaddr,state\n";
+        "fqdn_rev,hostname,hwaddr,state,user_context\n";
 
     // This string contains the contents of the current lease file.
     // It should not be moved.
     std::string current_file_contents = new_file_contents +
         "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,200,"
-        "8,100,0,7,0,1,1,,,1\n"
+        "8,100,0,7,0,1,1,,,1,\n"
         "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
-        "8,100,0,7,0,1,1,,,1\n";
+        "8,100,0,7,0,1,1,,,1,\n";
     LeaseFileIO current_file(getLeaseFilePath("leasefile6_0.csv"));
     current_file.writeFile(current_file_contents);
 
@@ -781,7 +781,7 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCopy) {
     // the same.
     std::string input_file_contents = new_file_contents +
         "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
-        "8,100,0,7,0,1,1,,,1\n";
+        "8,100,0,7,0,1,1,,,1,\n";
     LeaseFileIO input_file(getLeaseFilePath("leasefile6_0.csv.1"));
     input_file.writeFile(input_file_contents);
 
@@ -1132,22 +1132,22 @@ TEST_F(MemfileLeaseMgrTest, getDeclined6) {
 TEST_F(MemfileLeaseMgrTest, load4MultipleLeaseFiles) {
     LeaseFileIO io2(getLeaseFilePath("leasefile4_0.csv.2"));
     io2.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
-                  "fqdn_fwd,fqdn_rev,hostname,state\n"
-                  "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1\n"
-                  "192.0.2.11,bb:bb:bb:bb:bb:bb,,200,200,8,1,1,,1\n");
+                  "fqdn_fwd,fqdn_rev,hostname,state,user_context\n"
+                  "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1,\n"
+                  "192.0.2.11,bb:bb:bb:bb:bb:bb,,200,200,8,1,1,,1,\n");
 
     LeaseFileIO io1(getLeaseFilePath("leasefile4_0.csv.1"));
     io1.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
-                  "fqdn_fwd,fqdn_rev,hostname,state\n"
-                  "192.0.2.1,01:01:01:01:01:01,,200,200,8,1,1,,1\n"
-                  "192.0.2.11,bb:bb:bb:bb:bb:bb,,200,400,8,1,1,,1\n"
-                  "192.0.2.12,cc:cc:cc:cc:cc:cc,,200,200,8,1,1,,1\n");
+                  "fqdn_fwd,fqdn_rev,hostname,state,user_context\n"
+                  "192.0.2.1,01:01:01:01:01:01,,200,200,8,1,1,,1,\n"
+                  "192.0.2.11,bb:bb:bb:bb:bb:bb,,200,400,8,1,1,,1,\n"
+                  "192.0.2.12,cc:cc:cc:cc:cc:cc,,200,200,8,1,1,,1,\n");
 
     LeaseFileIO io(getLeaseFilePath("leasefile4_0.csv"));
     io.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
-                 "fqdn_fwd,fqdn_rev,hostname,state\n"
-                 "192.0.2.10,0a:0a:0a:0a:0a:0a,,200,200,8,1,1,,1\n"
-                 "192.0.2.12,cc:cc:cc:cc:cc:cc,,200,400,8,1,1,,1\n");
+                 "fqdn_fwd,fqdn_rev,hostname,state,user_context\n"
+                 "192.0.2.10,0a:0a:0a:0a:0a:0a,,200,200,8,1,1,,1,\n"
+                 "192.0.2.12,cc:cc:cc:cc:cc:cc,,200,400,8,1,1,,1,\n");
 
     startBackend(V4);
 
@@ -1190,27 +1190,27 @@ TEST_F(MemfileLeaseMgrTest, load4MultipleLeaseFiles) {
 TEST_F(MemfileLeaseMgrTest, load4CompletedFile) {
     LeaseFileIO io2(getLeaseFilePath("leasefile4_0.csv.2"));
     io2.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
-                  "fqdn_fwd,fqdn_rev,hostname,state\n"
-                  "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1\n"
-                  "192.0.2.11,bb:bb:bb:bb:bb:bb,,200,200,8,1,1,,1\n");
+                  "fqdn_fwd,fqdn_rev,hostname,state,user_context\n"
+                  "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1,\n"
+                  "192.0.2.11,bb:bb:bb:bb:bb:bb,,200,200,8,1,1,,1,\n");
 
     LeaseFileIO io1(getLeaseFilePath("leasefile4_0.csv.1"));
     io1.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
-                  "fqdn_fwd,fqdn_rev,hostname,state\n"
-                  "192.0.2.1,01:01:01:01:01:01,,200,200,8,1,1,,1\n"
-                  "192.0.2.11,bb:bb:bb:bb:bb:bb,,200,400,8,1,1,,1\n"
-                  "192.0.2.12,cc:cc:cc:cc:cc:cc,,200,200,8,1,1,,1\n");
+                  "fqdn_fwd,fqdn_rev,hostname,state,user_context\n"
+                  "192.0.2.1,01:01:01:01:01:01,,200,200,8,1,1,,1,\n"
+                  "192.0.2.11,bb:bb:bb:bb:bb:bb,,200,400,8,1,1,,1,\n"
+                  "192.0.2.12,cc:cc:cc:cc:cc:cc,,200,200,8,1,1,,1,\n");
 
     LeaseFileIO io(getLeaseFilePath("leasefile4_0.csv"));
     io.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
-                 "fqdn_fwd,fqdn_rev,hostname,state\n"
-                 "192.0.2.10,0a:0a:0a:0a:0a:0a,,200,200,8,1,1,,1\n"
-                 "192.0.2.12,cc:cc:cc:cc:cc:cc,,200,400,8,1,1,,1\n");
+                 "fqdn_fwd,fqdn_rev,hostname,state,user_context\n"
+                 "192.0.2.10,0a:0a:0a:0a:0a:0a,,200,200,8,1,1,,1,\n"
+                 "192.0.2.12,cc:cc:cc:cc:cc:cc,,200,400,8,1,1,,1,\n");
 
     LeaseFileIO ioc(getLeaseFilePath("leasefile4_0.csv.completed"));
     ioc.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
-                  "fqdn_fwd,fqdn_rev,hostname,state\n"
-                  "192.0.2.13,ff:ff:ff:ff:ff:ff,,200,200,8,1,1,,1\n");
+                  "fqdn_fwd,fqdn_rev,hostname,state,user_context\n"
+                  "192.0.2.13,ff:ff:ff:ff:ff:ff,,200,200,8,1,1,,1,\n");
 
     startBackend(V4);
 
@@ -1266,32 +1266,32 @@ TEST_F(MemfileLeaseMgrTest, load4LFCInProgress) {
 TEST_F(MemfileLeaseMgrTest, load6MultipleLeaseFiles) {
     LeaseFileIO io2(getLeaseFilePath("leasefile6_0.csv.2"));
     io2.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
-                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
-                  "state\n"
+                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
+                  "hwaddr,state,user_context\n"
                   "2001:db8:1::1,01:01:01:01:01:01:01:01:01:01:01:01:01,"
-                  "200,200,8,100,0,7,0,1,1,,,1\n"
+                  "200,200,8,100,0,7,0,1,1,,,1,\n"
                   "2001:db8:1::2,02:02:02:02:02:02:02:02:02:02:02:02:02,"
-                  "200,200,8,100,0,7,0,1,1,,,1\n");
+                  "200,200,8,100,0,7,0,1,1,,,1,\n");
 
     LeaseFileIO io1(getLeaseFilePath("leasefile6_0.csv.1"));
     io1.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
-                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
-                  "state\n"
+                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
+                  "hwaddr,state,user_context\n"
                   "2001:db8:1::3,03:03:03:03:03:03:03:03:03:03:03:03:03,"
-                  "200,200,8,100,0,7,0,1,1,,,1\n"
+                  "200,200,8,100,0,7,0,1,1,,,1,\n"
                   "2001:db8:1::2,02:02:02:02:02:02:02:02:02:02:02:02:02,"
-                  "300,800,8,100,0,7,0,1,1,,,1\n"
+                  "300,800,8,100,0,7,0,1,1,,,1,\n"
                   "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
-                  "200,200,8,100,0,7,0,1,1,,,1\n");
+                  "200,200,8,100,0,7,0,1,1,,,1,\n");
 
     LeaseFileIO io(getLeaseFilePath("leasefile6_0.csv"));
     io.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
-                 "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
-                 "state\n"
+                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
+                  "hwaddr,state,user_context\n"
                  "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
-                 "400,1000,8,100,0,7,0,1,1,,,1\n"
+                 "400,1000,8,100,0,7,0,1,1,,,1,\n"
                  "2001:db8:1::5,05:05:05:05:05:05:05:05:05:05:05:05:05,"
-                 "200,200,8,100,0,7,0,1,1,,,1\n");
+                 "200,200,8,100,0,7,0,1,1,,,1,\n");
 
     startBackend(V6);
 
@@ -1332,23 +1332,23 @@ TEST_F(MemfileLeaseMgrTest, load6MultipleLeaseFiles) {
 TEST_F(MemfileLeaseMgrTest, load6MultipleNoSecondFile) {
     LeaseFileIO io1(getLeaseFilePath("leasefile6_0.csv.1"));
     io1.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
-                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
-                  "state\n"
+                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
+                  "hwaddr,state,user_context\n"
                   "2001:db8:1::3,03:03:03:03:03:03:03:03:03:03:03:03:03,"
-                  "200,200,8,100,0,7,0,1,1,,,1\n"
+                  "200,200,8,100,0,7,0,1,1,,,1,\n"
                   "2001:db8:1::2,02:02:02:02:02:02:02:02:02:02:02:02:02,"
-                  "300,800,8,100,0,7,0,1,1,,,1\n"
+                  "300,800,8,100,0,7,0,1,1,,,1,\n"
                   "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
-                  "200,200,8,100,0,7,0,1,1,,,1\n");
+                  "200,200,8,100,0,7,0,1,1,,,1,\n");
 
     LeaseFileIO io(getLeaseFilePath("leasefile6_0.csv"));
     io.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
-                 "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
-                 "state\n"
+                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
+                  "hwaddr,state,user_context\n"
                  "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
-                 "400,1000,8,100,0,7,0,1,1,,,1\n"
+                 "400,1000,8,100,0,7,0,1,1,,,1,\n"
                  "2001:db8:1::5,05:05:05:05:05:05:05:05:05:05:05:05:05,"
-                 "200,200,8,100,0,7,0,1,1,,,1\n");
+                 "200,200,8,100,0,7,0,1,1,,,1,\n");
 
     startBackend(V6);
 
@@ -1380,21 +1380,21 @@ TEST_F(MemfileLeaseMgrTest, load6MultipleNoSecondFile) {
 TEST_F(MemfileLeaseMgrTest, load6MultipleNoFirstFile) {
     LeaseFileIO io2(getLeaseFilePath("leasefile6_0.csv.2"));
     io2.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
-                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
-                  "state\n"
+                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
+                  "hwaddr,state,user_context\n"
                   "2001:db8:1::1,01:01:01:01:01:01:01:01:01:01:01:01:01,"
-                  "200,200,8,100,0,7,0,1,1,,,1\n"
+                  "200,200,8,100,0,7,0,1,1,,,1,\n"
                   "2001:db8:1::2,02:02:02:02:02:02:02:02:02:02:02:02:02,"
-                  "200,200,8,100,0,7,0,1,1,,,1\n");
+                  "200,200,8,100,0,7,0,1,1,,,1,\n");
 
     LeaseFileIO io(getLeaseFilePath("leasefile6_0.csv"));
     io.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
-                 "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
-                 "state\n"
+                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
+                  "hwaddr,state,user_context\n"
                  "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
-                 "400,1000,8,100,0,7,0,1,1,,,1\n"
+                 "400,1000,8,100,0,7,0,1,1,,,1,\n"
                  "2001:db8:1::5,05:05:05:05:05:05:05:05:05:05:05:05:05,"
-                 "200,200,8,100,0,7,0,1,1,,,1\n");
+                 "200,200,8,100,0,7,0,1,1,,,1,\n");
 
     startBackend(V6);
 
@@ -1428,39 +1428,39 @@ TEST_F(MemfileLeaseMgrTest, load6MultipleNoFirstFile) {
 TEST_F(MemfileLeaseMgrTest, load6CompletedFile) {
     LeaseFileIO io2(getLeaseFilePath("leasefile6_0.csv.2"));
     io2.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
-                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
-                  "state\n"
+                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
+                  "hwaddr,state,user_context\n"
                   "2001:db8:1::1,01:01:01:01:01:01:01:01:01:01:01:01:01,"
-                  "200,200,8,100,0,7,0,1,1,,,1\n"
+                  "200,200,8,100,0,7,0,1,1,,,1,\n"
                   "2001:db8:1::2,02:02:02:02:02:02:02:02:02:02:02:02:02,"
-                  "200,200,8,100,0,7,0,1,1,,,1\n");
+                  "200,200,8,100,0,7,0,1,1,,,1,\n");
 
     LeaseFileIO io1(getLeaseFilePath("leasefile6_0.csv.1"));
     io1.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
-                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
-                  "state\n"
+                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
+                  "hwaddr,state,user_context\n"
                   "2001:db8:1::3,03:03:03:03:03:03:03:03:03:03:03:03:03,"
-                  "200,200,8,100,0,7,0,1,1,,,1\n"
+                  "200,200,8,100,0,7,0,1,1,,,1,\n"
                   "2001:db8:1::2,02:02:02:02:02:02:02:02:02:02:02:02:02,"
-                  "300,800,8,100,0,7,0,1,1,,,1\n"
+                  "300,800,8,100,0,7,0,1,1,,,1,\n"
                   "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
-                  "200,200,8,100,0,7,0,1,1,,,1\n");
+                  "200,200,8,100,0,7,0,1,1,,,1,\n");
 
     LeaseFileIO io(getLeaseFilePath("leasefile6_0.csv"));
     io.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
-                 "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
-                 "state\n"
+                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
+                  "hwaddr,state,user_context\n"
                  "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
-                 "400,1000,8,100,0,7,0,1,1,,,1\n"
+                 "400,1000,8,100,0,7,0,1,1,,,1,\n"
                  "2001:db8:1::5,05:05:05:05:05:05:05:05:05:05:05:05:05,"
-                 "200,200,8,100,0,7,0,1,1,,,1\n");
+                 "200,200,8,100,0,7,0,1,1,,,1,\n");
 
     LeaseFileIO ioc(getLeaseFilePath("leasefile6_0.csv.completed"));
     ioc.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
-                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
-                  "state\n"
+                  "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
+                  "hwaddr,state,user_context\n"
                   "2001:db8:1::125,ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff,"
-                  "400,1000,8,100,0,7,0,1,1,,,1\n");
+                  "400,1000,8,100,0,7,0,1,1,,,1,\n");
 
     startBackend(V6);
 
@@ -1521,7 +1521,7 @@ TEST_F(MemfileLeaseMgrTest, leaseUpgrade4) {
 
     std::string header_2_0 =
         "address,hwaddr,client_id,valid_lifetime,expire,"
-        "subnet_id,fqdn_fwd,fqdn_rev,hostname,state\n";
+        "subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context\n";
 
     // Create 1.0 Schema current lease file with two entries for
     // the same lease
@@ -1567,8 +1567,8 @@ TEST_F(MemfileLeaseMgrTest, leaseUpgrade4) {
 
     // Verify cleaned, converted contents
     std::string result_file_contents = header_2_0 +
-        "192.0.2.2,02:02:02:02:02:02,,200,800,8,1,1,,0\n"
-        "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,,0\n";
+        "192.0.2.2,02:02:02:02:02:02,,200,800,8,1,1,,0,\n"
+        "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,,0,\n";
     EXPECT_EQ(result_file_contents, input_file.readFile());
 }
 
@@ -1587,7 +1587,7 @@ TEST_F(MemfileLeaseMgrTest, leaseUpgrade6) {
     std::string header_3_0 =
         "address,duid,valid_lifetime,expire,subnet_id,"
         "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
-        "fqdn_rev,hostname,hwaddr,state\n";
+        "fqdn_rev,hostname,hwaddr,state,user_context\n";
 
     // The current lease file is schema 1.0 and has two entries for
     // the same lease
@@ -1638,9 +1638,9 @@ TEST_F(MemfileLeaseMgrTest, leaseUpgrade6) {
     // Verify cleaned, converted contents
     std::string result_file_contents = header_3_0 +
         "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
-        "8,100,0,7,0,1,1,,,0\n"
+        "8,100,0,7,0,1,1,,,0,\n"
         "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
-        "8,100,0,7,0,1,1,,11:22:33:44:55,0\n";
+        "8,100,0,7,0,1,1,,11:22:33:44:55,0,\n";
     EXPECT_EQ(result_file_contents, input_file.readFile());
 }
 
index 46f8e26f8e9c125c7b796ca9a8233c7527b1c627..000eefd4b1ee39c77a53712ad599ffcb21fd7b2e 100644 (file)
@@ -4,6 +4,7 @@ sqlscriptsdir = ${datarootdir}/${PACKAGE_NAME}/scripts/cql
 sqlscripts_DATA = dhcpdb_create.cql
 sqlscripts_DATA += dhcpdb_drop.cql
 sqlscripts_DATA += upgrade_1.0_to_2.0.sh
+sqlscripts_DATA += upgrade_2.0_to_2.1.sh
 sqlscripts_DATA += soft_wipe.cql
 
 EXTRA_DIST = ${sqlscripts_DATA}
index be163e68cd7098e8b613ea86a25edddba1bcf0df..1f565f68ae0b74375aa3f846ba1ec9945bee8a69 100644 (file)
@@ -1,3 +1,4 @@
+-- Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
 -- Copyright (C) 2015-2018 Deutsche Telekom AG.
 
 -- Author: Razvan Becheriu <razvan.becheriu@qualitance.com>
@@ -272,3 +273,27 @@ DELETE FROM schema_version WHERE version=1;
 INSERT INTO schema_version (version, minor) VALUES(2, 0);
 
 -- This line concludes database upgrade to version 2.0
+
+-- This line starts database upgrade to version 2.1
+
+-- Add a column holding leases for user context.
+ALTER TABLE lease4 ADD user_context text;
+ALTER TABLE lease6 ADD user_context text;
+
+-- -----------------------------------------------------
+-- Table `logs`
+-- -----------------------------------------------------
+CREATE TABLE IF NOT EXISTS logs (
+    timeuuid timeuuid,  -- creation timeuuid, use dateOf() to get timestamp
+    address varchar,    -- address or prefix
+    log text,           -- the log itself
+    PRIMARY KEY ((timeuuid))
+);
+
+-- Create search index for logs table
+CREATE INDEX IF NOT EXISTS logsindex ON logs (address);
+
+DELETE FROM schema_version WHERE version=2;
+INSERT INTO schema_version (version, minor) VALUES(2, 1);
+
+-- This line concludes database upgrade to version 2.1
index 387451f561fa033eee0cc2e658b8a0601f9b7abe..40641549f7163a5c480a8c65d430f4a319644c8b 100644 (file)
@@ -1,3 +1,4 @@
+-- Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
 -- Copyright (C) 2015-2017 Deutsche Telekom AG.
 
 -- Author: Razvan Becheriu <razvan.becheriu@qualitance.com>
@@ -25,6 +26,7 @@ DROP TABLE IF EXISTS dhcp4_options;
 DROP TABLE IF EXISTS dhcp6_options;
 DROP TABLE IF EXISTS host_identifier_type;
 DROP TABLE IF EXISTS dhcp_option_scope;
+DROP TABLE IF EXISTS logs;
 
 DROP INDEX IF EXISTS lease4index1;
 DROP INDEX IF EXISTS lease4index2;
@@ -46,3 +48,5 @@ DROP INDEX IF EXISTS host_reservationsindex4;
 DROP INDEX IF EXISTS host_reservationsindex5;
 DROP INDEX IF EXISTS host_reservationsindex6;
 DROP INDEX IF EXISTS host_reservationsindex7;
+
+DROP INDEX IF EXISTS logsindex;
index 5c9580843c2f70533554e64bdb85e4388ca6c062..722de01d79fac35d78a6ea55c552d8d34ef80a6c 100644 (file)
@@ -1,4 +1,4 @@
--- Copyright (C) 2016 Internet Systems Consortium.
+-- Copyright (C) 2016-2018 Internet Systems Consortium.
 --
 -- This Source Code Form is subject to the terms of the Mozilla Public
 -- License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -24,3 +24,4 @@ TRUNCATE TABLE lease_hwaddr_source;
 TRUNCATE TABLE lease_state;
 TRUNCATE TABLE schema_version;
 TRUNCATE TABLE host_reservations;
+TRUNCATE TABLE logs;
diff --git a/src/share/database/scripts/cql/upgrade_2.0_to_2.1.sh.in b/src/share/database/scripts/cql/upgrade_2.0_to_2.1.sh.in
new file mode 100644 (file)
index 0000000..94a27aa
--- /dev/null
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+prefix=@prefix@
+# 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
+    . @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh
+else
+    . @abs_top_builddir@/src/bin/admin/admin-utils.sh
+fi
+
+version=$(cql_version "$@")
+
+if [ "${version}" != "2.0" ]; then
+    printf "This script upgrades 2.0 to 2.1. Reported version is %s. Skipping upgrade.\n" "${version}"
+    exit 0
+fi
+
+cqlsh "$@" <<EOF
+-- This line starts database upgrade to version 2.1
+
+-- Add a column holding leases for user context.
+ALTER TABLE lease4 ADD user_context text;
+ALTER TABLE lease6 ADD user_context text;
+
+-- -----------------------------------------------------
+-- Table `logs`
+-- -----------------------------------------------------
+CREATE TABLE IF NOT EXISTS logs (
+    timeuuid timeuuid,  -- creation timeuuid, use dateOf() to get timestamp
+    address varchar,    -- address or prefix
+    log text,           -- the log itself
+    PRIMARY KEY ((timeuuid))
+);
+
+-- Create search index for logs table
+CREATE INDEX IF NOT EXISTS logsindex ON logs (address);
+
+DELETE FROM schema_version WHERE version=2;
+INSERT INTO schema_version (version, minor) VALUES(2, 1);
+
+-- This line concludes database upgrade to version 2.1
+EOF
+
+exit $?
index eff6631399f481509e7266df54316dace0126d7e..85525065f35e5979b02f5d5f85c1c0cab89dd12f 100644 (file)
@@ -11,6 +11,7 @@ sqlscripts_DATA += upgrade_4.1_to_5.0.sh
 sqlscripts_DATA += upgrade_5.0_to_5.1.sh
 sqlscripts_DATA += upgrade_5.1_to_5.2.sh
 sqlscripts_DATA += upgrade_5.2_to_6.0.sh
+sqlscripts_DATA += upgrade_6.0_to_6.1.sh
 
 DISTCLEANFILES = upgrade_1.0_to_2.0.sh
 DISTCLEANFILES += upgrade_2.0_to_3.0.sh
@@ -20,5 +21,6 @@ DISTCLEANFILES += upgrade_4.1_to_5.0.sh
 DISTCLEANFILES += upgrade_5.0_to_5.1.sh
 DISTCLEANFILES += upgrade_5.1_to_5.2.sh
 DISTCLEANFILES += upgrade_5.2_to_6.0.sh
+DISTCLEANFILES += upgrade_6.0_to_6.1.sh
 
 EXTRA_DIST = ${sqlscripts_DATA}
index 09dd299b0ac66ea649e521066104ba4e1fb81859..f71f6160c8f5009409e527385503a4539a9da76c 100644 (file)
@@ -677,6 +677,26 @@ SET version = '6', minor = '0';
 
 # This line concludes database upgrade to version 6.0.
 
+# Add user context into tables holding leases
+ALTER TABLE lease4 ADD COLUMN user_context TEXT NULL;
+ALTER TABLE lease6 ADD COLUMN user_context TEXT NULL;
+
+# Create logs table
+CREATE TABLE logs (
+    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  # creation timestamp
+    address VARCHAR(43) NULL,                       # address or prefix
+    log TEXT NOT NULL                               # the log itself
+    ) ENGINE = INNODB;
+
+# Create search index
+CREATE INDEX timestamp_index ON logs (timestamp);
+
+# Update the schema version number
+UPDATE schema_version
+SET version = '6', minor = '1';
+
+# This line concludes database upgrade to version 6.1.
+
 # Notes:
 #
 # Indexes
index 0879d2610195e6ec0283b90d236565040c0c650c..30c65c7bc2df4ad58b2cc2a884d1598815c638ae 100644 (file)
@@ -31,3 +31,4 @@ DROP TRIGGER IF EXISTS lease6_stat_insert;
 DROP TRIGGER IF EXISTS lease6_stat_update;
 DROP TRIGGER IF EXISTS lease6_stat_delete;
 DROP TABLE IF EXISTS lease6_stat;
+DROP TABLE IF EXISTS logs;
diff --git a/src/share/database/scripts/mysql/upgrade_6.0_to_6.1.sh.in b/src/share/database/scripts/mysql/upgrade_6.0_to_6.1.sh.in
new file mode 100644 (file)
index 0000000..8f1c0f9
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# 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
+    . @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh
+else
+    . @abs_top_builddir@/src/bin/admin/admin-utils.sh
+fi
+
+VERSION=`mysql_version "$@"`
+
+if [ "$VERSION" != "6.0" ]; then
+    printf "This script upgrades 6.0 to 6.1. Reported version is $VERSION. Skipping upgrade.\n"
+    exit 0
+fi
+
+mysql "$@" <<EOF
+
+# Add user context into tables holding leases
+ALTER TABLE lease4 ADD COLUMN user_context TEXT NULL;
+ALTER TABLE lease6 ADD COLUMN user_context TEXT NULL;
+
+# Create logs table
+CREATE TABLE logs (
+    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  # creation timestamp
+    address VARCHAR(43) NULL,                       # address or prefix
+    log TEXT NOT NULL                               # the log itself
+    ) ENGINE = INNODB;
+
+# Create search index
+CREATE INDEX timestamp_index ON logs (timestamp);
+
+# Update the schema version number
+UPDATE schema_version
+SET version = '6', minor = '1';
+
+# This line concludes database upgrade to version 6.1.
+
+EOF
+
+RESULT=$?
+
+exit $?
index 7187d143973194b639cc00211e4e8f2f9824f5aa..72213fe179127737879377dbe39bc7cd4c22c727 100644 (file)
@@ -9,6 +9,7 @@ sqlscripts_DATA += upgrade_3.0_to_3.1.sh
 sqlscripts_DATA += upgrade_3.1_to_3.2.sh
 sqlscripts_DATA += upgrade_3.2_to_3.3.sh
 sqlscripts_DATA += upgrade_3.3_to_4.0.sh
+sqlscripts_DATA += upgrade_4.0_to_4.1.sh
 
 DISTCLEANFILES = upgrade_1.0_to_2.0.sh
 DISTCLEANFILES += upgrade_2.0_to_3.0.sh
@@ -16,5 +17,6 @@ DISTCLEANFILES += upgrade_3.0_to_3.1.sh
 DISTCLEANFILES += upgrade_3.1_to_3.2.sh
 DISTCLEANFILES += upgrade_3.2_to_3.3.sh
 DISTCLEANFILES += upgrade_3.3_to_4.0.sh
+DISTCLEANFILES += upgrade_4.0_to_4.1.sh
 
 EXTRA_DIST = ${sqlscripts_DATA}
index a525b80915faed7c616b22ada00218ab91da4805..520ba434b621c42bcc756b845b15b9450fafda51 100644 (file)
@@ -754,6 +754,30 @@ UPDATE schema_version
 
 -- Schema 4.0 specification ends here.
 
+-- Upgrade to schema 4.1 begins here:
+
+-- Add a column holding leases for user context.
+ALTER TABLE lease4 ADD COLUMN user_context TEXT;
+ALTER TABLE lease6 ADD COLUMN user_context TEXT;
+
+-- Create logs table
+CREATE TABLE logs (
+    timestamp TIMESTAMP WITH TIME ZONE
+    DEFAULT CURRENT_TIMESTAMP,          -- creation timestamp
+    address VARCHAR(43) NULL,           -- address or prefix
+    log TEXT NOT NULL                   -- the log itself
+    );
+
+-- Create search indexes
+CREATE INDEX timestamp_id ON logs (timestamp);
+CREATE INDEX address_id ON logs (address);
+
+-- Set 4.1 schema version.
+UPDATE schema_version
+    SET version = '4', minor = '1';
+
+-- Schema 4.1 specification ends here.
+
 -- Commit the script transaction.
 COMMIT;
 
index 3d302f0c4d405a313015a661d49d23221b62695b..7e962675a372adbdc9a6674e57f92d7653555162 100644 (file)
@@ -28,3 +28,4 @@ DROP TABLE IF EXISTS lease6_stat CASCADE;
 DROP FUNCTION IF EXISTS proc_stat_lease6_insert ();
 DROP FUNCTION IF EXISTS proc_stat_lease6_update ();
 DROP FUNCTION IF EXISTS proc_stat_lease6_delete ();
+DROP TABLE IF EXISTS logs CASCADE;
diff --git a/src/share/database/scripts/pgsql/upgrade_4.0_to_4.1.sh.in b/src/share/database/scripts/pgsql/upgrade_4.0_to_4.1.sh.in
new file mode 100644 (file)
index 0000000..9a58581
--- /dev/null
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+# 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
+    . @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh
+else
+    . @abs_top_builddir@/src/bin/admin/admin-utils.sh
+fi
+
+VERSION=`pgsql_version "$@"`
+
+if [ "$VERSION" != "4.0" ]; then
+    printf "This script upgrades 4.0 to 4.1. Reported version is $VERSION. Skipping upgrade.\n"
+    exit 0
+fi
+
+psql "$@" >/dev/null <<EOF
+
+START TRANSACTION;
+
+-- Add a column holding leases for user context.
+ALTER TABLE lease4 ADD COLUMN user_context TEXT;
+ALTER TABLE lease6 ADD COLUMN user_context TEXT;
+
+-- Create logs table
+CREATE TABLE logs (
+    timestamp TIMESTAMP WITH TIME ZONE
+    DEFAULT CURRENT_TIMESTAMP,          -- creation timestamp
+    address VARCHAR(43) NULL,           -- address or prefix
+    log TEXT NOT NULL                   -- the log itself
+    );
+
+-- Create search indexes
+CREATE INDEX timestamp_id ON logs (timestamp);
+CREATE INDEX address_id ON logs (address);
+
+-- Set 4.1 schema version.
+UPDATE schema_version
+    SET version = '4', minor = '1';
+
+-- Schema 4.1 specification ends here.
+
+-- Commit the script transaction
+COMMIT;
+
+EOF
+
+exit $RESULT
+