1
#pragma once
2

            
3
#include <iostream>
4

            
5
#include "envoy/config/bootstrap/v3/bootstrap.pb.h"
6
#include "envoy/config/core/v3/config_source.pb.h"
7
#include "envoy/config/listener/v3/listener.pb.h"
8
#include "envoy/config/listener/v3/listener_components.pb.h"
9
#include "envoy/event/timer.h"
10
#include "envoy/server/drain_manager.h"
11
#include "envoy/server/instance.h"
12
#include "envoy/ssl/context_manager.h"
13
#include "envoy/tracing/tracer.h"
14

            
15
#include "source/common/access_log/access_log_manager_impl.h"
16
#include "source/common/common/assert.h"
17
#include "source/common/common/random_generator.h"
18
#include "source/common/config/xds_manager_impl.h"
19
#include "source/common/grpc/common.h"
20
#include "source/common/network/dns_resolver/dns_factory_util.h"
21
#include "source/common/protobuf/message_validator_impl.h"
22
#include "source/common/quic/quic_stat_names.h"
23
#include "source/common/router/context_impl.h"
24
#include "source/common/router/rds_impl.h"
25
#include "source/common/runtime/runtime_impl.h"
26
#include "source/common/secret/secret_manager_impl.h"
27
#include "source/common/singleton/manager_impl.h"
28
#include "source/common/thread_local/thread_local_impl.h"
29
#include "source/server/config_validation/admin.h"
30
#include "source/server/config_validation/api.h"
31
#include "source/server/config_validation/cluster_manager.h"
32
#include "source/server/hot_restart_nop_impl.h"
33
#include "source/server/server.h"
34

            
35
#include "absl/types/optional.h"
36

            
37
namespace Envoy {
38
namespace Server {
39

            
40
/**
41
 * validateConfig() takes over from main() for a config-validation run of Envoy. It returns true if
42
 * the config is valid, false if invalid.
43
 */
44
bool validateConfig(const Options& options,
45
                    const Network::Address::InstanceConstSharedPtr& local_address,
46
                    ComponentFactory& component_factory, Thread::ThreadFactory& thread_factory,
47
                    Filesystem::Instance& file_system,
48
                    const ProcessContextOptRef& process_context = absl::nullopt);
49

            
50
/**
51
 * ValidationInstance does the bulk of the work for config-validation runs of Envoy. It implements
52
 * Server::Instance, but some functionality not needed until serving time, such as updating
53
 * health-check status, is not implemented. Everything else is written in terms of other
54
 * validation-specific interface implementations, with the end result that we can load and
55
 * initialize a configuration, skipping any steps that affect the outside world (such as
56
 * hot-restarting or connecting to upstream clusters) but otherwise exercising the entire startup
57
 * flow.
58
 *
59
 * If we finish initialization, and reach the point where an ordinary Envoy run would begin serving
60
 * requests, the validation is considered successful.
61
 */
62
class ValidationInstance final : Logger::Loggable<Logger::Id::main>,
63
                                 public Instance,
64
                                 public ServerLifecycleNotifier,
65
                                 public WorkerFactory {
66
public:
67
  ValidationInstance(const Options& options, Event::TimeSystem& time_system,
68
                     const Network::Address::InstanceConstSharedPtr& local_address,
69
                     Stats::IsolatedStoreImpl& store, Thread::BasicLockable& access_log_lock,
70
                     ComponentFactory& component_factory, Thread::ThreadFactory& thread_factory,
71
                     Filesystem::Instance& file_system,
72
                     const ProcessContextOptRef& process_context = absl::nullopt);
73

            
74
  ~ValidationInstance() override;
75

            
76
  // Server::Instance
77
  void run() override { PANIC("not implemented"); }
78
293
  OptRef<Admin> admin() override {
79
293
    return makeOptRefFromPtr(static_cast<Envoy::Server::Admin*>(admin_.get()));
80
293
  }
81
720
  Api::Api& api() override { return *api_; }
82
725
  Upstream::ClusterManager& clusterManager() override { return *config_.clusterManager(); }
83
54
  Config::XdsManager& xdsManager() override { return *xds_manager_; }
84
  const Upstream::ClusterManager& clusterManager() const override {
85
    return *config_.clusterManager();
86
  }
87
49
  Http::HttpServerPropertiesCacheManager& httpServerPropertiesCacheManager() override {
88
49
    return *http_server_properties_cache_manager_;
89
49
  }
90
11
  Ssl::ContextManager& sslContextManager() override { return *ssl_context_manager_; }
91
635
  Event::Dispatcher& dispatcher() override { return *dispatcher_; }
92
  Network::DnsResolverSharedPtr dnsResolver() override;
93
4
  void drainListeners(OptRef<const Network::ExtraShutdownListenerOptions>) override {}
94
4
  DrainManager& drainManager() override { return *drain_manager_; }
95
8
  AccessLog::AccessLogManager& accessLogManager() override { return access_log_manager_; }
96
4
  void failHealthcheck(bool) override {}
97
4
  HotRestart& hotRestart() override { return nop_hot_restart_; }
98
38
  Init::Manager& initManager() override { return init_manager_; }
99
18
  ServerLifecycleNotifier& lifecycleNotifier() override { return *this; }
100
43
  ListenerManager& listenerManager() override { return *listener_manager_; }
101
7
  Secret::SecretManager& secretManager() override { return *secret_manager_; }
102
553
  Runtime::Loader& runtime() override { return *runtime_; }
103
  void shutdown() override;
104
4
  bool isShutdown() override { return false; }
105
4
  void shutdownAdmin() override {}
106
413
  Singleton::Manager& singletonManager() override { return singleton_manager_; }
107
55
  OverloadManager& overloadManager() override { return *overload_manager_; }
108
55
  OverloadManager& nullOverloadManager() override { return *null_overload_manager_; }
109
4
  bool healthCheckFailed() override { return false; }
110
286
  const Options& options() override { return options_; }
111
  time_t startTimeCurrentEpoch() override { PANIC("not implemented"); }
112
  time_t startTimeFirstEpoch() override { PANIC("not implemented"); }
113
455
  Stats::Store& stats() override { return stats_store_; }
114
53
  Grpc::Context& grpcContext() override { return grpc_context_; }
115
86
  Http::Context& httpContext() override { return http_context_; }
116
122
  Router::Context& routerContext() override { return router_context_; }
117
16
  ProcessContextOptRef processContext() override { return api_->processContext(); }
118
335
  ThreadLocal::Instance& threadLocal() override { return thread_local_; }
119
184
  LocalInfo::LocalInfo& localInfo() const override { return *local_info_; }
120
4
  TimeSource& timeSource() override { return api_->timeSource(); }
121
4
  Envoy::MutexTracer* mutexTracer() override { return mutex_tracer_; }
122
4
  void flushStats() override {}
123
417
  ProtobufMessage::ValidationContext& messageValidationContext() override {
124
417
    return validation_context_;
125
417
  }
126
135
  ProtobufMessage::ValidationVisitor& messageValidationVisitor() override {
127
135
    return validation_context_.staticValidationVisitor();
128
135
  }
129
43
  bool enableReusePortDefault() override { return true; }
130

            
131
57
  Configuration::StatsConfig& statsConfig() override { return config_.statsConfig(); }
132
2
  Regex::Engine& regexEngine() override { return *regex_engine_; }
133
3
  envoy::config::bootstrap::v3::Bootstrap& bootstrap() override { return bootstrap_; }
134
1090
  Configuration::ServerFactoryContext& serverFactoryContext() override { return server_contexts_; }
135
4
  Configuration::TransportSocketFactoryContext& transportSocketFactoryContext() override {
136
4
    return server_contexts_;
137
4
  }
138
49
  void setDefaultTracingConfig(const envoy::config::trace::v3::Tracing& tracing_config) override {
139
49
    http_context_.setDefaultTracingConfig(tracing_config);
140
49
  }
141
5
  void setSinkPredicates(std::unique_ptr<Stats::SinkPredicates>&&) override {}
142

            
143
  // Server::WorkerFactory
144
  WorkerPtr createWorker(uint32_t, OverloadManager&, OverloadManager&,
145
55
                         const std::string&) override {
146
    // Returned workers are not currently used so we can return nothing here safely vs. a
147
    // validation mock.
148
55
    return nullptr;
149
55
  }
150

            
151
  // ServerLifecycleNotifier
152
5
  ServerLifecycleNotifier::HandlePtr registerCallback(Stage, StageCallback) override {
153
5
    return nullptr;
154
5
  }
155
5
  ServerLifecycleNotifier::HandlePtr registerCallback(Stage, StageCallbackWithCompletion) override {
156
5
    return nullptr;
157
5
  }
158

            
159
private:
160
  void initialize(const Options& options,
161
                  const Network::Address::InstanceConstSharedPtr& local_address,
162
                  ComponentFactory& component_factory);
163

            
164
  // init_manager_ must come before any member that participates in initialization, and destructed
165
  // only after referencing members are gone, since initialization continuation can potentially
166
  // occur at any point during member lifetime.
167
  Init::ManagerImpl init_manager_{"Validation server"};
168
  Init::WatcherImpl init_watcher_{"(no-op)", []() {}};
169
  // secret_manager_ must come before listener_manager_, config_ and dispatcher_, and destructed
170
  // only after these members can no longer reference it, since:
171
  // - There may be active filter chains referencing it in listener_manager_.
172
  // - There may be active clusters referencing it in config_.cluster_manager_.
173
  // - There may be active connections referencing it.
174
  std::unique_ptr<Secret::SecretManager> secret_manager_;
175
  const Options& options_;
176
  ProtobufMessage::ProdValidationContextImpl validation_context_;
177
  Stats::IsolatedStoreImpl& stats_store_;
178
  ThreadLocal::InstanceImpl thread_local_;
179
  envoy::config::bootstrap::v3::Bootstrap bootstrap_;
180
  Api::ApiPtr api_;
181
  // ssl_context_manager_ must come before dispatcher_, since ClusterInfo
182
  // references SslSocketFactory and is deleted on the main thread via the dispatcher.
183
  std::unique_ptr<Ssl::ContextManager> ssl_context_manager_;
184
  Event::DispatcherPtr dispatcher_;
185
  std::unique_ptr<Server::ValidationAdmin> admin_;
186
  Singleton::ManagerImpl singleton_manager_;
187
  std::unique_ptr<Runtime::Loader> runtime_;
188
  Random::RandomGeneratorImpl random_generator_;
189
  Configuration::MainImpl config_;
190
  LocalInfo::LocalInfoPtr local_info_;
191
  AccessLog::AccessLogManagerImpl access_log_manager_;
192
  std::unique_ptr<Http::HttpServerPropertiesCacheManager> http_server_properties_cache_manager_;
193
  Config::XdsManagerPtr xds_manager_;
194
  std::unique_ptr<Upstream::ValidationClusterManagerFactory> cluster_manager_factory_;
195
  std::unique_ptr<ListenerManager> listener_manager_;
196
  std::unique_ptr<OverloadManager> overload_manager_;
197
  std::unique_ptr<OverloadManager> null_overload_manager_;
198
  MutexTracer* mutex_tracer_{nullptr};
199
  Grpc::ContextImpl grpc_context_;
200
  Http::ContextImpl http_context_;
201
  Router::ContextImpl router_context_;
202
  Event::TimeSystem& time_system_;
203
  ServerFactoryContextImpl server_contexts_;
204
  Quic::QuicStatNames quic_stat_names_;
205
  Filter::TcpListenerFilterConfigProviderManagerImpl tcp_listener_config_provider_manager_;
206
  Server::DrainManagerPtr drain_manager_;
207
  HotRestartNopImpl nop_hot_restart_;
208
  Regex::EnginePtr regex_engine_;
209
};
210

            
211
} // namespace Server
212
} // namespace Envoy