/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/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/stats/tag_producer_impl.h" |
15 | | #include "source/common/tls/context_manager_impl.h" |
16 | | #include "source/common/version/version.h" |
17 | | #include "source/server/admin/admin_factory_context.h" |
18 | | #include "source/server/listener_manager_factory.h" |
19 | | #include "source/server/null_overload_manager.h" |
20 | | #include "source/server/overload_manager_impl.h" |
21 | | #include "source/server/regex_engine.h" |
22 | | #include "source/server/utils.h" |
23 | | |
24 | | namespace Envoy { |
25 | | namespace Server { |
26 | | |
27 | | bool validateConfig(const Options& options, |
28 | | const Network::Address::InstanceConstSharedPtr& local_address, |
29 | | ComponentFactory& component_factory, Thread::ThreadFactory& thread_factory, |
30 | | Filesystem::Instance& file_system, |
31 | 5.52k | const ProcessContextOptRef& process_context) { |
32 | 5.52k | Thread::MutexBasicLockable access_log_lock; |
33 | 5.52k | Stats::IsolatedStoreImpl stats_store; |
34 | | |
35 | 5.52k | TRY_ASSERT_MAIN_THREAD { |
36 | 5.52k | Event::RealTimeSystem time_system; |
37 | 5.52k | ValidationInstance server(options, time_system, local_address, stats_store, access_log_lock, |
38 | 5.52k | component_factory, thread_factory, file_system, process_context); |
39 | 5.52k | std::cout << "configuration '" << options.configPath() << "' OK" << std::endl; |
40 | 5.52k | server.shutdown(); |
41 | 5.52k | return true; |
42 | 5.52k | } |
43 | 5.52k | END_TRY |
44 | 5.52k | catch (const EnvoyException& e) { |
45 | 5.52k | return false; |
46 | 5.52k | } |
47 | 5.52k | } |
48 | | |
49 | | ValidationInstance::ValidationInstance( |
50 | | const Options& options, Event::TimeSystem& time_system, |
51 | | const Network::Address::InstanceConstSharedPtr& local_address, Stats::IsolatedStoreImpl& store, |
52 | | Thread::BasicLockable& access_log_lock, ComponentFactory& component_factory, |
53 | | Thread::ThreadFactory& thread_factory, Filesystem::Instance& file_system, |
54 | | const ProcessContextOptRef& process_context) |
55 | | : options_(options), validation_context_(options_.allowUnknownStaticFields(), |
56 | | !options.rejectUnknownDynamicFields(), |
57 | | !options.ignoreUnknownDynamicFields()), |
58 | | stats_store_(store), |
59 | | api_(new Api::ValidationImpl(thread_factory, store, time_system, file_system, |
60 | | random_generator_, bootstrap_, process_context)), |
61 | | dispatcher_(api_->allocateDispatcher("main_thread")), |
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 | 5.52k | server_contexts_(*this), quic_stat_names_(stats_store_.symbolTable()) { |
67 | 5.52k | TRY_ASSERT_MAIN_THREAD { initialize(options, local_address, component_factory); } |
68 | 5.52k | END_TRY |
69 | 5.52k | catch (const EnvoyException& e) { |
70 | 5.52k | ENVOY_LOG(critical, "error initializing configuration '{}': {}", options.configPath(), |
71 | 5.52k | e.what()); |
72 | 5.52k | shutdown(); |
73 | 5.52k | throw; |
74 | 5.52k | } |
75 | 5.52k | } |
76 | | |
77 | | void ValidationInstance::initialize(const Options& options, |
78 | | const Network::Address::InstanceConstSharedPtr& local_address, |
79 | 5.52k | 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 | 5.52k | THROW_IF_NOT_OK(InstanceUtil::loadBootstrapConfig( |
91 | 5.52k | bootstrap_, options, messageValidationContext().staticValidationVisitor(), *api_)); |
92 | | |
93 | 5.52k | if (bootstrap_.has_application_log_config()) { |
94 | 2.05k | THROW_IF_NOT_OK( |
95 | 2.05k | Utility::assertExclusiveLogFormatMethod(options_, bootstrap_.application_log_config())); |
96 | 2.05k | THROW_IF_NOT_OK(Utility::maybeSetApplicationLogFormat(bootstrap_.application_log_config())); |
97 | 2.05k | } |
98 | | |
99 | | // Inject regex engine to singleton. |
100 | 5.49k | regex_engine_ = createRegexEngine( |
101 | 5.49k | bootstrap_, messageValidationContext().staticValidationVisitor(), serverFactoryContext()); |
102 | | |
103 | 5.49k | auto producer_or_error = |
104 | 5.49k | Stats::TagProducerImpl::createTagProducer(bootstrap_.stats_config(), options_.statsTags()); |
105 | 5.49k | THROW_IF_NOT_OK_REF(producer_or_error.status()); |
106 | 5.23k | if (!bootstrap_.node().user_agent_build_version().has_version()) { |
107 | 4.15k | *bootstrap_.mutable_node()->mutable_user_agent_build_version() = VersionInfo::buildVersion(); |
108 | 4.15k | } |
109 | | |
110 | 5.23k | local_info_ = std::make_unique<LocalInfo::LocalInfoImpl>( |
111 | 5.23k | stats().symbolTable(), bootstrap_.node(), bootstrap_.node_context_params(), local_address, |
112 | 5.23k | options.serviceZone(), options.serviceClusterName(), options.serviceNodeName()); |
113 | | |
114 | 5.23k | overload_manager_ = THROW_OR_RETURN_VALUE( |
115 | 5.23k | OverloadManagerImpl::create( |
116 | 5.23k | dispatcher(), *stats().rootScope(), threadLocal(), bootstrap_.overload_manager(), |
117 | 5.23k | messageValidationContext().staticValidationVisitor(), *api_, options_), |
118 | 5.23k | std::unique_ptr<OverloadManagerImpl>); |
119 | 5.23k | null_overload_manager_ = std::make_unique<NullOverloadManager>(threadLocal(), false); |
120 | 5.23k | absl::Status creation_status = absl::OkStatus(); |
121 | 5.23k | Configuration::InitialImpl initial_config(bootstrap_, creation_status); |
122 | 5.23k | THROW_IF_NOT_OK_REF(creation_status); |
123 | 5.18k | AdminFactoryContext factory_context(*this, std::make_shared<ListenerInfoImpl>()); |
124 | 5.18k | initial_config.initAdminAccessLog(bootstrap_, factory_context); |
125 | 5.18k | admin_ = std::make_unique<Server::ValidationAdmin>(initial_config.admin().address()); |
126 | 5.18k | listener_manager_ = Config::Utility::getAndCheckFactoryByName<ListenerManagerFactory>( |
127 | 5.18k | Config::ServerExtensionValues::get().VALIDATION_LISTENER) |
128 | 5.18k | .createListenerManager(*this, nullptr, *this, false, quic_stat_names_); |
129 | 5.18k | thread_local_.registerThread(*dispatcher_, true); |
130 | | |
131 | 5.18k | runtime_ = component_factory.createRuntime(*this, initial_config); |
132 | 5.18k | ENVOY_BUG(runtime_ != nullptr, |
133 | 5.18k | "Component factory should not return nullptr from createRuntime()"); |
134 | 5.18k | drain_manager_ = component_factory.createDrainManager(*this); |
135 | 5.18k | ENVOY_BUG(drain_manager_ != nullptr, |
136 | 5.18k | "Component factory should not return nullptr from createDrainManager()"); |
137 | | |
138 | 5.18k | secret_manager_ = std::make_unique<Secret::SecretManagerImpl>(admin()->getConfigTracker()); |
139 | 5.18k | ssl_context_manager_ = |
140 | 5.18k | std::make_unique<Extensions::TransportSockets::Tls::ContextManagerImpl>(server_contexts_); |
141 | | |
142 | 5.18k | http_server_properties_cache_manager_ = |
143 | 5.18k | std::make_unique<Http::HttpServerPropertiesCacheManagerImpl>( |
144 | 5.18k | serverFactoryContext(), messageValidationContext().staticValidationVisitor(), |
145 | 5.18k | thread_local_); |
146 | | |
147 | 5.18k | cluster_manager_factory_ = std::make_unique<Upstream::ValidationClusterManagerFactory>( |
148 | 5.18k | server_contexts_, stats(), threadLocal(), http_context_, |
149 | 5.18k | [this]() -> Network::DnsResolverSharedPtr { return this->dnsResolver(); }, |
150 | 5.18k | sslContextManager(), *secret_manager_, quic_stat_names_, *this); |
151 | 5.18k | THROW_IF_NOT_OK(config_.initialize(bootstrap_, *this, *cluster_manager_factory_)); |
152 | 5.18k | THROW_IF_NOT_OK(runtime().initialize(clusterManager())); |
153 | 5.18k | clusterManager().setInitializedCb([this]() -> void { init_manager_.initialize(init_watcher_); }); |
154 | 5.18k | } |
155 | | |
156 | 5.52k | void ValidationInstance::shutdown() { |
157 | | // This normally happens at the bottom of InstanceImpl::run(), but we don't have a run(). We can |
158 | | // do an abbreviated shutdown here since there's less to clean up -- for example, no workers to |
159 | | // exit. |
160 | 5.52k | thread_local_.shutdownGlobalThreading(); |
161 | 5.52k | if (config_.clusterManager() != nullptr) { |
162 | 0 | config_.clusterManager()->shutdown(); |
163 | 0 | } |
164 | 5.52k | thread_local_.shutdownThread(); |
165 | 5.52k | dispatcher_->shutdown(); |
166 | 5.52k | } |
167 | | |
168 | 0 | Network::DnsResolverSharedPtr ValidationInstance::dnsResolver() { |
169 | 0 | envoy::config::core::v3::TypedExtensionConfig typed_dns_resolver_config; |
170 | 0 | Network::DnsResolverFactory& dns_resolver_factory = |
171 | 0 | Network::createDefaultDnsResolverFactory(typed_dns_resolver_config); |
172 | 0 | return THROW_OR_RETURN_VALUE( |
173 | 0 | dns_resolver_factory.createDnsResolver(dispatcher(), api(), typed_dns_resolver_config), |
174 | 0 | Network::DnsResolverSharedPtr); |
175 | 0 | } |
176 | | |
177 | | } // namespace Server |
178 | | } // namespace Envoy |