2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 22:15:23 +00:00

[#3582] Extended option-data toElement

This commit is contained in:
Francis Dupont
2024-10-18 10:04:54 +02:00
committed by Tomek Mrugalski
parent f08c5d642b
commit 19a592b1f7
4 changed files with 87 additions and 5 deletions

View File

@@ -477,7 +477,13 @@ CfgOption::toElement() const {
}
ElementPtr
CfgOption::toElementWithMetadata(const bool include_metadata) const {
CfgOption::toElement(CfgOptionDefPtr cfg_option_def) const {
return (toElementWithMetadata(false, cfg_option_def));
}
ElementPtr
CfgOption::toElementWithMetadata(const bool include_metadata,
CfgOptionDefPtr cfg_option_def) const {
// option-data value is a list of maps
ElementPtr result = Element::createList();
// Iterate first on options using space names
@@ -495,7 +501,13 @@ CfgOption::toElementWithMetadata(const bool include_metadata) const {
uint16_t code = opt.option_->getType();
map->set("code", Element::create(code));
// Set the name (always for standard options else when asked for)
OptionDefinitionPtr def = LibDHCP::getOptionDef(name, code);
OptionDefinitionPtr def;
if (cfg_option_def) {
def = cfg_option_def->get(name, code);
}
if (!def) {
def = LibDHCP::getOptionDef(name, code);
}
if (!def) {
def = LibDHCP::getRuntimeOptionDef(name, code);
}

View File

@@ -747,15 +747,23 @@ public:
/// @return a pointer to unparsed configuration
virtual isc::data::ElementPtr toElement() const;
/// @brief Unparse a configuration object
///
/// @param cfg_option_def config option definitions
/// @return a pointer to unparsed configuration
virtual isc::data::ElementPtr toElement(CfgOptionDefPtr cfg_option_def) const;
/// @brief Unparse a configuration object with optionally including
/// the metadata.
///
/// @param include_metadata boolean value indicating if the metadata
/// should be included (if true) or not (if false).
/// @param cfg_option_def config option definitions (optional).
///
/// @return A pointer to the unparsed configuration.
isc::data::ElementPtr
toElementWithMetadata(const bool include_metadata) const;
toElementWithMetadata(const bool include_metadata,
CfgOptionDefPtr cfg_option_def = CfgOptionDefPtr()) const;
private:

View File

@@ -239,9 +239,11 @@ ClientClassDef::toElement() const {
// Set option-def (used only by DHCPv4)
if (cfg_option_def_ && (family == AF_INET)) {
result->set("option-def", cfg_option_def_->toElement());
result->set("option-data", cfg_option_->toElement(cfg_option_def_));
} else {
// Set option-data
result->set("option-data", cfg_option_->toElement());
}
// Set option-data
result->set("option-data", cfg_option_->toElement());
if (family == AF_INET) {
// V4 only

View File

@@ -1472,6 +1472,66 @@ TEST_F(ClientClassDefParserTest, option43Def) {
EXPECT_EQ(0, std::memcmp(expected, &opt->getData()[0], 4));
}
// Test verifies option-def and option-data is correctly unparsed
// option 43 as a string.
TEST_F(ClientClassDefParserTest, option43DefString) {
std::string cfg_text =
"{ \n"
" \"name\": \"aruba\", \n"
" \"option-def\": [ \n"
" { \n"
" \"name\": \"vendor-encapsulated-options\", \n"
" \"code\": 43, \n"
" \"space\": \"dhcp4\", \n"
" \"type\": \"string\" \n"
" } \n"
" ], \n"
" \"option-data\": [ \n"
" { \n"
" \"name\": \"vendor-encapsulated-options\", \n"
" \"csv-format\": true, \n"
" \"data\": \"192.168.0.150\" \n"
" } \n"
" ] \n"
"} \n";
ClientClassDefPtr cclass;
ASSERT_NO_THROW(cclass = parseClientClassDef(cfg_text, AF_INET));
// We should find our class.
ASSERT_TRUE(cclass);
// And the option definition.
CfgOptionDefPtr cfg_def = cclass->getCfgOptionDef();
ASSERT_TRUE(cfg_def);
EXPECT_TRUE(cfg_def->get(DHCP4_OPTION_SPACE, 43));
// Verify the option data.
OptionDescriptor od = cclass->getCfgOption()->get(DHCP4_OPTION_SPACE, 43);
ASSERT_TRUE(od.option_);
EXPECT_EQ(43, od.option_->getType());
OptionStringPtr opstr = boost::dynamic_pointer_cast<OptionString>(od.option_);
ASSERT_TRUE(opstr);
EXPECT_EQ("192.168.0.150", opstr->getValue());
// Verify unparse.
auto const& unparsed = cclass->toElement();
ASSERT_TRUE(unparsed);
ASSERT_EQ(unparsed->getType(), Element::map);
auto const& option_data = unparsed->get("option-data");
ASSERT_TRUE(option_data);
ASSERT_EQ(option_data->getType(), Element::list);
ASSERT_EQ(1, option_data->size());
auto const& option = option_data->get(0);
ASSERT_TRUE(option);
ASSERT_EQ(option->getType(), Element::map);
auto const& data = option->get("data");
ASSERT_TRUE(data);
ASSERT_EQ(data->getType(), Element::string);
// Data entry must be "192.168.0.150", not "".
EXPECT_EQ("192.168.0.150", data->stringValue());
}
// Test verifies that it is possible to define next-server field and it
// is actually set in the class properly.
TEST_F(ClientClassDefParserTest, nextServer) {