diff --git a/bazel/BUILD b/bazel/BUILD
index 11118ff8caabf..8c0c4224bae59 100644
--- a/bazel/BUILD
+++ b/bazel/BUILD
@@ -318,6 +318,11 @@ selects.config_setting_group(
],
)
+config_setting(
+ name = "disable_admin_html",
+ values = {"define": "admin_html=disabled"},
+)
+
config_setting(
name = "disable_hot_restart_setting",
values = {"define": "hot_restart=disabled"},
diff --git a/bazel/README.md b/bazel/README.md
index 042e83a34adcd..2f60fc0dc04df 100644
--- a/bazel/README.md
+++ b/bazel/README.md
@@ -661,6 +661,7 @@ The following optional features can be disabled on the Bazel build command-line:
tcmalloc with `--define tcmalloc=gperftools` which is the default for builds other than x86_64 and aarch64.
* deprecated features with `--define deprecated_features=disabled`
* http3/quic with --//bazel:http3=False
+* admin HTML home page with `--define=admin_html=disabled`
## Enabling optional features
diff --git a/bazel/envoy_build_system.bzl b/bazel/envoy_build_system.bzl
index f48ebe70564e9..f87903151df8d 100644
--- a/bazel/envoy_build_system.bzl
+++ b/bazel/envoy_build_system.bzl
@@ -18,6 +18,8 @@ load(
load(":envoy_pch.bzl", _envoy_pch_library = "envoy_pch_library")
load(
":envoy_select.bzl",
+ _envoy_select_admin_html = "envoy_select_admin_html",
+ _envoy_select_admin_no_html = "envoy_select_admin_no_html",
_envoy_select_boringssl = "envoy_select_boringssl",
_envoy_select_enable_http3 = "envoy_select_enable_http3",
_envoy_select_google_grpc = "envoy_select_google_grpc",
@@ -206,6 +208,8 @@ def envoy_google_grpc_external_deps():
# from the other bzl files (e.g. envoy_select.bzl, envoy_binary.bzl, etc.)
# Select wrappers (from envoy_select.bzl)
+envoy_select_admin_html = _envoy_select_admin_html
+envoy_select_admin_no_html = _envoy_select_admin_no_html
envoy_select_boringssl = _envoy_select_boringssl
envoy_select_google_grpc = _envoy_select_google_grpc
envoy_select_enable_http3 = _envoy_select_enable_http3
diff --git a/bazel/envoy_internal.bzl b/bazel/envoy_internal.bzl
index f2c15f6e0ba1c..76bce7f05a71f 100644
--- a/bazel/envoy_internal.bzl
+++ b/bazel/envoy_internal.bzl
@@ -1,6 +1,6 @@
# DO NOT LOAD THIS FILE. Targets from this file should be considered private
# and not used outside of the @envoy//bazel package.
-load(":envoy_select.bzl", "envoy_select_enable_http3", "envoy_select_google_grpc", "envoy_select_hot_restart")
+load(":envoy_select.bzl", "envoy_select_admin_html", "envoy_select_enable_http3", "envoy_select_google_grpc", "envoy_select_hot_restart")
# Compute the final copts based on various options.
def envoy_copts(repository, test = False):
@@ -122,6 +122,7 @@ def envoy_copts(repository, test = False):
repository + "//bazel:uhv_enabled": ["-DENVOY_ENABLE_UHV"],
"//conditions:default": [],
}) + envoy_select_hot_restart(["-DENVOY_HOT_RESTART"], repository) + \
+ envoy_select_admin_html(["-DENVOY_ADMIN_HTML"], repository) + \
envoy_select_enable_http3(["-DENVOY_ENABLE_QUIC"], repository) + \
_envoy_select_perf_annotation(["-DENVOY_PERF_ANNOTATION"]) + \
_envoy_select_perfetto(["-DENVOY_PERFETTO"]) + \
diff --git a/bazel/envoy_select.bzl b/bazel/envoy_select.bzl
index 4e664fe661868..50c34b8388b73 100644
--- a/bazel/envoy_select.bzl
+++ b/bazel/envoy_select.bzl
@@ -25,6 +25,19 @@ def envoy_select_google_grpc(xs, repository = ""):
"//conditions:default": xs,
})
+# Selects the given values if admin HTML is enabled in the current build.
+def envoy_select_admin_html(xs, repository = ""):
+ return select({
+ repository + "//bazel:disable_admin_html": [],
+ "//conditions:default": xs,
+ })
+
+def envoy_select_admin_no_html(xs, repository = ""):
+ return select({
+ repository + "//bazel:disable_admin_html": xs,
+ "//conditions:default": [],
+ })
+
# Selects the given values if http3 is enabled in the current build.
def envoy_select_enable_http3(xs, repository = ""):
return select({
diff --git a/changelogs/current.yaml b/changelogs/current.yaml
index f2f46e75a7f14..48e92fac53d43 100644
--- a/changelogs/current.yaml
+++ b/changelogs/current.yaml
@@ -57,8 +57,11 @@ minor_behavior_changes:
that loads shared object libraries, such as those installed via luarocks.
- area: admin
change: |
- changed default regex engine for /stats?filter= from std::regex to RE2, improving filtering speed
- 20x.
+ changed default regex engine for ``/stats?filter=`` from std::regex to RE2, improving
+ filtering speed 20x.
+- area: admin
+ change: |
+ added compile-time option ``--define=admin_html=disabled`` to disable HTML home page.
- area: skywalking
change: |
use request path as operation name of ENTRY/EXIT spans.
diff --git a/ci/do_ci.sh b/ci/do_ci.sh
index be00402efa65b..d85ae4bb80863 100755
--- a/ci/do_ci.sh
+++ b/ci/do_ci.sh
@@ -366,6 +366,7 @@ elif [[ "$CI_TARGET" == "bazel.compile_time_options" ]]; then
# Right now, none of the available compile-time options conflict with each other. If this
# changes, this build type may need to be broken up.
COMPILE_TIME_OPTIONS=(
+ "--define" "admin_html=disabled"
"--define" "signal_trace=disabled"
"--define" "hot_restart=disabled"
"--define" "google_grpc=disabled"
diff --git a/source/server/admin/BUILD b/source/server/admin/BUILD
index 69371bbb6c781..bbc3c475f76fe 100644
--- a/source/server/admin/BUILD
+++ b/source/server/admin/BUILD
@@ -2,6 +2,8 @@ load(
"//bazel:envoy_build_system.bzl",
"envoy_cc_library",
"envoy_package",
+ "envoy_select_admin_html",
+ "envoy_select_admin_no_html",
)
licenses(["notice"]) # Apache 2
@@ -10,7 +12,11 @@ envoy_package()
envoy_cc_library(
name = "admin_lib",
- srcs = ["admin.cc"],
+ srcs = ["admin.cc"] + envoy_select_admin_html([
+ "admin_html.cc",
+ ]) + envoy_select_admin_no_html([
+ "admin_no_html.cc",
+ ]),
hdrs = ["admin.h"],
deps = [
":admin_filter_lib",
@@ -45,7 +51,6 @@ envoy_cc_library(
"//source/common/common:mutex_tracer_lib",
"//source/common/common:utility_lib",
"//source/common/formatter:substitution_formatter_lib",
- "//source/common/html:utility_lib",
"//source/common/http:codes_lib",
"//source/common/http:conn_manager_lib",
"//source/common/http:date_provider_lib",
diff --git a/source/server/admin/admin.cc b/source/server/admin/admin.cc
index 9efe33c00a191..fe2dc58f5dde4 100644
--- a/source/server/admin/admin.cc
+++ b/source/server/admin/admin.cc
@@ -23,7 +23,6 @@
#include "source/common/common/mutex_tracer_impl.h"
#include "source/common/common/utility.h"
#include "source/common/formatter/substitution_formatter.h"
-#include "source/common/html/utility.h"
#include "source/common/http/codes.h"
#include "source/common/http/conn_manager_utility.h"
#include "source/common/http/header_map_impl.h"
@@ -45,72 +44,6 @@
namespace Envoy {
namespace Server {
-namespace {
-
-/**
- * Favicon base64 image was harvested by screen-capturing the favicon from a Chrome tab
- * while visiting https://www.envoyproxy.io/. The resulting PNG was translated to base64
- * by dropping it into https://www.base64-image.de/ and then pasting the resulting string
- * below.
- *
- * The actual favicon source for that, https://www.envoyproxy.io/img/favicon.ico is nicer
- * because it's transparent, but is also 67646 bytes, which is annoying to inline. We could
- * just reference that rather than inlining it, but then the favicon won't work when visiting
- * the admin page from a network that can't see the internet.
- */
-const char EnvoyFavicon[] =
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1"
- "BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAH9SURBVEhL7ZRdTttAFIUrUFaAX5w9gIhgUfzshFRK+gIbaVbA"
- "zwaqCly1dSpKk5A485/YCdXpHTB4BsdgVe0bD0cZ3Xsm38yZ8byTUuJ/6g3wqqoBrBhPTzmmLfptMbAzttJTpTKAF2MWC"
- "7ADCdNIwXZpvMMwayiIwwS874CcOc9VuQPR1dBBChPMITpFXXU45hukIIH6kHhzVqkEYB8F5HYGvZ5B7EvwmHt9K/59Cr"
- "U3QbY2RNYaQPYmJc+jPIBICNCcg20ZsAsCPfbcrFlRF+cJZpvXSJt9yMTxO/IAzJrCOfhJXiOgFEX/SbZmezTWxyNk4Q9"
- "anHMmjnzAhEyhAW8LCE6wl26J7ZFHH1FMYQxh567weQBOO1AW8D7P/UXAQySq/QvL8Fu9HfCEw4SKALm5BkC3bwjwhSKr"
- "A5hYAMXTJnPNiMyRBVzVjcgCyHiSm+8P+WGlnmwtP2RzbCMiQJ0d2KtmmmPorRHEhfMROVfTG5/fYrF5iWXzE80tfy9WP"
- "sCqx5Buj7FYH0LvDyHiqd+3otpsr4/fa5+xbEVQPfrYnntylQG5VGeMLBhgEfyE7o6e6qYzwHIjwl0QwXSvvTmrVAY4D5"
- "ddvT64wV0jRrr7FekO/XEjwuwwhuw7Ef7NY+dlfXpLb06EtHUJdVbsxvNUqBrwj/QGeEUSfwBAkmWHn5Bb/gAAAABJRU5";
-
-const char AdminHtmlStart[] = R"(
-
- Envoy Admin
-
-
-
-
-
-
-
Command
-
Description
-
-
-)";
-
-const char AdminHtmlEnd[] = R"(
-
-
-
-)";
-} // namespace
-
ConfigTracker& AdminImpl::getConfigTracker() { return config_tracker_; }
AdminImpl::NullRouteConfigProvider::NullRouteConfigProvider(TimeSource& time_source)
@@ -389,53 +322,6 @@ void AdminImpl::getHelp(Buffer::Instance& response) {
}
}
-Http::Code AdminImpl::handlerAdminHome(absl::string_view, Http::ResponseHeaderMap& response_headers,
- Buffer::Instance& response, AdminStream&) {
- response_headers.setReferenceContentType(Http::Headers::get().ContentTypeValues.Html);
-
- response.add(absl::StrReplaceAll(AdminHtmlStart, {{"@FAVICON@", EnvoyFavicon}}));
-
- // Prefix order is used during searching, but for printing do them in alpha order.
- for (const UrlHandler* handler : sortedHandlers()) {
- absl::string_view path = handler->prefix_;
-
- if (path == "/") {
- continue; // No need to print self-link to index page.
- }
-
- // Remove the leading slash from the link, so that the admin page can be
- // rendered as part of another console, on a sub-path.
- //
- // E.g. consider a downstream dashboard that embeds the Envoy admin console.
- // In that case, the "/stats" endpoint would be at
- // https://DASHBOARD/envoy_admin/stats. If the links we present on the home
- // page are absolute (e.g. "/stats") they won't work in the context of the
- // dashboard. Removing the leading slash, they will work properly in both
- // the raw admin console and when embedded in another page and URL
- // hierarchy.
- ASSERT(!path.empty());
- ASSERT(path[0] == '/');
- path = path.substr(1);
-
- // For handlers that mutate state, render the link as a button in a POST form,
- // rather than an anchor tag. This should discourage crawlers that find the /
- // page from accidentally mutating all the server state by GETting all the hrefs.
- const char* link_format =
- handler->mutates_server_state_
- ? ""
- : "{}";
- const std::string link = fmt::format(link_format, path, path);
-
- // Handlers are all specified by statically above, and are thus trusted and do
- // not require escaping.
- response.add(fmt::format("
{}
"
- "
{}
\n",
- link, Html::Utility::sanitize(handler->help_text_)));
- }
- response.add(AdminHtmlEnd);
- return Http::Code::OK;
-}
-
const Network::Address::Instance& AdminImpl::localAddress() {
return *server_.localInfo().address();
}
diff --git a/source/server/admin/admin_html.cc b/source/server/admin/admin_html.cc
new file mode 100644
index 0000000000000..3745bf85538d4
--- /dev/null
+++ b/source/server/admin/admin_html.cc
@@ -0,0 +1,122 @@
+#include "source/common/html/utility.h"
+#include "source/server/admin/admin.h"
+
+namespace Envoy {
+namespace Server {
+
+namespace {
+
+/**
+ * Favicon base64 image was harvested by screen-capturing the favicon from a Chrome tab
+ * while visiting https://www.envoyproxy.io/. The resulting PNG was translated to base64
+ * by dropping it into https://www.base64-image.de/ and then pasting the resulting string
+ * below.
+ *
+ * The actual favicon source for that, https://www.envoyproxy.io/img/favicon.ico is nicer
+ * because it's transparent, but is also 67646 bytes, which is annoying to inline. We could
+ * just reference that rather than inlining it, but then the favicon won't work when visiting
+ * the admin page from a network that can't see the internet.
+ */
+const char EnvoyFavicon[] =
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1"
+ "BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAH9SURBVEhL7ZRdTttAFIUrUFaAX5w9gIhgUfzshFRK+gIbaVbA"
+ "zwaqCly1dSpKk5A485/YCdXpHTB4BsdgVe0bD0cZ3Xsm38yZ8byTUuJ/6g3wqqoBrBhPTzmmLfptMbAzttJTpTKAF2MWC"
+ "7ADCdNIwXZpvMMwayiIwwS874CcOc9VuQPR1dBBChPMITpFXXU45hukIIH6kHhzVqkEYB8F5HYGvZ5B7EvwmHt9K/59Cr"
+ "U3QbY2RNYaQPYmJc+jPIBICNCcg20ZsAsCPfbcrFlRF+cJZpvXSJt9yMTxO/IAzJrCOfhJXiOgFEX/SbZmezTWxyNk4Q9"
+ "anHMmjnzAhEyhAW8LCE6wl26J7ZFHH1FMYQxh567weQBOO1AW8D7P/UXAQySq/QvL8Fu9HfCEw4SKALm5BkC3bwjwhSKr"
+ "A5hYAMXTJnPNiMyRBVzVjcgCyHiSm+8P+WGlnmwtP2RzbCMiQJ0d2KtmmmPorRHEhfMROVfTG5/fYrF5iWXzE80tfy9WP"
+ "sCqx5Buj7FYH0LvDyHiqd+3otpsr4/fa5+xbEVQPfrYnntylQG5VGeMLBhgEfyE7o6e6qYzwHIjwl0QwXSvvTmrVAY4D5"
+ "ddvT64wV0jRrr7FekO/XEjwuwwhuw7Ef7NY+dlfXpLb06EtHUJdVbsxvNUqBrwj/QGeEUSfwBAkmWHn5Bb/gAAAABJRU5";
+
+const char AdminHtmlStart[] = R"(
+
+ Envoy Admin
+
+
+
+
+
+
+
Command
+
Description
+
+
+)";
+
+const char AdminHtmlEnd[] = R"(
+
+
+
+)";
+
+} // namespace
+
+Http::Code AdminImpl::handlerAdminHome(absl::string_view, Http::ResponseHeaderMap& response_headers,
+ Buffer::Instance& response, AdminStream&) {
+ response_headers.setReferenceContentType(Http::Headers::get().ContentTypeValues.Html);
+
+ response.add(absl::StrReplaceAll(AdminHtmlStart, {{"@FAVICON@", EnvoyFavicon}}));
+
+ // Prefix order is used during searching, but for printing do them in alpha order.
+ for (const UrlHandler* handler : sortedHandlers()) {
+ absl::string_view path = handler->prefix_;
+
+ if (path == "/") {
+ continue; // No need to print self-link to index page.
+ }
+
+ // Remove the leading slash from the link, so that the admin page can be
+ // rendered as part of another console, on a sub-path.
+ //
+ // E.g. consider a downstream dashboard that embeds the Envoy admin console.
+ // In that case, the "/stats" endpoint would be at
+ // https://DASHBOARD/envoy_admin/stats. If the links we present on the home
+ // page are absolute (e.g. "/stats") they won't work in the context of the
+ // dashboard. Removing the leading slash, they will work properly in both
+ // the raw admin console and when embedded in another page and URL
+ // hierarchy.
+ ASSERT(!path.empty());
+ ASSERT(path[0] == '/');
+ path = path.substr(1);
+
+ // For handlers that mutate state, render the link as a button in a POST form,
+ // rather than an anchor tag. This should discourage crawlers that find the /
+ // page from accidentally mutating all the server state by GETting all the hrefs.
+ const char* link_format =
+ handler->mutates_server_state_
+ ? ""
+ : "{}";
+ const std::string link = fmt::format(link_format, path, path);
+
+ // Handlers are all specified by statically above, and are thus trusted and do
+ // not require escaping.
+ response.add(fmt::format("