LCOV - code coverage report
Current view: top level - source/common/upstream - health_checker_impl.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 34 100 34.0 %
Date: 2024-01-05 06:35:25 Functions: 3 6 50.0 %

          Line data    Source code
       1             : #include "source/common/upstream/health_checker_impl.h"
       2             : 
       3             : #include <cstdint>
       4             : #include <iterator>
       5             : #include <memory>
       6             : 
       7             : #include "envoy/config/core/v3/health_check.pb.h"
       8             : #include "envoy/data/core/v3/health_check_event.pb.h"
       9             : #include "envoy/server/health_checker_config.h"
      10             : #include "envoy/type/v3/http.pb.h"
      11             : #include "envoy/type/v3/range.pb.h"
      12             : 
      13             : #include "source/common/buffer/zero_copy_input_stream_impl.h"
      14             : #include "source/common/common/empty_string.h"
      15             : #include "source/common/common/enum_to_int.h"
      16             : #include "source/common/common/macros.h"
      17             : #include "source/common/config/utility.h"
      18             : #include "source/common/config/well_known_names.h"
      19             : #include "source/common/grpc/common.h"
      20             : #include "source/common/http/header_map_impl.h"
      21             : #include "source/common/http/header_utility.h"
      22             : #include "source/common/network/address_impl.h"
      23             : #include "source/common/network/socket_impl.h"
      24             : #include "source/common/network/utility.h"
      25             : #include "source/common/router/router.h"
      26             : #include "source/common/runtime/runtime_features.h"
      27             : #include "source/common/upstream/host_utility.h"
      28             : 
      29             : #include "absl/strings/match.h"
      30             : #include "absl/strings/str_cat.h"
      31             : 
      32             : namespace Envoy {
      33             : namespace Upstream {
      34             : 
      35             : // Helper functions to get the correct hostname for an L7 health check.
      36             : const std::string& HealthCheckerFactory::getHostname(const HostSharedPtr& host,
      37             :                                                      const std::string& config_hostname,
      38          48 :                                                      const ClusterInfoConstSharedPtr& cluster) {
      39          48 :   if (!host->hostnameForHealthChecks().empty()) {
      40           0 :     return host->hostnameForHealthChecks();
      41           0 :   }
      42             : 
      43          48 :   if (!config_hostname.empty()) {
      44           2 :     return config_hostname;
      45           2 :   }
      46             : 
      47          46 :   return cluster->name();
      48          48 : }
      49             : 
      50             : absl::StatusOr<HealthCheckerSharedPtr>
      51             : HealthCheckerFactory::create(const envoy::config::core::v3::HealthCheck& health_check_config,
      52             :                              Upstream::Cluster& cluster,
      53           0 :                              Server::Configuration::ServerFactoryContext& server_context) {
      54           0 :   Server::Configuration::CustomHealthCheckerFactory* factory = nullptr;
      55             : 
      56           0 :   switch (health_check_config.health_checker_case()) {
      57           0 :   case envoy::config::core::v3::HealthCheck::HealthCheckerCase::HEALTH_CHECKER_NOT_SET:
      58           0 :     return absl::InvalidArgumentError("invalid cluster config");
      59           0 :   case envoy::config::core::v3::HealthCheck::HealthCheckerCase::kHttpHealthCheck:
      60           0 :     factory = &Config::Utility::getAndCheckFactoryByName<
      61           0 :         Server::Configuration::CustomHealthCheckerFactory>("envoy.health_checkers.http");
      62           0 :     break;
      63           0 :   case envoy::config::core::v3::HealthCheck::HealthCheckerCase::kTcpHealthCheck:
      64           0 :     factory = &Config::Utility::getAndCheckFactoryByName<
      65           0 :         Server::Configuration::CustomHealthCheckerFactory>("envoy.health_checkers.tcp");
      66           0 :     break;
      67           0 :   case envoy::config::core::v3::HealthCheck::HealthCheckerCase::kGrpcHealthCheck:
      68           0 :     if (!(cluster.info()->features() & Upstream::ClusterInfo::Features::HTTP2)) {
      69           0 :       return absl::InvalidArgumentError(fmt::format(
      70           0 :           "{} cluster must support HTTP/2 for gRPC healthchecking", cluster.info()->name()));
      71           0 :     }
      72           0 :     factory = &Config::Utility::getAndCheckFactoryByName<
      73           0 :         Server::Configuration::CustomHealthCheckerFactory>("envoy.health_checkers.grpc");
      74           0 :     break;
      75           0 :   case envoy::config::core::v3::HealthCheck::HealthCheckerCase::kCustomHealthCheck: {
      76           0 :     factory =
      77           0 :         &Config::Utility::getAndCheckFactory<Server::Configuration::CustomHealthCheckerFactory>(
      78           0 :             health_check_config.custom_health_check());
      79           0 :   }
      80           0 :   }
      81             : 
      82           0 :   std::unique_ptr<Server::Configuration::HealthCheckerFactoryContext> context(
      83           0 :       new HealthCheckerFactoryContextImpl(cluster, server_context));
      84             : 
      85           0 :   if (!health_check_config.event_log_path().empty() /* deprecated */ ||
      86           0 :       !health_check_config.event_logger().empty()) {
      87           0 :     HealthCheckEventLoggerPtr event_logger;
      88           0 :     event_logger = std::make_unique<HealthCheckEventLoggerImpl>(health_check_config, *context);
      89           0 :     context->setEventLogger(std::move(event_logger));
      90           0 :   }
      91           0 :   return factory->createCustomHealthChecker(health_check_config, *context);
      92           0 : }
      93             : 
      94             : absl::StatusOr<PayloadMatcher::MatchSegments> PayloadMatcher::loadProtoBytes(
      95          44 :     const Protobuf::RepeatedPtrField<envoy::config::core::v3::HealthCheck::Payload>& byte_array) {
      96          44 :   MatchSegments result;
      97             : 
      98          44 :   for (const auto& entry : byte_array) {
      99          18 :     std::vector<uint8_t> decoded;
     100          18 :     if (entry.has_text()) {
     101          17 :       decoded = Hex::decode(entry.text());
     102          17 :       if (decoded.empty()) {
     103           0 :         return absl::InvalidArgumentError(fmt::format("invalid hex string '{}'", entry.text()));
     104           0 :       }
     105          17 :     } else {
     106           1 :       decoded.assign(entry.binary().begin(), entry.binary().end());
     107           1 :     }
     108          18 :     if (!decoded.empty()) {
     109          18 :       result.push_back(decoded);
     110          18 :     }
     111          18 :   }
     112             : 
     113          44 :   return result;
     114          44 : }
     115             : 
     116          11 : bool PayloadMatcher::match(const MatchSegments& expected, const Buffer::Instance& buffer) {
     117          11 :   uint64_t start_index = 0;
     118          11 :   for (const std::vector<uint8_t>& segment : expected) {
     119           8 :     ssize_t search_result = buffer.search(segment.data(), segment.size(), start_index);
     120           8 :     if (search_result == -1) {
     121           5 :       return false;
     122           5 :     }
     123             : 
     124           3 :     start_index = search_result + segment.size();
     125           3 :   }
     126             : 
     127           6 :   return true;
     128          11 : }
     129             : 
     130           0 : std::ostream& operator<<(std::ostream& out, HealthState state) {
     131           0 :   switch (state) {
     132           0 :   case HealthState::Unhealthy:
     133           0 :     out << "Unhealthy";
     134           0 :     break;
     135           0 :   case HealthState::Healthy:
     136           0 :     out << "Healthy";
     137           0 :     break;
     138           0 :   }
     139           0 :   return out;
     140           0 : }
     141             : 
     142           0 : std::ostream& operator<<(std::ostream& out, HealthTransition changed_state) {
     143           0 :   switch (changed_state) {
     144           0 :   case HealthTransition::Unchanged:
     145           0 :     out << "Unchanged";
     146           0 :     break;
     147           0 :   case HealthTransition::Changed:
     148           0 :     out << "Changed";
     149           0 :     break;
     150           0 :   case HealthTransition::ChangePending:
     151           0 :     out << "ChangePending";
     152           0 :     break;
     153           0 :   }
     154           0 :   return out;
     155           0 : }
     156             : 
     157             : } // namespace Upstream
     158             : } // namespace Envoy

Generated by: LCOV version 1.15