1
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
39 func MarshalToYaml(obj runtime.Object, gv schema.GroupVersion) ([]byte, error) {
40 return MarshalToYamlForCodecs(obj, gv, clientsetscheme.Codecs)
41 }
42
43
44
45
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
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
69
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
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
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
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
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
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
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
136 func GroupVersionKindsHasClusterConfiguration(gvks ...schema.GroupVersionKind) bool {
137 return GroupVersionKindsHasKind(gvks, constants.ClusterConfigurationKind)
138 }
139
140
141 func GroupVersionKindsHasInitConfiguration(gvks ...schema.GroupVersionKind) bool {
142 return GroupVersionKindsHasKind(gvks, constants.InitConfigurationKind)
143 }
144
145
146 func GroupVersionKindsHasJoinConfiguration(gvks ...schema.GroupVersionKind) bool {
147 return GroupVersionKindsHasKind(gvks, constants.JoinConfigurationKind)
148 }
149
150
151 func GroupVersionKindsHasResetConfiguration(gvks ...schema.GroupVersionKind) bool {
152 return GroupVersionKindsHasKind(gvks, constants.ResetConfigurationKind)
153 }
154
155
156 func GroupVersionKindsHasUpgradeConfiguration(gvks ...schema.GroupVersionKind) bool {
157 return GroupVersionKindsHasKind(gvks, constants.UpgradeConfigurationKind)
158 }
159
View as plain text