2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 05:55:28 +00:00

[#2601] update YANG developer guide

This commit is contained in:
Andrei Pavel
2022-11-08 12:02:29 +02:00
committed by Razvan Becheriu
parent e4e9d0e362
commit 13142fea93
4 changed files with 152 additions and 104 deletions

View 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

View 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,

View 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");
}
}

View 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