Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# .clang-format
BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4
UseTab: Never

BreakBeforeBraces: Allman # Open braces on a new line
AllowShortIfStatementsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline

ColumnLimit: 100 # Max line length (can be 80, 100, or more)
PointerAlignment: Right # `int* ptr` vs `int *ptr`

IncludeBlocks: Preserve
SortIncludes: true

SpacesBeforeTrailingComments: 1
SpaceBeforeParens: ControlStatements

Cpp11BracedListStyle: true
57 changes: 44 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CmakeModules")
find_package(PkgConfig) #official cmake module
find_package(Boost REQUIRED log system chrono) #just boost log, system and chrono libraries

pkg_check_modules(GTEST REQUIRED gtest)
find_package(absl REQUIRED)
find_package(Protobuf REQUIRED)
find_package(gRPC CONFIG REQUIRED)

pkg_check_modules(SYSREPOC REQUIRED sysrepo>=2.2.14 IMPORTED_TARGET)

pkg_check_modules(LIBYANGC REQUIRED libyang)
Expand Down Expand Up @@ -57,19 +62,32 @@ add_subdirectory(proto)
# Generate a compile_commands.json with compile options
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)

set(GNXI_SRC src/security/authentication.cpp
src/utils/log.cpp
src/utils/sysrepo.cpp
src/gnmi/gnmi.cpp
src/gnmi/gnmi_server.cpp
set(GNXI_SRC src/gnmi/encode/encode.cpp
src/gnmi/encode/json_ietf.cpp
src/gnmi/capabilities.cpp
src/gnmi/confirm.cpp
src/gnmi/get.cpp
src/gnmi/gnmi_server.cpp
src/gnmi/gnmi.cpp
src/gnmi/rpc.cpp
src/gnmi/set.cpp
src/gnmi/subscribe.cpp
src/gnmi/confirm.cpp
src/gnmi/encode/encode.cpp
src/gnmi/encode/json_ietf.cpp
src/security/authentication.cpp
src/utils/log.cpp
src/utils/sysrepo.cpp
)

set(GNXI_HEADERS src/gnmi/encode/encode.h
src/gnmi/confirm.h
src/gnmi/get.h
src/gnmi/gnmi.h
src/gnmi/rpc.h
src/gnmi/set.h
src/gnmi/subscribe.h
src/security/authentication.h
src/utils/log.h
src/utils/sysrepo.h
src/utils/utils.h
)

add_executable(gnxi_server ${GNXI_SRC} src/main.cpp)
Expand Down Expand Up @@ -107,20 +125,22 @@ target_link_libraries(gnxi_server gnmi
${SYSREPOC_LIBRARIES}
${LIBYANG_LIBRARIES}
${LIBYANGC_LIBRARIES}
gRPC::grpc++
${Protobuf_LIBRARIES}
)

# TEST
######
# TESTS
#######

enable_testing()

set(GNXI_TEST_SRC tests/main.cpp
tests/capabilities.cpp
set(GNXI_TEST_SRC tests/capabilities.cpp
tests/get.cpp
tests/main.cpp
tests/rpc.cpp
tests/set.cpp
tests/subscribe.cpp
)
)

add_executable(gnxi_server_test ${GNXI_TEST_SRC} ${GNXI_SRC})
configure_file(scripts/gnxi-server-logrotate gnxi-server-logrotate COPYONLY)
Expand Down Expand Up @@ -162,6 +182,8 @@ target_link_libraries(gnxi_server_test gnmi
${LIBYANGC_LIBRARIES}
${SYSTEMD_LIBRARIES}
gcov
gRPC::grpc++
${Protobuf_LIBRARIES}
)

# Remove test files and auto-generated files from coverage report
Expand All @@ -176,3 +198,12 @@ install(TARGETS gnxi_server
RUNTIME DESTINATION sbin
DESTINATION ${CMAKE_INSTALL_SBINDIR}
)

# FORMAT
########

add_custom_target(format
COMMAND clang-format -i ${GNXI_HEADERS} ${GNXI_SRC} ${GNXI_TEST_SRC}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Formatting header and source files."
USES_TERMINAL)
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ Supported RPCs:
* [X] Set
* [X] Get
* [X] Subscribe
* [X] Rpc
* [X] Confirm
* [X] Rpc (defined in proto/gnmi.proto)
* [X] Confirm (defined in proto/gnmi.proto)

Supported encoding:

Expand All @@ -32,16 +32,16 @@ Supported authentication/encryption methods:

# Dependencies

```
sysrepo-gnxi
+-- protobuf (>=3.0) #because of gnmi
+-- jsoncpp #because of get JSON
+-- grpc (cpp) (>=1.18.0) #because of TLS bug to verify client cert
+-- libyang-cpp
+-- sysrepo-cpp
| +-- libyang
| +-- sysrepo
```
- C++20 compiler
- cmake >= 3.18.1
- protobuf >= v31.1
- grpc (cpp) (>=1.18.0) #because of TLS bug to verify client cert
- libyang-cpp (master branch)
- sysrepo-cpp (master branch)
- libyang (devel branch)
- sysrepo (devel branch)

## Optional dependencies

You can either install dependencies from sources or from the packages.

Expand Down
2 changes: 1 addition & 1 deletion proto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
# gRPC 1.12.0 will compile but to prevent a security bug, use 1.18.0
# We leverage grpc pkg-config files in /usr/local/lib/pkgconfig
find_package(PkgConfig REQUIRED)
pkg_check_modules(grpc++ REQUIRED grpc++>=1.18.0)
#find_package(grpc-cpp REQUIRED)

# GENERATION OF SOURCE FILES
############################
Expand Down
89 changes: 43 additions & 46 deletions src/gnmi/capabilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,59 +15,56 @@
* limitations under the License.
*/

#include "gnmi.h"
#include <utils/log.h>
#include <proto/gnmi.grpc.pb.h>

using namespace gnmi;
using namespace std;
using google::protobuf::FileOptions;
#include "gnmi.h"
#include "utils/log.h"

Status GNMIService::Capabilities(ServerContext *context,
const CapabilityRequest* request,
CapabilityResponse* response)
grpc::Status GNMIService::Capabilities(grpc::ServerContext *context,
const gnmi::CapabilityRequest *request,
gnmi::CapabilityResponse *response)
{
(void)context;
string gnmi_version;
FileOptions fopts;
(void)context;
std::string gnmi_version;
google::protobuf::FileOptions fopts;

if (request->extension_size() > 0) {
BOOST_LOG_TRIVIAL(error) << "Extensions not implemented";
return Status(StatusCode::UNIMPLEMENTED, "Extensions not implemented");
}

try {
auto sess = sr_con.sessionStart();
auto node = sess.getModuleInfo();
for (auto mod_node : node.child()->siblings()) {
auto model = response->add_supported_models();
for (auto mod_value_node = mod_node.child(); mod_value_node.has_value();
mod_value_node = mod_value_node.value().nextSibling()) {
if (!mod_value_node->schema().name().compare("name")) {
auto name = std::string(mod_value_node->asTerm().valueStr());
model->set_name(name);
}
if (!mod_value_node->schema().name().compare("revision")) {
auto version = std::string(mod_value_node->asTerm().valueStr());
model->set_version(version);
}
}
if (request->extension_size() > 0)
{
BOOST_LOG_TRIVIAL(error) << "Extensions not implemented";
return grpc::Status(grpc::StatusCode::UNIMPLEMENTED, "Extensions not implemented");
}

gnmi_version = response->GetDescriptor()->file()->options()
.GetExtension(gnmi::gnmi_service);
response->set_gnmi_version(gnmi_version);
try
{
auto sess = sr_con.sessionStart();

//Encoding used in TypedValue for responses
//response->add_supported_encodings(gnmi::Encoding::JSON);
//response->add_supported_encodings(gnmi::Encoding::BYTES);
//response->add_supported_encodings(gnmi::Encoding::PROTO);
//response->add_supported_encodings(gnmi::Encoding::ASCII);
response->add_supported_encodings(gnmi::Encoding::JSON_IETF);
for (auto module : sess.getContext().modules())
{
if (module.implemented())
{
auto model = response->add_supported_models();
model->set_name(module.name());
model->set_organization(module.org().value_or(""));
model->set_version(module.revision().value_or(""));
}
}

gnmi_version =
response->GetDescriptor()->file()->options().GetExtension(gnmi::gnmi_service);
response->set_gnmi_version(gnmi_version);

} catch (const exception &exc) {
BOOST_LOG_TRIVIAL(error) << exc.what();
return Status(StatusCode::INTERNAL, "Fail getting schemas");
}
// Encoding used in TypedValue for responses
// response->add_supported_encodings(gnmi::Encoding::JSON);
// response->add_supported_encodings(gnmi::Encoding::BYTES);
// response->add_supported_encodings(gnmi::Encoding::PROTO);
// response->add_supported_encodings(gnmi::Encoding::ASCII);
response->add_supported_encodings(gnmi::Encoding::JSON_IETF);
}
catch (const std::exception &exc)
{
BOOST_LOG_TRIVIAL(error) << exc.what();
return grpc::Status(grpc::StatusCode::INTERNAL, "Fail getting schemas");
}

return Status::OK;
return grpc::Status::OK;
}
Loading