1
#include "source/extensions/common/tap/extension_config_base.h"
2

            
3
#include "envoy/config/tap/v3/common.pb.h"
4
#include "envoy/extensions/common/tap/v3/common.pb.h"
5

            
6
namespace Envoy {
7
namespace Extensions {
8
namespace Common {
9
namespace Tap {
10

            
11
ExtensionConfigBase::ExtensionConfigBase(
12
    const envoy::extensions::common::tap::v3::CommonExtensionConfig proto_config,
13
    TapConfigFactoryPtr&& config_factory, OptRef<Server::Admin> admin,
14
    Singleton::Manager& singleton_manager, ThreadLocal::SlotAllocator& tls,
15
    Event::Dispatcher& main_thread_dispatcher)
16
36
    : proto_config_(proto_config), config_factory_(std::move(config_factory)), tls_slot_(tls) {
17
68
  tls_slot_.set([](Event::Dispatcher&) { return std::make_shared<TlsFilterConfig>(); });
18

            
19
36
  switch (proto_config_.config_type_case()) {
20
19
  case envoy::extensions::common::tap::v3::CommonExtensionConfig::ConfigTypeCase::kAdminConfig: {
21
19
    admin_handler_ = AdminHandler::getSingleton(admin, singleton_manager, main_thread_dispatcher);
22
19
    admin_handler_->registerConfig(*this, proto_config_.admin_config().config_id());
23
19
    ENVOY_LOG(debug, "initializing tap extension with admin endpoint (config_id={})",
24
19
              proto_config_.admin_config().config_id());
25
19
    break;
26
  }
27
17
  case envoy::extensions::common::tap::v3::CommonExtensionConfig::ConfigTypeCase::kStaticConfig: {
28
    // Right now only one sink is supported.
29
17
    ASSERT(proto_config_.static_config().output_config().sinks().size() == 1);
30
17
    if (proto_config_.static_config().output_config().sinks()[0].output_sink_type_case() ==
31
17
        envoy::config::tap::v3::OutputSink::OutputSinkTypeCase::kStreamingAdmin) {
32
      // Require that users do not specify a streaming admin with static configuration.
33
1
      throw EnvoyException(
34
1
          fmt::format("Error: Specifying admin streaming output without configuring admin."));
35
1
    }
36
16
    installNewTap(proto_config_.static_config(), nullptr);
37
16
    ENVOY_LOG(debug, "initializing tap extension with static config");
38
16
    break;
39
17
  }
40
  case envoy::extensions::common::tap::v3::CommonExtensionConfig::ConfigTypeCase::
41
      CONFIG_TYPE_NOT_SET:
42
    PANIC_DUE_TO_CORRUPT_ENUM;
43
36
  }
44
36
}
45

            
46
34
ExtensionConfigBase::~ExtensionConfigBase() {
47
34
  if (admin_handler_) {
48
19
    admin_handler_->unregisterConfig(*this);
49
19
  }
50
34
}
51

            
52
19
const absl::string_view ExtensionConfigBase::adminId() {
53
  // It is only possible to get here if we had an admin config and registered with the admin
54
  // handler.
55
19
  ASSERT(proto_config_.has_admin_config());
56
19
  return proto_config_.admin_config().config_id();
57
19
}
58

            
59
20
void ExtensionConfigBase::clearTapConfig() {
60
20
  tls_slot_.runOnAllThreads(
61
40
      [](OptRef<TlsFilterConfig> tls_filter_config) { tls_filter_config->config_ = nullptr; });
62
20
}
63

            
64
void ExtensionConfigBase::installNewTap(const envoy::config::tap::v3::TapConfig& proto_config,
65
36
                                        Sink* admin_streamer) {
66
36
  TapConfigSharedPtr new_config =
67
36
      config_factory_->createConfigFromProto(proto_config, admin_streamer);
68
36
  tls_slot_.runOnAllThreads(
69
71
      [new_config](OptRef<TlsFilterConfig> tls_filter_config) {
70
70
        tls_filter_config->config_ = new_config;
71
70
      },
72
36
      []() -> void { ENVOY_LOG(debug, "New tap installed on all workers."); });
73
36
}
74

            
75
void ExtensionConfigBase::newTapConfig(const envoy::config::tap::v3::TapConfig& proto_config,
76
20
                                       Sink* admin_streamer) {
77
20
  installNewTap(proto_config, admin_streamer);
78
20
}
79

            
80
} // namespace Tap
81
} // namespace Common
82
} // namespace Extensions
83
} // namespace Envoy