return (s.str());
}
-isc::dhcp::ParserPtr
-CtrlAgentCfgMgr::createConfigParser(const std::string& /*element_id*/,
- const isc::data::Element::Position& /*pos*/) {
- isc_throw(NotImplemented, "We don't use parser pointers anymore");
-}
-
DCfgContextBasePtr
CtrlAgentCfgMgr::createNewContext() {
return (DCfgContextBasePtr(new CtrlAgentCfgContext()));
virtual isc::data::ConstElementPtr
parse(isc::data::ConstElementPtr config, bool check_only);
- /// @brief This is no longer used.
- ///
- /// @throw NotImplemented
- /// @return nothing, always throws
- virtual isc::dhcp::ParserPtr
- createConfigParser(const std::string&,
- const isc::data::Element::Position& pos);
-
/// @brief Creates a new, blank CtrlAgentCfgContext context.
///
///
#include <dhcpsrv/triplet.h>
#include <dhcpsrv/parsers/client_class_def_parser.h>
#include <dhcpsrv/parsers/dbaccess_parser.h>
-#include <dhcpsrv/parsers/dhcp_config_parser.h>
#include <dhcpsrv/parsers/dhcp_parsers.h>
#include <dhcpsrv/parsers/duid_config_parser.h>
#include <dhcpsrv/parsers/expiration_config_parser.h>
namespace {
-// Pointers to various parser objects.
-typedef boost::shared_ptr<BooleanParser> BooleanParserPtr;
-typedef boost::shared_ptr<StringParser> StringParserPtr;
-typedef boost::shared_ptr<Uint32Parser> Uint32ParserPtr;
-
/// @brief Parser for IPv6 pool definitions.
///
/// This is the IPv6 derivation of the PoolParser class and handles pool
# Configuration parsers
libkea_dhcpsrv_la_SOURCES += parsers/client_class_def_parser.cc
libkea_dhcpsrv_la_SOURCES += parsers/client_class_def_parser.h
-libkea_dhcpsrv_la_SOURCES += parsers/dhcp_config_parser.h
libkea_dhcpsrv_la_SOURCES += parsers/dbaccess_parser.cc
libkea_dhcpsrv_la_SOURCES += parsers/dbaccess_parser.h
libkea_dhcpsrv_la_SOURCES += parsers/dhcp_parsers.cc
+++ /dev/null
-// Copyright (C) 2013-2015,2017 Internet Systems Consortium, Inc. ("ISC")
-//
-// 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
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef DHCP_CONFIG_PARSER_H
-#define DHCP_CONFIG_PARSER_H
-
-#include <exceptions/exceptions.h>
-#include <cc/data.h>
-#include <cc/dhcp_config_error.h>
-#include <stdint.h>
-#include <string>
-#include <map>
-
-namespace isc {
-namespace dhcp {
-
-/// @brief Forward declaration to DhcpConfigParser class.
-///
-/// It is only needed here to define types that are
-/// based on this class before the class definition.
-class DhcpConfigParser;
-
-/// @brief a pointer to configuration parser
-typedef boost::shared_ptr<DhcpConfigParser> ParserPtr;
-
-/// @brief Collection of parsers.
-///
-/// This container is used to store pointer to parsers for a given scope.
-typedef std::vector<ParserPtr> ParserCollection;
-
-/// @brief Combination of parameter name and configuration contents
-typedef std::pair<std::string, isc::data::ConstElementPtr> ConfigPair;
-
-/// @brief Base abstract class for all DHCP parsers
-///
-/// Each instance of a class derived from this class parses one specific config
-/// element. Sometimes elements are simple (e.g. a string) and sometimes quite
-/// complex (e.g. a subnet). In such case, it is likely that a parser will
-/// spawn child parsers to parse child elements in the configuration.
-class DhcpConfigParser {
- ///
- /// @name Constructors and Destructor
- ///
- /// Note: The copy constructor and the assignment operator are
- /// intentionally defined as private to make it explicit that this is a
- /// pure base class.
- //@{
-private:
-
- // Private constructor and assignment operator assures that nobody
- // will be able to copy or assign a parser. There are no defined
- // bodies for them.
- DhcpConfigParser(const DhcpConfigParser& source);
- DhcpConfigParser& operator=(const DhcpConfigParser& source);
-protected:
- /// @brief The default constructor.
- ///
- /// This is intentionally defined as @c protected as this base class should
- /// never be instantiated (except as part of a derived class).
- DhcpConfigParser() {}
-public:
- /// The destructor.
- virtual ~DhcpConfigParser() {}
- //@}
-
- /// @brief Prepare configuration value.
- ///
- /// This method parses the "value part" of the configuration identifier
- /// that corresponds to this derived class and prepares a new value to
- /// apply to the server.
- ///
- /// This method must validate the given value both in terms of syntax
- /// and semantics of the configuration, so that the server will be
- /// validly configured at the time of @c commit(). Note: the given
- /// configuration value is normally syntactically validated, but the
- /// @c build() implementation must also expect invalid input. If it
- /// detects an error it may throw an exception of a derived class
- /// of @c isc::Exception.
- ///
- /// Preparing a configuration value will often require resource
- /// allocation. If it fails, it may throw a corresponding standard
- /// exception.
- ///
- /// This method is not expected to be called more than once in the
- /// life of the object. Although multiple calls are not prohibited
- /// by the interface, the behavior is undefined.
- ///
- /// @param config_value The configuration value for the identifier
- /// corresponding to the derived class.
- virtual void build(isc::data::ConstElementPtr config_value) = 0;
-
- /// @brief Apply the prepared configuration value to the server.
- ///
- /// This method is expected to be exception free, and, as a consequence,
- /// it should normally not involve resource allocation.
- /// Typically it would simply perform exception free assignment or swap
- /// operation on the value prepared in @c build().
- /// In some cases, however, it may be very difficult to meet this
- /// condition in a realistic way, while the failure case should really
- /// be very rare. In such a case it may throw, and, if the parser is
- /// called via @c configureDhcp4Server(), the caller will convert the
- /// exception as a fatal error.
- ///
- /// This method is expected to be called after @c build(), and only once.
- /// The result is undefined otherwise.
- virtual void commit() = 0;
-};
-
-}; // end of isc::dhcp namespace
-}; // end of isc namespace
-
-#endif // DHCP_CONFIG_PARSER_H
-
namespace isc {
namespace dhcp {
-// **************************** DebugParser *************************
-
-DebugParser::DebugParser(const std::string& param_name)
- :param_name_(param_name) {
-}
-
-void
-DebugParser::build(ConstElementPtr new_config) {
- value_ = new_config;
- std::cout << "Build for token: [" << param_name_ << "] = ["
- << value_->str() << "]" << std::endl;
-}
-
-void
-DebugParser::commit() {
- // Debug message. The whole DebugParser class is used only for parser
- // debugging, and is not used in production code. It is very convenient
- // to keep it around. Please do not turn this cout into logger calls.
- std::cout << "Commit for token: [" << param_name_ << "] = ["
- << value_->str() << "]" << std::endl;
-}
-
-// **************************** BooleanParser *************************
-
-template<> void ValueParser<bool>::build(isc::data::ConstElementPtr value) {
- // Invoke common code for all specializations of build().
- buildCommon(value);
- // The Config Manager checks if user specified a
- // valid value for a boolean parameter: true or false.
- // We should have a boolean Element, use value directly
- try {
- value_ = value->boolValue();
- } catch (const isc::data::TypeError &) {
- isc_throw(BadValue, " Wrong value type for " << param_name_
- << " : build called with a non-boolean element "
- << "(" << value->getPosition() << ").");
- }
-}
-
-// **************************** Uin32Parser *************************
-
-template<> void ValueParser<uint32_t>::build(ConstElementPtr value) {
- // Invoke common code for all specializations of build().
- buildCommon(value);
-
- int64_t check;
- string x = value->str();
- try {
- check = boost::lexical_cast<int64_t>(x);
- } catch (const boost::bad_lexical_cast &) {
- isc_throw(BadValue, "Failed to parse value " << value->str()
- << " as unsigned 32-bit integer "
- "(" << value->getPosition() << ").");
- }
- if (check > std::numeric_limits<uint32_t>::max()) {
- isc_throw(BadValue, "Value " << value->str() << " is too large"
- " for unsigned 32-bit integer "
- "(" << value->getPosition() << ").");
- }
- if (check < 0) {
- isc_throw(BadValue, "Value " << value->str() << " is negative."
- << " Only 0 or larger are allowed for unsigned 32-bit integer "
- "(" << value->getPosition() << ").");
- }
-
- // value is small enough to fit
- value_ = static_cast<uint32_t>(check);
-}
-
-// **************************** StringParser *************************
-
-template <> void ValueParser<std::string>::build(ConstElementPtr value) {
- // Invoke common code for all specializations of build().
- buildCommon(value);
-
- // For strings we need to use stringValue() rather than str().
- // str() returns fully escaped special characters, so
- // single backslash would be misrepresented as "\\".
- if (value->getType() == Element::string) {
- value_ = value->stringValue();
- } else {
- value_ = value->str();
- }
- boost::erase_all(value_, "\"");
-}
-
// ******************** MACSourcesListConfigParser *************************
void
#include <dhcpsrv/cfg_option_def.h>
#include <dhcpsrv/cfg_mac_source.h>
#include <dhcpsrv/srv_config.h>
-#include <dhcpsrv/parsers/dhcp_config_parser.h>
#include <cc/simple_parser.h>
#include <exceptions/exceptions.h>
#include <util/optional_value.h>
};
+/// @brief Combination of parameter name and configuration contents
+typedef std::pair<std::string, isc::data::ConstElementPtr> ConfigPair;
/// @brief a collection of elements that store uint32 values
typedef ValueStorage<uint32_t> Uint32Storage;
typedef ValueStorage<bool> BooleanStorage;
typedef boost::shared_ptr<BooleanStorage> BooleanStoragePtr;
-/// @brief Simple data-type parser template class
-///
-/// This is the template class for simple data-type parsers. It supports
-/// parsing a configuration parameter with specific data-type for its
-/// possible values. It provides a common constructor, commit, and templated
-/// data storage. The "build" method implementation must be provided by a
-/// declaring type.
-/// @param ValueType is the data type of the configuration parameter value
-/// the parser should handle.
-template<typename ValueType>
-class ValueParser : public DhcpConfigParser {
-public:
-
- /// @brief Constructor.
- ///
- /// @param param_name name of the parameter.
- /// @param storage is a pointer to the storage container where the parsed
- /// value be stored upon commit.
- /// @throw isc::dhcp::DhcpConfigError if a provided parameter's
- /// name is empty.
- /// @throw isc::dhcp::DhcpConfigError if storage is null.
- ValueParser(const std::string& param_name,
- boost::shared_ptr<ValueStorage<ValueType> > storage)
- : storage_(storage), param_name_(param_name), value_(), pos_() {
- // Empty parameter name is invalid.
- if (param_name_.empty()) {
- isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
- << "empty parameter name provided");
- }
-
- // Null storage is invalid.
- if (!storage_) {
- isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
- << "storage may not be NULL");
- }
- }
-
- /// @brief Parse a given element into a value of type @c ValueType
- ///
- /// @param value a value to be parsed.
- ///
- /// @throw isc::BadValue Typically the implementing type will throw
- /// a BadValue exception when given an invalid Element to parse.
- void build(isc::data::ConstElementPtr value);
-
- /// @brief Put a parsed value to the storage.
- void commit() {
- // If a given parameter already exists in the storage we override
- // its value. If it doesn't we insert a new element.
- storage_->setParam(param_name_, value_, pos_);
- }
-
-private:
-
- /// @brief Performs operations common for all specializations of the
- /// @c build function.
- ///
- /// This method should be called by all specializations of the @c build
- /// method.
- ///
- /// @param value a value being parsed.
- void buildCommon(isc::data::ConstElementPtr value) {
- // Remember position of the data element.
- pos_ = value->getPosition();
- }
-
- /// Pointer to the storage where committed value is stored.
- boost::shared_ptr<ValueStorage<ValueType> > storage_;
-
- /// Name of the parameter which value is parsed with this parser.
- std::string param_name_;
-
- /// Parsed value.
- ValueType value_;
-
- data::Element::Position pos_;
-};
-
-/// @brief typedefs for simple data type parsers
-typedef ValueParser<bool> BooleanParser;
-typedef ValueParser<uint32_t> Uint32Parser;
-typedef ValueParser<std::string> StringParser;
-
-/// @brief a dummy configuration parser
-///
-/// It is a debugging parser. It does not configure anything,
-/// will accept any configuration and will just print it out
-/// on commit. Useful for debugging existing configurations and
-/// adding new ones.
-class DebugParser : public DhcpConfigParser {
-public:
-
- /// @brief Constructor
- ///
- /// See @ref DhcpConfigParser class for details.
- ///
- /// @param param_name name of the parsed parameter
- DebugParser(const std::string& param_name);
-
- /// @brief builds parameter value
- ///
- /// See @ref DhcpConfigParser class for details.
- ///
- /// @param new_config pointer to the new configuration
- virtual void build(isc::data::ConstElementPtr new_config);
-
- /// @brief pretends to apply the configuration
- ///
- /// This is a method required by base class. It pretends to apply the
- /// configuration, but in fact it only prints the parameter out.
- ///
- /// See @ref DhcpConfigParser class for details.
- virtual void commit();
-
-private:
- /// name of the parsed parameter
- std::string param_name_;
-
- /// pointer to the actual value of the parameter
- isc::data::ConstElementPtr value_;
-
-};
-
/// @brief parser for MAC/hardware acquisition sources
///
/// This parser handles Dhcp6/mac-sources entry.
#include <cc/command_interpreter.h>
#include <dhcpsrv/lease_mgr_factory.h>
-#include <dhcpsrv/parsers/dhcp_config_parser.h>
#include <dhcpsrv/parsers/dbaccess_parser.h>
#include <dhcpsrv/testutils/mysql_schema.h>
#include <dhcpsrv/host_mgr.h>
}
};
-
-/// @brief Check BooleanParser basic functionality.
-///
-/// Verifies that the parser:
-/// 1. Does not allow empty for storage.
-/// 2. Rejects a non-boolean element.
-/// 3. Builds with a valid true value.
-/// 4. Bbuils with a valid false value.
-/// 5. Updates storage upon commit.
-TEST_F(DhcpParserTest, booleanParserTest) {
-
- const std::string name = "boolParm";
-
- // Verify that parser does not allow empty for storage.
- BooleanStoragePtr bs;
- EXPECT_THROW(BooleanParser(name, bs), isc::dhcp::DhcpConfigError);
-
- // Construct parser for testing.
- BooleanStoragePtr storage(new BooleanStorage());
- BooleanParser parser(name, storage);
-
- // Verify that parser with rejects a non-boolean element.
- ElementPtr wrong_element = Element::create("I am a string");
- EXPECT_THROW(parser.build(wrong_element), isc::BadValue);
-
- // Verify that parser will build with a valid true value.
- bool test_value = true;
- ElementPtr element = Element::create(test_value);
- ASSERT_NO_THROW(parser.build(element));
-
- // Verify that commit updates storage.
- bool actual_value = !test_value;
- parser.commit();
- EXPECT_NO_THROW((actual_value = storage->getParam(name)));
- EXPECT_EQ(test_value, actual_value);
-
- // Verify that parser will build with a valid false value.
- test_value = false;
- element->setValue(test_value);
- EXPECT_NO_THROW(parser.build(element));
-
- // Verify that commit updates storage.
- actual_value = !test_value;
- parser.commit();
- EXPECT_NO_THROW((actual_value = storage->getParam(name)));
- EXPECT_EQ(test_value, actual_value);
-}
-
-/// @brief Check StringParser basic functionality
-///
-/// Verifies that the parser:
-/// 1. Does not allow empty for storage.
-/// 2. Builds with a nont string value.
-/// 3. Builds with a string value.
-/// 4. Updates storage upon commit.
-TEST_F(DhcpParserTest, stringParserTest) {
-
- const std::string name = "strParm";
-
- // Verify that parser does not allow empty for storage.
- StringStoragePtr bs;
- EXPECT_THROW(StringParser(name, bs), isc::dhcp::DhcpConfigError);
-
- // Construct parser for testing.
- StringStoragePtr storage(new StringStorage());
- StringParser parser(name, storage);
-
- // Verify that parser with accepts a non-string element.
- ElementPtr element = Element::create(9999);
- EXPECT_NO_THROW(parser.build(element));
-
- // Verify that commit updates storage.
- parser.commit();
- std::string actual_value;
- EXPECT_NO_THROW((actual_value = storage->getParam(name)));
- EXPECT_EQ("9999", actual_value);
-
- // Verify that parser will build with a string value.
- const std::string test_value = "test value";
- element = Element::create(test_value);
- ASSERT_NO_THROW(parser.build(element));
-
- // Verify that commit updates storage.
- parser.commit();
- EXPECT_NO_THROW((actual_value = storage->getParam(name)));
- EXPECT_EQ(test_value, actual_value);
-
- // Verify that parser with accepts a boolean true element.
- element = Element::create(true);
- EXPECT_NO_THROW(parser.build(element));
-
- // Verify that commit updates storage.
- parser.commit();
- EXPECT_NO_THROW((actual_value = storage->getParam(name)));
- EXPECT_EQ("true", actual_value);
-
- // Verify that parser with accepts a boolean true element.
- element = Element::create(false);
- EXPECT_NO_THROW(parser.build(element));
-
- // Verify that commit updates storage.
- parser.commit();
- EXPECT_NO_THROW((actual_value = storage->getParam(name)));
- EXPECT_EQ("false", actual_value);
-}
-
-/// @brief Check Uint32Parser basic functionality
-///
-/// Verifies that the parser:
-/// 1. Does not allow empty for storage.
-/// 2. Rejects a non-integer element.
-/// 3. Rejects a negative value.
-/// 4. Rejects too large a value.
-/// 5. Builds with value of zero.
-/// 6. Builds with a value greater than zero.
-/// 7. Updates storage upon commit.
-TEST_F(DhcpParserTest, uint32ParserTest) {
-
- const std::string name = "intParm";
-
- // Verify that parser does not allow empty for storage.
- Uint32StoragePtr bs;
- EXPECT_THROW(Uint32Parser(name, bs), isc::dhcp::DhcpConfigError);
-
- // Construct parser for testing.
- Uint32StoragePtr storage(new Uint32Storage());
- Uint32Parser parser(name, storage);
-
- // Verify that parser with rejects a non-integer element.
- ElementPtr wrong_element = Element::create("I am a string");
- EXPECT_THROW(parser.build(wrong_element), isc::BadValue);
-
- // Verify that parser with rejects a negative value.
- ElementPtr int_element = Element::create(-1);
- EXPECT_THROW(parser.build(int_element), isc::BadValue);
-
- // Verify that parser with rejects too large a value provided we are on
- // 64-bit platform.
- if (sizeof(long) > sizeof(uint32_t)) {
- long max = (long)(std::numeric_limits<uint32_t>::max()) + 1;
- int_element->setValue(max);
- EXPECT_THROW(parser.build(int_element), isc::BadValue);
- }
-
- // Verify that parser will build with value of zero.
- int test_value = 0;
- int_element->setValue((long)test_value);
- ASSERT_NO_THROW(parser.build(int_element));
-
- // Verify that commit updates storage.
- parser.commit();
- uint32_t actual_value = 0;
- EXPECT_NO_THROW((actual_value = storage->getParam(name)));
- EXPECT_EQ(test_value, actual_value);
-
- // Verify that parser will build with a valid positive value.
- test_value = 77;
- int_element->setValue((long)test_value);
- ASSERT_NO_THROW(parser.build(int_element));
-
- // Verify that commit updates storage.
- parser.commit();
- EXPECT_NO_THROW((actual_value = storage->getParam(name)));
- EXPECT_EQ(test_value, actual_value);
-}
-
/// Verifies the code that parses mac sources and adds them to CfgMgr
TEST_F(DhcpParserTest, MacSources) {