Add support for executing RPCs
Creating a temporary YangAccess for RPC input means I need to somehow
give the right libyang schemas. For that reason I supply a callable
which is able to fetch the schema and create a YangAccess instance for
ProxyDatastore.
The ProxyDatastore class now has a simple mechanism for deciding whether
to use the normal datastore and the temporary based on a path prefix.
Change-Id: Ib455f53237598bc2620161a44fb89c48ddfeb6e3
diff --git a/src/interpreter.cpp b/src/interpreter.cpp
index 5ff73e7..26e2be4 100644
--- a/src/interpreter.cpp
+++ b/src/interpreter.cpp
@@ -30,6 +30,26 @@
}
};
+namespace {
+void printTree(const DatastoreAccess::Tree tree)
+{
+ for (auto it = tree.begin(); it != tree.end(); it++) {
+ auto [path, value] = *it;
+ if (value.type() == typeid(special_) && boost::get<special_>(value).m_value == SpecialValue::LeafList) {
+ auto leafListPrefix = path;
+ std::cout << path << " = " << leafDataToString(value) << std::endl;
+
+ while (it + 1 != tree.end() && boost::starts_with((it + 1)->first, leafListPrefix)) {
+ ++it;
+ std::cout << stripLeafListValueFromPath(it->first) << " = " << leafDataToString(it->second) << std::endl;
+ }
+ } else {
+ std::cout << path << " = " << leafDataToString(value) << std::endl;
+ }
+ }
+}
+}
+
template <typename PathType>
std::string pathToString(const PathType& path)
{
@@ -64,20 +84,7 @@
void Interpreter::operator()(const get_& get) const
{
auto items = m_datastore.getItems(pathToString(toCanonicalPath(get.m_path)));
- for (auto it = items.begin(); it != items.end(); it++) {
- auto [path, value] = *it;
- if (value.type() == typeid(special_) && boost::get<special_>(value).m_value == SpecialValue::LeafList) {
- auto leafListPrefix = path;
- std::cout << path << " = " << leafDataToString(value) << std::endl;
-
- while (it + 1 != items.end() && boost::starts_with((it + 1) ->first, leafListPrefix)) {
- ++it;
- std::cout << stripLeafListValueFromPath(it->first) << " = " << leafDataToString(it->second) << std::endl;
- }
- } else {
- std::cout << path << " = " << leafDataToString(value) << std::endl;
- }
- }
+ printTree(items);
}
void Interpreter::operator()(const cd_& cd) const
@@ -162,12 +169,14 @@
case yang::NodeTypes::List:
ss << "list";
break;
+ case yang::NodeTypes::Rpc:
+ ss << "RPC";
+ break;
case yang::NodeTypes::Action:
case yang::NodeTypes::AnyXml:
case yang::NodeTypes::LeafList:
case yang::NodeTypes::Notification:
- case yang::NodeTypes::Rpc:
- throw std::logic_error("describe got an rpc or an action: this should never happen, because their paths cannot be parsed");
+ throw std::logic_error("describe can't handle the type of " + path);
}
if (!m_datastore.schema()->isConfig(path)) {
@@ -201,6 +210,26 @@
std::cout << m_datastore.dump(dump.m_format) << "\n";
}
+void Interpreter::operator()(const rpc_& rpc) const
+{
+ m_datastore.initiateRpc(pathToString(toCanonicalPath(rpc.m_path)));
+ m_parser.changeNode(rpc.m_path);
+}
+
+void Interpreter::operator()(const exec_&) const
+{
+ m_parser.changeNode({Scope::Absolute, {}});
+ auto output = m_datastore.executeRpc();
+ std::cout << "RPC output:\n";
+ printTree(output);
+}
+
+void Interpreter::operator()(const cancel_&) const
+{
+ m_parser.changeNode({Scope::Absolute, {}});
+ m_datastore.cancelRpc();
+}
+
struct commandLongHelpVisitor : boost::static_visitor<const char*> {
template <typename T>
auto constexpr operator()(boost::type<T>) const