...

Source file src/k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/codec/codec.go

Documentation: k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/codec

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package codec
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  
    23  	"k8s.io/klog/v2"
    24  
    25  	// ensure the core apis are installed
    26  	_ "k8s.io/kubernetes/pkg/apis/core/install"
    27  
    28  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    29  	"k8s.io/apimachinery/pkg/runtime"
    30  	"k8s.io/apimachinery/pkg/runtime/schema"
    31  	"k8s.io/apimachinery/pkg/runtime/serializer"
    32  	"k8s.io/component-base/codec"
    33  	kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
    34  	"k8s.io/kubernetes/pkg/kubelet/apis/config/scheme"
    35  	kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1"
    36  )
    37  
    38  // EncodeKubeletConfig encodes an internal KubeletConfiguration to an external YAML representation.
    39  func EncodeKubeletConfig(internal *kubeletconfig.KubeletConfiguration, targetVersion schema.GroupVersion) ([]byte, error) {
    40  	encoder, err := NewKubeletconfigYAMLEncoder(targetVersion)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	// encoder will convert to external version
    45  	data, err := runtime.Encode(encoder, internal)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  	return data, nil
    50  }
    51  
    52  // NewKubeletconfigYAMLEncoder returns an encoder that can write objects in the kubeletconfig API group to YAML.
    53  func NewKubeletconfigYAMLEncoder(targetVersion schema.GroupVersion) (runtime.Encoder, error) {
    54  	_, codecs, err := scheme.NewSchemeAndCodecs()
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	mediaType := "application/yaml"
    59  	info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), mediaType)
    60  	if !ok {
    61  		return nil, fmt.Errorf("unsupported media type %q", mediaType)
    62  	}
    63  	return codecs.EncoderForVersion(info.Serializer, targetVersion), nil
    64  }
    65  
    66  // DecodeKubeletConfiguration decodes a serialized KubeletConfiguration to the internal type.
    67  func DecodeKubeletConfiguration(kubeletCodecs *serializer.CodecFactory, data []byte) (*kubeletconfig.KubeletConfiguration, error) {
    68  	var (
    69  		obj runtime.Object
    70  		gvk *schema.GroupVersionKind
    71  	)
    72  
    73  	// The UniversalDecoder runs defaulting and returns the internal type by default.
    74  	obj, gvk, err := kubeletCodecs.UniversalDecoder().Decode(data, nil, nil)
    75  	if err != nil {
    76  		// Try strict decoding first. If that fails decode with a lenient
    77  		// decoder, which has only v1beta1 registered, and log a warning.
    78  		// The lenient path is to be dropped when support for v1beta1 is dropped.
    79  		if !runtime.IsStrictDecodingError(err) {
    80  			return nil, fmt.Errorf("failed to decode: %w", err)
    81  		}
    82  
    83  		var lenientErr error
    84  		_, lenientCodecs, lenientErr := codec.NewLenientSchemeAndCodecs(
    85  			kubeletconfig.AddToScheme,
    86  			kubeletconfigv1beta1.AddToScheme,
    87  		)
    88  
    89  		if lenientErr != nil {
    90  			return nil, lenientErr
    91  		}
    92  
    93  		obj, gvk, lenientErr = lenientCodecs.UniversalDecoder().Decode(data, nil, nil)
    94  		if lenientErr != nil {
    95  			// Lenient decoding failed with the current version, return the
    96  			// original strict error.
    97  			return nil, fmt.Errorf("failed lenient decoding: %v", err)
    98  		}
    99  		// Continue with the v1beta1 object that was decoded leniently, but emit a warning.
   100  		klog.InfoS("Using lenient decoding as strict decoding failed", "err", err)
   101  	}
   102  
   103  	internalKC, ok := obj.(*kubeletconfig.KubeletConfiguration)
   104  	if !ok {
   105  		return nil, fmt.Errorf("failed to cast object to KubeletConfiguration, unexpected type: %v", gvk)
   106  	}
   107  
   108  	return internalKC, nil
   109  }
   110  
   111  // DecodeKubeletConfigurationIntoJSON decodes a serialized KubeletConfiguration to the internal type.
   112  func DecodeKubeletConfigurationIntoJSON(kubeletCodecs *serializer.CodecFactory, data []byte) ([]byte, error) {
   113  	// The UniversalDecoder runs defaulting and returns the internal type by default.
   114  	obj, _, err := kubeletCodecs.UniversalDecoder().Decode(data, nil, &unstructured.Unstructured{})
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  
   119  	objT := obj.(*unstructured.Unstructured)
   120  
   121  	return json.Marshal(objT.Object)
   122  }
   123  

View as plain text