return (vendor_options_.getItems(vendor_id));
}
+size_t
+CfgOption::del(const std::string& option_space, const uint16_t option_code) {
+ // Check for presence of options.
+ OptionContainerPtr options = getAll(option_space);
+ if (!options || options->empty()) {
+ // There are no options, so there is nothing to do.
+ return (0);
+ }
+
+ // If this is not top level option we may also need to delete the
+ // option instance from options encapsulating the particular option
+ // space.
+ if ((option_space != DHCP4_OPTION_SPACE) &&
+ (option_space != DHCP6_OPTION_SPACE)) {
+ // For each option space name iterate over the existing options.
+ auto option_space_names = getOptionSpaceNames();
+ for (auto option_space_from_list : option_space_names) {
+ // Get all options within the particular option space.
+ auto options_in_space = getAll(option_space_from_list);
+ for (auto option_it = options_in_space->begin();
+ option_it != options_in_space->end();
+ ++option_it) {
+
+ // Check if the option encapsulates our option space and
+ // it does, try to delete our option.
+ if (option_it->option_ &&
+ (option_it->option_->getEncapsulatedSpace() == option_space)) {
+ option_it->option_->delOption(option_code);
+ }
+ }
+ }
+ }
+
+ auto& idx = options->get<1>();
+ return (idx.erase(option_code));
+}
+
ElementPtr
CfgOption::toElement() const {
// option-data value is a list of maps
return (*od_itr);
}
- /// @brief Deletes option for the specified key and option code.
+ /// @brief Deletes option for the specified option space and option code.
///
- /// The key should be a string, in which case it specifies an option space
- /// name, or an uint32_t value, in which case it specifies a vendor
- /// identifier.
+ /// If the option is encapsulated within some non top level option space,
+ /// it is also deleted from all option instances encapsulating this
+ /// option space.
///
/// @param key Option space name or vendor identifier.
/// @param option_code Code of the option to be returned.
- /// @tparam Selector one of: @c std::string or @c uint32_t
///
/// @return Number of deleted options.
- template<typename Selector>
- size_t del(const Selector& key, const uint16_t option_code) {
- // Check for presence of options.
- OptionContainerPtr options = getAll(key);
- if (!options || options->empty()) {
- // There are no options, so there is nothing to do.
- return (0);
- }
-
- // Some options present, locate the one we are interested in.
- auto& idx = options->get<1>();
- return (idx.erase(option_code));
- }
+ size_t del(const std::string& key, const uint16_t option_code);
/// @brief Returns a list of configured option space names.
///
}
}
+// This test verifies that an option can be deleted from the configuration.
+TEST_F(CfgOptionTest, del) {
+ CfgOption cfg;
+
+ generateEncapsulatedOptions(cfg);
+
+ // Append options from "foo" and "bar" space as sub-options and options
+ // from "foo-subs" and "bar-subs" as sub-options of "foo" and "bar"
+ // options.
+ ASSERT_NO_THROW(cfg.encapsulate());
+
+ // The option with the code 5 should exist in the option space "foo".
+ ASSERT_TRUE(cfg.get("foo", 5).option_);
+
+ // Because we called "encapsulate", this option should have been
+ // propagated to the options encapsulating option space "foo".
+ for (uint16_t code = 1000; code < 1020; ++code) {
+ OptionDescriptor top_level_option(false);
+ ASSERT_NO_THROW(top_level_option = cfg.get(DHCP6_OPTION_SPACE, code));
+ // Make sure that the option with code 5 is there.
+ ASSERT_TRUE(top_level_option.option_);
+ ASSERT_TRUE(top_level_option.option_->getOption(5));
+ }
+
+ // Delete option with the code 5 and belonging to option space "foo".
+ uint64_t deleted_num;
+ ASSERT_NO_THROW(deleted_num = cfg.del("foo", 5));
+ EXPECT_EQ(1, deleted_num);
+
+ // The option should now be gone from options config.
+ EXPECT_FALSE(cfg.get("foo", 5).option_);
+
+ // Iterate over the options encapsulating "foo" option space. Make sure
+ // that the option with code 5 is no longer encapsulated by these options.
+ for (uint16_t code = 1000; code < 1020; ++code) {
+ OptionDescriptor top_level_option(false);
+ ASSERT_NO_THROW(top_level_option = cfg.get(DHCP6_OPTION_SPACE, code));
+ ASSERT_TRUE(top_level_option.option_);
+ EXPECT_FALSE(top_level_option.option_->getOption(5));
+ }
+}
+
// This test verifies that single option can be retrieved from the configuration
// using option code and option space.
TEST_F(CfgOptionTest, get) {