[VOL-3678] First implementation of the BBSim-sadis-server
Change-Id: I5077a8f861f4cc6af9759f31a4a415042c05eba3
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/codec.go b/vendor/k8s.io/apimachinery/pkg/runtime/codec.go
new file mode 100644
index 0000000..a928631
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/codec.go
@@ -0,0 +1,396 @@
+/*
+Copyright 2014 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 runtime
+
+import (
+ "bytes"
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/url"
+ "reflect"
+ "strconv"
+ "strings"
+
+ "k8s.io/apimachinery/pkg/conversion/queryparams"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/klog/v2"
+)
+
+// codec binds an encoder and decoder.
+type codec struct {
+ Encoder
+ Decoder
+}
+
+// NewCodec creates a Codec from an Encoder and Decoder.
+func NewCodec(e Encoder, d Decoder) Codec {
+ return codec{e, d}
+}
+
+// Encode is a convenience wrapper for encoding to a []byte from an Encoder
+func Encode(e Encoder, obj Object) ([]byte, error) {
+ // TODO: reuse buffer
+ buf := &bytes.Buffer{}
+ if err := e.Encode(obj, buf); err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
+
+// Decode is a convenience wrapper for decoding data into an Object.
+func Decode(d Decoder, data []byte) (Object, error) {
+ obj, _, err := d.Decode(data, nil, nil)
+ return obj, err
+}
+
+// DecodeInto performs a Decode into the provided object.
+func DecodeInto(d Decoder, data []byte, into Object) error {
+ out, gvk, err := d.Decode(data, nil, into)
+ if err != nil {
+ return err
+ }
+ if out != into {
+ return fmt.Errorf("unable to decode %s into %v", gvk, reflect.TypeOf(into))
+ }
+ return nil
+}
+
+// EncodeOrDie is a version of Encode which will panic instead of returning an error. For tests.
+func EncodeOrDie(e Encoder, obj Object) string {
+ bytes, err := Encode(e, obj)
+ if err != nil {
+ panic(err)
+ }
+ return string(bytes)
+}
+
+// UseOrCreateObject returns obj if the canonical ObjectKind returned by the provided typer matches gvk, or
+// invokes the ObjectCreator to instantiate a new gvk. Returns an error if the typer cannot find the object.
+func UseOrCreateObject(t ObjectTyper, c ObjectCreater, gvk schema.GroupVersionKind, obj Object) (Object, error) {
+ if obj != nil {
+ kinds, _, err := t.ObjectKinds(obj)
+ if err != nil {
+ return nil, err
+ }
+ for _, kind := range kinds {
+ if gvk == kind {
+ return obj, nil
+ }
+ }
+ }
+ return c.New(gvk)
+}
+
+// NoopEncoder converts an Decoder to a Serializer or Codec for code that expects them but only uses decoding.
+type NoopEncoder struct {
+ Decoder
+}
+
+var _ Serializer = NoopEncoder{}
+
+const noopEncoderIdentifier Identifier = "noop"
+
+func (n NoopEncoder) Encode(obj Object, w io.Writer) error {
+ // There is no need to handle runtime.CacheableObject, as we don't
+ // process the obj at all.
+ return fmt.Errorf("encoding is not allowed for this codec: %v", reflect.TypeOf(n.Decoder))
+}
+
+// Identifier implements runtime.Encoder interface.
+func (n NoopEncoder) Identifier() Identifier {
+ return noopEncoderIdentifier
+}
+
+// NoopDecoder converts an Encoder to a Serializer or Codec for code that expects them but only uses encoding.
+type NoopDecoder struct {
+ Encoder
+}
+
+var _ Serializer = NoopDecoder{}
+
+func (n NoopDecoder) Decode(data []byte, gvk *schema.GroupVersionKind, into Object) (Object, *schema.GroupVersionKind, error) {
+ return nil, nil, fmt.Errorf("decoding is not allowed for this codec: %v", reflect.TypeOf(n.Encoder))
+}
+
+// NewParameterCodec creates a ParameterCodec capable of transforming url values into versioned objects and back.
+func NewParameterCodec(scheme *Scheme) ParameterCodec {
+ return ¶meterCodec{
+ typer: scheme,
+ convertor: scheme,
+ creator: scheme,
+ defaulter: scheme,
+ }
+}
+
+// parameterCodec implements conversion to and from query parameters and objects.
+type parameterCodec struct {
+ typer ObjectTyper
+ convertor ObjectConvertor
+ creator ObjectCreater
+ defaulter ObjectDefaulter
+}
+
+var _ ParameterCodec = ¶meterCodec{}
+
+// DecodeParameters converts the provided url.Values into an object of type From with the kind of into, and then
+// converts that object to into (if necessary). Returns an error if the operation cannot be completed.
+func (c *parameterCodec) DecodeParameters(parameters url.Values, from schema.GroupVersion, into Object) error {
+ if len(parameters) == 0 {
+ return nil
+ }
+ targetGVKs, _, err := c.typer.ObjectKinds(into)
+ if err != nil {
+ return err
+ }
+ for i := range targetGVKs {
+ if targetGVKs[i].GroupVersion() == from {
+ if err := c.convertor.Convert(¶meters, into, nil); err != nil {
+ return err
+ }
+ // in the case where we going into the same object we're receiving, default on the outbound object
+ if c.defaulter != nil {
+ c.defaulter.Default(into)
+ }
+ return nil
+ }
+ }
+
+ input, err := c.creator.New(from.WithKind(targetGVKs[0].Kind))
+ if err != nil {
+ return err
+ }
+ if err := c.convertor.Convert(¶meters, input, nil); err != nil {
+ return err
+ }
+ // if we have defaulter, default the input before converting to output
+ if c.defaulter != nil {
+ c.defaulter.Default(input)
+ }
+ return c.convertor.Convert(input, into, nil)
+}
+
+// EncodeParameters converts the provided object into the to version, then converts that object to url.Values.
+// Returns an error if conversion is not possible.
+func (c *parameterCodec) EncodeParameters(obj Object, to schema.GroupVersion) (url.Values, error) {
+ gvks, _, err := c.typer.ObjectKinds(obj)
+ if err != nil {
+ return nil, err
+ }
+ gvk := gvks[0]
+ if to != gvk.GroupVersion() {
+ out, err := c.convertor.ConvertToVersion(obj, to)
+ if err != nil {
+ return nil, err
+ }
+ obj = out
+ }
+ return queryparams.Convert(obj)
+}
+
+type base64Serializer struct {
+ Encoder
+ Decoder
+
+ identifier Identifier
+}
+
+func NewBase64Serializer(e Encoder, d Decoder) Serializer {
+ return &base64Serializer{
+ Encoder: e,
+ Decoder: d,
+ identifier: identifier(e),
+ }
+}
+
+func identifier(e Encoder) Identifier {
+ result := map[string]string{
+ "name": "base64",
+ }
+ if e != nil {
+ result["encoder"] = string(e.Identifier())
+ }
+ identifier, err := json.Marshal(result)
+ if err != nil {
+ klog.Fatalf("Failed marshaling identifier for base64Serializer: %v", err)
+ }
+ return Identifier(identifier)
+}
+
+func (s base64Serializer) Encode(obj Object, stream io.Writer) error {
+ if co, ok := obj.(CacheableObject); ok {
+ return co.CacheEncode(s.Identifier(), s.doEncode, stream)
+ }
+ return s.doEncode(obj, stream)
+}
+
+func (s base64Serializer) doEncode(obj Object, stream io.Writer) error {
+ e := base64.NewEncoder(base64.StdEncoding, stream)
+ err := s.Encoder.Encode(obj, e)
+ e.Close()
+ return err
+}
+
+// Identifier implements runtime.Encoder interface.
+func (s base64Serializer) Identifier() Identifier {
+ return s.identifier
+}
+
+func (s base64Serializer) Decode(data []byte, defaults *schema.GroupVersionKind, into Object) (Object, *schema.GroupVersionKind, error) {
+ out := make([]byte, base64.StdEncoding.DecodedLen(len(data)))
+ n, err := base64.StdEncoding.Decode(out, data)
+ if err != nil {
+ return nil, nil, err
+ }
+ return s.Decoder.Decode(out[:n], defaults, into)
+}
+
+// SerializerInfoForMediaType returns the first info in types that has a matching media type (which cannot
+// include media-type parameters), or the first info with an empty media type, or false if no type matches.
+func SerializerInfoForMediaType(types []SerializerInfo, mediaType string) (SerializerInfo, bool) {
+ for _, info := range types {
+ if info.MediaType == mediaType {
+ return info, true
+ }
+ }
+ for _, info := range types {
+ if len(info.MediaType) == 0 {
+ return info, true
+ }
+ }
+ return SerializerInfo{}, false
+}
+
+var (
+ // InternalGroupVersioner will always prefer the internal version for a given group version kind.
+ InternalGroupVersioner GroupVersioner = internalGroupVersioner{}
+ // DisabledGroupVersioner will reject all kinds passed to it.
+ DisabledGroupVersioner GroupVersioner = disabledGroupVersioner{}
+)
+
+const (
+ internalGroupVersionerIdentifier = "internal"
+ disabledGroupVersionerIdentifier = "disabled"
+)
+
+type internalGroupVersioner struct{}
+
+// KindForGroupVersionKinds returns an internal Kind if one is found, or converts the first provided kind to the internal version.
+func (internalGroupVersioner) KindForGroupVersionKinds(kinds []schema.GroupVersionKind) (schema.GroupVersionKind, bool) {
+ for _, kind := range kinds {
+ if kind.Version == APIVersionInternal {
+ return kind, true
+ }
+ }
+ for _, kind := range kinds {
+ return schema.GroupVersionKind{Group: kind.Group, Version: APIVersionInternal, Kind: kind.Kind}, true
+ }
+ return schema.GroupVersionKind{}, false
+}
+
+// Identifier implements GroupVersioner interface.
+func (internalGroupVersioner) Identifier() string {
+ return internalGroupVersionerIdentifier
+}
+
+type disabledGroupVersioner struct{}
+
+// KindForGroupVersionKinds returns false for any input.
+func (disabledGroupVersioner) KindForGroupVersionKinds(kinds []schema.GroupVersionKind) (schema.GroupVersionKind, bool) {
+ return schema.GroupVersionKind{}, false
+}
+
+// Identifier implements GroupVersioner interface.
+func (disabledGroupVersioner) Identifier() string {
+ return disabledGroupVersionerIdentifier
+}
+
+// Assert that schema.GroupVersion and GroupVersions implement GroupVersioner
+var _ GroupVersioner = schema.GroupVersion{}
+var _ GroupVersioner = schema.GroupVersions{}
+var _ GroupVersioner = multiGroupVersioner{}
+
+type multiGroupVersioner struct {
+ target schema.GroupVersion
+ acceptedGroupKinds []schema.GroupKind
+ coerce bool
+}
+
+// NewMultiGroupVersioner returns the provided group version for any kind that matches one of the provided group kinds.
+// Kind may be empty in the provided group kind, in which case any kind will match.
+func NewMultiGroupVersioner(gv schema.GroupVersion, groupKinds ...schema.GroupKind) GroupVersioner {
+ if len(groupKinds) == 0 || (len(groupKinds) == 1 && groupKinds[0].Group == gv.Group) {
+ return gv
+ }
+ return multiGroupVersioner{target: gv, acceptedGroupKinds: groupKinds}
+}
+
+// NewCoercingMultiGroupVersioner returns the provided group version for any incoming kind.
+// Incoming kinds that match the provided groupKinds are preferred.
+// Kind may be empty in the provided group kind, in which case any kind will match.
+// Examples:
+// gv=mygroup/__internal, groupKinds=mygroup/Foo, anothergroup/Bar
+// KindForGroupVersionKinds(yetanother/v1/Baz, anothergroup/v1/Bar) -> mygroup/__internal/Bar (matched preferred group/kind)
+//
+// gv=mygroup/__internal, groupKinds=mygroup, anothergroup
+// KindForGroupVersionKinds(yetanother/v1/Baz, anothergroup/v1/Bar) -> mygroup/__internal/Bar (matched preferred group)
+//
+// gv=mygroup/__internal, groupKinds=mygroup, anothergroup
+// KindForGroupVersionKinds(yetanother/v1/Baz, yetanother/v1/Bar) -> mygroup/__internal/Baz (no preferred group/kind match, uses first kind in list)
+func NewCoercingMultiGroupVersioner(gv schema.GroupVersion, groupKinds ...schema.GroupKind) GroupVersioner {
+ return multiGroupVersioner{target: gv, acceptedGroupKinds: groupKinds, coerce: true}
+}
+
+// KindForGroupVersionKinds returns the target group version if any kind matches any of the original group kinds. It will
+// use the originating kind where possible.
+func (v multiGroupVersioner) KindForGroupVersionKinds(kinds []schema.GroupVersionKind) (schema.GroupVersionKind, bool) {
+ for _, src := range kinds {
+ for _, kind := range v.acceptedGroupKinds {
+ if kind.Group != src.Group {
+ continue
+ }
+ if len(kind.Kind) > 0 && kind.Kind != src.Kind {
+ continue
+ }
+ return v.target.WithKind(src.Kind), true
+ }
+ }
+ if v.coerce && len(kinds) > 0 {
+ return v.target.WithKind(kinds[0].Kind), true
+ }
+ return schema.GroupVersionKind{}, false
+}
+
+// Identifier implements GroupVersioner interface.
+func (v multiGroupVersioner) Identifier() string {
+ groupKinds := make([]string, 0, len(v.acceptedGroupKinds))
+ for _, gk := range v.acceptedGroupKinds {
+ groupKinds = append(groupKinds, gk.String())
+ }
+ result := map[string]string{
+ "name": "multi",
+ "target": v.target.String(),
+ "accepted": strings.Join(groupKinds, ","),
+ "coerce": strconv.FormatBool(v.coerce),
+ }
+ identifier, err := json.Marshal(result)
+ if err != nil {
+ klog.Fatalf("Failed marshaling Identifier for %#v: %v", v, err)
+ }
+ return string(identifier)
+}