mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
move category expansion out of restmapper
This commit is contained in:
parent
f4986235c7
commit
8895f314b4
@ -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
|
||||
}
|
||||
|
@ -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).
|
||||
|
@ -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().
|
||||
|
@ -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().
|
||||
|
@ -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...).
|
||||
|
@ -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) {
|
||||
|
@ -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).
|
||||
|
@ -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...).
|
||||
|
@ -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"}...).
|
||||
|
@ -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
|
||||
|
@ -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().
|
||||
|
@ -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).
|
||||
|
@ -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().
|
||||
|
@ -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().
|
||||
|
@ -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).
|
||||
|
@ -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).
|
||||
|
@ -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).
|
||||
|
@ -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 != "" {
|
||||
|
@ -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).
|
||||
|
@ -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().
|
||||
|
@ -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}}).
|
||||
|
@ -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...).
|
||||
|
@ -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...).
|
||||
|
@ -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...).
|
||||
|
@ -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...).
|
||||
|
@ -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...).
|
||||
|
@ -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).
|
||||
|
@ -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).
|
||||
|
@ -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).
|
||||
|
@ -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...).
|
||||
|
@ -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...).
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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()
|
||||
|
||||
|
109
pkg/kubectl/resource/categories.go
Normal file
109
pkg/kubectl/resource/categories.go
Normal file
@ -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"}},
|
||||
},
|
||||
}
|
65
pkg/kubectl/resource/categories_test.go
Normal file
65
pkg/kubectl/resource/categories_test.go
Normal file
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user