kuberc: introduce fuzzing for kuberc types

Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: c29accaf5819bd4b05409cecb9bbb3ba065d840b
This commit is contained in:
Maciej Szulik 2025-05-16 13:45:37 +02:00 committed by Kubernetes Publisher
parent ca5a831a47
commit 8500d2979d
5 changed files with 86 additions and 23 deletions

View file

@ -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)
},
}
}

View file

@ -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))

View file

@ -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)
}

View file

@ -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 {

View file

@ -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