]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2601] update YANG developer guide
authorAndrei Pavel <andrei@isc.org>
Tue, 8 Nov 2022 10:02:29 +0000 (12:02 +0200)
committerRazvan Becheriu <razvan@isc.org>
Fri, 25 Nov 2022 16:15:33 +0000 (18:15 +0200)
src/lib/yang/translator.cc
src/lib/yang/translator.h
src/lib/yang/translator_config.cc
src/lib/yang/yang.dox

index b2df24b57ccc799b8d79447fc873ec1842f0133a..002c5de308af3aa6d71194fa33a13dab9f25a8d9 100644 (file)
@@ -60,9 +60,9 @@ Translator::checkAndGetAndJsonifyLeaf(ElementPtr& storage,
 }
 
 void
-Translator::checkAndJsonifyAndSetLeaf(ConstElementPtr const& from,
-                                      string const& xpath,
-                                      string const& name) {
+Translator::checkAndStringifyAndSetLeaf(ConstElementPtr const& from,
+                                        string const& xpath,
+                                        string const& name) {
     ConstElementPtr const& x(from->get(name));
     if (x) {
         ElementPtr const& json(Element::create(x->str()));
@@ -112,16 +112,6 @@ void Translator::checkAndSetUserContext(ConstElementPtr const& from,
     }
 }
 
-string
-Translator::decode64(string const& input) {
-    vector<uint8_t> binary;
-    decodeBase64(input, binary);
-    string result;
-    result.resize(binary.size());
-    memmove(&result[0], &binary[0], result.size());
-    return (result);
-}
-
 void
 Translator::deleteItem(string const& xpath) {
 
@@ -135,15 +125,6 @@ Translator::deleteItem(string const& xpath) {
     session_.applyChanges();
 }
 
-
-string
-Translator::encode64(string const& input) {
-    vector<uint8_t> binary;
-    binary.resize(input.size());
-    memmove(&binary[0], input.c_str(), binary.size());
-    return (encodeBase64(binary));
-}
-
 DataNode
 Translator::findXPath(string const& xpath) const {
     optional<DataNode> const& data_node(getData(xpath));
@@ -233,60 +214,6 @@ Translator::getMandatoryDivergingLeaf(ElementPtr& storage,
     storage->set(name, x);
 }
 
-Translator::Deserializer
-Translator::initializeDeserializer() {
-    Deserializer result;
-
-    result.emplace(LeafBaseType::Binary, [](string const& value) -> ElementPtr const {
-        return Element::create(decode64(value));
-    });
-
-    for (LeafBaseType const& i :
-         {LeafBaseType::Bool, LeafBaseType::Dec64, LeafBaseType::Int8, LeafBaseType::Int16,
-          LeafBaseType::Int32, LeafBaseType::Int64, LeafBaseType::Uint8, LeafBaseType::Uint16,
-          LeafBaseType::Uint32, LeafBaseType::Uint64}) {
-        result.emplace(i, [](string const& value) -> ElementPtr const {
-            return Element::fromJSON(value);
-        });
-    }
-
-    // The rest of YANG values can be expressed as strings.
-    for (LeafBaseType const& i :
-         {LeafBaseType::Bits, LeafBaseType::Empty, LeafBaseType::Enum, LeafBaseType::IdentityRef,
-          LeafBaseType::InstanceIdentifier, LeafBaseType::Leafref, LeafBaseType::String,
-          LeafBaseType::Union, LeafBaseType::Unknown}) {
-        result.emplace(i, [](string const& value) -> ElementPtr const {
-            return Element::create(value);
-        });
-    }
-
-    return result;
-}
-
-Translator::Serializer
-Translator::initializeSerializer() {
-    Serializer result;
-
-    result.emplace(LeafBaseType::Binary, [](string const& value) -> string const {
-        return encode64(value);
-    });
-
-    // The rest of YANG values can be expressed directly.
-    for (LeafBaseType const& i :
-         {LeafBaseType::Bits, LeafBaseType::Bool, LeafBaseType::Dec64, LeafBaseType::Empty,
-          LeafBaseType::Enum, LeafBaseType::IdentityRef, LeafBaseType::InstanceIdentifier,
-          LeafBaseType::Int8, LeafBaseType::Int16, LeafBaseType::Int32, LeafBaseType::Int64,
-          LeafBaseType::Leafref, LeafBaseType::String, LeafBaseType::Uint8, LeafBaseType::Uint16,
-          LeafBaseType::Uint32, LeafBaseType::Uint64, LeafBaseType::Union, LeafBaseType::Unknown}) {
-        result.emplace(i, [](string const& value) -> string const {
-            return value;
-        });
-    }
-
-    return result;
-}
-
-
 bool Translator::schemaNodeExists(string const& xpath) const {
     Context const& context(session_.getContext());
     try {
@@ -377,5 +304,76 @@ Translator::translateToYang(ConstElementPtr const& element,
     return serializer.at(type)(string_representation);
 }
 
+string
+Translator::decode64(string const& input) {
+    vector<uint8_t> binary;
+    decodeBase64(input, binary);
+    string result;
+    result.resize(binary.size());
+    memmove(&result[0], &binary[0], result.size());
+    return (result);
+}
+
+string
+Translator::encode64(string const& input) {
+    vector<uint8_t> binary;
+    binary.resize(input.size());
+    memmove(&binary[0], input.c_str(), binary.size());
+    return (encodeBase64(binary));
+}
+
+Translator::Deserializer
+Translator::initializeDeserializer() {
+    Deserializer result;
+
+    result.emplace(LeafBaseType::Binary, [](string const& value) -> ElementPtr const {
+        return Element::create(decode64(value));
+    });
+
+    for (LeafBaseType const& i :
+         {LeafBaseType::Bool, LeafBaseType::Dec64, LeafBaseType::Int8, LeafBaseType::Int16,
+          LeafBaseType::Int32, LeafBaseType::Int64, LeafBaseType::Uint8, LeafBaseType::Uint16,
+          LeafBaseType::Uint32, LeafBaseType::Uint64}) {
+        result.emplace(i, [](string const& value) -> ElementPtr const {
+            return Element::fromJSON(value);
+        });
+    }
+
+    // The rest of YANG values can be expressed as strings.
+    for (LeafBaseType const& i :
+         {LeafBaseType::Bits, LeafBaseType::Empty, LeafBaseType::Enum, LeafBaseType::IdentityRef,
+          LeafBaseType::InstanceIdentifier, LeafBaseType::Leafref, LeafBaseType::String,
+          LeafBaseType::Union, LeafBaseType::Unknown}) {
+        result.emplace(i, [](string const& value) -> ElementPtr const {
+            return Element::create(value);
+        });
+    }
+
+    return result;
+}
+
+Translator::Serializer
+Translator::initializeSerializer() {
+    Serializer result;
+
+    result.emplace(LeafBaseType::Binary, [](string const& value) -> string const {
+        return encode64(value);
+    });
+
+    // The rest of YANG values can be expressed directly.
+    for (LeafBaseType const& i :
+         {LeafBaseType::Bits, LeafBaseType::Bool, LeafBaseType::Dec64, LeafBaseType::Empty,
+          LeafBaseType::Enum, LeafBaseType::IdentityRef, LeafBaseType::InstanceIdentifier,
+          LeafBaseType::Int8, LeafBaseType::Int16, LeafBaseType::Int32, LeafBaseType::Int64,
+          LeafBaseType::Leafref, LeafBaseType::String, LeafBaseType::Uint8, LeafBaseType::Uint16,
+          LeafBaseType::Uint32, LeafBaseType::Uint64, LeafBaseType::Union, LeafBaseType::Unknown}) {
+        result.emplace(i, [](string const& value) -> string const {
+            return value;
+        });
+    }
+
+    return result;
+}
+
 }  // namespace yang
 }  // namespace isc
index 1d279d4a77d2f7a2b1eb3ea32198e92c1883c7ce..a6cc09ecb8f372feec2d8b970cc3a58b1d6172d5 100644 (file)
@@ -121,9 +121,9 @@ public:
     /// @param xpath the xpath to the YANG node without the last node
     /// @param name the name of the YANG node which should also match the map
     /// key in the JSON configuration
-    void checkAndJsonifyAndSetLeaf(isc::data::ConstElementPtr const& from,
-                                   std::string const& xpath,
-                                   std::string const& name);
+    void checkAndStringifyAndSetLeaf(isc::data::ConstElementPtr const& from,
+                                     std::string const& xpath,
+                                     std::string const& name);
 
     /// @brief Get an element from given ElementPtr node and set it in sysrepo
     /// at given xpath.
@@ -132,7 +132,7 @@ public:
     /// @param xpath the xpath to the YANG node without the last node
     /// @param name the name of the YANG node which should also match the map
     /// key in the JSON configuration
-    /// @param type the sysrepo node type
+    /// @param type the YANG node type
     void checkAndSetLeaf(isc::data::ConstElementPtr const& from,
                          std::string const& xpath,
                          std::string const& name,
@@ -148,7 +148,7 @@ public:
     /// @param xpath the xpath to the YANG node without the last node
     /// @param name the name of the parameter to be set in storage
     /// @param yang_name the name by which to find the parameter in the YANG data node
-    /// @param type the sysrepo node type
+    /// @param type the YANG node type
     void checkAndSetDivergingLeaf(isc::data::ConstElementPtr const& from,
                                   std::string const& xpath,
                                   std::string const& name,
@@ -158,10 +158,10 @@ public:
     /// @brief Get an element from given ElementPtr node and set it in sysrepo
     /// at given xpath as a leaf-list.
     ///
-    /// @param from the parent configuration node from which to take the value
+    /// @param from the parent configuration node from which to take the values
     /// @param xpath the xpath to the YANG node without the last node
     /// @param name the name of the parameter to be set in storage
-    /// @param type the sysrepo node type
+    /// @param type the YANG node type of the underlying leaf-list nodes
     void checkAndSetLeafList(isc::data::ConstElementPtr const& from,
                              std::string const& xpath,
                              std::string const& name,
@@ -218,13 +218,6 @@ public:
         }
     }
 
-    /// @brief Checks whether a YANG node exists in the schema.
-    ///
-    /// @param xpath the xpath to be checked
-    ///
-    /// @return true if the YANG node exists in the schema, false otherwise
-    bool schemaNodeExists(std::string const& xpath) const;
-
     /// @brief Get a YANG data node found at the given absolute xpath.
     ///
     /// @note This is a computationally expensive operation that makes a lookup in the sysrepo
@@ -325,6 +318,13 @@ public:
                                    std::string const& name,
                                    std::string const& yang_name) const;
 
+    /// @brief Checks whether a YANG node exists in the schema.
+    ///
+    /// @param xpath the xpath to be checked
+    ///
+    /// @return true if the YANG node exists in the schema, false otherwise
+    bool schemaNodeExists(std::string const& xpath) const;
+
     /// @brief Translate and set basic value from JSON to YANG.
     ///
     /// @param xpath The xpath of the basic value.
@@ -341,7 +341,7 @@ public:
     /// @param xpath the xpath to the YANG node without the last node
     /// @param name the name of the YANG node which should also match the map
     /// key in the JSON configuration
-    /// @param type the sysrepo node type
+    /// @param type the YANG node type
     void setMandatoryLeaf(isc::data::ConstElementPtr const& from,
                           std::string const& xpath,
                           std::string const& name,
@@ -355,7 +355,7 @@ public:
     /// @param name the name of the YANG node which should also match the map
     /// key in the JSON configuration
     /// @param yang_name the name by which to find the parameter in the YANG data node
-    /// @param type the sysrepo node type
+    /// @param type the YANG node type
     void setMandatoryDivergingLeaf(isc::data::ConstElementPtr const& from,
                                    std::string const& xpath,
                                    std::string const& name,
index d55cc52cfe7b1b0ef6a69d0983ec14cc40db510c..d93cf9b3417ccc051307d3e94464dfff92ca5c69 100644 (file)
@@ -523,7 +523,7 @@ TranslatorConfig::setServerKeaDhcpCommon(string const& xpath,
 
     checkAndSetLeafList(elem, xpath, "host-reservation-identifiers", LeafBaseType::Enum);
 
-    checkAndJsonifyAndSetLeaf(elem, xpath, "dhcp-queue-control");
+    checkAndStringifyAndSetLeaf(elem, xpath, "dhcp-queue-control");
 
     checkAndSetUserContext(elem, xpath);
 
@@ -596,7 +596,7 @@ TranslatorConfig::setServerKeaDhcpCommon(string const& xpath,
                      << name->stringValue() << "']";
             string const hook_xpath(hook_lib.str());
             setItem(hook_xpath, ElementPtr(), LeafBaseType::Unknown);
-            checkAndJsonifyAndSetLeaf(lib, hook_xpath, "parameters");
+            checkAndStringifyAndSetLeaf(lib, hook_xpath, "parameters");
         }
     }
 
index 9978db6a5edc508db2c362718e14a79ec636b3bf..b2d580b3950733fee79b94efac6132c0470e33ce 100644 (file)
@@ -43,25 +43,75 @@ All translators take a Session pointer (a structure provided by Sysrepo that
 is responsible for maintaining a connection) in constructors and derive from
 the basic / base class and recursively from translators for embedded parts.
 
-@c isc::yang::Translator provides some methods:
+@c isc::yang::Translator provides several public methods:
+
+  - @c isc::yang::Translator::checkAndGet() is able to retrieve a YANG node that
+    can be retrieved through complex logic which is abstracted through a lambda.
+
   - @c isc::yang::Translator::checkAndGetLeaf() is a convenience wrapper
     over @c isc::yang::Translator::getItem().
+
+  - @c isc::yang::Translator::checkAndGetAndJsonifyLeaf() retrieves elements
+    that are strings in the YANG schema, but that require passing through
+    @c isc::data::Element::fromJSON() when translating to ElementPtr.
+
+  - @c isc::yang::Translator::checkAndStringifyAndSetLeaf() does the opposite of
+    @c isc::yang::Translator::checkAndGetAndJsonifyLeaf(). It takes an arbitrary
+    Element and sets it as a YANG string in sysrepo.
+
   - @c isc::yang::Translator::checkAndSetLeaf() is a convenience wrapper
     over @c isc::yang::Translator::setItem().
+
+  - @c isc::yang::Translator::checkAndSetLeafList() is able to push multiple
+    leaf list nodes to the same xpath to form a leaf list.
+
+  - @c isc::yang::Translator::checkAndSetUserContext() is specifically tailored
+    for setting user context in sysrepo. It's use is frequent enough to have
+    earned its own function.
+
   - @c isc::yang::Translator::deleteItem() deletes the data node found at
-    given xpth.
+    given xpath.
+
+  - @c isc::yang::Translator::findXPath() retrieves any data node found at any
+    xpath. It is computationally intensive. Use sparingly.
+
   - @c isc::yang::Translator::forAll() iterates over the node found at
     given xpath and all its descendants and calls the given function.
+
+  - @c isc::yang::Translator::getData() retrieves any data node found at any
+    xpath. The difference from @c isc::yang::Translator::findXPath() is that it
+    does not throw if the data node is not found and instead returns nullopt.
+
   - @c isc::yang::Translator::getItem() retrieves and translates a leaf
-    from YANG to JSON.
+    from YANG to Element.
+
   - @c isc::yang::Translator::getList() retrieves a list from Sysrepo and
-    translates it form YANG to JSON.
-  - @c isc::yang::Translator::setItem() translates a leaf from JSON to
+    translates it form YANG to Element.
+
+  - @c isc::yang::Translator::getMandatoryLeaf() fetches a leaf that is expected
+    to be present in the YANG data node, most of the time a YANG key.
+
+  - @c isc::yang::Translator::schemaNodeExists() checks if an xpath is valid
+    from the YANG schema point of view. Not used anywhere, but it's here to
+    substitute logic that had been previously removed.
+
+  - @c isc::yang::Translator::setItem() translates a leaf from Element to
     YANG and sets it in Sysrepo.
-  - @c isc::yang::Translator::translateFromYang(optional<DataNode>, string) translates a YANG
-    leaf to a JSON node.
+
+  - @c isc::yang::Translator::setMandatoryLeaf() sets a leaf that is expected
+    to be present in the Element node, most of the time a YANG key.
+
+  - @c isc::yang::Translator::translateFromYang(optional<DataNode>, string)
+    translates a YANG leaf to an Element node based on YANG type.
+    All YANG types are explicitly handled.
+
   - @c isc::yang::Translator::translateToYang(ConstElementPtr, LeafBaseType)
-    translates a JSON leaf to a string.
+    translates an Element leaf to a string based on the YANG type.
+    All YANG types are explicitly handled.
+
+Some of these methods have a counterpart that have "Diverging" in their name.
+They are exceptionally used in the case where YANG xpath and Element map key are
+different. This facilitates identifying these diverging nodes.
 
 @section yangTranslatorPool Pool translator
 
@@ -85,8 +135,8 @@ some of them depend on other structures, for instance
 depends on the corresponding list item translator
 @c isc::yang::TranslatorOptionData. This multiple inheritance forms
 a graph with the basic and the configuration translators at the two ends.
-Multiple inheritance and its "diamond" issue are handled by C++ with
-the "virtual" inheritance: depending classes must be virtually inherited
+Multiple inheritance and its diamond issue are handled by C++ with
+the virtual inheritance: depending classes must be virtually inherited
 and explicitly constructed.
 
 @section yangTranslatorSubnet Subnet translator