func (s *Scheme) DecodeToVersionedObject(data []byte) (interface{}, unversioned.GroupVersionKind, error) { kind, err := s.DataKind(data) if err != nil { return nil, unversioned.GroupVersionKind{}, err } internalGV, exists := s.InternalVersions[kind.Group] if !exists { return nil, unversioned.GroupVersionKind{}, fmt.Errorf("no internalVersion specified for %v", kind) } if len(kind.Group) == 0 && len(internalGV.Group) != 0 { return nil, unversioned.GroupVersionKind{}, fmt.Errorf("group not set in '%s'", string(data)) } if len(kind.Version) == 0 && len(internalGV.Version) != 0 { return nil, unversioned.GroupVersionKind{}, fmt.Errorf("version not set in '%s'", string(data)) } if kind.Kind == "" { return nil, unversioned.GroupVersionKind{}, fmt.Errorf("kind not set in '%s'", string(data)) } obj, err := s.NewObject(kind) if err != nil { return nil, unversioned.GroupVersionKind{}, err } if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(obj); err != nil { return nil, unversioned.GroupVersionKind{}, err } return obj, kind, nil }
// DecodeIntoWithSpecifiedVersionKind compares the passed in requestGroupVersionKind // with data.Version and data.Kind, defaulting data.Version and // data.Kind to the specified value if they are empty, or generating an error if // data.Version and data.Kind are not empty and differ from the specified value. // The function then implements the functionality of DecodeInto. // If specifiedVersion and specifiedKind are empty, the function degenerates to // DecodeInto. func (s *Scheme) DecodeIntoWithSpecifiedVersionKind(data []byte, obj interface{}, requestedGVK unversioned.GroupVersionKind) error { if len(data) == 0 { return errors.New("empty input") } dataKind, err := s.DataKind(data) if err != nil { return err } if len(dataKind.Group) == 0 { dataKind.Group = requestedGVK.Group } if len(dataKind.Version) == 0 { dataKind.Version = requestedGVK.Version } if len(dataKind.Kind) == 0 { dataKind.Kind = requestedGVK.Kind } if len(requestedGVK.Group) > 0 && requestedGVK.Group != dataKind.Group { return errors.New(fmt.Sprintf("The fully qualified kind in the data (%v) does not match the specified apiVersion(%v)", dataKind, requestedGVK)) } if len(requestedGVK.Version) > 0 && requestedGVK.Version != dataKind.Version { return errors.New(fmt.Sprintf("The fully qualified kind in the data (%v) does not match the specified apiVersion(%v)", dataKind, requestedGVK)) } if len(requestedGVK.Kind) > 0 && requestedGVK.Kind != dataKind.Kind { return errors.New(fmt.Sprintf("The fully qualified kind in the data (%v) does not match the specified apiVersion(%v)", dataKind, requestedGVK)) } objGVK, err := s.ObjectKind(obj) if err != nil { return err } // Assume objects with unset fields are being unmarshalled into the // correct type. if len(dataKind.Group) == 0 { dataKind.Group = objGVK.Group } if len(dataKind.Version) == 0 { dataKind.Version = objGVK.Version } if len(dataKind.Kind) == 0 { dataKind.Kind = objGVK.Kind } external, err := s.NewObject(dataKind) if err != nil { return err } if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(external); err != nil { return err } flags, meta := s.generateConvertMeta(dataKind.GroupVersion(), objGVK.GroupVersion(), external) if err := s.converter.Convert(external, obj, flags, meta); err != nil { return err } // Version and Kind should be blank in memory. return s.SetVersionAndKind("", "", obj) }