예제 #1
0
// RunGet implements the generic Get command
// TODO: convert all direct flag accessors to a struct and pass that instead of cmd
func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
	selector := cmdutil.GetFlagString(cmd, "selector")
	allNamespaces := cmdutil.GetFlagBool(cmd, "all-namespaces")
	mapper, typer := f.Object()

	cmdNamespace, err := f.DefaultNamespace()
	if err != nil {
		return err
	}

	if len(args) == 0 {
		fmt.Fprint(out, `
You must specify the type of resource to get. Valid resource types include:
   * pods (aka 'po')
   * replicationcontrollers (aka 'rc')
   * services
   * nodes (aka 'no')
   * events (aka 'ev')
   * secrets
   * limits
   * persistentVolumes (aka 'pv')
   * persistentVolumeClaims (aka 'pvc')
   * quota
`)
		return errors.New("Required resource not specified.")
	}

	// handle watch separately since we cannot watch multiple resource types
	isWatch, isWatchOnly := cmdutil.GetFlagBool(cmd, "watch"), cmdutil.GetFlagBool(cmd, "watch-only")
	if isWatch || isWatchOnly {
		r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()).
			NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces).
			SelectorParam(selector).
			ResourceTypeOrNameArgs(true, args...).
			SingleResourceType().
			Do()
		if err != nil {
			return err
		}

		mapping, err := r.ResourceMapping()
		if err != nil {
			return err
		}

		printer, err := f.PrinterForMapping(cmd, mapping, allNamespaces)
		if err != nil {
			return err
		}

		obj, err := r.Object()
		if err != nil {
			return err
		}

		rv, err := mapping.MetadataAccessor.ResourceVersion(obj)
		if err != nil {
			return err
		}

		// print the current object
		if !isWatchOnly {
			if err := printer.PrintObj(obj, out); err != nil {
				return fmt.Errorf("unable to output the provided object: %v", err)
			}
		}

		// print watched changes
		w, err := r.Watch(rv)
		if err != nil {
			return err
		}

		qingctl.WatchLoop(w, func(e watch.Event) error {
			return printer.PrintObj(e.Object, out)
		})
		return nil
	}

	b := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()).
		NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces).
		SelectorParam(selector).
		ResourceTypeOrNameArgs(true, args...).
		ContinueOnError().
		Latest()
	printer, generic, err := cmdutil.PrinterForCommand(cmd)
	if err != nil {
		return err
	}

	if generic {
		clientConfig, err := f.ClientConfig()
		if err != nil {
			return err
		}
		defaultVersion := clientConfig.Version

		singular := false
		r := b.Flatten().Do()
		infos, err := r.IntoSingular(&singular).Infos()
		if err != nil {
			return err
		}

		// the outermost object will be converted to the output-version, but inner
		// objects can use their mappings
		version := cmdutil.OutputVersion(cmd, defaultVersion)
		obj, err := resource.AsVersionedObject(infos, !singular, version)
		if err != nil {
			return err
		}

		return printer.PrintObj(obj, out)
	}

	// use the default printer for each object
	return b.Do().Visit(func(r *resource.Info) error {
		printer, err := f.PrinterForMapping(cmd, r.Mapping, allNamespaces)
		if err != nil {
			return err
		}
		return printer.PrintObj(r.Object, out)
	})
}
예제 #2
0
func RunLabel(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
	resources, labelArgs := []string{}, []string{}
	first := true
	for _, s := range args {
		isLabel := strings.Contains(s, "=") || strings.HasSuffix(s, "-")
		switch {
		case first && isLabel:
			first = false
			fallthrough
		case !first && isLabel:
			labelArgs = append(labelArgs, s)
		case first && !isLabel:
			resources = append(resources, s)
		case !first && !isLabel:
			return cmdutil.UsageError(cmd, "all resources must be specified before label changes: %s", s)
		}
	}
	if len(resources) < 1 {
		return cmdutil.UsageError(cmd, "one or more resources must be specified as <resource> <name> or <resource>/<name>")
	}
	if len(labelArgs) < 1 {
		return cmdutil.UsageError(cmd, "at least one label update is required")
	}

	selector := cmdutil.GetFlagString(cmd, "selector")
	all := cmdutil.GetFlagBool(cmd, "all")
	overwrite := cmdutil.GetFlagBool(cmd, "overwrite")
	resourceVersion := cmdutil.GetFlagString(cmd, "resource-version")

	cmdNamespace, err := f.DefaultNamespace()
	if err != nil {
		return err
	}

	labels, remove, err := parseLabels(labelArgs)
	if err != nil {
		return cmdutil.UsageError(cmd, err.Error())
	}

	mapper, typer := f.Object()
	b := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()).
		ContinueOnError().
		NamespaceParam(cmdNamespace).DefaultNamespace().
		SelectorParam(selector).
		ResourceTypeOrNameArgs(all, resources...).
		Flatten().
		Latest()

	one := false
	r := b.Do().IntoSingular(&one)
	if err := r.Err(); err != nil {
		return err
	}
	// only apply resource version locking on a single resource
	if !one && len(resourceVersion) > 0 {
		return cmdutil.UsageError(cmd, "--resource-version may only be used with a single resource")
	}

	// TODO: support bulk generic output a la Get
	return r.Visit(func(info *resource.Info) error {
		obj, err := updateObject(info, func(obj runtime.Object) (runtime.Object, error) {
			outObj, err := labelFunc(obj, overwrite, resourceVersion, labels, remove)
			if err != nil {
				return nil, err
			}
			return outObj, nil
		})
		if err != nil {
			return err
		}

		printer, err := f.PrinterForMapping(cmd, info.Mapping, false)
		if err != nil {
			return err
		}
		return printer.PrintObj(obj, out)
	})
}