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
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
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
])
+// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-2017 Deutsche Telekom AG.
//
// Authors: Razvan Becheriu <razvan.becheriu@qualitance.com>
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
+// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-2018 Deutsche Telekom AG.
//
// Authors: Razvan Becheriu <razvan.becheriu@qualitance.com>
#include <asiolink/io_address.h>
+using namespace isc::data;
using isc::asiolink::IOAddress;
namespace isc {
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
///
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.
/// @brief Lease state
cass_int32_t state_;
+
+ /// @brief User context
+ std::string user_context_;
};
/// @brief Exchange Lease4 information between Kea and CQL
{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 "}},
"fqdn_fwd = ?, "
"fqdn_rev = ?, "
"hostname = ?, "
- "state = ? "
+ "state = ?, "
+ "user_context = ? "
"WHERE address = ? "
"IF EXISTS "}},
{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 < ? "
{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
{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 = ? "}},
{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 "}},
{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 = ? "
{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 "}},
{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 = ? "
{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 "}}
// 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_);
data.add(&fqdn_rev_);
data.add(&hostname_);
data.add(&state_);
+ data.add(&user_context_);
} catch (const Exception &ex) {
isc_throw(DbOperationError, "CqlLease4Exchange::createBindForInsert(): "
// 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_);
data.add(&fqdn_rev_);
data.add(&hostname_);
data.add(&state_);
+ data.add(&user_context_);
data.add(&address_);
} catch (const Exception &ex) {
// state: int
data.add(&state_);
+
+ // user_context: text
+ data.add(&user_context_);
}
boost::any
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_,
result->state_ = state_;
+ if (ctx) {
+ result->setContext(ctx);
+ }
+
return (result);
} catch (const Exception &ex) {
isc_throw(DbOperationError,
"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 "}},
"hwaddr = ?, "
"hwtype = ?, "
"hwaddr_source = ?, "
- "state = ? "
+ "state = ?, "
+ "user_context = ? "
"WHERE address = ? "
"IF EXISTS "}},
"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 < ? "
"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 = ? "
"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 = ? "
"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 = ? "
// 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(&hwtype_);
data.add(&hwaddr_source_);
data.add(&state_);
+ data.add(&user_context_);
} catch (const Exception &ex) {
isc_throw(DbOperationError, "CqlLease6Exchange::createBindForInsert(): "
// 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(&hwtype_);
data.add(&hwaddr_source_);
data.add(&state_);
+ data.add(&user_context_);
data.add(&address_);
} catch (const Exception &ex) {
// state: int
data.add(&state_);
+
+ // user_context: text
+ data.add(&user_context_);
}
boost::any
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(
result->state_ = state_;
+ if (ctx) {
+ result->setContext(ctx);
+ }
+
return (result);
} catch (const Exception &ex) {
isc_throw(DbOperationError,
-// 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
#include <dhcpsrv/csv_lease_file4.h>
using namespace isc::asiolink;
+using namespace isc::data;
using namespace isc::util;
namespace isc {
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);
" 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],
readHostname(row)));
lease->state_ = state;
+ if (ctx) {
+ lease->setContext(ctx);
+ }
+
} catch (std::exception& ex) {
// bump the read error count
++read_errs_;
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");
}
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
-// 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
/// - fqdn_rev
/// - hostname
/// - state
+ /// - user_context
void initColumns();
///
///
/// @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);
//@}
};
-// 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
#include <dhcpsrv/csv_lease_file6.h>
using namespace isc::asiolink;
+using namespace isc::data;
using namespace isc::util;
namespace isc {
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&) {
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_;
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");
}
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
-// 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
/// - hostname
/// - hwaddr
/// - state
+ /// - user_context
void initColumns();
///
///
/// @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);
//@}
};
}
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)
client_id_.reset();
}
+
+ if (other.getContext()) {
+ setContext(other.getContext());
+ }
}
Lease4::Lease4(const isc::asiolink::IOAddress& address,
} else {
client_id_.reset();
}
+
+ if (other.getContext()) {
+ setContext(other.getContext());
+ }
}
return (*this);
}
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)));
<< "Subnet ID: " << subnet_id_ << "\n"
<< "State: " << statesToText(state_) << "\n";
+ if (getContext()) {
+ stream << "User context: " << getContext() << "\n";
+ }
+
return (stream.str());
}
<< "Subnet ID: " << subnet_id_ << "\n"
<< "State: " << statesToText(state_) << "\n";
+ if (getContext()) {
+ stream << "User context: " << getContext() << "\n";
+ }
+
return (stream.str());
}
hostname_ == other.hostname_ &&
fqdn_fwd_ == other.fqdn_fwd_ &&
fqdn_rev_ == other.fqdn_rev_ &&
- state_ == other.state_);
+ state_ == other.state_ &&
+ nullOrEqualValues(getContext(), other.getContext()));
}
bool
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) {
#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 {
///
/// 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 {
/// 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;
/// @}
/// @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;
//@}
using namespace isc;
using namespace isc::dhcp;
+using namespace isc::data;
using namespace std;
/// @file
/// 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,
"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 "
"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, "
"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,
"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,
"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 = ?"},
"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,
"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 "
"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 = ?, "
"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"
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
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)
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
// 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,
// 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.
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_,
// Set state.
lease->state_ = state_;
+ if (ctx) {
+ lease->setContext(ctx);
+ }
+
return (lease);
}
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
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
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)
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
// 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,
// 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.
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_,
// Set state.
result->state_ = state_;
+ if (ctx) {
+ result->setContext(ctx);
+ }
+
return (result);
}
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
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
using namespace isc;
using namespace isc::dhcp;
+using namespace isc::data;
using namespace std;
namespace {
"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
"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"},
"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"},
"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"},
"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"},
"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"},
"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"},
"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 "
"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
"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"},
"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"},
"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"},
"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"},
"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",
: 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(){}
bool fqdn_rev_;
std::string hostname_;
std::string state_str_;
+ std::string user_context_;
//@}
};
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:
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.
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: "
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_,
result->state_ = state;
+ if (ctx) {
+ result->setContext(ctx);
+ }
+
return (result);
} catch (const std::exception& ex) {
isc_throw(DbOperationError,
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()
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.
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: "
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,
result->state_ = state;
+ if (ctx) {
+ result->setContext(ctx);
+ }
+
return (result);
} catch (const std::exception& ex) {
isc_throw(DbOperationError,
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.
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());
}
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_);
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_);
// 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());
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.
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());
}
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_);
// 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.
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());
/// @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";
}
};
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
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
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";
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
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.
// 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;
// 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);
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
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);
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
// 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
// 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);
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);
// 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);
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);
// 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);
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);
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);
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);
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);
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);
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);
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
// 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());
}
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
// 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());
}
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}
+-- Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
-- Copyright (C) 2015-2018 Deutsche Telekom AG.
-- Author: Razvan Becheriu <razvan.becheriu@qualitance.com>
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
+-- Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
-- Copyright (C) 2015-2017 Deutsche Telekom AG.
-- Author: Razvan Becheriu <razvan.becheriu@qualitance.com>
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;
DROP INDEX IF EXISTS host_reservationsindex5;
DROP INDEX IF EXISTS host_reservationsindex6;
DROP INDEX IF EXISTS host_reservationsindex7;
+
+DROP INDEX IF EXISTS logsindex;
--- 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
TRUNCATE TABLE lease_state;
TRUNCATE TABLE schema_version;
TRUNCATE TABLE host_reservations;
+TRUNCATE TABLE logs;
--- /dev/null
+#!/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 $?
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
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}
# 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
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;
--- /dev/null
+#!/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 $?
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
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}
-- 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;
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;
--- /dev/null
+#!/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
+