// Copyright (C) 2018-2022 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_CONFIG_H #define ISC_TRANSLATOR_CONFIG_H 1 #include #include #include #include #include #include namespace isc { namespace yang { /// @brief DHCP configuration translation between YANG and JSON /// /// This translator supports kea-dhcp4-server, kea-dhcp6-server and /// partially ietf-dhcpv6-server. /// JSON syntax for kea-dhcp4 is: /// @code /// "Dhcp4": { /// "valid-lifetime": , /// "min-valid-lifetime": , /// "max-valid-lifetime": , /// "renew-timer": , /// "rebind-timer": , /// "calculate-tee-times": , /// "t1-percent": , /// "t2-percent": , /// "decline-probation-period": , /// "subnet4": [ ], /// , /// "interfaces-config": { /// "interfaces" [ ], /// ... /// }, /// , /// , /// , /// , /// , /// , /// , /// , /// , /// , /// , /// , /// "echo-client-id": , /// "match-client-id": , /// "next-server": , /// "server-hostname": , /// "boot-file-name": , /// "authoritative": , /// , /// , /// "sanity-checks": { }, /// "reservation-mode": , /// "reservations": [ ], /// , /// "server-tag": , /// "dhcp-queue-control": { }, /// "loggers": [ ] /// }, /// @endcode /// /// YANG syntax for kea-dhcp4-server:config is: /// @code /// +--rw valid-lifetime? uint32 /// +--rw min-valid-lifetime? uint32 /// +--rw max-valid-lifetime? uint32 /// +--rw renew-timer? uint32 /// +--rw rebind-timer? uint32 /// +--rw calculate-tee-times? boolean /// +--rw t1-percent? decimal64 /// +--rw t2-percent? decimal64 /// +--rw decline-probation-period? uint32 /// +--rw subnet4* [id] /// +--rw shared-network* [name] /// +--rw interfaces-config /// +--rw lease-database! /// +--rw hosts-database* [database-type] /// +--rw host-reservation-identifiers* host-identifier-type /// +--rw client-class* [name] /// +--rw option-def* [code space] /// +--rw option-data* [code space] /// +--rw hook-library* [library] /// +--rw expired-leases-processing /// +--rw dhcp4o6-port? uint16 /// +--rw control-socket! /// +--rw hostname-char-set? string /// +--rw hostname-char-replacement? string /// +--rw dhcp-ddns /// +--rw echo-client-id? boolean /// +--rw match-client-id? boolean /// +--rw next-server? inet:ipv4-address /// +--rw server-hostname? string /// +--rw boot-file-name? string /// +--rw authoritative? boolean /// +--rw user-context? user-context /// +--rw sanity-checks /// +--rw reservation-mode? host-reservation-mode /// +--rw host* [identifier-type identifier] /// +--rw config-control /// +--rw server-tag? string /// +--rw dhcp-queue-control? string /// +--rw logger* [name] /// +--rw cache-max-age? uint32 /// +--rw cache-threshold? decimal64 /// +--rw compatibility /// +--rw ddns-generated-prefix? string /// +--rw ddns-override-client-update? boolean /// +--rw ddns-override-no-update? boolean /// +--rw ddns-qualifying-suffix? string /// +--rw ddns-replace-client-name? string /// +--rw ddns-send-updates? boolean /// +--rw ddns-update-on-renew? boolean /// +--rw ddns-use-conflict-resolution? boolean /// +--rw ip-reservations-unique? boolean /// +--rw early-global-reservations-lookup? boolean /// +--rw reservations-lookup-first? boolean /// +--rw multi-threading /// +--rw parked-packet-limit? uint32 /// +--rw reservations-global? boolean /// +--rw reservations-in-subnet? boolean /// +--rw reservations-out-of-pool? boolean /// +--rw statistic-default-sample-age? uint32 /// +--rw statistic-default-sample-count? uint32 /// +--rw store-extended-info? boolean /// @endcode /// /// Example of kea-dhcp6 simple configuration: /// @code /// { /// "Dhcp4": { /// "interfaces-config": /// { /// "interfaces": [ "eth1" ] /// }, /// "control-socket": { /// "socket-type": "unix", /// "socket-name": "/tmp/kea4-sock" /// }, /// "subnet4": /// [ /// { /// "subnet": "10.0.35.0/24", /// "pools": /// [ /// { /// "pool": "10.0.35.64/27" /// } /// ] /// } /// ] /// } /// } /// /// @endcode /// /// The same configuration wrote into YANG datastore using @c setConfig() /// with the kea-dhcp4-model and exported to XML format: /// @code /// /// /// 1 /// /// 10.0.35.64 /// 10.0.35.95 /// 10.0.35.64/27 /// /// 10.0.35.0/24 /// /// /// eth1 /// /// /// /tmp/kea4-sock /// unix /// /// /// @endcode /// JSON syntax for kea-dhcp6 is: /// @code /// "Dhcp6": { /// "data-directory": , /// "preferred-lifetime": , /// "min-preferred-lifetime": , /// "max-preferred-lifetime": , /// "valid-lifetime": , /// "min-valid-lifetime": , /// "max-valid-lifetime": , /// "renew-timer": , /// "rebind-timer": , /// "calculate-tee-times": , /// "t1-percent": , /// "t2-percent": , /// "decline-probation-period": , /// "subnet6": [ ], /// , /// "interfaces-config": { /// "interfaces" [ ], /// ... /// }, /// , /// , /// , /// , /// , /// , /// , /// , /// , /// , /// , /// , /// , /// , /// , /// , /// /// "sanity-checks": { }, /// "reservation-mode": , /// "reservations": [ ], /// , /// "server-tag": , /// "dhcp-queue-control": { }, /// "loggers": [ ] /// }, /// @endcode /// /// YANG syntax for kea-dhcp6-server:config is: /// @code /// +--rw data-directory? string /// +--rw preferred-lifetime? uint32 /// +--rw min-preferred-lifetime? uint32 /// +--rw max-preferred-lifetime? uint32 /// +--rw valid-lifetime? uint32 /// +--rw min-valid-lifetime? uint32 /// +--rw max-valid-lifetime? uint32 /// +--rw renew-timer? uint32 /// +--rw rebind-timer? uint32 /// +--rw calculate-tee-times? boolean /// +--rw t1-percent? decimal64 /// +--rw t2-percent? decimal64 /// +--rw decline-probation-period? uint32 /// +--rw subnet6* [id] /// +--rw shared-network* [name] /// +--rw interfaces-config /// +--rw lease-database! /// +--rw hosts-database* [database-type] /// +--rw relay-supplied-options* string /// +--rw mac-sources* string /// +--rw host-reservation-identifiers* host-identifier-type /// +--rw client-class* [name] /// +--rw option-def* [code space] /// +--rw option-data* [code space] /// +--rw hook-library* [library] /// +--rw expired-leases-processing /// +--rw server-id! /// +--rw dhcp4o6-port? uint16 /// +--rw control-socket! /// +--rw hostname-char-set? string /// +--rw hostname-char-replacement? string /// +--rw dhcp-ddns /// +--rw user-context? user-context /// +--rw sanity-checks /// +--rw reservation-mode? host-reservation-mode /// +--rw host* [identifier-type identifier] /// +--rw config-control /// +--rw server-tag? string /// +--rw dhcp-queue-control? string /// +--rw logger* [name] /// +--rw cache-max-age? uint32 /// +--rw cache-threshold? decimal64 /// +--rw compatibility /// +--rw ddns-generated-prefix? string /// +--rw ddns-override-client-update? boolean /// +--rw ddns-override-no-update? boolean /// +--rw ddns-qualifying-suffix? string /// +--rw ddns-replace-client-name? string /// +--rw ddns-send-updates? boolean /// +--rw ddns-update-on-renew? boolean /// +--rw ddns-use-conflict-resolution? boolean /// +--rw ip-reservations-unique? boolean /// +--rw early-global-reservations-lookup? boolean /// +--rw reservations-lookup-first? boolean /// +--rw multi-threading /// +--rw parked-packet-limit? uint32 /// +--rw reservations-global? boolean /// +--rw reservations-in-subnet? boolean /// +--rw reservations-out-of-pool? boolean /// +--rw statistic-default-sample-age? uint32 /// +--rw statistic-default-sample-count? uint32 /// +--rw store-extended-info? boolean /// @endcode /// /// Example of kea-dhcp6 simple configuration: /// @code /// { /// "Dhcp6": { /// "interfaces-config": /// { /// "interfaces": [ "eth1" ] /// }, /// "control-socket": { /// "socket-type": "unix", /// "socket-name": "/tmp/kea6-sock" /// }, /// "subnet6": /// [ /// { /// "subnet": "2001:db8::/64", /// "pools": /// [ /// { /// "pool": "2001:db8::1:0/112" /// } /// ] /// } /// ] /// } /// } /// @endcode /// /// The same configuration wrote into YANG datastore using @c setConfig() /// with the kea-dhcp6-model and exported to XML format: /// @code /// /// /// 1 /// /// 2001:db8::1:0 /// 2001:db8::1:ffff /// 2001:db8::1:0/112 /// /// 2001:db8::/64 /// /// /// eth1 /// /// /// /tmp/kea6-sock /// unix /// /// /// @endcode /// Inheritance graph between translators is: /// /// +-----------------------------------------+ /// | | /// +------------------------------+ | /// | | | /// +----------+-------------------+----------+ /// | | | | /// | | +---------+----------+ /// | | | | | /// config +- shared +- subnet +- pool --+- option -+ basic /// | network (list) | (list) | data | /// | (list) | | (list) | /// | | | | /// | +- pd ----+ | /// | | pool | | /// | | (list) | | /// | | | | /// +--------------------+- host --+ | /// | (liat) | | /// | | | /// | +--------------------+----------+ /// | | | /// +- class -+- option ----------------------+ /// | (list) | def | /// | | (list) | /// +---------+ | /// | | /// + control --------------------------------+ /// | socket | /// | | /// +------------+ | /// | | | /// +- database -+- database -----------------+ /// | list | /// | | /// +- logger --------------------------------+ /// (list) /// /// 'XXX (list)' stands for 'XXX list --- XXX' which is a common motif /// (only database shows direct dependencies on both the list and the element) /// @brief A translator class for converting the config between YANG and JSON. /// /// Currently supports the following models: /// - kea-dhcp4-server /// - kea-dhcp6-server /// - ietf-dhcpv6-server (partial) class TranslatorConfig : virtual public TranslatorControlSocket, virtual public TranslatorDatabases, virtual public TranslatorClasses, virtual public TranslatorSharedNetworks, virtual public TranslatorLoggers { public: /// @brief Constructor. /// /// @param session Sysrepo session. /// @param model Model name. TranslatorConfig(sysrepo::Session session, const std::string& model); /// @brief Destructor. virtual ~TranslatorConfig() = default; /// @brief Translate the whole DHCP server configuration from YANG to JSON. /// /// @return JSON representation of the config. /// @throw NetconfError when sysrepo raises an error. isc::data::ElementPtr getConfig(); /// @brief Translate and set the DHCP server configuration from JSON to YANG. /// /// Null elem argument removes the config containers. /// /// @param elem The JSON element. void setConfig(isc::data::ElementPtr elem); protected: /// @brief getConfig for ietf-dhcpv6-server. /// /// This implementation is very preliminary. It handles network-ranges /// only partially and nothing else. /// /// @return JSON representation of the config. /// @throw NetconfError when sysrepo raises an error. isc::data::ElementPtr getConfigIetf6(); /// @brief delConfig for ietf-dhcpv6-server. void delConfigIetf6(); /// @brief setConfig for ietf-dhcpv6-server. /// /// This implementation is very preliminary. It handles network-ranges /// only partially and nothing else. /// /// @param elem The JSON element. /// @throw BadValue on config without Dhcp6. void setConfigIetf6(isc::data::ConstElementPtr elem); /// @brief getConfig for kea-dhcp4-server. /// /// @return JSON representation of the config. /// @throw NetconfError when sysrepo raises an error. isc::data::ElementPtr getConfigKea4(); /// @brief getConfig for kea-dhcp6-server. /// /// @return JSON representation of the config. /// @throw NetconfError when sysrepo raises an error. isc::data::ElementPtr getConfigKea6(); /// @brief getServer common part for kea-dhcp[46]-server:config. /// /// @param data_node the YANG node representing the server configuration /// /// @return JSON representation of the server. isc::data::ElementPtr getServerKeaDhcpCommon(libyang::DataNode const& data_node); /// @brief getServer for kea-dhcp4-server:config. /// /// @return JSON representation of the config. /// @throw NetconfError when sysrepo raises an error. isc::data::ElementPtr getServerKeaDhcp4(); /// @brief getServer for kea-dhcp6-server:config. /// /// @return JSON representation of the config. /// @throw NetconfError when sysrepo raises an error. isc::data::ElementPtr getServerKeaDhcp6(); /// @brief delConfig for kea-dhcp[46]-server. void delConfigKea(); /// @brief setConfig for kea-dhcp[46]-server. /// /// @param elem The JSON element. void setConfigKea4(isc::data::ConstElementPtr elem); /// @brief setConfig for kea-dhcp6-server. /// /// @param elem The JSON element. void setConfigKea6(isc::data::ConstElementPtr elem); /// @brief setServer common part for kea-dhcp[46]-server:config. /// /// @param xpath The xpath of the server. /// @param elem The JSON element. void setServerKeaDhcpCommon(const std::string& xpath, isc::data::ConstElementPtr elem); isc::data::ElementPtr getHook(libyang::DataNode const& data_node); /// @brief Retrieves hooks configuration from sysrepo. /// /// @param data_node the YANG node representing the hook libraries /// /// @return ElementList with hooks configuration. isc::data::ElementPtr getHooksKea(libyang::DataNode const& data_node); /// @brief Retrieves expired leases processing parameters from sysrepo. /// /// @param data_node the YANG node representing the configuration for expired lease processing /// /// @return ElementList with expired leases configuration. isc::data::ElementPtr getExpiredKea(libyang::DataNode const& data_node); /// @brief Retrieves DDNS configuration from sysrepo /// /// @param data_node the YANG node representing dhcp-ddns configuration /// /// @return ElementList with dhcp-ddns configuration. isc::data::ElementPtr getDdnsKea(libyang::DataNode const& data_node); /// @brief Retrieves configuration control from sysrepo. /// /// @param data_node the YANG node representing configuration control /// /// @return ElementMap with configuration control. isc::data::ElementPtr getConfigControlKea(libyang::DataNode const& data_node); /// @brief Retrieves interfaces configuration from sysrepo. /// /// @param data_node the YANG node representing the interfaces configuration /// /// @return ElementMap with configuration control. isc::data::ElementPtr getInterfacesKea(libyang::DataNode const& data_node); /// @brief setServer for kea-dhcp4-server:config. /// /// @param elem The JSON element. void setServerKeaDhcp4(isc::data::ConstElementPtr elem); /// @brief setServer for kea-dhcp6-server:config. /// /// @param elem The JSON element. void setServerKeaDhcp6(isc::data::ConstElementPtr elem); }; // TranslatorConfig } // namespace yang } // namespace isc #endif // ISC_TRANSLATOR_CONFIG_H