Merge pull request #130332 from richabanker/automated-cherry-pick-of-#129996-upstream-release-1.32

Automated cherry pick of #129996: fix: apiserver flagz to response actual parsed flags
This commit is contained in:
Kubernetes Prow Robot 2025-02-24 06:44:28 -08:00 committed by GitHub
commit ea73dad549
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 66 additions and 10 deletions

View File

@ -57,7 +57,7 @@ func (s *ServerRunOptions) Complete(ctx context.Context) (CompletedOptions, erro
if err != nil {
return CompletedOptions{}, err
}
controlplane, err := s.Options.Complete(ctx, s.Flags(), []string{"kubernetes.default.svc", "kubernetes.default", "kubernetes"}, []net.IP{apiServerServiceIP})
controlplane, err := s.Options.Complete(ctx, []string{"kubernetes.default.svc", "kubernetes.default", "kubernetes"}, []net.IP{apiServerServiceIP})
if err != nil {
return CompletedOptions{}, err
}

View File

@ -48,6 +48,7 @@ import (
"k8s.io/component-base/term"
utilversion "k8s.io/component-base/version"
"k8s.io/component-base/version/verflag"
"k8s.io/component-base/zpages/flagz"
"k8s.io/klog/v2"
aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
@ -124,6 +125,9 @@ cluster's shared state through which all other components interact.`,
fs := cmd.Flags()
namedFlagSets := s.Flags()
s.Flagz = flagz.NamedFlagSetsReader{
FlagSets: namedFlagSets,
}
verflag.AddFlags(namedFlagSets.FlagSet("global"))
globalflag.AddGlobalFlags(namedFlagSets.FlagSet("global"), cmd.Name(), logs.SkipLoggingConfigurationFlags())
options.AddCustomGlobalFlags(namedFlagSets.FlagSet("generic"))

View File

@ -59,6 +59,8 @@ import (
featuregatetesting "k8s.io/component-base/featuregate/testing"
logsapi "k8s.io/component-base/logs/api/v1"
utilversion "k8s.io/component-base/version"
zpagesfeatures "k8s.io/component-base/zpages/features"
"k8s.io/component-base/zpages/flagz"
"k8s.io/klog/v2"
"k8s.io/kube-aggregator/pkg/apiserver"
"k8s.io/kubernetes/pkg/features"
@ -213,7 +215,8 @@ func StartTestServer(t ktesting.TB, instanceOptions *TestServerInstanceOptions,
s.GenericServerRunOptions.RequestTimeout = instanceOptions.RequestTimeout
}
for _, f := range s.Flags().FlagSets {
namedFlagSets := s.Flags()
for _, f := range namedFlagSets.FlagSets {
fs.AddFlagSet(f)
}
@ -356,6 +359,9 @@ func StartTestServer(t ktesting.TB, instanceOptions *TestServerInstanceOptions,
if err := fs.Parse(customFlags); err != nil {
return result, err
}
if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentFlagz) {
s.Flagz = flagz.NamedFlagSetsReader{FlagSets: namedFlagSets}
}
// the RequestHeader options pointer gets replaced in the case of EnableCertAuth override
// and so flags are connected to a struct that no longer appears in the ServerOptions struct

View File

@ -25,7 +25,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
apiserveroptions "k8s.io/apiserver/pkg/server/options"
cliflag "k8s.io/component-base/cli/flag"
aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/controlplane/apiserver/options"
@ -47,7 +46,7 @@ func TestBuildGenericConfig(t *testing.T) {
s.BindPort = ln.Addr().(*net.TCPAddr).Port
opts.SecureServing = s
completedOptions, err := opts.Complete(context.TODO(), cliflag.NamedFlagSets{}, nil, nil)
completedOptions, err := opts.Complete(context.TODO(), nil, nil)
if err != nil {
t.Fatalf("Failed to complete apiserver options: %v", err)
}

View File

@ -203,7 +203,7 @@ func (s *Options) AddFlags(fss *cliflag.NamedFlagSets) {
"Path to socket where a external JWT signer is listening. This flag is mutually exclusive with --service-account-signing-key-file and --service-account-key-file. Requires enabling feature gate (ExternalServiceAccountTokenSigner)")
}
func (o *Options) Complete(ctx context.Context, fss cliflag.NamedFlagSets, alternateDNS []string, alternateIPs []net.IP) (CompletedOptions, error) {
func (o *Options) Complete(ctx context.Context, alternateDNS []string, alternateIPs []net.IP) (CompletedOptions, error) {
if o == nil {
return CompletedOptions{completedOptions: &completedOptions{}}, nil
}
@ -259,8 +259,6 @@ func (o *Options) Complete(ctx context.Context, fss cliflag.NamedFlagSets, alter
}
}
completed.Flagz = flagz.NamedFlagSetsReader{FlagSets: fss}
return CompletedOptions{
completedOptions: &completed,
}, nil

View File

@ -24,7 +24,6 @@ import (
"path/filepath"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@ -86,7 +85,7 @@ APIs.`,
ctx := genericapiserver.SetupSignalContext()
completedOptions, err := s.Complete(ctx, cliflag.NamedFlagSets{FlagSets: map[string]*pflag.FlagSet{"sample_generic_controlplane": fs}}, []string{}, []net.IP{})
completedOptions, err := s.Complete(ctx, []string{}, []net.IP{})
if err != nil {
return err
}

View File

@ -37,10 +37,13 @@ import (
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apiserver/pkg/storage/storagebackend"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
cliflag "k8s.io/component-base/cli/flag"
logsapi "k8s.io/component-base/logs/api/v1"
zpagesfeatures "k8s.io/component-base/zpages/features"
"k8s.io/component-base/zpages/flagz"
"k8s.io/klog/v2"
controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver/options"
"k8s.io/kubernetes/test/utils/ktesting"
@ -126,6 +129,9 @@ func StartTestServer(t ktesting.TB, instanceOptions *TestServerInstanceOptions,
o := server.NewOptions()
var fss cliflag.NamedFlagSets
o.AddFlags(&fss)
if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentFlagz) {
o.Flagz = flagz.NamedFlagSetsReader{FlagSets: fss}
}
fs := pflag.NewFlagSet("test", pflag.PanicOnError)
for _, f := range fss.FlagSets {
@ -164,7 +170,7 @@ func StartTestServer(t ktesting.TB, instanceOptions *TestServerInstanceOptions,
o.Authentication.ServiceAccounts.Issuers = []string{"https://foo.bar.example.com"}
o.Authentication.ServiceAccounts.KeyFiles = []string{saSigningKeyFile.Name()}
completedOptions, err := o.Complete(tCtx, fss, nil, nil)
completedOptions, err := o.Complete(tCtx, nil, nil)
if err != nil {
return result, fmt.Errorf("failed to set default ServerRunOptions: %w", err)
}

View File

@ -28,6 +28,9 @@ import (
"time"
"k8s.io/apiextensions-apiserver/test/integration/fixtures"
utilfeature "k8s.io/apiserver/pkg/util/feature"
featuregatetesting "k8s.io/component-base/featuregate/testing"
"k8s.io/component-base/zpages/features"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
@ -127,6 +130,47 @@ func TestLivezAndReadyz(t *testing.T) {
}
}
func TestFlagz(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ComponentFlagz, true)
testServerFlags := append(framework.DefaultTestServerFlags(), "--emulated-version=1.32")
server := kubeapiservertesting.StartTestServerOrDie(t, nil, testServerFlags, framework.SharedEtcd())
defer server.TearDownFn()
client, err := kubernetes.NewForConfig(server.ClientConfig)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
res := client.CoreV1().RESTClient().Get().RequestURI("/flagz").Do(context.TODO())
var status int
res.StatusCode(&status)
if status != http.StatusOK {
t.Fatalf("flagz/ should be healthy, got %v", status)
}
expectedHeader := `
kube-apiserver flags
Warning: This endpoint is not meant to be machine parseable, has no formatting compatibility guarantees and is for debugging purposes only.`
raw, err := res.Raw()
if err != nil {
t.Fatal(err)
}
if !bytes.HasPrefix(raw, []byte(expectedHeader)) {
t.Fatalf("Header mismatch!\nExpected:\n%s\n\nGot:\n%s", expectedHeader, string(raw))
}
found := false
for _, line := range strings.Split(string(raw), "\n") {
if strings.Contains(line, "emulated-version") && strings.Contains(line, "1.32") {
found = true
break
}
}
if !found {
t.Fatalf("Expected flag --emulated-version=[1.32] to be reflected in /flagz output, got:\n%s", string(raw))
}
}
// TestOpenAPIDelegationChainPlumbing is a smoke test that checks for
// the existence of some representative paths from the
// apiextensions-server and the kube-aggregator server, both part of