Skip to content

Commit

Permalink
Migrate Ingress from API extensions/v1beta1 to networking.k8s.io/v1be…
Browse files Browse the repository at this point in the history
…ta1 (#1039)

* Migrate Ingress from API extensions/v1beta1 to networking.k8s.io/v1beta1

Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>

* Add network.k8s.io ingress api detection

Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>

* Add client layer for decide which version of API ingress to use

Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>

* Ingress new/old api tests

Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>

* Set used api when the client is created, minor format issues

Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>

* Fix lint issues

Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>

* Change the API detection to run once at start

Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>

* Avoid string assertion on viper.get

Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>
  • Loading branch information
rubenvp8510 authored May 14, 2020
1 parent bead1d5 commit ee0ead3
Show file tree
Hide file tree
Showing 13 changed files with 395 additions and 30 deletions.
12 changes: 12 additions & 0 deletions deploy/cluster_role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,18 @@ rules:
- 'update'
- 'delete'
- 'watch'
# Ingress for kubernetes 1.14 or higher
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- 'get'
- 'list'
- 'create'
- 'update'
- 'delete'
- 'watch'
- apiGroups:
- batch
resources:
Expand Down
13 changes: 13 additions & 0 deletions deploy/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ rules:
- 'update'
- 'delete'
- 'watch'
# Ingress for kubernetes 1.14 or higher
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- 'get'
- 'list'
- 'create'
- 'update'
- 'delete'
- 'watch'
- apiGroups:
- batch
resources:
Expand Down Expand Up @@ -156,3 +168,4 @@ rules:
- 'update'
- 'delete'
- 'watch'

21 changes: 21 additions & 0 deletions pkg/autodetect/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/manager"

"github.com/jaegertracing/jaeger-operator/pkg/ingress"

v1 "github.com/jaegertracing/jaeger-operator/pkg/apis/jaegertracing/v1"
"github.com/jaegertracing/jaeger-operator/pkg/inject"
)
Expand Down Expand Up @@ -98,6 +100,8 @@ func (b *Background) autoDetectCapabilities() {
b.firstRun.Do(func() {
// the platform won't change during the execution of the operator, need to run it only once
b.detectPlatform(ctx, apiList)
b.detectIngressAPI()

})

b.detectElasticsearch(ctx, apiList)
Expand Down Expand Up @@ -133,6 +137,23 @@ func (b *Background) detectPlatform(ctx context.Context, apiList *metav1.APIGrou
}
}

func (b *Background) detectIngressAPI() {
apiRes, err := b.dcl.ServerResourcesForGroupVersion("networking.k8s.io/v1beta1")
if err != nil {
viper.Set("ingress-api", ingress.ExtensionAPI)
log.WithField("ingress-api", viper.GetString("ingress-api")).Info("Auto-detected ingress api")
return
}

for _, r := range apiRes.APIResources {
if r.Name == "ingresses" {
viper.Set("ingress-api", ingress.NetworkingAPI)
log.WithField("ingress-api", viper.GetString("ingress-api")).Info("Auto-detected ingress api")
break
}
}
}

func (b *Background) detectElasticsearch(ctx context.Context, apiList *metav1.APIGroupList) {
// detect whether the Elasticsearch operator is available
if b.retryDetectEs {
Expand Down
13 changes: 8 additions & 5 deletions pkg/controller/jaeger/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package jaeger
import (
"context"

"github.com/jaegertracing/jaeger-operator/pkg/ingress"

log "github.com/sirupsen/logrus"
"go.opentelemetry.io/otel/global"
"k8s.io/api/extensions/v1beta1"
"k8s.io/api/networking/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"

v1 "github.com/jaegertracing/jaeger-operator/pkg/apis/jaegertracing/v1"
Expand All @@ -14,6 +16,7 @@ import (
)

func (r *ReconcileJaeger) applyIngresses(ctx context.Context, jaeger v1.Jaeger, desired []v1beta1.Ingress) error {
ingressClient := ingress.NewIngressClient(r.client, r.rClient)
tracer := global.TraceProvider().GetTracer(v1.ReconciliationTracer)
ctx, span := tracer.Start(ctx, "applyIngresses")
defer span.End()
Expand All @@ -26,7 +29,7 @@ func (r *ReconcileJaeger) applyIngresses(ctx context.Context, jaeger v1.Jaeger,
}),
}
list := &v1beta1.IngressList{}
if err := r.rClient.List(ctx, list, opts...); err != nil {
if err := ingressClient.List(ctx, list, opts...); err != nil {
return tracing.HandleError(err, span)
}

Expand All @@ -36,7 +39,7 @@ func (r *ReconcileJaeger) applyIngresses(ctx context.Context, jaeger v1.Jaeger,
"ingress": d.Name,
"namespace": d.Namespace,
}).Debug("creating ingress")
if err := r.client.Create(ctx, &d); err != nil {
if err := ingressClient.Create(ctx, &d); err != nil {
return tracing.HandleError(err, span)
}
}
Expand All @@ -46,7 +49,7 @@ func (r *ReconcileJaeger) applyIngresses(ctx context.Context, jaeger v1.Jaeger,
"ingress": d.Name,
"namespace": d.Namespace,
}).Debug("updating ingress")
if err := r.client.Update(ctx, &d); err != nil {
if err := ingressClient.Update(ctx, &d); err != nil {
return tracing.HandleError(err, span)
}
}
Expand All @@ -56,7 +59,7 @@ func (r *ReconcileJaeger) applyIngresses(ctx context.Context, jaeger v1.Jaeger,
"ingress": d.Name,
"namespace": d.Namespace,
}).Debug("deleting ingress")
if err := r.client.Delete(ctx, &d); err != nil {
if err := ingressClient.Delete(ctx, &d); err != nil {
return tracing.HandleError(err, span)
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/jaeger/ingress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"k8s.io/api/extensions/v1beta1"
"k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
Expand Down
172 changes: 172 additions & 0 deletions pkg/ingress/ingress.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package ingress

import (
"context"

"github.com/spf13/viper"

extv1beta "k8s.io/api/extensions/v1beta1"
netv1beta "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

// ExtensionAPI indicate k8s networking.k8s.io/v1beta1 should be used on the current cluster
const ExtensionAPI = "extension"

// NetworkingAPI indicate k8s extensions/v1beta1 should be used on the current cluster
const NetworkingAPI = "networking"

// Client wrap around k8s client, and decide which ingress API should be used, depending on cluster capabilities.
type Client struct {
client client.Client
rClient client.Reader
extensionAPI bool
}

// NewIngressClient Creates a new Ingress.client wrapper.
func NewIngressClient(client client.Client, reader client.Reader) *Client {
return &Client{
client: client,
rClient: reader,
extensionAPI: viper.GetString("ingress-api") == ExtensionAPI,
}
}

func (c *Client) fromExtToNet(ingress extv1beta.Ingress) netv1beta.Ingress {
oldIngress := netv1beta.Ingress{
TypeMeta: metav1.TypeMeta{
Kind: "Ingress",
APIVersion: "extensions/v1beta1",
},
ObjectMeta: ingress.ObjectMeta,
}

if ingress.Spec.Backend != nil {
oldIngress.Spec = netv1beta.IngressSpec{
Backend: &netv1beta.IngressBackend{
ServiceName: ingress.Spec.Backend.ServiceName,
ServicePort: ingress.Spec.Backend.ServicePort,
},
}
}

for _, tls := range ingress.Spec.TLS {
oldIngress.Spec.TLS = append(oldIngress.Spec.TLS, netv1beta.IngressTLS{
Hosts: tls.Hosts,
SecretName: tls.SecretName,
})
}

for _, rule := range ingress.Spec.Rules {
httpIngressPaths := make([]netv1beta.HTTPIngressPath, len(rule.HTTP.Paths))
for i, path := range rule.HTTP.Paths {
httpIngressPaths[i].Backend.ServicePort = path.Backend.ServicePort
httpIngressPaths[i].Backend.ServiceName = path.Backend.ServiceName
httpIngressPaths[i].Path = path.Path

}

oldIngress.Spec.Rules = append(oldIngress.Spec.Rules, netv1beta.IngressRule{
Host: rule.Host,
IngressRuleValue: netv1beta.IngressRuleValue{
HTTP: &netv1beta.HTTPIngressRuleValue{
Paths: httpIngressPaths,
},
},
})
}

return oldIngress
}

func (c *Client) fromNetToExt(ingress netv1beta.Ingress) extv1beta.Ingress {
oldIngress := extv1beta.Ingress{
TypeMeta: metav1.TypeMeta{
Kind: "Ingress",
APIVersion: "extensions/v1beta1",
},
ObjectMeta: ingress.ObjectMeta,
}

if ingress.Spec.Backend != nil {
oldIngress.Spec = extv1beta.IngressSpec{
Backend: &extv1beta.IngressBackend{
ServiceName: ingress.Spec.Backend.ServiceName,
ServicePort: ingress.Spec.Backend.ServicePort,
},
}
}

for _, tls := range ingress.Spec.TLS {
oldIngress.Spec.TLS = append(oldIngress.Spec.TLS, extv1beta.IngressTLS{
Hosts: tls.Hosts,
SecretName: tls.SecretName,
})
}

for _, rule := range ingress.Spec.Rules {
httpIngressPaths := make([]extv1beta.HTTPIngressPath, len(rule.HTTP.Paths))
for i, path := range rule.HTTP.Paths {
httpIngressPaths[i].Backend.ServicePort = path.Backend.ServicePort
httpIngressPaths[i].Backend.ServiceName = path.Backend.ServiceName
httpIngressPaths[i].Path = path.Path

}

oldIngress.Spec.Rules = append(oldIngress.Spec.Rules, extv1beta.IngressRule{
Host: rule.Host,
IngressRuleValue: extv1beta.IngressRuleValue{
HTTP: &extv1beta.HTTPIngressRuleValue{
Paths: httpIngressPaths,
},
},
})
}

return oldIngress
}

// List is a wrap function that calls k8s client List with extend or networking API.
func (c *Client) List(ctx context.Context, list *netv1beta.IngressList, opts ...client.ListOption) error {
if c.extensionAPI {
extIngressList := extv1beta.IngressList{}
err := c.rClient.List(ctx, &extIngressList, opts...)
if err != nil {
return err
}
for _, item := range extIngressList.Items {
list.Items = append(list.Items, c.fromExtToNet(item))
}
return nil
}
return c.rClient.List(ctx, list, opts...)
}

// Update is a wrap function that calls k8s client Update with extend or networking API.
func (c *Client) Update(ctx context.Context, obj *netv1beta.Ingress, opts ...client.UpdateOption) error {
if c.extensionAPI {
extIngressList := c.fromNetToExt(*obj)
return c.client.Update(ctx, &extIngressList, opts...)
}
return c.client.Update(ctx, obj, opts...)

}

// Delete is a wrap function that calls k8s client Delete with extend or networking API.
func (c *Client) Delete(ctx context.Context, obj *netv1beta.Ingress, opts ...client.DeleteOption) error {
if c.extensionAPI {
extIngressList := c.fromNetToExt(*obj)
return c.client.Delete(ctx, &extIngressList, opts...)
}
return c.client.Delete(ctx, obj, opts...)
}

// Create is a wrap function that calls k8s client Create with extend or networking API.
func (c *Client) Create(ctx context.Context, obj *netv1beta.Ingress, opts ...client.CreateOption) error {
if c.extensionAPI {
extIngressList := c.fromNetToExt(*obj)
return c.client.Create(ctx, &extIngressList, opts...)
}
return c.client.Create(ctx, obj, opts...)
}
Loading

0 comments on commit ee0ead3

Please sign in to comment.