--- /dev/null
+// Copyright (C) 2018 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/.
+
+#include <yang/translator_option_def.h>
+#include <yang/adaptor.h>
+#include <sstream>
+
+using namespace std;
+using namespace isc::data;
+
+namespace isc {
+namespace yang {
+
+TranslatorOptionDef::TranslatorOptionDef(S_Session session,
+ const string& model)
+ : TranslatorBasic(session), model_(model) {
+}
+
+TranslatorOptionDef::~TranslatorOptionDef() {
+}
+
+ElementPtr
+TranslatorOptionDef::getOptionDef(const string& xpath) {
+ try {
+ if ((model_ == "kea-dhcp4") || (model_ == "kea-dhcp6")) {
+ return (getOptionDefKea(xpath));
+ }
+ } catch (const sysrepo_exception& ex) {
+ isc_throw(SysrepoError,
+ "sysrepo error getting option definition at '" << xpath
+ << "': " << ex.what());
+ }
+ isc_throw(NotImplemented,
+ "getOptionDef not implemented for the model: " << model_);
+}
+
+ElementPtr
+TranslatorOptionDef::getOptionDefKea(const string& xpath) {
+ ConstElementPtr code = getItem(xpath + "/code");
+ ConstElementPtr name = getItem(xpath + "/name");
+ ConstElementPtr type = getItem(xpath + "/type");
+ ConstElementPtr space = getItem(xpath + "/space");
+ if (!code || !name || !type || !space) {
+ return (ElementPtr());
+ }
+ ElementPtr result = Element::createMap();
+ result->set("code", code);
+ result->set("name", name);
+ result->set("type", type);
+ result->set("space", getItem(xpath + "/space"));
+ ConstElementPtr record = getItem(xpath + "/record-types");
+ if (record) {
+ result->set("record-types", record);
+ }
+ ConstElementPtr array = getItem(xpath + "/array");
+ if (array) {
+ result->set("array", array);
+ }
+ ConstElementPtr encapsulate = getItem(xpath + "/encapsulate");
+ if (encapsulate) {
+ result->set("encapsulate", encapsulate);
+ }
+ ConstElementPtr context = getItem(xpath + "/user-context");
+ if (context) {
+ result->set("user-context", Element::fromJSON(context->stringValue()));
+ }
+ return (result);
+}
+
+void
+TranslatorOptionDef::setOptionDef(const string& xpath, ConstElementPtr elem) {
+ try {
+ if ((model_ == "kea-dhcp4") || (model_ == "kea-dhcp6")) {
+ setOptionDefKea(xpath, elem);
+ } else {
+ isc_throw(NotImplemented,
+ "setOptionDef not implemented for the model: "
+ << model_);
+ }
+ } catch (const sysrepo_exception& ex) {
+ isc_throw(SysrepoError,
+ "sysrepo error setting option definition '" << elem->str()
+ << "' at '" << xpath << "': " << ex.what());
+ }
+}
+
+void
+TranslatorOptionDef::setOptionDefKea(const string& xpath,
+ ConstElementPtr elem) {
+ ConstElementPtr name = elem->get("name");
+ if (!name) {
+ isc_throw(BadValue, "option definition with name: " << elem->str());
+ }
+ setItem(xpath + "/name", name, SR_STRING_T);
+ ConstElementPtr type = elem->get("type");
+ if (!type) {
+ isc_throw(BadValue, "option definition with type: " << elem->str());
+ }
+ setItem(xpath + "/type", type, SR_STRING_T);
+ ConstElementPtr record = elem->get("record-types");
+ if (record) {
+ setItem(xpath + "/record-types", record, SR_STRING_T);
+ }
+ ConstElementPtr array = elem->get("array");
+ if (array) {
+ setItem(xpath + "/array", array, SR_BOOL_T);
+ }
+ ConstElementPtr encapsulate = elem->get("encapsulate");
+ if (encapsulate) {
+ setItem(xpath + "/encapsulate", encapsulate, SR_STRING_T);
+ }
+ ConstElementPtr context = Adaptor::getContext(elem);
+ if (context) {
+ setItem(xpath + "/user-context", Element::create(context->str()),
+ SR_STRING_T);
+ }
+}
+
+TranslatorOptionDefList::TranslatorOptionDefList(S_Session session,
+ const string& model)
+ : TranslatorBasic(session), TranslatorOptionDef(session, model),
+ model_(model) {
+}
+
+TranslatorOptionDefList::~TranslatorOptionDefList() {
+}
+
+ConstElementPtr
+TranslatorOptionDefList::getOptionDefList(const string& xpath) {
+ try {
+ if ((model_ == "kea-dhcp4") || (model_ == "kea-dhcp6")) {
+ return (getOptionDefListKea(xpath));
+ }
+ } catch (const sysrepo_exception& ex) {
+ isc_throw(SysrepoError,
+ "sysrepo error getting option definition list at '" << xpath
+ << "': " << ex.what());
+ }
+ isc_throw(NotImplemented,
+ "getOptionDefList not implemented for the model: " << model_);
+}
+
+ConstElementPtr
+TranslatorOptionDefList::getOptionDefListKea(const string& xpath) {
+ ElementPtr result = Element::createList();
+ S_Iter_Value iter = getIter(xpath + "/*");
+ if (!iter) {
+ return (ConstElementPtr());
+ }
+ for (;;) {
+ const string& def = getNext(iter);
+ if (def.empty()) {
+ break;
+ }
+ result->add(getOptionDef(def));
+ }
+ return (result);
+}
+
+void
+TranslatorOptionDefList::setOptionDefList(const string& xpath,
+ ConstElementPtr elem) {
+ try {
+ if ((model_ == "kea-dhcp4") || (model_ == "kea-dhcp6")) {
+ setOptionDefListKea(xpath, elem);
+ } else {
+ isc_throw(NotImplemented,
+ "setOptionDefList not implemented for the model: "
+ << model_);
+ }
+ } catch (const sysrepo_exception& ex) {
+ isc_throw(SysrepoError,
+ "sysrepo error setting option definition list '"
+ << elem->str() << "' at '" << xpath << "': " << ex.what());
+ }
+}
+
+void
+TranslatorOptionDefList::setOptionDefListKea(const string& xpath,
+ ConstElementPtr elem) {
+ for (size_t i = 0; i < elem->size(); ++i) {
+ ConstElementPtr def = elem->get(i);
+ if (!def->contains("code")) {
+ isc_throw(BadValue,
+ "option definition without code: " << def->str());
+ }
+ unsigned code = static_cast<unsigned>(def->get("code")->intValue());
+ if (!def->contains("space")) {
+ isc_throw(BadValue,
+ "option definition without space: " << def->str());
+ }
+ string space = def->get("space")->stringValue();
+ ostringstream keys;
+ keys << xpath << "/option-def[code='" << code
+ << "'][space='" << space << "']";
+ setOptionDef(keys.str(), def);
+ }
+}
+
+}; // end of namespace isc::yang
+}; // end of namespace isc
--- /dev/null
+// Copyright (C) 2018 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 ISC_TRANSLATOR_OPTION_DEF_H
+#define ISC_TRANSLATOR_OPTION_DEF_H 1
+
+#include <yang/translator.h>
+#include <list>
+
+namespace isc {
+namespace yang {
+
+// @brief Between Yang and JSON translator class for the option definition.
+class TranslatorOptionDef : virtual public TranslatorBasic {
+public:
+
+ /// @brief Constructor.
+ ///
+ /// @param session Sysrepo session.
+ /// @param model Model name.
+ TranslatorOptionDef(S_Session session, const std::string& model);
+
+ /// @brief Destructor.
+ virtual ~TranslatorOptionDef();
+
+ /// @brief Get and translate an option definition from Yang to JSON.
+ ///
+ /// JSON syntax for Kea DHCP with command channel is:
+ /// @code
+ /// {
+ /// "code": <code>,
+ /// "name": <name>,
+ /// "space": <space>,
+ /// "type": <type>,
+ /// "array": <array flag>,
+ /// "encapsulate": <encapsulated space>,
+ /// "record-types": <record types>,
+ /// "user-context": { <json map> },
+ /// "comment": "<comment>"
+ /// }
+ /// @endcode
+ ///
+ /// @param xpath The xpath of the option definition.
+ /// @return JSON representation of the option definition.
+ /// @throw SysrepoError when sysrepo raises an error.
+ isc::data::ElementPtr getOptionDef(const std::string& xpath);
+
+ /// @brief Translate and set option definition from JSON to Yang.
+ ///
+ /// @param xpath The xpath of the option definition..
+ /// @param elem The JSON element.
+ void setOptionDef(const std::string& xpath,
+ isc::data::ConstElementPtr elem);
+
+protected:
+ /// @brief getOptionDef JSON for kea-dhcp[46].
+ ///
+ /// @param xpath The xpath of the option definition.
+ /// @return JSON representation of the option definition.
+ /// @throw SysrepoError when sysrepo raises an error.
+ isc::data::ElementPtr getOptionDefKea(const std::string& xpath);
+
+ /// @brief setOptionDef for kea-dhcp[46].
+ ///
+ /// Yang syntax for kea-dhcp[46] with code and space as keys is:
+ /// @code
+ /// +--rw name string
+ /// +--rw code uint8 / uint16
+ /// +--rw type string
+ /// +--rw record-types? string
+ /// +--rw space string
+ /// +--rw encapsulate? string
+ /// +--rw array? boolean
+ /// +--rw user-context? string
+ /// @endcode
+ ///
+ /// @param xpath The xpath of the option definition.
+ /// @param elem The JSON element.
+ void setOptionDefKea(const std::string& xpath,
+ isc::data::ConstElementPtr elem);
+
+ /// @brief The model.
+ std::string model_;
+};
+
+// @brief Between Yang and JSON translator class for option definition list.
+class TranslatorOptionDefList : virtual public TranslatorOptionDef {
+public:
+
+ /// @brief Constructor.
+ ///
+ /// @param session Sysrepo session.
+ /// @param model Model name.
+ TranslatorOptionDefList(S_Session session, const std::string& model);
+
+ /// @brief Destructor.
+ virtual ~TranslatorOptionDefList();
+
+ /// @brief Get and translate option definition list from Yang to JSON.
+ ///
+ /// @param xpath The xpath of the option definition list.
+ /// @throw SysrepoError when sysrepo raises an error.
+ isc::data::ConstElementPtr getOptionDefList(const std::string& xpath);
+
+ /// @brief Translate and set option definition list from JSON to Yang.
+ ///
+ /// @param xpath The xpath of the option definition list.
+ /// @param elem The JSON element.
+ void setOptionDefList(const std::string& xpath,
+ isc::data::ConstElementPtr elem);
+
+protected:
+ /// @brief getOptionDefList for kea-dhcp[46].
+ ///
+ /// @param xpath The xpath of the option definition list.
+ /// @throw SysrepoError when sysrepo raises an error.
+ isc::data::ConstElementPtr getOptionDefListKea(const std::string& xpath);
+
+ /// @brief setOptionDefList for kea-dhcp[46].
+ ///
+ /// Yang syntax is a option-def list keyed by code and space.
+ ///
+ /// @param xpath The xpath of the option definition list.
+ /// @param elem The JSON element.
+ void setOptionDefListKea(const std::string& xpath,
+ isc::data::ConstElementPtr elem);
+
+ /// @brief The model.
+ std::string model_;
+};
+
+}; // end of namespace isc::yang
+}; // end of namespace isc
+
+#endif // ISC_TRANSLATOR_OPTION_DEF_H