mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-05 15:37:24 +00:00
Merge pull request #18835 from brendandburns/3rdparty
Automatic merge from submit-queue
Add support for 3rd party objects to kubectl
@deads2k @jlowdermilk
Instructions for playing around with this:
Run an apiserver with third party resources turned on (`--runtime-config=extensions/v1beta1=true,extensions/v1beta1/thirdpartyresources=true`)
Then you should be able to:
```
kubectl create -f rsrc.json
```
```json
{
"metadata": {
"name": "foo.company.com"
},
"apiVersion": "extensions/v1beta1",
"kind": "ThirdPartyResource",
"versions": [
{
"apiGroup": "group",
"name": "v1"
},
{
"apiGroup": "group",
"name": "v2"
}
]
}
```
Once that is done, you should be able to:
```
curl http://<server>/apis/company.com/v1/foos
```
```
curl -X POST -d @${HOME}/foo.json http://localhost:8080/apis/company.com/v1/namespaces/default/foos
```
```json
{
"kind": "Foo",
"apiVersion": "company.com/v1",
"metadata": {
"name": "baz"
},
"someField": "hello world",
"otherField": 1
}
```
After this PR, you can do:
```
kubectl create -f foo.json
```
```
kubectl get foos
```
etc.
This commit is contained in:
@@ -110,6 +110,7 @@ func NewCmdAnnotate(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
},
|
||||
}
|
||||
cmdutil.AddPrinterFlags(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
cmd.Flags().StringVarP(&options.selector, "selector", "l", "", "Selector (label query) to filter on")
|
||||
cmd.Flags().BoolVar(&options.overwrite, "overwrite", false, "If true, allow annotations to be overwritten, otherwise reject annotation updates that overwrite existing annotations.")
|
||||
cmd.Flags().BoolVar(&options.all, "all", false, "select all resources in the namespace of the specified resource types")
|
||||
@@ -161,7 +162,7 @@ func (o *AnnotateOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra
|
||||
o.recordChangeCause = cmdutil.GetRecordFlag(cmd)
|
||||
o.changeCause = f.Command()
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
o.builder = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
ContinueOnError().
|
||||
NamespaceParam(namespace).DefaultNamespace().
|
||||
@@ -246,11 +247,13 @@ func (o AnnotateOptions) RunAnnotate() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mapper, _ := o.f.Object(cmdutil.GetIncludeThirdPartyAPIs(o.cmd))
|
||||
outputFormat := cmdutil.GetFlagString(o.cmd, "output")
|
||||
if outputFormat != "" {
|
||||
return o.f.PrintObject(o.cmd, outputObj, o.out)
|
||||
return o.f.PrintObject(o.cmd, mapper, outputObj, o.out)
|
||||
}
|
||||
mapper, _ := o.f.Object()
|
||||
|
||||
cmdutil.PrintSuccess(mapper, false, o.out, info.Mapping.Resource, info.Name, "annotated")
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -72,6 +72,7 @@ func NewCmdApply(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmdutil.AddRecursiveFlag(cmd, &options.Recursive)
|
||||
cmdutil.AddOutputFlagsForMutation(cmd)
|
||||
cmdutil.AddRecordFlag(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -95,7 +96,7 @@ func RunApply(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer, options *Ap
|
||||
return err
|
||||
}
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
Schema(schema).
|
||||
ContinueOnError().
|
||||
|
||||
@@ -74,6 +74,7 @@ func NewCmdAutoscale(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmdutil.AddRecursiveFlag(cmd, &options.Recursive)
|
||||
cmdutil.AddApplyAnnotationFlags(cmd)
|
||||
cmdutil.AddRecordFlag(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -88,7 +89,7 @@ func RunAutoscale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []
|
||||
return err
|
||||
}
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
ContinueOnError().
|
||||
NamespaceParam(namespace).DefaultNamespace().
|
||||
@@ -157,7 +158,7 @@ func RunAutoscale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []
|
||||
}
|
||||
// TODO: extract this flag to a central location, when such a location exists.
|
||||
if cmdutil.GetFlagBool(cmd, "dry-run") {
|
||||
return f.PrintObject(cmd, object, out)
|
||||
return f.PrintObject(cmd, mapper, object, out)
|
||||
}
|
||||
|
||||
if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), hpa, f.JSONEncoder()); err != nil {
|
||||
@@ -170,7 +171,7 @@ func RunAutoscale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []
|
||||
}
|
||||
|
||||
if len(cmdutil.GetFlagString(cmd, "output")) > 0 {
|
||||
return f.PrintObject(cmd, object, out)
|
||||
return f.PrintObject(cmd, mapper, object, out)
|
||||
}
|
||||
cmdutil.PrintSuccess(mapper, false, out, info.Mapping.Resource, info.Name, "autoscaled")
|
||||
return nil
|
||||
|
||||
@@ -42,6 +42,7 @@ func NewCmdClusterInfo(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmdutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -56,7 +57,7 @@ func RunClusterInfo(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command) error
|
||||
}
|
||||
printService(out, "Kubernetes master", client.Host)
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
cmdNamespace := cmdutil.GetFlagString(cmd, "namespace")
|
||||
if cmdNamespace == "" {
|
||||
cmdNamespace = api.NamespaceSystem
|
||||
|
||||
@@ -180,7 +180,7 @@ func NewTestFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) {
|
||||
Typer: scheme,
|
||||
}
|
||||
return &cmdutil.Factory{
|
||||
Object: func() (meta.RESTMapper, runtime.ObjectTyper) {
|
||||
Object: func(discovery bool) (meta.RESTMapper, runtime.ObjectTyper) {
|
||||
priorityRESTMapper := meta.PriorityRESTMapper{
|
||||
Delegate: t.Mapper,
|
||||
ResourcePriority: []unversioned.GroupVersionResource{
|
||||
@@ -221,7 +221,7 @@ func NewTestFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) {
|
||||
|
||||
func NewMixedFactory(apiClient resource.RESTClient) (*cmdutil.Factory, *testFactory, runtime.Codec) {
|
||||
f, t, c := NewTestFactory()
|
||||
f.Object = func() (meta.RESTMapper, runtime.ObjectTyper) {
|
||||
f.Object = func(discovery bool) (meta.RESTMapper, runtime.ObjectTyper) {
|
||||
priorityRESTMapper := meta.PriorityRESTMapper{
|
||||
Delegate: meta.MultiRESTMapper{t.Mapper, testapi.Default.RESTMapper()},
|
||||
ResourcePriority: []unversioned.GroupVersionResource{
|
||||
@@ -248,7 +248,7 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) {
|
||||
}
|
||||
|
||||
f := &cmdutil.Factory{
|
||||
Object: func() (meta.RESTMapper, runtime.ObjectTyper) {
|
||||
Object: func(discovery bool) (meta.RESTMapper, runtime.ObjectTyper) {
|
||||
return testapi.Default.RESTMapper(), api.Scheme
|
||||
},
|
||||
Client: func() (*client.Client, error) {
|
||||
@@ -380,7 +380,8 @@ func ExamplePrintReplicationControllerWithNamespace() {
|
||||
Replicas: 1,
|
||||
},
|
||||
}
|
||||
err := f.PrintObject(cmd, ctrl, os.Stdout)
|
||||
mapper, _ := f.Object(false)
|
||||
err := f.PrintObject(cmd, mapper, ctrl, os.Stdout)
|
||||
if err != nil {
|
||||
fmt.Printf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -428,7 +429,8 @@ func ExamplePrintMultiContainersReplicationControllerWithWide() {
|
||||
Replicas: 1,
|
||||
},
|
||||
}
|
||||
err := f.PrintObject(cmd, ctrl, os.Stdout)
|
||||
mapper, _ := f.Object(false)
|
||||
err := f.PrintObject(cmd, mapper, ctrl, os.Stdout)
|
||||
if err != nil {
|
||||
fmt.Printf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -476,7 +478,8 @@ func ExamplePrintReplicationController() {
|
||||
Replicas: 1,
|
||||
},
|
||||
}
|
||||
err := f.PrintObject(cmd, ctrl, os.Stdout)
|
||||
mapper, _ := f.Object(false)
|
||||
err := f.PrintObject(cmd, mapper, ctrl, os.Stdout)
|
||||
if err != nil {
|
||||
fmt.Printf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -511,7 +514,8 @@ func ExamplePrintPodWithWideFormat() {
|
||||
},
|
||||
},
|
||||
}
|
||||
err := f.PrintObject(cmd, pod, os.Stdout)
|
||||
mapper, _ := f.Object(false)
|
||||
err := f.PrintObject(cmd, mapper, pod, os.Stdout)
|
||||
if err != nil {
|
||||
fmt.Printf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -550,7 +554,8 @@ func ExamplePrintPodWithShowLabels() {
|
||||
},
|
||||
},
|
||||
}
|
||||
err := f.PrintObject(cmd, pod, os.Stdout)
|
||||
mapper, _ := f.Object(false)
|
||||
err := f.PrintObject(cmd, mapper, pod, os.Stdout)
|
||||
if err != nil {
|
||||
fmt.Printf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -660,7 +665,8 @@ func ExamplePrintPodHideTerminated() {
|
||||
}
|
||||
cmd := NewCmdRun(f, os.Stdin, os.Stdout, os.Stderr)
|
||||
podList := newAllPhasePodList()
|
||||
err := f.PrintObject(cmd, podList, os.Stdout)
|
||||
mapper, _ := f.Object(false)
|
||||
err := f.PrintObject(cmd, mapper, podList, os.Stdout)
|
||||
if err != nil {
|
||||
fmt.Printf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -680,7 +686,8 @@ func ExamplePrintPodShowAll() {
|
||||
}
|
||||
cmd := NewCmdRun(f, os.Stdin, os.Stdout, os.Stderr)
|
||||
podList := newAllPhasePodList()
|
||||
err := f.PrintObject(cmd, podList, os.Stdout)
|
||||
mapper, _ := f.Object(false)
|
||||
err := f.PrintObject(cmd, mapper, podList, os.Stdout)
|
||||
if err != nil {
|
||||
fmt.Printf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -748,7 +755,9 @@ func ExamplePrintServiceWithNamespacesAndLabels() {
|
||||
}
|
||||
ld := util.NewLineDelimiter(os.Stdout, "|")
|
||||
defer ld.Flush()
|
||||
err := f.PrintObject(cmd, svc, ld)
|
||||
|
||||
mapper, _ := f.Object(false)
|
||||
err := f.PrintObject(cmd, mapper, svc, ld)
|
||||
if err != nil {
|
||||
fmt.Printf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ func NewCmdConvert(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmdutil.AddValidateFlags(cmd)
|
||||
cmdutil.AddPrinterFlags(cmd)
|
||||
cmd.Flags().BoolVar(&options.local, "local", true, "If true, convert will NOT try to contact api-server but run locally.")
|
||||
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -109,8 +109,9 @@ func (o *ConvertOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra.
|
||||
}
|
||||
|
||||
// build the builder
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
clientMapper := resource.ClientMapperFunc(f.ClientForMapping)
|
||||
|
||||
if o.local {
|
||||
fmt.Fprintln(out, "running in local mode...")
|
||||
o.builder = resource.NewBuilder(mapper, typer, resource.DisabledClientForMapping{ClientMapper: clientMapper}, f.Decoder(true))
|
||||
|
||||
@@ -76,6 +76,7 @@ func NewCmdCreate(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmdutil.AddOutputFlagsForMutation(cmd)
|
||||
cmdutil.AddApplyAnnotationFlags(cmd)
|
||||
cmdutil.AddRecordFlag(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
|
||||
// create subcommands
|
||||
cmd.AddCommand(NewCmdCreateNamespace(f, out))
|
||||
@@ -103,7 +104,7 @@ func RunCreate(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer, options *C
|
||||
return err
|
||||
}
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
Schema(schema).
|
||||
ContinueOnError().
|
||||
@@ -223,7 +224,7 @@ func RunCreateSubcommand(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
gvk, err := typer.ObjectKind(obj)
|
||||
mapping, err := mapper.RESTMapping(unversioned.GroupKind{Group: gvk.Group, Kind: gvk.Kind}, gvk.Version)
|
||||
if err != nil {
|
||||
@@ -257,5 +258,5 @@ func RunCreateSubcommand(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer,
|
||||
return nil
|
||||
}
|
||||
|
||||
return f.PrintObject(cmd, obj, out)
|
||||
return f.PrintObject(cmd, mapper, obj, out)
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ func NewCmdCreateNamespace(f *cmdutil.Factory, cmdOut io.Writer) *cobra.Command
|
||||
cmdutil.AddValidateFlags(cmd)
|
||||
cmdutil.AddPrinterFlags(cmd)
|
||||
cmdutil.AddGeneratorFlags(cmd, cmdutil.NamespaceV1GeneratorName)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ func NewCmdCreateSecret(f *cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
|
||||
}
|
||||
cmd.AddCommand(NewCmdCreateSecretDockerRegistry(f, cmdOut))
|
||||
cmd.AddCommand(NewCmdCreateSecretGeneric(f, cmdOut))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -155,6 +156,7 @@ func NewCmdCreateSecretDockerRegistry(f *cmdutil.Factory, cmdOut io.Writer) *cob
|
||||
cmd.Flags().String("docker-email", "", "Email for Docker registry")
|
||||
cmd.MarkFlagRequired("docker-email")
|
||||
cmd.Flags().String("docker-server", "https://index.docker.io/v1/", "Server location for Docker registry")
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ func NewCmdCreateServiceAccount(f *cmdutil.Factory, cmdOut io.Writer) *cobra.Com
|
||||
cmdutil.AddApplyAnnotationFlags(cmd)
|
||||
cmdutil.AddValidateFlags(cmd)
|
||||
cmdutil.AddPrinterFlags(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
cmdutil.AddGeneratorFlags(cmd, cmdutil.ServiceAccountV1GeneratorName)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -100,6 +100,7 @@ func NewCmdDelete(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmd.Flags().Int("grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.")
|
||||
cmd.Flags().Duration("timeout", 0, "The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object")
|
||||
cmdutil.AddOutputFlagsForMutation(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -109,7 +110,7 @@ func RunDelete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
|
||||
return err
|
||||
}
|
||||
deleteAll := cmdutil.GetFlagBool(cmd, "all")
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
ContinueOnError().
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
|
||||
@@ -89,6 +89,7 @@ func NewCmdDescribe(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
|
||||
cmdutil.AddRecursiveFlag(cmd, &options.Recursive)
|
||||
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on")
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -103,7 +104,7 @@ func RunDescribe(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s
|
||||
return cmdutil.UsageError(cmd, "Required resource not specified.")
|
||||
}
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
ContinueOnError().
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
|
||||
@@ -60,7 +60,7 @@ kubectl cordon foo
|
||||
func NewCmdCordon(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
options := &DrainOptions{factory: f, out: out}
|
||||
|
||||
return &cobra.Command{
|
||||
cmd := &cobra.Command{
|
||||
Use: "cordon NODE",
|
||||
Short: "Mark node as unschedulable",
|
||||
Long: cordon_long,
|
||||
@@ -70,6 +70,7 @@ func NewCmdCordon(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmdutil.CheckErr(options.RunCordonOrUncordon(true))
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -83,7 +84,7 @@ $ kubectl uncordon foo
|
||||
func NewCmdUncordon(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
options := &DrainOptions{factory: f, out: out}
|
||||
|
||||
return &cobra.Command{
|
||||
cmd := &cobra.Command{
|
||||
Use: "uncordon NODE",
|
||||
Short: "Mark node as schedulable",
|
||||
Long: uncordon_long,
|
||||
@@ -93,6 +94,7 @@ func NewCmdUncordon(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmdutil.CheckErr(options.RunCordonOrUncordon(false))
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -149,14 +151,14 @@ func (o *DrainOptions) SetupDrain(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
o.mapper, o.typer = o.factory.Object()
|
||||
o.mapper, o.typer = o.factory.Object(false)
|
||||
|
||||
cmdNamespace, _, err := o.factory.DefaultNamespace()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r := o.factory.NewBuilder().
|
||||
r := o.factory.NewBuilder(cmdutil.GetIncludeThirdPartyAPIs(cmd)).
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
ResourceNames("node", args[0]).
|
||||
Do()
|
||||
|
||||
@@ -107,6 +107,7 @@ func NewCmdEdit(f *cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
||||
cmd.Flags().Bool("windows-line-endings", gruntime.GOOS == "windows", "Use Windows line-endings (default Unix line-endings)")
|
||||
cmdutil.AddApplyAnnotationFlags(cmd)
|
||||
cmdutil.AddRecordFlag(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -129,7 +130,7 @@ func RunEdit(f *cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args
|
||||
return err
|
||||
}
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
resourceMapper := &resource.Mapper{
|
||||
ObjectTyper: typer,
|
||||
RESTMapper: mapper,
|
||||
|
||||
@@ -52,6 +52,7 @@ func NewCmdExplain(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
},
|
||||
}
|
||||
cmd.Flags().Bool("recursive", false, "Print the fields of fields (Currently only 1 level deep)")
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -65,7 +66,7 @@ func RunExplain(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []st
|
||||
apiVersionString := cmdutil.GetFlagString(cmd, "api-version")
|
||||
apiVersion := unversioned.GroupVersion{}
|
||||
|
||||
mapper, _ := f.Object()
|
||||
mapper, _ := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
// TODO: After we figured out the new syntax to separate group and resource, allow
|
||||
// the users to use it in explain (kubectl explain <group><syntax><resource>).
|
||||
// Refer to issue #16039 for why we do this. Refer to PR #15808 that used "/" syntax.
|
||||
|
||||
@@ -115,7 +115,7 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
|
||||
return err
|
||||
}
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(false)
|
||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
ContinueOnError().
|
||||
NamespaceParam(namespace).DefaultNamespace().
|
||||
@@ -229,7 +229,7 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
|
||||
info.Refresh(object, true)
|
||||
// TODO: extract this flag to a central location, when such a location exists.
|
||||
if cmdutil.GetFlagBool(cmd, "dry-run") {
|
||||
return f.PrintObject(cmd, object, out)
|
||||
return f.PrintObject(cmd, mapper, object, out)
|
||||
}
|
||||
if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info, f.JSONEncoder()); err != nil {
|
||||
return err
|
||||
@@ -242,7 +242,7 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
|
||||
}
|
||||
|
||||
if len(cmdutil.GetFlagString(cmd, "output")) > 0 {
|
||||
return f.PrintObject(cmd, object, out)
|
||||
return f.PrintObject(cmd, mapper, object, out)
|
||||
}
|
||||
cmdutil.PrintSuccess(mapper, false, out, info.Mapping.Resource, info.Name, "exposed")
|
||||
return nil
|
||||
|
||||
@@ -102,6 +102,7 @@ func NewCmdGet(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
usage := "Filename, directory, or URL to a file identifying the resource to get from a server."
|
||||
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
|
||||
cmdutil.AddRecursiveFlag(cmd, &options.Recursive)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -110,7 +111,7 @@ func NewCmdGet(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, options *GetOptions) error {
|
||||
selector := cmdutil.GetFlagString(cmd, "selector")
|
||||
allNamespaces := cmdutil.GetFlagBool(cmd, "all-namespaces")
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
|
||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||
if err != nil {
|
||||
|
||||
@@ -100,6 +100,7 @@ func NewCmdLabel(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmdutil.AddRecursiveFlag(cmd, &options.Recursive)
|
||||
cmd.Flags().Bool("dry-run", false, "If true, only print the object that would be sent, without sending it.")
|
||||
cmdutil.AddRecordFlag(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
@@ -204,8 +205,7 @@ func RunLabel(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
|
||||
if err != nil {
|
||||
return cmdutil.UsageError(cmd, err.Error())
|
||||
}
|
||||
mapper, typer := f.Object()
|
||||
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
b := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
ContinueOnError().
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
@@ -296,7 +296,7 @@ func RunLabel(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
|
||||
}
|
||||
outputFormat := cmdutil.GetFlagString(cmd, "output")
|
||||
if outputFormat != "" {
|
||||
return f.PrintObject(cmd, outputObj, out)
|
||||
return f.PrintObject(cmd, mapper, outputObj, out)
|
||||
}
|
||||
cmdutil.PrintSuccess(mapper, false, out, info.Mapping.Resource, info.Name, dataChangeMsg)
|
||||
return nil
|
||||
|
||||
@@ -101,6 +101,7 @@ func NewCmdLogs(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
|
||||
cmd.Flags().Bool("interactive", false, "If true, prompt the user for input when required.")
|
||||
cmd.Flags().MarkDeprecated("interactive", "This flag is no longer respected and there is no replacement.")
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -155,7 +156,7 @@ func (o *LogsOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Com
|
||||
o.ClientMapper = resource.ClientMapperFunc(f.ClientForMapping)
|
||||
o.Out = out
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
decoder := f.Decoder(true)
|
||||
if o.Object == nil {
|
||||
infos, err := resource.NewBuilder(mapper, typer, o.ClientMapper, decoder).
|
||||
|
||||
@@ -80,6 +80,7 @@ func NewCmdPatch(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmd.Flags().String("type", "strategic", fmt.Sprintf("The type of patch being provided; one of %v", sets.StringKeySet(patchTypes).List()))
|
||||
cmdutil.AddOutputFlagsForMutation(cmd)
|
||||
cmdutil.AddRecordFlag(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
|
||||
usage := "Filename, directory, or URL to a file identifying the resource to update"
|
||||
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
|
||||
@@ -112,7 +113,7 @@ func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
|
||||
return fmt.Errorf("unable to parse %q: %v", patch, err)
|
||||
}
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
ContinueOnError().
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
|
||||
@@ -87,6 +87,8 @@ func NewCmdReplace(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmdutil.AddOutputFlagsForMutation(cmd)
|
||||
cmdutil.AddApplyAnnotationFlags(cmd)
|
||||
cmdutil.AddRecordFlag(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -114,7 +116,7 @@ func RunReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []st
|
||||
return forceReplace(f, out, cmd, args, shortOutput, options)
|
||||
}
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
Schema(schema).
|
||||
ContinueOnError().
|
||||
@@ -182,7 +184,7 @@ func forceReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []
|
||||
}
|
||||
}
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
ContinueOnError().
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
|
||||
@@ -102,6 +102,8 @@ func NewCmdRollingUpdate(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmd.Flags().Bool("rollback", false, "If true, this is a request to abort an existing rollout that is partially rolled out. It effectively reverses current and next and runs a rollout")
|
||||
cmdutil.AddValidateFlags(cmd)
|
||||
cmdutil.AddPrinterFlags(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -190,7 +192,7 @@ func RunRollingUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, arg
|
||||
var keepOldName bool
|
||||
var replicasDefaulted bool
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
|
||||
if len(filename) != 0 {
|
||||
schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"), cmdutil.GetFlagString(cmd, "schema-cache-dir"))
|
||||
@@ -311,10 +313,10 @@ func RunRollingUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, arg
|
||||
oldRcData.WriteString(oldRc.Name)
|
||||
newRcData.WriteString(newRc.Name)
|
||||
} else {
|
||||
if err := f.PrintObject(cmd, oldRc, oldRcData); err != nil {
|
||||
if err := f.PrintObject(cmd, mapper, oldRc, oldRcData); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := f.PrintObject(cmd, newRc, newRcData); err != nil {
|
||||
if err := f.PrintObject(cmd, mapper, newRc, newRcData); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -359,7 +361,7 @@ func RunRollingUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, arg
|
||||
return err
|
||||
}
|
||||
if outputFormat != "" {
|
||||
return f.PrintObject(cmd, newRc, out)
|
||||
return f.PrintObject(cmd, mapper, newRc, out)
|
||||
}
|
||||
kind, err := api.Scheme.ObjectKind(newRc)
|
||||
if err != nil {
|
||||
|
||||
@@ -43,7 +43,6 @@ func NewCmdRollout(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
// subcommands
|
||||
cmd.AddCommand(NewCmdRolloutHistory(f, out))
|
||||
cmd.AddCommand(NewCmdRolloutPause(f, out))
|
||||
|
||||
@@ -70,7 +70,7 @@ func RunHistory(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []st
|
||||
}
|
||||
revisionDetail := cmdutil.GetFlagInt64(cmd, "revision")
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(false)
|
||||
|
||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||
if err != nil {
|
||||
|
||||
@@ -80,7 +80,7 @@ func (o *PauseConfig) CompletePause(f *cmdutil.Factory, cmd *cobra.Command, out
|
||||
return cmdutil.UsageError(cmd, cmd.Use)
|
||||
}
|
||||
|
||||
o.Mapper, o.Typer = f.Object()
|
||||
o.Mapper, o.Typer = f.Object(false)
|
||||
o.PauseObject = f.PauseObject
|
||||
o.Out = out
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ func (o *ResumeConfig) CompleteResume(f *cmdutil.Factory, cmd *cobra.Command, ou
|
||||
return cmdutil.UsageError(cmd, cmd.Use)
|
||||
}
|
||||
|
||||
o.Mapper, o.Typer = f.Object()
|
||||
o.Mapper, o.Typer = f.Object(false)
|
||||
o.ResumeObject = f.ResumeObject
|
||||
o.Out = out
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ func (o *UndoOptions) CompleteUndo(f *cmdutil.Factory, cmd *cobra.Command, out i
|
||||
}
|
||||
|
||||
o.ToRevision = cmdutil.GetFlagInt64(cmd, "to-revision")
|
||||
o.Mapper, o.Typer = f.Object()
|
||||
o.Mapper, o.Typer = f.Object(false)
|
||||
o.Out = out
|
||||
|
||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||
|
||||
@@ -87,6 +87,7 @@ func NewCmdRun(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *c
|
||||
addRunFlags(cmd)
|
||||
cmdutil.AddApplyAnnotationFlags(cmd)
|
||||
cmdutil.AddRecordFlag(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -256,7 +257,7 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, typer := f.Object()
|
||||
_, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
ContinueOnError().
|
||||
NamespaceParam(namespace).DefaultNamespace().
|
||||
@@ -270,7 +271,7 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob
|
||||
|
||||
outputFormat := cmdutil.GetFlagString(cmd, "output")
|
||||
if outputFormat != "" {
|
||||
return f.PrintObject(cmd, obj, cmdOut)
|
||||
return f.PrintObject(cmd, mapper, obj, cmdOut)
|
||||
}
|
||||
cmdutil.PrintSuccess(mapper, false, cmdOut, mapping.Resource, args[0], "created")
|
||||
return nil
|
||||
@@ -421,7 +422,7 @@ func generateService(f *cmdutil.Factory, cmd *cobra.Command, args []string, serv
|
||||
}
|
||||
|
||||
if cmdutil.GetFlagString(cmd, "output") != "" {
|
||||
return f.PrintObject(cmd, obj, out)
|
||||
return f.PrintObject(cmd, mapper, obj, out)
|
||||
}
|
||||
cmdutil.PrintSuccess(mapper, false, out, mapping.Resource, args[0], "created")
|
||||
|
||||
@@ -440,7 +441,7 @@ func createGeneratedObject(f *cmdutil.Factory, cmd *cobra.Command, generator kub
|
||||
return nil, "", nil, nil, err
|
||||
}
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
groupVersionKind, err := typer.ObjectKind(obj)
|
||||
if err != nil {
|
||||
return nil, "", nil, nil, err
|
||||
|
||||
@@ -302,6 +302,7 @@ func TestGenerateService(t *testing.T) {
|
||||
cmd.Flags().String("output", "", "")
|
||||
cmd.Flags().Bool(cmdutil.ApplyAnnotationsFlag, false, "")
|
||||
cmd.Flags().Bool("record", false, "Record current kubectl command in the resource annotation.")
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
addRunFlags(cmd)
|
||||
|
||||
if !test.expectPOST {
|
||||
|
||||
@@ -85,6 +85,7 @@ func NewCmdScale(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmd.Flags().Duration("timeout", 0, "The length of time to wait before giving up on a scale operation, zero means don't wait.")
|
||||
cmdutil.AddOutputFlagsForMutation(cmd)
|
||||
cmdutil.AddRecordFlag(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
|
||||
usage := "Filename, directory, or URL to a file identifying the resource to set a new size"
|
||||
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
|
||||
@@ -108,7 +109,7 @@ func RunScale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
|
||||
return err
|
||||
}
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
ContinueOnError().
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
|
||||
@@ -77,6 +77,7 @@ func NewCmdStop(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
cmd.Flags().Int("grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.")
|
||||
cmd.Flags().Duration("timeout", 0, "The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object")
|
||||
cmdutil.AddOutputFlagsForMutation(cmd)
|
||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -86,7 +87,7 @@ func RunStop(f *cmdutil.Factory, cmd *cobra.Command, args []string, out io.Write
|
||||
return err
|
||||
}
|
||||
|
||||
mapper, typer := f.Object()
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
ContinueOnError().
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
|
||||
@@ -39,6 +39,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/apimachinery"
|
||||
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
@@ -51,6 +52,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/runtime/serializer/json"
|
||||
utilflag "k8s.io/kubernetes/pkg/util/flag"
|
||||
@@ -69,8 +71,9 @@ type Factory struct {
|
||||
clients *ClientCache
|
||||
flags *pflag.FlagSet
|
||||
|
||||
// Returns interfaces for dealing with arbitrary runtime.Objects.
|
||||
Object func() (meta.RESTMapper, runtime.ObjectTyper)
|
||||
// Returns interfaces for dealing with arbitrary runtime.Objects. If thirdPartyDiscovery is true, performs API calls
|
||||
// to discovery dynamic API objects registered by third parties.
|
||||
Object func(thirdPartyDiscovery bool) (meta.RESTMapper, runtime.ObjectTyper)
|
||||
// Returns interfaces for decoding objects - if toInternal is set, decoded objects will be converted
|
||||
// into their internal form (if possible). Eventually the internal form will be removed as an option,
|
||||
// and only versioned objects will be returned.
|
||||
@@ -179,6 +182,31 @@ func DefaultGenerators(cmdName string) map[string]kubectl.Generator {
|
||||
return generators[cmdName]
|
||||
}
|
||||
|
||||
func getGroupVersionKinds(gvks []unversioned.GroupVersionKind, group string) []unversioned.GroupVersionKind {
|
||||
result := []unversioned.GroupVersionKind{}
|
||||
for ix := range gvks {
|
||||
if gvks[ix].Group == group {
|
||||
result = append(result, gvks[ix])
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func makeInterfacesFor(versionList []unversioned.GroupVersion) func(version unversioned.GroupVersion) (*meta.VersionInterfaces, error) {
|
||||
accessor := meta.NewAccessor()
|
||||
return func(version unversioned.GroupVersion) (*meta.VersionInterfaces, error) {
|
||||
for ix := range versionList {
|
||||
if versionList[ix].String() == version.String() {
|
||||
return &meta.VersionInterfaces{
|
||||
ObjectConvertor: thirdpartyresourcedata.NewThirdPartyObjectConverter(api.Scheme),
|
||||
MetadataAccessor: accessor,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, versionList)
|
||||
}
|
||||
}
|
||||
|
||||
// NewFactory creates a factory with the default Kubernetes resources defined
|
||||
// if optionalClientConfig is nil, then flags will be bound to a new clientcmd.ClientConfig.
|
||||
// if optionalClientConfig is not nil, then this factory will make use of it.
|
||||
@@ -199,17 +227,61 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
||||
clients: clients,
|
||||
flags: flags,
|
||||
|
||||
Object: func() (meta.RESTMapper, runtime.ObjectTyper) {
|
||||
// If discoverDynamicAPIs is true, make API calls to the discovery service to find APIs that
|
||||
// have been dynamically added to the apiserver
|
||||
Object: func(discoverDynamicAPIs bool) (meta.RESTMapper, runtime.ObjectTyper) {
|
||||
cfg, err := clientConfig.ClientConfig()
|
||||
CheckErr(err)
|
||||
cmdApiVersion := unversioned.GroupVersion{}
|
||||
if cfg.GroupVersion != nil {
|
||||
cmdApiVersion = *cfg.GroupVersion
|
||||
}
|
||||
if discoverDynamicAPIs {
|
||||
client, err := clients.ClientForVersion(&unversioned.GroupVersion{Version: "v1"})
|
||||
CheckErr(err)
|
||||
|
||||
versions, gvks, err := GetThirdPartyGroupVersions(client.Discovery())
|
||||
CheckErr(err)
|
||||
if len(versions) > 0 {
|
||||
priorityMapper, ok := mapper.RESTMapper.(meta.PriorityRESTMapper)
|
||||
if !ok {
|
||||
CheckErr(fmt.Errorf("expected PriorityMapper, saw: %v", mapper.RESTMapper))
|
||||
return nil, nil
|
||||
}
|
||||
multiMapper, ok := priorityMapper.Delegate.(meta.MultiRESTMapper)
|
||||
if !ok {
|
||||
CheckErr(fmt.Errorf("unexpected type: %v", mapper.RESTMapper))
|
||||
return nil, nil
|
||||
}
|
||||
groupsMap := map[string][]unversioned.GroupVersion{}
|
||||
for _, version := range versions {
|
||||
groupsMap[version.Group] = append(groupsMap[version.Group], version)
|
||||
}
|
||||
for group, versionList := range groupsMap {
|
||||
preferredExternalVersion := versionList[0]
|
||||
|
||||
thirdPartyMapper, err := kubectl.NewThirdPartyResourceMapper(versionList, getGroupVersionKinds(gvks, group))
|
||||
CheckErr(err)
|
||||
accessor := meta.NewAccessor()
|
||||
groupMeta := apimachinery.GroupMeta{
|
||||
GroupVersion: preferredExternalVersion,
|
||||
GroupVersions: versionList,
|
||||
RESTMapper: thirdPartyMapper,
|
||||
SelfLinker: runtime.SelfLinker(accessor),
|
||||
InterfacesFor: makeInterfacesFor(versionList),
|
||||
}
|
||||
|
||||
CheckErr(registered.RegisterGroup(groupMeta))
|
||||
registered.AddThirdPartyAPIGroupVersions(versionList...)
|
||||
multiMapper = append(meta.MultiRESTMapper{thirdPartyMapper}, multiMapper...)
|
||||
}
|
||||
priorityMapper.Delegate = multiMapper
|
||||
// Re-assign to the RESTMapper here because priorityMapper is actually a copy, so if we
|
||||
// don't re-assign, the above assignement won't actually update mapper.RESTMapper
|
||||
mapper.RESTMapper = priorityMapper
|
||||
}
|
||||
}
|
||||
outputRESTMapper := kubectl.OutputVersionMapper{RESTMapper: mapper, OutputVersions: []unversioned.GroupVersion{cmdApiVersion}}
|
||||
|
||||
// eventually this should allow me choose a group priority based on the order of the discovery doc, for now hardcode a given order
|
||||
priorityRESTMapper := meta.PriorityRESTMapper{
|
||||
Delegate: outputRESTMapper,
|
||||
ResourcePriority: []unversioned.GroupVersionResource{
|
||||
@@ -223,7 +295,6 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
||||
{Group: metrics.GroupName, Version: meta.AnyVersion, Kind: meta.AnyKind},
|
||||
},
|
||||
}
|
||||
|
||||
return priorityRESTMapper, api.Scheme
|
||||
},
|
||||
Client: func() (*client.Client, error) {
|
||||
@@ -233,22 +304,39 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
||||
return clients.ClientConfigForVersion(nil)
|
||||
},
|
||||
ClientForMapping: func(mapping *meta.RESTMapping) (resource.RESTClient, error) {
|
||||
gvk := mapping.GroupVersionKind
|
||||
mappingVersion := mapping.GroupVersionKind.GroupVersion()
|
||||
client, err := clients.ClientForVersion(&mappingVersion)
|
||||
c, err := clients.ClientForVersion(&mappingVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch mapping.GroupVersionKind.Group {
|
||||
switch gvk.Group {
|
||||
case api.GroupName:
|
||||
return client.RESTClient, nil
|
||||
return c.RESTClient, nil
|
||||
case autoscaling.GroupName:
|
||||
return client.AutoscalingClient.RESTClient, nil
|
||||
return c.AutoscalingClient.RESTClient, nil
|
||||
case batch.GroupName:
|
||||
return client.BatchClient.RESTClient, nil
|
||||
return c.BatchClient.RESTClient, nil
|
||||
case extensions.GroupName:
|
||||
return client.ExtensionsClient.RESTClient, nil
|
||||
return c.ExtensionsClient.RESTClient, nil
|
||||
case api.SchemeGroupVersion.Group:
|
||||
return c.RESTClient, nil
|
||||
case extensions.SchemeGroupVersion.Group:
|
||||
return c.ExtensionsClient.RESTClient, nil
|
||||
default:
|
||||
if !registered.IsThirdPartyAPIGroupVersion(gvk.GroupVersion()) {
|
||||
return nil, fmt.Errorf("unknown api group/version: %s", gvk.String())
|
||||
}
|
||||
cfg, err := clientConfig.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gv := gvk.GroupVersion()
|
||||
cfg.GroupVersion = &gv
|
||||
cfg.APIPath = "/apis"
|
||||
cfg.Codec = thirdpartyresourcedata.NewCodec(c.ExtensionsClient.RESTClient.Codec(), gvk.Kind)
|
||||
return restclient.RESTClientFor(cfg)
|
||||
}
|
||||
return nil, fmt.Errorf("unable to get RESTClient for resource '%s'", mapping.Resource)
|
||||
},
|
||||
Describer: func(mapping *meta.RESTMapping) (kubectl.Describer, error) {
|
||||
mappingVersion := mapping.GroupVersionKind.GroupVersion()
|
||||
@@ -810,6 +898,10 @@ func (c *clientSwaggerSchema) ValidateBytes(data []byte) error {
|
||||
}
|
||||
return getSchemaAndValidate(c.c.BatchClient.RESTClient, data, "apis/", gvk.GroupVersion().String(), c.cacheDir)
|
||||
}
|
||||
if registered.IsThirdPartyAPIGroupVersion(gvk.GroupVersion()) {
|
||||
// Don't attempt to validate third party objects
|
||||
return nil
|
||||
}
|
||||
if gvk.Group == extensions.GroupName {
|
||||
if c.c.ExtensionsClient == nil {
|
||||
return errors.New("unable to validate: no experimental client")
|
||||
@@ -874,8 +966,7 @@ func DefaultClientConfig(flags *pflag.FlagSet) clientcmd.ClientConfig {
|
||||
}
|
||||
|
||||
// PrintObject prints an api object given command line flags to modify the output format
|
||||
func (f *Factory) PrintObject(cmd *cobra.Command, obj runtime.Object, out io.Writer) error {
|
||||
mapper, _ := f.Object()
|
||||
func (f *Factory) PrintObject(cmd *cobra.Command, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error {
|
||||
gvk, err := api.Scheme.ObjectKind(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -936,8 +1027,8 @@ func (f *Factory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMappin
|
||||
}
|
||||
|
||||
// One stop shopping for a Builder
|
||||
func (f *Factory) NewBuilder() *resource.Builder {
|
||||
mapper, typer := f.Object()
|
||||
func (f *Factory) NewBuilder(thirdPartyDiscovery bool) *resource.Builder {
|
||||
mapper, typer := f.Object(thirdPartyDiscovery)
|
||||
|
||||
return resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true))
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||
"k8s.io/kubernetes/pkg/client/typed/discovery"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
@@ -514,3 +516,53 @@ func ContainsChangeCause(info *resource.Info) bool {
|
||||
func ShouldRecord(cmd *cobra.Command, info *resource.Info) bool {
|
||||
return GetRecordFlag(cmd) || ContainsChangeCause(info)
|
||||
}
|
||||
|
||||
func GetThirdPartyGroupVersions(discovery discovery.DiscoveryInterface) ([]unversioned.GroupVersion, []unversioned.GroupVersionKind, error) {
|
||||
result := []unversioned.GroupVersion{}
|
||||
gvks := []unversioned.GroupVersionKind{}
|
||||
|
||||
groupList, err := discovery.ServerGroups()
|
||||
if err != nil {
|
||||
// On forbidden or not found, just return empty lists.
|
||||
if errors.IsForbidden(err) || errors.IsNotFound(err) {
|
||||
return result, gvks, nil
|
||||
}
|
||||
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
for ix := range groupList.Groups {
|
||||
group := &groupList.Groups[ix]
|
||||
for jx := range group.Versions {
|
||||
gv, err2 := unversioned.ParseGroupVersion(group.Versions[jx].GroupVersion)
|
||||
if err2 != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Skip GroupVersionKinds that have been statically registered.
|
||||
if registered.IsRegisteredVersion(gv) {
|
||||
continue
|
||||
}
|
||||
result = append(result, gv)
|
||||
|
||||
resourceList, err := discovery.ServerResourcesForGroupVersion(group.Versions[jx].GroupVersion)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
for kx := range resourceList.APIResources {
|
||||
gvks = append(gvks, gv.WithKind(resourceList.APIResources[kx].Kind))
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, gvks, nil
|
||||
}
|
||||
|
||||
func GetIncludeThirdPartyAPIs(cmd *cobra.Command) bool {
|
||||
if cmd.Flags().Lookup("include-extended-apis") == nil {
|
||||
return false
|
||||
}
|
||||
return GetFlagBool(cmd, "include-extended-apis")
|
||||
}
|
||||
|
||||
func AddInclude3rdPartyFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().Bool("include-extended-apis", true, "If true, include definitions of new APIs via calls to the API server. [default true]")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user