mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-03 23:45:27 +00:00
[#3582] Extended option-data toElement
This commit is contained in:
committed by
Tomek Mrugalski
parent
f08c5d642b
commit
19a592b1f7
@@ -477,7 +477,13 @@ CfgOption::toElement() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ElementPtr
|
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
|
// option-data value is a list of maps
|
||||||
ElementPtr result = Element::createList();
|
ElementPtr result = Element::createList();
|
||||||
// Iterate first on options using space names
|
// Iterate first on options using space names
|
||||||
@@ -495,7 +501,13 @@ CfgOption::toElementWithMetadata(const bool include_metadata) const {
|
|||||||
uint16_t code = opt.option_->getType();
|
uint16_t code = opt.option_->getType();
|
||||||
map->set("code", Element::create(code));
|
map->set("code", Element::create(code));
|
||||||
// Set the name (always for standard options else when asked for)
|
// 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) {
|
if (!def) {
|
||||||
def = LibDHCP::getRuntimeOptionDef(name, code);
|
def = LibDHCP::getRuntimeOptionDef(name, code);
|
||||||
}
|
}
|
||||||
|
@@ -747,15 +747,23 @@ public:
|
|||||||
/// @return a pointer to unparsed configuration
|
/// @return a pointer to unparsed configuration
|
||||||
virtual isc::data::ElementPtr toElement() const;
|
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
|
/// @brief Unparse a configuration object with optionally including
|
||||||
/// the metadata.
|
/// the metadata.
|
||||||
///
|
///
|
||||||
/// @param include_metadata boolean value indicating if the metadata
|
/// @param include_metadata boolean value indicating if the metadata
|
||||||
/// should be included (if true) or not (if false).
|
/// should be included (if true) or not (if false).
|
||||||
|
/// @param cfg_option_def config option definitions (optional).
|
||||||
///
|
///
|
||||||
/// @return A pointer to the unparsed configuration.
|
/// @return A pointer to the unparsed configuration.
|
||||||
isc::data::ElementPtr
|
isc::data::ElementPtr
|
||||||
toElementWithMetadata(const bool include_metadata) const;
|
toElementWithMetadata(const bool include_metadata,
|
||||||
|
CfgOptionDefPtr cfg_option_def = CfgOptionDefPtr()) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@@ -239,9 +239,11 @@ ClientClassDef::toElement() const {
|
|||||||
// Set option-def (used only by DHCPv4)
|
// Set option-def (used only by DHCPv4)
|
||||||
if (cfg_option_def_ && (family == AF_INET)) {
|
if (cfg_option_def_ && (family == AF_INET)) {
|
||||||
result->set("option-def", cfg_option_def_->toElement());
|
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) {
|
if (family == AF_INET) {
|
||||||
// V4 only
|
// V4 only
|
||||||
|
@@ -1472,6 +1472,66 @@ TEST_F(ClientClassDefParserTest, option43Def) {
|
|||||||
EXPECT_EQ(0, std::memcmp(expected, &opt->getData()[0], 4));
|
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
|
// Test verifies that it is possible to define next-server field and it
|
||||||
// is actually set in the class properly.
|
// is actually set in the class properly.
|
||||||
TEST_F(ClientClassDefParserTest, nextServer) {
|
TEST_F(ClientClassDefParserTest, nextServer) {
|
||||||
|
Reference in New Issue
Block a user