// Resolve attemps to read the template file and transform it into a template object func (r *TemplateFileResolver) Resolve(value string) (*ComponentMatch, error) { var isSingular bool obj, err := resource.NewBuilder(r.Mapper, r.Typer, r.ClientMapper). NamespaceParam(r.Namespace).RequireNamespace(). FilenameParam(false, value). Do(). IntoSingular(&isSingular). Object() if err != nil { return nil, err } if !isSingular { return nil, fmt.Errorf("there is more than one object in %q", value) } template, ok := obj.(*templateapi.Template) if !ok { return nil, fmt.Errorf("object in %q is not a template", value) } return &ComponentMatch{ Value: value, Argument: fmt.Sprintf("--file=%q", value), Name: value, Description: fmt.Sprintf("Template file %s", value), Score: 0, Template: template, }, nil }
func (o AddSecretOptions) AddSecrets() error { r := resource.NewBuilder(o.Mapper, o.Typer, o.ClientMapper). NamespaceParam(o.Namespace). ResourceTypeOrNameArgs(false, o.TargetName). SingleResourceType(). Do() if r.Err() != nil { return r.Err() } obj, err := r.Object() if err != nil { return err } switch t := obj.(type) { case *api.ServiceAccount: switch o.Type { case PullType: _, err := o.AddSecretsToSAPullSecrets(t) return err case MountType: _, err := o.AddSecretsToSAMountableSecrets(t) return err default: return fmt.Errorf("%v is not handled for ServiceAccounts", o.Type) } default: return fmt.Errorf("unhandled object: %#v", t) } return nil }
// Complete turns a partially defined RollbackActions into a solvent structure // which can be validated and used for a rollback. func (o *RollbackOptions) Complete(f *clientcmd.Factory, args []string, out io.Writer) error { // Extract basic flags. if len(args) == 1 { o.TargetName = args[0] } namespace, _, err := f.DefaultNamespace() if err != nil { return err } o.Namespace = namespace // Set up client based support. mapper, typer := f.Object() o.getBuilder = func() *resource.Builder { return resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()) } oClient, kClient, err := f.Clients() if err != nil { return err } o.oc = oClient o.kc = kClient o.out = out return nil }
func RunUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error { schema, err := f.Validator() if err != nil { return err } cmdNamespace, err := f.DefaultNamespace() if err != nil { return err } patch := cmdutil.GetFlagString(cmd, "patch") if len(filenames) == 0 && len(patch) == 0 { return cmdutil.UsageError(cmd, "Must specify --filename or --patch to update") } if len(filenames) != 0 && len(patch) != 0 { return cmdutil.UsageError(cmd, "Can not specify both --filename and --patch") } // TODO: Make patching work with -f, updating with patched JSON input files if len(filenames) == 0 { name, err := updateWithPatch(cmd, args, f, patch) if err != nil { return err } fmt.Fprintf(out, "%s\n", name) return nil } if len(filenames) == 0 { return cmdutil.UsageError(cmd, "Must specify --filename to update") } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).RequireNamespace(). FilenameParam(filenames...). Flatten(). Do() err = r.Err() if err != nil { return err } return r.Visit(func(info *resource.Info) error { data, err := info.Mapping.Codec.Encode(info.Object) if err != nil { return err } obj, err := resource.NewHelper(info.Client, info.Mapping).Update(info.Namespace, info.Name, true, data) if err != nil { return err } info.Refresh(obj, true) printObjectSpecificMessage(obj, out) fmt.Fprintf(out, "%s/%s\n", info.Mapping.Resource, info.Name) return nil }) }
func (f *Factory) NewCmdDelete(out io.Writer) *cobra.Command { flags := &struct { Filenames util.StringList }{} cmd := &cobra.Command{ Use: "delete ([-f filename] | (<resource> [(<id> | -l <label>)]", Short: "Delete a resource by filename, stdin or resource and id", Long: `Delete a resource by filename, stdin, resource and id or by resources and label selector. JSON and YAML formats are accepted. If both a filename and command line arguments are passed, the command line arguments are used and the filename is ignored. Note that the delete command does NOT do resource version checks, so if someone submits an update to a resource right when you submit a delete, their update will be lost along with the rest of the resource. Examples: $ kubectl delete -f pod.json <delete a pod using the type and id pod.json> $ cat pod.json | kubectl delete -f - <delete a pod based on the type and id in the json passed into stdin> $ kubectl delete pods,services -l name=myLabel <delete pods and services with label name=myLabel> $ kubectl delete pod 1234-56-7890-234234-456456 <delete a pod with ID 1234-56-7890-234234-456456>`, Run: func(cmd *cobra.Command, args []string) { mapper, typer := f.Object(cmd) r := resource.NewBuilder(mapper, typer, ClientMapperForCommand(cmd, f)). ContinueOnError(). NamespaceParam(GetKubeNamespace(cmd)).DefaultNamespace(). FilenameParam(flags.Filenames...). SelectorParam(GetFlagString(cmd, "selector")). ResourceTypeOrNameArgs(args...). Flatten(). Do() found := 0 err := r.IgnoreErrors(errors.IsNotFound).Visit(func(r *resource.Info) error { found++ if err := resource.NewHelper(r.Client, r.Mapping).Delete(r.Namespace, r.Name); err != nil { return err } fmt.Fprintf(out, "%s\n", r.Name) return nil }) checkErr(err) if found == 0 { fmt.Fprintf(cmd.Out(), "No resources found\n") } }, } cmd.Flags().VarP(&flags.Filenames, "filename", "f", "Filename, directory, or URL to a file containing the resource to delete") cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on") return cmd }
func DescribeMatchingResources(mapper meta.RESTMapper, typer runtime.ObjectTyper, describer kubectl.Describer, f *cmdutil.Factory, namespace, rsrc, prefix string, out io.Writer, originalError error) error { r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). NamespaceParam(namespace).DefaultNamespace(). ResourceTypeOrNameArgs(true, rsrc). SingleResourceType(). Flatten(). Do() infos, err := r.Infos() if err != nil { return err } isFound := false for ix := range infos { info := infos[ix] if strings.HasPrefix(info.Name, prefix) { isFound = true s, err := describer.Describe(info.Namespace, info.Name) if err != nil { return err } fmt.Fprintf(out, "%s\n", s) } } if !isFound { return originalError } return nil }
func RunDelete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error { cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, filenames...). SelectorParam(cmdutil.GetFlagString(cmd, "selector")). SelectAllParam(cmdutil.GetFlagBool(cmd, "all")). ResourceTypeOrNameArgs(false, args...).RequireObject(false). Flatten(). Do() err = r.Err() if err != nil { return err } ignoreNotFound := cmdutil.GetFlagBool(cmd, "ignore-not-found") // By default use a reaper to delete all related resources. if cmdutil.GetFlagBool(cmd, "cascade") { return ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), ignoreNotFound, cmdutil.GetFlagDuration(cmd, "timeout"), cmdutil.GetFlagInt(cmd, "grace-period")) } return DeleteResult(r, out, ignoreNotFound) }
func (o AddSecretOptions) getSecrets() ([]*kapi.Secret, error) { r := resource.NewBuilder(o.Mapper, o.Typer, o.ClientMapper). NamespaceParam(o.Namespace). ResourceTypeOrNameArgs(false, o.SecretNames...). SingleResourceType(). Do() if r.Err() != nil { return nil, r.Err() } infos, err := r.Infos() if err != nil { return nil, err } secrets := []*kapi.Secret{} for i := range infos { info := infos[i] switch t := info.Object.(type) { case *kapi.Secret: secrets = append(secrets, t) default: return nil, fmt.Errorf("unhandled object: %#v", t) } } return secrets, nil }
func (o AddSecretOptions) AddSecrets() error { r := resource.NewBuilder(o.Mapper, o.Typer, o.ClientMapper). NamespaceParam(o.Namespace). ResourceTypeOrNameArgs(false, o.TargetName). SingleResourceType(). Do() if r.Err() != nil { return r.Err() } obj, err := r.Object() if err != nil { return err } switch t := obj.(type) { case *kapi.ServiceAccount: err = o.addSecretsToServiceAccount(t) if err != nil { return err } default: return fmt.Errorf("unhandled object: %#v", t) } return nil }
func (f *Factory) NewCmdCreate(out io.Writer) *cobra.Command { flags := &struct { Filenames util.StringList }{} cmd := &cobra.Command{ Use: "create -f filename", Short: "Create a resource by filename or stdin", Long: `Create a resource by filename or stdin. JSON and YAML formats are accepted. Examples: $ kubectl create -f pod.json <create a pod using the data in pod.json> $ cat pod.json | kubectl create -f - <create a pod based on the json passed into stdin>`, Run: func(cmd *cobra.Command, args []string) { schema, err := f.Validator(cmd) checkErr(err) cmdNamespace, err := f.DefaultNamespace(cmd) checkErr(err) mapper, typer := f.Object(cmd) r := resource.NewBuilder(mapper, typer, ClientMapperForCommand(cmd, f)). ContinueOnError(). NamespaceParam(cmdNamespace).RequireNamespace(). FilenameParam(flags.Filenames...). Flatten(). Do() count := 0 err = r.Visit(func(info *resource.Info) error { data, err := info.Mapping.Codec.Encode(info.Object) if err != nil { return err } if err := schema.ValidateBytes(data); err != nil { return err } if err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, data); err != nil { return err } count++ // TODO: if generation of names added to server side, change this to use the server's name fmt.Fprintf(out, "%s\n", info.Name) return nil }) checkErr(err) if count == 0 { checkErr(fmt.Errorf("no objects passed to create")) } }, } cmd.Flags().VarP(&flags.Filenames, "filename", "f", "Filename, directory, or URL to file to use to create the resource") return cmd }
// RunScale executes the scaling func RunScale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, shortOutput bool) error { if len(os.Args) > 1 && os.Args[1] == "resize" { printDeprecationWarning("scale", "resize") } count := cmdutil.GetFlagInt(cmd, "replicas") if count < 0 { return cmdutil.UsageError(cmd, "--replicas=COUNT RESOURCE NAME") } cmdNamespace, _, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return err } mapping, err := r.ResourceMapping() if err != nil { return err } infos, err := r.Infos() if err != nil { return err } if len(infos) > 1 { return fmt.Errorf("multiple resources provided: %v", args) } info := infos[0] scaler, err := f.Scaler(mapping) if err != nil { return err } resourceVersion := cmdutil.GetFlagString(cmd, "resource-version") currentSize := cmdutil.GetFlagInt(cmd, "current-replicas") precondition := &kubectl.ScalePrecondition{currentSize, resourceVersion} retry := kubectl.NewRetryParams(kubectl.Interval, kubectl.Timeout) waitForReplicas := kubectl.NewRetryParams(kubectl.Interval, kubectl.Timeout) if err := scaler.Scale(info.Namespace, info.Name, uint(count), precondition, retry, waitForReplicas); err != nil { return err } cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "scaled") return nil }
func RunResize(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { count := cmdutil.GetFlagInt(cmd, "replicas") if len(args) != 2 || count < 0 { return cmdutil.UsageError(cmd, "--replicas=COUNT RESOURCE ID") } cmdNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return err } mapping, err := r.ResourceMapping() if err != nil { return err } infos, err := r.Infos() if err != nil { return err } info := infos[0] resizer, err := f.Resizer(mapping) if err != nil { return err } resourceVersion := cmdutil.GetFlagString(cmd, "resource-version") currentSize := cmdutil.GetFlagInt(cmd, "current-replicas") precondition := &kubectl.ResizePrecondition{currentSize, resourceVersion} cond := kubectl.ResizeCondition(resizer, precondition, info.Namespace, info.Name, uint(count)) msg := "resized" if err = wait.Poll(retryFrequency, retryTimeout, cond); err != nil { msg = fmt.Sprintf("Failed to resize controller in spite of retrying for %s", retryTimeout) if err != nil { return err } } fmt.Fprintf(out, "%s\n", msg) return nil }
func RunClusterInfo(factory *cmdutil.Factory, out io.Writer, cmd *cobra.Command) error { if os.Args[1] == "clusterinfo" { printDeprecationWarning("cluster-info", "clusterinfo") } client, err := factory.ClientConfig() if err != nil { return err } printService(out, "Kubernetes master", client.Host) mapper, typer := factory.Object() cmdNamespace := cmdutil.GetFlagString(cmd, "namespace") if cmdNamespace == "" { cmdNamespace = api.NamespaceSystem } // TODO use generalized labels once they are implemented (#341) b := resource.NewBuilder(mapper, typer, factory.ClientMapperForCommand()). NamespaceParam(cmdNamespace).DefaultNamespace(). SelectorParam("kubernetes.io/cluster-service=true"). ResourceTypeOrNameArgs(false, []string{"services"}...). Latest() b.Do().Visit(func(r *resource.Info) error { services := r.Object.(*api.ServiceList).Items for _, service := range services { var link string if len(service.Status.LoadBalancer.Ingress) > 0 { ingress := service.Status.LoadBalancer.Ingress[0] ip := ingress.IP if ip == "" { ip = ingress.Hostname } for _, port := range service.Spec.Ports { link += "http://" + ip + ":" + strconv.Itoa(port.Port) + " " } } else { link = client.Host + "/api/" + client.Version + "/proxy/namespaces/" + service.ObjectMeta.Namespace + "/services/" + service.ObjectMeta.Name } name := service.ObjectMeta.Labels["kubernetes.io/name"] if len(name) == 0 { name = service.ObjectMeta.Name } printService(out, name, link) } return nil }) return nil // TODO consider printing more information about cluster }
func RunDescribe(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { selector := cmdutil.GetFlagString(cmd, "selector") cmdNamespace, _, err := f.DefaultNamespace() if err != nil { return err } if len(args) == 0 { fmt.Fprint(out, "You must specify the type of resource to describe. ", valid_resources) return cmdutil.UsageError(cmd, "Required resource not specified.") } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). SelectorParam(selector). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return err } mapping, err := r.ResourceMapping() if err != nil { return err } describer, err := f.Describer(mapping) if err != nil { return err } infos, err := r.Infos() if err != nil { if apierrors.IsNotFound(err) && len(args) == 2 { return DescribeMatchingResources(mapper, typer, describer, f, cmdNamespace, args[0], args[1], out, err) } return err } for _, info := range infos { s, err := describer.Describe(info.Namespace, info.Name) if err != nil { return err } fmt.Fprintf(out, "%s\n\n", s) } return nil }
func updateWithPatch(cmd *cobra.Command, args []string, f *cmdutil.Factory, patch string) (string, error) { cmdNamespace, err := f.DefaultNamespace() if err != nil { return "", err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return "", err } mapping, err := r.ResourceMapping() if err != nil { return "", err } client, err := f.RESTClient(mapping) if err != nil { return "", err } infos, err := r.Infos() if err != nil { return "", err } name, namespace := infos[0].Name, infos[0].Namespace helper := resource.NewHelper(client, mapping) obj, err := helper.Get(namespace, name) if err != nil { return "", err } patchedObj, err := cmdutil.Merge(obj, patch, mapping.Kind) if err != nil { return "", err } data, err := helper.Codec.Encode(patchedObj) if err != nil { return "", err } _, err = helper.Update(namespace, name, true, data) return name, err }
func RunReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error { if os.Args[1] == "update" { printDeprecationWarning("replace", "update") } schema, err := f.Validator() if err != nil { return err } cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } force := cmdutil.GetFlagBool(cmd, "force") if len(filenames) == 0 { return cmdutil.UsageError(cmd, "Must specify --filename to replace") } if force { return forceReplace(f, out, cmd, args, filenames) } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, filenames...). Flatten(). Do() err = r.Err() if err != nil { return err } return r.Visit(func(info *resource.Info) error { data, err := info.Mapping.Codec.Encode(info.Object) if err != nil { return cmdutil.AddSourceToErr("replacing", info.Source, err) } obj, err := resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, true, data) if err != nil { return cmdutil.AddSourceToErr("replacing", info.Source, err) } info.Refresh(obj, true) printObjectSpecificMessage(obj, out) fmt.Fprintf(out, "%s/%s\n", info.Mapping.Resource, info.Name) return nil }) }
func RunCreate(f *cmdutil.Factory, out io.Writer, filenames util.StringList, shortOutput bool) error { schema, err := f.Validator() if err != nil { return err } cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, filenames...). Flatten(). Do() err = r.Err() if err != nil { return err } count := 0 err = r.Visit(func(info *resource.Info) error { data, err := info.Mapping.Codec.Encode(info.Object) if err != nil { return cmdutil.AddSourceToErr("creating", info.Source, err) } obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, data) if err != nil { return cmdutil.AddSourceToErr("creating", info.Source, err) } count++ info.Refresh(obj, true) if !shortOutput { printObjectSpecificMessage(info.Object, out) } cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "created") return nil }) if err != nil { return err } if count == 0 { return fmt.Errorf("no objects passed to create") } return nil }
func (n *NodeOptions) GetNodes() ([]*kapi.Node, error) { nameArgs := []string{"nodes"} if len(n.NodeNames) != 0 { nameArgs = append(nameArgs, n.NodeNames...) } r := resource.NewBuilder(n.Mapper, n.Typer, resource.ClientMapperFunc(n.RESTClientFactory)). ContinueOnError(). NamespaceParam(n.DefaultNamespace). SelectorParam(n.Selector). ResourceTypeOrNameArgs(true, nameArgs...). Flatten(). Do() if r.Err() != nil { return nil, r.Err() } errList := []error{} nodeList := []*kapi.Node{} _ = r.Visit(func(info *resource.Info) error { node, ok := info.Object.(*kapi.Node) if !ok { err := fmt.Errorf("cannot convert input to Node: ", reflect.TypeOf(info.Object)) errList = append(errList, err) // Don't bail out if one node fails return nil } nodeList = append(nodeList, node) return nil }) if len(errList) != 0 { return nodeList, kerrors.NewAggregate(errList) } if len(nodeList) == 0 { return nodeList, fmt.Errorf("No nodes found") } else { givenNodeNames := util.NewStringSet(n.NodeNames...) foundNodeNames := util.StringSet{} for _, node := range nodeList { foundNodeNames.Insert(node.ObjectMeta.Name) } skippedNodeNames := givenNodeNames.Difference(foundNodeNames) if skippedNodeNames.Len() > 0 { return nodeList, fmt.Errorf("Nodes %v not found", strings.Join(skippedNodeNames.List(), ", ")) } } return nodeList, nil }
func RunCreate(f *cmdutil.Factory, out io.Writer, filenames util.StringList) error { schema, err := f.Validator() if err != nil { return err } cmdNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).RequireNamespace(). FilenameParam(filenames...). Flatten(). Do() err = r.Err() if err != nil { return err } count := 0 err = r.Visit(func(info *resource.Info) error { data, err := info.Mapping.Codec.Encode(info.Object) if err != nil { return err } if err := schema.ValidateBytes(data); err != nil { return err } obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, data) if err != nil { return err } count++ info.Refresh(obj, true) fmt.Fprintf(out, "%s/%s\n", info.Mapping.Resource, info.Name) return nil }) if err != nil { return err } if count == 0 { return fmt.Errorf("no objects passed to create") } return nil }
func RunDescribe(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { cmdNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return err } mapping, err := r.ResourceMapping() if err != nil { return err } describer, err := f.Describer(mapping) if err != nil { return err } infos, err := r.Infos() if err != nil { if errors.IsNotFound(err) && len(args) == 2 { return DescribeMatchingResources(mapper, typer, describer, f, cmdNamespace, args[0], args[1], out) } return err } if len(infos) > 1 { return fmt.Errorf("multiple resources provided: %v", args) } info := infos[0] s, err := describer.Describe(info.Namespace, info.Name) if err != nil { return err } fmt.Fprintf(out, "%s\n", s) return nil }
func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, shortOutput bool) error { cmdNamespace, _, err := f.DefaultNamespace() if err != nil { return err } patch := cmdutil.GetFlagString(cmd, "patch") if len(patch) == 0 { return cmdutil.UsageError(cmd, "Must specify -p to patch") } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return err } mapping, err := r.ResourceMapping() if err != nil { return err } client, err := f.RESTClient(mapping) if err != nil { return err } infos, err := r.Infos() if err != nil { return err } name, namespace := infos[0].Name, infos[0].Namespace helper := resource.NewHelper(client, mapping) _, err = helper.Patch(namespace, name, api.StrategicMergePatchType, []byte(patch)) if err != nil { return err } cmdutil.PrintSuccess(mapper, shortOutput, out, "", name, "patched") return nil }
func RunStop(f *cmdutil.Factory, cmd *cobra.Command, args []string, filenames util.StringList, out io.Writer) error { cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceTypeOrNameArgs(false, args...). FilenameParam(enforceNamespace, filenames...). SelectorParam(cmdutil.GetFlagString(cmd, "selector")). SelectAllParam(cmdutil.GetFlagBool(cmd, "all")). Flatten(). Do() if r.Err() != nil { return r.Err() } return ReapResult(r, f, out, false, cmdutil.GetFlagBool(cmd, "ignore-not-found"), cmdutil.GetFlagDuration(cmd, "timeout"), cmdutil.GetFlagInt(cmd, "grace-period")) }
func (f *Factory) NewCmdStop(out io.Writer) *cobra.Command { flags := &struct { Filenames util.StringList }{} cmd := &cobra.Command{ Use: "stop (-f FILENAME | RESOURCE (ID | -l label | --all))", Short: "Gracefully shut down a resource by id or filename.", Long: stop_long, Example: stop_example, Run: func(cmd *cobra.Command, args []string) { cmdNamespace, err := f.DefaultNamespace() cmdutil.CheckErr(err) mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand(cmd)). ContinueOnError(). NamespaceParam(cmdNamespace).RequireNamespace(). ResourceTypeOrNameArgs(false, args...). FilenameParam(flags.Filenames...). SelectorParam(cmdutil.GetFlagString(cmd, "selector")). SelectAllParam(cmdutil.GetFlagBool(cmd, "all")). Flatten(). Do() cmdutil.CheckErr(r.Err()) r.Visit(func(info *resource.Info) error { reaper, err := f.Reaper(info.Mapping) cmdutil.CheckErr(err) s, err := reaper.Stop(info.Namespace, info.Name) if err != nil { return err } fmt.Fprintf(out, "%s\n", s) return nil }) }, } cmd.Flags().VarP(&flags.Filenames, "filename", "f", "Filename, directory, or URL to file of resource(s) to be stopped") cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on") cmd.Flags().Bool("all", false, "[-all] to select all the specified resources") return cmd }
func RunClusterInfo(factory *cmdutil.Factory, out io.Writer, cmd *cobra.Command) error { if os.Args[1] == "clusterinfo" { printDeprecationWarning("cluster-info", "clusterinfo") } client, err := factory.ClientConfig() if err != nil { return err } printService(out, "Kubernetes master", client.Host, false) mapper, typer := factory.Object() cmdNamespace, err := factory.DefaultNamespace() if err != nil { return err } // TODO use generalized labels once they are implemented (#341) b := resource.NewBuilder(mapper, typer, factory.ClientMapperForCommand()). NamespaceParam(cmdNamespace).DefaultNamespace(). SelectorParam("kubernetes.io/cluster-service=true"). ResourceTypeOrNameArgs(false, []string{"services"}...). Latest() b.Do().Visit(func(r *resource.Info) error { services := r.Object.(*api.ServiceList).Items for _, service := range services { splittedLink := strings.Split(strings.Split(service.ObjectMeta.SelfLink, "?")[0], "/") // insert "proxy" into the link splittedLink = append(splittedLink, "") copy(splittedLink[4:], splittedLink[3:]) splittedLink[3] = "proxy" link := client.Host + strings.Join(splittedLink, "/") + "/" printService(out, service.ObjectMeta.Labels["name"], link, true) } return nil }) return nil // TODO consider printing more information about cluster }
func RunDelete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList, shortOutput bool) error { cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } deleteAll := cmdutil.GetFlagBool(cmd, "all") mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, filenames...). SelectorParam(cmdutil.GetFlagString(cmd, "selector")). SelectAllParam(deleteAll). ResourceTypeOrNameArgs(false, args...).RequireObject(false). Flatten(). Do() err = r.Err() if err != nil { return err } ignoreNotFound := cmdutil.GetFlagBool(cmd, "ignore-not-found") if deleteAll { f := cmd.Flags().Lookup("ignore-not-found") // The flag should never be missing if f == nil { return fmt.Errorf("missing --ignore-not-found flag") } // If the user didn't explicitly set the option, default to ignoring NotFound errors when used with --all if !f.Changed { ignoreNotFound = true } } // By default use a reaper to delete all related resources. if cmdutil.GetFlagBool(cmd, "cascade") { return ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), ignoreNotFound, cmdutil.GetFlagDuration(cmd, "timeout"), cmdutil.GetFlagInt(cmd, "grace-period"), shortOutput, mapper) } return DeleteResult(r, out, ignoreNotFound, shortOutput, mapper) }
func RunDescribe(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { cmdNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return err } mapping, err := r.ResourceMapping() if err != nil { return err } describer, err := f.Describer(mapping) if err != nil { return err } infos, err := r.Infos() if err != nil { return err } info := infos[0] s, err := describer.Describe(info.Namespace, info.Name) if err != nil { return err } fmt.Fprintf(out, "%s\n", s) return nil }
func BuildGraph(path string) (osgraph.Graph, []runtime.Object, error) { g := osgraph.New() objs := []runtime.Object{} abspath, err := filepath.Abs(path) if err != nil { return g, objs, err } mapper := latest.RESTMapper typer := kapi.Scheme clientMapper := resource.ClientMapperFunc(func(mapping *meta.RESTMapping) (resource.RESTClient, error) { return nil, nil }) r := resource.NewBuilder(mapper, typer, clientMapper). FilenameParam(abspath). Flatten(). Do() if r.Err() != nil { return g, objs, r.Err() } infos, err := r.Infos() if err != nil { return g, objs, err } for _, info := range infos { objs = append(objs, info.Object) if err := EnsureNode(g, info.Object); err != nil { return g, objs, err } } return g, objs, nil }
// Search attemps to read template files and transform it into template objects func (r *TemplateFileSearcher) Search(terms ...string) (ComponentMatches, error) { matches := ComponentMatches{} for _, term := range terms { var isSingular bool obj, err := resource.NewBuilder(r.Mapper, r.Typer, r.ClientMapper). NamespaceParam(r.Namespace).RequireNamespace(). FilenameParam(false, term). Do(). IntoSingular(&isSingular). Object() if err != nil { return nil, err } if !isSingular { return nil, fmt.Errorf("there is more than one object in %q", term) } template, ok := obj.(*templateapi.Template) if !ok { return nil, fmt.Errorf("object in %q is not a template", term) } matches = append(matches, &ComponentMatch{ Value: term, Argument: fmt.Sprintf("--file=%q", template.Name), Name: template.Name, Description: fmt.Sprintf("Template file %s", term), Score: 0, Template: template, }) } return matches, nil }
func RunDelete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error { cmdNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(filenames...). SelectorParam(cmdutil.GetFlagString(cmd, "selector")). SelectAllParam(cmdutil.GetFlagBool(cmd, "all")). ResourceTypeOrNameArgs(false, args...).RequireObject(false). Flatten(). Do() err = r.Err() if err != nil { return err } found := 0 err = r.IgnoreErrors(errors.IsNotFound).Visit(func(r *resource.Info) error { found++ if err := resource.NewHelper(r.Client, r.Mapping).Delete(r.Namespace, r.Name); err != nil { return err } fmt.Fprintf(out, "%s/%s\n", r.Mapping.Resource, r.Name) return nil }) if err != nil { return err } if found == 0 { fmt.Fprintf(cmd.Out(), "No resources found\n") } return nil }
func updateWithPatch(cmd *cobra.Command, args []string, f *cmdutil.Factory, patch string) (string, error) { cmdNamespace, err := f.DefaultNamespace() if err != nil { return "", err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return "", err } mapping, err := r.ResourceMapping() if err != nil { return "", err } client, err := f.RESTClient(mapping) if err != nil { return "", err } infos, err := r.Infos() if err != nil { return "", err } name, namespace := infos[0].Name, infos[0].Namespace helper := resource.NewHelper(client, mapping) _, err = helper.Patch(namespace, name, api.StrategicMergePatchType, []byte(patch)) return name, err }