Unverified Commit 4a7a3b3b authored by jean-christophe81's avatar jean-christophe81 Committed by GitHub
Browse files

MON-12394_MON-12695 backport (#53)

parent a2c204d4
......@@ -11,7 +11,6 @@ set(CONNECTOR_VERSION "${CONNECTOR_MAJOR}.${CONNECTOR_MINOR}.${CONNECTOR_PATCH}"
add_definitions(-DCENTREON_CONNECTOR_VERSION=\"${CONNECTOR_VERSION}\")
include(${CMAKE_SOURCE_DIR}/cmake/Findclib.cmake)
#include(${CMAKE_SOURCE_DIR}/cmake/FindSSH.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/Findperl.cmake)
include(${CMAKE_BINARY_DIR}/conan_paths.cmake)
......@@ -19,8 +18,11 @@ include(${CMAKE_BINARY_DIR}/conan_paths.cmake)
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
find_package(asio REQUIRED)
find_package(Boost 1.78.0 REQUIRED)
find_package(absl REQUIRED)
find_package(Boost REQUIRED)
find_package(Libssh2 REQUIRED)
find_package(OpenSSL REQUIRED)
find_package(ZLIB REQUIRED)
add_definitions(${spdlog_DEFINITIONS})
......@@ -28,9 +30,9 @@ add_definitions(${spdlog_DEFINITIONS})
include_directories(${fmt_INCLUDE_DIRS})
include_directories(${spdlog_INCLUDE_DIRS})
include_directories(${asio_INCLUDE_DIRS})
include_directories(${absl_INCLUDE_DIRS})
include_directories(${Boost_INCLUDE_DIRS})
# Generate code to dynamically load modules.
add_custom_command(OUTPUT "${CMAKE_SOURCE_DIR}/perl/src/xs_init.cc"
COMMAND "${PERL_EXECUTABLE}" "-MExtUtils::Embed" "-e" "xsinit" "--" "-o" "${CMAKE_SOURCE_DIR}/perl/src/xs_init.cc")
......@@ -64,38 +66,40 @@ if (WITH_TESTING)
include_directories(${CMAKE_SOURCE_DIR}/perl/inc)
include_directories(${CMAKE_SOURCE_DIR}/ssh/inc)
include_directories(${Libssh2_INCLUDE_DIR})
add_definitions(-DBUILD_PATH="${CMAKE_BINARY_DIR}")
add_executable(ut
# Core sources
${CMAKE_SOURCE_DIR}/perl/src/embedded_perl.cc
${CMAKE_SOURCE_DIR}/common/src/log.cc
${CMAKE_SOURCE_DIR}/perl/src/pipe_handle.cc
${CMAKE_SOURCE_DIR}/perl/src/script.cc
${CMAKE_SOURCE_DIR}/perl/src/xs_init.cc
${CMAKE_SOURCE_DIR}/ssh/src/checks/check.cc
${CMAKE_SOURCE_DIR}/ssh/src/checks/result.cc
${CMAKE_SOURCE_DIR}/ssh/src/orders/options.cc
${CMAKE_SOURCE_DIR}/ssh/src/orders/parser.cc
${CMAKE_SOURCE_DIR}/ssh/src/sessions/credentials.cc
${CMAKE_SOURCE_DIR}/ssh/src/sessions/session.cc
${CMAKE_SOURCE_DIR}/ssh/src/reporter.cc
${PROJECT_SOURCE_DIR}/perl/src/embedded_perl.cc
${PROJECT_SOURCE_DIR}/common/src/log.cc
${PROJECT_SOURCE_DIR}/common/src/result.cc
${PROJECT_SOURCE_DIR}/common/src/reporter.cc
${PROJECT_SOURCE_DIR}/common/src/parser.cc
${PROJECT_SOURCE_DIR}/perl/src/checks/check.cc
${PROJECT_SOURCE_DIR}/perl/src/script.cc
${PROJECT_SOURCE_DIR}/perl/src/xs_init.cc
${PROJECT_SOURCE_DIR}/ssh/src/checks/check.cc
${PROJECT_SOURCE_DIR}/ssh/src/orders/options.cc
${PROJECT_SOURCE_DIR}/ssh/src/orders/parser.cc
${PROJECT_SOURCE_DIR}/ssh/src/sessions/credentials.cc
${PROJECT_SOURCE_DIR}/ssh/src/sessions/session.cc
# Test sources.
${CMAKE_SOURCE_DIR}/perl/test/main.cc
${CMAKE_SOURCE_DIR}/perl/test/connector.cc
${CMAKE_SOURCE_DIR}/perl/test/embedded_perl.cc
${CMAKE_SOURCE_DIR}/ssh/test/buffer_handle.cc
${CMAKE_SOURCE_DIR}/ssh/test/checks.cc
${CMAKE_SOURCE_DIR}/ssh/test/connector.cc
${CMAKE_SOURCE_DIR}/ssh/test/fake_listener.cc
${CMAKE_SOURCE_DIR}/ssh/test/orders.cc
${CMAKE_SOURCE_DIR}/ssh/test/reporter.cc
${CMAKE_SOURCE_DIR}/ssh/test/sessions.cc
${PROJECT_SOURCE_DIR}/perl/test/main.cc
${PROJECT_SOURCE_DIR}/perl/test/connector.cc
${PROJECT_SOURCE_DIR}/perl/test/embedded_perl.cc
${PROJECT_SOURCE_DIR}/ssh/test/buffer_handle.cc
${PROJECT_SOURCE_DIR}/ssh/test/checks.cc
${PROJECT_SOURCE_DIR}/ssh/test/connector.cc
${PROJECT_SOURCE_DIR}/ssh/test/fake_listener.cc
${PROJECT_SOURCE_DIR}/ssh/test/orders.cc
${PROJECT_SOURCE_DIR}/ssh/test/reporter.cc
${PROJECT_SOURCE_DIR}/ssh/test/sessions.cc
)
target_precompile_headers(ut PRIVATE ${CMAKE_SOURCE_DIR}/ssh/precomp_inc/precomp.hh)
target_link_libraries(ut ${GTest_LIBS} ${CLIB_LIBRARIES} ${PERL_LIBRARIES} ${fmt_LIBS} ${spdlog_LIBS} ${Libssh2_LIBRARIES})
target_link_libraries(ut ${GTest_LIBS} ${CLIB_LIBRARIES} ${PERL_LIBRARIES} ${fmt_LIBS} ${spdlog_LIBS} ${absl_LIBS} ${Libssh2_LIBS} ${OpenSSL_LIBS} ${ZLIB_LIBS} pthread dl)
file(COPY ${CMAKE_SOURCE_DIR}/test/test_pattern DESTINATION ${CMAKE_BINARY_DIR})
endif (WITH_TESTING)
/*
* Copyright 2022 Centreon (https://www.centreon.com/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* For more information : contact@centreon.com
*
*/
#ifndef CONNECTORS_INC_COM_CENTREON_CONNECTOR_IPOLICY_H_
#define CONNECTORS_INC_COM_CENTREON_CONNECTOR_IPOLICY_H_
#include "namespace.hh"
CCC_BEGIN()
namespace orders {
class options;
}
class policy_interface : public std::enable_shared_from_this<policy_interface> {
public:
virtual ~policy_interface() = default;
virtual void on_eof() = 0;
virtual void on_error(uint64_t cmd_id, const std::string& msg) = 0;
virtual void on_execute(uint64_t cmd_id,
const time_point& timeout,
const std::shared_ptr<orders::options>& opt) = 0;
virtual void on_quit() = 0;
virtual void on_version() = 0;
};
CCC_END()
#endif
/*
* Copyright 2020 Centreon (https://www.centreon.com/)
* Copyright 2022 Centreon (https://www.centreon.com/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -19,11 +19,6 @@
#ifndef CONNECTORS_PERL_INC_COM_CENTREON_CONNECTOR_PERL_LOG_H_
#define CONNECTORS_PERL_INC_COM_CENTREON_CONNECTOR_PERL_LOG_H_
#include <spdlog/common.h>
#include <spdlog/spdlog.h>
#include <memory>
#include "com/centreon/connector/namespace.hh"
CCC_BEGIN();
......@@ -37,6 +32,7 @@ class log {
public:
static log& instance();
void add_pid_to_log();
void set_level(spdlog::level::level_enum level);
void switch_to_stdout();
void switch_to_file(std::string const& filename);
......
/*
** Copyright 2011-2013 Centreon
** Copyright 2022 Centreon
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
......@@ -16,41 +16,61 @@
** For more information : contact@centreon.com
*/
#ifndef CCCP_REPORTER_HH
#define CCCP_REPORTER_HH
#ifndef CCC_ORDERS_PARSER_HH
#define CCC_ORDERS_PARSER_HH
#include <string>
#include "com/centreon/connector/namespace.hh"
#include "com/centreon/connector/perl/checks/listener.hh"
#include "com/centreon/connector/perl/namespace.hh"
#include "com/centreon/handle_listener.hh"
CCC_BEGIN()
CCCP_BEGIN()
class policy_interface;
constexpr unsigned parser_buff_size = 4096;
/**
* @class reporter reporter.hh "com/centreon/connector/perl/reporter.hh"
* @brief Report data back to the monitoring engine.
* @class parser parser.hh "com/centreon/connector/ssh/orders/parser.hh"
* @brief Parse orders.
*
* Send replies to the monitoring engine.
* Parse orders, generally issued by the monitoring engine. The
* parser class can handle be registered with one handle at a time
* and one listener.
*/
class reporter : public com::centreon::handle_listener {
class parser : public std::enable_shared_from_this<parser> {
protected:
shared_io_context _io_context;
asio::posix::stream_descriptor _sin;
std::string _buffer;
bool _can_report;
unsigned int _reported;
bool _dont_care_about_stdin_eof;
std::shared_ptr<policy_interface> _owner;
char _recv_buff[parser_buff_size];
void read();
void _parse(std::string const& cmd);
parser(const shared_io_context& io_context,
const std::shared_ptr<policy_interface>& policy);
virtual void start_read();
void read_file(const std::string& test_file_path);
void read_handler(const std::error_code& error,
std::size_t bytes_transferred);
virtual void execute(const std::string& cmd) = 0;
public:
reporter();
~reporter() noexcept override;
reporter(reporter const& r) = delete;
reporter& operator=(reporter const& r) = delete;
bool can_report() const noexcept;
void error(handle& h) override;
void send_result(checks::result const& r);
void send_version(unsigned int major, unsigned int minor);
bool want_write(handle& h) override;
void write(handle& h) override;
using pointer = std::shared_ptr<parser>;
static const std::error_code eof_err; // used by test
virtual ~parser() = default;
parser(parser const& p) = delete;
parser& operator=(parser const& p) = delete;
};
CCCP_END()
CCC_END()
#endif // !CCCP_REPORTER_HH
#endif // !CCC_ORDERS_PARSER_HH
/*
** Copyright 2011-2013 Centreon
** Copyright 2022 Centreon
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
......@@ -16,13 +16,13 @@
** For more information : contact@centreon.com
*/
#ifndef CCCS_REPORTER_HH
#define CCCS_REPORTER_HH
#ifndef CCC_REPORTER_HH
#define CCC_REPORTER_HH
#include "com/centreon/connector/ssh/checks/result.hh"
#include "com/centreon/connector/ssh/namespace.hh"
#include "com/centreon/connector/namespace.hh"
#include "com/centreon/connector/result.hh"
CCCS_BEGIN()
CCC_BEGIN()
/**
* @class reporter reporter.hh "com/centreon/connector/ssh/reporter.hh"
......@@ -51,13 +51,13 @@ class reporter : public std::enable_shared_from_this<reporter> {
reporter& operator=(reporter const& r) = delete;
bool can_report() const { return _can_report; };
void error();
void send_result(checks::result const& r);
void send_result(result const& r);
void send_version(unsigned int major, unsigned int minor);
virtual void write();
const std::string& get_buffer() const { return *_buffer; }
};
CCCS_END()
CCC_END()
#endif // !CCCS_REPORTER_HH
#endif // !CCC_REPORTER_HH
/*
** Copyright 2011-2013 Centreon
** Copyright 2022 Centreon
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
......@@ -16,15 +16,13 @@
** For more information : contact@centreon.com
*/
#ifndef CCCS_CHECKS_RESULT_HH
#define CCCS_CHECKS_RESULT_HH
#ifndef CCC_CHECKS_RESULT_HH
#define CCC_CHECKS_RESULT_HH
#include <string>
#include "com/centreon/connector/ssh/namespace.hh"
#include "com/centreon/connector/namespace.hh"
CCCS_BEGIN()
CCC_BEGIN()
namespace checks {
/**
* @class result result.hh "com/centreon/connector/ssh/checks/result.hh"
* @brief Check result.
......@@ -63,8 +61,7 @@ class result {
int _exit_code;
std::string _output;
};
} // namespace checks
CCCS_END()
CCC_END()
#endif // !CCCS_CHECKS_RESULT_HH
#endif // !CCC_CHECKS_RESULT_HH
/*
* Copyright 2020 Centreon (https://www.centreon.com/)
* Copyright 2022 Centreon (https://www.centreon.com/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -32,8 +32,7 @@ log::log() {
_core_log->flush_on(spdlog::level::trace);
}
log::~log() {
}
log::~log() {}
com::centreon::connector::log& log::instance() {
static log instance;
......@@ -46,6 +45,10 @@ void log::set_level(spdlog::level::level_enum level) {
_core_log->flush_on(level);
}
void log::add_pid_to_log() {
_core_log->set_pattern("%P %+");
}
void log::switch_to_stdout() {
auto filesink = std::make_shared<spdlog::sinks::stderr_color_sink_mt>();
spdlog::level::level_enum lvl = _core_log->level();
......@@ -66,4 +69,4 @@ void log::switch_to_file(std::string const& filename) {
std::shared_ptr<spdlog::logger> log::core() {
return log::instance()._core_log;
}
\ No newline at end of file
}
/*
** Copyright 2022 Centreon
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
** For more information : contact@centreon.com
*/
#include "com/centreon/connector/parser.hh"
#include "com/centreon/connector/ipolicy.hh"
#include "com/centreon/connector/log.hh"
#include "com/centreon/exceptions/basic.hh"
using namespace com::centreon::connector;
parser::parser(const shared_io_context& io_context,
const std::shared_ptr<policy_interface>& policy)
: _io_context(io_context),
_sin(*io_context, dup(STDIN_FILENO)),
_dont_care_about_stdin_eof(false),
_owner(policy) {}
void parser::start_read() {
log::core()->debug("reading data for parsing");
_sin.async_read_some(
asio::buffer(_recv_buff, parser_buff_size),
[me = shared_from_this()](const std::error_code& error,
std::size_t bytes_transferred) {
me->read_handler(error, bytes_transferred);
});
}
void parser::read_file(const std::string& test_file_path) {
std::ifstream file(test_file_path);
std::stringstream ss;
ss << file.rdbuf();
_buffer = ss.str();
read();
}
const std::error_code parser::eof_err(asio::error::eof,
asio::error::get_misc_category());
void parser::read_handler(const std::error_code& error,
std::size_t bytes_transferred) {
if (_dont_care_about_stdin_eof) {
return;
}
if (error) {
if (error == eof_err) { // stdin's eof is reached.
log::core()->debug("got eof on read handle");
_owner->on_eof();
return;
}
log::core()->error("fail to read from stdin {}:{} {}", error.value(),
error.category().name(), error.message());
_owner->on_error(0, "error on handle");
_io_context->stop();
return;
}
_buffer.append(_recv_buff, bytes_transferred);
read();
start_read();
}
/**
* Read data
*
*/
void parser::read() {
// Find a command boundary.
constexpr char boundary[4]{0, 0, 0, 0};
size_t bound(_buffer.find(boundary, 0, sizeof(boundary)));
// Parse command.
while (bound != std::string::npos) {
log::core()->debug("got command boundary at offset {}", bound);
bound += sizeof(boundary);
std::string cmd(_buffer.substr(0, bound));
_buffer.erase(0, bound);
std::string error_msg;
try {
_parse(cmd);
} catch (std::exception const& e) {
error_msg = "orders parsing error: ";
error_msg.append(e.what());
log::core()->error("{}", error_msg);
_owner->on_error(0, error_msg);
} catch (...) {
error_msg = "unknown orders parsing error";
log::core()->error("{}", error_msg);
_owner->on_error(0, error_msg);
}
bound = _buffer.find(boundary, 0, sizeof(boundary));
}
}
/**************************************
* *
* Private Methods *
* *
**************************************/
/**
* @brief Parse a command.
*
* It is the caller's responsibility to ensure that the command given
* to parse is terminated with 4 \0.
*
* @param[in] cmd Command to parse.
*/
void parser::_parse(std::string const& cmd) {
// Get command ID.
size_t pos(cmd.find('\0'));
unsigned int id(strtoul(cmd.c_str(), nullptr, 10));
++pos;
log::core()->debug("receive cmd {}", id);
// Process each command as necessary.
switch (id) {
case 0: // Version query.
_owner->on_version();
break;
case 2: // Execute query.
execute(cmd.substr(pos));
break;
case 4: // Quit query.
_owner->on_quit();
break;
case 10: // dont care about stdin eof any more
_dont_care_about_stdin_eof = true;
break;
default:
throw basic_error() << "invalid command received (ID " << id << ")";
};
}
/*
** Copyright 2011-2013 Centreon
** Copyright 2022 Centreon
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
......@@ -16,15 +16,12 @@
** For more information : contact@centreon.com
*/
#include "com/centreon/connector/ssh/reporter.hh"
#include <sstream>
#include "com/centreon/connector/reporter.hh"
#include "com/centreon/connector/log.hh"
#include "com/centreon/connector/ssh/checks/result.hh"
#include "com/centreon/exceptions/basic.hh"
#include "com/centreon/connector/result.hh"
using namespace com::centreon::connector::ssh;
using namespace com::centreon::connector;
/**************************************
* *
......@@ -69,7 +66,7 @@ void reporter::error() {
*
* @param[in] r Check result.
*/
void reporter::send_result(checks::result const& r) {
void reporter::send_result(result const& r) {
// Update statistics.
++_reported;
log::core()->debug(
......
/*
** Copyright 2011-2013 Centreon
** Copyright 2022 Centreon
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
......@@ -16,9 +16,9 @@
** For more information : contact@centreon.com
*/
#include "com/centreon/connector/ssh/checks/result.hh"
#include "com/centreon/connector/result.hh"
using namespace com::centreon::connector::ssh::checks;
using namespace com::centreon::connector;
/**************************************
* *
......
......@@ -5,6 +5,7 @@ spdlog/1.8.5
asio/1.21.0
boost/1.78.0
libssh2/1.10.0
abseil/20211102.0
[generators]
cmake_paths
......
......@@ -24,37 +24,34 @@ include_directories(${CMAKE_SOURCE_DIR}/perl/inc/)
# Perl connector.
add_executable(centreon_connector_perl
# Sources.
${CMAKE_SOURCE_DIR}/common/src/log.cc
${CMAKE_SOURCE_DIR}/perl/src/main.cc
${CMAKE_SOURCE_DIR}/perl/src/checks/check.cc
${CMAKE_SOURCE_DIR}/perl/src/checks/result.cc
${CMAKE_SOURCE_DIR}/perl/src/checks/timeout.cc
${CMAKE_SOURCE_DIR}/perl/src/embedded_perl.cc
${CMAKE_SOURCE_DIR}/perl/src/multiplexer.cc
${CMAKE_SOURCE_DIR}/perl/src/options.cc
${CMAKE_SOURCE_DIR}/perl/src/orders/parser.cc
${CMAKE_SOURCE_DIR}/perl/src/pipe_handle.cc
${CMAKE_SOURCE_DIR}/perl/src/policy.cc
${CMAKE_SOURCE_DIR}/perl/src/reporter.cc
${CMAKE_SOURCE_DIR}/perl/src/script.cc
${CMAKE_SOURCE_DIR}/perl/src/xs_init.cc
${PROJECT_SOURCE_DIR}/common/src/log.cc
${PROJECT_SOURCE_DIR}/common/src/reporter.cc
${PROJECT_SOURCE_DIR}/common/src/result.cc
${PROJECT_SOURCE_DIR}/common/src/parser.cc
${PROJECT_SOURCE_DIR}/perl/src/main.cc
${PROJECT_SOURCE_DIR}/perl/src/checks/check.cc
${PROJECT_SOURCE_DIR}/perl/src/embedded_perl.cc
${PROJECT_SOURCE_DIR}/perl/src/options.cc
${PROJECT_SOURCE_DIR}/perl/src/orders/parser.cc
${PROJECT_SOURCE_DIR}/perl/src/policy.cc
${PROJECT_SOURCE_DIR}/perl/src/script.cc
${PROJECT_SOURCE_DIR}/perl/src/xs_init.cc
# Headers.
${CMAKE_SOURCE_DIR}/perl/inc/com/centreon/connector/perl/checks/check.hh
${CMAKE_SOURCE_DIR}/perl/inc/com/centreon/connector/perl/checks/listener.hh
${CMAKE_SOURCE_DIR}/perl/inc/com/centreon/connector/perl/checks/result.hh
${CMAKE_SOURCE_DIR}/perl/inc/com/centreon/connector/perl/checks/timeout.hh
${CMAKE_SOURCE_DIR}/perl/inc/com/centreon/connector/perl/embedded_perl.hh
${CMAKE_SOURCE_DIR}/perl/inc/com/centreon/connector/perl/multiplexer.hh