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:
committed by
Razvan Becheriu
parent
e4e9d0e362
commit
13142fea93
@@ -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
|
||||
|
@@ -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,
|
||||
|
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user