mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
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:
commit
ea73dad549
@ -57,7 +57,7 @@ func (s *ServerRunOptions) Complete(ctx context.Context) (CompletedOptions, erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return CompletedOptions{}, err
|
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 {
|
if err != nil {
|
||||||
return CompletedOptions{}, err
|
return CompletedOptions{}, err
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ import (
|
|||||||
"k8s.io/component-base/term"
|
"k8s.io/component-base/term"
|
||||||
utilversion "k8s.io/component-base/version"
|
utilversion "k8s.io/component-base/version"
|
||||||
"k8s.io/component-base/version/verflag"
|
"k8s.io/component-base/version/verflag"
|
||||||
|
"k8s.io/component-base/zpages/flagz"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
|
aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
|
||||||
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
|
"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()
|
fs := cmd.Flags()
|
||||||
namedFlagSets := s.Flags()
|
namedFlagSets := s.Flags()
|
||||||
|
s.Flagz = flagz.NamedFlagSetsReader{
|
||||||
|
FlagSets: namedFlagSets,
|
||||||
|
}
|
||||||
verflag.AddFlags(namedFlagSets.FlagSet("global"))
|
verflag.AddFlags(namedFlagSets.FlagSet("global"))
|
||||||
globalflag.AddGlobalFlags(namedFlagSets.FlagSet("global"), cmd.Name(), logs.SkipLoggingConfigurationFlags())
|
globalflag.AddGlobalFlags(namedFlagSets.FlagSet("global"), cmd.Name(), logs.SkipLoggingConfigurationFlags())
|
||||||
options.AddCustomGlobalFlags(namedFlagSets.FlagSet("generic"))
|
options.AddCustomGlobalFlags(namedFlagSets.FlagSet("generic"))
|
||||||
|
@ -59,6 +59,8 @@ import (
|
|||||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||||
logsapi "k8s.io/component-base/logs/api/v1"
|
logsapi "k8s.io/component-base/logs/api/v1"
|
||||||
utilversion "k8s.io/component-base/version"
|
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/klog/v2"
|
||||||
"k8s.io/kube-aggregator/pkg/apiserver"
|
"k8s.io/kube-aggregator/pkg/apiserver"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
"k8s.io/kubernetes/pkg/features"
|
||||||
@ -213,7 +215,8 @@ func StartTestServer(t ktesting.TB, instanceOptions *TestServerInstanceOptions,
|
|||||||
s.GenericServerRunOptions.RequestTimeout = instanceOptions.RequestTimeout
|
s.GenericServerRunOptions.RequestTimeout = instanceOptions.RequestTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, f := range s.Flags().FlagSets {
|
namedFlagSets := s.Flags()
|
||||||
|
for _, f := range namedFlagSets.FlagSets {
|
||||||
fs.AddFlagSet(f)
|
fs.AddFlagSet(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,6 +359,9 @@ func StartTestServer(t ktesting.TB, instanceOptions *TestServerInstanceOptions,
|
|||||||
if err := fs.Parse(customFlags); err != nil {
|
if err := fs.Parse(customFlags); err != nil {
|
||||||
return result, err
|
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
|
// 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
|
// and so flags are connected to a struct that no longer appears in the ServerOptions struct
|
||||||
|
@ -25,7 +25,6 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
apiserveroptions "k8s.io/apiserver/pkg/server/options"
|
apiserveroptions "k8s.io/apiserver/pkg/server/options"
|
||||||
cliflag "k8s.io/component-base/cli/flag"
|
|
||||||
aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme"
|
aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
"k8s.io/kubernetes/pkg/controlplane/apiserver/options"
|
"k8s.io/kubernetes/pkg/controlplane/apiserver/options"
|
||||||
@ -47,7 +46,7 @@ func TestBuildGenericConfig(t *testing.T) {
|
|||||||
s.BindPort = ln.Addr().(*net.TCPAddr).Port
|
s.BindPort = ln.Addr().(*net.TCPAddr).Port
|
||||||
opts.SecureServing = s
|
opts.SecureServing = s
|
||||||
|
|
||||||
completedOptions, err := opts.Complete(context.TODO(), cliflag.NamedFlagSets{}, nil, nil)
|
completedOptions, err := opts.Complete(context.TODO(), nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to complete apiserver options: %v", err)
|
t.Fatalf("Failed to complete apiserver options: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -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)")
|
"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 {
|
if o == nil {
|
||||||
return CompletedOptions{completedOptions: &completedOptions{}}, 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{
|
return CompletedOptions{
|
||||||
completedOptions: &completed,
|
completedOptions: &completed,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -24,7 +24,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
|
||||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
@ -86,7 +85,7 @@ APIs.`,
|
|||||||
|
|
||||||
ctx := genericapiserver.SetupSignalContext()
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -37,10 +37,13 @@ import (
|
|||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/apiserver/pkg/storage/storagebackend"
|
"k8s.io/apiserver/pkg/storage/storagebackend"
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
cliflag "k8s.io/component-base/cli/flag"
|
cliflag "k8s.io/component-base/cli/flag"
|
||||||
logsapi "k8s.io/component-base/logs/api/v1"
|
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"
|
"k8s.io/klog/v2"
|
||||||
controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver/options"
|
controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver/options"
|
||||||
"k8s.io/kubernetes/test/utils/ktesting"
|
"k8s.io/kubernetes/test/utils/ktesting"
|
||||||
@ -126,6 +129,9 @@ func StartTestServer(t ktesting.TB, instanceOptions *TestServerInstanceOptions,
|
|||||||
o := server.NewOptions()
|
o := server.NewOptions()
|
||||||
var fss cliflag.NamedFlagSets
|
var fss cliflag.NamedFlagSets
|
||||||
o.AddFlags(&fss)
|
o.AddFlags(&fss)
|
||||||
|
if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentFlagz) {
|
||||||
|
o.Flagz = flagz.NamedFlagSetsReader{FlagSets: fss}
|
||||||
|
}
|
||||||
|
|
||||||
fs := pflag.NewFlagSet("test", pflag.PanicOnError)
|
fs := pflag.NewFlagSet("test", pflag.PanicOnError)
|
||||||
for _, f := range fss.FlagSets {
|
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.Issuers = []string{"https://foo.bar.example.com"}
|
||||||
o.Authentication.ServiceAccounts.KeyFiles = []string{saSigningKeyFile.Name()}
|
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 {
|
if err != nil {
|
||||||
return result, fmt.Errorf("failed to set default ServerRunOptions: %w", err)
|
return result, fmt.Errorf("failed to set default ServerRunOptions: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/test/integration/fixtures"
|
"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"
|
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
|
// TestOpenAPIDelegationChainPlumbing is a smoke test that checks for
|
||||||
// the existence of some representative paths from the
|
// the existence of some representative paths from the
|
||||||
// apiextensions-server and the kube-aggregator server, both part of
|
// apiextensions-server and the kube-aggregator server, both part of
|
||||||
|
Loading…
Reference in New Issue
Block a user