LCOV - code coverage report
Current view: top level - source/common/upstream - health_checker_impl.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 22 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 12 0.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <cstdint>
       4             : 
       5             : #include "envoy/access_log/access_log.h"
       6             : #include "envoy/api/api.h"
       7             : #include "envoy/common/random_generator.h"
       8             : #include "envoy/config/core/v3/health_check.pb.h"
       9             : #include "envoy/data/core/v3/health_check_event.pb.h"
      10             : #include "envoy/grpc/status.h"
      11             : #include "envoy/network/socket.h"
      12             : #include "envoy/server/factory_context.h"
      13             : #include "envoy/server/health_checker_config.h"
      14             : #include "envoy/type/v3/http.pb.h"
      15             : #include "envoy/type/v3/range.pb.h"
      16             : #include "envoy/upstream/health_checker.h"
      17             : 
      18             : #include "source/common/common/dump_state_utils.h"
      19             : #include "source/common/common/logger.h"
      20             : #include "source/common/grpc/codec.h"
      21             : #include "source/common/http/codec_client.h"
      22             : #include "source/common/router/header_parser.h"
      23             : #include "source/common/stream_info/stream_info_impl.h"
      24             : #include "source/common/upstream/health_checker_event_logger.h"
      25             : 
      26             : #include "src/proto/grpc/health/v1/health.pb.h"
      27             : 
      28             : namespace Envoy {
      29             : namespace Upstream {
      30             : 
      31             : constexpr uint64_t kDefaultMaxBytesInBuffer = 1024;
      32             : 
      33             : /**
      34             :  * HealthCheckerHash and HealthCheckerEqualTo are used to allow the HealthCheck proto to be used as
      35             :  * a flat_hash_map key.
      36             :  */
      37             : struct HealthCheckerHash {
      38           0 :   size_t operator()(const envoy::config::core::v3::HealthCheck& health_check) const {
      39           0 :     return MessageUtil::hash(health_check);
      40           0 :   }
      41             : };
      42             : 
      43             : struct HealthCheckerEqualTo {
      44             :   bool operator()(const envoy::config::core::v3::HealthCheck& lhs,
      45           0 :                   const envoy::config::core::v3::HealthCheck& rhs) const {
      46           0 :     return Protobuf::util::MessageDifferencer::Equals(lhs, rhs);
      47           0 :   }
      48             : };
      49             : 
      50             : /**
      51             :  * Health checker factory context.
      52             :  */
      53             : class HealthCheckerFactoryContextImpl : public Server::Configuration::HealthCheckerFactoryContext {
      54             : public:
      55             :   HealthCheckerFactoryContextImpl(Upstream::Cluster& cluster,
      56             :                                   Server::Configuration::ServerFactoryContext& server_context)
      57             :       : cluster_(cluster), runtime_(server_context.runtime()),
      58             :         dispatcher_(server_context.mainThreadDispatcher()),
      59             :         validation_visitor_(server_context.messageValidationVisitor()),
      60             :         log_manager_(server_context.accessLogManager()), api_(server_context.api()),
      61           0 :         server_context_(server_context) {}
      62           0 :   Upstream::Cluster& cluster() override { return cluster_; }
      63           0 :   Envoy::Runtime::Loader& runtime() override { return runtime_; }
      64           0 :   Event::Dispatcher& mainThreadDispatcher() override { return dispatcher_; }
      65           0 :   HealthCheckEventLoggerPtr eventLogger() override { return std::move(event_logger_); }
      66           0 :   ProtobufMessage::ValidationVisitor& messageValidationVisitor() override {
      67           0 :     return validation_visitor_;
      68           0 :   }
      69           0 :   Api::Api& api() override { return api_; }
      70             : 
      71           0 :   AccessLog::AccessLogManager& accessLogManager() override { return log_manager_; }
      72           0 :   void setEventLogger(HealthCheckEventLoggerPtr event_logger) override {
      73           0 :     event_logger_ = std::move(event_logger);
      74           0 :   }
      75             : 
      76           0 :   Server::Configuration::ServerFactoryContext& serverFactoryContext() override {
      77           0 :     return server_context_;
      78           0 :   };
      79             : 
      80             : private:
      81             :   Upstream::Cluster& cluster_;
      82             :   Envoy::Runtime::Loader& runtime_;
      83             :   Event::Dispatcher& dispatcher_;
      84             :   ProtobufMessage::ValidationVisitor& validation_visitor_;
      85             :   AccessLog::AccessLogManager& log_manager_;
      86             :   Api::Api& api_;
      87             :   HealthCheckEventLoggerPtr event_logger_;
      88             :   Server::Configuration::ServerFactoryContext& server_context_;
      89             : };
      90             : 
      91             : /**
      92             :  * Factory for creating health checker implementations.
      93             :  */
      94             : class HealthCheckerFactory : public Logger::Loggable<Logger::Id::health_checker> {
      95             : public:
      96             :   // Helper functions to get the correct hostname for an L7 health check.
      97             :   static const std::string& getHostname(const HostSharedPtr& host,
      98             :                                         const std::string& config_hostname,
      99             :                                         const ClusterInfoConstSharedPtr& cluster);
     100             :   /**
     101             :    * Create a health checker or return an error.
     102             :    * @param health_check_config supplies the health check proto.
     103             :    * @param cluster supplies the owning cluster.
     104             :    * @param server_context reference to the Server context object
     105             :    * @return a health checker.
     106             :    */
     107             :   static absl::StatusOr<HealthCheckerSharedPtr>
     108             :   create(const envoy::config::core::v3::HealthCheck& health_check_config,
     109             :          Upstream::Cluster& cluster, Server::Configuration::ServerFactoryContext& server_context);
     110             : };
     111             : 
     112             : /**
     113             :  * Utility class for loading a binary health checking config and matching it against a buffer.
     114             :  * Split out for ease of testing. The type of matching performed is the following (this is the
     115             :  * MongoDB health check request and response):
     116             :  *
     117             :  * "send": [
     118             :     {"text": "39000000"},
     119             :     {"text": "EEEEEEEE"},
     120             :     {"text": "00000000"},
     121             :     {"text": "d4070000"},
     122             :     {"text": "00000000"},
     123             :     {"text": "746573742e"},
     124             :     {"text": "24636d6400"},
     125             :     {"text": "00000000"},
     126             :     {"text": "FFFFFFFF"},
     127             : 
     128             :     {"text": "13000000"},
     129             :     {"text": "01"},
     130             :     {"text": "70696e6700"},
     131             :     {"text": "000000000000f03f"},
     132             :     {"text": "00"}
     133             :    ],
     134             :    "receive": [
     135             :     {"text": "EEEEEEEE"},
     136             :     {"text": "01000000"},
     137             :     {"text": "00000000"},
     138             :     {"text": "0000000000000000"},
     139             :     {"text": "00000000"},
     140             :     {"text": "11000000"},
     141             :     {"text": "01"},
     142             :     {"text": "6f6b"},
     143             :     {"text": "00000000000000f03f"},
     144             :     {"text": "00"}
     145             :    ]
     146             :  * Each text or binary filed in Payload is converted to a binary block.
     147             :  * The text is Hex string by default.
     148             :  *
     149             :  * During each health check cycle, all of the "send" bytes are sent to the target server. Each
     150             :  * binary block can be of arbitrary length and is just concatenated together when sent.
     151             :  *
     152             :  * On the receive side, "fuzzy" matching is performed such that each binary block must be found,
     153             :  * and in the order specified, but not necessary contiguous. Thus, in the example above,
     154             :  * "FFFFFFFF" could be inserted in the response between "EEEEEEEE" and "01000000" and the check
     155             :  * would still pass.
     156             :  *
     157             :  */
     158             : class PayloadMatcher {
     159             : public:
     160             :   using MatchSegments = std::list<std::vector<uint8_t>>;
     161             : 
     162             :   static absl::StatusOr<MatchSegments> loadProtoBytes(
     163             :       const Protobuf::RepeatedPtrField<envoy::config::core::v3::HealthCheck::Payload>& byte_array);
     164             :   static bool match(const MatchSegments& expected, const Buffer::Instance& buffer);
     165             : };
     166             : 
     167             : } // namespace Upstream
     168             : } // namespace Envoy

Generated by: LCOV version 1.15