From 8b90dbdd4410e94fb5e45cf28a84c8e9527429b6 Mon Sep 17 00:00:00 2001 From: Maciej Szulik Date: Thu, 29 Apr 2021 15:06:41 +0200 Subject: [PATCH 1/2] Drop cronjob beta API from create command --- .../kubectl/pkg/cmd/create/create_cronjob.go | 103 +----------------- .../kubectl/pkg/cmd/create/create_job.go | 37 +------ .../kubectl/pkg/cmd/create/create_job_test.go | 69 +----------- 3 files changed, 8 insertions(+), 201 deletions(-) diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_cronjob.go b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_cronjob.go index f0b672c490d..76f88da7929 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_cronjob.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_cronjob.go @@ -23,14 +23,12 @@ import ( "github.com/spf13/cobra" batchv1 "k8s.io/api/batch/v1" - batchv1beta1 "k8s.io/api/batch/v1beta1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/resource" batchv1client "k8s.io/client-go/kubernetes/typed/batch/v1" - batchv1beta1client "k8s.io/client-go/kubernetes/typed/batch/v1beta1" cmdutil "k8s.io/kubectl/pkg/cmd/util" "k8s.io/kubectl/pkg/scheme" "k8s.io/kubectl/pkg/util" @@ -64,7 +62,6 @@ type CreateCronJobOptions struct { Namespace string EnforceNamespace bool - ClientBeta batchv1beta1client.BatchV1beta1Interface Client batchv1client.BatchV1Interface DryRunStrategy cmdutil.DryRunStrategy DryRunVerifier *resource.DryRunVerifier @@ -132,34 +129,10 @@ func (o *CreateCronJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, a if err != nil { return err } - - // TODO: drop this condition when beta disappears in 1.25 - clientset, err := f.KubernetesClientSet() + o.Client, err = batchv1client.NewForConfig(clientConfig) if err != nil { return err } - resources, err := clientset.Discovery().ServerResourcesForGroupVersion(batchv1.SchemeGroupVersion.String()) - if err != nil { - return fmt.Errorf("failed to discover supported resources: %v", err) - } - found := false - for _, serverResource := range resources.APIResources { - if serverResource.Name == "cronjobs" { - found = true - break - } - } - if found { - o.Client, err = batchv1client.NewForConfig(clientConfig) - if err != nil { - return err - } - } else { - o.ClientBeta, err = batchv1beta1client.NewForConfig(clientConfig) - if err != nil { - return err - } - } o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace() if err != nil { @@ -192,36 +165,8 @@ func (o *CreateCronJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, a // Run performs the execution of 'create cronjob' sub command func (o *CreateCronJobOptions) Run() error { - if o.Client != nil { - cronJob := o.createCronJob() - if err := util.CreateOrUpdateAnnotation(o.CreateAnnotation, cronJob, scheme.DefaultJSONEncoder()); err != nil { - return err - } - - if o.DryRunStrategy != cmdutil.DryRunClient { - createOptions := metav1.CreateOptions{} - if o.FieldManager != "" { - createOptions.FieldManager = o.FieldManager - } - if o.DryRunStrategy == cmdutil.DryRunServer { - if err := o.DryRunVerifier.HasSupport(cronJob.GroupVersionKind()); err != nil { - return err - } - createOptions.DryRun = []string{metav1.DryRunAll} - } - var err error - cronJob, err = o.Client.CronJobs(o.Namespace).Create(context.TODO(), cronJob, createOptions) - if err != nil { - return fmt.Errorf("failed to create cronjob: %v", err) - } - } - - return o.PrintObj(cronJob) - } - - // TODO: drop this condition when beta disappears in 1.25 - cronJobBeta := o.createCronJobBeta() - if err := util.CreateOrUpdateAnnotation(o.CreateAnnotation, cronJobBeta, scheme.DefaultJSONEncoder()); err != nil { + cronJob := o.createCronJob() + if err := util.CreateOrUpdateAnnotation(o.CreateAnnotation, cronJob, scheme.DefaultJSONEncoder()); err != nil { return err } @@ -231,55 +176,19 @@ func (o *CreateCronJobOptions) Run() error { createOptions.FieldManager = o.FieldManager } if o.DryRunStrategy == cmdutil.DryRunServer { - if err := o.DryRunVerifier.HasSupport(cronJobBeta.GroupVersionKind()); err != nil { + if err := o.DryRunVerifier.HasSupport(cronJob.GroupVersionKind()); err != nil { return err } createOptions.DryRun = []string{metav1.DryRunAll} } var err error - cronJobBeta, err = o.ClientBeta.CronJobs(o.Namespace).Create(context.TODO(), cronJobBeta, createOptions) + cronJob, err = o.Client.CronJobs(o.Namespace).Create(context.TODO(), cronJob, createOptions) if err != nil { return fmt.Errorf("failed to create cronjob: %v", err) } } - return o.PrintObj(cronJobBeta) - -} - -func (o *CreateCronJobOptions) createCronJobBeta() *batchv1beta1.CronJob { - cronjob := &batchv1beta1.CronJob{ - TypeMeta: metav1.TypeMeta{APIVersion: batchv1beta1.SchemeGroupVersion.String(), Kind: "CronJob"}, - ObjectMeta: metav1.ObjectMeta{ - Name: o.Name, - }, - Spec: batchv1beta1.CronJobSpec{ - Schedule: o.Schedule, - JobTemplate: batchv1beta1.JobTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Name: o.Name, - }, - Spec: batchv1.JobSpec{ - Template: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: o.Name, - Image: o.Image, - Command: o.Command, - }, - }, - RestartPolicy: corev1.RestartPolicy(o.Restart), - }, - }, - }, - }, - }, - } - if o.EnforceNamespace { - cronjob.Namespace = o.Namespace - } - return cronjob + return o.PrintObj(cronJob) } func (o *CreateCronJobOptions) createCronJob() *batchv1.CronJob { diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_job.go b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_job.go index 41ed9d09a56..57a177fdde4 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_job.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_job.go @@ -23,7 +23,6 @@ import ( "github.com/spf13/cobra" batchv1 "k8s.io/api/batch/v1" - batchv1beta1 "k8s.io/api/batch/v1beta1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -194,8 +193,6 @@ func (o *CreateJobOptions) Run() error { switch obj := infos[0].Object.(type) { case *batchv1.CronJob: job = o.createJobFromCronJob(obj) - case *batchv1beta1.CronJob: - job = o.createJobFromCronJobV1Beta1(obj) default: return fmt.Errorf("unknown object type %T", obj) } @@ -254,38 +251,6 @@ func (o *CreateJobOptions) createJob() *batchv1.Job { return job } -func (o *CreateJobOptions) createJobFromCronJobV1Beta1(cronJob *batchv1beta1.CronJob) *batchv1.Job { - annotations := make(map[string]string) - annotations["cronjob.kubernetes.io/instantiate"] = "manual" - for k, v := range cronJob.Spec.JobTemplate.Annotations { - annotations[k] = v - } - - job := &batchv1.Job{ - // this is ok because we know exactly how we want to be serialized - TypeMeta: metav1.TypeMeta{APIVersion: batchv1.SchemeGroupVersion.String(), Kind: "Job"}, - ObjectMeta: metav1.ObjectMeta{ - Name: o.Name, - Annotations: annotations, - Labels: cronJob.Spec.JobTemplate.Labels, - OwnerReferences: []metav1.OwnerReference{ - { - // TODO (soltysh): switch this to v1 in v1.22, when n-1 skew will be fulfilled - APIVersion: batchv1beta1.SchemeGroupVersion.String(), - Kind: "CronJob", - Name: cronJob.GetName(), - UID: cronJob.GetUID(), - }, - }, - }, - Spec: cronJob.Spec.JobTemplate.Spec, - } - if o.EnforceNamespace { - job.Namespace = o.Namespace - } - return job -} - func (o *CreateJobOptions) createJobFromCronJob(cronJob *batchv1.CronJob) *batchv1.Job { annotations := make(map[string]string) annotations["cronjob.kubernetes.io/instantiate"] = "manual" @@ -302,7 +267,7 @@ func (o *CreateJobOptions) createJobFromCronJob(cronJob *batchv1.CronJob) *batch Labels: cronJob.Spec.JobTemplate.Labels, OwnerReferences: []metav1.OwnerReference{ { - APIVersion: batchv1beta1.SchemeGroupVersion.String(), + APIVersion: batchv1.SchemeGroupVersion.String(), Kind: "CronJob", Name: cronJob.GetName(), UID: cronJob.GetUID(), diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_job_test.go b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_job_test.go index b5160fbd26a..fca7c87c319 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_job_test.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_job_test.go @@ -21,7 +21,6 @@ import ( "testing" batchv1 "k8s.io/api/batch/v1" - batchv1beta1 "k8s.io/api/batch/v1beta1" corev1 "k8s.io/api/core/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -135,72 +134,6 @@ func TestCreateJob(t *testing.T) { } } -func TestCreateJobFromCronJobV1Beta1(t *testing.T) { - jobName := "test-job" - cronJob := &batchv1beta1.CronJob{ - Spec: batchv1beta1.CronJobSpec{ - JobTemplate: batchv1beta1.JobTemplateSpec{ - Spec: batchv1.JobSpec{ - Template: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - {Image: "test-image"}, - }, - RestartPolicy: corev1.RestartPolicyNever, - }, - }, - }, - }, - }, - } - tests := map[string]struct { - from *batchv1beta1.CronJob - expected *batchv1.Job - }{ - "from CronJob": { - from: cronJob, - expected: &batchv1.Job{ - TypeMeta: metav1.TypeMeta{APIVersion: batchv1.SchemeGroupVersion.String(), Kind: "Job"}, - ObjectMeta: metav1.ObjectMeta{ - Name: jobName, - Annotations: map[string]string{"cronjob.kubernetes.io/instantiate": "manual"}, - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: batchv1beta1.SchemeGroupVersion.String(), - Kind: "CronJob", - Name: cronJob.GetName(), - UID: cronJob.GetUID(), - }, - }, - }, - Spec: batchv1.JobSpec{ - Template: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - {Image: "test-image"}, - }, - RestartPolicy: corev1.RestartPolicyNever, - }, - }, - }, - }, - }, - } - - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - o := &CreateJobOptions{ - Name: jobName, - } - job := o.createJobFromCronJobV1Beta1(tc.from) - - if !apiequality.Semantic.DeepEqual(job, tc.expected) { - t.Errorf("expected:\n%#v\ngot:\n%#v", tc.expected, job) - } - }) - } -} - func TestCreateJobFromCronJob(t *testing.T) { jobName := "test-job" cronJob := &batchv1.CronJob{ @@ -232,7 +165,7 @@ func TestCreateJobFromCronJob(t *testing.T) { Annotations: map[string]string{"cronjob.kubernetes.io/instantiate": "manual"}, OwnerReferences: []metav1.OwnerReference{ { - APIVersion: batchv1beta1.SchemeGroupVersion.String(), + APIVersion: batchv1.SchemeGroupVersion.String(), Kind: "CronJob", Name: cronJob.GetName(), UID: cronJob.GetUID(), From 628321130b2b754621eabdd0ec32aa7ef34814fe Mon Sep 17 00:00:00 2001 From: Maciej Szulik Date: Thu, 29 Apr 2021 15:07:07 +0200 Subject: [PATCH 2/2] Drop PDB's beta from create command --- .../kubectl/pkg/cmd/create/create_pdb.go | 14 +++++----- .../kubectl/pkg/cmd/create/create_pdb_test.go | 28 +++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_pdb.go b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_pdb.go index 2e2518bb40f..64dc4bf7119 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_pdb.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_pdb.go @@ -23,13 +23,13 @@ import ( "github.com/spf13/cobra" - policyv1beta1 "k8s.io/api/policy/v1beta1" + policyv1 "k8s.io/api/policy/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/cli-runtime/pkg/genericclioptions" resourcecli "k8s.io/cli-runtime/pkg/resource" - policyclient "k8s.io/client-go/kubernetes/typed/policy/v1beta1" + policyv1client "k8s.io/client-go/kubernetes/typed/policy/v1" cmdutil "k8s.io/kubectl/pkg/cmd/util" "k8s.io/kubectl/pkg/scheme" "k8s.io/kubectl/pkg/util" @@ -69,7 +69,7 @@ type PodDisruptionBudgetOpts struct { Namespace string EnforceNamespace bool - Client *policyclient.PolicyV1beta1Client + Client *policyv1client.PolicyV1Client DryRunStrategy cmdutil.DryRunStrategy DryRunVerifier *resourcecli.DryRunVerifier @@ -127,7 +127,7 @@ func (o *PodDisruptionBudgetOpts) Complete(f cmdutil.Factory, cmd *cobra.Command if err != nil { return err } - o.Client, err = policyclient.NewForConfig(restConfig) + o.Client, err = policyv1client.NewForConfig(restConfig) if err != nil { return err } @@ -230,15 +230,15 @@ func (o *PodDisruptionBudgetOpts) Run() error { return o.PrintObj(podDisruptionBudget) } -func (o *PodDisruptionBudgetOpts) createPodDisruptionBudgets() (*policyv1beta1.PodDisruptionBudget, error) { +func (o *PodDisruptionBudgetOpts) createPodDisruptionBudgets() (*policyv1.PodDisruptionBudget, error) { namespace := "" if o.EnforceNamespace { namespace = o.Namespace } - podDisruptionBudget := &policyv1beta1.PodDisruptionBudget{ + podDisruptionBudget := &policyv1.PodDisruptionBudget{ TypeMeta: metav1.TypeMeta{ - APIVersion: policyv1beta1.SchemeGroupVersion.String(), + APIVersion: policyv1.SchemeGroupVersion.String(), Kind: "PodDisruptionBudget", }, ObjectMeta: metav1.ObjectMeta{ diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_pdb_test.go b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_pdb_test.go index addd403b9e8..4053787572c 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_pdb_test.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_pdb_test.go @@ -19,7 +19,7 @@ package create import ( "testing" - policyv1beta1 "k8s.io/api/policy/v1beta1" + policyv1 "k8s.io/api/policy/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -137,7 +137,7 @@ func TestCreatePdb(t *testing.T) { tests := map[string]struct { options *PodDisruptionBudgetOpts - expected *policyv1beta1.PodDisruptionBudget + expected *policyv1.PodDisruptionBudget }{ "test-valid-min-available-pods-number": { options: &PodDisruptionBudgetOpts{ @@ -145,15 +145,15 @@ func TestCreatePdb(t *testing.T) { Selector: selectorOpts, MinAvailable: podAmountNumber, }, - expected: &policyv1beta1.PodDisruptionBudget{ + expected: &policyv1.PodDisruptionBudget{ TypeMeta: metav1.TypeMeta{ Kind: "PodDisruptionBudget", - APIVersion: "policy/v1beta1", + APIVersion: "policy/v1", }, ObjectMeta: metav1.ObjectMeta{ Name: "my-pdb", }, - Spec: policyv1beta1.PodDisruptionBudgetSpec{ + Spec: policyv1.PodDisruptionBudgetSpec{ Selector: selector, MinAvailable: &minAvailableNumber, }, @@ -165,15 +165,15 @@ func TestCreatePdb(t *testing.T) { Selector: selectorOpts, MinAvailable: podAmountPercent, }, - expected: &policyv1beta1.PodDisruptionBudget{ + expected: &policyv1.PodDisruptionBudget{ TypeMeta: metav1.TypeMeta{ Kind: "PodDisruptionBudget", - APIVersion: "policy/v1beta1", + APIVersion: "policy/v1", }, ObjectMeta: metav1.ObjectMeta{ Name: "my-pdb", }, - Spec: policyv1beta1.PodDisruptionBudgetSpec{ + Spec: policyv1.PodDisruptionBudgetSpec{ Selector: selector, MinAvailable: &minAvailablePercent, }, @@ -185,15 +185,15 @@ func TestCreatePdb(t *testing.T) { Selector: selectorOpts, MinAvailable: podAmountNumber, }, - expected: &policyv1beta1.PodDisruptionBudget{ + expected: &policyv1.PodDisruptionBudget{ TypeMeta: metav1.TypeMeta{ Kind: "PodDisruptionBudget", - APIVersion: "policy/v1beta1", + APIVersion: "policy/v1", }, ObjectMeta: metav1.ObjectMeta{ Name: "my-pdb", }, - Spec: policyv1beta1.PodDisruptionBudgetSpec{ + Spec: policyv1.PodDisruptionBudgetSpec{ Selector: selector, MinAvailable: &minUnavailableNumber, }, @@ -205,15 +205,15 @@ func TestCreatePdb(t *testing.T) { Selector: selectorOpts, MinAvailable: podAmountPercent, }, - expected: &policyv1beta1.PodDisruptionBudget{ + expected: &policyv1.PodDisruptionBudget{ TypeMeta: metav1.TypeMeta{ Kind: "PodDisruptionBudget", - APIVersion: "policy/v1beta1", + APIVersion: "policy/v1", }, ObjectMeta: metav1.ObjectMeta{ Name: "my-pdb", }, - Spec: policyv1beta1.PodDisruptionBudgetSpec{ + Spec: policyv1.PodDisruptionBudgetSpec{ Selector: selector, MinAvailable: &minUnavailablePercent, },