Skip to content

Commit

Permalink
Migrate autoscaling v2beta2 to v2 for Kubernetes 1.26 (#2055)
Browse files Browse the repository at this point in the history
* Migrate autoscaling v2beta2 to v2

Signed-off-by: Israel Blancas <[email protected]>

* Fix some unit tests

Signed-off-by: Israel Blancas <[email protected]>

* Fix rest of unit tests

Signed-off-by: Israel Blancas <[email protected]>

* Increase unit test coverage

Signed-off-by: Israel Blancas <[email protected]>

* Fix linting

Signed-off-by: Israel Blancas <[email protected]>

* Apply changes requestd in CR

Signed-off-by: Israel Blancas <[email protected]>

* Apply changes requestd in CR

Signed-off-by: Israel Blancas <[email protected]>

* Increase code coverage

Signed-off-by: Israel Blancas <[email protected]>

* Increase code coverage

Signed-off-by: Israel Blancas <[email protected]>

Signed-off-by: Israel Blancas <[email protected]>
  • Loading branch information
iblancasa authored Sep 6, 2022
1 parent 3be8ea9 commit f579ee9
Show file tree
Hide file tree
Showing 14 changed files with 697 additions and 168 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ endif
.PHONY: unit-tests
unit-tests: envtest
@echo Running unit tests...
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test ${GOTEST_OPTS} ./... -cover -coverprofile=cover.out -ldflags $(LD_FLAGS)
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test -p 1 ${GOTEST_OPTS} ./... -cover -coverprofile=cover.out -ldflags $(LD_FLAGS)

.PHONY: set-node-os-linux
set-node-os-linux:
Expand Down
13 changes: 11 additions & 2 deletions apis/v1/jaeger_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,21 @@ const (
// FlagCronJobsVersion represents the version of the Kubernetes CronJob API
FlagCronJobsVersion = "cronjobs-version"

// FlagCronJobsVersionBatchV1 represents the batch/v1 version of the kubernetes CronJob API, available as of 1.21
// FlagCronJobsVersionBatchV1 represents the batch/v1 version of the Kubernetes CronJob API, available as of 1.21
FlagCronJobsVersionBatchV1 = "batch/v1"

// FlagCronJobsVersionBatchV1Beta1 represents the batch/v1beta1 version of the kubernetes CronJob API, no longer available as of 1.25
// FlagCronJobsVersionBatchV1Beta1 represents the batch/v1beta1 version of the Kubernetes CronJob API, no longer available as of 1.25
FlagCronJobsVersionBatchV1Beta1 = "batch/v1beta1"

// FlagAutoscalingVersion represents the version of the Kubernetes Autoscaling API
FlagAutoscalingVersion = "autoscaling-version"

// FlagAutoscalingVersionV2 represents the v2 version of the Kubernetes Autoscaling API, available as of 1.23
FlagAutoscalingVersionV2 = "autoscaling/v2"

// FlagAutoscalingVersionV2Beta2 represents the v2beta2 version of the Kubernetes Autoscaling API, no longer available as of 1.26
FlagAutoscalingVersionV2Beta2 = "autoscaling/v2beta2"

// FlagPlatformKubernetes represents the value for the 'platform' flag for Kubernetes
FlagPlatformKubernetes = "kubernetes"

Expand Down
36 changes: 30 additions & 6 deletions pkg/autodetect/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,34 +100,58 @@ func (b *Background) autoDetectCapabilities() {
b.detectElasticsearch(ctx, apiList)
b.detectKafka(ctx, apiList)
b.detectCronjobsVersion(ctx)
b.detectAutoscalingVersion(ctx)
}

b.detectClusterRoles(ctx)
b.cleanDeployments(ctx)
}

func (b *Background) detectCronjobsVersion(ctx context.Context) {
apiGroupVersions := []string{"batch/v1", "batch/v1beta1"}
apiGroupVersions := []string{v1.FlagCronJobsVersionBatchV1, v1.FlagCronJobsVersionBatchV1Beta1}
for _, apiGroupVersion := range apiGroupVersions {
groupAPIList, err := b.dcl.ServerResourcesForGroupVersion(apiGroupVersion)
if err != nil {
log.Log.Error(
err,
fmt.Sprintf("Error getting %s api list", apiGroupVersion),
log.Log.V(-1).Info(
fmt.Sprintf("error getting %s api list: %s", apiGroupVersion, err),
)
continue
}
for _, api := range groupAPIList.APIResources {
if api.Name == "cronjobs" {
viper.Set(v1.FlagCronJobsVersion, apiGroupVersion)
log.Log.V(-1).Info(fmt.Sprintf("Found the cronjobs api in %s", apiGroupVersion))
log.Log.V(-1).Info(fmt.Sprintf("found the cronjobs api in %s", apiGroupVersion))
return
}
}
}

log.Log.V(2).Info(
fmt.Sprintf("did not find the cronjobs api in %s", strings.Join(apiGroupVersions, " or ")),
)
}

func (b *Background) detectAutoscalingVersion(ctx context.Context) {
apiGroupVersions := []string{v1.FlagAutoscalingVersionV2, v1.FlagAutoscalingVersionV2Beta2}
for _, apiGroupVersion := range apiGroupVersions {
groupAPIList, err := b.dcl.ServerResourcesForGroupVersion(apiGroupVersion)
if err != nil {
log.Log.V(-1).Info(
fmt.Sprintf("error getting %s api list: %s", apiGroupVersion, err),
)
continue
}
for _, api := range groupAPIList.APIResources {
if api.Name == "horizontalpodautoscalers" {
viper.Set(v1.FlagAutoscalingVersion, apiGroupVersion)
log.Log.V(-1).Info(fmt.Sprintf("found the horizontalpodautoscalers api in %s", apiGroupVersion))
return
}
}
}

log.Log.V(2).Info(
fmt.Sprintf("Did not find the cronjobs api in %s", strings.Join(apiGroupVersions, " or ")),
fmt.Sprintf("did not find the autoscaling api in %s", strings.Join(apiGroupVersions, " or ")),
)
}

Expand Down
48 changes: 48 additions & 0 deletions pkg/autodetect/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,54 @@ func TestAutoDetectCronJobsVersion(t *testing.T) {
}
}

func TestAutoDetectAutoscalingVersion(t *testing.T) {
apiGroupVersions := []string{v1.FlagAutoscalingVersionV2, v1.FlagAutoscalingVersionV2Beta2}
for _, apiGroup := range apiGroupVersions {
dcl := &fakeDiscoveryClient{}
cl := fake.NewFakeClient() // nolint:staticcheck
b := WithClients(cl, dcl, cl)
dcl.ServerGroupsFunc = func() (apiGroupList *metav1.APIGroupList, err error) {
return &metav1.APIGroupList{Groups: []metav1.APIGroup{{
Name: apiGroup,
Versions: []metav1.GroupVersionForDiscovery{{Version: apiGroup}},
}}}, nil
}

dcl.ServerResourcesForGroupVersionFunc = func(requestedApiVersion string) (apiGroupList *metav1.APIResourceList, err error) {
if requestedApiVersion == apiGroup {
apiResourceList := &metav1.APIResourceList{GroupVersion: apiGroup, APIResources: []metav1.APIResource{{Name: "horizontalpodautoscalers"}}}
return apiResourceList, nil
}
return &metav1.APIResourceList{}, nil
}

// test
b.autoDetectCapabilities()

// verify
assert.Equal(t, apiGroup, viper.GetString(v1.FlagAutoscalingVersion))
fmt.Printf("Test finished on [%s]\n", apiGroup)
}

// Check what happens when there ServerResourcesForGroupVersion returns error
dcl := &fakeDiscoveryClient{}
cl := fake.NewFakeClient() // nolint:staticcheck
b := WithClients(cl, dcl, cl)
dcl.ServerGroupsFunc = func() (apiGroupList *metav1.APIGroupList, err error) {
return &metav1.APIGroupList{Groups: []metav1.APIGroup{{
Name: v1.FlagAutoscalingVersionV2,
Versions: []metav1.GroupVersionForDiscovery{{Version: v1.FlagAutoscalingVersionV2}},
}}}, nil
}

dcl.ServerResourcesForGroupVersionFunc = func(requestedApiVersion string) (apiGroupList *metav1.APIResourceList, err error) {
return &metav1.APIResourceList{}, fmt.Errorf("Fake error")
}

// test
b.autoDetectCapabilities()
}

func TestSkipAuthDelegatorNonOpenShift(t *testing.T) {
// prepare
viper.Set("platform", v1.FlagPlatformKubernetes)
Expand Down
132 changes: 98 additions & 34 deletions pkg/controller/jaeger/horizontalpodautoscaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ import (
"context"

"go.opentelemetry.io/otel"
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

autoscalingv2 "k8s.io/api/autoscaling/v2"
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"

"github.com/spf13/viper"

v1 "github.com/jaegertracing/jaeger-operator/apis/v1"
"github.com/jaegertracing/jaeger-operator/pkg/inventory"
"github.com/jaegertracing/jaeger-operator/pkg/tracing"
)

func (r *ReconcileJaeger) applyHorizontalPodAutoscalers(ctx context.Context, jaeger v1.Jaeger, desired []autoscalingv2beta2.HorizontalPodAutoscaler) error {
func (r *ReconcileJaeger) applyHorizontalPodAutoscalers(ctx context.Context, jaeger v1.Jaeger, desired []runtime.Object) error {
tracer := otel.GetTracerProvider().Tracer(v1.ReconciliationTracer)
ctx, span := tracer.Start(ctx, "applyHorizontalPodAutoscalers")
defer span.End()
Expand All @@ -24,46 +29,105 @@ func (r *ReconcileJaeger) applyHorizontalPodAutoscalers(ctx context.Context, jae
"app.kubernetes.io/managed-by": "jaeger-operator",
}),
}
hpaList := &autoscalingv2beta2.HorizontalPodAutoscalerList{}
if err := r.rClient.List(ctx, hpaList, opts...); err != nil {
return tracing.HandleError(err, span)
}

hpaInventory := inventory.ForHorizontalPodAutoscalers(hpaList.Items, desired)
for i := range hpaInventory.Create {
d := hpaInventory.Create[i]
jaeger.Logger().V(-1).Info(
"creating hpa",
"hpa", d.Name,
"namespace", d.Namespace,
)
if err := r.client.Create(ctx, &d); err != nil {
autoscalingVersion := viper.GetString(v1.FlagAutoscalingVersion)

if autoscalingVersion == v1.FlagAutoscalingVersionV2Beta2 {
hpaList := &autoscalingv2beta2.HorizontalPodAutoscalerList{}

if err := r.rClient.List(ctx, hpaList, opts...); err != nil {
return tracing.HandleError(err, span)
}
}

for i := range hpaInventory.Update {
d := hpaInventory.Update[i]
jaeger.Logger().V(-1).Info(
"updating hpa",
"hpa", d.Name,
"namespace", d.Namespace,
)
if err := r.client.Update(ctx, &d); err != nil {
return tracing.HandleError(err, span)
var existing []runtime.Object
for _, i := range hpaList.Items {
existing = append(existing, i.DeepCopyObject())
}

hpaInventory := inventory.ForHorizontalPodAutoscalers(existing, desired)
for i := range hpaInventory.Create {
d := hpaInventory.Create[i].(*autoscalingv2beta2.HorizontalPodAutoscaler)
jaeger.Logger().V(-1).Info(
"creating hpa",
"hpa", d.Name,
"namespace", d.Namespace,
)
if err := r.client.Create(ctx, d); err != nil {
return tracing.HandleError(err, span)
}
}
}

for i := range hpaInventory.Delete {
d := hpaInventory.Delete[i]
jaeger.Logger().V(-1).Info(
"deleting hpa",
"hpa", d.Name,
"namespace", d.Namespace,
)
if err := r.client.Delete(ctx, &d); err != nil {
for i := range hpaInventory.Update {
d := hpaInventory.Update[i].(*autoscalingv2beta2.HorizontalPodAutoscaler)
jaeger.Logger().V(-1).Info(
"updating hpa",
"hpa", d.Name,
"namespace", d.Namespace,
)
if err := r.client.Update(ctx, d); err != nil {
return tracing.HandleError(err, span)
}
}

for i := range hpaInventory.Delete {
d := hpaInventory.Delete[i].(*autoscalingv2beta2.HorizontalPodAutoscaler)
jaeger.Logger().V(-1).Info(
"deleting hpa",
"hpa", d.Name,
"namespace", d.Namespace,
)
if err := r.client.Delete(ctx, d); err != nil {
return tracing.HandleError(err, span)
}
}
} else {
hpaList := &autoscalingv2.HorizontalPodAutoscalerList{}

if err := r.rClient.List(ctx, hpaList, opts...); err != nil {
return tracing.HandleError(err, span)
}

var existing []runtime.Object
for _, i := range hpaList.Items {
existing = append(existing, i.DeepCopyObject())
}

hpaInventory := inventory.ForHorizontalPodAutoscalers(existing, desired)
for i := range hpaInventory.Create {
d := hpaInventory.Create[i].(*autoscalingv2.HorizontalPodAutoscaler)
jaeger.Logger().V(-1).Info(
"creating hpa",
"hpa", d.Name,
"namespace", d.Namespace,
)
if err := r.client.Create(ctx, d); err != nil {
return tracing.HandleError(err, span)
}
}

for i := range hpaInventory.Update {
d := hpaInventory.Update[i].(*autoscalingv2.HorizontalPodAutoscaler)
jaeger.Logger().V(-1).Info(
"updating hpa",
"hpa", d.Name,
"namespace", d.Namespace,
)
if err := r.client.Update(ctx, d); err != nil {
return tracing.HandleError(err, span)
}
}

for i := range hpaInventory.Delete {
d := hpaInventory.Delete[i].(*autoscalingv2.HorizontalPodAutoscaler)
jaeger.Logger().V(-1).Info(
"deleting hpa",
"hpa", d.Name,
"namespace", d.Namespace,
)
if err := r.client.Delete(ctx, d); err != nil {
return tracing.HandleError(err, span)
}
}
}

return nil
Expand Down
Loading

0 comments on commit f579ee9

Please sign in to comment.