Refactor compatibility version code
Replace DefaultComponentGlobalsRegistry with new instance of componentGlobalsRegistry in test api server. Signed-off-by: Siyuan Zhang <sizhang@google.com> move kube effective version validation out of component base. Signed-off-by: Siyuan Zhang <sizhang@google.com> move DefaultComponentGlobalsRegistry out of component base. Signed-off-by: Siyuan Zhang <sizhang@google.com> move ComponentGlobalsRegistry out of featuregate pkg. Signed-off-by: Siyuan Zhang <sizhang@google.com> remove usage of DefaultComponentGlobalsRegistry in test files. Signed-off-by: Siyuan Zhang <sizhang@google.com> change non-test DefaultKubeEffectiveVersion to use DefaultBuildEffectiveVersion. Signed-off-by: Siyuan Zhang <sizhang@google.com> Restore useDefaultBuildBinaryVersion in effective version. Signed-off-by: Siyuan Zhang <sizhang@google.com> rename DefaultKubeEffectiveVersion to DefaultKubeEffectiveVersionForTest. Signed-off-by: Siyuan Zhang <sizhang@google.com> pass options.ComponentGlobalsRegistry into config for controller manager and scheduler. Signed-off-by: Siyuan Zhang <sizhang@google.com> Pass apiserver effective version to DefaultResourceEncodingConfig. Signed-off-by: Siyuan Zhang <sizhang@google.com> change statusz registry to take effective version from the components. Signed-off-by: Siyuan Zhang <sizhang@google.com> Address review comments Signed-off-by: Siyuan Zhang <sizhang@google.com> update vendor Signed-off-by: Siyuan Zhang <sizhang@google.com> Kubernetes-commit: 8fc3a33454ba38783bb63de41ecf5343e2ced67c
This commit is contained in:
parent
9bb5fd51d1
commit
9bb4aa730a
|
@ -34,7 +34,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
asn1util "k8s.io/apimachinery/pkg/apis/asn1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/version"
|
||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
|
@ -799,9 +798,6 @@ func TestX509(t *testing.T) {
|
|||
ExpectErr: false,
|
||||
setupFunc: func(t *testing.T) {
|
||||
t.Helper()
|
||||
// This statement can be removed once utilversion.DefaultKubeEffectiveVersion() is >= 1.33
|
||||
featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, version.MustParse("1.33"))
|
||||
|
||||
},
|
||||
},
|
||||
"common name and empty UID with feature gate disabled": {
|
||||
|
@ -822,8 +818,6 @@ func TestX509(t *testing.T) {
|
|||
ExpectErr: false,
|
||||
setupFunc: func(t *testing.T) {
|
||||
t.Helper()
|
||||
// This statement can be removed once utilversion.DefaultKubeEffectiveVersion() is >= 1.33
|
||||
featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, version.MustParse("1.33"))
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.AllowParsingUserUIDFromCertAuth, false)
|
||||
},
|
||||
},
|
||||
|
@ -836,9 +830,6 @@ func TestX509(t *testing.T) {
|
|||
ExpectErrMsg: regexp.MustCompile("UID cannot be an empty string"),
|
||||
setupFunc: func(t *testing.T) {
|
||||
t.Helper()
|
||||
// This statement can be removed once utilversion.DefaultKubeEffectiveVersion() is >= 1.33
|
||||
featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, version.MustParse("1.33"))
|
||||
|
||||
},
|
||||
},
|
||||
"ca with non-string UID": {
|
||||
|
@ -850,9 +841,6 @@ func TestX509(t *testing.T) {
|
|||
ExpectErrMsg: regexp.MustCompile("unable to parse UID into a string"),
|
||||
setupFunc: func(t *testing.T) {
|
||||
t.Helper()
|
||||
// This statement can be removed once utilversion.DefaultKubeEffectiveVersion() is >= 1.33
|
||||
featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, version.MustParse("1.33"))
|
||||
|
||||
},
|
||||
},
|
||||
"ca with multiple UIDs": {
|
||||
|
@ -866,9 +854,6 @@ func TestX509(t *testing.T) {
|
|||
ExpectErrMsg: regexp.MustCompile("expected 1 UID, but found multiple"),
|
||||
setupFunc: func(t *testing.T) {
|
||||
t.Helper()
|
||||
// This statement can be removed once utilversion.DefaultKubeEffectiveVersion() is >= 1.33
|
||||
featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, version.MustParse("1.33"))
|
||||
|
||||
},
|
||||
},
|
||||
"ca with multiple organizations": {
|
||||
|
|
|
@ -32,9 +32,9 @@ import (
|
|||
celconfig "k8s.io/apiserver/pkg/apis/cel"
|
||||
"k8s.io/apiserver/pkg/cel/library"
|
||||
genericfeatures "k8s.io/apiserver/pkg/features"
|
||||
"k8s.io/apiserver/pkg/util/compatibility"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/component-base/featuregate"
|
||||
utilversion "k8s.io/component-base/version"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
)
|
||||
|
||||
// DefaultCompatibilityVersion returns a default compatibility version for use with EnvSet
|
||||
|
@ -50,9 +50,9 @@ import (
|
|||
// A default version number equal to the current Kubernetes major.minor version
|
||||
// indicates fast forward CEL features that can be used when rollback is no longer needed.
|
||||
func DefaultCompatibilityVersion() *version.Version {
|
||||
effectiveVer := featuregate.DefaultComponentGlobalsRegistry.EffectiveVersionFor(featuregate.DefaultKubeComponent)
|
||||
effectiveVer := compatibility.DefaultComponentGlobalsRegistry.EffectiveVersionFor(basecompatibility.DefaultKubeComponent)
|
||||
if effectiveVer == nil {
|
||||
effectiveVer = utilversion.DefaultKubeEffectiveVersion()
|
||||
effectiveVer = compatibility.DefaultBuildEffectiveVersion()
|
||||
}
|
||||
return effectiveVer.MinCompatibilityVersion()
|
||||
}
|
||||
|
|
|
@ -73,12 +73,12 @@ import (
|
|||
flowcontrolrequest "k8s.io/apiserver/pkg/util/flowcontrol/request"
|
||||
"k8s.io/client-go/informers"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
"k8s.io/component-base/featuregate"
|
||||
"k8s.io/component-base/logs"
|
||||
"k8s.io/component-base/metrics/features"
|
||||
"k8s.io/component-base/metrics/prometheus/slis"
|
||||
"k8s.io/component-base/tracing"
|
||||
utilversion "k8s.io/component-base/version"
|
||||
"k8s.io/component-base/zpages/flagz"
|
||||
"k8s.io/klog/v2"
|
||||
openapicommon "k8s.io/kube-openapi/pkg/common"
|
||||
|
@ -153,7 +153,7 @@ type Config struct {
|
|||
|
||||
// EffectiveVersion determines which apis and features are available
|
||||
// based on when the api/feature lifecyle.
|
||||
EffectiveVersion utilversion.EffectiveVersion
|
||||
EffectiveVersion basecompatibility.EffectiveVersion
|
||||
// FeatureGate is a way to plumb feature gate through if you have them.
|
||||
FeatureGate featuregate.FeatureGate
|
||||
// AuditBackend is where audit events are sent to.
|
||||
|
|
|
@ -47,9 +47,9 @@ import (
|
|||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/client-go/rest"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/component-base/tracing"
|
||||
utilversion "k8s.io/component-base/version"
|
||||
"k8s.io/klog/v2/ktesting"
|
||||
netutils "k8s.io/utils/net"
|
||||
)
|
||||
|
@ -124,7 +124,7 @@ func TestNewWithDelegate(t *testing.T) {
|
|||
delegateConfig.PublicAddress = netutils.ParseIPSloppy("192.168.10.4")
|
||||
delegateConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
||||
delegateConfig.LoopbackClientConfig = &rest.Config{}
|
||||
delegateConfig.EffectiveVersion = utilversion.NewEffectiveVersion("")
|
||||
delegateConfig.EffectiveVersion = basecompatibility.NewEffectiveVersionFromString("", "", "")
|
||||
clientset := fake.NewSimpleClientset()
|
||||
if clientset == nil {
|
||||
t.Fatal("unable to create fake client set")
|
||||
|
@ -157,7 +157,7 @@ func TestNewWithDelegate(t *testing.T) {
|
|||
wrappingConfig.PublicAddress = netutils.ParseIPSloppy("192.168.10.4")
|
||||
wrappingConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
||||
wrappingConfig.LoopbackClientConfig = &rest.Config{}
|
||||
wrappingConfig.EffectiveVersion = utilversion.NewEffectiveVersion("")
|
||||
wrappingConfig.EffectiveVersion = basecompatibility.NewEffectiveVersionFromString("", "", "")
|
||||
|
||||
wrappingConfig.HealthzChecks = append(wrappingConfig.HealthzChecks, healthz.NamedCheck("wrapping-health", func(r *http.Request) error {
|
||||
return fmt.Errorf("wrapping failed healthcheck")
|
||||
|
@ -434,7 +434,7 @@ func TestNewFeatureGatedSerializer(t *testing.T) {
|
|||
}
|
||||
})))
|
||||
config.ExternalAddress = "192.168.10.4:443"
|
||||
config.EffectiveVersion = utilversion.NewEffectiveVersion("")
|
||||
config.EffectiveVersion = basecompatibility.NewEffectiveVersionFromString("", "", "")
|
||||
config.LoopbackClientConfig = &rest.Config{}
|
||||
|
||||
if _, err := config.Complete(nil).New("test", NewEmptyDelegate()); err != nil {
|
||||
|
|
|
@ -54,8 +54,8 @@ import (
|
|||
"k8s.io/apiserver/pkg/storageversion"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
"k8s.io/component-base/featuregate"
|
||||
utilversion "k8s.io/component-base/version"
|
||||
"k8s.io/klog/v2"
|
||||
openapibuilder3 "k8s.io/kube-openapi/pkg/builder3"
|
||||
openapicommon "k8s.io/kube-openapi/pkg/common"
|
||||
|
@ -244,7 +244,7 @@ type GenericAPIServer struct {
|
|||
|
||||
// EffectiveVersion determines which apis and features are available
|
||||
// based on when the api/feature lifecyle.
|
||||
EffectiveVersion utilversion.EffectiveVersion
|
||||
EffectiveVersion basecompatibility.EffectiveVersion
|
||||
// FeatureGate is a way to plumb feature gate through if you have them.
|
||||
FeatureGate featuregate.FeatureGate
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
utilversion "k8s.io/apimachinery/pkg/util/version"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
"k8s.io/apiserver/pkg/apis/example"
|
||||
|
@ -52,7 +53,7 @@ import (
|
|||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
utilversion "k8s.io/component-base/version"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
"k8s.io/klog/v2/ktesting"
|
||||
kubeopenapi "k8s.io/kube-openapi/pkg/common"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
|
@ -138,7 +139,7 @@ func setUp(t *testing.T) (Config, *assert.Assertions) {
|
|||
if clientset == nil {
|
||||
t.Fatal("unable to create fake client set")
|
||||
}
|
||||
config.EffectiveVersion = utilversion.NewEffectiveVersion("")
|
||||
config.EffectiveVersion = basecompatibility.NewEffectiveVersionFromString("", "", "")
|
||||
config.OpenAPIConfig = DefaultOpenAPIConfig(testGetOpenAPIDefinitions, openapinamer.NewDefinitionNamer(runtime.NewScheme()))
|
||||
config.OpenAPIConfig.Info.Version = "unversioned"
|
||||
config.OpenAPIV3Config = DefaultOpenAPIV3Config(testGetOpenAPIDefinitions, openapinamer.NewDefinitionNamer(runtime.NewScheme()))
|
||||
|
@ -460,8 +461,8 @@ func TestNotRestRoutesHaveAuth(t *testing.T) {
|
|||
config.EnableProfiling = true
|
||||
|
||||
kubeVersion := fakeVersion()
|
||||
effectiveVersion := utilversion.NewEffectiveVersion(kubeVersion.String())
|
||||
effectiveVersion.Set(effectiveVersion.BinaryVersion().WithInfo(kubeVersion), effectiveVersion.EmulationVersion(), effectiveVersion.MinCompatibilityVersion())
|
||||
binaryVersion := utilversion.MustParse(kubeVersion.String())
|
||||
effectiveVersion := basecompatibility.NewEffectiveVersion(binaryVersion, false, binaryVersion, binaryVersion.SubtractMinor(1))
|
||||
config.EffectiveVersion = effectiveVersion
|
||||
|
||||
s, err := config.Complete(nil).New("test", NewEmptyDelegate())
|
||||
|
|
|
@ -27,9 +27,9 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/errors"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/apiserver/pkg/util/compatibility"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/component-base/featuregate"
|
||||
utilversion "k8s.io/component-base/version"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
@ -95,22 +95,22 @@ type ServerRunOptions struct {
|
|||
ShutdownWatchTerminationGracePeriod time.Duration
|
||||
|
||||
// ComponentGlobalsRegistry is the registry where the effective versions and feature gates for all components are stored.
|
||||
ComponentGlobalsRegistry featuregate.ComponentGlobalsRegistry
|
||||
ComponentGlobalsRegistry basecompatibility.ComponentGlobalsRegistry
|
||||
// ComponentName is name under which the server's global variabled are registered in the ComponentGlobalsRegistry.
|
||||
ComponentName string
|
||||
}
|
||||
|
||||
func NewServerRunOptions() *ServerRunOptions {
|
||||
if featuregate.DefaultComponentGlobalsRegistry.EffectiveVersionFor(featuregate.DefaultKubeComponent) == nil {
|
||||
if compatibility.DefaultComponentGlobalsRegistry.EffectiveVersionFor(basecompatibility.DefaultKubeComponent) == nil {
|
||||
featureGate := utilfeature.DefaultMutableFeatureGate
|
||||
effectiveVersion := utilversion.DefaultKubeEffectiveVersion()
|
||||
utilruntime.Must(featuregate.DefaultComponentGlobalsRegistry.Register(featuregate.DefaultKubeComponent, effectiveVersion, featureGate))
|
||||
effectiveVersion := compatibility.DefaultBuildEffectiveVersion()
|
||||
utilruntime.Must(compatibility.DefaultComponentGlobalsRegistry.Register(basecompatibility.DefaultKubeComponent, effectiveVersion, featureGate))
|
||||
}
|
||||
|
||||
return NewServerRunOptionsForComponent(featuregate.DefaultKubeComponent, featuregate.DefaultComponentGlobalsRegistry)
|
||||
return NewServerRunOptionsForComponent(basecompatibility.DefaultKubeComponent, compatibility.DefaultComponentGlobalsRegistry)
|
||||
}
|
||||
|
||||
func NewServerRunOptionsForComponent(componentName string, componentGlobalsRegistry featuregate.ComponentGlobalsRegistry) *ServerRunOptions {
|
||||
func NewServerRunOptionsForComponent(componentName string, componentGlobalsRegistry basecompatibility.ComponentGlobalsRegistry) *ServerRunOptions {
|
||||
defaults := server.NewConfig(serializer.CodecFactory{})
|
||||
return &ServerRunOptions{
|
||||
MaxRequestsInFlight: defaults.MaxRequestsInFlight,
|
||||
|
|
|
@ -26,15 +26,15 @@ import (
|
|||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/version"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/component-base/featuregate"
|
||||
utilversion "k8s.io/component-base/version"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
netutils "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
func TestServerRunOptionsValidate(t *testing.T) {
|
||||
testRegistry := featuregate.NewComponentGlobalsRegistry()
|
||||
defaultComponentGlobalsRegistry := basecompatibility.NewComponentGlobalsRegistry()
|
||||
testRegistry := basecompatibility.NewComponentGlobalsRegistry()
|
||||
featureGate := utilfeature.DefaultFeatureGate.DeepCopy()
|
||||
effectiveVersion := utilversion.NewEffectiveVersion("1.35")
|
||||
effectiveVersion := basecompatibility.NewEffectiveVersionFromString("1.35", "1.32", "1.32")
|
||||
effectiveVersion.SetEmulationVersion(version.MajorMinor(1, 31))
|
||||
testComponent := "test"
|
||||
utilruntime.Must(testRegistry.Register(testComponent, effectiveVersion, featureGate))
|
||||
|
@ -55,7 +55,7 @@ func TestServerRunOptionsValidate(t *testing.T) {
|
|||
MinRequestTimeout: 1800,
|
||||
JSONPatchMaxCopyBytes: 10 * 1024 * 1024,
|
||||
MaxRequestBodyBytes: 10 * 1024 * 1024,
|
||||
ComponentGlobalsRegistry: featuregate.DefaultComponentGlobalsRegistry,
|
||||
ComponentGlobalsRegistry: defaultComponentGlobalsRegistry,
|
||||
},
|
||||
expectErr: "--max-requests-inflight can not be negative value",
|
||||
},
|
||||
|
@ -70,7 +70,7 @@ func TestServerRunOptionsValidate(t *testing.T) {
|
|||
MinRequestTimeout: 1800,
|
||||
JSONPatchMaxCopyBytes: 10 * 1024 * 1024,
|
||||
MaxRequestBodyBytes: 10 * 1024 * 1024,
|
||||
ComponentGlobalsRegistry: featuregate.DefaultComponentGlobalsRegistry,
|
||||
ComponentGlobalsRegistry: defaultComponentGlobalsRegistry,
|
||||
},
|
||||
expectErr: "--max-mutating-requests-inflight can not be negative value",
|
||||
},
|
||||
|
@ -85,7 +85,7 @@ func TestServerRunOptionsValidate(t *testing.T) {
|
|||
MinRequestTimeout: 1800,
|
||||
JSONPatchMaxCopyBytes: 10 * 1024 * 1024,
|
||||
MaxRequestBodyBytes: 10 * 1024 * 1024,
|
||||
ComponentGlobalsRegistry: featuregate.DefaultComponentGlobalsRegistry,
|
||||
ComponentGlobalsRegistry: defaultComponentGlobalsRegistry,
|
||||
},
|
||||
expectErr: "--request-timeout can not be negative value",
|
||||
},
|
||||
|
@ -100,7 +100,7 @@ func TestServerRunOptionsValidate(t *testing.T) {
|
|||
MinRequestTimeout: -1800,
|
||||
JSONPatchMaxCopyBytes: 10 * 1024 * 1024,
|
||||
MaxRequestBodyBytes: 10 * 1024 * 1024,
|
||||
ComponentGlobalsRegistry: featuregate.DefaultComponentGlobalsRegistry,
|
||||
ComponentGlobalsRegistry: defaultComponentGlobalsRegistry,
|
||||
},
|
||||
expectErr: "--min-request-timeout can not be negative value",
|
||||
},
|
||||
|
@ -115,7 +115,7 @@ func TestServerRunOptionsValidate(t *testing.T) {
|
|||
MinRequestTimeout: 1800,
|
||||
JSONPatchMaxCopyBytes: -10 * 1024 * 1024,
|
||||
MaxRequestBodyBytes: 10 * 1024 * 1024,
|
||||
ComponentGlobalsRegistry: featuregate.DefaultComponentGlobalsRegistry,
|
||||
ComponentGlobalsRegistry: defaultComponentGlobalsRegistry,
|
||||
},
|
||||
expectErr: "ServerRunOptions.JSONPatchMaxCopyBytes can not be negative value",
|
||||
},
|
||||
|
@ -130,7 +130,7 @@ func TestServerRunOptionsValidate(t *testing.T) {
|
|||
MinRequestTimeout: 1800,
|
||||
JSONPatchMaxCopyBytes: 10 * 1024 * 1024,
|
||||
MaxRequestBodyBytes: -10 * 1024 * 1024,
|
||||
ComponentGlobalsRegistry: featuregate.DefaultComponentGlobalsRegistry,
|
||||
ComponentGlobalsRegistry: defaultComponentGlobalsRegistry,
|
||||
},
|
||||
expectErr: "ServerRunOptions.MaxRequestBodyBytes can not be negative value",
|
||||
},
|
||||
|
@ -146,7 +146,7 @@ func TestServerRunOptionsValidate(t *testing.T) {
|
|||
JSONPatchMaxCopyBytes: 10 * 1024 * 1024,
|
||||
MaxRequestBodyBytes: 10 * 1024 * 1024,
|
||||
LivezGracePeriod: -time.Second,
|
||||
ComponentGlobalsRegistry: featuregate.DefaultComponentGlobalsRegistry,
|
||||
ComponentGlobalsRegistry: defaultComponentGlobalsRegistry,
|
||||
},
|
||||
expectErr: "--livez-grace-period can not be a negative value",
|
||||
},
|
||||
|
@ -162,7 +162,7 @@ func TestServerRunOptionsValidate(t *testing.T) {
|
|||
JSONPatchMaxCopyBytes: 10 * 1024 * 1024,
|
||||
MaxRequestBodyBytes: 10 * 1024 * 1024,
|
||||
ShutdownDelayDuration: -time.Second,
|
||||
ComponentGlobalsRegistry: featuregate.DefaultComponentGlobalsRegistry,
|
||||
ComponentGlobalsRegistry: defaultComponentGlobalsRegistry,
|
||||
},
|
||||
expectErr: "--shutdown-delay-duration can not be negative value",
|
||||
},
|
||||
|
@ -178,7 +178,7 @@ func TestServerRunOptionsValidate(t *testing.T) {
|
|||
MinRequestTimeout: 1800,
|
||||
JSONPatchMaxCopyBytes: 10 * 1024 * 1024,
|
||||
MaxRequestBodyBytes: 10 * 1024 * 1024,
|
||||
ComponentGlobalsRegistry: featuregate.DefaultComponentGlobalsRegistry,
|
||||
ComponentGlobalsRegistry: defaultComponentGlobalsRegistry,
|
||||
},
|
||||
expectErr: "--strict-transport-security-directives invalid, allowed values: max-age=expireTime, includeSubDomains, preload. see https://tools.ietf.org/html/rfc6797#section-6.1 for more information",
|
||||
},
|
||||
|
@ -211,7 +211,7 @@ func TestServerRunOptionsValidate(t *testing.T) {
|
|||
MinRequestTimeout: 1800,
|
||||
JSONPatchMaxCopyBytes: 10 * 1024 * 1024,
|
||||
MaxRequestBodyBytes: 10 * 1024 * 1024,
|
||||
ComponentGlobalsRegistry: featuregate.DefaultComponentGlobalsRegistry,
|
||||
ComponentGlobalsRegistry: defaultComponentGlobalsRegistry,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ import (
|
|||
"k8s.io/client-go/discovery"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
cliflag "k8s.io/component-base/cli/flag"
|
||||
utilversion "k8s.io/component-base/version"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
"k8s.io/klog/v2/ktesting"
|
||||
netutils "k8s.io/utils/net"
|
||||
)
|
||||
|
@ -278,7 +278,7 @@ func TestServerRunWithSNI(t *testing.T) {
|
|||
// launch server
|
||||
config := setUp(t)
|
||||
v := fakeVersion()
|
||||
config.EffectiveVersion = utilversion.NewEffectiveVersion(v.String())
|
||||
config.EffectiveVersion = basecompatibility.NewEffectiveVersionFromString(v.String(), "", "")
|
||||
|
||||
config.EnableIndex = true
|
||||
secureOptions := (&SecureServingOptions{
|
||||
|
|
|
@ -22,7 +22,8 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
apimachineryversion "k8s.io/apimachinery/pkg/util/version"
|
||||
version "k8s.io/component-base/version"
|
||||
"k8s.io/apiserver/pkg/util/compatibility"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
)
|
||||
|
||||
type ResourceEncodingConfig interface {
|
||||
|
@ -43,7 +44,7 @@ type DefaultResourceEncodingConfig struct {
|
|||
// resources records the overriding encoding configs for individual resources.
|
||||
resources map[schema.GroupResource]*OverridingResourceEncoding
|
||||
scheme *runtime.Scheme
|
||||
effectiveVersion version.EffectiveVersion
|
||||
effectiveVersion basecompatibility.EffectiveVersion
|
||||
}
|
||||
|
||||
type OverridingResourceEncoding struct {
|
||||
|
@ -54,7 +55,11 @@ type OverridingResourceEncoding struct {
|
|||
var _ ResourceEncodingConfig = &DefaultResourceEncodingConfig{}
|
||||
|
||||
func NewDefaultResourceEncodingConfig(scheme *runtime.Scheme) *DefaultResourceEncodingConfig {
|
||||
return &DefaultResourceEncodingConfig{resources: map[schema.GroupResource]*OverridingResourceEncoding{}, scheme: scheme, effectiveVersion: version.DefaultKubeEffectiveVersion()}
|
||||
return NewDefaultResourceEncodingConfigForEffectiveVersion(scheme, compatibility.DefaultComponentGlobalsRegistry.EffectiveVersionFor(basecompatibility.DefaultKubeComponent))
|
||||
}
|
||||
|
||||
func NewDefaultResourceEncodingConfigForEffectiveVersion(scheme *runtime.Scheme, effectiveVersion basecompatibility.EffectiveVersion) *DefaultResourceEncodingConfig {
|
||||
return &DefaultResourceEncodingConfig{resources: map[schema.GroupResource]*OverridingResourceEncoding{}, scheme: scheme, effectiveVersion: effectiveVersion}
|
||||
}
|
||||
|
||||
func (o *DefaultResourceEncodingConfig) SetResourceEncoding(resourceBeingStored schema.GroupResource, externalEncodingVersion, internalVersion schema.GroupVersion) {
|
||||
|
@ -64,7 +69,7 @@ func (o *DefaultResourceEncodingConfig) SetResourceEncoding(resourceBeingStored
|
|||
}
|
||||
}
|
||||
|
||||
func (o *DefaultResourceEncodingConfig) SetEffectiveVersion(effectiveVersion version.EffectiveVersion) {
|
||||
func (o *DefaultResourceEncodingConfig) SetEffectiveVersion(effectiveVersion basecompatibility.EffectiveVersion) {
|
||||
o.effectiveVersion = effectiveVersion
|
||||
}
|
||||
|
||||
|
@ -121,7 +126,7 @@ type replacementInterface interface {
|
|||
APILifecycleReplacement() schema.GroupVersionKind
|
||||
}
|
||||
|
||||
func emulatedStorageVersion(binaryVersionOfResource schema.GroupVersion, example runtime.Object, effectiveVersion version.EffectiveVersion, scheme *runtime.Scheme) (schema.GroupVersion, error) {
|
||||
func emulatedStorageVersion(binaryVersionOfResource schema.GroupVersion, example runtime.Object, effectiveVersion basecompatibility.EffectiveVersion, scheme *runtime.Scheme) (schema.GroupVersion, error) {
|
||||
if example == nil || effectiveVersion == nil {
|
||||
return binaryVersionOfResource, nil
|
||||
}
|
||||
|
@ -172,7 +177,7 @@ func emulatedStorageVersion(binaryVersionOfResource schema.GroupVersion, example
|
|||
}
|
||||
|
||||
// If it was introduced after current compatibility version, don't use it
|
||||
// skip the introduced check for test when currentVersion is 0.0 to test all apis
|
||||
// skip the introduced check for test when current compatibility version is 0.0 to test all apis
|
||||
if introduced, hasIntroduced := exampleOfGVK.(introducedInterface); hasIntroduced && (compatibilityVersion.Major() > 0 || compatibilityVersion.Minor() > 0) {
|
||||
|
||||
// Skip versions that have a replacement.
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/test"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
utilversion "k8s.io/apimachinery/pkg/util/version"
|
||||
"k8s.io/component-base/version"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
)
|
||||
|
||||
func TestEmulatedStorageVersion(t *testing.T) {
|
||||
|
@ -33,21 +33,21 @@ func TestEmulatedStorageVersion(t *testing.T) {
|
|||
name string
|
||||
scheme *runtime.Scheme
|
||||
binaryVersion schema.GroupVersion
|
||||
effectiveVersion version.EffectiveVersion
|
||||
effectiveVersion basecompatibility.EffectiveVersion
|
||||
want schema.GroupVersion
|
||||
}{
|
||||
{
|
||||
name: "pick compatible",
|
||||
scheme: AlphaBetaScheme(utilversion.MustParse("1.31"), utilversion.MustParse("1.32")),
|
||||
binaryVersion: v1beta1,
|
||||
effectiveVersion: version.NewEffectiveVersion("1.32"),
|
||||
effectiveVersion: basecompatibility.NewEffectiveVersionFromString("1.32", "", ""),
|
||||
want: v1alpha1,
|
||||
},
|
||||
{
|
||||
name: "alpha has been replaced, pick binary version",
|
||||
scheme: AlphaReplacedBetaScheme(utilversion.MustParse("1.31"), utilversion.MustParse("1.32")),
|
||||
binaryVersion: v1beta1,
|
||||
effectiveVersion: version.NewEffectiveVersion("1.32"),
|
||||
effectiveVersion: basecompatibility.NewEffectiveVersionFromString("1.32", "", ""),
|
||||
want: v1beta1,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ import (
|
|||
"k8s.io/apiserver/pkg/apis/example2"
|
||||
example2install "k8s.io/apiserver/pkg/apis/example2/install"
|
||||
"k8s.io/apiserver/pkg/storage/storagebackend"
|
||||
version "k8s.io/component-base/version"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -569,8 +569,7 @@ func TestStorageFactoryCompatibilityVersion(t *testing.T) {
|
|||
|
||||
gvk := gvks[0]
|
||||
t.Run(gvk.GroupKind().String()+"@"+tc.effectiveVersion, func(t *testing.T) {
|
||||
config := NewDefaultResourceEncodingConfig(sch)
|
||||
config.SetEffectiveVersion(version.NewEffectiveVersion(tc.effectiveVersion))
|
||||
config := NewDefaultResourceEncodingConfigForEffectiveVersion(sch, basecompatibility.NewEffectiveVersionFromString(tc.effectiveVersion, "", ""))
|
||||
f := NewDefaultStorageFactory(
|
||||
storagebackend.Config{},
|
||||
"",
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package compatibility
|
||||
|
||||
import (
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
)
|
||||
|
||||
// DefaultComponentGlobalsRegistry is the global var to store the effective versions and feature gates for all components for easy access.
|
||||
// Example usage:
|
||||
// // register the component effective version and feature gate first
|
||||
// wardleEffectiveVersion := basecompatibility.NewEffectiveVersion("1.2")
|
||||
// wardleFeatureGate := featuregate.NewFeatureGate()
|
||||
// utilruntime.Must(compatibility.DefaultComponentGlobalsRegistry.Register(apiserver.WardleComponentName, wardleEffectiveVersion, wardleFeatureGate, false))
|
||||
//
|
||||
// cmd := &cobra.Command{
|
||||
// ...
|
||||
// // call DefaultComponentGlobalsRegistry.Set() in PersistentPreRunE to ensure the feature gates are set based on emulation version right after parsing the flags.
|
||||
// PersistentPreRunE: func(*cobra.Command, []string) error {
|
||||
// if err := compatibility.DefaultComponentGlobalsRegistry.Set(); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// ...
|
||||
// },
|
||||
// RunE: func(c *cobra.Command, args []string) error {
|
||||
// // call compatibility.DefaultComponentGlobalsRegistry.Validate() somewhere
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// flags := cmd.Flags()
|
||||
// // add flags
|
||||
// compatibility.DefaultComponentGlobalsRegistry.AddFlags(flags)
|
||||
var DefaultComponentGlobalsRegistry basecompatibility.ComponentGlobalsRegistry = basecompatibility.NewComponentGlobalsRegistry()
|
||||
|
||||
func init() {
|
||||
utilruntime.Must(DefaultComponentGlobalsRegistry.Register(basecompatibility.DefaultKubeComponent, DefaultBuildEffectiveVersion(), utilfeature.DefaultMutableFeatureGate))
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package compatibility
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/util/version"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
baseversion "k8s.io/component-base/version"
|
||||
)
|
||||
|
||||
// minimumKubeEmulationVersion is the first release emulation version is introduced,
|
||||
// so the emulation version cannot go lower than that.
|
||||
var minimumKubeEmulationVersion *version.Version = version.MajorMinor(1, 31)
|
||||
|
||||
// DefaultBuildEffectiveVersion returns the MutableEffectiveVersion based on the
|
||||
// current build information.
|
||||
func DefaultBuildEffectiveVersion() basecompatibility.MutableEffectiveVersion {
|
||||
binaryVersion := defaultBuildBinaryVersion()
|
||||
useDefaultBuildBinaryVersion := true
|
||||
// fall back to the hard coded kube version only when the git tag is not available for local unit tests.
|
||||
if binaryVersion.Major() == 0 && binaryVersion.Minor() == 0 {
|
||||
useDefaultBuildBinaryVersion = false
|
||||
binaryVersion = version.MustParse(baseversion.DefaultKubeBinaryVersion)
|
||||
}
|
||||
versionFloor := kubeEffectiveVersionFloors(binaryVersion)
|
||||
return basecompatibility.NewEffectiveVersion(binaryVersion, useDefaultBuildBinaryVersion, versionFloor, versionFloor)
|
||||
}
|
||||
|
||||
func kubeEffectiveVersionFloors(binaryVersion *version.Version) *version.Version {
|
||||
// both emulationVersion and minCompatibilityVersion can be set to binaryVersion - 3
|
||||
versionFloor := binaryVersion.WithPatch(0).SubtractMinor(3)
|
||||
if versionFloor.LessThan(minimumKubeEmulationVersion) {
|
||||
versionFloor = minimumKubeEmulationVersion
|
||||
}
|
||||
return versionFloor
|
||||
}
|
||||
|
||||
// DefaultKubeEffectiveVersionForTest returns the MutableEffectiveVersion based on the
|
||||
// latest K8s release hardcoded in DefaultKubeBinaryVersion.
|
||||
// DefaultKubeBinaryVersion is hard coded because defaultBuildBinaryVersion would return 0.0 when test is run without a git tag.
|
||||
// We do not enforce the N-3..N emulation version range in tests so that the tests would not automatically fail when there is a version bump.
|
||||
// Only used in tests.
|
||||
func DefaultKubeEffectiveVersionForTest() basecompatibility.MutableEffectiveVersion {
|
||||
binaryVersion := version.MustParse(baseversion.DefaultKubeBinaryVersion).WithInfo(baseversion.Get())
|
||||
return basecompatibility.NewEffectiveVersion(binaryVersion, false, version.MustParse("0.0"), version.MustParse("0.0"))
|
||||
}
|
||||
|
||||
func defaultBuildBinaryVersion() *version.Version {
|
||||
verInfo := baseversion.Get()
|
||||
return version.MustParse(verInfo.String()).WithInfo(verInfo)
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package compatibility
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/version"
|
||||
basecompatibility "k8s.io/component-base/compatibility"
|
||||
)
|
||||
|
||||
func TestValidateKubeEffectiveVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
emulationVersion string
|
||||
minCompatibilityVersion string
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
name: "valid versions",
|
||||
emulationVersion: "v1.32.0",
|
||||
minCompatibilityVersion: "v1.31.0",
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: "emulationVersion too low",
|
||||
emulationVersion: "v1.30.0",
|
||||
minCompatibilityVersion: "v1.31.0",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
name: "minCompatibilityVersion too low",
|
||||
emulationVersion: "v1.31.0",
|
||||
minCompatibilityVersion: "v1.30.0",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
name: "both versions too low",
|
||||
emulationVersion: "v1.30.0",
|
||||
minCompatibilityVersion: "v1.29.0",
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
binaryVersion := version.MustParseGeneric("1.33")
|
||||
versionFloor := kubeEffectiveVersionFloors(binaryVersion)
|
||||
effective := basecompatibility.NewEffectiveVersion(binaryVersion, false, versionFloor, versionFloor)
|
||||
effective.SetEmulationVersion(version.MustParseGeneric(test.emulationVersion))
|
||||
effective.SetMinCompatibilityVersion(version.MustParseGeneric(test.minCompatibilityVersion))
|
||||
|
||||
err := effective.Validate()
|
||||
if test.expectErr && err == nil {
|
||||
t.Error("expected error, but got nil")
|
||||
}
|
||||
if !test.expectErr && err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue