mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
Add flatz to kubelet auth.
Fix: Move flagz to InstallDebuggingHandlers. Move flagz to the lower switch statemen Fix linter Drop the function parameter for the read-only server.
This commit is contained in:
parent
7b6c56e5fb
commit
2db729cfa4
@ -86,6 +86,8 @@ import (
|
|||||||
"k8s.io/component-base/tracing"
|
"k8s.io/component-base/tracing"
|
||||||
"k8s.io/component-base/version"
|
"k8s.io/component-base/version"
|
||||||
"k8s.io/component-base/version/verflag"
|
"k8s.io/component-base/version/verflag"
|
||||||
|
zpagesfeatures "k8s.io/component-base/zpages/features"
|
||||||
|
"k8s.io/component-base/zpages/flagz"
|
||||||
nodeutil "k8s.io/component-helpers/node/util"
|
nodeutil "k8s.io/component-helpers/node/util"
|
||||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||||
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
|
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
|
||||||
@ -267,6 +269,13 @@ is checked every 20 seconds (also configurable with a flag).`,
|
|||||||
return fmt.Errorf("failed to construct kubelet dependencies: %w", err)
|
return fmt.Errorf("failed to construct kubelet dependencies: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentFlagz) {
|
||||||
|
if cleanFlagSet != nil {
|
||||||
|
namedFlagSet := map[string]*pflag.FlagSet{server.ComponentKubelet: cleanFlagSet}
|
||||||
|
kubeletDeps.Flagz = flagz.NamedFlagSetsReader{FlagSets: cliflag.NamedFlagSets{FlagSets: namedFlagSet}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := checkPermissions(); err != nil {
|
if err := checkPermissions(); err != nil {
|
||||||
klog.ErrorS(err, "kubelet running with insufficient permissions")
|
klog.ErrorS(err, "kubelet running with insufficient permissions")
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ import (
|
|||||||
"k8s.io/client-go/util/certificate"
|
"k8s.io/client-go/util/certificate"
|
||||||
"k8s.io/client-go/util/flowcontrol"
|
"k8s.io/client-go/util/flowcontrol"
|
||||||
cloudprovider "k8s.io/cloud-provider"
|
cloudprovider "k8s.io/cloud-provider"
|
||||||
|
"k8s.io/component-base/zpages/flagz"
|
||||||
"k8s.io/component-helpers/apimachinery/lease"
|
"k8s.io/component-helpers/apimachinery/lease"
|
||||||
internalapi "k8s.io/cri-api/pkg/apis"
|
internalapi "k8s.io/cri-api/pkg/apis"
|
||||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||||
@ -292,6 +293,7 @@ type Dependencies struct {
|
|||||||
Options []Option
|
Options []Option
|
||||||
|
|
||||||
// Injected Dependencies
|
// Injected Dependencies
|
||||||
|
Flagz flagz.Reader
|
||||||
Auth server.AuthInterface
|
Auth server.AuthInterface
|
||||||
CAdvisorInterface cadvisor.Interface
|
CAdvisorInterface cadvisor.Interface
|
||||||
Cloud cloudprovider.Interface
|
Cloud cloudprovider.Interface
|
||||||
@ -616,6 +618,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||||||
nodeStatusMaxImages: nodeStatusMaxImages,
|
nodeStatusMaxImages: nodeStatusMaxImages,
|
||||||
tracer: tracer,
|
tracer: tracer,
|
||||||
nodeStartupLatencyTracker: kubeDeps.NodeStartupLatencyTracker,
|
nodeStartupLatencyTracker: kubeDeps.NodeStartupLatencyTracker,
|
||||||
|
flagz: kubeDeps.Flagz,
|
||||||
}
|
}
|
||||||
|
|
||||||
if klet.cloud != nil {
|
if klet.cloud != nil {
|
||||||
@ -1433,6 +1436,9 @@ type Kubelet struct {
|
|||||||
|
|
||||||
// Health check kubelet
|
// Health check kubelet
|
||||||
healthChecker watchdog.HealthChecker
|
healthChecker watchdog.HealthChecker
|
||||||
|
|
||||||
|
// flagz is the Reader interface to get flags for flagz page.
|
||||||
|
flagz flagz.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListPodStats is delegated to StatsProvider, which implements stats.Provider interface
|
// ListPodStats is delegated to StatsProvider, which implements stats.Provider interface
|
||||||
@ -3084,12 +3090,12 @@ func (kl *Kubelet) BirthCry() {
|
|||||||
// ListenAndServe runs the kubelet HTTP server.
|
// ListenAndServe runs the kubelet HTTP server.
|
||||||
func (kl *Kubelet) ListenAndServe(kubeCfg *kubeletconfiginternal.KubeletConfiguration, tlsOptions *server.TLSOptions,
|
func (kl *Kubelet) ListenAndServe(kubeCfg *kubeletconfiginternal.KubeletConfiguration, tlsOptions *server.TLSOptions,
|
||||||
auth server.AuthInterface, tp trace.TracerProvider) {
|
auth server.AuthInterface, tp trace.TracerProvider) {
|
||||||
server.ListenAndServeKubeletServer(kl, kl.resourceAnalyzer, kl.containerManager.GetHealthCheckers(), kubeCfg, tlsOptions, auth, tp)
|
server.ListenAndServeKubeletServer(kl, kl.resourceAnalyzer, kl.containerManager.GetHealthCheckers(), kl.flagz, kubeCfg, tlsOptions, auth, tp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListenAndServeReadOnly runs the kubelet HTTP server in read-only mode.
|
// ListenAndServeReadOnly runs the kubelet HTTP server in read-only mode.
|
||||||
func (kl *Kubelet) ListenAndServeReadOnly(address net.IP, port uint, tp trace.TracerProvider) {
|
func (kl *Kubelet) ListenAndServeReadOnly(address net.IP, port uint, tp trace.TracerProvider) {
|
||||||
server.ListenAndServeKubeletReadOnlyServer(kl, kl.resourceAnalyzer, kl.containerManager.GetHealthCheckers(), address, port, tp)
|
server.ListenAndServeKubeletReadOnlyServer(kl, kl.resourceAnalyzer, kl.containerManager.GetHealthCheckers(), kl.flagz, address, port, tp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListenAndServePodResources runs the kubelet podresources grpc service
|
// ListenAndServePodResources runs the kubelet podresources grpc service
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/server/healthz"
|
"k8s.io/apiserver/pkg/server/healthz"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
"k8s.io/component-base/configz"
|
"k8s.io/component-base/configz"
|
||||||
|
"k8s.io/component-base/zpages/flagz"
|
||||||
"k8s.io/component-base/zpages/statusz"
|
"k8s.io/component-base/zpages/statusz"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
"k8s.io/kubernetes/pkg/features"
|
||||||
@ -74,6 +75,7 @@ func isSubpath(subpath, path string) bool {
|
|||||||
// /runningPods/* => verb=<api verb from request>, resource=nodes, name=<node name>, subresource(s)=pods,proxy
|
// /runningPods/* => verb=<api verb from request>, resource=nodes, name=<node name>, subresource(s)=pods,proxy
|
||||||
// /healthz/* => verb=<api verb from request>, resource=nodes, name=<node name>, subresource(s)=healthz,proxy
|
// /healthz/* => verb=<api verb from request>, resource=nodes, name=<node name>, subresource(s)=healthz,proxy
|
||||||
// /configz => verb=<api verb from request>, resource=nodes, name=<node name>, subresource(s)=configz,proxy
|
// /configz => verb=<api verb from request>, resource=nodes, name=<node name>, subresource(s)=configz,proxy
|
||||||
|
// /flagz => verb=<api verb from request>, resource=nodes, name=<node name>, subresource(s)=configz,proxy
|
||||||
func (n nodeAuthorizerAttributesGetter) GetRequestAttributes(u user.Info, r *http.Request) []authorizer.Attributes {
|
func (n nodeAuthorizerAttributesGetter) GetRequestAttributes(u user.Info, r *http.Request) []authorizer.Attributes {
|
||||||
|
|
||||||
apiVerb := ""
|
apiVerb := ""
|
||||||
@ -120,6 +122,8 @@ func (n nodeAuthorizerAttributesGetter) GetRequestAttributes(u user.Info, r *htt
|
|||||||
subresources = append(subresources, "checkpoint")
|
subresources = append(subresources, "checkpoint")
|
||||||
case isSubpath(requestPath, statusz.DefaultStatuszPath):
|
case isSubpath(requestPath, statusz.DefaultStatuszPath):
|
||||||
subresources = append(subresources, "statusz")
|
subresources = append(subresources, "statusz")
|
||||||
|
case isSubpath(requestPath, flagz.DefaultFlagzPath):
|
||||||
|
subresources = append(subresources, "configz")
|
||||||
default:
|
default:
|
||||||
subresources = append(subresources, "proxy")
|
subresources = append(subresources, "proxy")
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,7 @@ func AuthzTestCases(fineGrained bool) []AuthzTestCase {
|
|||||||
"/attach/{podNamespace}/{podID}/{uid}/{containerName}": {"proxy"},
|
"/attach/{podNamespace}/{podID}/{uid}/{containerName}": {"proxy"},
|
||||||
"/checkpoint/{podNamespace}/{podID}/{containerName}": {"checkpoint"},
|
"/checkpoint/{podNamespace}/{podID}/{containerName}": {"checkpoint"},
|
||||||
"/configz": {"proxy"},
|
"/configz": {"proxy"},
|
||||||
|
"/flagz": {"configz"},
|
||||||
"/statusz": {"statusz"},
|
"/statusz": {"statusz"},
|
||||||
"/containerLogs/{podNamespace}/{podID}/{containerName}": {"proxy"},
|
"/containerLogs/{podNamespace}/{podID}/{containerName}": {"proxy"},
|
||||||
"/debug/flags/v": {"proxy"},
|
"/debug/flags/v": {"proxy"},
|
||||||
|
@ -69,6 +69,7 @@ import (
|
|||||||
"k8s.io/component-base/metrics/legacyregistry"
|
"k8s.io/component-base/metrics/legacyregistry"
|
||||||
"k8s.io/component-base/metrics/prometheus/slis"
|
"k8s.io/component-base/metrics/prometheus/slis"
|
||||||
zpagesfeatures "k8s.io/component-base/zpages/features"
|
zpagesfeatures "k8s.io/component-base/zpages/features"
|
||||||
|
"k8s.io/component-base/zpages/flagz"
|
||||||
"k8s.io/component-base/zpages/statusz"
|
"k8s.io/component-base/zpages/statusz"
|
||||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||||
"k8s.io/cri-client/pkg/util"
|
"k8s.io/cri-client/pkg/util"
|
||||||
@ -117,6 +118,7 @@ const (
|
|||||||
|
|
||||||
// Server is a http.Handler which exposes kubelet functionality over HTTP.
|
// Server is a http.Handler which exposes kubelet functionality over HTTP.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
|
flagz flagz.Reader
|
||||||
auth AuthInterface
|
auth AuthInterface
|
||||||
host HostInterface
|
host HostInterface
|
||||||
restfulCont containerInterface
|
restfulCont containerInterface
|
||||||
@ -167,6 +169,7 @@ func ListenAndServeKubeletServer(
|
|||||||
host HostInterface,
|
host HostInterface,
|
||||||
resourceAnalyzer stats.ResourceAnalyzer,
|
resourceAnalyzer stats.ResourceAnalyzer,
|
||||||
checkers []healthz.HealthChecker,
|
checkers []healthz.HealthChecker,
|
||||||
|
flagz flagz.Reader,
|
||||||
kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
||||||
tlsOptions *TLSOptions,
|
tlsOptions *TLSOptions,
|
||||||
auth AuthInterface,
|
auth AuthInterface,
|
||||||
@ -175,7 +178,7 @@ func ListenAndServeKubeletServer(
|
|||||||
address := netutils.ParseIPSloppy(kubeCfg.Address)
|
address := netutils.ParseIPSloppy(kubeCfg.Address)
|
||||||
port := uint(kubeCfg.Port)
|
port := uint(kubeCfg.Port)
|
||||||
klog.InfoS("Starting to listen", "address", address, "port", port)
|
klog.InfoS("Starting to listen", "address", address, "port", port)
|
||||||
handler := NewServer(host, resourceAnalyzer, checkers, auth, kubeCfg)
|
handler := NewServer(host, resourceAnalyzer, checkers, flagz, auth, kubeCfg)
|
||||||
|
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.KubeletTracing) {
|
if utilfeature.DefaultFeatureGate.Enabled(features.KubeletTracing) {
|
||||||
handler.InstallTracingFilter(tp)
|
handler.InstallTracingFilter(tp)
|
||||||
@ -210,11 +213,12 @@ func ListenAndServeKubeletReadOnlyServer(
|
|||||||
host HostInterface,
|
host HostInterface,
|
||||||
resourceAnalyzer stats.ResourceAnalyzer,
|
resourceAnalyzer stats.ResourceAnalyzer,
|
||||||
checkers []healthz.HealthChecker,
|
checkers []healthz.HealthChecker,
|
||||||
|
flagz flagz.Reader,
|
||||||
address net.IP,
|
address net.IP,
|
||||||
port uint,
|
port uint,
|
||||||
tp oteltrace.TracerProvider) {
|
tp oteltrace.TracerProvider) {
|
||||||
klog.InfoS("Starting to listen read-only", "address", address, "port", port)
|
klog.InfoS("Starting to listen read-only", "address", address, "port", port)
|
||||||
s := NewServer(host, resourceAnalyzer, checkers, nil, nil)
|
s := NewServer(host, resourceAnalyzer, checkers, nil, nil, nil)
|
||||||
|
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.KubeletTracing) {
|
if utilfeature.DefaultFeatureGate.Enabled(features.KubeletTracing) {
|
||||||
s.InstallTracingFilter(tp, otelrestful.WithPublicEndpoint())
|
s.InstallTracingFilter(tp, otelrestful.WithPublicEndpoint())
|
||||||
@ -291,10 +295,12 @@ func NewServer(
|
|||||||
host HostInterface,
|
host HostInterface,
|
||||||
resourceAnalyzer stats.ResourceAnalyzer,
|
resourceAnalyzer stats.ResourceAnalyzer,
|
||||||
checkers []healthz.HealthChecker,
|
checkers []healthz.HealthChecker,
|
||||||
|
flagz flagz.Reader,
|
||||||
auth AuthInterface,
|
auth AuthInterface,
|
||||||
kubeCfg *kubeletconfiginternal.KubeletConfiguration) Server {
|
kubeCfg *kubeletconfiginternal.KubeletConfiguration) Server {
|
||||||
|
|
||||||
server := Server{
|
server := Server{
|
||||||
|
flagz: flagz,
|
||||||
host: host,
|
host: host,
|
||||||
resourceAnalyzer: resourceAnalyzer,
|
resourceAnalyzer: resourceAnalyzer,
|
||||||
auth: auth,
|
auth: auth,
|
||||||
@ -575,6 +581,13 @@ func (s *Server) InstallAuthRequiredHandlers() {
|
|||||||
statusz.Install(s.restfulCont, ComponentKubelet, statusz.NewRegistry(compatibility.DefaultBuildEffectiveVersion()))
|
statusz.Install(s.restfulCont, ComponentKubelet, statusz.NewRegistry(compatibility.DefaultBuildEffectiveVersion()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentFlagz) {
|
||||||
|
if s.flagz != nil {
|
||||||
|
s.addMetricsBucketMatcher("flagz")
|
||||||
|
flagz.Install(s.restfulCont, ComponentKubelet, s.flagz)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The /runningpods endpoint is used for testing only.
|
// The /runningpods endpoint is used for testing only.
|
||||||
s.addMetricsBucketMatcher("runningpods")
|
s.addMetricsBucketMatcher("runningpods")
|
||||||
ws = new(restful.WebService)
|
ws = new(restful.WebService)
|
||||||
|
@ -59,6 +59,7 @@ import (
|
|||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||||
zpagesfeatures "k8s.io/component-base/zpages/features"
|
zpagesfeatures "k8s.io/component-base/zpages/features"
|
||||||
|
"k8s.io/component-base/zpages/flagz"
|
||||||
"k8s.io/kubelet/pkg/cri/streaming"
|
"k8s.io/kubelet/pkg/cri/streaming"
|
||||||
"k8s.io/kubelet/pkg/cri/streaming/portforward"
|
"k8s.io/kubelet/pkg/cri/streaming/portforward"
|
||||||
remotecommandserver "k8s.io/kubelet/pkg/cri/streaming/remotecommand"
|
remotecommandserver "k8s.io/kubelet/pkg/cri/streaming/remotecommand"
|
||||||
@ -373,6 +374,7 @@ func newServerTestWithDebuggingHandlers(kubeCfg *kubeletconfiginternal.KubeletCo
|
|||||||
fw.fakeKubelet,
|
fw.fakeKubelet,
|
||||||
stats.NewResourceAnalyzer(fw.fakeKubelet, time.Minute, &record.FakeRecorder{}),
|
stats.NewResourceAnalyzer(fw.fakeKubelet, time.Minute, &record.FakeRecorder{}),
|
||||||
[]healthz.HealthChecker{},
|
[]healthz.HealthChecker{},
|
||||||
|
flagz.NamedFlagSetsReader{},
|
||||||
fw.fakeAuth,
|
fw.fakeAuth,
|
||||||
kubeCfg,
|
kubeCfg,
|
||||||
)
|
)
|
||||||
@ -646,6 +648,7 @@ func TestAuthFilters(t *testing.T) {
|
|||||||
// Enable features.ContainerCheckpoint during test
|
// Enable features.ContainerCheckpoint during test
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ContainerCheckpoint, true)
|
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ContainerCheckpoint, true)
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, zpagesfeatures.ComponentStatusz, true)
|
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, zpagesfeatures.ComponentStatusz, true)
|
||||||
|
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, zpagesfeatures.ComponentFlagz, true)
|
||||||
|
|
||||||
fw := newServerTest()
|
fw := newServerTest()
|
||||||
defer fw.testHTTPServer.Close()
|
defer fw.testHTTPServer.Close()
|
||||||
@ -1729,9 +1732,11 @@ func TestMetricBuckets(t *testing.T) {
|
|||||||
"stats": {url: "/stats/", bucket: "stats"},
|
"stats": {url: "/stats/", bucket: "stats"},
|
||||||
"stats summary sub": {url: "/stats/summary", bucket: "stats"},
|
"stats summary sub": {url: "/stats/summary", bucket: "stats"},
|
||||||
"statusz": {url: "/statusz", bucket: "statusz"},
|
"statusz": {url: "/statusz", bucket: "statusz"},
|
||||||
|
"/flagz": {url: "/flagz", bucket: "flagz"},
|
||||||
"invalid path": {url: "/junk", bucket: "other"},
|
"invalid path": {url: "/junk", bucket: "other"},
|
||||||
"invalid path starting with good": {url: "/healthzjunk", bucket: "other"},
|
"invalid path starting with good": {url: "/healthzjunk", bucket: "other"},
|
||||||
}
|
}
|
||||||
|
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, zpagesfeatures.ComponentFlagz, true)
|
||||||
fw := newServerTest()
|
fw := newServerTest()
|
||||||
defer fw.testHTTPServer.Close()
|
defer fw.testHTTPServer.Close()
|
||||||
|
|
||||||
@ -1960,8 +1965,8 @@ func TestNewServerRegistersMetricsSLIsEndpointTwice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
resourceAnalyzer := stats.NewResourceAnalyzer(nil, time.Minute, &record.FakeRecorder{})
|
resourceAnalyzer := stats.NewResourceAnalyzer(nil, time.Minute, &record.FakeRecorder{})
|
||||||
|
|
||||||
server1 := NewServer(host, resourceAnalyzer, []healthz.HealthChecker{}, nil, nil)
|
server1 := NewServer(host, resourceAnalyzer, []healthz.HealthChecker{}, flagz.NamedFlagSetsReader{}, nil, nil)
|
||||||
server2 := NewServer(host, resourceAnalyzer, []healthz.HealthChecker{}, nil, nil)
|
server2 := NewServer(host, resourceAnalyzer, []healthz.HealthChecker{}, flagz.NamedFlagSetsReader{}, nil, nil)
|
||||||
|
|
||||||
// Check if both servers registered the /metrics/slis endpoint
|
// Check if both servers registered the /metrics/slis endpoint
|
||||||
assert.Contains(t, server1.restfulCont.RegisteredHandlePaths(), "/metrics/slis", "First server should register /metrics/slis")
|
assert.Contains(t, server1.restfulCont.RegisteredHandlePaths(), "/metrics/slis", "First server should register /metrics/slis")
|
||||||
|
@ -30,6 +30,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
DefaultFlagzPath = "/flagz"
|
||||||
|
|
||||||
flagzHeaderFmt = `
|
flagzHeaderFmt = `
|
||||||
%s flags
|
%s flags
|
||||||
Warning: This endpoint is not meant to be machine parseable, has no formatting compatibility guarantees and is for debugging purposes only.
|
Warning: This endpoint is not meant to be machine parseable, has no formatting compatibility guarantees and is for debugging purposes only.
|
||||||
@ -56,7 +58,7 @@ func Install(m mux, componentName string, flagReader Reader) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (reg *registry) installHandler(m mux, componentName string, flagReader Reader) {
|
func (reg *registry) installHandler(m mux, componentName string, flagReader Reader) {
|
||||||
m.Handle("/flagz", reg.handleFlags(componentName, flagReader))
|
m.Handle(DefaultFlagzPath, reg.handleFlags(componentName, flagReader))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (reg *registry) handleFlags(componentName string, flagReader Reader) http.HandlerFunc {
|
func (reg *registry) handleFlags(componentName string, flagReader Reader) http.HandlerFunc {
|
||||||
|
@ -85,7 +85,7 @@ func TestFlagz(t *testing.T) {
|
|||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
Install(mux, componentName, test.flagzReader)
|
Install(mux, componentName, test.flagzReader)
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, "http://example.com/flagz", nil)
|
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://example.com%s", DefaultFlagzPath), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("case[%d] Unexpected error: %v", i, err)
|
t.Fatalf("case[%d] Unexpected error: %v", i, err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user