LCOV - code coverage report
Current view: top level - source/server/config_validation - server.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 76 78 97.4 %
Date: 2024-01-05 06:35:25 Functions: 4 6 66.7 %

          Line data    Source code
       1             : #include "source/server/config_validation/server.h"
       2             : 
       3             : #include <memory>
       4             : 
       5             : #include "envoy/config/bootstrap/v3/bootstrap.pb.h"
       6             : 
       7             : #include "source/common/common/utility.h"
       8             : #include "source/common/config/utility.h"
       9             : #include "source/common/config/well_known_names.h"
      10             : #include "source/common/event/real_time_system.h"
      11             : #include "source/common/listener_manager/listener_info_impl.h"
      12             : #include "source/common/local_info/local_info_impl.h"
      13             : #include "source/common/protobuf/utility.h"
      14             : #include "source/common/singleton/manager_impl.h"
      15             : #include "source/common/version/version.h"
      16             : #include "source/server/admin/admin_factory_context.h"
      17             : #include "source/server/listener_manager_factory.h"
      18             : #include "source/server/overload_manager_impl.h"
      19             : #include "source/server/regex_engine.h"
      20             : #include "source/server/ssl_context_manager.h"
      21             : #include "source/server/utils.h"
      22             : 
      23             : namespace Envoy {
      24             : namespace Server {
      25             : 
      26             : bool validateConfig(const Options& options,
      27             :                     const Network::Address::InstanceConstSharedPtr& local_address,
      28             :                     ComponentFactory& component_factory, Thread::ThreadFactory& thread_factory,
      29             :                     Filesystem::Instance& file_system,
      30         320 :                     const ProcessContextOptRef& process_context) {
      31         320 :   Thread::MutexBasicLockable access_log_lock;
      32         320 :   Stats::IsolatedStoreImpl stats_store;
      33             : 
      34         320 :   TRY_ASSERT_MAIN_THREAD {
      35         320 :     Event::RealTimeSystem time_system;
      36         320 :     ValidationInstance server(options, time_system, local_address, stats_store, access_log_lock,
      37         320 :                               component_factory, thread_factory, file_system, process_context);
      38         320 :     std::cout << "configuration '" << options.configPath() << "' OK" << std::endl;
      39         320 :     server.shutdown();
      40         320 :     return true;
      41         320 :   }
      42         320 :   END_TRY
      43         320 :   catch (const EnvoyException& e) {
      44         320 :     return false;
      45         320 :   }
      46         320 : }
      47             : 
      48             : ValidationInstance::ValidationInstance(
      49             :     const Options& options, Event::TimeSystem& time_system,
      50             :     const Network::Address::InstanceConstSharedPtr& local_address, Stats::IsolatedStoreImpl& store,
      51             :     Thread::BasicLockable& access_log_lock, ComponentFactory& component_factory,
      52             :     Thread::ThreadFactory& thread_factory, Filesystem::Instance& file_system,
      53             :     const ProcessContextOptRef& process_context)
      54             :     : options_(options), validation_context_(options_.allowUnknownStaticFields(),
      55             :                                              !options.rejectUnknownDynamicFields(),
      56             :                                              !options.ignoreUnknownDynamicFields()),
      57             :       stats_store_(store),
      58             :       api_(new Api::ValidationImpl(thread_factory, store, time_system, file_system,
      59             :                                    random_generator_, bootstrap_, process_context)),
      60             :       dispatcher_(api_->allocateDispatcher("main_thread")),
      61             :       singleton_manager_(new Singleton::ManagerImpl(api_->threadFactory())),
      62             :       access_log_manager_(options.fileFlushIntervalMsec(), *api_, *dispatcher_, access_log_lock,
      63             :                           store),
      64             :       grpc_context_(stats_store_.symbolTable()), http_context_(stats_store_.symbolTable()),
      65             :       router_context_(stats_store_.symbolTable()), time_system_(time_system),
      66         320 :       server_contexts_(*this), quic_stat_names_(stats_store_.symbolTable()) {
      67         320 :   TRY_ASSERT_MAIN_THREAD { initialize(options, local_address, component_factory); }
      68         320 :   END_TRY
      69         320 :   catch (const EnvoyException& e) {
      70         320 :     ENVOY_LOG(critical, "error initializing configuration '{}': {}", options.configPath(),
      71         320 :               e.what());
      72         320 :     shutdown();
      73         320 :     throw;
      74         320 :   }
      75         320 : }
      76             : 
      77             : void ValidationInstance::initialize(const Options& options,
      78             :                                     const Network::Address::InstanceConstSharedPtr& local_address,
      79         320 :                                     ComponentFactory& component_factory) {
      80             :   // See comments on InstanceImpl::initialize() for the overall flow here.
      81             :   //
      82             :   // For validation, we only do a subset of normal server initialization: everything that could fail
      83             :   // on a malformed config (e.g. JSON parsing and all the object construction that follows), but
      84             :   // more importantly nothing with observable effects (e.g. binding to ports or shutting down any
      85             :   // other Envoy process).
      86             :   //
      87             :   // If we get all the way through that stripped-down initialization flow, to the point where we'd
      88             :   // be ready to serve, then the config has passed validation.
      89             :   // Handle configuration that needs to take place prior to the main configuration load.
      90         320 :   InstanceUtil::loadBootstrapConfig(bootstrap_, options,
      91         320 :                                     messageValidationContext().staticValidationVisitor(), *api_);
      92             : 
      93         320 :   if (bootstrap_.has_application_log_config()) {
      94           4 :     THROW_IF_NOT_OK(
      95           4 :         Utility::assertExclusiveLogFormatMethod(options_, bootstrap_.application_log_config()));
      96           4 :     THROW_IF_NOT_OK(Utility::maybeSetApplicationLogFormat(bootstrap_.application_log_config()));
      97           4 :   }
      98             : 
      99             :   // Inject regex engine to singleton.
     100         320 :   Regex::EnginePtr regex_engine = createRegexEngine(
     101         320 :       bootstrap_, messageValidationContext().staticValidationVisitor(), serverFactoryContext());
     102             : 
     103         320 :   Config::Utility::createTagProducer(bootstrap_, options_.statsTags());
     104         320 :   if (!bootstrap_.node().user_agent_build_version().has_version()) {
     105         114 :     *bootstrap_.mutable_node()->mutable_user_agent_build_version() = VersionInfo::buildVersion();
     106         114 :   }
     107             : 
     108         320 :   local_info_ = std::make_unique<LocalInfo::LocalInfoImpl>(
     109         320 :       stats().symbolTable(), bootstrap_.node(), bootstrap_.node_context_params(), local_address,
     110         320 :       options.serviceZone(), options.serviceClusterName(), options.serviceNodeName());
     111             : 
     112         320 :   overload_manager_ = std::make_unique<OverloadManagerImpl>(
     113         320 :       dispatcher(), *stats().rootScope(), threadLocal(), bootstrap_.overload_manager(),
     114         320 :       messageValidationContext().staticValidationVisitor(), *api_, options_);
     115         320 :   Configuration::InitialImpl initial_config(bootstrap_);
     116         320 :   AdminFactoryContext factory_context(*this, std::make_shared<ListenerInfoImpl>());
     117         320 :   initial_config.initAdminAccessLog(bootstrap_, factory_context);
     118         320 :   admin_ = std::make_unique<Server::ValidationAdmin>(initial_config.admin().address());
     119         320 :   listener_manager_ = Config::Utility::getAndCheckFactoryByName<ListenerManagerFactory>(
     120         320 :                           Config::ServerExtensionValues::get().VALIDATION_LISTENER)
     121         320 :                           .createListenerManager(*this, nullptr, *this, false, quic_stat_names_);
     122         320 :   thread_local_.registerThread(*dispatcher_, true);
     123             : 
     124         320 :   runtime_ = component_factory.createRuntime(*this, initial_config);
     125         320 :   ENVOY_BUG(runtime_ != nullptr,
     126         320 :             "Component factory should not return nullptr from createRuntime()");
     127         320 :   drain_manager_ = component_factory.createDrainManager(*this);
     128         320 :   ENVOY_BUG(drain_manager_ != nullptr,
     129         320 :             "Component factory should not return nullptr from createDrainManager()");
     130             : 
     131         320 :   secret_manager_ = std::make_unique<Secret::SecretManagerImpl>(admin()->getConfigTracker());
     132         320 :   ssl_context_manager_ = createContextManager("ssl_context_manager", api_->timeSource());
     133         320 :   cluster_manager_factory_ = std::make_unique<Upstream::ValidationClusterManagerFactory>(
     134         320 :       server_contexts_, stats(), threadLocal(), http_context_,
     135         320 :       [this]() -> Network::DnsResolverSharedPtr { return this->dnsResolver(); },
     136         320 :       sslContextManager(), *secret_manager_, quic_stat_names_, *this);
     137         320 :   config_.initialize(bootstrap_, *this, *cluster_manager_factory_);
     138         320 :   runtime().initialize(clusterManager());
     139         320 :   clusterManager().setInitializedCb([this]() -> void { init_manager_.initialize(init_watcher_); });
     140         320 : }
     141             : 
     142         320 : void ValidationInstance::shutdown() {
     143             :   // This normally happens at the bottom of InstanceImpl::run(), but we don't have a run(). We can
     144             :   // do an abbreviated shutdown here since there's less to clean up -- for example, no workers to
     145             :   // exit.
     146         320 :   thread_local_.shutdownGlobalThreading();
     147         320 :   if (config_.clusterManager() != nullptr) {
     148           0 :     config_.clusterManager()->shutdown();
     149           0 :   }
     150         320 :   thread_local_.shutdownThread();
     151         320 :   dispatcher_->shutdown();
     152         320 : }
     153             : 
     154             : } // namespace Server
     155             : } // namespace Envoy

Generated by: LCOV version 1.15