2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-03 07:25:18 +00:00

[313-return-a-list-of-all-reservations-by-subnet-id] Finished the getAll[46] implementation

This commit is contained in:
Francis Dupont
2019-01-13 11:40:20 +01:00
parent 2a5750c931
commit 55e2828cf2
18 changed files with 625 additions and 36 deletions

View File

@@ -106,7 +106,8 @@ EXTRA_DIST += api/network6-add.json api/network6-del.json
EXTRA_DIST += api/network6-get.json api/network6-list.json EXTRA_DIST += api/network6-get.json api/network6-list.json
EXTRA_DIST += api/network6-subnet-add.json api/network6-subnet-del.json EXTRA_DIST += api/network6-subnet-add.json api/network6-subnet-del.json
EXTRA_DIST += api/reservation-add.json api/reservation-del.json EXTRA_DIST += api/reservation-add.json api/reservation-del.json
EXTRA_DIST += api/reservation-get.json api/shutdown.json EXTRA_DIST += api/reservation-get.json api/reservation-get-all.json
EXTRA_DIST += api/shutdown.json
EXTRA_DIST += api/statistic-get-all.json api/statistic-get.json EXTRA_DIST += api/statistic-get-all.json api/statistic-get.json
EXTRA_DIST += api/statistic-remove-all.json api/statistic-remove.json EXTRA_DIST += api/statistic-remove-all.json api/statistic-remove.json
EXTRA_DIST += api/statistic-reset-all.json api/statistic-reset.json EXTRA_DIST += api/statistic-reset-all.json api/statistic-reset.json

View File

@@ -0,0 +1,14 @@
{
"name": "reservation-get-all",
"brief": "Retrieve all host reservations for a specified subnet.",
"support": [ "kea-dhcp4", "kea-dhcp6" ],
"hook": "host_cmds",
"avail": "1.6.0",
"cmd-syntax": "{
\"command\": \"reservation-get-all\",
\"arguments\": {
\"subnet-id\": <integer>
}",
"resp-comment": "reservation-get-all command may result in very large responses."
}

View File

@@ -51,6 +51,7 @@ network6-subnet-del
reservation-add reservation-add
reservation-del reservation-del
reservation-get reservation-get
reservation-get-all
shutdown shutdown
stat-lease4-get stat-lease4-get
stat-lease6-get stat-lease6-get

View File

@@ -63,6 +63,7 @@
, <command><link linkend="ref-reservation-add">reservation-add</link></command> , <command><link linkend="ref-reservation-add">reservation-add</link></command>
, <command><link linkend="ref-reservation-del">reservation-del</link></command> , <command><link linkend="ref-reservation-del">reservation-del</link></command>
, <command><link linkend="ref-reservation-get">reservation-get</link></command> , <command><link linkend="ref-reservation-get">reservation-get</link></command>
, <command><link linkend="ref-reservation-get-all">reservation-get-all</link></command>
, <command><link linkend="ref-shutdown">shutdown</link></command> , <command><link linkend="ref-shutdown">shutdown</link></command>
, <command><link linkend="ref-stat-lease4-get">stat-lease4-get</link></command> , <command><link linkend="ref-stat-lease4-get">stat-lease4-get</link></command>
, <command><link linkend="ref-stat-lease6-get">stat-lease6-get</link></command> , <command><link linkend="ref-stat-lease6-get">stat-lease6-get</link></command>
@@ -143,6 +144,7 @@
, <command><link linkend="ref-reservation-add">reservation-add</link></command> , <command><link linkend="ref-reservation-add">reservation-add</link></command>
, <command><link linkend="ref-reservation-del">reservation-del</link></command> , <command><link linkend="ref-reservation-del">reservation-del</link></command>
, <command><link linkend="ref-reservation-get">reservation-get</link></command> , <command><link linkend="ref-reservation-get">reservation-get</link></command>
, <command><link linkend="ref-reservation-get-all">reservation-get-all</link></command>
, <command><link linkend="ref-shutdown">shutdown</link></command> , <command><link linkend="ref-shutdown">shutdown</link></command>
, <command><link linkend="ref-stat-lease4-get">stat-lease4-get</link></command> , <command><link linkend="ref-stat-lease4-get">stat-lease4-get</link></command>
, <command><link linkend="ref-statistic-get">statistic-get</link></command> , <command><link linkend="ref-statistic-get">statistic-get</link></command>
@@ -198,6 +200,7 @@
, <command><link linkend="ref-reservation-add">reservation-add</link></command> , <command><link linkend="ref-reservation-add">reservation-add</link></command>
, <command><link linkend="ref-reservation-del">reservation-del</link></command> , <command><link linkend="ref-reservation-del">reservation-del</link></command>
, <command><link linkend="ref-reservation-get">reservation-get</link></command> , <command><link linkend="ref-reservation-get">reservation-get</link></command>
, <command><link linkend="ref-reservation-get-all">reservation-get-all</link></command>
, <command><link linkend="ref-shutdown">shutdown</link></command> , <command><link linkend="ref-shutdown">shutdown</link></command>
, <command><link linkend="ref-stat-lease6-get">stat-lease6-get</link></command> , <command><link linkend="ref-stat-lease6-get">stat-lease6-get</link></command>
, <command><link linkend="ref-statistic-get">statistic-get</link></command> , <command><link linkend="ref-statistic-get">statistic-get</link></command>
@@ -233,6 +236,7 @@
<para xml:id="commands-host_cmds-lib">Commands supported by host_cmds hook library: <command><link linkend="ref-reservation-add">reservation-add</link></command> <para xml:id="commands-host_cmds-lib">Commands supported by host_cmds hook library: <command><link linkend="ref-reservation-add">reservation-add</link></command>
, <command><link linkend="ref-reservation-del">reservation-del</link></command> , <command><link linkend="ref-reservation-del">reservation-del</link></command>
, <command><link linkend="ref-reservation-get">reservation-get</link></command> , <command><link linkend="ref-reservation-get">reservation-get</link></command>
, <command><link linkend="ref-reservation-get-all">reservation-get-all</link></command>
.</para> .</para>
<para xml:id="commands-lease_cmds-lib">Commands supported by lease_cmds hook library: <command><link linkend="ref-lease4-add">lease4-add</link></command> <para xml:id="commands-lease_cmds-lib">Commands supported by lease_cmds hook library: <command><link linkend="ref-lease4-add">lease4-add</link></command>
, <command><link linkend="ref-lease4-del">lease4-del</link></command> , <command><link linkend="ref-lease4-del">lease4-del</link></command>
@@ -2511,6 +2515,61 @@ object appear only if specific field is set.</para>
</section> </section>
<!-- end of reservation-get --> <!-- end of reservation-get -->
<!-- start of reservation-get-all -->
<section xml:id="reference-reservation-get-all">
<title>reservation-get reference</title>
<para xml:id="ref-reservation-get-all"><command>reservation-get-all</command> - Retrieve all host reservations for a specified subnet.</para>
<para>Supported by: <command><link linkend="commands-kea-dhcp4">kea-dhcp4</link></command>, <command><link linkend="commands-kea-dhcp6">kea-dhcp6</link></command></para>
<para>Availability: 1.6.0 (<link linkend="commands-host_cmds-lib">host_cmds</link> hook)</para>
<para>Description and examples: See <xref linkend="command-reservation-get-all"/></para>
<para>Command syntax:
<screen>{
"command": "reservation-get-all",
"arguments": {
"subnet-id": &lt;integer&gt;
}
}</screen>
Host reservations can be identified by subnet-id.</para>
<para>Response syntax:
<screen>{
"result": &lt;integer&gt;,
"text": &lt;string&gt;,
"arguments": {
"hosts": [
{
"boot-file-name": &lt;string&gt;,
"comment": &lt;string&gt;
"client-id": &lt;string&gt;,
"circuit-id": &lt;string&gt;,
"duid": &lt;string&gt;,
"flex-id": &lt;string&gt;,
"ip-address": &lt;string (IPv4 address)&gt;,
"ip-addresses": [ &lt;comma separated strings&gt; ],
"hw-address": &lt;string&gt;,
"hostname": &lt;string&gt;,
"next-server": &lt;string (IPv4 address)&gt;,
"option-data-list": [ &lt;comma separated structures defining options&gt; ],
"prefixes": [ &lt;comma separated IPv6 prefixes&gt; ],
"reservation-client-classes": [ &lt;comma separated strings&gt; ],
"server-hostname": &lt;string&gt;,
"subnet-id": &lt;integer&gt;,
"user-context": &lt;any valid JSON&gt;,
},
...
]
}
}</screen>
The reservation-get-all command may result in very large responses.</para>
</section>
<!-- end of reservation-get-all -->
<!-- start of shutdown --> <!-- start of shutdown -->
<section xml:id="reference-shutdown"> <section xml:id="reference-shutdown">
<title>shutdown reference</title> <title>shutdown reference</title>

View File

@@ -1,5 +1,5 @@
<!-- <!--
- Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2014-2019 Internet Systems Consortium, Inc. ("ISC")
- -
- This Source Code Form is subject to the terms of the Mozilla Public - 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 - License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -1418,9 +1418,11 @@ $
</para> </para>
<para> <para>
Currently three commands are supported: reservation-add (which adds Currently four commands are supported: reservation-add (which adds
new host reservation), reservation-get (which returns existing new host reservation), reservation-get (which returns existing
reservation if specified criteria are matched) and reservation-del reservation if specified criteria are matched), reservation-get-all
(which returns all reservations in a specified subnet) and
reservation-del
(which attempts to delete a reservation matching specified (which attempts to delete a reservation matching specified
criteria). To use commands that change the reservation information criteria). To use commands that change the reservation information
(currently these are reservation-add and reservation-del, but this (currently these are reservation-add and reservation-del, but this
@@ -1585,7 +1587,7 @@ Here is an example of complex IPv6 reservation:
"circuit-id", "client-id" and "flex-id", but additional types may be "circuit-id", "client-id" and "flex-id", but additional types may be
added in the future. If any new identifier types are defined in the added in the future. If any new identifier types are defined in the
future, reservation-get command will support them automatically. future, reservation-get command will support them automatically.
The <command>subnet-id</command> is manadatory. Use a value of zero (0) to The <command>subnet-id</command> is mandatory. Use a value of zero (0) to
fetch a global reservation, or the id of the subnet to which the reservation fetch a global reservation, or the id of the subnet to which the reservation
belongs. belongs.
</para> </para>
@@ -1648,6 +1650,22 @@ An example result returned when the query was malformed:<screen>
</section> </section>
<section xml:id="command-reservation-get-all">
<title>reservation-get-all command</title>
<para><command>reservation-get-all</command> can be used to
query the host database and retrieve all reservations in a
specified subnet. This command uses parameters providing the
mandatory subnet-id. Use a value of zero (0) to fetch global
reservations.
</para>
<!-- Add example? -->
<para>The response returned by <command>reservation-get-all</command>
can be very long.
</para>
</section>
<section xml:id="command-reservation-del"> <section xml:id="command-reservation-del">
<title>reservation-del command</title> <title>reservation-del command</title>
<para><command>reservation-del</command> can be used to delete a <para><command>reservation-del</command> can be used to delete a

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2016-2017 Deutsche Telekom AG. // Copyright (C) 2016-2017 Deutsche Telekom AG.
// //
// Author: Andrei Pavel <andrei.pavel@qualitance.com> // Author: Andrei Pavel <andrei.pavel@qualitance.com>
@@ -311,6 +311,16 @@ public:
// Deletes a host reservation. // Deletes a host reservation.
static constexpr StatementTag DELETE_HOST = static constexpr StatementTag DELETE_HOST =
"DELETE_HOST"; "DELETE_HOST";
// Retrieves host information along with the IPv4 options associated
// with it using a subnet identifier.
static constexpr StatementTag GET_HOST_BY_IPV4_SUBNET_ID =
"GET_HOST_BY_IPV4_SUBNET_ID";
// Retrieves host information; IPv6 reservations and IPv6 options
// associated with a host using subnet identifier.
static constexpr StatementTag GET_HOST_BY_IPV6_SUBNET_ID =
"GET_HOST_BY_IPV6_SUBNET_ID";
/// @} /// @}
/// @brief Cassandra statements /// @brief Cassandra statements
@@ -420,6 +430,8 @@ constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS;
constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_PREFIX; constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_PREFIX;
constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS; constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS;
constexpr StatementTag CqlHostExchange::DELETE_HOST; constexpr StatementTag CqlHostExchange::DELETE_HOST;
constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID;
constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID;
StatementMap CqlHostExchange::tagged_statements_ = { StatementMap CqlHostExchange::tagged_statements_ = {
{INSERT_HOST, {INSERT_HOST,
@@ -762,6 +774,78 @@ StatementMap CqlHostExchange::tagged_statements_ = {
{DELETE_HOST, {DELETE_HOST,
"DELETE FROM host_reservations WHERE id = ? " "DELETE FROM host_reservations WHERE id = ? "
"IF EXISTS " "IF EXISTS "
}},
{GET_HOST_BY_IPV4_SUBNET_ID,
{GET_HOST_BY_IPV4_SUBNET_ID,
"SELECT "
"id, "
"host_identifier, "
"host_identifier_type, "
"host_ipv4_subnet_id, "
"host_ipv6_subnet_id, "
"host_ipv4_address, "
"host_ipv4_next_server, "
"host_ipv4_server_hostname, "
"host_ipv4_boot_file_name, "
"auth_key, "
"hostname, "
"user_context, "
"host_ipv4_client_classes, "
"host_ipv6_client_classes, "
"reserved_ipv6_prefix_address, "
"reserved_ipv6_prefix_length, "
"reserved_ipv6_prefix_address_type, "
"iaid, "
"option_universe, "
"option_code, "
"option_value, "
"option_formatted_value, "
"option_space, "
"option_is_persistent, "
"option_client_class, "
"option_subnet_id, "
"option_user_context, "
"option_scope_id "
"FROM host_reservations "
"WHERE host_ipv4_subnet_id = ? "
"ALLOW FILTERING "
}},
{GET_HOST_BY_IPV6_SUBNET_ID,
{GET_HOST_BY_IPV6_SUBNET_ID,
"SELECT "
"id, "
"host_identifier, "
"host_identifier_type, "
"host_ipv4_subnet_id, "
"host_ipv6_subnet_id, "
"host_ipv4_address, "
"host_ipv4_next_server, "
"host_ipv4_server_hostname, "
"host_ipv4_boot_file_name, "
"auth_key, "
"hostname, "
"user_context, "
"host_ipv4_client_classes, "
"host_ipv6_client_classes, "
"reserved_ipv6_prefix_address, "
"reserved_ipv6_prefix_length, "
"reserved_ipv6_prefix_address_type, "
"iaid, "
"option_universe, "
"option_code, "
"option_value, "
"option_formatted_value, "
"option_space, "
"option_is_persistent, "
"option_client_class, "
"option_subnet_id, "
"option_user_context, "
"option_scope_id "
"FROM host_reservations "
"WHERE host_ipv6_subnet_id = ? "
"ALLOW FILTERING "
}} }}
}; };
@@ -905,7 +989,7 @@ CqlHostExchange::prepareExchange(const HostPtr& host,
// auth_key: varchar // auth_key: varchar
auth_key_ = host->getKey().ToText(); auth_key_ = host->getKey().ToText();
// hostname: text // hostname: text
hostname_ = host->getHostname(); hostname_ = host->getHostname();
if (hostname_.size() > HOSTNAME_MAX_LENGTH) { if (hostname_.size() > HOSTNAME_MAX_LENGTH) {
@@ -1428,6 +1512,20 @@ public:
const uint8_t* identifier_begin, const uint8_t* identifier_begin,
const size_t identifier_len) const; const size_t identifier_len) const;
/// @brief Implementation of @ref CqlHostDataSource::getAll4()
///
/// See @ref CqlHostDataSource::getAll4() for parameter details.
///
/// @param subnet_id identifier of the subnet to which hosts belong
virtual ConstHostCollection getAll4(const SubnetID& subnet_id) const;
/// @brief Implementation of @ref CqlHostDataSource::getAll6()
///
/// See @ref CqlHostDataSource::getAll6() for parameter details.
///
/// @param subnet_id identifier of the subnet to which hosts belong
virtual ConstHostCollection getAll6(const SubnetID& subnet_id) const;
/// @brief Implementation of @ref CqlHostDataSource::getAll4() /// @brief Implementation of @ref CqlHostDataSource::getAll4()
/// ///
/// See @ref CqlHostDataSource::getAll4() for parameter details. /// See @ref CqlHostDataSource::getAll4() for parameter details.
@@ -1813,6 +1911,40 @@ CqlHostDataSourceImpl::getAll(const Host::IdentifierType& identifier_type,
return (result); return (result);
} }
ConstHostCollection
CqlHostDataSourceImpl::getAll4(const SubnetID& subnet_id) const {
// Convert to CQL data types.
cass_int32_t host_ipv4_subnet_id = static_cast<cass_int32_t>(subnet_id);
// Bind to array.
AnyArray where_values;
where_values.add(&host_ipv4_subnet_id);
// Run statement.
ConstHostCollection result =
getHostCollection(CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID,
where_values);
return (result);
}
ConstHostCollection
CqlHostDataSourceImpl::getAll6(const SubnetID& subnet_id) const {
// Convert to CQL data types.
cass_int32_t host_ipv6_subnet_id = static_cast<cass_int32_t>(subnet_id);
// Bind to array.
AnyArray where_values;
where_values.add(&host_ipv6_subnet_id);
// Run statement.
ConstHostCollection result =
getHostCollection(CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID,
where_values);
return (result);
}
ConstHostCollection ConstHostCollection
CqlHostDataSourceImpl::getAll4(const asiolink::IOAddress& address) const { CqlHostDataSourceImpl::getAll4(const asiolink::IOAddress& address) const {
// Convert to CQL data types. // Convert to CQL data types.
@@ -2099,6 +2231,20 @@ CqlHostDataSource::getAll(const Host::IdentifierType& identifier_type,
return (impl_->getAll(identifier_type, identifier_begin, identifier_len)); return (impl_->getAll(identifier_type, identifier_begin, identifier_len));
} }
ConstHostCollection
CqlHostDataSource::getAll4(const SubnetID& subnet_id) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_HOST_GET_ALL);
return (impl_->getAll4(subnet_id));
}
ConstHostCollection
CqlHostDataSource::getAll6(const SubnetID& subnet_id) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_HOST_GET_ALL);
return (impl_->getAll6(subnet_id));
}
ConstHostCollection ConstHostCollection
CqlHostDataSource::getAll4(const asiolink::IOAddress& address) const { CqlHostDataSource::getAll4(const asiolink::IOAddress& address) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_HOST_GET_ALL); LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_HOST_GET_ALL);

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // 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 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -129,7 +129,7 @@ public:
bind_(columns_num_), columns_(columns_num_), bind_(columns_num_), columns_(columns_num_),
error_(columns_num_, MLM_FALSE), host_id_(0), error_(columns_num_, MLM_FALSE), host_id_(0),
dhcp_identifier_length_(0), dhcp_identifier_type_(0), dhcp_identifier_length_(0), dhcp_identifier_type_(0),
dhcp4_subnet_id_(SUBNET_ID_UNUSED), dhcp4_subnet_id_(SUBNET_ID_UNUSED),
dhcp6_subnet_id_(SUBNET_ID_UNUSED), ipv4_address_(0), dhcp6_subnet_id_(SUBNET_ID_UNUSED), ipv4_address_(0),
hostname_length_(0), dhcp4_client_classes_length_(0), hostname_length_(0), dhcp4_client_classes_length_(0),
dhcp6_client_classes_length_(0), dhcp6_client_classes_length_(0),
@@ -407,7 +407,7 @@ public:
auth_key_null_ = auth_key.empty() ? MLM_TRUE : MLM_FALSE; auth_key_null_ = auth_key.empty() ? MLM_TRUE : MLM_FALSE;
bind_[13].buffer = auth_key_; bind_[13].buffer = auth_key_;
bind_[13].buffer_length = auth_key.length(); bind_[13].buffer_length = auth_key.length();
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
isc_throw(DbOperationError, isc_throw(DbOperationError,
"Could not create bind array from Host: " "Could not create bind array from Host: "
@@ -542,7 +542,7 @@ public:
bind_[13].buffer_length = auth_key_length_; bind_[13].buffer_length = auth_key_length_;
bind_[13].length = &auth_key_length_; bind_[13].length = &auth_key_length_;
bind_[13].is_null = &auth_key_null_; bind_[13].is_null = &auth_key_null_;
// Add the error flags // Add the error flags
setErrorIndicators(bind_, error_); setErrorIndicators(bind_, error_);
@@ -800,7 +800,7 @@ private:
/// The length of the string for holding keys /// The length of the string for holding keys
unsigned long auth_key_length_; unsigned long auth_key_length_;
/// @name Boolean values indicating if values of specific columns in /// @name Boolean values indicating if values of specific columns in
/// the database are NULL. /// the database are NULL.
//@{ //@{
@@ -1951,6 +1951,8 @@ public:
DEL_HOST_ADDR4, // Delete v4 host (subnet-id, addr4) DEL_HOST_ADDR4, // Delete v4 host (subnet-id, addr4)
DEL_HOST_SUBID4_ID, // Delete v4 host (subnet-id, ident.type, identifier) DEL_HOST_SUBID4_ID, // Delete v4 host (subnet-id, ident.type, identifier)
DEL_HOST_SUBID6_ID, // Delete v6 host (subnet-id, ident.type, identifier) DEL_HOST_SUBID6_ID, // Delete v6 host (subnet-id, ident.type, identifier)
GET_HOST_SUBID4, // Gets host by IPv4 SubnetID
GET_HOST_SUBID6, // Gets host by IPv6 SubnetID
NUM_STATEMENTS // Number of statements NUM_STATEMENTS // Number of statements
}; };
@@ -2330,7 +2332,41 @@ TaggedStatementArray tagged_statements = { {
{MySqlHostDataSourceImpl::DEL_HOST_SUBID6_ID, {MySqlHostDataSourceImpl::DEL_HOST_SUBID6_ID,
"DELETE FROM hosts WHERE dhcp6_subnet_id = ? AND dhcp_identifier_type=? " "DELETE FROM hosts WHERE dhcp6_subnet_id = ? AND dhcp_identifier_type=? "
"AND dhcp_identifier = ?"} "AND dhcp_identifier = ?"},
{MySqlHostDataSourceImpl::GET_HOST_SUBID4,
"SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
"h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
"h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
"h.dhcp4_next_server, h.dhcp4_server_hostname, "
"h.dhcp4_boot_file_name, h.auth_key, "
"o.option_id, o.code, o.value, o.formatted_value, o.space, "
"o.persistent, o.user_context "
"FROM hosts AS h "
"LEFT JOIN dhcp4_options AS o "
"ON h.host_id = o.host_id "
"WHERE h.dhcp4_subnet_id = ? "
"ORDER BY h.host_id, o.option_id"},
{MySqlHostDataSourceImpl::GET_HOST_SUBID6,
"SELECT h.host_id, h.dhcp_identifier, "
"h.dhcp_identifier_type, h.dhcp4_subnet_id, "
"h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
"h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
"h.dhcp4_next_server, h.dhcp4_server_hostname, "
"h.dhcp4_boot_file_name, h.auth_key, "
"o.option_id, o.code, o.value, o.formatted_value, o.space, "
"o.persistent, o.user_context, "
"r.reservation_id, r.address, r.prefix_len, r.type, "
"r.dhcp6_iaid "
"FROM hosts AS h "
"LEFT JOIN dhcp6_options AS o "
"ON h.host_id = o.host_id "
"LEFT JOIN ipv6_reservations AS r "
"ON h.host_id = r.host_id "
"WHERE h.dhcp6_subnet_id = ? "
"ORDER BY h.host_id, o.option_id, r.reservation_id"}
} }
}; };
@@ -2870,6 +2906,40 @@ MySqlHostDataSource::getAll(const Host::IdentifierType& identifier_type,
return (result); return (result);
} }
ConstHostCollection
MySqlHostDataSource::getAll4(const SubnetID& subnet_id) const {
// Set up the WHERE clause value
MYSQL_BIND inbind[1];
memset(inbind, 0, sizeof(inbind));
uint32_t subnet = subnet_id;
inbind[0].buffer_type = MYSQL_TYPE_LONG;
inbind[0].buffer = reinterpret_cast<char*>(&subnet);
inbind[0].is_unsigned = MLM_TRUE;
ConstHostCollection result;
impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_SUBID4,
inbind, impl_->host_exchange_,
result, false);
return (result);
}
ConstHostCollection
MySqlHostDataSource::getAll6(const SubnetID& subnet_id) const {
// Set up the WHERE clause value
MYSQL_BIND inbind[1];
memset(inbind, 0, sizeof(inbind));
uint32_t subnet = subnet_id;
inbind[0].buffer_type = MYSQL_TYPE_LONG;
inbind[0].buffer = reinterpret_cast<char*>(&subnet);
inbind[0].is_unsigned = MLM_TRUE;
ConstHostCollection result;
impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_SUBID6,
inbind, impl_->host_ipv6_exchange_,
result, false);
return (result);
}
ConstHostCollection ConstHostCollection
MySqlHostDataSource::getAll4(const asiolink::IOAddress& address) const { MySqlHostDataSource::getAll4(const asiolink::IOAddress& address) const {

View File

@@ -140,7 +140,7 @@ public:
/// ///
/// @return Collection of const @ref Host objects. /// @return Collection of const @ref Host objects.
virtual ConstHostCollection virtual ConstHostCollection
getAll4(const SubnetID& subnet_id) const override; getAll4(const SubnetID& subnet_id) const;
/// @brief Return all hosts in a DHCPv6 subnet. /// @brief Return all hosts in a DHCPv6 subnet.
/// ///
@@ -151,7 +151,7 @@ public:
/// ///
/// @return Collection of const @ref Host objects. /// @return Collection of const @ref Host objects.
virtual ConstHostCollection virtual ConstHostCollection
getAll6(const SubnetID& subnet_id) const override; getAll6(const SubnetID& subnet_id) const;
/// @brief Returns a collection of hosts using the specified IPv4 address. /// @brief Returns a collection of hosts using the specified IPv4 address.
/// ///

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2016-2019 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // 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 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -257,12 +257,12 @@ public:
// add auth keys // add auth keys
std::string key = host->getKey().ToText(); std::string key = host->getKey().ToText();
if (key.empty()) { if (key.empty()) {
bind_array->addNull(); bind_array->addNull();
} else { } else {
bind_array->add(key); bind_array->add(key);
} }
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
host_.reset(); host_.reset();
isc_throw(DbOperationError, isc_throw(DbOperationError,
@@ -1293,6 +1293,8 @@ public:
DEL_HOST_ADDR4, // Delete v4 host (subnet-id, addr4) DEL_HOST_ADDR4, // Delete v4 host (subnet-id, addr4)
DEL_HOST_SUBID4_ID, // Delete v4 host (subnet-id, ident.type, identifier) DEL_HOST_SUBID4_ID, // Delete v4 host (subnet-id, ident.type, identifier)
DEL_HOST_SUBID6_ID, // Delete v6 host (subnet-id, ident.type, identifier) DEL_HOST_SUBID6_ID, // Delete v6 host (subnet-id, ident.type, identifier)
GET_HOST_SUBID4, // Gets host by IPv4 SubnetID
GET_HOST_SUBID6, // Gets host by IPv6 SubnetID
NUM_STATEMENTS // Number of statements NUM_STATEMENTS // Number of statements
}; };
@@ -1714,6 +1716,50 @@ TaggedStatementArray tagged_statements = { {
"DELETE FROM hosts WHERE dhcp6_subnet_id = $1 " "DELETE FROM hosts WHERE dhcp6_subnet_id = $1 "
"AND dhcp_identifier_type = $2 " "AND dhcp_identifier_type = $2 "
"AND dhcp_identifier = $3" "AND dhcp_identifier = $3"
},
// PgSqlHostDataSourceImpl::GET_HOST_SUBID4
// Retrieves host information along with the DHCPv4 options associated with
// it. Left joining the dhcp4_options table results in multiple rows being
// returned for the same host. The host is retrieved by subnet id.
{1,
{ OID_INT8 }, "get_host_subid4",
"SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
" h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
" h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
" h.dhcp4_next_server, h.dhcp4_server_hostname, "
" h.dhcp4_boot_file_name, h.auth_key, "
" o.option_id, o.code, o.value, o.formatted_value, o.space, "
" o.persistent, o.user_context "
"FROM hosts AS h "
"LEFT JOIN dhcp4_options AS o ON h.host_id = o.host_id "
"WHERE h.dhcp4_subnet_id = $1 "
"ORDER BY h.host_id, o.option_id"
},
// PgSqlHostDataSourceImpl::GET_HOST_SUBID6
// Retrieves host information, IPv6 reservations and DHCPv6 options
// associated with a host using IPv6 subnet id. This query returns
// host information for a single host. However, multiple rows are
// returned due to left joining IPv6 reservations and DHCPv6 options.
// The number of rows returned is multiplication of number of existing
// IPv6 reservations and DHCPv6 options.
{1,
{ OID_INT8 }, "get_host_subid6",
"SELECT h.host_id, h.dhcp_identifier, "
" h.dhcp_identifier_type, h.dhcp4_subnet_id, "
" h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
" h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, "
" h.dhcp4_next_server, h.dhcp4_server_hostname, "
" h.dhcp4_boot_file_name, h.auth_key, "
" o.option_id, o.code, o.value, o.formatted_value, o.space, "
" o.persistent, o.user_context, "
" r.reservation_id, r.address, r.prefix_len, r.type, r.dhcp6_iaid "
"FROM hosts AS h "
"LEFT JOIN dhcp6_options AS o ON h.host_id = o.host_id "
"LEFT JOIN ipv6_reservations AS r ON h.host_id = r.host_id "
"WHERE h.dhcp6_subnet_id = $1 "
"ORDER BY h.host_id, o.option_id, r.reservation_id"
} }
} }
}; };
@@ -2097,6 +2143,38 @@ PgSqlHostDataSource::getAll(const Host::IdentifierType& identifier_type,
return (result); return (result);
} }
ConstHostCollection
PgSqlHostDataSource::getAll4(const SubnetID& subnet_id) const {
// Set up the WHERE clause value
PsqlBindArrayPtr bind_array(new PsqlBindArray());
// Add the subnet id.
bind_array->add(subnet_id);
ConstHostCollection result;
impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_SUBID4,
bind_array, impl_->host_exchange_,
result, false);
return (result);
}
ConstHostCollection
PgSqlHostDataSource::getAll6(const SubnetID& subnet_id) const {
// Set up the WHERE clause value
PsqlBindArrayPtr bind_array(new PsqlBindArray());
// Add the subnet id.
bind_array->add(subnet_id);
ConstHostCollection result;
impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_SUBID6,
bind_array, impl_->host_ipv6_exchange_,
result, false);
return (result);
}
ConstHostCollection ConstHostCollection
PgSqlHostDataSource::getAll4(const asiolink::IOAddress& address) const { PgSqlHostDataSource::getAll4(const asiolink::IOAddress& address) const {

View File

@@ -167,7 +167,7 @@ public:
/// ///
/// @return Collection of const @ref Host objects. /// @return Collection of const @ref Host objects.
virtual ConstHostCollection virtual ConstHostCollection
getAll4(const SubnetID& subnet_id) const override; getAll4(const SubnetID& subnet_id) const;
/// @brief Return all hosts in a DHCPv6 subnet. /// @brief Return all hosts in a DHCPv6 subnet.
/// ///
@@ -178,7 +178,7 @@ public:
/// ///
/// @return Collection of const @ref Host objects. /// @return Collection of const @ref Host objects.
virtual ConstHostCollection virtual ConstHostCollection
getAll6(const SubnetID& subnet_id) const override; getAll6(const SubnetID& subnet_id) const;
/// @brief Returns a collection of hosts using the specified IPv4 address. /// @brief Returns a collection of hosts using the specified IPv4 address.
/// ///

View File

@@ -206,6 +206,64 @@ TEST_F(CfgHostsTest, getAllRepeatingHosts) {
} }
} }
// This test checks that hosts in the same subnet can be retrieved from
// the host configuration.
TEST_F(CfgHostsTest, getAll4BySubnet) {
CfgHosts cfg;
// Add 25 hosts identified by HW address in the same subnet.
for (unsigned i = 0; i < 25; ++i) {
cfg.add(HostPtr(new Host(hwaddrs_[i]->toText(false),
"hw-address",
SubnetID(1), SubnetID(1),
addressesa_[i])));
}
// Check that other subnets are empty.
HostCollection hosts = cfg.getAll4(SubnetID(100));
EXPECT_EQ(0, hosts.size());
// Try to retrieve all added reservations.
hosts = cfg.getAll4(SubnetID(1));
ASSERT_EQ(25, hosts.size());
for (unsigned i = 0; i < 25; ++i) {
EXPECT_EQ(1, hosts[i]->getIPv4SubnetID());
EXPECT_EQ(addressesa_[i].toText(),
hosts[i]->getIPv4Reservation().toText());
}
}
// This test checks that hosts in the same subnet can be retrieved from
// the host configuration.
TEST_F(CfgHostsTest, getAll6BySubnet) {
CfgHosts cfg;
// Add 25 hosts identified by DUID in the same subnet.
for (unsigned i = 0; i < 25; ++i) {
HostPtr host = HostPtr(new Host(duids_[i]->toText(), "duid",
SubnetID(1), SubnetID(1),
IOAddress("0.0.0.0")));
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
increase(IOAddress("2001:db8:1::1"),
i)));
cfg.add(host);
}
// Check that other subnets are empty.
HostCollection hosts = cfg.getAll6(SubnetID(100));
EXPECT_EQ(0, hosts.size());
// Try to retrieve all added reservations.
hosts = cfg.getAll6(SubnetID(1));
ASSERT_EQ(25, hosts.size());
for (unsigned i = 0; i < 25; ++i) {
EXPECT_EQ(1, hosts[i]->getIPv6SubnetID());
IPv6ResrvRange reservations =
hosts[i]->getIPv6Reservations(IPv6Resrv::TYPE_NA);
ASSERT_EQ(1, std::distance(reservations.first, reservations.second));
EXPECT_EQ(increase(IOAddress("2001:db8:1::1"), i),
reservations.first->second.getPrefix());
}
}
// This test checks that all reservations for the specified IPv4 address can // This test checks that all reservations for the specified IPv4 address can
// be retrieved. // be retrieved.
TEST_F(CfgHostsTest, getAll4ByAddress) { TEST_F(CfgHostsTest, getAll4ByAddress) {

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2017-2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2017-2019 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2016-2017 Deutsche Telekom AG. // Copyright (C) 2016-2017 Deutsche Telekom AG.
// //
// Author: Andrei Pavel <andrei.pavel@qualitance.com> // Author: Andrei Pavel <andrei.pavel@qualitance.com>
@@ -293,6 +293,16 @@ TEST_F(CqlHostDataSourceTest, DISABLED_testReadOnlyDatabase) {
testReadOnlyDatabase(CQL_VALID_TYPE); testReadOnlyDatabase(CQL_VALID_TYPE);
} }
// Verifies that IPv4 host reservations in the same subnet can be retrieved
TEST_F(CqlHostDataSourceTest, getAll4BySubnet) {
testGetAll4(Host::IDENT_HWADDR);
}
// Verifies that IPv6 host reservations in the same subnet can be retrieved
TEST_F(CqlHostDataSourceTest, getAll6BySubnet) {
testGetAll6(Host::IDENT_DUID);
}
// Test verifies if a host reservation can be added and later retrieved by IPv4 // Test verifies if a host reservation can be added and later retrieved by IPv4
// address. Host uses hw address as identifier. // address. Host uses hw address as identifier.
TEST_F(CqlHostDataSourceTest, basic4HWAddr) { TEST_F(CqlHostDataSourceTest, basic4HWAddr) {

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // 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 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -311,6 +311,16 @@ TEST_F(MySqlHostDataSourceTest, maxSubnetId6) {
testMaxSubnetId6(); testMaxSubnetId6();
} }
// Verifies that IPv4 host reservations in the same subnet can be retrieved
TEST_F(MySqlHostDataSourceTest, getAll4BySubnet) {
testGetAll4(Host::IDENT_HWADDR);
}
// Verifies that IPv6 host reservations in the same subnet can be retrieved
TEST_F(MySqlHostDataSourceTest, getAll6BySubnet) {
testGetAll6(Host::IDENT_DUID);
}
// Test verifies if a host reservation can be added and later retrieved by IPv4 // Test verifies if a host reservation can be added and later retrieved by IPv4
// address. Host uses client-id (DUID) as identifier. // address. Host uses client-id (DUID) as identifier.
TEST_F(MySqlHostDataSourceTest, basic4ClientId) { TEST_F(MySqlHostDataSourceTest, basic4ClientId) {

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2016-2019 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // 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 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -296,6 +296,16 @@ TEST_F(PgSqlHostDataSourceTest, maxSubnetId6) {
testMaxSubnetId6(); testMaxSubnetId6();
} }
// Verifies that IPv4 host reservations in the same subnet can be retrieved
TEST_F(PgSqlHostDataSourceTest, getAll4BySubnet) {
testGetAll4(Host::IDENT_HWADDR);
}
// Verifies that IPv6 host reservations in the same subnet can be retrieved
TEST_F(PgSqlHostDataSourceTest, getAll6BySubnet) {
testGetAll6(Host::IDENT_DUID);
}
// Test verifies if a host reservation can be added and later retrieved by IPv4 // Test verifies if a host reservation can be added and later retrieved by IPv4
// address. Host uses client-id (DUID) as identifier. // address. Host uses client-id (DUID) as identifier.
TEST_F(PgSqlHostDataSourceTest, basic4ClientId) { TEST_F(PgSqlHostDataSourceTest, basic4ClientId) {

View File

@@ -356,6 +356,92 @@ void GenericHostDataSourceTest::testMaxSubnetId6() {
EXPECT_FALSE(host_by_id); EXPECT_FALSE(host_by_id);
} }
void
GenericHostDataSourceTest::testGetAll4(const Host::IdentifierType& id) {
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
// Let's create a couple of hosts...
HostPtr host1 = HostDataSourceUtils::initializeHost4("192.0.2.1", id);
HostPtr host2 = HostDataSourceUtils::initializeHost4("192.0.2.2", id);
HostPtr host3 = HostDataSourceUtils::initializeHost4("192.0.2.3", id);
HostPtr host4 = HostDataSourceUtils::initializeHost4("192.0.2.4", id);
// Set them in the same subnets.
SubnetID subnet4 = host1->getIPv4SubnetID();
host2->setIPv4SubnetID(subnet4);
host3->setIPv4SubnetID(subnet4);
host4->setIPv4SubnetID(subnet4);
SubnetID subnet6 = host1->getIPv6SubnetID();
host2->setIPv6SubnetID(subnet6);
host3->setIPv6SubnetID(subnet6);
host4->setIPv6SubnetID(subnet6);
// ... and add them to the data source.
ASSERT_NO_THROW(hdsptr_->add(host1));
ASSERT_NO_THROW(hdsptr_->add(host2));
ASSERT_NO_THROW(hdsptr_->add(host3));
ASSERT_NO_THROW(hdsptr_->add(host4));
// And then try to retrieve them back.
ConstHostCollection from_hds = hdsptr_->getAll4(subnet4);
// Make sure we got something back.
ASSERT_EQ(4, from_hds.size());
// Then let's check that what we got seems correct.
// There is no ORDER BY in Cassandra so skip it.
if (hdsptr_->getType() != "cql") {
HostDataSourceUtils::compareHosts(host1, from_hds[0]);
HostDataSourceUtils::compareHosts(host2, from_hds[1]);
HostDataSourceUtils::compareHosts(host3, from_hds[2]);
HostDataSourceUtils::compareHosts(host4, from_hds[3]);
}
}
void
GenericHostDataSourceTest::testGetAll6(const Host::IdentifierType& id) {
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
// Let's create a couple of hosts...
HostPtr host1 = HostDataSourceUtils::initializeHost6("2001:db8::1", id, false);
HostPtr host2 = HostDataSourceUtils::initializeHost6("2001:db8::2", id, false);
HostPtr host3 = HostDataSourceUtils::initializeHost6("2001:db8::3", id, false);
HostPtr host4 = HostDataSourceUtils::initializeHost6("2001:db8::4", id, false);
// Set them in the same subnets.
SubnetID subnet4 = host1->getIPv4SubnetID();
host2->setIPv4SubnetID(subnet4);
host3->setIPv4SubnetID(subnet4);
host4->setIPv4SubnetID(subnet4);
SubnetID subnet6 = host1->getIPv6SubnetID();
host2->setIPv6SubnetID(subnet6);
host3->setIPv6SubnetID(subnet6);
host4->setIPv6SubnetID(subnet6);
// ... and add them to the data source.
ASSERT_NO_THROW(hdsptr_->add(host1));
ASSERT_NO_THROW(hdsptr_->add(host2));
ASSERT_NO_THROW(hdsptr_->add(host3));
ASSERT_NO_THROW(hdsptr_->add(host4));
// And then try to retrieve them back.
ConstHostCollection from_hds = hdsptr_->getAll6(subnet6);
// Make sure we got something back.
ASSERT_EQ(4, from_hds.size());
// Then let's check that what we got seems correct.
// There is no ORDER BY in Cassandra so skip it.
if (hdsptr_->getType() != "cql") {
HostDataSourceUtils::compareHosts(host1, from_hds[0]);
HostDataSourceUtils::compareHosts(host2, from_hds[1]);
HostDataSourceUtils::compareHosts(host3, from_hds[2]);
HostDataSourceUtils::compareHosts(host4, from_hds[3]);
}
}
void void
GenericHostDataSourceTest::testGetByIPv4(const Host::IdentifierType& id) { GenericHostDataSourceTest::testGetByIPv4(const Host::IdentifierType& id) {
// Make sure we have a pointer to the host data source. // Make sure we have a pointer to the host data source.
@@ -1024,8 +1110,8 @@ void GenericHostDataSourceTest::testOptionsReservations4(const bool formatted,
// getAll4(subnet_id) // getAll4(subnet_id)
ConstHostCollection hosts_by_subnet = hdsptr_->getAll4(subnet_id); ConstHostCollection hosts_by_subnet = hdsptr_->getAll4(subnet_id);
// Not yet implemented. ASSERT_EQ(1, hosts_by_subnet.size());
EXPECT_EQ(0, hosts_by_subnet.size()); ASSERT_NO_FATAL_FAILURE(HostDataSourceUtils::compareHosts(host, *hosts_by_subnet.begin()));
// getAll4(address) // getAll4(address)
ConstHostCollection hosts_by_addr = ConstHostCollection hosts_by_addr =
@@ -1079,8 +1165,8 @@ GenericHostDataSourceTest::testOptionsReservations46(const bool formatted) {
// getAll6(subnet_id) // getAll6(subnet_id)
ConstHostCollection hosts_by_subnet = hdsptr_->getAll6(subnet_id); ConstHostCollection hosts_by_subnet = hdsptr_->getAll6(subnet_id);
// Not yet implemented. EXPECT_EQ(1, hosts_by_subnet.size());
EXPECT_EQ(0, hosts_by_subnet.size()); // Don't compare as getAll6() returns the v6 part only.
// getAll(identifier_type, identifier, identifier_size) // getAll(identifier_type, identifier, identifier_size)
ConstHostCollection hosts_by_id = ConstHostCollection hosts_by_id =

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // 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 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -178,6 +178,20 @@ public:
/// Uses gtest macros to report failures. /// Uses gtest macros to report failures.
void testMaxSubnetId6(); void testMaxSubnetId6();
/// @brief Test that Verifies that IPv4 host reservations in the
/// same subnet can be retrieved properly.
///
/// Uses gtest macros to report failures.
/// @param id Identifier type.
void testGetAll4(const Host::IdentifierType& id);
/// @brief Test that Verifies that IPv6 host reservations in the
/// same subnet can be retrieved properly.
///
/// Uses gtest macros to report failures.
/// @param id Identifier type.
void testGetAll6(const Host::IdentifierType& id);
/// @brief Test inserts several hosts with unique IPv4 address and /// @brief Test inserts several hosts with unique IPv4 address and
/// checks that they can be retrieved properly. /// checks that they can be retrieved properly.
/// ///

View File

@@ -23,13 +23,27 @@ MemHostDataSource::getAll(const Host::IdentifierType& /*identifier_type*/,
} }
ConstHostCollection ConstHostCollection
MemHostDataSource::getAll4(const SubnetID& /*subnet_id*/) const { MemHostDataSource::getAll4(const SubnetID& subnet_id) const {
return (ConstHostCollection()); ConstHostCollection hosts;
for (auto h = store_.begin(); h != store_.end(); ++h) {
// Keep it when subnet_id matchs.
if ((*h)->getIPv4SubnetID() == subnet_id) {
hosts.push_back(*h);
}
}
return (hosts);
} }
ConstHostCollection ConstHostCollection
MemHostDataSource::getAll6(const SubnetID& /*subnet_id*/) const { MemHostDataSource::getAll6(const SubnetID& subnet_id) const {
return (ConstHostCollection()); ConstHostCollection hosts;
for (auto h = store_.begin(); h != store_.end(); ++h) {
// Keep it when subnet_id matchs.
if ((*h)->getIPv6SubnetID() == subnet_id) {
hosts.push_back(*h);
}
}
return (hosts);
} }
ConstHostCollection ConstHostCollection
@@ -129,6 +143,7 @@ MemHostDataSource::get6(const SubnetID& subnet_id,
void void
MemHostDataSource::add(const HostPtr& host) { MemHostDataSource::add(const HostPtr& host) {
host->setHostId(++next_host_id_);
store_.push_back(host); store_.push_back(host);
} }

View File

@@ -48,16 +48,12 @@ public:
/// @brief Return all hosts in a DHCPv4 subnet. /// @brief Return all hosts in a DHCPv4 subnet.
/// ///
/// Currently not implemented.
///
/// @param subnet_id Subnet identifier. /// @param subnet_id Subnet identifier.
virtual ConstHostCollection virtual ConstHostCollection
getAll4(const SubnetID& subnet_id) const; getAll4(const SubnetID& subnet_id) const;
/// @brief Return all hosts in a DHCPv6 subnet. /// @brief Return all hosts in a DHCPv6 subnet.
/// ///
/// Currently not implemented.
///
/// @param subnet_id Subnet identifier. /// @param subnet_id Subnet identifier.
virtual ConstHostCollection virtual ConstHostCollection
getAll6(const SubnetID& subnet_id) const; getAll6(const SubnetID& subnet_id) const;
@@ -211,6 +207,9 @@ protected:
/// @brief Store /// @brief Store
std::vector<HostPtr> store_; std::vector<HostPtr> store_;
/// @brief Next host id
uint64_t next_host_id_;
}; };
/// Pointer to the Mem host data source. /// Pointer to the Mem host data source.