libkea_yang_la_SOURCES += translator_pd_pool.cc translator_pd_pool.h
libkea_yang_la_SOURCES += translator_host.cc translator_host.h
libkea_yang_la_SOURCES += translator_subnet.cc translator_subnet.h
+libkea_yang_la_SOURCES += translator_shared_network.cc
+libkea_yang_la_SOURCES += translator_shared_network.h
libkea_yang_la_SOURCES += yang_models.h
libkea_yang_la_LIBADD = $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
translator_option_def.h \
translator_pool.h \
translator_pd_pool.h \
+ translator_shared_network.h \
translator_subnet.h \
yang_models.h
run_unittests_SOURCES += translator_pd_pool_unittests.cc
run_unittests_SOURCES += translator_host_unittests.cc
run_unittests_SOURCES += translator_subnet_unittests.cc
+run_unittests_SOURCES += translator_shared_network_unittests.cc
run_unittests_SOURCES += run_unittests.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
--- /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 <config.h>
+
+#include <yang/translator_shared_network.h>
+#include <yang/yang_models.h>
+#include <yang/tests/sysrepo_setup.h>
+
+#include <gtest/gtest.h>
+
+using namespace std;
+using namespace isc;
+using namespace isc::data;
+using namespace isc::yang;
+using namespace isc::yang::test;
+
+namespace {
+
+/// @brief Translator name.
+extern char const shared_networks[] = "shared networks";
+
+/// @brief Test fixture class for @ref TranslatorSharedNetworks.
+class TranslatorSharedNetworksTest :
+ public GenericTranslatorTest<shared_networks, TranslatorSharedNetworks> {
+public:
+
+ /// Constructor.
+ TranslatorSharedNetworksTest() { }
+
+ /// Destructor (does nothing).
+ virtual ~TranslatorSharedNetworksTest() { }
+};
+
+// This test verifies that an empty shared network list can be properly
+// translated from YANG to JSON.
+TEST_F(TranslatorSharedNetworksTest, getEmpty) {
+ useModel(KEA_DHCP4_SERVER);
+
+ // Get the shared network list and check if it is empty.
+ const string& xpath = "/kea-dhcp4-server:config/shared-networks";
+ ConstElementPtr networks;
+ EXPECT_NO_THROW(networks = t_obj_->getSharedNetworks(xpath));
+ ASSERT_TRUE(networks);
+ ASSERT_EQ(Element::list, networks->getType());
+ EXPECT_EQ(0, networks->size());
+}
+
+// This test verifies that one shared network can be properly
+// translated from YANG to JSON.
+TEST_F(TranslatorSharedNetworksTest, get) {
+ useModel(KEA_DHCP6_SERVER);
+
+ // Create the subnet 2001:db8::/48 #111 in shared network foo.
+ const string& xpath = "/kea-dhcp6-server:config/shared-networks";
+ const string& xnetwork = xpath + "/shared-network[name='foo']";
+ const string& xsubnet = xnetwork + "/subnet6/subnet6[id='111']/subnet";
+ S_Val v_subnet(new Val("2001:db8::/48", SR_STRING_T));
+ EXPECT_NO_THROW(sess_->set_item(xsubnet.c_str(), v_subnet));
+
+ // Get the shared network.
+ ConstElementPtr network;
+ EXPECT_NO_THROW(network = t_obj_->getSharedNetwork(xnetwork));
+ ASSERT_TRUE(network);
+ ElementPtr subnet = Element::createMap();
+ subnet->set("id", Element::create(111));
+ subnet->set("subnet", Element::create(string("2001:db8::/48")));
+ ElementPtr subnets = Element::createList();
+ subnets->add(subnet);
+ ElementPtr expected = Element::createMap();
+ expected->set("name", Element::create(string("foo")));
+ expected->set("subnet6", subnets);
+ EXPECT_TRUE(expected->equals(*network));
+
+ // Get the shared network list and check if the shared network is in it.
+ ConstElementPtr networks;
+ EXPECT_NO_THROW(networks = t_obj_->getSharedNetworks(xpath));
+ ASSERT_TRUE(networks);
+ ASSERT_EQ(Element::list, networks->getType());
+ ASSERT_EQ(1, networks->size());
+ EXPECT_TRUE(network->equals(*networks->get(0)));
+}
+
+// This test verifies that an empty shared network list can be properly
+// translated from JSON to YANG.
+TEST_F(TranslatorSharedNetworksTest, setEmpty) {
+ useModel(KEA_DHCP4_SERVER);
+
+ // Set empty list.
+ const string& xpath = "/kea-dhcp4-server:config/shared-networks";
+ ConstElementPtr networks = Element::createList();
+ EXPECT_NO_THROW(t_obj_->setSharedNetworks(xpath, networks));
+
+ // Get it back.
+ networks.reset();
+ EXPECT_NO_THROW(networks = t_obj_->getSharedNetworks(xpath));
+ ASSERT_TRUE(networks);
+ ASSERT_EQ(Element::list, networks->getType());
+ EXPECT_EQ(0, networks->size());
+
+ // Check that the tree representation is empty.
+ S_Tree tree;
+ EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp4-server:config"));
+ EXPECT_FALSE(tree);
+}
+
+// This test verifies that one shared network can be properly
+// translated from JSON to YANG.
+TEST_F(TranslatorSharedNetworksTest, set) {
+ useModel(KEA_DHCP6_SERVER);
+
+ // Set one shared network.
+ const string& xpath = "/kea-dhcp6-server:config/shared-networks";
+ ElementPtr networks = Element::createList();
+ ElementPtr share = Element::createMap();
+ ElementPtr subnets = Element::createList();
+ ElementPtr subnet = Element::createMap();
+ subnet->set("subnet", Element::create(string("2001:db8::/48")));
+ subnet->set("id", Element::create(123));
+ subnets->add(subnet);
+ share->set("name", Element::create(string("foo")));
+ share->set("subnet6", subnets);
+ networks->add(share);
+ EXPECT_NO_THROW(t_obj_->setSharedNetworks(xpath, networks));
+
+ // Get it back.
+ networks.reset();
+ EXPECT_NO_THROW(networks = t_obj_->getSharedNetworks(xpath));
+ ASSERT_TRUE(networks);
+ ASSERT_EQ(Element::list, networks->getType());
+ ASSERT_EQ(1, networks->size());
+ EXPECT_TRUE(share->equals(*networks->get(0)));
+
+ // Check the tree representation.
+ S_Tree tree;
+ EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp6-server:config"));
+ ASSERT_TRUE(tree);
+ string expected =
+ "kea-dhcp6-server:config (container)\n"
+ " |\n"
+ " -- shared-networks (container)\n"
+ " |\n"
+ " -- shared-network (list instance)\n"
+ " |\n"
+ " -- name = foo\n"
+ " |\n"
+ " -- subnet6 (container)\n"
+ " |\n"
+ " -- subnet6 (list instance)\n"
+ " |\n"
+ " -- id = 123\n"
+ " |\n"
+ " -- subnet = 2001:db8::/48\n";
+ EXPECT_EQ(expected, tree->to_string(100));
+
+ // Check it validates.
+ EXPECT_NO_THROW(sess_->validate());
+}
+
+}; // end of anonymous namespace
--- /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_shared_network.h>
+#include <yang/adaptor.h>
+#include <yang/yang_models.h>
+#include <sstream>
+
+using namespace std;
+using namespace isc::data;
+
+namespace isc {
+namespace yang {
+
+TranslatorSharedNetwork::TranslatorSharedNetwork(S_Session session,
+ const string& model)
+ : TranslatorBasic(session),
+ TranslatorOptionData(session, model),
+ TranslatorOptionDataList(session, model),
+ TranslatorPool(session, model),
+ TranslatorPools(session, model),
+ TranslatorPdPool(session, model),
+ TranslatorPdPools(session, model),
+ TranslatorHost(session, model),
+ TranslatorHosts(session, model),
+ TranslatorSubnet(session, model),
+ TranslatorSubnets(session, model),
+ model_(model) {
+}
+
+TranslatorSharedNetwork::~TranslatorSharedNetwork() {
+}
+
+ElementPtr
+TranslatorSharedNetwork::getSharedNetwork(const string& xpath) {
+ try {
+ if (model_ == KEA_DHCP4_SERVER) {
+ return (getSharedNetworkKea(xpath, "subnet4"));
+ } else if (model_ == KEA_DHCP6_SERVER) {
+ return (getSharedNetworkKea(xpath, "subnet6"));
+ }
+ } catch (const sysrepo_exception& ex) {
+ isc_throw(SysrepoError,
+ "sysrepo error getting shared network at '" << xpath
+ << "': " << ex.what());
+ }
+ isc_throw(NotImplemented,
+ "getSharedNetwork not implemented for the model: " << model_);
+}
+
+ElementPtr
+TranslatorSharedNetwork::getSharedNetworkKea(const string& xpath,
+ const std::string& subsel) {
+ ElementPtr result = Element::createMap();
+ result->set("name", getItem(xpath + "/name"));
+ ConstElementPtr subnets = getSubnets(xpath + "/" + subsel);
+ if (subnets && (subnets->size() > 0)) {
+ result->set(subsel, subnets);
+ }
+ if (subsel == "subnet6") {
+ ConstElementPtr preferred = getItem(xpath + "/preferred-lifetime");
+ if (preferred) {
+ result->set("preferred-lifetime", preferred);
+ }
+ }
+ ConstElementPtr valid = getItem(xpath + "/valid-lifetime");
+ if (valid) {
+ result->set("valid-lifetime", valid);
+ }
+ ConstElementPtr renew = getItem(xpath + "/renew-timer");
+ if (renew) {
+ result->set("renew-timer", renew);
+ }
+ ConstElementPtr rebind = getItem(xpath + "/rebind-timer");
+ if (rebind) {
+ result->set("rebind-timer", rebind);
+ }
+ ConstElementPtr options = getOptionDataList(xpath + "/option-data-list");
+ if (options && (options->size() > 0)) {
+ result->set("option-data", options);
+ }
+ ConstElementPtr interface = getItem(xpath + "/interface");
+ if (interface) {
+ result->set("interface", interface);
+ }
+ if (subsel == "subnet6") {
+ ConstElementPtr interface_id = getItem(xpath + "/interface-id");
+ if (interface_id) {
+ result->set("interface-id", interface_id);
+ }
+ ConstElementPtr rapid_commit = getItem(xpath + "/rapid-commit");
+ if (rapid_commit) {
+ result->set("rapid-commit", rapid_commit);
+ }
+ }
+ ConstElementPtr guard = getItem(xpath + "/client-class");
+ if (guard) {
+ result->set("client-class", guard);
+ }
+ ConstElementPtr required = getItems(xpath + "/require-client-classes");
+ if (required && (required->size() > 0)) {
+ result->set("require-client-classes", required);
+ }
+ ConstElementPtr mode = getItem(xpath + "/reservation-mode");
+ if (mode) {
+ result->set("reservation-mode", mode);
+ }
+ ConstElementPtr relay = getItems(xpath + "/relay/ip-addresses");
+ if (relay && (relay->size() > 0)) {
+ ElementPtr relay_map = Element::createMap();
+ relay_map->set("ip-addresses", relay);
+ result->set("relay", relay_map);
+ }
+ if (subsel == "subnet4") {
+ ConstElementPtr match = getItem(xpath + "/match-client-id");
+ if (match) {
+ result->set("match-client-id", match);
+ }
+ ConstElementPtr next = getItem(xpath + "/next-server");
+ if (next) {
+ result->set("next-server", next);
+ }
+ ConstElementPtr hostname = getItem(xpath + "/server-hostname");
+ if (hostname) {
+ result->set("server-hostname", hostname);
+ }
+ ConstElementPtr boot = getItem(xpath + "/boot-file-name");
+ if (boot) {
+ result->set("boot-file-name", boot);
+ }
+ }
+ ConstElementPtr context = getItem(xpath + "/user-context");
+ if (context) {
+ result->set("user-context", Element::fromJSON(context->stringValue()));
+ }
+ return (result);
+}
+
+void
+TranslatorSharedNetwork::setSharedNetwork(const string& xpath,
+ ConstElementPtr elem) {
+ try {
+ if (model_ == KEA_DHCP4_SERVER) {
+ setSharedNetworkKea(xpath, elem, "subnet4");
+ } else if (model_ == KEA_DHCP6_SERVER) {
+ setSharedNetworkKea(xpath, elem, "subnet6");
+ } else {
+ isc_throw(NotImplemented,
+ "setSharedNetwork not implemented for the model: "
+ << model_);
+ }
+ } catch (const sysrepo_exception& ex) {
+ isc_throw(SysrepoError,
+ "sysrepo error setting shared network '" << elem->str()
+ << "' at '" << xpath << "': " << ex.what());
+ }
+}
+
+void
+TranslatorSharedNetwork::setSharedNetworkKea(const string& xpath,
+ ConstElementPtr elem,
+ const std::string& subsel) {
+ // Skip name which is the key.
+ ConstElementPtr subnets = elem->get(subsel);
+ if (subnets && (subnets->size() > 0)) {
+ setSubnets(xpath + "/" + subsel, subnets);
+ }
+ if (subsel == "subnet6") {
+ ConstElementPtr preferred = elem->get("preferred-lifetime");
+ if (preferred) {
+ setItem(xpath + "/preferred-lifetime", preferred, SR_UINT32_T);
+ }
+ }
+ ConstElementPtr valid = elem->get("valid-lifetime");
+ if (valid) {
+ setItem(xpath + "/valid-lifetime", valid, SR_UINT32_T);
+ }
+ ConstElementPtr renew = elem->get("renew-timer");
+ if (renew) {
+ setItem(xpath + "/renew-timer", renew, SR_UINT32_T);
+ }
+ ConstElementPtr rebind = elem->get("rebind-timer");
+ if (rebind) {
+ setItem(xpath + "/rebind-timer", rebind, SR_UINT32_T);
+ }
+ ConstElementPtr options = elem->get("option-data");
+ if (options && (options->size() > 0)) {
+ setOptionDataList(xpath + "/option-data-list", options);
+ }
+ ConstElementPtr interface = elem->get("interface");
+ if (interface) {
+ setItem(xpath + "/interface", interface, SR_STRING_T);
+ }
+ if (subsel == "subnet6") {
+ ConstElementPtr interface_id = elem->get("interface-id");
+ if (interface_id) {
+ setItem(xpath + "/interface-id", interface_id, SR_STRING_T);
+ }
+ ConstElementPtr rapid_commit = elem->get("rapid-commit");
+ if (rapid_commit) {
+ setItem(xpath + "/rapid-commit", rapid_commit, SR_BOOL_T);
+ }
+ }
+ ConstElementPtr guard = elem->get("client-class");
+ if (guard) {
+ setItem(xpath + "/client-class", guard, SR_STRING_T);
+ }
+ ConstElementPtr required = elem->get("require-client-classes");
+ if (required && (required->size() > 0)) {
+ for (ConstElementPtr rclass : required->listValue()) {
+ setItem(xpath + "/require-client-classes", rclass, SR_STRING_T);
+ }
+ }
+ ConstElementPtr mode = elem->get("reservation-mode");
+ if (mode) {
+ setItem(xpath + "/reservation-mode", mode, SR_ENUM_T);
+ }
+ ConstElementPtr relay = elem->get("relay");
+ if (relay) {
+ ConstElementPtr address = relay->get("ip-address");
+ ConstElementPtr addresses = relay->get("ip-addresses");
+ if (address) {
+ setItem(xpath + "/relay/ip-addresses", address, SR_STRING_T);
+ } else if (addresses && (addresses->size() > 0)) {
+ for (ConstElementPtr addr : addresses->listValue()) {
+ setItem(xpath + "/relay/ip-addresses", addr, SR_STRING_T);
+ }
+ }
+ }
+ if (subsel == "subnet4") {
+ ConstElementPtr match = elem->get("match-client-id");
+ if (match) {
+ setItem(xpath + "/match-client-id", match, SR_BOOL_T);
+ }
+ ConstElementPtr next = elem->get("next-server");
+ if (next) {
+ setItem(xpath + "/next-server", next, SR_STRING_T);
+ }
+ ConstElementPtr hostname = elem->get("server-hostname");
+ if (hostname) {
+ setItem(xpath + "/server-hostname", hostname, SR_STRING_T);
+ }
+ ConstElementPtr boot = elem->get("boot-file-name");
+ if (boot) {
+ setItem(xpath + "/boot-file-name", boot, SR_STRING_T);
+ }
+ }
+ ConstElementPtr context = Adaptor::getContext(elem);
+ if (context) {
+ ConstElementPtr repr = Element::create(context->str());
+ setItem(xpath + "/user-context", repr, SR_STRING_T);
+ }
+}
+
+TranslatorSharedNetworks::TranslatorSharedNetworks(S_Session session,
+ const string& model)
+ : TranslatorBasic(session),
+ TranslatorOptionData(session, model),
+ TranslatorOptionDataList(session, model),
+ TranslatorPool(session, model),
+ TranslatorPools(session, model),
+ TranslatorPdPool(session, model),
+ TranslatorPdPools(session, model),
+ TranslatorHost(session, model),
+ TranslatorHosts(session, model),
+ TranslatorSubnet(session, model),
+ TranslatorSubnets(session, model),
+ TranslatorSharedNetwork(session, model),
+ model_(model) {
+}
+
+TranslatorSharedNetworks::~TranslatorSharedNetworks() {
+}
+
+ElementPtr
+TranslatorSharedNetworks::getSharedNetworks(const string& xpath) {
+ try {
+ ElementPtr result = Element::createList();
+ S_Iter_Value iter = getIter(xpath + "/*");
+ if (!iter) {
+ // Can't happen.
+ isc_throw(Unexpected, "getSharedNetworks: can't get iterator: "
+ << xpath);
+ }
+ for (;;) {
+ const string& network = getNext(iter);
+ if (network.empty()) {
+ break;
+ }
+ result->add(getSharedNetwork(network));
+ }
+ return (result);
+ } catch (const sysrepo_exception& ex) {
+ isc_throw(SysrepoError,
+ "sysrepo error getting shared networks at '" << xpath
+ << "': " << ex.what());
+ }
+}
+
+void
+TranslatorSharedNetworks::setSharedNetworks(const string& xpath,
+ ConstElementPtr elem) {
+ try {
+ if ((model_ == KEA_DHCP4_SERVER) ||
+ (model_ == KEA_DHCP6_SERVER)) {
+ setSharedNetworksKea(xpath, elem);
+ } else {
+ isc_throw(NotImplemented,
+ "setSharedNetworks not implemented for the model: "
+ << model_);
+ }
+ } catch (const sysrepo_exception& ex) {
+ isc_throw(SysrepoError,
+ "sysrepo error setting shared networks '" << elem->str()
+ << "' at '" << xpath << "': " << ex.what());
+ }
+}
+
+void
+TranslatorSharedNetworks::setSharedNetworksKea(const string& xpath,
+ ConstElementPtr elem) {
+ for (size_t i = 0; i < elem->size(); ++i) {
+ ConstElementPtr network = elem->get(i);
+ if (!network->contains("name")) {
+ isc_throw(BadValue, "setSharedNetworksKea requires name: "
+ << network->str());
+ }
+ string name = network->get("name")->stringValue();
+ ostringstream key;
+ key<< xpath << "/shared-network[name='" << name << "']";
+ setSharedNetwork(key.str(), network);
+ }
+}
+
+}; // 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_SHARED_NETWORK_H
+#define ISC_TRANSLATOR_SHARED_NETWORK_H 1
+
+#include <yang/translator.h>
+#include <yang/translator_subnet.h>
+#include <list>
+
+namespace isc {
+namespace yang {
+
+/// Shared network translation between YANG and JSON
+///
+/// JSON syntax for kea-dhcp4 is:
+/// @code
+/// {
+/// "name": <name>,
+/// "subnet4": <subnet list>,
+/// "valid-lifetime": <valid lifetime>,
+/// "renew-timer": <renew timer>,
+/// "rebind-timer": <rebind timer>,
+/// "option-data": [ <list of option data> ],
+/// "interface": "<interface>",
+/// "client-class": "<guard class name>",
+/// "require-client-classes": [ <list of required class names> ],
+/// "reservation-mode": <host reservation mode>,
+/// "relay": <relay ip address(es)>,
+/// "match-client-id": <match client id flag>,
+/// "next-server": "<next server>",
+/// "server-hostname": "<server hostname>",
+/// "boot-file-name": "<boot file name>",
+/// "user-context": { <json map> },
+/// "comment": "<comment>"
+/// }
+/// @endcode
+///
+/// JSON syntax for kea-dhcp6 is:
+/// @code
+/// {
+/// "name": <name>,
+/// "subnet6": <subnet list>,
+/// "preferred-lifetime": <preferred lifetime>,
+/// "valid-lifetime": <valid lifetime>,
+/// "renew-timer": <renew timer>,
+/// "rebind-timer": <rebind timer>,
+/// "option-data": [ <list of option data> ],
+/// "interface": "<interface>",
+/// "interface-id": "<interface id>",
+/// "rapid-commit": <rapid commit flag>,
+/// "client-class": "<guard class name>",
+/// "require-client-classes": [ <list of required class names> ],
+/// "reservation-mode": <host reservation mode>,
+/// "relay": <relay ip address(es)>,
+/// "user-context": { <json map> },
+/// "comment": "<comment>"
+/// }
+/// @endcode
+///
+/// YANG syntax for kea-dhcp[46] is with name as the list key:
+/// @code
+/// +--rw name string
+/// +--rw valid-lifetime? uint32
+/// +--rw renew-timer? uint32
+/// +--rw rebind-timer? uint32
+/// +--rw option-data-list option-data*
+/// +--rw interface? string
+/// +--rw client-class? string
+/// +--rw require-client-classes* string
+/// +--rw reservation-mode? enumeration
+/// +--rw relay ip-addresses*
+/// +--rw user-context? string
+/// (DHCPv4 only)
+/// +--rw subnet4 subnet4*
+/// +--rw match-client-id? boolean
+/// +--rw next-server? inet:ipv4-address
+/// +--rw server-hostname? string
+/// +--rw boot-file-name? string
+/// (DHCPv6 only)
+/// +--rw subnet6 subnet6*
+/// +--rw preferred-lifetime? uint32
+/// +--rw interface-id? string
+/// +--rw rapid-commit? boolean
+/// @endcode
+///
+/// An example in JSON and YANG formats:
+/// @code
+/// [
+/// {
+/// "name": "foo",
+/// "subnet6":
+/// [
+/// {
+/// "subnet": "2001:db8::/48",
+/// "id": 123
+/// }
+/// ]
+/// }
+/// ]
+/// @endcode
+/// @code
+/// /kea-dhcp6-server:config (container)
+/// /kea-dhcp6-server:config/shared-networks (container)
+/// /kea-dhcp6-server:config/shared-networks/
+/// shared-network[name='foo'] (list instance)
+/// /kea-dhcp6-server:config/shared-networks/shared-network[name='foo']/
+/// name = foo
+/// /kea-dhcp6-server:config/shared-networks/shared-network[name='foo']/
+/// subnet6 (container)
+/// /kea-dhcp6-server:config/shared-networks/shared-network[name='foo']/
+/// subnet6/subnet6[id='123'] (list instance)
+/// /kea-dhcp6-server:config/shared-networks/shared-network[name='foo']/
+/// subnet6/subnet6[id='123']/id = 123
+/// /kea-dhcp6-server:config/shared-networks/shared-network[name='foo']/
+/// subnet6/subnet6[id='123']/subnet = 2001:db8::/48
+/// @endcode
+
+/// @brief A translator class for converting a shared network between
+/// YANG and JSON.
+///
+/// Currently supports on kea-dhcp[46]-server. Does not exist in
+/// ietf-dhcpv6-server.
+class TranslatorSharedNetwork : virtual public TranslatorSubnets {
+public:
+
+ /// @brief Constructor.
+ ///
+ /// @param session Sysrepo session.
+ /// @param model Model name.
+ TranslatorSharedNetwork(S_Session session, const std::string& model);
+
+ /// @brief Destructor.
+ virtual ~TranslatorSharedNetwork();
+
+ /// @brief Get and translate a shared network from YANG to JSON.
+ ///
+ /// @param xpath The xpath of the shared network.
+ /// @return JSON representation of the shared network.
+ /// @throw SysrepoError when sysrepo raises an error.
+ isc::data::ElementPtr getSharedNetwork(const std::string& xpath);
+
+ /// @brief Translate and set shared network from JSON to YANG.
+ ///
+ /// @param xpath The xpath of the shared network.
+ /// @param elem The JSON element.
+ void setSharedNetwork(const std::string& xpath,
+ isc::data::ConstElementPtr elem);
+
+protected:
+ /// @brief getSharedNetwork for kea-dhcp[46].
+ ///
+ /// @param xpath The xpath of the shared network.
+ /// @param subsel The subnet list name.
+ /// @return JSON representation of the shared network.
+ isc::data::ElementPtr getSharedNetworkKea(const std::string& xpath,
+ const std::string& subsel);
+
+ /// @brief setSharedNetwork for kea-dhcp[46].
+ ///
+ /// @param xpath The xpath of the shared network.
+ /// @param elem The JSON element.
+ /// @param subsel The subnet list name.
+ void setSharedNetworkKea(const std::string& xpath,
+ isc::data::ConstElementPtr elem,
+ const std::string& subsel);
+
+ /// @brief The model.
+ std::string model_;
+};
+
+/// @brief A translator class for converting a shared network list between
+/// YANG and JSON.
+///
+/// Currently supports on kea-dhcp[46]-server. Does not exist in
+/// ietf-dhcpv6-server.
+class TranslatorSharedNetworks : virtual public TranslatorSharedNetwork {
+public:
+
+ /// @brief Constructor.
+ ///
+ /// @param session Sysrepo session.
+ /// @param model Model name.
+ TranslatorSharedNetworks(S_Session session, const std::string& model);
+
+ /// @brief Destructor.
+ virtual ~TranslatorSharedNetworks();
+
+ /// @brief Get and translate shared networks from YANG to JSON.
+ ///
+ /// @param xpath The xpath of the shared network list.
+ /// @throw SysrepoError when sysrepo raises an error.
+ isc::data::ElementPtr getSharedNetworks(const std::string& xpath);
+
+ /// @brief Translate and set shared networks from JSON to YANG.
+ ///
+ /// @param xpath The xpath of the shared network list.
+ /// @param elem The JSON element.
+ void setSharedNetworks(const std::string& xpath,
+ isc::data::ConstElementPtr elem);
+
+protected:
+ /// @brief setSharedNetworks for kea-dhcp[46].
+ ///
+ /// @param xpath The xpath of the shared network list.
+ /// @param elem The JSON element.
+ /// @throw BadValue on a shared network without name.
+ void setSharedNetworksKea(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_SHARED_NETWORK_H