mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 22:15:23 +00:00
[5584] Checkpoint: updated schema, code and partially tests
This commit is contained in:
@@ -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
|
||||
])
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
//@}
|
||||
|
||||
};
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
//@}
|
||||
|
||||
};
|
||||
|
@@ -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) {
|
||||
|
@@ -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 {
|
||||
|
@@ -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;
|
||||
|
||||
/// @}
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
//@}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
@@ -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());
|
||||
|
@@ -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());
|
||||
|
@@ -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;
|
||||
|
@@ -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());
|
||||
}
|
||||
|
||||
|
@@ -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}
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
45
src/share/database/scripts/cql/upgrade_2.0_to_2.1.sh.in
Normal file
45
src/share/database/scripts/cql/upgrade_2.0_to_2.1.sh.in
Normal file
@@ -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 $?
|
@@ -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}
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
44
src/share/database/scripts/mysql/upgrade_6.0_to_6.1.sh.in
Normal file
44
src/share/database/scripts/mysql/upgrade_6.0_to_6.1.sh.in
Normal file
@@ -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 $?
|
@@ -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}
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
|
50
src/share/database/scripts/pgsql/upgrade_4.0_to_4.1.sh.in
Normal file
50
src/share/database/scripts/pgsql/upgrade_4.0_to_4.1.sh.in
Normal file
@@ -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
|
||||
|
Reference in New Issue
Block a user