diff --git a/federation/apis/core/install/install.go b/federation/apis/core/install/install.go index b93f383ca65..1cd5e0a451a 100644 --- a/federation/apis/core/install/install.go +++ b/federation/apis/core/install/install.go @@ -83,9 +83,6 @@ func enableVersions(externalVersions []schema.GroupVersion) error { return nil } -// userResources is a group of resources mostly used by a kubectl user -var userResources = []string{"svc"} - func newRESTMapper(externalVersions []schema.GroupVersion) meta.RESTMapper { // the list of kinds that are scoped at the root of the api hierarchy // if a kind is not enumerated here, it is assumed to have a namespace scope @@ -100,8 +97,6 @@ func newRESTMapper(externalVersions []schema.GroupVersion) meta.RESTMapper { "Status") mapper := meta.NewDefaultRESTMapperFromScheme(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped, core.Scheme) - // setup aliases for groups of resources - mapper.AddResourceAlias("all", userResources...) return mapper } diff --git a/pkg/kubectl/cmd/annotate.go b/pkg/kubectl/cmd/annotate.go index bf71e61e7c7..c1082bb23e0 100644 --- a/pkg/kubectl/cmd/annotate.go +++ b/pkg/kubectl/cmd/annotate.go @@ -190,7 +190,7 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro if err != nil { return err } - b := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + b := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). diff --git a/pkg/kubectl/cmd/apply.go b/pkg/kubectl/cmd/apply.go index c24f7d9d135..e0cb45759c1 100644 --- a/pkg/kubectl/cmd/apply.go +++ b/pkg/kubectl/cmd/apply.go @@ -205,7 +205,7 @@ func RunApply(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opti } } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). diff --git a/pkg/kubectl/cmd/apply_set_last_applied.go b/pkg/kubectl/cmd/apply_set_last_applied.go index 3ff1972c0fe..51cf2d98046 100644 --- a/pkg/kubectl/cmd/apply_set_last_applied.go +++ b/pkg/kubectl/cmd/apply_set_last_applied.go @@ -120,7 +120,7 @@ func (o *SetLastAppliedOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) } func (o *SetLastAppliedOptions) Validate(f cmdutil.Factory, cmd *cobra.Command) error { - r := resource.NewBuilder(o.Mapper, o.Typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + r := resource.NewBuilder(o.Mapper, f.CategoryExpander(), o.Typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). NamespaceParam(o.Namespace).DefaultNamespace(). FilenameParam(o.EnforceNamespace, &o.FilenameOptions). Latest(). diff --git a/pkg/kubectl/cmd/apply_view_last_applied.go b/pkg/kubectl/cmd/apply_view_last_applied.go index f763d0034c8..e6546405456 100644 --- a/pkg/kubectl/cmd/apply_view_last_applied.go +++ b/pkg/kubectl/cmd/apply_view_last_applied.go @@ -90,7 +90,7 @@ func (o *ViewLastAppliedOptions) Complete(f cmdutil.Factory, args []string) erro return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). ResourceTypeOrNameArgs(enforceNamespace, args...). diff --git a/pkg/kubectl/cmd/attach.go b/pkg/kubectl/cmd/attach.go index 0c9f181be87..9c3e9d7de6b 100644 --- a/pkg/kubectl/cmd/attach.go +++ b/pkg/kubectl/cmd/attach.go @@ -134,7 +134,7 @@ func (p *AttachOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, argsIn [ } mapper, typer := f.Object() - builder := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + builder := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). NamespaceParam(namespace).DefaultNamespace() switch len(argsIn) { diff --git a/pkg/kubectl/cmd/autoscale.go b/pkg/kubectl/cmd/autoscale.go index 0c1a796bb34..d570fde0e75 100644 --- a/pkg/kubectl/cmd/autoscale.go +++ b/pkg/kubectl/cmd/autoscale.go @@ -91,7 +91,7 @@ func RunAutoscale(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s } mapper, typer := f.Object() - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). diff --git a/pkg/kubectl/cmd/certificates.go b/pkg/kubectl/cmd/certificates.go index 7aff19b791a..6ae7f66897a 100644 --- a/pkg/kubectl/cmd/certificates.go +++ b/pkg/kubectl/cmd/certificates.go @@ -167,7 +167,7 @@ func (options *CertificateOptions) modifyCertificateCondition(f cmdutil.Factory, if err != nil { return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). ContinueOnError(). FilenameParam(false, &options.FilenameOptions). ResourceNames("certificatesigningrequest", options.csrNames...). diff --git a/pkg/kubectl/cmd/clusterinfo.go b/pkg/kubectl/cmd/clusterinfo.go index 5e2b6f90b49..aef2b517c5f 100644 --- a/pkg/kubectl/cmd/clusterinfo.go +++ b/pkg/kubectl/cmd/clusterinfo.go @@ -79,7 +79,7 @@ func RunClusterInfo(f cmdutil.Factory, out io.Writer, cmd *cobra.Command) error } // TODO use generalized labels once they are implemented (#341) - b := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + b := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). NamespaceParam(cmdNamespace).DefaultNamespace(). SelectorParam("kubernetes.io/cluster-service=true"). ResourceTypeOrNameArgs(false, []string{"services"}...). diff --git a/pkg/kubectl/cmd/convert.go b/pkg/kubectl/cmd/convert.go index a4697d7d0dd..c5f5ea7cd05 100644 --- a/pkg/kubectl/cmd/convert.go +++ b/pkg/kubectl/cmd/convert.go @@ -132,9 +132,9 @@ func (o *ConvertOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.C if o.local { fmt.Fprintln(os.Stderr, "running in local mode...") - o.builder = resource.NewBuilder(mapper, typer, resource.DisabledClientForMapping{ClientMapper: clientMapper}, f.Decoder(true)) + o.builder = resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.DisabledClientForMapping{ClientMapper: clientMapper}, f.Decoder(true)) } else { - o.builder = resource.NewBuilder(mapper, typer, clientMapper, f.Decoder(true)) + o.builder = resource.NewBuilder(mapper, f.CategoryExpander(), typer, clientMapper, f.Decoder(true)) schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"), cmdutil.GetFlagString(cmd, "schema-cache-dir")) if err != nil { return err diff --git a/pkg/kubectl/cmd/create.go b/pkg/kubectl/cmd/create.go index e4da50b9468..c7fe72001f2 100644 --- a/pkg/kubectl/cmd/create.go +++ b/pkg/kubectl/cmd/create.go @@ -128,7 +128,7 @@ func RunCreate(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opt if err != nil { return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). diff --git a/pkg/kubectl/cmd/delete.go b/pkg/kubectl/cmd/delete.go index 908a1304378..3507d85c6a6 100644 --- a/pkg/kubectl/cmd/delete.go +++ b/pkg/kubectl/cmd/delete.go @@ -175,7 +175,7 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args return err } o.Mapper = mapper - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). diff --git a/pkg/kubectl/cmd/describe.go b/pkg/kubectl/cmd/describe.go index c71bda26bb8..a56f955a9e6 100644 --- a/pkg/kubectl/cmd/describe.go +++ b/pkg/kubectl/cmd/describe.go @@ -121,7 +121,7 @@ func RunDescribe(f cmdutil.Factory, out, cmdErr io.Writer, cmd *cobra.Command, a if err != nil { return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces). FilenameParam(enforceNamespace, options). @@ -181,7 +181,7 @@ func DescribeMatchingResources(mapper meta.RESTMapper, typer runtime.ObjectTyper if err != nil { return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). NamespaceParam(namespace).DefaultNamespace(). ResourceTypeOrNameArgs(true, rsrc). SingleResourceType(). diff --git a/pkg/kubectl/cmd/edit.go b/pkg/kubectl/cmd/edit.go index b28ce0216e0..105f562d11c 100644 --- a/pkg/kubectl/cmd/edit.go +++ b/pkg/kubectl/cmd/edit.go @@ -385,7 +385,7 @@ func getMapperAndResult(f cmdutil.Factory, args []string, options *resource.File return nil, nil, nil, "", err } - b := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme) + b := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme) if editMode == NormalEditMode { // if in normal mode, also read from args, and fetch latest from the server b = b.ResourceTypeOrNameArgs(true, args...).Latest() @@ -403,7 +403,7 @@ func getMapperAndResult(f cmdutil.Factory, args []string, options *resource.File updatedResultGetter := func(data []byte) *resource.Result { // resource builder to read objects from edited data - return resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + return resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). Stream(bytes.NewReader(data), "edited-file"). ContinueOnError(). Flatten(). diff --git a/pkg/kubectl/cmd/expose.go b/pkg/kubectl/cmd/expose.go index f5690fdea66..aa6cfa3ba10 100644 --- a/pkg/kubectl/cmd/expose.go +++ b/pkg/kubectl/cmd/expose.go @@ -127,7 +127,7 @@ func RunExpose(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri } mapper, typer := f.Object() - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). diff --git a/pkg/kubectl/cmd/get.go b/pkg/kubectl/cmd/get.go index dd8a306aa1f..63dff19e342 100644 --- a/pkg/kubectl/cmd/get.go +++ b/pkg/kubectl/cmd/get.go @@ -193,7 +193,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ // 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, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces). FilenameParam(enforceNamespace, &options.FilenameOptions). SelectorParam(selector). @@ -283,7 +283,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ return nil } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces). FilenameParam(enforceNamespace, &options.FilenameOptions). SelectorParam(selector). diff --git a/pkg/kubectl/cmd/label.go b/pkg/kubectl/cmd/label.go index edae2d88e73..db00de86890 100644 --- a/pkg/kubectl/cmd/label.go +++ b/pkg/kubectl/cmd/label.go @@ -185,7 +185,7 @@ func (o *LabelOptions) RunLabel(f cmdutil.Factory, cmd *cobra.Command) error { if err != nil { return err } - b := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + b := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). diff --git a/pkg/kubectl/cmd/logs.go b/pkg/kubectl/cmd/logs.go index 1c4ac682541..7ebf245df34 100644 --- a/pkg/kubectl/cmd/logs.go +++ b/pkg/kubectl/cmd/logs.go @@ -193,7 +193,7 @@ func (o *LogsOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Comm mapper, typer := f.Object() decoder := f.Decoder(true) if o.Object == nil { - builder := resource.NewBuilder(mapper, typer, o.ClientMapper, decoder). + builder := resource.NewBuilder(mapper, f.CategoryExpander(), typer, o.ClientMapper, decoder). NamespaceParam(o.Namespace).DefaultNamespace(). SingleResourceType() if o.ResourceArg != "" { diff --git a/pkg/kubectl/cmd/patch.go b/pkg/kubectl/cmd/patch.go index 0fab9f32da8..935b64492a3 100644 --- a/pkg/kubectl/cmd/patch.go +++ b/pkg/kubectl/cmd/patch.go @@ -153,7 +153,7 @@ func RunPatch(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin if err != nil { return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &options.FilenameOptions). diff --git a/pkg/kubectl/cmd/replace.go b/pkg/kubectl/cmd/replace.go index c3d737279e3..4e5262dd7fc 100644 --- a/pkg/kubectl/cmd/replace.go +++ b/pkg/kubectl/cmd/replace.go @@ -129,7 +129,7 @@ func RunReplace(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str if err != nil { return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). @@ -200,7 +200,7 @@ func forceReplace(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s if err != nil { return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). @@ -249,7 +249,7 @@ func forceReplace(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s }) }) - r = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + r = resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). diff --git a/pkg/kubectl/cmd/rollingupdate.go b/pkg/kubectl/cmd/rollingupdate.go index 90c21f2dd7f..d3262dab63e 100644 --- a/pkg/kubectl/cmd/rollingupdate.go +++ b/pkg/kubectl/cmd/rollingupdate.go @@ -205,7 +205,7 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args return err } - request := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + request := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). Schema(schema). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &resource.FilenameOptions{Recursive: false, Filenames: []string{filename}}). diff --git a/pkg/kubectl/cmd/rollout/rollout_history.go b/pkg/kubectl/cmd/rollout/rollout_history.go index 7cf7181d67e..7edea7dbbc0 100644 --- a/pkg/kubectl/cmd/rollout/rollout_history.go +++ b/pkg/kubectl/cmd/rollout/rollout_history.go @@ -81,7 +81,7 @@ func RunHistory(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []str return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). ResourceTypeOrNameArgs(true, args...). diff --git a/pkg/kubectl/cmd/rollout/rollout_pause.go b/pkg/kubectl/cmd/rollout/rollout_pause.go index c40fb56ce8c..afe2709558d 100644 --- a/pkg/kubectl/cmd/rollout/rollout_pause.go +++ b/pkg/kubectl/cmd/rollout/rollout_pause.go @@ -111,7 +111,7 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, out i return err } - r := resource.NewBuilder(o.Mapper, o.Typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + r := resource.NewBuilder(o.Mapper, f.CategoryExpander(), o.Typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). ResourceTypeOrNameArgs(true, args...). diff --git a/pkg/kubectl/cmd/rollout/rollout_resume.go b/pkg/kubectl/cmd/rollout/rollout_resume.go index 19641f0772c..d22050532cf 100644 --- a/pkg/kubectl/cmd/rollout/rollout_resume.go +++ b/pkg/kubectl/cmd/rollout/rollout_resume.go @@ -109,7 +109,7 @@ func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, out return err } - r := resource.NewBuilder(o.Mapper, o.Typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + r := resource.NewBuilder(o.Mapper, f.CategoryExpander(), o.Typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). ResourceTypeOrNameArgs(true, args...). diff --git a/pkg/kubectl/cmd/rollout/rollout_status.go b/pkg/kubectl/cmd/rollout/rollout_status.go index a5514c2cfda..cc9abd32e90 100644 --- a/pkg/kubectl/cmd/rollout/rollout_status.go +++ b/pkg/kubectl/cmd/rollout/rollout_status.go @@ -84,7 +84,7 @@ func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []stri return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). ResourceTypeOrNameArgs(true, args...). diff --git a/pkg/kubectl/cmd/rollout/rollout_undo.go b/pkg/kubectl/cmd/rollout/rollout_undo.go index d3f04060280..eb60ea492b9 100644 --- a/pkg/kubectl/cmd/rollout/rollout_undo.go +++ b/pkg/kubectl/cmd/rollout/rollout_undo.go @@ -110,7 +110,7 @@ func (o *UndoOptions) CompleteUndo(f cmdutil.Factory, cmd *cobra.Command, out io return err } - r := resource.NewBuilder(o.Mapper, o.Typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + r := resource.NewBuilder(o.Mapper, f.CategoryExpander(), o.Typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). ResourceTypeOrNameArgs(true, args...). diff --git a/pkg/kubectl/cmd/run.go b/pkg/kubectl/cmd/run.go index 4c7a7609c65..9e16f701090 100644 --- a/pkg/kubectl/cmd/run.go +++ b/pkg/kubectl/cmd/run.go @@ -334,7 +334,7 @@ func Run(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cobr return err } _, typer := f.Object() - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace(). ResourceNames(mapping.Resource, name). diff --git a/pkg/kubectl/cmd/scale.go b/pkg/kubectl/cmd/scale.go index 930233d6002..e5155bf7729 100644 --- a/pkg/kubectl/cmd/scale.go +++ b/pkg/kubectl/cmd/scale.go @@ -106,7 +106,7 @@ func RunScale(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin } mapper, typer := f.Object() - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). diff --git a/pkg/kubectl/cmd/set/set_image.go b/pkg/kubectl/cmd/set/set_image.go index 327652ec293..d5ad2cfcc70 100644 --- a/pkg/kubectl/cmd/set/set_image.go +++ b/pkg/kubectl/cmd/set/set_image.go @@ -136,7 +136,7 @@ func (o *ImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st return err } - builder := resource.NewBuilder(o.Mapper, o.Typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + builder := resource.NewBuilder(o.Mapper, f.CategoryExpander(), o.Typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). diff --git a/pkg/kubectl/cmd/set/set_resources.go b/pkg/kubectl/cmd/set/set_resources.go index 2525a10fc20..14d302bf657 100644 --- a/pkg/kubectl/cmd/set/set_resources.go +++ b/pkg/kubectl/cmd/set/set_resources.go @@ -140,7 +140,7 @@ func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args return err } - builder := resource.NewBuilder(o.Mapper, o.Typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + builder := resource.NewBuilder(o.Mapper, f.CategoryExpander(), o.Typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). //FilenameParam(enforceNamespace, o.Filenames...). diff --git a/pkg/kubectl/cmd/stop.go b/pkg/kubectl/cmd/stop.go index d964b50f304..74bcc4753b3 100644 --- a/pkg/kubectl/cmd/stop.go +++ b/pkg/kubectl/cmd/stop.go @@ -84,7 +84,7 @@ func RunStop(f cmdutil.Factory, cmd *cobra.Command, args []string, out io.Writer } mapper, typer := f.Object() - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + r := resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceTypeOrNameArgs(false, args...). diff --git a/pkg/kubectl/cmd/taint.go b/pkg/kubectl/cmd/taint.go index 4a7507f1f21..211e36f71e6 100644 --- a/pkg/kubectl/cmd/taint.go +++ b/pkg/kubectl/cmd/taint.go @@ -226,7 +226,7 @@ func (o *TaintOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Com } mapper, typer := f.Object() - o.builder = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + o.builder = resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace() if o.all { diff --git a/pkg/kubectl/cmd/testing/fake.go b/pkg/kubectl/cmd/testing/fake.go index 7fee0380c31..bfe0c6e1cff 100644 --- a/pkg/kubectl/cmd/testing/fake.go +++ b/pkg/kubectl/cmd/testing/fake.go @@ -277,6 +277,10 @@ func (f *FakeFactory) UnstructuredObject() (meta.RESTMapper, runtime.ObjectTyper return expander, typer, err } +func (f *FakeFactory) CategoryExpander() resource.CategoryExpander { + return resource.LegacyCategoryExpander +} + func (f *FakeFactory) Decoder(bool) runtime.Decoder { return f.Codec } @@ -689,7 +693,7 @@ func (f *fakeAPIFactory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RES func (f *fakeAPIFactory) NewBuilder() *resource.Builder { mapper, typer := f.Object() - return resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)) + return resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)) } func (f *fakeAPIFactory) SuggestedPodTemplateResources() []schema.GroupResource { diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index 8adc8afab56..d65e5e719ec 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -189,6 +189,8 @@ type ObjectMappingFactory interface { // Returns interfaces for dealing with arbitrary // runtime.Unstructured. This performs API calls to discover types. UnstructuredObject() (meta.RESTMapper, runtime.ObjectTyper, error) + // Returns interface for expanding categories like `all`. + CategoryExpander() resource.CategoryExpander // Returns a RESTClient for working with the specified RESTMapping or an error. This is intended // for working with arbitrary resources and is not guaranteed to point to a Kubernetes APIServer. ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) diff --git a/pkg/kubectl/cmd/util/factory_builder.go b/pkg/kubectl/cmd/util/factory_builder.go index 4667e5bc560..c8fc81b84a5 100644 --- a/pkg/kubectl/cmd/util/factory_builder.go +++ b/pkg/kubectl/cmd/util/factory_builder.go @@ -126,6 +126,7 @@ func (f *ring2Factory) PrintObject(cmd *cobra.Command, mapper meta.RESTMapper, o func (f *ring2Factory) NewBuilder() *resource.Builder { mapper, typer := f.objectMappingFactory.Object() + categoryExpander := f.objectMappingFactory.CategoryExpander() - return resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.objectMappingFactory.ClientForMapping), f.clientAccessFactory.Decoder(true)) + return resource.NewBuilder(mapper, categoryExpander, typer, resource.ClientMapperFunc(f.objectMappingFactory.ClientForMapping), f.clientAccessFactory.Decoder(true)) } diff --git a/pkg/kubectl/cmd/util/factory_object_mapping.go b/pkg/kubectl/cmd/util/factory_object_mapping.go index 57d398ea717..93d2de92266 100644 --- a/pkg/kubectl/cmd/util/factory_object_mapping.go +++ b/pkg/kubectl/cmd/util/factory_object_mapping.go @@ -105,6 +105,20 @@ func (f *ring1Factory) UnstructuredObject() (meta.RESTMapper, runtime.ObjectType return expander, typer, err } +func (f *ring1Factory) CategoryExpander() resource.CategoryExpander { + var categoryExpander resource.CategoryExpander + categoryExpander = resource.LegacyCategoryExpander + discoveryClient, err := f.clientAccessFactory.DiscoveryClient() + if err == nil { + // wrap with discovery based filtering + categoryExpander, err = resource.NewDiscoveryFilteredExpander(categoryExpander, discoveryClient) + // you only have an error on missing discoveryClient, so this shouldn't fail. Check anyway. + CheckErr(err) + } + + return categoryExpander +} + func (f *ring1Factory) ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) { cfg, err := f.clientAccessFactory.ClientConfig() if err != nil { diff --git a/pkg/kubectl/cmd/util/factory_test.go b/pkg/kubectl/cmd/util/factory_test.go index 9d2a3ebc4a4..b7215e4a59d 100644 --- a/pkg/kubectl/cmd/util/factory_test.go +++ b/pkg/kubectl/cmd/util/factory_test.go @@ -740,12 +740,12 @@ func TestDiscoveryReplaceAliases(t *testing.T) { { name: "all-replacement", arg: "all", - expected: "pods,replicationcontrollers,services,statefulsets,horizontalpodautoscalers,jobs,deployments,replicasets", + expected: "pods,replicationcontrollers,services,statefulsets.apps,horizontalpodautoscalers.autoscaling,jobs.batch,deployments.extensions,replicasets.extensions", }, { name: "alias-in-comma-separated-arg", arg: "all,secrets", - expected: "pods,replicationcontrollers,services,statefulsets,horizontalpodautoscalers,jobs,deployments,replicasets,secrets", + expected: "pods,replicationcontrollers,services,statefulsets.apps,horizontalpodautoscalers.autoscaling,jobs.batch,deployments.extensions,replicasets.extensions,secrets", }, } @@ -754,7 +754,7 @@ func TestDiscoveryReplaceAliases(t *testing.T) { if err != nil { t.Fatalf("Unable to create shortcut expander, err = %s", err.Error()) } - b := resource.NewBuilder(mapper, api.Scheme, fakeClient(), testapi.Default.Codec()) + b := resource.NewBuilder(mapper, resource.LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()) for _, test := range tests { replaced := b.ReplaceAliases(test.arg) diff --git a/pkg/kubectl/cmd/util/shortcut_restmapper.go b/pkg/kubectl/cmd/util/shortcut_restmapper.go index a68357c9905..8d71af02ceb 100644 --- a/pkg/kubectl/cmd/util/shortcut_restmapper.go +++ b/pkg/kubectl/cmd/util/shortcut_restmapper.go @@ -21,6 +21,7 @@ import ( "strings" "github.com/golang/glog" + "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/discovery" @@ -31,8 +32,6 @@ import ( type shortcutExpander struct { RESTMapper meta.RESTMapper - All []schema.GroupResource - discoveryClient discovery.DiscoveryInterface } @@ -42,33 +41,7 @@ func NewShortcutExpander(delegate meta.RESTMapper, client discovery.DiscoveryInt if client == nil { return shortcutExpander{}, errors.New("Please provide discovery client to shortcut expander") } - return shortcutExpander{All: UserResources, RESTMapper: delegate, discoveryClient: client}, nil -} - -func (e shortcutExpander) getAll() []schema.GroupResource { - // Check if we have access to server resources - apiResources, err := e.discoveryClient.ServerResources() - if err != nil { - return e.All - } - - availableResources, err := discovery.GroupVersionResources(apiResources) - if err != nil { - return e.All - } - - availableAll := []schema.GroupResource{} - for _, requestedResource := range e.All { - for availableResource := range availableResources { - if requestedResource.Group == availableResource.Group && - requestedResource.Resource == availableResource.Resource { - availableAll = append(availableAll, requestedResource) - break - } - } - } - - return availableAll + return shortcutExpander{RESTMapper: delegate, discoveryClient: client}, nil } func (e shortcutExpander) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { @@ -99,38 +72,6 @@ func (e shortcutExpander) RESTMappings(gk schema.GroupKind, versions ...string) return e.RESTMapper.RESTMappings(gk, versions...) } -// UserResources are the resource names that apply to the primary, user facing resources used by -// client tools. They are in deletion-first order - dependent resources should be last. -// Should remain exported in order to expose a current list of resources to downstream -// composition that wants to build on the concept of 'all' for their CLIs. -var UserResources = []schema.GroupResource{ - {Group: "", Resource: "pods"}, - {Group: "", Resource: "replicationcontrollers"}, - {Group: "", Resource: "services"}, - {Group: "apps", Resource: "statefulsets"}, - {Group: "autoscaling", Resource: "horizontalpodautoscalers"}, - {Group: "batch", Resource: "jobs"}, - {Group: "extensions", Resource: "deployments"}, - {Group: "extensions", Resource: "replicasets"}, -} - -// AliasesForResource returns whether a resource has an alias or not -func (e shortcutExpander) AliasesForResource(resource string) ([]string, bool) { - if strings.ToLower(resource) == "all" { - var resources []schema.GroupResource - if resources = e.getAll(); len(resources) == 0 { - resources = UserResources - } - aliases := []string{} - for _, r := range resources { - aliases = append(aliases, r.Resource) - } - return aliases, true - } - expanded := e.expandResourceShortcut(schema.GroupVersionResource{Resource: resource}).Resource - return []string{expanded}, (expanded != resource) -} - // getShortcutMappings returns a set of tuples which holds short names for resources. // First the list of potential resources will be taken from the API server. // Next we will append the hardcoded list of resources - to be backward compatible with old servers. diff --git a/pkg/kubectl/cmd/util/shortcut_restmapper_test.go b/pkg/kubectl/cmd/util/shortcut_restmapper_test.go index e4bee982c0a..91527abb71a 100644 --- a/pkg/kubectl/cmd/util/shortcut_restmapper_test.go +++ b/pkg/kubectl/cmd/util/shortcut_restmapper_test.go @@ -17,7 +17,6 @@ limitations under the License. package util import ( - "strings" "testing" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -29,43 +28,25 @@ func TestReplaceAliases(t *testing.T) { tests := []struct { name string arg string - expected string + expected schema.GroupVersionResource srvRes []*metav1.APIResourceList }{ - { - name: "no-replacement", - arg: "service", - expected: "service", - srvRes: []*metav1.APIResourceList{}, - }, - { - name: "all-replacement", - arg: "all", - expected: "pods,replicationcontrollers,services,statefulsets,horizontalpodautoscalers,jobs,deployments,replicasets", - srvRes: []*metav1.APIResourceList{}, - }, - { - name: "alias-in-comma-separated-arg", - arg: "all,secrets", - expected: "pods,replicationcontrollers,services,statefulsets,horizontalpodautoscalers,jobs,deployments,replicasets,secrets", - srvRes: []*metav1.APIResourceList{}, - }, { name: "rc-resolves-to-replicationcontrollers", arg: "rc", - expected: "replicationcontrollers", + expected: schema.GroupVersionResource{Resource: "replicationcontrollers"}, srvRes: []*metav1.APIResourceList{}, }, { name: "storageclasses-no-replacement", arg: "storageclasses", - expected: "storageclasses", + expected: schema.GroupVersionResource{Resource: "storageclasses"}, srvRes: []*metav1.APIResourceList{}, }, { name: "hpa-priority", arg: "hpa", - expected: "superhorizontalpodautoscalers", + expected: schema.GroupVersionResource{Resource: "superhorizontalpodautoscalers"}, srvRes: []*metav1.APIResourceList{ { GroupVersion: "autoscaling/v1", @@ -96,16 +77,12 @@ func TestReplaceAliases(t *testing.T) { } for _, test := range tests { - resources := []string{} ds.serverResourcesHandler = func() ([]*metav1.APIResourceList, error) { return test.srvRes, nil } - for _, arg := range strings.Split(test.arg, ",") { - curr, _ := mapper.AliasesForResource(arg) - resources = append(resources, curr...) - } - if strings.Join(resources, ",") != test.expected { - t.Errorf("%s: unexpected argument: expected %s, got %s", test.name, test.expected, resources) + actual := mapper.expandResourceShortcut(schema.GroupVersionResource{Resource: test.arg}) + if actual != test.expected { + t.Errorf("%s: unexpected argument: expected %s, got %s", test.name, test.expected, actual) } } } diff --git a/pkg/kubectl/resource/BUILD b/pkg/kubectl/resource/BUILD index 1bdf515f1bf..83d7edba177 100644 --- a/pkg/kubectl/resource/BUILD +++ b/pkg/kubectl/resource/BUILD @@ -12,6 +12,7 @@ go_library( name = "go_default_library", srcs = [ "builder.go", + "categories.go", "doc.go", "helper.go", "interfaces.go", @@ -40,6 +41,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/util/sets", "//vendor:k8s.io/apimachinery/pkg/util/yaml", "//vendor:k8s.io/apimachinery/pkg/watch", + "//vendor:k8s.io/client-go/discovery", "//vendor:k8s.io/client-go/rest", ], ) @@ -48,6 +50,7 @@ go_test( name = "go_default_test", srcs = [ "builder_test.go", + "categories_test.go", "helper_test.go", "visitor_test.go", ], @@ -72,6 +75,7 @@ go_test( "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apimachinery/pkg/labels", "//vendor:k8s.io/apimachinery/pkg/runtime", + "//vendor:k8s.io/apimachinery/pkg/runtime/schema", "//vendor:k8s.io/apimachinery/pkg/runtime/serializer/streaming", "//vendor:k8s.io/apimachinery/pkg/util/errors", "//vendor:k8s.io/apimachinery/pkg/watch", diff --git a/pkg/kubectl/resource/builder.go b/pkg/kubectl/resource/builder.go index 9cb9c0b5f1b..75428e7edfc 100644 --- a/pkg/kubectl/resource/builder.go +++ b/pkg/kubectl/resource/builder.go @@ -42,7 +42,8 @@ const defaultHttpGetAttempts int = 3 // from the command line and converting them to a list of resources to iterate // over using the Visitor interface. type Builder struct { - mapper *Mapper + mapper *Mapper + categoryExpander CategoryExpander errs []error @@ -105,10 +106,11 @@ type resourceTuple struct { } // NewBuilder creates a builder that operates on generic objects. -func NewBuilder(mapper meta.RESTMapper, typer runtime.ObjectTyper, clientMapper ClientMapper, decoder runtime.Decoder) *Builder { +func NewBuilder(mapper meta.RESTMapper, categoryExpander CategoryExpander, typer runtime.ObjectTyper, clientMapper ClientMapper, decoder runtime.Decoder) *Builder { return &Builder{ - mapper: &Mapper{typer, mapper, clientMapper, decoder}, - requireObject: true, + mapper: &Mapper{typer, mapper, clientMapper, decoder}, + categoryExpander: categoryExpander, + requireObject: true, } } @@ -371,8 +373,16 @@ func (b *Builder) ResourceTypeOrNameArgs(allowEmptySelector bool, args ...string func (b *Builder) ReplaceAliases(input string) string { replaced := []string{} for _, arg := range strings.Split(input, ",") { - if aliases, ok := b.mapper.AliasesForResource(arg); ok { - arg = strings.Join(aliases, ",") + if resources, ok := b.categoryExpander.Expand(arg); ok { + asStrings := []string{} + for _, resource := range resources { + if len(resource.Group) == 0 { + asStrings = append(asStrings, resource.Resource) + continue + } + asStrings = append(asStrings, resource.Resource+"."+resource.Group) + } + arg = strings.Join(asStrings, ",") } replaced = append(replaced, arg) } diff --git a/pkg/kubectl/resource/builder_test.go b/pkg/kubectl/resource/builder_test.go index 7e6eb4eab44..0f59547ae83 100644 --- a/pkg/kubectl/resource/builder_test.go +++ b/pkg/kubectl/resource/builder_test.go @@ -255,7 +255,7 @@ var aRC string = ` ` func TestPathBuilderAndVersionedObjectNotDefaulted(t *testing.T) { - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{"../../../test/fixtures/pkg/kubectl/builder/kitten-rc.yaml"}}) test := &testVisitor{} @@ -294,7 +294,7 @@ func TestNodeBuilder(t *testing.T) { w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), node))) }() - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). NamespaceParam("test").Stream(r, "STDIN") test := &testVisitor{} @@ -358,7 +358,7 @@ func TestPathBuilderWithMultiple(t *testing.T) { } for _, test := range tests { - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). FilenameParam(false, &FilenameOptions{Recursive: test.recursive, Filenames: []string{test.directory}}). NamespaceParam("test").DefaultNamespace() @@ -417,7 +417,7 @@ func TestPathBuilderWithMultipleInvalid(t *testing.T) { } for _, test := range tests { - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). FilenameParam(false, &FilenameOptions{Recursive: test.recursive, Filenames: []string{test.directory}}). NamespaceParam("test").DefaultNamespace() @@ -432,7 +432,7 @@ func TestPathBuilderWithMultipleInvalid(t *testing.T) { } func TestDirectoryBuilder(t *testing.T) { - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{"../../../examples/guestbook/legacy"}}). NamespaceParam("test").DefaultNamespace() @@ -463,7 +463,7 @@ func TestNamespaceOverride(t *testing.T) { })) defer s.Close() - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{s.URL}}). NamespaceParam("test") @@ -474,7 +474,7 @@ func TestNamespaceOverride(t *testing.T) { t.Fatalf("unexpected response: %v %#v", err, test.Infos) } - b = NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b = NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). FilenameParam(true, &FilenameOptions{Recursive: false, Filenames: []string{s.URL}}). NamespaceParam("test") @@ -494,7 +494,7 @@ func TestURLBuilder(t *testing.T) { })) defer s.Close() - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{s.URL}}). NamespaceParam("foo") @@ -523,7 +523,7 @@ func TestURLBuilderRequireNamespace(t *testing.T) { })) defer s.Close() - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{s.URL}}). NamespaceParam("test").RequireNamespace() @@ -538,7 +538,7 @@ func TestURLBuilderRequireNamespace(t *testing.T) { func TestResourceByName(t *testing.T) { pods, _ := testData() - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), }), testapi.Default.Codec()). NamespaceParam("test") @@ -571,7 +571,7 @@ func TestResourceByName(t *testing.T) { func TestMultipleResourceByTheSameName(t *testing.T) { pods, svcs := testData() - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), "/namespaces/test/pods/baz": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[1]), "/namespaces/test/services/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &svcs.Items[0]), @@ -603,7 +603,7 @@ func TestMultipleResourceByTheSameName(t *testing.T) { func TestResourceNames(t *testing.T) { pods, svc := testData() - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), "/namespaces/test/services/baz": runtime.EncodeOrDie(testapi.Default.Codec(), &svc.Items[0]), }), testapi.Default.Codec()). @@ -631,7 +631,7 @@ func TestResourceNames(t *testing.T) { func TestResourceNamesWithoutResource(t *testing.T) { pods, svc := testData() - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), "/namespaces/test/services/baz": runtime.EncodeOrDie(testapi.Default.Codec(), &svc.Items[0]), }), testapi.Default.Codec()). @@ -652,7 +652,7 @@ func TestResourceNamesWithoutResource(t *testing.T) { } func TestResourceByNameWithoutRequireObject(t *testing.T) { - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{}), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClientWith("", t, map[string]string{}), testapi.Default.Codec()). NamespaceParam("test") test := &testVisitor{} @@ -686,7 +686,7 @@ func TestResourceByNameWithoutRequireObject(t *testing.T) { func TestResourceByNameAndEmptySelector(t *testing.T) { pods, _ := testData() - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), }), testapi.Default.Codec()). NamespaceParam("test"). @@ -714,7 +714,7 @@ func TestResourceByNameAndEmptySelector(t *testing.T) { func TestSelector(t *testing.T) { pods, svc := testData() labelKey := metav1.LabelSelectorQueryParam(api.Registry.GroupOrDie(api.GroupName).GroupVersion.String()) - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), pods), "/namespaces/test/services?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), svc), }), testapi.Default.Codec()). @@ -745,7 +745,7 @@ func TestSelector(t *testing.T) { } func TestSelectorRequiresKnownTypes(t *testing.T) { - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). SelectorParam("a=b"). NamespaceParam("test"). ResourceTypes("unknown") @@ -756,7 +756,7 @@ func TestSelectorRequiresKnownTypes(t *testing.T) { } func TestSingleResourceType(t *testing.T) { - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). SelectorParam("a=b"). SingleResourceType(). ResourceTypeOrNameArgs(true, "pods,services") @@ -826,7 +826,7 @@ func TestResourceTuple(t *testing.T) { } } - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith(k, t, expectedRequests), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClientWith(k, t, expectedRequests), testapi.Default.Codec()). NamespaceParam("test").DefaultNamespace(). ResourceTypeOrNameArgs(true, testCase.args...).RequireObject(requireObject) @@ -857,7 +857,7 @@ func TestResourceTuple(t *testing.T) { func TestStream(t *testing.T) { r, pods, rc := streamTestData() - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). NamespaceParam("test").Stream(r, "STDIN").Flatten() test := &testVisitor{} @@ -874,7 +874,7 @@ func TestStream(t *testing.T) { func TestYAMLStream(t *testing.T) { r, pods, rc := streamYAMLTestData() - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). NamespaceParam("test").Stream(r, "STDIN").Flatten() test := &testVisitor{} @@ -891,7 +891,7 @@ func TestYAMLStream(t *testing.T) { func TestMultipleObject(t *testing.T) { r, pods, svc := streamTestData() - obj, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + obj, err := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). NamespaceParam("test").Stream(r, "STDIN").Flatten(). Do().Object() @@ -913,7 +913,7 @@ func TestMultipleObject(t *testing.T) { func TestContinueOnErrorVisitor(t *testing.T) { r, _, _ := streamTestData() - req := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + req := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). ContinueOnError(). NamespaceParam("test").Stream(r, "STDIN").Flatten(). Do() @@ -942,7 +942,7 @@ func TestContinueOnErrorVisitor(t *testing.T) { } func TestSingleItemImpliedObject(t *testing.T) { - obj, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + obj, err := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). NamespaceParam("test").DefaultNamespace(). FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{"../../../examples/guestbook/legacy/redis-master-controller.yaml"}}). Flatten(). @@ -962,7 +962,7 @@ func TestSingleItemImpliedObject(t *testing.T) { } func TestSingleItemImpliedObjectNoExtension(t *testing.T) { - obj, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + obj, err := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). NamespaceParam("test").DefaultNamespace(). FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{"../../../examples/pod"}}). Flatten(). @@ -984,7 +984,7 @@ func TestSingleItemImpliedObjectNoExtension(t *testing.T) { func TestSingleItemImpliedRootScopedObject(t *testing.T) { node := &api.Node{ObjectMeta: metav1.ObjectMeta{Name: "test"}, Spec: api.NodeSpec{ExternalID: "test"}} r := streamTestObject(node) - infos, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + infos, err := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). NamespaceParam("test").DefaultNamespace(). Stream(r, "STDIN"). Flatten(). @@ -1009,7 +1009,7 @@ func TestSingleItemImpliedRootScopedObject(t *testing.T) { func TestListObject(t *testing.T) { pods, _ := testData() labelKey := metav1.LabelSelectorQueryParam(api.Registry.GroupOrDie(api.GroupName).GroupVersion.String()) - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), pods), }), testapi.Default.Codec()). SelectorParam("a=b"). @@ -1042,7 +1042,7 @@ func TestListObject(t *testing.T) { func TestListObjectWithDifferentVersions(t *testing.T) { pods, svc := testData() labelKey := metav1.LabelSelectorQueryParam(api.Registry.GroupOrDie(api.GroupName).GroupVersion.String()) - obj, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + obj, err := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), pods), "/namespaces/test/services?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), svc), }), testapi.Default.Codec()). @@ -1068,7 +1068,7 @@ func TestListObjectWithDifferentVersions(t *testing.T) { func TestWatch(t *testing.T) { _, svc := testData() - w, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + w, err := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/services?fieldSelector=metadata.name%3Dredis-master&resourceVersion=12&watch=true": watchBody(watch.Event{ Type: watch.Added, Object: &svc.Items[0], @@ -1100,7 +1100,7 @@ func TestWatch(t *testing.T) { } func TestWatchMultipleError(t *testing.T) { - _, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + _, err := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). NamespaceParam("test").DefaultNamespace(). FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{"../../../examples/guestbook/legacy/redis-master-controller.yaml"}}).Flatten(). FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{"../../../examples/guestbook/legacy/redis-master-controller.yaml"}}).Flatten(). @@ -1123,7 +1123,7 @@ func TestLatest(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "15"}, } - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClientWith("", t, map[string]string{ "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), newPod), "/namespaces/test/pods/bar": runtime.EncodeOrDie(testapi.Default.Codec(), newPod2), "/namespaces/test/services/baz": runtime.EncodeOrDie(testapi.Default.Codec(), newSvc), @@ -1159,7 +1159,7 @@ func TestReceiveMultipleErrors(t *testing.T) { w2.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &svc.Items[0]))) }() - b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). + b := NewBuilder(testapi.Default.RESTMapper(), LegacyCategoryExpander, api.Scheme, fakeClient(), testapi.Default.Codec()). Stream(r, "1").Stream(r2, "2"). ContinueOnError() diff --git a/pkg/kubectl/resource/categories.go b/pkg/kubectl/resource/categories.go new file mode 100644 index 00000000000..e547ab1ed7b --- /dev/null +++ b/pkg/kubectl/resource/categories.go @@ -0,0 +1,109 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resource + +import ( + "errors" + + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/discovery" +) + +type CategoryExpander interface { + Expand(category string) ([]schema.GroupResource, bool) +} + +type SimpleCategoryExpander struct { + Expansions map[string][]schema.GroupResource +} + +func (e SimpleCategoryExpander) Expand(category string) ([]schema.GroupResource, bool) { + ret, ok := e.Expansions[category] + return ret, ok +} + +type discoveryFilteredExpander struct { + delegate CategoryExpander + + discoveryClient discovery.DiscoveryInterface +} + +// NewDiscoveryFilteredExpander returns a category expander that filters the returned groupresources by +// what the server has available +func NewDiscoveryFilteredExpander(delegate CategoryExpander, client discovery.DiscoveryInterface) (discoveryFilteredExpander, error) { + if client == nil { + return discoveryFilteredExpander{}, errors.New("Please provide discovery client to shortcut expander") + } + return discoveryFilteredExpander{delegate: delegate, discoveryClient: client}, nil +} + +func (e discoveryFilteredExpander) Expand(category string) ([]schema.GroupResource, bool) { + delegateExpansion, ok := e.delegate.Expand(category) + + // Check if we have access to server resources + apiResources, err := e.discoveryClient.ServerResources() + if err != nil { + return delegateExpansion, ok + } + + availableResources, err := discovery.GroupVersionResources(apiResources) + if err != nil { + return delegateExpansion, ok + } + + available := []schema.GroupResource{} + for _, requestedResource := range delegateExpansion { + for availableResource := range availableResources { + if requestedResource.Group == availableResource.Group && + requestedResource.Resource == availableResource.Resource { + available = append(available, requestedResource) + break + } + } + } + + return available, ok +} + +// legacyUserResources are the resource names that apply to the primary, user facing resources used by +// client tools. They are in deletion-first order - dependent resources should be last. +// Should remain exported in order to expose a current list of resources to downstream +// composition that wants to build on the concept of 'all' for their CLIs. +var legacyUserResources = []schema.GroupResource{ + {Group: "", Resource: "pods"}, + {Group: "", Resource: "replicationcontrollers"}, + {Group: "", Resource: "services"}, + {Group: "apps", Resource: "statefulsets"}, + {Group: "autoscaling", Resource: "horizontalpodautoscalers"}, + {Group: "batch", Resource: "jobs"}, + {Group: "extensions", Resource: "deployments"}, + {Group: "extensions", Resource: "replicasets"}, +} + +// LegacyCategoryExpander is the old hardcoded expansion +var LegacyCategoryExpander CategoryExpander = SimpleCategoryExpander{ + Expansions: map[string][]schema.GroupResource{ + "all": legacyUserResources, + }, +} + +// LegacyFederationCategoryExpander is the old hardcoded expansion for federation +var LegacyFederationCategoryExpander CategoryExpander = SimpleCategoryExpander{ + Expansions: map[string][]schema.GroupResource{ + "all": {{Group: "", Resource: "services"}}, + }, +} diff --git a/pkg/kubectl/resource/categories_test.go b/pkg/kubectl/resource/categories_test.go new file mode 100644 index 00000000000..dbc489d188e --- /dev/null +++ b/pkg/kubectl/resource/categories_test.go @@ -0,0 +1,65 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resource + +import ( + "reflect" + "testing" + + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func TestCategoryExpansion(t *testing.T) { + tests := []struct { + name string + arg string + + expected []schema.GroupResource + expectedOk bool + }{ + { + name: "no-replacement", + arg: "service", + expected: nil, + }, + { + name: "all-replacement", + arg: "all", + expected: []schema.GroupResource{ + {Resource: "pods"}, + {Resource: "replicationcontrollers"}, + {Resource: "services"}, + {Resource: "statefulsets", Group: "apps"}, + {Resource: "horizontalpodautoscalers", Group: "autoscaling"}, + {Resource: "jobs", Group: "batch"}, + {Resource: "deployments", Group: "extensions"}, + {Resource: "replicasets", Group: "extensions"}, + }, + expectedOk: true, + }, + } + + for _, test := range tests { + actual, actualOk := LegacyCategoryExpander.Expand(test.arg) + if e, a := test.expected, actual; !reflect.DeepEqual(e, a) { + t.Errorf("%s: expected %s, got %s", test.name, e, a) + } + if e, a := test.expectedOk, actualOk; e != a { + t.Errorf("%s: expected %v, got %v", test.name, e, a) + } + } +} diff --git a/pkg/registry/extensions/thirdpartyresourcedata/codec.go b/pkg/registry/extensions/thirdpartyresourcedata/codec.go index 514d6bacc97..e78ddb58d56 100644 --- a/pkg/registry/extensions/thirdpartyresourcedata/codec.go +++ b/pkg/registry/extensions/thirdpartyresourcedata/codec.go @@ -171,10 +171,6 @@ func (t *thirdPartyResourceDataMapper) RESTMappings(gk schema.GroupKind, version return mappings, nil } -func (t *thirdPartyResourceDataMapper) AliasesForResource(resource string) ([]string, bool) { - return t.mapper.AliasesForResource(resource) -} - func (t *thirdPartyResourceDataMapper) ResourceSingularizer(resource string) (singular string, err error) { return t.mapper.ResourceSingularizer(resource) } diff --git a/staging/src/k8s.io/apimachinery/pkg/api/meta/interfaces.go b/staging/src/k8s.io/apimachinery/pkg/api/meta/interfaces.go index 524b1ebd813..b2c8c97b112 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/meta/interfaces.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/meta/interfaces.go @@ -142,6 +142,5 @@ type RESTMapper interface { // the provided version(s). RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) - AliasesForResource(resource string) ([]string, bool) ResourceSingularizer(resource string) (singular string, err error) } diff --git a/staging/src/k8s.io/apimachinery/pkg/api/meta/multirestmapper.go b/staging/src/k8s.io/apimachinery/pkg/api/meta/multirestmapper.go index d32b0dbf795..679098fe56f 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/meta/multirestmapper.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/meta/multirestmapper.go @@ -22,7 +22,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" utilerrors "k8s.io/apimachinery/pkg/util/errors" - "k8s.io/apimachinery/pkg/util/sets" ) // MultiRESTMapper is a wrapper for multiple RESTMappers. @@ -209,23 +208,3 @@ func (m MultiRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ( } return allMappings, nil } - -// AliasesForResource finds the first alias response for the provided mappers. -func (m MultiRESTMapper) AliasesForResource(alias string) ([]string, bool) { - seenAliases := sets.NewString() - allAliases := []string{} - handled := false - - for _, t := range m { - if currAliases, currOk := t.AliasesForResource(alias); currOk { - for _, currAlias := range currAliases { - if !seenAliases.Has(currAlias) { - allAliases = append(allAliases, currAlias) - seenAliases.Insert(currAlias) - } - } - handled = true - } - } - return allAliases, handled -} diff --git a/staging/src/k8s.io/apimachinery/pkg/api/meta/multirestmapper_test.go b/staging/src/k8s.io/apimachinery/pkg/api/meta/multirestmapper_test.go index b287682b968..dec07a16f7b 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/meta/multirestmapper_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/meta/multirestmapper_test.go @@ -350,10 +350,6 @@ func (m fixedRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ( return m.mappings, m.err } -func (m fixedRESTMapper) AliasesForResource(alias string) (aliases []string, ok bool) { - return nil, false -} - func (m fixedRESTMapper) ResourceIsValid(resource schema.GroupVersionResource) bool { return false } diff --git a/staging/src/k8s.io/apimachinery/pkg/api/meta/priority.go b/staging/src/k8s.io/apimachinery/pkg/api/meta/priority.go index 91203d11fcd..2a14aa7ab17 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/meta/priority.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/meta/priority.go @@ -209,10 +209,6 @@ func (m PriorityRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string return m.Delegate.RESTMappings(gk, versions...) } -func (m PriorityRESTMapper) AliasesForResource(alias string) (aliases []string, ok bool) { - return m.Delegate.AliasesForResource(alias) -} - func (m PriorityRESTMapper) ResourceSingularizer(resource string) (singular string, err error) { return m.Delegate.ResourceSingularizer(resource) } diff --git a/staging/src/k8s.io/apimachinery/pkg/api/meta/restmapper.go b/staging/src/k8s.io/apimachinery/pkg/api/meta/restmapper.go index bf4c77a82bd..3a9d05f6d93 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/meta/restmapper.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/meta/restmapper.go @@ -79,9 +79,6 @@ type DefaultRESTMapper struct { pluralToSingular map[schema.GroupVersionResource]schema.GroupVersionResource interfacesFunc VersionInterfacesFunc - - // aliasToResource is used for mapping aliases to resources - aliasToResource map[string][]string } func (m *DefaultRESTMapper) String() string { @@ -105,7 +102,6 @@ func NewDefaultRESTMapper(defaultGroupVersions []schema.GroupVersion, f VersionI kindToScope := make(map[schema.GroupVersionKind]RESTScope) singularToPlural := make(map[schema.GroupVersionResource]schema.GroupVersionResource) pluralToSingular := make(map[schema.GroupVersionResource]schema.GroupVersionResource) - aliasToResource := make(map[string][]string) // TODO: verify name mappings work correctly when versions differ return &DefaultRESTMapper{ @@ -115,7 +111,6 @@ func NewDefaultRESTMapper(defaultGroupVersions []schema.GroupVersion, f VersionI defaultGroupVersions: defaultGroupVersions, singularToPlural: singularToPlural, pluralToSingular: pluralToSingular, - aliasToResource: aliasToResource, interfacesFunc: f, } } @@ -548,19 +543,3 @@ func (m *DefaultRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string } return mappings, nil } - -// AddResourceAlias maps aliases to resources -func (m *DefaultRESTMapper) AddResourceAlias(alias string, resources ...string) { - if len(resources) == 0 { - return - } - m.aliasToResource[alias] = resources -} - -// AliasesForResource returns whether a resource has an alias or not -func (m *DefaultRESTMapper) AliasesForResource(alias string) ([]string, bool) { - if res, ok := m.aliasToResource[alias]; ok { - return res, true - } - return nil, false -} diff --git a/staging/src/k8s.io/client-go/discovery/restmapper.go b/staging/src/k8s.io/client-go/discovery/restmapper.go index 9b0769a1871..5c77464e3aa 100644 --- a/staging/src/k8s.io/client-go/discovery/restmapper.go +++ b/staging/src/k8s.io/client-go/discovery/restmapper.go @@ -279,20 +279,6 @@ func (d *DeferredDiscoveryRESTMapper) RESTMappings(gk schema.GroupKind, versions return } -// AliasesForResource returns whether a resource has an alias or not. -func (d *DeferredDiscoveryRESTMapper) AliasesForResource(resource string) (as []string, ok bool) { - del, err := d.getDelegate() - if err != nil { - return nil, false - } - as, ok = del.AliasesForResource(resource) - if len(as) == 0 && !d.cl.Fresh() { - d.Reset() - as, ok = d.AliasesForResource(resource) - } - return -} - // ResourceSingularizer converts a resource name from plural to // singular (e.g., from pods to pod). func (d *DeferredDiscoveryRESTMapper) ResourceSingularizer(resource string) (singular string, err error) {