-
Notifications
You must be signed in to change notification settings - Fork 5.3k
admin: Richer HTML home page with forms for params #19546
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c4101e1
29cf776
94c97c0
aa00670
34c7607
4e821b4
8cbcf36
ff2aaf9
1e4d606
256b6c9
49212f6
ba5a1dc
c78b6a4
33b2f22
efe142e
78091d1
119270c
68a89d2
70ce924
71c1647
d04a05c
85d33f7
d482473
d42f01a
2c4422a
594b618
102d95c
a5706e1
a4de093
246af3a
987e764
5f5ae3c
c9041e6
afbcf1a
3fc02f0
fc5ac30
7bb3a00
6dcac05
81f2763
329281b
c537b80
25c871e
685e307
182c26d
fecece3
f187c65
d16f773
2ec28de
e23c884
4f59d62
c2350a2
c9a0467
e8abc92
bfb734a
752ae63
e8d16fd
abe2049
ab028cf
d9d03c8
b28dd55
1b95d3b
048d239
93fe3f3
5c0fd6c
85cde04
b626917
ddda5d7
2a62570
03be332
ce6e904
26f200d
50dbe5a
0859243
603f0f8
1cc67ca
ee21f74
379b316
a7b3565
c456954
8c3af8b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -99,10 +99,26 @@ AdminImpl::AdminImpl(const std::string& profile_path, Server::Instance& server, | |
| MAKE_ADMIN_HANDLER(server_info_handler_.handlerCerts), false, false), | ||
| makeHandler("/clusters", "upstream cluster status", | ||
| MAKE_ADMIN_HANDLER(clusters_handler_.handlerClusters), false, false), | ||
| makeHandler("/config_dump", "dump current Envoy configs (experimental)", | ||
| MAKE_ADMIN_HANDLER(config_dump_handler_.handlerConfigDump), false, false), | ||
| makeHandler( | ||
| "/config_dump", "dump current Envoy configs (experimental)", | ||
| MAKE_ADMIN_HANDLER(config_dump_handler_.handlerConfigDump), false, false, | ||
| {{Admin::ParamDescriptor::Type::String, "resource", "The resource to dump"}, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is missing certain parameters listed on the doc page:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I realized that and was thinking of filling in all the new parameters that were added since I first wrote this code as a follow up. However I'm glad you asked about this because this brings a new complexity. I'll get that sorted before asking for the next round of comments. /wait
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I decided to back out my addition of POST params in this PR and will follow up. I got this working but it was too hacky. I need to make some infrastructural changes to get POST params to work well, and also to handling the "/logging" semantics for an optional enum param. |
||
| {Admin::ParamDescriptor::Type::String, "mask", | ||
| "The mask to apply. When both resource and mask are specified, " | ||
| "the mask is applied to every element in the desired repeated field so that only a " | ||
| "subset of fields are returned. The mask is parsed as a ProtobufWkt::FieldMask"}, | ||
| {Admin::ParamDescriptor::Type::String, "name_regex", | ||
| "Dump only the currently loaded configurations whose names match the specified " | ||
| "regex. Can be used with both resource and mask query parameters."}, | ||
| {Admin::ParamDescriptor::Type::Boolean, "include_eds", | ||
| "Dump currently loaded configuration including EDS. See the response definition " | ||
| "for more information"}}), | ||
| makeHandler("/init_dump", "dump current Envoy init manager information (experimental)", | ||
| MAKE_ADMIN_HANDLER(init_dump_handler_.handlerInitDump), false, false), | ||
| MAKE_ADMIN_HANDLER(init_dump_handler_.handlerInitDump), false, false, | ||
| {{Admin::ParamDescriptor::Type::String, "mask", | ||
| "The desired component to dump unready targets. The mask is parsed as " | ||
| "a ProtobufWkt::FieldMask. For example, get the unready targets of " | ||
| "all listeners with /init_dump?mask=listener`"}}), | ||
| makeHandler("/contention", "dump current Envoy mutex contention stats (if enabled)", | ||
| MAKE_ADMIN_HANDLER(stats_handler_.handlerContention), false, false), | ||
| makeHandler("/cpuprofiler", "enable/disable the CPU profiler", | ||
|
|
@@ -118,8 +134,13 @@ AdminImpl::AdminImpl(const std::string& profile_path, Server::Instance& server, | |
| makeHandler("/hot_restart_version", "print the hot restart compatibility version", | ||
| MAKE_ADMIN_HANDLER(server_info_handler_.handlerHotRestartVersion), false, | ||
| false), | ||
|
|
||
| // TODO(jmarantz): add support for param-passing through a POST. Browsers send | ||
| // those params as the post-body rather than query-params and that requires some | ||
| // re-plumbing through the admin callback API. See also drain_listeners. | ||
| makeHandler("/logging", "query/change logging levels", | ||
| MAKE_ADMIN_HANDLER(logs_handler_.handlerLogging), false, true), | ||
|
|
||
| makeHandler("/memory", "print current allocation/heap usage", | ||
| MAKE_ADMIN_HANDLER(server_info_handler_.handlerMemory), false, false), | ||
| makeHandler("/quitquitquit", "exit the server", | ||
|
|
@@ -132,9 +153,16 @@ AdminImpl::AdminImpl(const std::string& profile_path, Server::Instance& server, | |
| MAKE_ADMIN_HANDLER(server_info_handler_.handlerServerInfo), false, false), | ||
| makeHandler("/ready", "print server state, return 200 if LIVE, otherwise return 503", | ||
| MAKE_ADMIN_HANDLER(server_info_handler_.handlerReady), false, false), | ||
| makeStreamingHandler("/stats", "print server stats", stats_handler_, false, false), | ||
| stats_handler_.statsHandler(), | ||
| makeHandler("/stats/prometheus", "print server stats in prometheus format", | ||
| MAKE_ADMIN_HANDLER(stats_handler_.handlerPrometheusStats), false, false), | ||
| MAKE_ADMIN_HANDLER(stats_handler_.handlerPrometheusStats), false, false, | ||
| {{ParamDescriptor::Type::Boolean, "usedonly", | ||
| "Only include stats that have been written by system since restart"}, | ||
| {ParamDescriptor::Type::Boolean, "text_readouts", | ||
| "Render text_readouts as new gaugues with value 0 (increases Prometheus " | ||
| "data size)"}, | ||
| {ParamDescriptor::Type::String, "filter", | ||
| "Regular expression (ecmascript) for filtering stats"}}), | ||
| makeHandler("/stats/recentlookups", "Show recent stat-name lookups", | ||
| MAKE_ADMIN_HANDLER(stats_handler_.handlerStatsRecentLookups), false, false), | ||
| makeHandler("/stats/recentlookups/clear", "clear list of stat-name lookups and counter", | ||
|
|
@@ -147,18 +175,35 @@ AdminImpl::AdminImpl(const std::string& profile_path, Server::Instance& server, | |
| "/stats/recentlookups/enable", "enable recording of reset stat-name lookup names", | ||
| MAKE_ADMIN_HANDLER(stats_handler_.handlerStatsRecentLookupsEnable), false, true), | ||
| makeHandler("/listeners", "print listener info", | ||
| MAKE_ADMIN_HANDLER(listeners_handler_.handlerListenerInfo), false, false), | ||
| MAKE_ADMIN_HANDLER(listeners_handler_.handlerListenerInfo), false, false, | ||
| {{Admin::ParamDescriptor::Type::Enum, | ||
| "format", | ||
| "File format to use", | ||
| {"text", "json"}}}), | ||
| makeHandler("/runtime", "print runtime values", | ||
| MAKE_ADMIN_HANDLER(runtime_handler_.handlerRuntime), false, false), | ||
| makeHandler("/runtime_modify", "modify runtime values", | ||
| makeHandler("/runtime_modify", | ||
| "Adds or modifies runtime values as passed in query parameters. To delete a " | ||
| "previously added key, use an empty string as the value. Note that deletion " | ||
| "only applies to overrides added via this endpoint; values loaded from disk " | ||
| "can be modified via override but not deleted. E.g. " | ||
| "?key1=value1&key2=value2...", | ||
| MAKE_ADMIN_HANDLER(runtime_handler_.handlerRuntimeModify), false, true), | ||
| makeHandler("/reopen_logs", "reopen access logs", | ||
| MAKE_ADMIN_HANDLER(logs_handler_.handlerReopenLogs), false, true), | ||
| }, | ||
| date_provider_(server.dispatcher().timeSource()), | ||
| admin_filter_chain_(std::make_shared<AdminFilterChain>()), | ||
| local_reply_(LocalReply::Factory::createDefault()), | ||
| ignore_global_conn_limit_(ignore_global_conn_limit) {} | ||
| ignore_global_conn_limit_(ignore_global_conn_limit) { | ||
| #ifndef NDEBUG | ||
| // Verify that no duplicate handlers exist. | ||
| absl::flat_hash_set<absl::string_view> handlers; | ||
| for (const UrlHandler& handler : handlers_) { | ||
| ASSERT(handlers.insert(handler.prefix_).second); | ||
| } | ||
| #endif | ||
| } | ||
|
|
||
| Http::ServerConnectionPtr AdminImpl::createCodec(Network::Connection& connection, | ||
| const Buffer::Instance& data, | ||
|
|
@@ -322,6 +367,13 @@ void AdminImpl::getHelp(Buffer::Instance& response) { | |
| // Prefix order is used during searching, but for printing do them in alpha order. | ||
| for (const UrlHandler* handler : sortedHandlers()) { | ||
| response.add(fmt::format(" {}: {}\n", handler->prefix_, handler->help_text_)); | ||
| for (const ParamDescriptor& param : handler->params_) { | ||
| response.add(fmt::format(" {}: {}", param.id_, param.help_)); | ||
| if (param.type_ == ParamDescriptor::Type::Enum) { | ||
| response.addFragments({"; One of (", absl::StrJoin(param.enum_choices_, ", "), ")"}); | ||
| } | ||
| response.add("\n"); | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -331,12 +383,15 @@ const Network::Address::Instance& AdminImpl::localAddress() { | |
|
|
||
| AdminImpl::UrlHandler AdminImpl::makeHandler(const std::string& prefix, | ||
| const std::string& help_text, HandlerCb callback, | ||
| bool removable, bool mutates_state) { | ||
| return UrlHandler{prefix, help_text, RequestGasket::makeGen(callback), removable, mutates_state}; | ||
| bool removable, bool mutates_state, | ||
| const ParamDescriptorVec& params) { | ||
| return UrlHandler{prefix, help_text, RequestGasket::makeGen(callback), | ||
| removable, mutates_state, params}; | ||
| } | ||
|
|
||
| bool AdminImpl::addStreamingHandler(const std::string& prefix, const std::string& help_text, | ||
| GenRequestFn callback, bool removable, bool mutates_state) { | ||
| GenRequestFn callback, bool removable, bool mutates_state, | ||
| const ParamDescriptorVec& params) { | ||
| ASSERT(prefix.size() > 1); | ||
| ASSERT(prefix[0] == '/'); | ||
|
|
||
|
|
@@ -353,16 +408,17 @@ bool AdminImpl::addStreamingHandler(const std::string& prefix, const std::string | |
| auto it = std::find_if(handlers_.cbegin(), handlers_.cend(), | ||
| [&prefix](const UrlHandler& entry) { return prefix == entry.prefix_; }); | ||
| if (it == handlers_.end()) { | ||
| handlers_.push_back({prefix, help_text, callback, removable, mutates_state}); | ||
| handlers_.push_back({prefix, help_text, callback, removable, mutates_state, params}); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| bool AdminImpl::addHandler(const std::string& prefix, const std::string& help_text, | ||
| HandlerCb callback, bool removable, bool mutates_state) { | ||
| HandlerCb callback, bool removable, bool mutates_state, | ||
| const ParamDescriptorVec& params) { | ||
| return addStreamingHandler(prefix, help_text, RequestGasket::makeGen(callback), removable, | ||
| mutates_state); | ||
| mutates_state, params); | ||
| } | ||
|
|
||
| bool AdminImpl::removeHandler(const std::string& prefix) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| .home-table { | ||
| font-family: sans-serif; | ||
| font-size: medium; | ||
| border-collapse: collapse; | ||
| border-spacing: 0; | ||
| } | ||
|
|
||
| .home-data { | ||
| text-align: left; | ||
| padding: 4px; | ||
| } | ||
|
|
||
| .home-form { | ||
| margin-bottom: 0; | ||
| } | ||
|
|
||
| .button-as-link { | ||
| background: none!important; | ||
| border: none; | ||
| padding: 0!important; | ||
| font-family: sans-serif; | ||
| font-size: medium; | ||
| color: #069; | ||
| text-decoration: underline; | ||
| cursor: pointer; | ||
| } | ||
|
|
||
| .gray { | ||
| background-color: #dddddd; | ||
| } | ||
|
|
||
| .vert-space { | ||
| height: 4px; | ||
| } | ||
|
|
||
| .option { | ||
| padding-bottom: 4px; | ||
| padding-top: 4px; | ||
| padding-right: 4px; | ||
| padding-left: 20px; | ||
| text-align: right; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to have an assert in the constructor body that there are no duplicate prefixes in handlers_ ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.