// ResourceFromFile retrieves the name and namespace from a valid file. If the file does not // resolve to a known type an error is returned. The returned mapping can be used to determine // the correct REST endpoint to modify this resource with. func ResourceFromFile(filename string, typer runtime.ObjectTyper, mapper meta.RESTMapper) (mapping *meta.RESTMapping, namespace, name string, data []byte) { configData, err := ReadConfigData(filename) checkErr(err) data = configData version, kind, err := typer.DataVersionAndKind(data) checkErr(err) // TODO: allow unversioned objects? if len(version) == 0 { checkErr(fmt.Errorf("The resource in the provided file has no apiVersion defined")) } mapping, err = mapper.RESTMapping(version, kind) checkErr(err) obj, err := mapping.Codec.Decode(data) checkErr(err) meta := mapping.MetadataAccessor namespace, err = meta.Namespace(obj) checkErr(err) name, err = meta.Name(obj) checkErr(err) return }
// CreateObjects creates bulk of resources provided by items list. Each item must // be valid API type. It requires ObjectTyper to parse the Version and Kind and // RESTMapper to get the resource URI and REST client that knows how to create // given type func CreateObjects(typer runtime.ObjectTyper, mapper meta.RESTMapper, clientFor ClientFunc, objects []runtime.Object) util.ErrorList { allErrors := util.ErrorList{} for i, obj := range objects { version, kind, err := typer.ObjectVersionAndKind(obj) if err != nil { allErrors = append(allErrors, fmt.Errorf("Config.item[%d] kind: %v", i, err)) continue } mapping, err := mapper.RESTMapping(version, kind) if err != nil { allErrors = append(allErrors, fmt.Errorf("Config.item[%d] mapping: %v", i, err)) continue } client, err := clientFor(mapping) if err != nil { allErrors = append(allErrors, fmt.Errorf("Config.item[%d] client: %v", i, err)) continue } if err := CreateObject(client, mapping, obj); err != nil { allErrors = append(allErrors, fmt.Errorf("Config.item[%d]: %v", i, err)) } } return allErrors }
// DataToObjects converts the raw JSON data into API objects func DataToObjects(m meta.RESTMapper, t runtime.ObjectTyper, data []byte) (result []runtime.Object, errors []error) { configObj := []runtime.RawExtension{} if err := yaml.Unmarshal(data, &configObj); err != nil { errors = append(errors, fmt.Errorf("config unmarshal: %v", err)) return result, errors } for i, in := range configObj { version, kind, err := t.DataVersionAndKind(in.RawJSON) if err != nil { errors = append(errors, fmt.Errorf("item[%d] kind: %v", i, err)) continue } mapping, err := m.RESTMapping(kind, version) if err != nil { errors = append(errors, fmt.Errorf("item[%d] mapping: %v", i, err)) continue } obj, err := mapping.Codec.Decode(in.RawJSON) if err != nil { errors = append(errors, fmt.Errorf("item[%d] decode: %v", i, err)) continue } result = append(result, obj) } return }
// CreateObjects creates bulk of resources provided by items list. Each item must // be valid API type. It requires ObjectTyper to parse the Version and Kind and // RESTMapper to get the resource URI and REST client that knows how to create // given type func CreateObjects(typer runtime.ObjectTyper, mapper meta.RESTMapper, clientFor ClientFunc, objects []runtime.Object) errs.ValidationErrorList { allErrors := errs.ValidationErrorList{} for i, obj := range objects { version, kind, err := typer.ObjectVersionAndKind(obj) if err != nil { reportError(&allErrors, i, errs.NewFieldInvalid("kind", obj)) continue } mapping, err := mapper.RESTMapping(version, kind) if err != nil { reportError(&allErrors, i, errs.NewFieldNotSupported("mapping", err)) continue } client, err := clientFor(mapping) if err != nil { reportError(&allErrors, i, errs.NewFieldNotSupported("client", obj)) continue } if err := CreateObject(client, mapping, obj); err != nil { reportError(&allErrors, i, *err) } } return allErrors.Prefix("Config") }
// transformDecodeError adds additional information when a decode fails. func transformDecodeError(typer runtime.ObjectTyper, baseErr error, into runtime.Object, body []byte) error { _, kind, err := typer.ObjectVersionAndKind(into) if err != nil { return err } if version, dataKind, err := typer.DataVersionAndKind(body); err == nil && len(dataKind) > 0 { return errors.NewBadRequest(fmt.Sprintf("%s in version %s cannot be handled as a %s: %v", dataKind, version, kind, baseErr)) } return errors.NewBadRequest(fmt.Sprintf("the object provided is unrecognized (must be of type %s): %v", kind, baseErr)) }
// objectMetaAndKind retrieves kind and ObjectMeta from a runtime object, or returns an error. func objectMetaAndKind(typer runtime.ObjectTyper, obj runtime.Object) (*api.ObjectMeta, string, error) { objectMeta, err := api.ObjectMetaFor(obj) if err != nil { return nil, "", errors.NewInternalError(err) } _, kind, err := typer.ObjectVersionAndKind(obj) if err != nil { return nil, "", errors.NewInternalError(err) } return objectMeta, kind, nil }
// ResourceFromFile retrieves the name and namespace from a valid file. If the file does not // resolve to a known type an error is returned. The returned mapping can be used to determine // the correct REST endpoint to modify this resource with. // DEPRECATED: Use resource.Builder func ResourceFromFile(filename string, typer runtime.ObjectTyper, mapper meta.RESTMapper, schema validation.Schema, cmdVersion string) (mapping *meta.RESTMapping, namespace, name string, data []byte, err error) { data, err = ReadConfigData(filename) if err != nil { return } objVersion, kind, err := typer.DataVersionAndKind(data) if err != nil { return } // TODO: allow unversioned objects? if len(objVersion) == 0 { err = fmt.Errorf("the resource in the provided file has no apiVersion defined") } err = schema.ValidateBytes(data) if err != nil { return } // decode using the version stored with the object (allows codec to vary across versions) mapping, err = mapper.RESTMapping(kind, objVersion) if err != nil { return } obj, err := mapping.Codec.Decode(data) if err != nil { return } meta := mapping.MetadataAccessor namespace, err = meta.Namespace(obj) if err != nil { return } name, err = meta.Name(obj) if err != nil { return } // if the preferred API version differs, get a different mapper if cmdVersion != objVersion { mapping, err = mapper.RESTMapping(kind, cmdVersion) } return }
// ResourceFromFile retrieves the name and namespace from a valid file. If the file does not // resolve to a known type an error is returned. The returned mapping can be used to determine // the correct REST endpoint to modify this resource with. func ResourceFromFile(cmd *cobra.Command, filename string, typer runtime.ObjectTyper, mapper meta.RESTMapper, schema validation.Schema) (mapping *meta.RESTMapping, namespace, name string, data []byte) { configData, err := ReadConfigData(filename) checkErr(err) data = configData objVersion, kind, err := typer.DataVersionAndKind(data) checkErr(err) // TODO: allow unversioned objects? if len(objVersion) == 0 { checkErr(fmt.Errorf("the resource in the provided file has no apiVersion defined")) } err = schema.ValidateBytes(data) checkErr(err) // decode using the version stored with the object (allows codec to vary across versions) mapping, err = mapper.RESTMapping(kind, objVersion) checkErr(err) obj, err := mapping.Codec.Decode(data) checkErr(err) meta := mapping.MetadataAccessor namespace, err = meta.Namespace(obj) checkErr(err) name, err = meta.Name(obj) checkErr(err) // if the preferred API version differs, get a different mapper version := GetFlagString(cmd, "api-version") if version != objVersion { mapping, err = mapper.RESTMapping(kind, version) checkErr(err) } return }
// DataToObjects converts the raw JSON data into API objects func DataToObjects(m meta.RESTMapper, t runtime.ObjectTyper, data []byte) (result []runtime.Object, errors errs.ValidationErrorList) { configObj := []runtime.RawExtension{} if err := yaml.Unmarshal(data, &configObj); err != nil { errors = append(errors, errs.NewFieldInvalid("unmarshal", err)) return result, errors.Prefix("Config") } for i, in := range configObj { version, kind, err := t.DataVersionAndKind(in.RawJSON) if err != nil { itemErrs := errs.ValidationErrorList{} itemErrs = append(itemErrs, errs.NewFieldInvalid("kind", string(in.RawJSON))) errors = append(errors, itemErrs.PrefixIndex(i).Prefix("item")...) continue } mapping, err := m.RESTMapping(version, kind) if err != nil { itemErrs := errs.ValidationErrorList{} itemErrs = append(itemErrs, errs.NewFieldRequired("mapping", err)) errors = append(errors, itemErrs.PrefixIndex(i).Prefix("item")...) continue } obj, err := mapping.Codec.Decode(in.RawJSON) if err != nil { itemErrs := errs.ValidationErrorList{} itemErrs = append(itemErrs, errs.NewFieldInvalid("decode", err)) errors = append(errors, itemErrs.PrefixIndex(i).Prefix("item")...) continue } result = append(result, obj) } return }