Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/common/config/datasource.cc
Line
Count
Source (jump to first uncovered line)
1
#include "source/common/config/datasource.h"
2
3
#include "envoy/config/core/v3/base.pb.h"
4
5
#include "source/common/config/utility.h"
6
7
#include "fmt/format.h"
8
9
namespace Envoy {
10
namespace Config {
11
namespace DataSource {
12
13
// Default Parameters of the jittered backoff strategy.
14
static constexpr uint32_t RetryInitialDelayMilliseconds = 1000;
15
static constexpr uint32_t RetryMaxDelayMilliseconds = 10 * 1000;
16
static constexpr uint32_t RetryCount = 1;
17
18
std::string read(const envoy::config::core::v3::DataSource& source, bool allow_empty, Api::Api& api,
19
14.1k
                 uint64_t max_size) {
20
14.1k
  std::string data;
21
14.1k
  absl::StatusOr<std::string> file_or_error;
22
14.1k
  switch (source.specifier_case()) {
23
140
  case envoy::config::core::v3::DataSource::SpecifierCase::kFilename:
24
140
    if (max_size > 0) {
25
36
      if (!api.fileSystem().fileExists(source.filename())) {
26
36
        throwEnvoyExceptionOrPanic(fmt::format("file {} does not exist", source.filename()));
27
36
      }
28
0
      const ssize_t size = api.fileSystem().fileSize(source.filename());
29
0
      if (size < 0) {
30
0
        throwEnvoyExceptionOrPanic(
31
0
            absl::StrCat("cannot determine size of file ", source.filename()));
32
0
      }
33
0
      if (static_cast<uint64_t>(size) > max_size) {
34
0
        throwEnvoyExceptionOrPanic(fmt::format("file {} size is {} bytes; maximum is {}",
35
0
                                               source.filename(), size, max_size));
36
0
      }
37
0
    }
38
104
    file_or_error = api.fileSystem().fileReadToEnd(source.filename());
39
104
    THROW_IF_STATUS_NOT_OK(file_or_error, throw);
40
49
    data = file_or_error.value();
41
49
    break;
42
2.08k
  case envoy::config::core::v3::DataSource::SpecifierCase::kInlineBytes:
43
2.08k
    data = source.inline_bytes();
44
2.08k
    break;
45
1.47k
  case envoy::config::core::v3::DataSource::SpecifierCase::kInlineString:
46
1.47k
    data = source.inline_string();
47
1.47k
    break;
48
126
  case envoy::config::core::v3::DataSource::SpecifierCase::kEnvironmentVariable: {
49
126
    const char* environment_variable = std::getenv(source.environment_variable().c_str());
50
126
    if (environment_variable == nullptr) {
51
71
      throwEnvoyExceptionOrPanic(
52
71
          fmt::format("Environment variable doesn't exist: {}", source.environment_variable()));
53
71
    }
54
55
    data = environment_variable;
55
55
    break;
56
126
  }
57
10.3k
  default:
58
10.3k
    if (!allow_empty) {
59
0
      throwEnvoyExceptionOrPanic(
60
0
          fmt::format("Unexpected DataSource::specifier_case(): {}", source.specifier_case()));
61
0
    }
62
14.1k
  }
63
13.9k
  if (!allow_empty && data.empty()) {
64
0
    throwEnvoyExceptionOrPanic("DataSource cannot be empty");
65
0
  }
66
13.9k
  return data;
67
13.9k
}
68
69
43
absl::optional<std::string> getPath(const envoy::config::core::v3::DataSource& source) {
70
43
  return source.specifier_case() == envoy::config::core::v3::DataSource::SpecifierCase::kFilename
71
43
             ? absl::make_optional(source.filename())
72
43
             : absl::nullopt;
73
43
}
74
75
RemoteAsyncDataProvider::RemoteAsyncDataProvider(
76
    Upstream::ClusterManager& cm, Init::Manager& manager,
77
    const envoy::config::core::v3::RemoteDataSource& source, Event::Dispatcher& dispatcher,
78
    Random::RandomGenerator& random, bool allow_empty, AsyncDataSourceCb&& callback)
79
    : allow_empty_(allow_empty), callback_(std::move(callback)),
80
      fetcher_(std::make_unique<Config::DataFetcher::RemoteDataFetcher>(cm, source.http_uri(),
81
                                                                        source.sha256(), *this)),
82
0
      init_target_("RemoteAsyncDataProvider", [this]() { start(); }),
83
      retries_remaining_(
84
0
          PROTOBUF_GET_WRAPPED_OR_DEFAULT(source.retry_policy(), num_retries, RetryCount)) {
85
86
0
  backoff_strategy_ = Utility::prepareJitteredExponentialBackOffStrategy(
87
0
      source, random, RetryInitialDelayMilliseconds, RetryMaxDelayMilliseconds);
88
89
0
  retry_timer_ = dispatcher.createTimer([this]() -> void { start(); });
90
91
0
  manager.add(init_target_);
92
0
}
93
94
} // namespace DataSource
95
} // namespace Config
96
} // namespace Envoy