diff --git a/pkg/config/fuzzer/fuzzer.go b/pkg/config/fuzzer/fuzzer.go new file mode 100644 index 000000000..c9f864e99 --- /dev/null +++ b/pkg/config/fuzzer/fuzzer.go @@ -0,0 +1,33 @@ +/* +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 fuzzer + +import ( + "sigs.k8s.io/randfill" + + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/kubectl/pkg/config" +) + +// Funcs returns the fuzzer functions for the kubectl apis. +func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(obj *config.Preference, c randfill.Continue) { + c.FillNoCustom(obj) + }, + } +} diff --git a/pkg/config/install/install.go b/pkg/config/scheme/scheme.go similarity index 53% rename from pkg/config/install/install.go rename to pkg/config/scheme/scheme.go index 19d9fb1a6..27c9d9179 100644 --- a/pkg/config/install/install.go +++ b/pkg/config/scheme/scheme.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +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. @@ -14,20 +14,34 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package install installs the experimental API group, making it available as -// an option to all of the API encoding/decoding machinery. -package install +package scheme import ( "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/kubectl/pkg/config" "k8s.io/kubectl/pkg/config/v1alpha1" "k8s.io/kubectl/pkg/config/v1beta1" ) -// Install registers the API group and adds types to a scheme -func Install(scheme *runtime.Scheme) { +var ( + // Scheme defines methods for serializing and deserializing API objects. + Scheme = runtime.NewScheme() + // StrictCodecs provides methods for retrieving codecs and serializers + // for specific versions and content types. + StrictCodecs = serializer.NewCodecFactory(Scheme, serializer.EnableStrict) + // LenientCodecs provides methods for retrieving codecs and serializers + // for specific versions and content types. + LenientCodecs = serializer.NewCodecFactory(Scheme, serializer.DisableStrict) +) + +func init() { + AddToScheme(Scheme) +} + +// AddToScheme registers the API group and adds types to a scheme +func AddToScheme(scheme *runtime.Scheme) { utilruntime.Must(config.AddToScheme(scheme)) utilruntime.Must(v1beta1.AddToScheme(scheme)) utilruntime.Must(v1alpha1.AddToScheme(scheme)) diff --git a/pkg/config/scheme/scheme_test.go b/pkg/config/scheme/scheme_test.go new file mode 100644 index 000000000..e14549da4 --- /dev/null +++ b/pkg/config/scheme/scheme_test.go @@ -0,0 +1,28 @@ +/* +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 scheme + +import ( + "testing" + + "k8s.io/apimachinery/pkg/api/apitesting/roundtrip" + "k8s.io/kubectl/pkg/config/fuzzer" +) + +func TestRoundTripTypes(t *testing.T) { + roundtrip.RoundTripTestForScheme(t, Scheme, fuzzer.Funcs) +} diff --git a/pkg/kuberc/kuberc.go b/pkg/kuberc/kuberc.go index 6562daa4f..23f08fc06 100644 --- a/pkg/kuberc/kuberc.go +++ b/pkg/kuberc/kuberc.go @@ -24,16 +24,13 @@ import ( "regexp" "strings" - "k8s.io/kubectl/pkg/config" - kuberc "k8s.io/kubectl/pkg/config/install" - "github.com/spf13/cobra" "github.com/spf13/pflag" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/util/homedir" + "k8s.io/kubectl/pkg/config" ) const RecommendedKubeRCFileName = "kuberc" @@ -44,16 +41,8 @@ var ( aliasNameRegex = regexp.MustCompile("^[a-zA-Z]+$") shortHandRegex = regexp.MustCompile("^-[a-zA-Z]+$") - - scheme = runtime.NewScheme() - strictCodecs = serializer.NewCodecFactory(scheme, serializer.EnableStrict) - lenientCodecs = serializer.NewCodecFactory(scheme, serializer.DisableStrict) ) -func init() { - kuberc.Install(scheme) -} - // PreferencesHandler is responsible for setting default flags // arguments based on user's kuberc configuration. type PreferencesHandler interface { diff --git a/pkg/kuberc/marshal.go b/pkg/kuberc/marshal.go index 3c2323e45..537b6c272 100644 --- a/pkg/kuberc/marshal.go +++ b/pkg/kuberc/marshal.go @@ -24,12 +24,11 @@ import ( "io" "os" - "k8s.io/klog/v2" - "k8s.io/apimachinery/pkg/runtime/schema" utilyaml "k8s.io/apimachinery/pkg/util/yaml" - + "k8s.io/klog/v2" "k8s.io/kubectl/pkg/config" + "k8s.io/kubectl/pkg/config/scheme" ) // decodePreference iterates over the yamls in kuberc file to find the supported kuberc version. @@ -58,10 +57,10 @@ func decodePreference(kubercFile string) (*config.Preference, error) { } // remember we attempted attemptedItems++ - pref, gvk, strictDecodeErr := strictCodecs.UniversalDecoder().Decode(doc, nil, nil) + pref, gvk, strictDecodeErr := scheme.StrictCodecs.UniversalDecoder().Decode(doc, nil, nil) if strictDecodeErr != nil { var lenientDecodeErr error - pref, gvk, lenientDecodeErr = lenientCodecs.UniversalDecoder().Decode(doc, nil, nil) + pref, gvk, lenientDecodeErr = scheme.LenientCodecs.UniversalDecoder().Decode(doc, nil, nil) if lenientDecodeErr != nil { // both strict and lenient failed // verbose log the error with the most information about this item and continue