Commit da9288ba authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[3560] Added methods to add classes to the Host object.

parent e2850e90
......@@ -13,6 +13,7 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <dhcpsrv/host.h>
#include <util/strutil.h>
#include <exceptions/exceptions.h>
namespace isc {
......@@ -34,10 +35,13 @@ Host::Host(const uint8_t* identifier, const size_t identifier_len,
const IdentifierType& identifier_type,
const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
const asiolink::IOAddress& ipv4_reservation,
const std::string& hostname)
const std::string& hostname,
const std::string& dhcp4_client_classes,
const std::string& dhcp6_client_classes)
: hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id),
ipv6_subnet_id_(ipv6_subnet_id), ipv4_reservation_(ipv4_reservation),
hostname_(hostname), dhcp4_client_classes_(), dhcp6_client_classes_() {
hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
dhcp6_client_classes_(dhcp6_client_classes) {
// Initialize HWAddr or DUID
setIdentifier(identifier, identifier_len, identifier_type);
......@@ -46,10 +50,13 @@ Host::Host(const uint8_t* identifier, const size_t identifier_len,
Host::Host(const std::string& identifier, const std::string& identifier_name,
const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
const asiolink::IOAddress& ipv4_reservation,
const std::string& hostname)
const std::string& hostname,
const std::string& dhcp4_client_classes,
const std::string& dhcp6_client_classes)
: hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id),
ipv6_subnet_id_(ipv6_subnet_id), ipv4_reservation_(ipv4_reservation),
hostname_(hostname), dhcp4_client_classes_(), dhcp6_client_classes_() {
hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
dhcp6_client_classes_(dhcp6_client_classes) {
// Initialize HWAddr or DUID
setIdentifier(identifier, identifier_name);
......@@ -99,6 +106,14 @@ Host::getIPv6Reservations(const IPv6Resrv::Type& type) const {
return (ipv6_reservations_.equal_range(type));
}
void
Host::addClientClassInternal(ClientClasses& classes,
const std::string& class_name) {
std::string trimmed = util::str::trim(class_name);
if (!class_name.empty()) {
classes.insert(ClientClass(class_name));
}
}
} // end of namespace isc::dhcp
} // end of namespace isc
......@@ -178,6 +178,10 @@ public:
/// this address is set to 0, there is no reservation.
/// @param hostname Hostname to be allocated to both DHCPv4 and DHCPv6
/// clients. This is empty string if hostname is not allocated.
/// @param dhcp4_client_classes A string holding DHCPv4 client class names
/// separated by commas. The names get trimmed by this constructor.
/// @param dhcp6_client_classes A string holding DHCPv6 client class names
/// separated by commas. The names get trimmed by this constructor.
///
/// @throw BadValue if the provided values are invalid. In particular,
/// if the identifier is invalid.
......@@ -185,7 +189,9 @@ public:
const IdentifierType& identifier_type,
const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
const asiolink::IOAddress& ipv4_reservation,
const std::string& hostname = "");
const std::string& hostname = "",
const std::string& dhcp4_client_classes = "",
const std::string& dhcp6_client_classes = "");
/// @brief Constructor.
///
......@@ -206,13 +212,19 @@ public:
/// this address is set to 0, there is no reservation.
/// @param hostname Hostname to be allocated to both DHCPv4 and DHCPv6
/// clients. This is empty string if hostname is not allocated.
/// @param dhcp4_client_classes A string holding DHCPv4 client class names
/// separated by commas. The names get trimmed by this constructor.
/// @param dhcp6_client_classes A string holding DHCPv6 client class names
/// separated by commas. The names get trimmed by this constructor.
///
/// @throw BadValue if the provided values are invalid. In particular,
/// if the identifier is invalid.
Host(const std::string& identifier, const std::string& identifier_name,
const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
const asiolink::IOAddress& ipv4_reservation,
const std::string& hostname = "");
const std::string& hostname = "",
const std::string& dhcp4_client_classes = "",
const std::string& dhcp6_client_classes = "");
/// @brief Replaces currently used identifier with a new identifier.
///
......@@ -325,11 +337,25 @@ public:
return (hostname_);
}
/// @brief Adds new client class for DHCPv4.
///
/// @param class_name Class name.
void addClientClass4(const std::string& class_name) {
addClientClassInternal(dhcp4_client_classes_, class_name);
}
/// @brief Returns classes which DHCPv4 client is associated with.
const ClientClasses& getClientClasses4() const {
return (dhcp4_client_classes_);
}
/// @brief Adds new client class for DHCPv6.
///
/// @param class_name Class name.
void addClientClass6(const std::string& class_name) {
addClientClassInternal(dhcp6_client_classes_, class_name);
}
/// @brief Returns classes which DHCPv6 client is associated with.
const ClientClasses& getClientClasses6() const {
return (dhcp6_client_classes_);
......@@ -337,6 +363,19 @@ public:
private:
/// @brief Adds new client class for DHCPv4 or DHCPv6.
///
/// This method is called internally by the @c addClientClass4 and
/// @c addClientClass6 functions. It adds the class of the specified name
/// to the supplied class set. The class names are trimmed before they are
/// added. Empty class names are ignored.
///
/// @param [out] classes Set of classes to which the new class should be
/// inserted.
/// @param class_name Class name.
void addClientClassInternal(ClientClasses& classes,
const std::string& class_name);
/// @brief Pointer to the hardware address associated with the reservations
/// for the host.
HWAddrPtr hw_address_;
......
......@@ -146,12 +146,6 @@ TEST(HostTest, createFromDUIDString) {
isc::BadValue);
// Empty DUID is also not allowed.
try {
Host("", "duid", SubnetID(1), SubnetID(2),
IOAddress("192.0.2.3"), "somehost.example.org");
} catch (const std::exception& ex) {
std::cout << ex.what() << std::endl;
}
EXPECT_THROW(Host("", "duid", SubnetID(1), SubnetID(2),
IOAddress("192.0.2.3"), "somehost.example.org"),
isc::BadValue);
......@@ -362,4 +356,72 @@ TEST(HostTest, setValues) {
EXPECT_EQ("10.0.0.1", host->getIPv4Reservation().toText());
}
// Test that Host constructors initialize client classes from string.
TEST(HostTest, clientClassesFromConstructor) {
boost::scoped_ptr<Host> host;
// Prepare the hardware address in binary format.
const uint8_t hwaddr_data[] = {
0xaa, 0xab, 0xca, 0xda, 0xbb, 0xee
};
// Try the "from binary" constructor.
ASSERT_NO_THROW(host.reset(new Host(hwaddr_data,
sizeof(hwaddr_data),
Host::IDENT_HWADDR,
SubnetID(1), SubnetID(2),
IOAddress("192.0.2.3"),
"somehost.example.org",
"alpha, , beta",
"gamma")));
EXPECT_TRUE(host->getClientClasses4().contains("alpha"));
EXPECT_TRUE(host->getClientClasses4().contains("beta"));
EXPECT_FALSE(host->getClientClasses4().contains("gamma"));
EXPECT_TRUE(host->getClientClasses6().contains("gamma"));
EXPECT_FALSE(host->getClientClasses6().contains("alpha"));
EXPECT_FALSE(host->getClientClasses6().contains("beta"));
// Try the "from string" constructor.
ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address",
SubnetID(1), SubnetID(2),
IOAddress("192.0.2.3"),
"somehost.example.org",
"alpha, beta, gamma",
"beta, gamma")));
EXPECT_TRUE(host->getClientClasses4().contains("alpha"));
EXPECT_TRUE(host->getClientClasses4().contains("beta"));
EXPECT_TRUE(host->getClientClasses4().contains("gamma"));
EXPECT_FALSE(host->getClientClasses6().contains("alpha"));
EXPECT_TRUE(host->getClientClasses6().contains("beta"));
EXPECT_TRUE(host->getClientClasses6().contains("gamma"));
}
// Test that new client classes can be added for the Host.
TEST(HostTest, addClientClasses) {
boost::scoped_ptr<Host> host;
ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address",
SubnetID(1), SubnetID(2),
IOAddress("192.0.2.3"))));
EXPECT_FALSE(host->getClientClasses4().contains("foo"));
EXPECT_FALSE(host->getClientClasses6().contains("foo"));
EXPECT_FALSE(host->getClientClasses4().contains("bar"));
EXPECT_FALSE(host->getClientClasses6().contains("bar"));
host->addClientClass4("foo");
host->addClientClass6("bar");
EXPECT_TRUE(host->getClientClasses4().contains("foo"));
EXPECT_FALSE(host->getClientClasses6().contains("foo"));
EXPECT_FALSE(host->getClientClasses4().contains("bar"));
EXPECT_TRUE(host->getClientClasses6().contains("bar"));
host->addClientClass4("bar");
host->addClientClass6("foo");
EXPECT_TRUE(host->getClientClasses4().contains("foo"));
EXPECT_TRUE(host->getClientClasses6().contains("foo"));
EXPECT_TRUE(host->getClientClasses4().contains("bar"));
EXPECT_TRUE(host->getClientClasses6().contains("bar"));
}
} // end of anonymous namespace
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment