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