diff --git a/pkg/kubectl/cmd/BUILD b/pkg/kubectl/cmd/BUILD index c9d981029d..3f60d639fc 100644 --- a/pkg/kubectl/cmd/BUILD +++ b/pkg/kubectl/cmd/BUILD @@ -106,10 +106,8 @@ go_library( "//vendor/github.com/renstrom/dedent:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", - "//vendor/k8s.io/api/apps/v1beta1: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", @@ -134,7 +132,6 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/version:go_default_library", "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library", "//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library", - "//vendor/k8s.io/client-go/discovery:go_default_library", "//vendor/k8s.io/client-go/rest:go_default_library", "//vendor/k8s.io/client-go/tools/clientcmd:go_default_library", "//vendor/k8s.io/client-go/tools/portforward:go_default_library", diff --git a/pkg/kubectl/cmd/create_deployment.go b/pkg/kubectl/cmd/create_deployment.go index eba52bed39..15071837e4 100644 --- a/pkg/kubectl/cmd/create_deployment.go +++ b/pkg/kubectl/cmd/create_deployment.go @@ -22,8 +22,6 @@ import ( "github.com/spf13/cobra" - appsv1beta1 "k8s.io/api/apps/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -63,35 +61,6 @@ func NewCmdCreateDeployment(f cmdutil.Factory, cmdOut, cmdErr io.Writer) *cobra. return cmd } -// fallbackGeneratorNameIfNecessary returns the name of the old generator -// (v1beta1) if server does not support apps/v1beta1 deployments. Otherwise, the -// generator string is returned unchanged. -// -// If the generator name is changed, print a warning message to let the user -// know. -func fallbackGeneratorNameIfNecessary( - generatorName string, - resourcesList []*metav1.APIResourceList, - cmdErr io.Writer, -) string { - - if generatorName == cmdutil.DeploymentBasicAppsV1Beta1GeneratorName && - !contains(resourcesList, appsv1beta1.SchemeGroupVersion.WithResource("deployments")) { - - fmt.Fprintf(cmdErr, - "WARNING: New deployments generator %q specified, "+ - "but apps/v1beta1.Deployments are not available. "+ - "Falling back to %q.\n", - cmdutil.DeploymentBasicAppsV1Beta1GeneratorName, - cmdutil.DeploymentBasicV1Beta1GeneratorName, - ) - - return cmdutil.DeploymentBasicV1Beta1GeneratorName - } - - return generatorName -} - // generatorFromName returns the appropriate StructuredGenerator based on the // generatorName. If the generatorName is unrecognized, then return (nil, // false). @@ -150,7 +119,7 @@ func createDeployment(f cmdutil.Factory, cmdOut, cmdErr io.Writer, // It is possible we have to modify the user-provided generator name if // the server does not have support for the requested generator. - generatorName = fallbackGeneratorNameIfNecessary(generatorName, resourcesList, cmdErr) + generatorName = cmdutil.FallbackGeneratorNameIfNecessary(generatorName, resourcesList, cmdErr) imageNames := cmdutil.GetFlagStringSlice(cmd, "image") generator, ok := generatorFromName(generatorName, imageNames, deploymentName) diff --git a/pkg/kubectl/cmd/run.go b/pkg/kubectl/cmd/run.go index 6100002740..ed62ad54ca 100644 --- a/pkg/kubectl/cmd/run.go +++ b/pkg/kubectl/cmd/run.go @@ -25,15 +25,12 @@ import ( batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" - batchv2alpha1 "k8s.io/api/batch/v2alpha1" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/discovery" "k8s.io/kubernetes/pkg/api" coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" conditions "k8s.io/kubernetes/pkg/client/unversioned" @@ -226,7 +223,7 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c generatorName := cmdutil.GetFlagString(cmd, "generator") schedule := cmdutil.GetFlagString(cmd, "schedule") if len(schedule) != 0 && len(generatorName) == 0 { - if contains(resourcesList, batchv1beta1.SchemeGroupVersion.WithResource("cronjobs")) { + if cmdutil.Contains(resourcesList, batchv1beta1.SchemeGroupVersion.WithResource("cronjobs")) { generatorName = cmdutil.CronJobV1Beta1GeneratorName } else { generatorName = cmdutil.CronJobV2Alpha1GeneratorName @@ -237,13 +234,13 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c case api.RestartPolicyAlways: // TODO: we need to deprecate this along with extensions/v1beta1.Deployments // in favor of the new generator for apps/v1beta1.Deployments - if contains(resourcesList, extensionsv1beta1.SchemeGroupVersion.WithResource("deployments")) { + if cmdutil.Contains(resourcesList, extensionsv1beta1.SchemeGroupVersion.WithResource("deployments")) { generatorName = cmdutil.DeploymentV1Beta1GeneratorName } else { generatorName = cmdutil.RunV1GeneratorName } case api.RestartPolicyOnFailure: - if contains(resourcesList, batchv1.SchemeGroupVersion.WithResource("jobs")) { + if cmdutil.Contains(resourcesList, batchv1.SchemeGroupVersion.WithResource("jobs")) { generatorName = cmdutil.JobV1GeneratorName } else { generatorName = cmdutil.RunPodV1GeneratorName @@ -253,13 +250,7 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c } } - // TODO: this should be removed alongside with extensions/v1beta1 depployments generator - generatorName = fallbackGeneratorNameIfNecessary(generatorName, resourcesList, cmdErr) - - if generatorName == cmdutil.CronJobV2Alpha1GeneratorName && - !contains(resourcesList, batchv2alpha1.SchemeGroupVersion.WithResource("cronjobs")) { - return fmt.Errorf("CronJob generator specified, but batch/v2alpha1.CronJobs are not available") - } + generatorName = cmdutil.FallbackGeneratorNameIfNecessary(generatorName, resourcesList, cmdErr) generators := f.Generators("run") generator, found := generators[generatorName] @@ -407,14 +398,6 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c return nil } -// TODO turn this into reusable method checking available resources -func contains(resourcesList []*metav1.APIResourceList, resource schema.GroupVersionResource) bool { - resources := discovery.FilteredBy(discovery.ResourcePredicateFunc(func(gv string, r *metav1.APIResource) bool { - return resource.GroupVersion().String() == gv && resource.Resource == r.Name - }), resourcesList) - return len(resources) != 0 -} - // waitForPod watches the given pod until the exitCondition is true func waitForPod(podClient coreclient.PodsGetter, ns, name string, exitCondition watch.ConditionFunc) (*api.Pod, error) { w, err := podClient.Pods(ns).Watch(metav1.SingleObject(metav1.ObjectMeta{Name: name})) diff --git a/pkg/kubectl/cmd/util/BUILD b/pkg/kubectl/cmd/util/BUILD index 180988c990..c94acee13d 100644 --- a/pkg/kubectl/cmd/util/BUILD +++ b/pkg/kubectl/cmd/util/BUILD @@ -47,6 +47,8 @@ go_library( "//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/api/apps/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/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_client_access.go b/pkg/kubectl/cmd/util/factory_client_access.go index 5484eeb0ef..6278b5a696 100644 --- a/pkg/kubectl/cmd/util/factory_client_access.go +++ b/pkg/kubectl/cmd/util/factory_client_access.go @@ -32,7 +32,10 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" + appsv1beta1 "k8s.io/api/apps/v1beta1" + batchv2alpha1 "k8s.io/api/batch/v2alpha1" "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilflag "k8s.io/apiserver/pkg/util/flag" @@ -571,6 +574,50 @@ func DefaultGenerators(cmdName string) map[string]kubectl.Generator { return generator } +// fallbackGeneratorNameIfNecessary returns the name of the old generator +// if server does not support new generator. Otherwise, the +// generator string is returned unchanged. +// +// If the generator name is changed, print a warning message to let the user +// know. +func FallbackGeneratorNameIfNecessary( + generatorName string, + resourcesList []*metav1.APIResourceList, + cmdErr io.Writer, +) string { + switch generatorName { + case DeploymentBasicAppsV1Beta1GeneratorName: + if !Contains(resourcesList, appsv1beta1.SchemeGroupVersion.WithResource("deployments")) { + warning(cmdErr, DeploymentBasicAppsV1Beta1GeneratorName, DeploymentBasicV1Beta1GeneratorName) + + return DeploymentBasicV1Beta1GeneratorName + } + case CronJobV2Alpha1GeneratorName: + if !Contains(resourcesList, batchv2alpha1.SchemeGroupVersion.WithResource("cronjobs")) { + warning(cmdErr, CronJobV2Alpha1GeneratorName, JobV1GeneratorName) + + return JobV1GeneratorName + } + } + return generatorName +} + +func warning(cmdErr io.Writer, newGeneratorName, oldGeneratorName string) { + fmt.Fprintf(cmdErr, "WARNING: New deployments generator %q specified, "+ + "but it isn't available. "+ + "Falling back to %q.\n", + newGeneratorName, + oldGeneratorName, + ) +} + +func Contains(resourcesList []*metav1.APIResourceList, resource schema.GroupVersionResource) bool { + resources := discovery.FilteredBy(discovery.ResourcePredicateFunc(func(gv string, r *metav1.APIResource) bool { + return resource.GroupVersion().String() == gv && resource.Resource == r.Name + }), resourcesList) + return len(resources) != 0 +} + func (f *ring0Factory) Generators(cmdName string) map[string]kubectl.Generator { return DefaultGenerators(cmdName) }