func RunEdit(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames []string) error { addSource := func(b *resource.Builder, enforceNamespace bool, printer kubectl.ResourcePrinter) *resource.Builder { return b.FilenameParam(enforceNamespace, filenames...). ResourceTypeOrNameArgs(true, args...). Latest() } process := func(visitor resource.Visitor, original, edited []byte, obj runtime.Object, updates *resource.Info, file string, results *editResults, mapper meta.RESTMapper, defaultVersion string) error { // use strategic merge to create a patch originalJS, err := yaml.ToJSON(original) if err != nil { return preservedFile(err, file, out) } editedJS, err := yaml.ToJSON(edited) if err != nil { return preservedFile(err, file, out) } patch, err := strategicpatch.CreateStrategicMergePatch(originalJS, editedJS, obj) // TODO: change all jsonmerge to strategicpatch // for checking preconditions preconditions := []jsonmerge.PreconditionFunc{} if err != nil { glog.V(4).Infof("Unable to calculate diff, no merge is possible: %v", err) return preservedFile(err, file, out) } else { preconditions = append(preconditions, jsonmerge.RequireKeyUnchanged("apiVersion")) preconditions = append(preconditions, jsonmerge.RequireKeyUnchanged("kind")) preconditions = append(preconditions, jsonmerge.RequireMetadataKeyUnchanged("name")) results.version = defaultVersion } if hold, msg := jsonmerge.TestPreconditionsHold(patch, preconditions); !hold { fmt.Fprintf(out, "error: %s", msg) return preservedFile(nil, file, out) } return visitor.Visit(func(info *resource.Info, err error) error { patched, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, api.StrategicMergePatchType, patch) if err != nil { fmt.Fprintln(out, results.addError(err, info)) return nil } info.Refresh(patched, true) cmdutil.PrintSuccess(mapper, false, out, info.Mapping.Resource, info.Name, "edited") return nil }) } return doEdit(f, out, cmd, "kubectl-edit-", true, addSource, process) }
func (conf *K8sClientConfig) CreateRc(fileName string) (rc *api.ReplicationController, err error) { if conf.client == nil { conf.Init() } if !strings.HasSuffix(fileName, ".yaml") && !strings.HasSuffix(fileName, ".json") { err = fmt.Errorf("Only Support Yaml and Json") return } data, err := ioutil.ReadFile(fileName) if err != nil { log.Fatalf("Unexpected error while reading file: %v", err) return } jsonData := data if strings.HasSuffix(fileName, ".yaml") { jsonData, err = yaml.ToJSON(data) if err != nil { log.Fatalf("Unexpected error while changing Yaml to Json: %v", err) return } } //log.Println(string(jsonData)) ctrl := &api.ReplicationController{} if err = runtime.DecodeInto(api.Codecs.LegacyCodec(apiunversioned.GroupVersion{}), jsonData, ctrl); err != nil { log.Fatalf("Unexpected error decoding rc: %v", err) } //log.Println(ctrl.Spec.Template.) rc, err = conf.createReplicationControllers(ctrl) return }
func registerAdmissionPlugins(t *testing.T, names ...string) { for _, name := range names { pluginName := name admission.RegisterPlugin(pluginName, func(client kclientset.Interface, config io.Reader) (admission.Interface, error) { plugin := &testAdmissionPlugin{ name: pluginName, } if config != nil && !reflect.ValueOf(config).IsNil() { configData, err := ioutil.ReadAll(config) if err != nil { return nil, err } configData, err = kyaml.ToJSON(configData) if err != nil { return nil, err } configObj := &TestPluginConfig{} err = runtime.DecodeInto(kapi.Codecs.UniversalDecoder(), configData, configObj) if err != nil { return nil, err } plugin.labelValue = configObj.Data } return plugin, nil }) } }
// Parse takes a filename, loads the file, and parses it into one or more *Manifest objects. func Parse(filename string) ([]*Manifest, error) { in, err := os.Open(filename) if err != nil { return nil, err } ms := []*Manifest{} docs, err := SplitYAML(in) in.Close() if err != nil { return ms, err } for _, doc := range docs { data, err := yaml.ToJSON(doc) if err != nil { return nil, fmt.Errorf("Failed to parse %s: %s", filename, err) } vo, version, kind, err := api.Scheme.Raw().DecodeToVersionedObject(data) if err != nil { return ms, err } m := &Manifest{Version: version, Kind: kind, VersionedObject: vo, Source: filename} ms = append(ms, m) } return ms, nil }
func tryDecodeSinglePod(data []byte, defaultFn defaultFunc) (parsed bool, pod *api.Pod, err error) { // JSON is valid YAML, so this should work for everything. json, err := utilyaml.ToJSON(data) if err != nil { return false, nil, err } obj, err := api.Scheme.Decode(json) if err != nil { return false, pod, err } // Check whether the object could be converted to single pod. if _, ok := obj.(*api.Pod); !ok { err = fmt.Errorf("invalid pod: %+v", obj) return false, pod, err } newPod := obj.(*api.Pod) // Apply default values and validate the pod. if err = defaultFn(newPod); err != nil { return true, pod, err } if errs := validation.ValidatePod(newPod); len(errs) > 0 { err = fmt.Errorf("invalid pod: %v", errs) return true, pod, err } return true, newPod, nil }
// TODO: Consider using a mocking library instead or fully fleshing this out into a fake impl and putting it in some // generally available location func (f *Factory) ValidateBytes(data []byte) error { var obj interface{} out, err := k8syaml.ToJSON(data) if err != nil { return err } data = out if err := json.Unmarshal(data, &obj); err != nil { return err } fields, ok := obj.(map[string]interface{}) if !ok { return fmt.Errorf("error in unmarshaling data %s", string(data)) } // Note: This only supports the 2 api versions we expect from the test it is currently supporting. groupVersion := fields["apiVersion"] switch groupVersion { case "v1": return f.defaultSchema.ValidateBytes(data) case "extensions/v1beta1": return f.extensionsSchema.ValidateBytes(data) default: return fmt.Errorf("Unsupported API version %s", groupVersion) } }
// ReadObjectsFromPath reads objects from the specified file for testing. func ReadObjectsFromPath(path, namespace string, decoder runtime.Decoder, typer runtime.ObjectTyper) ([]runtime.Object, error) { data, err := ioutil.ReadFile(path) if err != nil { return nil, err } data, err = yaml.ToJSON(data) if err != nil { return nil, err } obj, err := runtime.Decode(decoder, data) if err != nil { return nil, err } if !meta.IsListType(obj) { if err := setNamespace(typer, obj, namespace); err != nil { return nil, err } return []runtime.Object{obj}, nil } list, err := meta.ExtractList(obj) if err != nil { return nil, err } errs := runtime.DecodeList(list, decoder) if len(errs) > 0 { return nil, errs[0] } for _, o := range list { if err := setNamespace(typer, o, namespace); err != nil { return nil, err } } return list, nil }
func IsThirdPartyObject(rawData []byte, gvk *unversioned.GroupVersionKind) (isThirdParty bool, gvkOut *unversioned.GroupVersionKind, err error) { var gv unversioned.GroupVersion if gvk == nil { data, err := yaml.ToJSON(rawData) if err != nil { return false, nil, err } metadata := unversioned.TypeMeta{} if err = json.Unmarshal(data, &metadata); err != nil { return false, nil, err } gv, err = unversioned.ParseGroupVersion(metadata.APIVersion) if err != nil { return false, nil, err } gvkOut = &unversioned.GroupVersionKind{ Group: gv.Group, Version: gv.Version, Kind: metadata.Kind, } } else { gv = gvk.GroupVersion() gvkOut = gvk } return registered.IsThirdPartyAPIGroupVersion(gv), gvkOut, nil }
func walkJSONFiles(inDir string, fn func(name, path string, data []byte)) error { err := filepath.Walk(inDir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() && path != inDir { return filepath.SkipDir } name := filepath.Base(path) ext := filepath.Ext(name) if ext != "" { name = name[:len(name)-len(ext)] } if !(ext == ".json" || ext == ".yaml") { return nil } glog.Infof("testing %s", path) data, err := ioutil.ReadFile(path) if err != nil { return err } if ext == ".yaml" { data, err = yaml.ToJSON(data) if err != nil { return err } } fn(name, path, data) return nil }) return err }
func (c *commandTokenSource) parseTokenCmdOutput(output []byte) (*oauth2.Token, error) { output, err := yaml.ToJSON(output) if err != nil { return nil, err } var data interface{} if err := json.Unmarshal(output, &data); err != nil { return nil, err } accessToken, err := parseJSONPath(data, "token-key", c.tokenKey) if err != nil { return nil, fmt.Errorf("error parsing token-key %q: %v", c.tokenKey, err) } expiryStr, err := parseJSONPath(data, "expiry-key", c.expiryKey) if err != nil { return nil, fmt.Errorf("error parsing expiry-key %q: %v", c.expiryKey, err) } var expiry time.Time if t, err := time.Parse(c.timeFmt, expiryStr); err != nil { glog.V(4).Infof("Failed to parse token expiry from %s (fmt=%s): %v", expiryStr, c.timeFmt, err) } else { expiry = t } return &oauth2.Token{ AccessToken: accessToken, TokenType: "Bearer", Expiry: expiry, }, nil }
func tryDecodePodList(data []byte, defaultFn defaultFunc) (parsed bool, pods api.PodList, err error) { json, err := utilyaml.ToJSON(data) if err != nil { return false, api.PodList{}, err } obj, err := api.Scheme.Decode(json) if err != nil { return false, pods, err } // Check whether the object could be converted to list of pods. if _, ok := obj.(*api.PodList); !ok { err = fmt.Errorf("invalid pods list: %+v", obj) return false, pods, err } newPods := obj.(*api.PodList) // Apply default values and validate pods. for i := range newPods.Items { newPod := &newPods.Items[i] if err = defaultFn(newPod); err != nil { return true, pods, err } if errs := validation.ValidatePod(newPod); len(errs) > 0 { err = fmt.Errorf("invalid pod: %v", errs) return true, pods, err } } return true, *newPods, err }
// stripComments will transform a YAML file into JSON, thus dropping any comments // in it. Note that if the given file has a syntax error, the transformation will // fail and we will manually drop all comments from the file. func stripComments(file []byte) []byte { stripped, err := yaml.ToJSON(file) if err != nil { stripped = manualStrip(file) } return stripped }
func walkJSONFiles(inDir string, fn func(name, path string, data []byte)) error { return filepath.Walk(inDir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() && path != inDir { return filepath.SkipDir } file := filepath.Base(path) if ext := filepath.Ext(file); ext == ".json" || ext == ".yaml" { glog.Infof("Testing %s", path) data, err := ioutil.ReadFile(path) if err != nil { return err } name := strings.TrimSuffix(file, ext) if ext == ".yaml" { out, err := yaml.ToJSON(data) if err != nil { return fmt.Errorf("%s: %v", path, err) } data = out } fn(name, path, data) } return nil }) }
func (s *SwaggerSchema) ValidateBytes(data []byte) error { var obj interface{} out, err := yaml.ToJSON(data) if err != nil { return err } data = out if err := json.Unmarshal(data, &obj); err != nil { return err } fields, ok := obj.(map[string]interface{}) if !ok { return fmt.Errorf("error in unmarshaling data %s", string(data)) } apiVersion := fields["apiVersion"] if apiVersion == nil { return fmt.Errorf("apiVersion not set") } kind := fields["kind"] if kind == nil { return fmt.Errorf("kind not set") } allErrs := s.ValidateObject(obj, apiVersion.(string), "", apiVersion.(string)+"."+kind.(string)) if len(allErrs) == 1 { return allErrs[0] } return errors.NewAggregate(allErrs) }
// Apply attempts to apply the changes described by Delta onto latest, // returning an error if the changes cannot be applied cleanly. // IsConflicting will be true if the changes overlap, otherwise a // generic error will be returned. func (d *Delta) Apply(latest []byte) ([]byte, error) { base, err := yaml.ToJSON(latest) if err != nil { return nil, err } changes, err := jsonpatch.CreateMergePatch(d.original, base) if err != nil { return nil, err } diff1 := make(map[string]interface{}) if err := json.Unmarshal(d.edit, &diff1); err != nil { return nil, err } diff2 := make(map[string]interface{}) if err := json.Unmarshal(changes, &diff2); err != nil { return nil, err } for _, fn := range d.preconditions { hold1, _ := fn(diff1) hold2, _ := fn(diff2) if !hold1 || !hold2 { return nil, ErrPreconditionFailed } } glog.V(6).Infof("Testing for conflict between:\n%s\n%s", string(d.edit), string(changes)) if hasConflicts(diff1, diff2) { return nil, ErrConflict } return jsonpatch.MergePatch(base, d.edit) }
func (c yamlCodec) Decode(data []byte) (Object, error) { out, err := yaml.ToJSON(data) if err != nil { return nil, err } data = out return c.Codec.Decode(data) }
func (c yamlSerializer) Decode(data []byte, gvk *unversioned.GroupVersionKind, into runtime.Object) (runtime.Object, *unversioned.GroupVersionKind, error) { out, err := yaml.ToJSON(data) if err != nil { return nil, nil, err } data = out return c.Serializer.Decode(data, gvk, into) }
// TODO: Remove this when a YAML serializer is available from upstream func ReadYAMLInto(data []byte, obj runtime.Object) error { data, err := kyaml.ToJSON(data) if err != nil { return err } err = runtime.DecodeInto(Codec, data, obj) return captureSurroundingJSONForError("error reading config: ", data, err) }
func (c yamlCodec) DecodeInto(data []byte, obj Object) error { out, err := yaml.ToJSON(data) if err != nil { return err } data = out return c.Codec.DecodeInto(data, obj) }
func (o *SyncGroupsOptions) Complete(typeArg, whitelistFile, blacklistFile, configFile string, args []string, f *clientcmd.Factory) error { switch typeArg { case string(GroupSyncSourceLDAP): o.Source = GroupSyncSourceLDAP case string(GroupSyncSourceOpenShift): o.Source = GroupSyncSourceOpenShift default: return fmt.Errorf("unrecognized --type %q; allowed types %v", typeArg, strings.Join(AllowedSourceTypes, ",")) } // if args are given, they are OpenShift Group names forming a whitelist if len(args) > 0 { o.Whitelist = append(o.Whitelist, args...) } // unpack whitelist file from source if len(whitelistFile) != 0 { whitelistData, err := readLines(whitelistFile) if err != nil { return err } o.Whitelist = append(o.Whitelist, whitelistData...) } // unpack blacklist file from source if len(blacklistFile) != 0 { blacklistData, err := readLines(blacklistFile) if err != nil { return err } o.Blacklist = append(o.Blacklist, blacklistData...) } yamlConfig, err := ioutil.ReadFile(configFile) if err != nil { return fmt.Errorf("could not read file %s: %v", configFile, err) } jsonConfig, err := kyaml.ToJSON(yamlConfig) if err != nil { return fmt.Errorf("could not parse file %s: %v", configFile, err) } if err := configapilatest.Codec.DecodeInto(jsonConfig, &o.Config); err != nil { return err } if f != nil { osClient, _, err := f.Clients() if err != nil { return err } o.GroupInterface = osClient.Groups() } return nil }
func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, shortOutput bool, options *PatchOptions) error { cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } cmdTenant, enforceTenant, err := f.DefaultTenant() if err != nil { return err } patch := cmdutil.GetFlagString(cmd, "patch") if len(patch) == 0 { return cmdutil.UsageError(cmd, "Must specify -p to patch") } patchBytes, err := yaml.ToJSON([]byte(patch)) if err != nil { return fmt.Errorf("unable to parse %q: %v", patch, err) } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). TenantParam(cmdTenant).DefaultTenant(). FilenameParam(enforceTenant, enforceNamespace, options.Filenames...). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return err } infos, err := r.Infos() if err != nil { return err } if len(infos) > 1 { return fmt.Errorf("multiple resources provided") } info := infos[0] name, namespace := info.Name, info.Namespace mapping := info.ResourceMapping() client, err := f.RESTClient(mapping) if err != nil { return err } helper := resource.NewHelper(client, mapping) _, err = helper.Patch(namespace, name, api.StrategicMergePatchType, patchBytes) if err != nil { return err } cmdutil.PrintSuccess(mapper, shortOutput, out, "", name, "patched") return nil }
// NewDelta accepts two JSON or YAML documents and calculates the difference // between them. It returns a Delta object which can be used to resolve // conflicts against a third version with a common parent, or an error // if either document is in error. func NewDelta(from, to []byte) (*Delta, error) { d := &Delta{} before, err := yaml.ToJSON(from) if err != nil { return nil, err } after, err := yaml.ToJSON(to) if err != nil { return nil, err } diff, err := jsonpatch.CreateMergePatch(before, after) if err != nil { return nil, err } glog.V(6).Infof("Patch created from:\n%s\n%s\n%s", string(before), string(after), string(diff)) d.original = before d.edit = diff return d, nil }
// rcFromManifest reads a .json/yaml file and returns the rc in it. func rcFromManifest(fileName string) *api.ReplicationController { var controller api.ReplicationController framework.Logf("Parsing rc from %v", fileName) data := framework.ReadOrDie(fileName) json, err := utilyaml.ToJSON(data) Expect(err).NotTo(HaveOccurred()) Expect(runtime.DecodeInto(api.Codecs.UniversalDecoder(), json, &controller)).NotTo(HaveOccurred()) return &controller }
// svcFromManifest reads a .json/yaml file and returns the rc in it. func svcFromManifest(fileName string) *api.Service { var svc api.Service framework.Logf("Parsing service from %v", fileName) data := framework.ReadOrDie(fileName) json, err := utilyaml.ToJSON(data) Expect(err).NotTo(HaveOccurred()) Expect(runtime.DecodeInto(api.Codecs.UniversalDecoder(), json, &svc)).NotTo(HaveOccurred()) return &svc }
// svcFromManifest reads a .json/yaml file and returns the rc in it. func svcFromManifest(fileName string) *api.Service { var svc api.Service Logf("Parsing service from %v", fileName) data, err := ioutil.ReadFile(fileName) Expect(err).NotTo(HaveOccurred()) json, err := utilyaml.ToJSON(data) Expect(err).NotTo(HaveOccurred()) Expect(api.Scheme.DecodeInto(json, &svc)).NotTo(HaveOccurred()) return &svc }
// rcFromManifest reads a .json/yaml file and returns the rc in it. func rcFromManifest(fileName string) *api.ReplicationController { var controller api.ReplicationController Logf("Parsing rc from %v", fileName) data, err := ioutil.ReadFile(fileName) Expect(err).NotTo(HaveOccurred()) json, err := utilyaml.ToJSON(data) Expect(err).NotTo(HaveOccurred()) Expect(api.Scheme.DecodeInto(json, &controller)).NotTo(HaveOccurred()) return &controller }
// InfoForData creates an Info object for the given data. An error is returned // if any of the decoding or client lookup steps fail. Name and namespace will be // set into Info if the mapping's MetadataAccessor can retrieve them. func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) { json, err := yaml.ToJSON(data) if err != nil { return nil, fmt.Errorf("unable to parse %q: %v", source, err) } data = json version, kind, err := runtime.UnstructuredJSONScheme.DataVersionAndKind(data) if err != nil { return nil, fmt.Errorf("unable to get type info from %q: %v", source, err) } gv, err := unversioned.ParseGroupVersion(version) if err != nil { return nil, fmt.Errorf("unable to parse group/version from %q: %v", version, err) } if ok := registered.IsRegisteredAPIGroupVersion(gv); !ok { return nil, fmt.Errorf("API version %q in %q isn't supported, only supports API versions %q", version, source, registered.RegisteredGroupVersions) } if kind == "" { return nil, fmt.Errorf("kind not set in %q", source) } mapping, err := m.RESTMapping(unversioned.GroupKind{Group: gv.Group, Kind: kind}, gv.Version) if err != nil { return nil, fmt.Errorf("unable to recognize %q: %v", source, err) } obj, err := mapping.Codec.Decode(data) if err != nil { return nil, fmt.Errorf("unable to load %q: %v", source, err) } client, err := m.ClientForMapping(mapping) if err != nil { return nil, fmt.Errorf("unable to connect to a server to handle %q: %v", mapping.Resource, err) } name, _ := mapping.MetadataAccessor.Name(obj) namespace, _ := mapping.MetadataAccessor.Namespace(obj) resourceVersion, _ := mapping.MetadataAccessor.ResourceVersion(obj) var versionedObject interface{} if vo, _, _, err := api.Scheme.Raw().DecodeToVersionedObject(data); err == nil { versionedObject = vo } return &Info{ Mapping: mapping, Client: client, Namespace: namespace, Name: name, Source: source, VersionedObject: versionedObject, Object: obj, ResourceVersion: resourceVersion, }, nil }
func ReadYAMLFile(filename string, obj runtime.Object) error { data, err := ioutil.ReadFile(filename) if err != nil { return err } data, err = kyaml.ToJSON(data) if err != nil { return err } err = Codec.DecodeInto(data, obj) return captureSurroundingJSONForError(fmt.Sprintf("could not load config file %q due to an error: ", filename), data, err) }
// ingFromManifest reads a .json/yaml file and returns the rc in it. func ingFromManifest(fileName string) *extensions.Ingress { var ing extensions.Ingress framework.Logf("Parsing ingress from %v", fileName) data, err := ioutil.ReadFile(fileName) framework.ExpectNoError(err) json, err := utilyaml.ToJSON(data) framework.ExpectNoError(err) framework.ExpectNoError(runtime.DecodeInto(api.Codecs.UniversalDecoder(), json, &ing)) return &ing }
func updateResource(target *resource.Info, currentObj runtime.Object) error { encoder := api.Codecs.LegacyCodec(registered.EnabledVersions()...) originalSerialization, err := runtime.Encode(encoder, currentObj) if err != nil { return err } editedSerialization, err := runtime.Encode(encoder, target.Object) if err != nil { return err } originalJS, err := yaml.ToJSON(originalSerialization) if err != nil { return err } editedJS, err := yaml.ToJSON(editedSerialization) if err != nil { return err } if reflect.DeepEqual(originalJS, editedJS) { return ErrAlreadyExists{target.Name} } patch, err := strategicpatch.CreateStrategicMergePatch(originalJS, editedJS, currentObj) if err != nil { return err } // send patch to server helper := resource.NewHelper(target.Client, target.Mapping) if _, err = helper.Patch(target.Namespace, target.Name, api.StrategicMergePatchType, patch); err != nil { return err } return nil }