...

Source file src/k8s.io/kubernetes/cmd/kubeadm/app/util/marshal.go

Documentation: k8s.io/kubernetes/cmd/kubeadm/app/util

     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 util
    18  
    19  import (
    20  	"bufio"
    21  	"bytes"
    22  	"io"
    23  
    24  	"github.com/pkg/errors"
    25  
    26  	"k8s.io/apimachinery/pkg/runtime"
    27  	"k8s.io/apimachinery/pkg/runtime/schema"
    28  	"k8s.io/apimachinery/pkg/runtime/serializer"
    29  	yamlserializer "k8s.io/apimachinery/pkg/runtime/serializer/yaml"
    30  	errorsutil "k8s.io/apimachinery/pkg/util/errors"
    31  	utilyaml "k8s.io/apimachinery/pkg/util/yaml"
    32  	clientsetscheme "k8s.io/client-go/kubernetes/scheme"
    33  
    34  	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
    35  	"k8s.io/kubernetes/cmd/kubeadm/app/constants"
    36  )
    37  
    38  // MarshalToYaml marshals an object into yaml.
    39  func MarshalToYaml(obj runtime.Object, gv schema.GroupVersion) ([]byte, error) {
    40  	return MarshalToYamlForCodecs(obj, gv, clientsetscheme.Codecs)
    41  }
    42  
    43  // MarshalToYamlForCodecs marshals an object into yaml using the specified codec
    44  // TODO: Is specifying the gv really needed here?
    45  // TODO: Can we support json out of the box easily here?
    46  func MarshalToYamlForCodecs(obj runtime.Object, gv schema.GroupVersion, codecs serializer.CodecFactory) ([]byte, error) {
    47  	const mediaType = runtime.ContentTypeYAML
    48  	info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), mediaType)
    49  	if !ok {
    50  		return []byte{}, errors.Errorf("unsupported media type %q", mediaType)
    51  	}
    52  
    53  	encoder := codecs.EncoderForVersion(info.Serializer, gv)
    54  	return runtime.Encode(encoder, obj)
    55  }
    56  
    57  // UniversalUnmarshal unmarshals YAML or JSON into a runtime.Object using the universal deserializer.
    58  func UniversalUnmarshal(buffer []byte) (runtime.Object, error) {
    59  	codecs := clientsetscheme.Codecs
    60  	decoder := codecs.UniversalDeserializer()
    61  	obj, _, err := decoder.Decode(buffer, nil, nil)
    62  	if err != nil {
    63  		return nil, errors.Wrapf(err, "failed to decode %s into runtime.Object", buffer)
    64  	}
    65  	return obj, nil
    66  }
    67  
    68  // SplitYAMLDocuments reads the YAML bytes per-document, unmarshals the TypeMeta information from each document
    69  // and returns a map between the GroupVersionKind of the document and the document bytes
    70  func SplitYAMLDocuments(yamlBytes []byte) (kubeadmapi.DocumentMap, error) {
    71  	gvkmap := kubeadmapi.DocumentMap{}
    72  	knownKinds := map[string]bool{}
    73  	errs := []error{}
    74  	buf := bytes.NewBuffer(yamlBytes)
    75  	reader := utilyaml.NewYAMLReader(bufio.NewReader(buf))
    76  	for {
    77  		// Read one YAML document at a time, until io.EOF is returned
    78  		b, err := reader.Read()
    79  		if err == io.EOF {
    80  			break
    81  		} else if err != nil {
    82  			return nil, err
    83  		}
    84  		if len(b) == 0 {
    85  			break
    86  		}
    87  		// Deserialize the TypeMeta information of this byte slice
    88  		gvk, err := yamlserializer.DefaultMetaFactory.Interpret(b)
    89  		if err != nil {
    90  			return nil, err
    91  		}
    92  		if len(gvk.Group) == 0 || len(gvk.Version) == 0 || len(gvk.Kind) == 0 {
    93  			return nil, errors.Errorf("invalid configuration for GroupVersionKind %+v: kind and apiVersion is mandatory information that must be specified", gvk)
    94  		}
    95  
    96  		// Check whether the kind has been registered before. If it has, throw an error
    97  		if known := knownKinds[gvk.Kind]; known {
    98  			errs = append(errs, errors.Errorf("invalid configuration: kind %q is specified twice in YAML file", gvk.Kind))
    99  			continue
   100  		}
   101  		knownKinds[gvk.Kind] = true
   102  
   103  		// Save the mapping between the gvk and the bytes that object consists of
   104  		gvkmap[*gvk] = b
   105  	}
   106  	if err := errorsutil.NewAggregate(errs); err != nil {
   107  		return nil, err
   108  	}
   109  	return gvkmap, nil
   110  }
   111  
   112  // GroupVersionKindsFromBytes parses the bytes and returns a gvk slice
   113  func GroupVersionKindsFromBytes(b []byte) ([]schema.GroupVersionKind, error) {
   114  	gvkmap, err := SplitYAMLDocuments(b)
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  	gvks := []schema.GroupVersionKind{}
   119  	for gvk := range gvkmap {
   120  		gvks = append(gvks, gvk)
   121  	}
   122  	return gvks, nil
   123  }
   124  
   125  // GroupVersionKindsHasKind returns whether the following gvk slice contains the kind given as a parameter
   126  func GroupVersionKindsHasKind(gvks []schema.GroupVersionKind, kind string) bool {
   127  	for _, gvk := range gvks {
   128  		if gvk.Kind == kind {
   129  			return true
   130  		}
   131  	}
   132  	return false
   133  }
   134  
   135  // GroupVersionKindsHasClusterConfiguration returns whether the following gvk slice contains a ClusterConfiguration object
   136  func GroupVersionKindsHasClusterConfiguration(gvks ...schema.GroupVersionKind) bool {
   137  	return GroupVersionKindsHasKind(gvks, constants.ClusterConfigurationKind)
   138  }
   139  
   140  // GroupVersionKindsHasInitConfiguration returns whether the following gvk slice contains a InitConfiguration object
   141  func GroupVersionKindsHasInitConfiguration(gvks ...schema.GroupVersionKind) bool {
   142  	return GroupVersionKindsHasKind(gvks, constants.InitConfigurationKind)
   143  }
   144  
   145  // GroupVersionKindsHasJoinConfiguration returns whether the following gvk slice contains a JoinConfiguration object
   146  func GroupVersionKindsHasJoinConfiguration(gvks ...schema.GroupVersionKind) bool {
   147  	return GroupVersionKindsHasKind(gvks, constants.JoinConfigurationKind)
   148  }
   149  
   150  // GroupVersionKindsHasResetConfiguration returns whether the following gvk slice contains a ResetConfiguration object
   151  func GroupVersionKindsHasResetConfiguration(gvks ...schema.GroupVersionKind) bool {
   152  	return GroupVersionKindsHasKind(gvks, constants.ResetConfigurationKind)
   153  }
   154  
   155  // GroupVersionKindsHasUpgradeConfiguration returns whether the following gvk slice contains a UpgradeConfiguration object
   156  func GroupVersionKindsHasUpgradeConfiguration(gvks ...schema.GroupVersionKind) bool {
   157  	return GroupVersionKindsHasKind(gvks, constants.UpgradeConfigurationKind)
   158  }
   159  

View as plain text