1
#include "source/extensions/bootstrap/dynamic_modules/factory.h"
2

            
3
#include "envoy/common/exception.h"
4
#include "envoy/extensions/bootstrap/dynamic_modules/v3/dynamic_modules.pb.h"
5
#include "envoy/extensions/bootstrap/dynamic_modules/v3/dynamic_modules.pb.validate.h"
6
#include "envoy/registry/registry.h"
7

            
8
#include "source/common/protobuf/utility.h"
9
#include "source/common/runtime/runtime_features.h"
10
#include "source/extensions/dynamic_modules/dynamic_modules.h"
11

            
12
namespace Envoy {
13
namespace Extensions {
14
namespace Bootstrap {
15
namespace DynamicModules {
16

            
17
Server::BootstrapExtensionPtr DynamicModuleBootstrapExtensionFactory::createBootstrapExtension(
18
14
    const Protobuf::Message& config, Server::Configuration::ServerFactoryContext& context) {
19

            
20
14
  const auto& proto_config = MessageUtil::downcastAndValidate<
21
14
      const envoy::extensions::bootstrap::dynamic_modules::v3::DynamicModuleBootstrapExtension&>(
22
14
      config, context.messageValidationVisitor());
23

            
24
14
  const auto& module_config = proto_config.dynamic_module_config();
25
14
  auto dynamic_module = Extensions::DynamicModules::newDynamicModuleByName(
26
14
      module_config.name(), module_config.do_not_close(), module_config.load_globally());
27
14
  if (!dynamic_module.ok()) {
28
1
    throwEnvoyExceptionOrPanic("Failed to load dynamic module: " +
29
1
                               std::string(dynamic_module.status().message()));
30
1
  }
31

            
32
13
  std::string extension_config_str;
33
13
  if (proto_config.has_extension_config()) {
34
12
    auto config_or_error = MessageUtil::knownAnyToBytes(proto_config.extension_config());
35
12
    if (!config_or_error.ok()) {
36
1
      throwEnvoyExceptionOrPanic("Failed to parse extension config: " +
37
1
                                 std::string(config_or_error.status().message()));
38
1
    }
39
11
    extension_config_str = std::move(config_or_error.value());
40
11
  }
41

            
42
  // Use configured metrics namespace or fall back to the default.
43
12
  const std::string metrics_namespace = module_config.metrics_namespace().empty()
44
12
                                            ? std::string(DefaultMetricsNamespace)
45
12
                                            : module_config.metrics_namespace();
46

            
47
12
  auto extension_config = newDynamicModuleBootstrapExtensionConfig(
48
12
      proto_config.extension_name(), extension_config_str, metrics_namespace,
49
12
      std::move(dynamic_module.value()), context.mainThreadDispatcher(), context,
50
12
      context.serverScope().store());
51

            
52
12
  if (!extension_config.ok()) {
53
1
    throwEnvoyExceptionOrPanic("Failed to create extension config: " +
54
1
                               std::string(extension_config.status().message()));
55
1
  }
56

            
57
  // When the runtime guard is enabled, register the metrics namespace as a custom stat namespace.
58
  // This causes the namespace prefix to be stripped from prometheus output and no envoy_ prefix
59
  // is added. This is the legacy behavior for backward compatibility.
60
11
  if (Runtime::runtimeFeatureEnabled(
61
11
          "envoy.reloadable_features.dynamic_modules_strip_custom_stat_prefix")) {
62
    context.api().customStatNamespaces().registerStatNamespace(metrics_namespace);
63
  }
64

            
65
11
  auto extension = std::make_unique<DynamicModuleBootstrapExtension>(extension_config.value());
66
11
  extension->initializeInModuleExtension();
67
11
  return extension;
68
12
}
69

            
70
15
ProtobufTypes::MessagePtr DynamicModuleBootstrapExtensionFactory::createEmptyConfigProto() {
71
15
  return std::make_unique<
72
15
      envoy::extensions::bootstrap::dynamic_modules::v3::DynamicModuleBootstrapExtension>();
73
15
}
74

            
75
/**
76
 * Static registration for the dynamic modules bootstrap extension factory.
77
 */
78
REGISTER_FACTORY(DynamicModuleBootstrapExtensionFactory,
79
                 Server::Configuration::BootstrapExtensionFactory);
80

            
81
} // namespace DynamicModules
82
} // namespace Bootstrap
83
} // namespace Extensions
84
} // namespace Envoy