Skip to content

Commit

Permalink
Use v1 Ingresses when available (#182)
Browse files Browse the repository at this point in the history
  • Loading branch information
LCaparelli authored Oct 29, 2020
1 parent 4f12f49 commit 41b9b04
Show file tree
Hide file tree
Showing 23 changed files with 649 additions and 179 deletions.
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ all: manager

# Run tests
ENVTEST_ASSETS_DIR=$(shell pwd)/testbin
# Needed to support k8s.io/api/networking/v1 Ingress
K8S_VERSION=1.19.0
test: generate-installer fmt vet bundle
mkdir -p ${ENVTEST_ASSETS_DIR}
test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/master/hack/setup-envtest.sh
sed -i "s,#\!.*,#\!\/bin\/bash,g" ${ENVTEST_ASSETS_DIR}/setup-envtest.sh
sed -i "/pipefail/d" ${ENVTEST_ASSETS_DIR}/setup-envtest.sh
source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); go test ./... -coverprofile cover.out
source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; ENVTEST_K8S_VERSION=$(K8S_VERSION) fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); go test ./... -coverprofile cover.out

generate-installer: generate manifests kustomize
cd config/manager && $(KUSTOMIZE) edit set image controller=$(OPERATOR_IMG)
Expand Down
9 changes: 5 additions & 4 deletions controllers/nexus/resource/deployment/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ import (

"github.com/m88i/nexus-operator/api/v1alpha1"
"github.com/m88i/nexus-operator/pkg/framework"
"github.com/m88i/nexus-operator/pkg/framework/kind"
"github.com/m88i/nexus-operator/pkg/logger"
)

var managedObjectsRef = map[string]resource.KubernetesResource{
framework.DeploymentKind: &appsv1.Deployment{},
framework.ServiceKind: &corev1.Service{},
kind.DeploymentKind: &appsv1.Deployment{},
kind.ServiceKind: &corev1.Service{},
}

// Manager is responsible for creating deployment-related resources, fetching deployed ones and comparing them
Expand All @@ -56,8 +57,8 @@ func NewManager(nexus *v1alpha1.Nexus, client client.Client) *Manager {

// GetRequiredResources returns the resources initialized by the manager
func (m *Manager) GetRequiredResources() ([]resource.KubernetesResource, error) {
m.log.Debug("Generating required resource", "kind", framework.DeploymentKind)
m.log.Debug("Generating required resource", "kind", framework.ServiceKind)
m.log.Debug("Generating required resource", "kind", kind.DeploymentKind)
m.log.Debug("Generating required resource", "kind", kind.ServiceKind)
return []resource.KubernetesResource{newDeployment(m.nexus), newService(m.nexus)}, nil
}

Expand Down
45 changes: 25 additions & 20 deletions controllers/nexus/resource/networking/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,46 @@
package networking

import (
"k8s.io/api/networking/v1beta1"
"k8s.io/apimachinery/pkg/util/intstr"
v1 "k8s.io/api/networking/v1"

"github.com/m88i/nexus-operator/api/v1alpha1"
"github.com/m88i/nexus-operator/controllers/nexus/resource/deployment"
"github.com/m88i/nexus-operator/controllers/nexus/resource/meta"
)

const (
ingressBasePath = "/"
)
const ingressBasePath = "/"

// hack to take the address of v1.PathExactType
var pathTypeExact = v1.PathTypeExact

type ingressBuilder struct {
*v1beta1.Ingress
*v1.Ingress
nexus *v1alpha1.Nexus
}

func newIngressBuilder(nexus *v1alpha1.Nexus) *ingressBuilder {
ingress := &v1beta1.Ingress{
ingress := &v1.Ingress{
ObjectMeta: meta.DefaultObjectMeta(nexus),
Spec: v1beta1.IngressSpec{
Rules: []v1beta1.IngressRule{
Spec: v1.IngressSpec{
Rules: []v1.IngressRule{
{
Host: nexus.Spec.Networking.Host,
IngressRuleValue: v1beta1.IngressRuleValue{HTTP: &v1beta1.HTTPIngressRuleValue{
Paths: []v1beta1.HTTPIngressPath{
{
Path: ingressBasePath,
Backend: v1beta1.IngressBackend{
ServiceName: nexus.Name,
ServicePort: intstr.FromInt(deployment.NexusServicePort),
IngressRuleValue: v1.IngressRuleValue{
HTTP: &v1.HTTPIngressRuleValue{
Paths: []v1.HTTPIngressPath{
{
PathType: &pathTypeExact,
Path: ingressBasePath,
Backend: v1.IngressBackend{
Service: &v1.IngressServiceBackend{
Name: nexus.Name,
Port: v1.ServiceBackendPort{Number: deployment.NexusServicePort},
},
},
},
},
},
}},
},
},
},
},
Expand All @@ -59,7 +64,7 @@ func newIngressBuilder(nexus *v1alpha1.Nexus) *ingressBuilder {
}

func (i *ingressBuilder) withCustomTLS() *ingressBuilder {
i.Spec.TLS = []v1beta1.IngressTLS{
i.Spec.TLS = []v1.IngressTLS{
{
Hosts: hosts(i.Spec.Rules),
SecretName: i.nexus.Spec.Networking.TLS.SecretName,
Expand All @@ -68,11 +73,11 @@ func (i *ingressBuilder) withCustomTLS() *ingressBuilder {
return i
}

func (i *ingressBuilder) build() *v1beta1.Ingress {
func (i *ingressBuilder) build() *v1.Ingress {
return i.Ingress
}

func hosts(rules []v1beta1.IngressRule) []string {
func hosts(rules []v1.IngressRule) []string {
var hosts []string
for _, rule := range rules {
hosts = append(hosts, rule.Host)
Expand Down
34 changes: 10 additions & 24 deletions controllers/nexus/resource/networking/ingress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ import (
"testing"

"github.com/stretchr/testify/assert"
v1 "k8s.io/api/core/v1"
"k8s.io/api/networking/v1beta1"
v1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"

"github.com/m88i/nexus-operator/api/v1alpha1"
"github.com/m88i/nexus-operator/controllers/nexus/resource/deployment"
Expand All @@ -44,38 +42,26 @@ var (
},
},
}

ingressService = &v1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "nexus3",
Namespace: "nexus",
},
Spec: v1.ServiceSpec{
Ports: []v1.ServicePort{
{TargetPort: intstr.FromInt(deployment.NexusServicePort)},
},
},
}
)

func TestHosts(t *testing.T) {
ingress := &v1beta1.Ingress{
Spec: v1beta1.IngressSpec{
Rules: []v1beta1.IngressRule{},
ingress := &v1.Ingress{
Spec: v1.IngressSpec{
Rules: []v1.IngressRule{},
},
}

h := hosts(ingress.Spec.Rules)
assert.Len(t, h, 0)

host := "a"
ingress.Spec.Rules = append(ingress.Spec.Rules, v1beta1.IngressRule{Host: host})
ingress.Spec.Rules = append(ingress.Spec.Rules, v1.IngressRule{Host: host})
h = hosts(ingress.Spec.Rules)
assert.Len(t, h, 1)
assert.Equal(t, h[0], host)

host = "b"
ingress.Spec.Rules = append(ingress.Spec.Rules, v1beta1.IngressRule{Host: host})
ingress.Spec.Rules = append(ingress.Spec.Rules, v1.IngressRule{Host: host})
h = hosts(ingress.Spec.Rules)
assert.Len(t, h, 2)
assert.Equal(t, h[1], host)
Expand All @@ -92,7 +78,7 @@ func TestNewIngressWithSecretName(t *testing.T) {
assertIngressSecretName(t, ingress)
}

func assertIngressBasic(t *testing.T, ingress *v1beta1.Ingress) {
func assertIngressBasic(t *testing.T, ingress *v1.Ingress) {
assert.Equal(t, ingressNexus.Name, ingress.Name)
assert.Equal(t, ingressNexus.Namespace, ingress.Namespace)

Expand All @@ -110,11 +96,11 @@ func assertIngressBasic(t *testing.T, ingress *v1beta1.Ingress) {

assert.Equal(t, ingressBasePath, path.Path)
assert.NotNil(t, path.Backend)
assert.Equal(t, ingressService.Spec.Ports[0].TargetPort, path.Backend.ServicePort)
assert.Equal(t, ingressService.Name, path.Backend.ServiceName)
assert.Equal(t, int32(deployment.NexusServicePort), path.Backend.Service.Port.Number)
assert.Equal(t, ingressNexus.Name, path.Backend.Service.Name)
}

func assertIngressSecretName(t *testing.T, ingress *v1beta1.Ingress) {
func assertIngressSecretName(t *testing.T, ingress *v1.Ingress) {
assert.Len(t, ingress.Spec.TLS, 1)
assert.Equal(t, ingressNexus.Spec.Networking.TLS.SecretName, ingress.Spec.TLS[0].SecretName)

Expand Down
79 changes: 79 additions & 0 deletions controllers/nexus/resource/networking/legacy_ingress.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2020 Nexus Operator and/or its authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package networking

import (
"k8s.io/api/networking/v1beta1"
"k8s.io/apimachinery/pkg/util/intstr"

"github.com/m88i/nexus-operator/api/v1alpha1"
"github.com/m88i/nexus-operator/controllers/nexus/resource/deployment"
"github.com/m88i/nexus-operator/controllers/nexus/resource/meta"
)

type legacyIngressBuilder struct {
*v1beta1.Ingress
nexus *v1alpha1.Nexus
}

func newLegacyIngressBuilder(nexus *v1alpha1.Nexus) *legacyIngressBuilder {
ingress := &v1beta1.Ingress{
ObjectMeta: meta.DefaultObjectMeta(nexus),
Spec: v1beta1.IngressSpec{
Rules: []v1beta1.IngressRule{
{
Host: nexus.Spec.Networking.Host,
IngressRuleValue: v1beta1.IngressRuleValue{
HTTP: &v1beta1.HTTPIngressRuleValue{
Paths: []v1beta1.HTTPIngressPath{
{
Path: ingressBasePath,
Backend: v1beta1.IngressBackend{
ServiceName: nexus.Name,
ServicePort: intstr.FromInt(deployment.NexusServicePort),
},
},
},
},
},
},
},
},
}

return &legacyIngressBuilder{Ingress: ingress, nexus: nexus}
}

func (i *legacyIngressBuilder) withCustomTLS() *legacyIngressBuilder {
i.Spec.TLS = []v1beta1.IngressTLS{
{
Hosts: legacyHosts(i.Spec.Rules),
SecretName: i.nexus.Spec.Networking.TLS.SecretName,
},
}
return i
}

func (i *legacyIngressBuilder) build() *v1beta1.Ingress {
return i.Ingress
}

func legacyHosts(rules []v1beta1.IngressRule) []string {
var hosts []string
for _, rule := range rules {
hosts = append(hosts, rule.Host)
}
return hosts
}
89 changes: 89 additions & 0 deletions controllers/nexus/resource/networking/legacy_ingress_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright 2020 Nexus Operator and/or its authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package networking

import (
"testing"

"github.com/stretchr/testify/assert"
"k8s.io/api/networking/v1beta1"
"k8s.io/apimachinery/pkg/util/intstr"

"github.com/m88i/nexus-operator/controllers/nexus/resource/deployment"
)

func TestLegacyHosts(t *testing.T) {
ingress := &v1beta1.Ingress{
Spec: v1beta1.IngressSpec{
Rules: []v1beta1.IngressRule{},
},
}

h := legacyHosts(ingress.Spec.Rules)
assert.Len(t, h, 0)

host := "a"
ingress.Spec.Rules = append(ingress.Spec.Rules, v1beta1.IngressRule{Host: host})
h = legacyHosts(ingress.Spec.Rules)
assert.Len(t, h, 1)
assert.Equal(t, h[0], host)

host = "b"
ingress.Spec.Rules = append(ingress.Spec.Rules, v1beta1.IngressRule{Host: host})
h = legacyHosts(ingress.Spec.Rules)
assert.Len(t, h, 2)
assert.Equal(t, h[1], host)
}

func TestNewLegacyIngress(t *testing.T) {
ingress := newLegacyIngressBuilder(ingressNexus).build()
assertLegacyIngressBasic(t, ingress)
}

func TestNewLegacyIngressWithSecretName(t *testing.T) {
ingress := newLegacyIngressBuilder(ingressNexus).withCustomTLS().build()
assertLegacyIngressBasic(t, ingress)
assertLegacyIngressSecretName(t, ingress)
}

func assertLegacyIngressBasic(t *testing.T, ingress *v1beta1.Ingress) {
assert.Equal(t, ingressNexus.Name, ingress.Name)
assert.Equal(t, ingressNexus.Namespace, ingress.Namespace)

assert.NotNil(t, ingress.Spec)

assert.Len(t, ingress.Spec.Rules, 1)
rule := ingress.Spec.Rules[0]

assert.Equal(t, ingressNexus.Spec.Networking.Host, rule.Host)
assert.NotNil(t, rule.IngressRuleValue)
assert.NotNil(t, rule.IngressRuleValue.HTTP)

assert.Len(t, rule.IngressRuleValue.HTTP.Paths, 1)
path := rule.IngressRuleValue.HTTP.Paths[0]

assert.Equal(t, ingressBasePath, path.Path)
assert.NotNil(t, path.Backend)
assert.Equal(t, intstr.FromInt(deployment.NexusServicePort), path.Backend.ServicePort)
assert.Equal(t, ingressNexus.Name, path.Backend.ServiceName)
}

func assertLegacyIngressSecretName(t *testing.T, ingress *v1beta1.Ingress) {
assert.Len(t, ingress.Spec.TLS, 1)
assert.Equal(t, ingressNexus.Spec.Networking.TLS.SecretName, ingress.Spec.TLS[0].SecretName)

assert.Len(t, ingress.Spec.TLS[0].Hosts, 1)
assert.Equal(t, ingressNexus.Spec.Networking.Host, ingress.Spec.TLS[0].Hosts[0])
}
Loading

0 comments on commit 41b9b04

Please sign in to comment.