From 087140aee9c001fd6c56eb3f4f9a7b808d6384d0 Mon Sep 17 00:00:00 2001 From: David Eads Date: Mon, 21 May 2018 16:06:58 -0400 Subject: [PATCH] move updatepodspecforobject out of factory --- pkg/kubectl/cmd/set/BUILD | 1 + pkg/kubectl/cmd/set/set_env.go | 5 +- pkg/kubectl/cmd/set/set_image.go | 5 +- pkg/kubectl/cmd/set/set_resources.go | 5 +- pkg/kubectl/cmd/set/set_serviceaccount.go | 5 +- pkg/kubectl/cmd/util/BUILD | 2 - pkg/kubectl/cmd/util/factory.go | 5 - pkg/kubectl/cmd/util/factory_client_access.go | 64 ------------- pkg/kubectl/polymorphichelpers/BUILD | 3 + pkg/kubectl/polymorphichelpers/interface.go | 8 ++ .../polymorphichelpers/updatepodspec.go | 91 +++++++++++++++++++ 11 files changed, 115 insertions(+), 79 deletions(-) create mode 100644 pkg/kubectl/polymorphichelpers/updatepodspec.go diff --git a/pkg/kubectl/cmd/set/BUILD b/pkg/kubectl/cmd/set/BUILD index 161f7ac79a9..c96b85e7cef 100644 --- a/pkg/kubectl/cmd/set/BUILD +++ b/pkg/kubectl/cmd/set/BUILD @@ -26,6 +26,7 @@ go_library( "//pkg/kubectl/cmd/util/env:go_default_library", "//pkg/kubectl/genericclioptions:go_default_library", "//pkg/kubectl/genericclioptions/resource:go_default_library", + "//pkg/kubectl/polymorphichelpers:go_default_library", "//pkg/kubectl/scheme:go_default_library", "//pkg/kubectl/util/i18n:go_default_library", "//pkg/printers:go_default_library", diff --git a/pkg/kubectl/cmd/set/set_env.go b/pkg/kubectl/cmd/set/set_env.go index 90f2f22f92b..eba08dc03fc 100644 --- a/pkg/kubectl/cmd/set/set_env.go +++ b/pkg/kubectl/cmd/set/set_env.go @@ -35,6 +35,7 @@ import ( envutil "k8s.io/kubernetes/pkg/kubectl/cmd/util/env" "k8s.io/kubernetes/pkg/kubectl/genericclioptions" "k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" + "k8s.io/kubernetes/pkg/kubectl/polymorphichelpers" "k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/printers" ) @@ -114,7 +115,7 @@ type EnvOptions struct { output string dryRun bool builder func() *resource.Builder - updatePodSpecForObject func(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error) + updatePodSpecForObject polymorphichelpers.UpdatePodSpecForObjectFunc namespace string enforceNamespace bool clientset *kubernetes.Clientset @@ -192,7 +193,7 @@ func (o *EnvOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri return fmt.Errorf("all resources must be specified before environment changes: %s", strings.Join(args, " ")) } - o.updatePodSpecForObject = f.UpdatePodSpecForObject + o.updatePodSpecForObject = polymorphichelpers.UpdatePodSpecForObjectFn o.output = cmdutil.GetFlagString(cmd, "output") o.dryRun = cmdutil.GetDryRunFlag(cmd) diff --git a/pkg/kubectl/cmd/set/set_image.go b/pkg/kubectl/cmd/set/set_image.go index 76dd52646b7..57ae09a5b3a 100644 --- a/pkg/kubectl/cmd/set/set_image.go +++ b/pkg/kubectl/cmd/set/set_image.go @@ -30,6 +30,7 @@ import ( cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/genericclioptions" "k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" + "k8s.io/kubernetes/pkg/kubectl/polymorphichelpers" "k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/printers" @@ -54,7 +55,7 @@ type SetImageOptions struct { PrintObj printers.ResourcePrinterFunc Recorder genericclioptions.Recorder - UpdatePodSpecForObject func(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error) + UpdatePodSpecForObject polymorphichelpers.UpdatePodSpecForObjectFunc Resources []string ContainerImages map[string]string @@ -134,7 +135,7 @@ func (o *SetImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [ return err } - o.UpdatePodSpecForObject = f.UpdatePodSpecForObject + o.UpdatePodSpecForObject = polymorphichelpers.UpdatePodSpecForObjectFn o.DryRun = cmdutil.GetDryRunFlag(cmd) o.Output = cmdutil.GetFlagString(cmd, "output") o.ResolveImage = f.ResolveImage diff --git a/pkg/kubectl/cmd/set/set_resources.go b/pkg/kubectl/cmd/set/set_resources.go index 0fd6bc5b310..6f83109a176 100644 --- a/pkg/kubectl/cmd/set/set_resources.go +++ b/pkg/kubectl/cmd/set/set_resources.go @@ -34,6 +34,7 @@ import ( cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/genericclioptions" "k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" + "k8s.io/kubernetes/pkg/kubectl/polymorphichelpers" "k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/util/i18n" ) @@ -84,7 +85,7 @@ type SetResourcesOptions struct { Requests string ResourceRequirements v1.ResourceRequirements - UpdatePodSpecForObject func(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error) + UpdatePodSpecForObject polymorphichelpers.UpdatePodSpecForObjectFunc Resources []string genericclioptions.IOStreams @@ -153,7 +154,7 @@ func (o *SetResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, ar return err } - o.UpdatePodSpecForObject = f.UpdatePodSpecForObject + o.UpdatePodSpecForObject = polymorphichelpers.UpdatePodSpecForObjectFn o.Output = cmdutil.GetFlagString(cmd, "output") o.DryRun = cmdutil.GetDryRunFlag(cmd) diff --git a/pkg/kubectl/cmd/set/set_serviceaccount.go b/pkg/kubectl/cmd/set/set_serviceaccount.go index d06184ddee1..e3706ab43f6 100644 --- a/pkg/kubectl/cmd/set/set_serviceaccount.go +++ b/pkg/kubectl/cmd/set/set_serviceaccount.go @@ -33,6 +33,7 @@ import ( cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/genericclioptions" "k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" + "k8s.io/kubernetes/pkg/kubectl/polymorphichelpers" "k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/util/i18n" ) @@ -67,7 +68,7 @@ type SetServiceAccountOptions struct { all bool output string local bool - updatePodSpecForObject func(runtime.Object, func(*v1.PodSpec) error) (bool, error) + updatePodSpecForObject polymorphichelpers.UpdatePodSpecForObjectFunc infos []*resource.Info serviceAccountName string @@ -130,7 +131,7 @@ func (o *SetServiceAccountOptions) Complete(f cmdutil.Factory, cmd *cobra.Comman o.shortOutput = cmdutil.GetFlagString(cmd, "output") == "name" o.dryRun = cmdutil.GetDryRunFlag(cmd) o.output = cmdutil.GetFlagString(cmd, "output") - o.updatePodSpecForObject = f.UpdatePodSpecForObject + o.updatePodSpecForObject = polymorphichelpers.UpdatePodSpecForObjectFn if o.dryRun { o.PrintFlags.Complete("%s (dry run)") diff --git a/pkg/kubectl/cmd/util/BUILD b/pkg/kubectl/cmd/util/BUILD index eca56bc1cbb..41cba673fa6 100644 --- a/pkg/kubectl/cmd/util/BUILD +++ b/pkg/kubectl/cmd/util/BUILD @@ -36,11 +36,9 @@ go_library( "//vendor/github.com/spf13/pflag:go_default_library", "//vendor/k8s.io/api/apps/v1:go_default_library", "//vendor/k8s.io/api/apps/v1beta1:go_default_library", - "//vendor/k8s.io/api/apps/v1beta2:go_default_library", "//vendor/k8s.io/api/batch/v1:go_default_library", "//vendor/k8s.io/api/batch/v1beta1:go_default_library", "//vendor/k8s.io/api/batch/v2alpha1:go_default_library", - "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/api/extensions/v1beta1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index 8f867553028..f42f80560e8 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -23,7 +23,6 @@ import ( "github.com/spf13/cobra" - "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -79,10 +78,6 @@ type ClientAccessFactory interface { // and which implements the common patterns for CLI interactions with generic resources. NewBuilder() *resource.Builder - // UpdatePodSpecForObject will call the provided function on the pod spec this object supports, - // return false if no pod spec is supported, or return an error. - UpdatePodSpecForObject(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error) - // MapBasedSelectorForObject returns the map-based selector associated with the provided object. If a // new set-based selector is provided, an error is returned if the selector cannot be converted to a // map-based selector diff --git a/pkg/kubectl/cmd/util/factory_client_access.go b/pkg/kubectl/cmd/util/factory_client_access.go index 55ffc2bb3cb..519021d919b 100644 --- a/pkg/kubectl/cmd/util/factory_client_access.go +++ b/pkg/kubectl/cmd/util/factory_client_access.go @@ -26,14 +26,11 @@ import ( "path/filepath" "strings" - "k8s.io/api/core/v1" - "github.com/spf13/cobra" "github.com/spf13/pflag" appsv1 "k8s.io/api/apps/v1" appsv1beta1 "k8s.io/api/apps/v1beta1" - appsv1beta2 "k8s.io/api/apps/v1beta2" batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" batchv2alpha1 "k8s.io/api/batch/v2alpha1" @@ -129,67 +126,6 @@ func (f *ring0Factory) RESTClient() (*restclient.RESTClient, error) { return restclient.RESTClientFor(clientConfig) } -func (f *ring0Factory) UpdatePodSpecForObject(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error) { - // TODO: replace with a swagger schema based approach (identify pod template via schema introspection) - switch t := obj.(type) { - case *v1.Pod: - return true, fn(&t.Spec) - // ReplicationController - case *v1.ReplicationController: - if t.Spec.Template == nil { - t.Spec.Template = &v1.PodTemplateSpec{} - } - return true, fn(&t.Spec.Template.Spec) - - // Deployment - case *extensionsv1beta1.Deployment: - return true, fn(&t.Spec.Template.Spec) - case *appsv1beta1.Deployment: - return true, fn(&t.Spec.Template.Spec) - case *appsv1beta2.Deployment: - return true, fn(&t.Spec.Template.Spec) - case *appsv1.Deployment: - return true, fn(&t.Spec.Template.Spec) - - // DaemonSet - case *extensionsv1beta1.DaemonSet: - return true, fn(&t.Spec.Template.Spec) - case *appsv1beta2.DaemonSet: - return true, fn(&t.Spec.Template.Spec) - case *appsv1.DaemonSet: - return true, fn(&t.Spec.Template.Spec) - - // ReplicaSet - case *extensionsv1beta1.ReplicaSet: - return true, fn(&t.Spec.Template.Spec) - case *appsv1beta2.ReplicaSet: - return true, fn(&t.Spec.Template.Spec) - case *appsv1.ReplicaSet: - return true, fn(&t.Spec.Template.Spec) - - // StatefulSet - case *appsv1beta1.StatefulSet: - return true, fn(&t.Spec.Template.Spec) - case *appsv1beta2.StatefulSet: - return true, fn(&t.Spec.Template.Spec) - case *appsv1.StatefulSet: - return true, fn(&t.Spec.Template.Spec) - - // Job - case *batchv1.Job: - return true, fn(&t.Spec.Template.Spec) - - // CronJob - case *batchv1beta1.CronJob: - return true, fn(&t.Spec.JobTemplate.Spec.Template.Spec) - case *batchv2alpha1.CronJob: - return true, fn(&t.Spec.JobTemplate.Spec.Template.Spec) - - default: - return false, fmt.Errorf("the object is not a pod or does not have a pod template: %T", t) - } -} - func (f *ring0Factory) MapBasedSelectorForObject(object runtime.Object) (string, error) { // TODO: replace with a swagger schema based approach (identify pod selector via schema introspection) switch t := object.(type) { diff --git a/pkg/kubectl/polymorphichelpers/BUILD b/pkg/kubectl/polymorphichelpers/BUILD index cf624a54558..1feaaf523b1 100644 --- a/pkg/kubectl/polymorphichelpers/BUILD +++ b/pkg/kubectl/polymorphichelpers/BUILD @@ -9,6 +9,7 @@ go_library( "interface.go", "logsforobject.go", "statusviewer.go", + "updatepodspec.go", ], importpath = "k8s.io/kubernetes/pkg/kubectl/polymorphichelpers", visibility = ["//visibility:public"], @@ -27,6 +28,8 @@ go_library( "//vendor/k8s.io/api/apps/v1beta1:go_default_library", "//vendor/k8s.io/api/apps/v1beta2:go_default_library", "//vendor/k8s.io/api/batch/v1:go_default_library", + "//vendor/k8s.io/api/batch/v1beta1:go_default_library", + "//vendor/k8s.io/api/batch/v2alpha1:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/api/extensions/v1beta1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", diff --git a/pkg/kubectl/polymorphichelpers/interface.go b/pkg/kubectl/polymorphichelpers/interface.go index 63e1006318a..3029730742e 100644 --- a/pkg/kubectl/polymorphichelpers/interface.go +++ b/pkg/kubectl/polymorphichelpers/interface.go @@ -19,6 +19,7 @@ package polymorphichelpers import ( "time" + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/rest" @@ -50,3 +51,10 @@ type StatusViewerFunc func(restClientGetter genericclioptions.RESTClientGetter, // StatusViewerFn gives a way to easily override the function for unit testing if needed var StatusViewerFn StatusViewerFunc = statusViewer + +// UpdatePodSpecForObjectFunc will call the provided function on the pod spec this object supports, +// return false if no pod spec is supported, or return an error. +type UpdatePodSpecForObjectFunc func(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error) + +// UpdatePodSpecForObjectFn gives a way to easily override the function for unit testing if needed +var UpdatePodSpecForObjectFn UpdatePodSpecForObjectFunc = updatePodSpecForObject diff --git a/pkg/kubectl/polymorphichelpers/updatepodspec.go b/pkg/kubectl/polymorphichelpers/updatepodspec.go new file mode 100644 index 00000000000..40448638246 --- /dev/null +++ b/pkg/kubectl/polymorphichelpers/updatepodspec.go @@ -0,0 +1,91 @@ +/* +Copyright 2018 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 polymorphichelpers + +import ( + "fmt" + + appsv1 "k8s.io/api/apps/v1" + appsv1beta1 "k8s.io/api/apps/v1beta1" + appsv1beta2 "k8s.io/api/apps/v1beta2" + batchv1 "k8s.io/api/batch/v1" + batchv1beta1 "k8s.io/api/batch/v1beta1" + batchv2alpha1 "k8s.io/api/batch/v2alpha1" + "k8s.io/api/core/v1" + extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + "k8s.io/apimachinery/pkg/runtime" +) + +func updatePodSpecForObject(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error) { + switch t := obj.(type) { + case *v1.Pod: + return true, fn(&t.Spec) + // ReplicationController + case *v1.ReplicationController: + if t.Spec.Template == nil { + t.Spec.Template = &v1.PodTemplateSpec{} + } + return true, fn(&t.Spec.Template.Spec) + + // Deployment + case *extensionsv1beta1.Deployment: + return true, fn(&t.Spec.Template.Spec) + case *appsv1beta1.Deployment: + return true, fn(&t.Spec.Template.Spec) + case *appsv1beta2.Deployment: + return true, fn(&t.Spec.Template.Spec) + case *appsv1.Deployment: + return true, fn(&t.Spec.Template.Spec) + + // DaemonSet + case *extensionsv1beta1.DaemonSet: + return true, fn(&t.Spec.Template.Spec) + case *appsv1beta2.DaemonSet: + return true, fn(&t.Spec.Template.Spec) + case *appsv1.DaemonSet: + return true, fn(&t.Spec.Template.Spec) + + // ReplicaSet + case *extensionsv1beta1.ReplicaSet: + return true, fn(&t.Spec.Template.Spec) + case *appsv1beta2.ReplicaSet: + return true, fn(&t.Spec.Template.Spec) + case *appsv1.ReplicaSet: + return true, fn(&t.Spec.Template.Spec) + + // StatefulSet + case *appsv1beta1.StatefulSet: + return true, fn(&t.Spec.Template.Spec) + case *appsv1beta2.StatefulSet: + return true, fn(&t.Spec.Template.Spec) + case *appsv1.StatefulSet: + return true, fn(&t.Spec.Template.Spec) + + // Job + case *batchv1.Job: + return true, fn(&t.Spec.Template.Spec) + + // CronJob + case *batchv1beta1.CronJob: + return true, fn(&t.Spec.JobTemplate.Spec.Template.Spec) + case *batchv2alpha1.CronJob: + return true, fn(&t.Spec.JobTemplate.Spec.Template.Spec) + + default: + return false, fmt.Errorf("the object is not a pod or does not have a pod template: %T", t) + } +}