// DecodeToVersion converts a JSON string back into a pointer to an api object. // Deduces the type based upon the fields added by the MetaInsertionFactory // technique. The object will be converted, if necessary, into the versioned // type before being returned. Decode will not decode objects without version // set unless version is also "". // a GroupVersion with .IsEmpty() == true is means "use the internal version for // the object's group" func (s *Scheme) DecodeToVersion(data []byte, targetVersion unversioned.GroupVersion) (interface{}, error) { obj, sourceKind, err := s.DecodeToVersionedObject(data) if err != nil { return nil, err } // Version and Kind should be blank in memory. if err := s.SetVersionAndKind("", "", obj); err != nil { return nil, err } // if the targetVersion is empty, then we want the internal version, but the internal version varies by // group. We can lookup the group now because we have knowledge of the group if targetVersion.IsEmpty() { exists := false targetVersion, exists = s.InternalVersions[sourceKind.Group] if !exists { return nil, fmt.Errorf("no internalVersion specified for %v", targetVersion) } } // Convert if needed. if targetVersion != sourceKind.GroupVersion() { objOut, err := s.NewObject(targetVersion.WithKind(sourceKind.Kind)) if err != nil { return nil, err } flags, meta := s.generateConvertMeta(sourceKind.GroupVersion(), targetVersion, obj) if err := s.converter.Convert(obj, objOut, flags, meta); err != nil { return nil, err } obj = objOut } return obj, nil }
// OriginSwaggerSchema returns a swagger API doc for an Origin schema under the /oapi prefix. func (f *Factory) OriginSwaggerSchema(client *kclient.RESTClient, version unversioned.GroupVersion) (*swagger.ApiDeclaration, error) { if version.IsEmpty() { return nil, fmt.Errorf("groupVersion cannot be empty") } body, err := client.Get().AbsPath("/").Suffix("swaggerapi", "oapi", version.Version).Do().Raw() if err != nil { return nil, err } var schema swagger.ApiDeclaration err = json.Unmarshal(body, &schema) if err != nil { return nil, fmt.Errorf("got '%s': %v", string(body), err) } return &schema, nil }
// SwaggerSchema retrieves and parses the swagger API schema the server supports. func (c *Client) SwaggerSchema(version unversioned.GroupVersion) (*swagger.ApiDeclaration, error) { if version.IsEmpty() { return nil, fmt.Errorf("groupVersion cannot be empty") } groupList, err := c.Discovery().ServerGroups() if err != nil { return nil, err } groupVersions := ExtractGroupVersions(groupList) // This check also takes care the case that kubectl is newer than the running endpoint if stringDoesntExistIn(version.String(), groupVersions) { return nil, fmt.Errorf("API version: %v is not supported by the server. Use one of: %v", version, groupVersions) } var path string if version == v1.SchemeGroupVersion { path = "/swaggerapi/api/" + version.Version } else { path = "/swaggerapi/apis/" + version.Group + "/" + version.Version } body, err := c.Get().AbsPath(path).Do().Raw() if err != nil { return nil, err } var schema swagger.ApiDeclaration err = json.Unmarshal(body, &schema) if err != nil { return nil, fmt.Errorf("got '%s': %v", string(body), err) } return &schema, nil }
// convertItemsForDisplay returns a new list that contains parallel elements that have been converted to the most preferred external version func convertItemsForDisplay(objs []runtime.Object, preferredVersions ...unversioned.GroupVersion) ([]runtime.Object, error) { ret := []runtime.Object{} for i := range objs { obj := objs[i] kind, _, err := kapi.Scheme.ObjectKind(obj) if err != nil { return nil, err } groupMeta, err := registered.Group(kind.Group) if err != nil { return nil, err } requestedVersion := unversioned.GroupVersion{} for _, preferredVersion := range preferredVersions { if preferredVersion.Group == kind.Group { requestedVersion = preferredVersion break } } actualOutputVersion := unversioned.GroupVersion{} for _, externalVersion := range groupMeta.GroupVersions { if externalVersion == requestedVersion { actualOutputVersion = externalVersion break } if actualOutputVersion.IsEmpty() { actualOutputVersion = externalVersion } } convertedObject, err := kapi.Scheme.ConvertToVersion(obj, actualOutputVersion) if err != nil { return nil, err } ret = append(ret, convertedObject) } return ret, nil }
// AsVersionedObjects converts a list of infos into versioned objects. The provided // version will be preferred as the conversion target, but the Object's mapping version will be // used if that version is not present. func AsVersionedObjects(infos []*Info, version unversioned.GroupVersion, encoder runtime.Encoder) ([]runtime.Object, error) { objects := []runtime.Object{} for _, info := range infos { if info.Object == nil { continue } // TODO: use info.VersionedObject as the value? switch obj := info.Object.(type) { case *extensions.ThirdPartyResourceData: objects = append(objects, &runtime.Unknown{Raw: obj.Data}) continue } // objects that are not part of api.Scheme must be converted to JSON // TODO: convert to map[string]interface{}, attach to runtime.Unknown? if !version.IsEmpty() { if _, err := api.Scheme.ObjectKind(info.Object); runtime.IsNotRegisteredError(err) { // TODO: ideally this would encode to version, but we don't expose multiple codecs here. data, err := runtime.Encode(encoder, info.Object) if err != nil { return nil, err } // TODO: Set ContentEncoding and ContentType. objects = append(objects, &runtime.Unknown{Raw: data}) continue } } converted, err := tryConvert(info.Mapping.ObjectConvertor, info.Object, version, info.Mapping.GroupVersionKind.GroupVersion()) if err != nil { return nil, err } objects = append(objects, converted) } return objects, nil }