From 17c1aaa1316298cfcedb1b062e76118a4366065c Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Sat, 21 Sep 2019 15:52:29 +0000 Subject: [PATCH] chore(probe): for Kubernetes 1.16 move to 'v1' APIs Scope will no longer work with Kubernetes 1.8 and below. For CronJob there is no 'v1' as yet, but we can remove the alpha version. --- probe/kubernetes/client.go | 38 ++++++++++---------------- probe/kubernetes/cronjob.go | 44 +++---------------------------- probe/kubernetes/daemonset.go | 6 ++--- probe/kubernetes/deployment.go | 6 ++--- probe/kubernetes/reporter_test.go | 6 ++--- probe/kubernetes/statefulset.go | 10 +++---- 6 files changed, 30 insertions(+), 80 deletions(-) diff --git a/probe/kubernetes/client.go b/probe/kubernetes/client.go index 352ba855d..a6e077a36 100644 --- a/probe/kubernetes/client.go +++ b/probe/kubernetes/client.go @@ -17,12 +17,10 @@ import ( "github.com/pborman/uuid" log "github.com/sirupsen/logrus" apiappsv1 "k8s.io/api/apps/v1" - apiappsv1beta1 "k8s.io/api/apps/v1beta1" + autoscalingv1 "k8s.io/api/autoscaling/v1" apibatchv1 "k8s.io/api/batch/v1" apibatchv1beta1 "k8s.io/api/batch/v1beta1" - apibatchv2alpha1 "k8s.io/api/batch/v2alpha1" apiv1 "k8s.io/api/core/v1" - apiextensionsv1beta1 "k8s.io/api/extensions/v1beta1" storagev1 "k8s.io/api/storage/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" apimeta "k8s.io/apimachinery/pkg/api/meta" @@ -242,28 +240,19 @@ func (c *client) clientAndType(resource string) (rest.Interface, interface{}, er case "storageclasses": return c.client.StorageV1().RESTClient(), &storagev1.StorageClass{}, nil case "deployments": - return c.client.ExtensionsV1beta1().RESTClient(), &apiextensionsv1beta1.Deployment{}, nil + return c.client.AppsV1().RESTClient(), &apiappsv1.Deployment{}, nil case "daemonsets": - return c.client.ExtensionsV1beta1().RESTClient(), &apiextensionsv1beta1.DaemonSet{}, nil + return c.client.AppsV1().RESTClient(), &apiappsv1.DaemonSet{}, nil case "jobs": return c.client.BatchV1().RESTClient(), &apibatchv1.Job{}, nil case "statefulsets": - return c.client.AppsV1beta1().RESTClient(), &apiappsv1beta1.StatefulSet{}, nil + return c.client.AppsV1().RESTClient(), &apiappsv1.StatefulSet{}, nil case "volumesnapshots": return c.snapshotClient.VolumesnapshotV1().RESTClient(), &snapshotv1.VolumeSnapshot{}, nil case "volumesnapshotdatas": return c.snapshotClient.VolumesnapshotV1().RESTClient(), &snapshotv1.VolumeSnapshotData{}, nil case "cronjobs": - ok, err := c.isResourceSupported(c.client.BatchV1beta1().RESTClient().APIVersion(), resource) - if err != nil { - return nil, nil, err - } - if ok { - // kubernetes >= 1.8 - return c.client.BatchV1beta1().RESTClient(), &apibatchv1beta1.CronJob{}, nil - } - // kubernetes < 1.8 - return c.client.BatchV2alpha1().RESTClient(), &apibatchv2alpha1.CronJob{}, nil + return c.client.BatchV1beta1().RESTClient(), &apibatchv1beta1.CronJob{}, nil } return nil, nil, fmt.Errorf("Invalid resource: %v", resource) } @@ -372,7 +361,7 @@ func (c *client) WalkDeployments(f func(Deployment) error) error { return nil } for _, m := range c.deploymentStore.List() { - d := m.(*apiextensionsv1beta1.Deployment) + d := m.(*apiappsv1.Deployment) if err := f(NewDeployment(d)); err != nil { return err } @@ -386,7 +375,7 @@ func (c *client) WalkDaemonSets(f func(DaemonSet) error) error { return nil } for _, m := range c.daemonSetStore.List() { - ds := m.(*apiextensionsv1beta1.DaemonSet) + ds := m.(*apiappsv1.DaemonSet) if err := f(NewDaemonSet(ds)); err != nil { return err } @@ -400,7 +389,7 @@ func (c *client) WalkStatefulSets(f func(StatefulSet) error) error { return nil } for _, m := range c.statefulSetStore.List() { - s := m.(*apiappsv1beta1.StatefulSet) + s := m.(*apiappsv1.StatefulSet) if err := f(NewStatefulSet(s)); err != nil { return err } @@ -420,7 +409,8 @@ func (c *client) WalkCronJobs(f func(CronJob) error) error { jobs[j.UID] = j } for _, m := range c.cronJobStore.List() { - if err := f(NewCronJob(m, jobs)); err != nil { + cj := m.(*apibatchv1beta1.CronJob) + if err := f(NewCronJob(cj, jobs)); err != nil { return err } } @@ -609,19 +599,19 @@ func (c *client) DeleteVolumeSnapshot(namespaceID, volumeSnapshotID string) erro } func (c *client) ScaleUp(namespaceID, id string) error { - return c.modifyScale(namespaceID, id, func(scale *apiextensionsv1beta1.Scale) { + return c.modifyScale(namespaceID, id, func(scale *autoscalingv1.Scale) { scale.Spec.Replicas++ }) } func (c *client) ScaleDown(namespaceID, id string) error { - return c.modifyScale(namespaceID, id, func(scale *apiextensionsv1beta1.Scale) { + return c.modifyScale(namespaceID, id, func(scale *autoscalingv1.Scale) { scale.Spec.Replicas-- }) } -func (c *client) modifyScale(namespaceID, id string, f func(*apiextensionsv1beta1.Scale)) error { - scaler := c.client.ExtensionsV1beta1().Deployments(namespaceID) +func (c *client) modifyScale(namespaceID, id string, f func(*autoscalingv1.Scale)) error { + scaler := c.client.AppsV1().Deployments(namespaceID) scale, err := scaler.GetScale(id, metav1.GetOptions{}) if err != nil { return err diff --git a/probe/kubernetes/cronjob.go b/probe/kubernetes/cronjob.go index e6543efb9..5598fc256 100644 --- a/probe/kubernetes/cronjob.go +++ b/probe/kubernetes/cronjob.go @@ -5,8 +5,7 @@ import ( "time" batchv1 "k8s.io/api/batch/v1" - batchv1beta1 "k8s.io/api/batch/v1beta1" - batchv2alpha1 "k8s.io/api/batch/v2alpha1" + apibatchv1beta1 "k8s.io/api/batch/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" @@ -30,25 +29,14 @@ type CronJob interface { } type cronJob struct { - *batchv1beta1.CronJob + *apibatchv1beta1.CronJob Meta jobs []*batchv1.Job } // NewCronJob creates a new cron job. jobs should be all jobs, which will be filtered // for those matching this cron job. -func NewCronJob(cji interface{}, jobs map[types.UID]*batchv1.Job) CronJob { - switch cj := cji.(type) { - case *batchv2alpha1.CronJob: - return newCronJob(upgradeCronJob(cj), jobs) - case *batchv1beta1.CronJob: - return newCronJob(cj, jobs) - default: - panic(fmt.Sprintf("interface conversion: interface{} is %T, not *batchv2alpha1.CronJob or *batchv1beta1.CronJob", cj)) - } -} - -func newCronJob(cj *batchv1beta1.CronJob, jobs map[types.UID]*batchv1.Job) CronJob { +func NewCronJob(cj *apibatchv1beta1.CronJob, jobs map[types.UID]*batchv1.Job) CronJob { myJobs := []*batchv1.Job{} for _, o := range cj.Status.Active { if j, ok := jobs[o.UID]; ok { @@ -89,29 +77,3 @@ func (cj *cronJob) GetNode(probeID string) report.Node { WithLatests(latest). WithLatestActiveControls(Describe) } - -func upgradeCronJob(legacy *batchv2alpha1.CronJob) *batchv1beta1.CronJob { - jobTemplate := batchv1beta1.JobTemplateSpec{ - ObjectMeta: legacy.Spec.JobTemplate.ObjectMeta, - Spec: legacy.Spec.JobTemplate.Spec, - } - spec := batchv1beta1.CronJobSpec{ - Schedule: legacy.Spec.Schedule, - StartingDeadlineSeconds: legacy.Spec.StartingDeadlineSeconds, - ConcurrencyPolicy: batchv1beta1.ConcurrencyPolicy(legacy.Spec.ConcurrencyPolicy), - Suspend: legacy.Spec.Suspend, - JobTemplate: jobTemplate, - SuccessfulJobsHistoryLimit: legacy.Spec.SuccessfulJobsHistoryLimit, - FailedJobsHistoryLimit: legacy.Spec.FailedJobsHistoryLimit, - } - status := batchv1beta1.CronJobStatus{ - Active: legacy.Status.Active, - LastScheduleTime: legacy.Status.LastScheduleTime, - } - return &batchv1beta1.CronJob{ - TypeMeta: legacy.TypeMeta, - ObjectMeta: legacy.ObjectMeta, - Spec: spec, - Status: status, - } -} diff --git a/probe/kubernetes/daemonset.go b/probe/kubernetes/daemonset.go index d7dd638b3..ab2115db7 100644 --- a/probe/kubernetes/daemonset.go +++ b/probe/kubernetes/daemonset.go @@ -3,7 +3,7 @@ package kubernetes import ( "fmt" - apiv1beta1 "k8s.io/api/extensions/v1beta1" + apiv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -23,12 +23,12 @@ type DaemonSet interface { } type daemonSet struct { - *apiv1beta1.DaemonSet + *apiv1.DaemonSet Meta } // NewDaemonSet creates a new daemonset -func NewDaemonSet(d *apiv1beta1.DaemonSet) DaemonSet { +func NewDaemonSet(d *apiv1.DaemonSet) DaemonSet { return &daemonSet{ DaemonSet: d, Meta: meta{d.ObjectMeta}, diff --git a/probe/kubernetes/deployment.go b/probe/kubernetes/deployment.go index 78777e27c..4f85bc2e0 100644 --- a/probe/kubernetes/deployment.go +++ b/probe/kubernetes/deployment.go @@ -5,8 +5,8 @@ import ( "github.com/weaveworks/scope/report" + apiappsv1 "k8s.io/api/apps/v1" apiv1 "k8s.io/api/core/v1" - apiv1beta1 "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" ) @@ -27,13 +27,13 @@ type Deployment interface { } type deployment struct { - *apiv1beta1.Deployment + *apiappsv1.Deployment Meta Node *apiv1.Node } // NewDeployment creates a new Deployment -func NewDeployment(d *apiv1beta1.Deployment) Deployment { +func NewDeployment(d *apiappsv1.Deployment) Deployment { return &deployment{Deployment: d, Meta: meta{d.ObjectMeta}} } diff --git a/probe/kubernetes/reporter_test.go b/probe/kubernetes/reporter_test.go index d742fb79d..1abd9b624 100644 --- a/probe/kubernetes/reporter_test.go +++ b/probe/kubernetes/reporter_test.go @@ -7,8 +7,8 @@ import ( "strings" "testing" + appsv1 "k8s.io/api/apps/v1" apiv1 "k8s.io/api/core/v1" - apiv1beta1 "k8s.io/api/extensions/v1beta1" k8smeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -323,10 +323,10 @@ func BenchmarkReporter(b *testing.B) { pod := apiPod1 pod.ObjectMeta.UID = types.UID(fmt.Sprintf("pod%d", i)) mockK8s.pods = append(mockK8s.pods, kubernetes.NewPod(&pod)) - deployment := apiv1beta1.Deployment{ + deployment := appsv1.Deployment{ TypeMeta: metav1.TypeMeta{ Kind: "Deployment", - APIVersion: "v1beta1", + APIVersion: "v1", }, ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("deployment%d", i), diff --git a/probe/kubernetes/statefulset.go b/probe/kubernetes/statefulset.go index db5539372..4f388cefc 100644 --- a/probe/kubernetes/statefulset.go +++ b/probe/kubernetes/statefulset.go @@ -3,7 +3,7 @@ package kubernetes import ( "fmt" - "k8s.io/api/apps/v1beta1" + appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -18,12 +18,12 @@ type StatefulSet interface { } type statefulSet struct { - *v1beta1.StatefulSet + *appsv1.StatefulSet Meta } // NewStatefulSet creates a new statefulset -func NewStatefulSet(s *v1beta1.StatefulSet) StatefulSet { +func NewStatefulSet(s *appsv1.StatefulSet) StatefulSet { return &statefulSet{ StatefulSet: s, Meta: meta{s.ObjectMeta}, @@ -48,9 +48,7 @@ func (s *statefulSet) GetNode(probeID string) report.Node { DesiredReplicas: fmt.Sprint(desiredReplicas), Replicas: fmt.Sprint(s.Status.Replicas), report.ControlProbeID: probeID, - } - if s.Status.ObservedGeneration != nil { - latests[ObservedGeneration] = fmt.Sprint(*s.Status.ObservedGeneration) + ObservedGeneration: fmt.Sprint(s.Status.ObservedGeneration), } return s.MetaNode(report.MakeStatefulSetNodeID(s.UID())). WithLatests(latests).