Repository: appvia/kev (go)

Issue:
Update transform code to use v1 for networking API instead of v1beta
Current `pkg/kev/converter/kubernetes/transform.go` code uses v1beta for the Ingress components; update to v1 for this


Pull request description:
Bump k8s ingress api to v1
Resolves #616 

This PR updates generated ingress object to `v1` from previous `v1beta1`. 

Patch:
diff --git a/docs/reference/config-params.md b/docs/reference/config-params.md
index 7e24d34..83e2a2d 100644
--- a/docs/reference/config-params.md
+++ b/docs/reference/config-params.md
@@ -1114,7 +1114,9 @@ Defines how to expose the service externally. By default, all component services
 #### Possible options:
 
 - "default" - ingress will be created with Kubernetes cluster defaults.
-- "domain.com,otherdomain.com..." - comma separated list of domains for the ingress.
+- "domain.com" - a single domain name for the ingress.
+- "domain.com/foo" - a single domain name with a path.
+- "domain.com,otherdomain.com/bar,..." - comma separated list of domains (with or without path) for the ingress.
 
 #### Default: `""` - No ingress will be created!
 
diff --git a/pkg/kev/converter/kubernetes/transform.go b/pkg/kev/converter/kubernetes/transform.go
index f48601c..d4657a9 100644
--- a/pkg/kev/converter/kubernetes/transform.go
+++ b/pkg/kev/converter/kubernetes/transform.go
@@ -44,7 +44,7 @@ import (
 	v1batch "k8s.io/api/batch/v1"
 	v1 "k8s.io/api/core/v1"
 	networking "k8s.io/api/networking/v1"
-	networkingv1beta1 "k8s.io/api/networking/v1beta1"
+	networkingv1 "k8s.io/api/networking/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -645,38 +645,39 @@ func (k *Kubernetes) initJob(projectService ProjectService, replicas int) *v1bat
 
 // initIngress initialises ingress object
 // @orig: https://github.com/kubernetes/kompose/blob/master/pkg/transformer/kubernetes/kubernetes.go#L446
-// @todo change to networkingv1 after migration to k8s 0.19
-func (k *Kubernetes) initIngress(projectService ProjectService, port int32) *networkingv1beta1.Ingress {
+func (k *Kubernetes) initIngress(projectService ProjectService, port int32) *networkingv1.Ingress {
 	expose, _ := projectService.exposeService()
 	if expose == "" {
 		return nil
 	}
 	hosts := regexp.MustCompile("[ ,]*,[ ,]*").Split(expose, -1)
 
-	ingress := &networkingv1beta1.Ingress{
+	ingress := &networkingv1.Ingress{
 		TypeMeta: meta.TypeMeta{
 			Kind:       "Ingress",
-			APIVersion: "networking.k8s.io/v1beta1",
+			APIVersion: "networking.k8s.io/v1",
 		},
 		ObjectMeta: meta.ObjectMeta{
 			Name:        projectService.Name,
 			Labels:      configLabels(projectService.Name),
 			Annotations: projectService.ingressAnnotations(),
 		},
-		Spec: networkingv1beta1.IngressSpec{},
+		Spec: networkingv1.IngressSpec{},
 	}
 
 	if hasDefaultIngressBackendKeyword(hosts) {
-		ingress.Spec.Backend = &networkingv1beta1.IngressBackend{
-			ServiceName: projectService.Name,
-			ServicePort: intstr.IntOrString{
-				IntVal: port,
+		ingress.Spec.DefaultBackend = &networkingv1.IngressBackend{
+			Service: &networkingv1.IngressServiceBackend{
+				Name: projectService.Name,
+				Port: networkingv1.ServiceBackendPort{
+					Number: port,
+				},
 			},
 		}
 		return ingress
 	}
 
-	var ingressRules []networkingv1beta1.IngressRule
+	var ingressRules []networkingv1.IngressRule
 	for _, host := range hosts {
 		host, p := parseIngressPath(host)
 		ingressRules = append(ingressRules, createIngressRule(host, p, projectService.Name, port))
@@ -685,7 +686,7 @@ func (k *Kubernetes) initIngress(projectService ProjectService, port int32) *net
 
 	tlsSecretName := projectService.tlsSecretName()
 	if tlsSecretName != "" {
-		ingress.Spec.TLS = []networkingv1beta1.IngressTLS{
+		ingress.Spec.TLS = []networkingv1.IngressTLS{
 			{
 				Hosts:      hosts,
 				SecretName: tlsSecretName,
diff --git a/pkg/kev/converter/kubernetes/utils.go b/pkg/kev/converter/kubernetes/utils.go
index 124cb97..2c3d30c 100644
--- a/pkg/kev/converter/kubernetes/utils.go
+++ b/pkg/kev/converter/kubernetes/utils.go
@@ -40,12 +40,11 @@ import (
 	"github.com/pkg/errors"
 	"gopkg.in/yaml.v3"
 	v1 "k8s.io/api/core/v1"
-	networkingv1beta1 "k8s.io/api/networking/v1beta1"
+	networkingv1 "k8s.io/api/networking/v1"
 	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
-	"k8s.io/apimachinery/pkg/util/intstr"
 )
 
 // Selector used as labels and selector
@@ -962,18 +961,23 @@ func hasDefaultIngressBackendKeyword(v []string) bool {
 }
 
 // createIngressRule creates an ingress rule using a set of parameters.
-func createIngressRule(host, path, serviceName string, port int32) networkingv1beta1.IngressRule {
-	return networkingv1beta1.IngressRule{
+func createIngressRule(host, path, serviceName string, port int32) networkingv1.IngressRule {
+	pathType := networkingv1.PathTypeImplementationSpecific
+
+	return networkingv1.IngressRule{
 		Host: host,
-		IngressRuleValue: networkingv1beta1.IngressRuleValue{
-			HTTP: &networkingv1beta1.HTTPIngressRuleValue{
-				Paths: []networkingv1beta1.HTTPIngressPath{
+		IngressRuleValue: networkingv1.IngressRuleValue{
+			HTTP: &networkingv1.HTTPIngressRuleValue{
+				Paths: []networkingv1.HTTPIngressPath{
 					{
-						Path: path,
-						Backend: networkingv1beta1.IngressBackend{
-							ServiceName: serviceName,
-							ServicePort: intstr.IntOrString{
-								IntVal: port,
+						Path:     path,
+						PathType: &pathType,
+						Backend: networkingv1.IngressBackend{
+							Service: &networkingv1.IngressServiceBackend{
+								Name: serviceName,
+								Port: networkingv1.ServiceBackendPort{
+									Number: port,
+								},
 							},
 						},
 					},


Test patch:
diff --git a/pkg/kev/converter/kubernetes/transform_test.go b/pkg/kev/converter/kubernetes/transform_test.go
index 0d57c75..c2cd0e4 100644
--- a/pkg/kev/converter/kubernetes/transform_test.go
+++ b/pkg/kev/converter/kubernetes/transform_test.go
@@ -32,9 +32,7 @@ import (
 	v1apps "k8s.io/api/apps/v1"
 	v1batch "k8s.io/api/batch/v1"
 	v1 "k8s.io/api/core/v1"
-	"k8s.io/api/extensions/v1beta1"
-	networking "k8s.io/api/networking/v1"
-	networkingv1beta1 "k8s.io/api/networking/v1beta1"
+	networkingv1 "k8s.io/api/networking/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -922,29 +920,34 @@ var _ = Describe("Transform", func() {
 			It("initialises Ingress with a port routing to the project service name", func() {
 				ing := k.initIngress(projectService, port)
 
-				Expect(ing).To(Equal(&networkingv1beta1.Ingress{
+				pathType := networkingv1.PathTypeImplementationSpecific
+
+				Expect(ing).To(Equal(&networkingv1.Ingress{
 					TypeMeta: meta.TypeMeta{
 						Kind:       "Ingress",
-						APIVersion: "networking.k8s.io/v1beta1",
+						APIVersion: "networking.k8s.io/v1",
 					},
 					ObjectMeta: meta.ObjectMeta{
 						Name:        projectService.Name,
 						Labels:      configLabels(projectService.Name),
 						Annotations: ingressAnnotations,
 					},
-					Spec: networkingv1beta1.IngressSpec{
-						Rules: []networkingv1beta1.IngressRule{
+					Spec: networkingv1.IngressSpec{
+						Rules: []networkingv1.IngressRule{
 							{
 								Host: domain,
-								IngressRuleValue: networkingv1beta1.IngressRuleValue{
-									HTTP: &networkingv1beta1.HTTPIngressRuleValue{
-										Paths: []networkingv1beta1.HTTPIngressPath{
+								IngressRuleValue: networkingv1.IngressRuleValue{
+									HTTP: &networkingv1.HTTPIngressRuleValue{
+										Paths: []networkingv1.HTTPIngressPath{
 											{
-												Path: "",
-												Backend: networkingv1beta1.IngressBackend{
-													ServiceName: projectService.Name,
-													ServicePort: intstr.IntOrString{
-														IntVal: port,
+												Path:     "",
+												PathType: &pathType,
+												Backend: networkingv1.IngressBackend{
+													Service: &networkingv1.IngressServiceBackend{
+														Name: projectService.Name,
+														Port: networkingv1.ServiceBackendPort{
+															Number: port,
+														},
 													},
 												},
 											},
@@ -965,13 +968,13 @@ var _ = Describe("Transform", func() {
 
 			It("initialises Ingress with the correct service", func() {
 				ingress := k.initIngress(projectService, port)
-				configuredService := ingress.Spec.Rules[0].IngressRuleValue.HTTP.Paths[0].Backend.ServiceName
+				configuredService := ingress.Spec.Rules[0].IngressRuleValue.HTTP.Paths[0].Backend.Service.Name
 				Expect(configuredService).To(Equal(projectService.Name))
 			})
 
 			It("initialises Ingress with the correct port", func() {
 				ingress := k.initIngress(projectService, port)
-				configuredPort := ingress.Spec.Rules[0].IngressRuleValue.HTTP.Paths[0].Backend.ServicePort.IntVal
+				configuredPort := ingress.Spec.Rules[0].IngressRuleValue.HTTP.Paths[0].Backend.Service.Port.Number
 				Expect(configuredPort).To(Equal(port))
 			})
 		})
@@ -1020,8 +1023,8 @@ var _ = Describe("Transform", func() {
 
 			It("creates a default backend in the initialised Ingress with no rules`", func() {
 				ingress := k.initIngress(projectService, port)
-				Expect(ingress.Spec.Backend.ServiceName).To(Equal(projectService.Name))
-				Expect(ingress.Spec.Backend.ServicePort.IntVal).To(Equal(port))
+				Expect(ingress.Spec.DefaultBackend.Service.Name).To(Equal(projectService.Name))
+				Expect(ingress.Spec.DefaultBackend.Service.Port.Number).To(Equal(port))
 				Expect(ingress.Spec.Rules).To(HaveLen(0))
 			})
 		})
@@ -1052,7 +1055,7 @@ var _ = Describe("Transform", func() {
 			It("will include it in the ingress spec", func() {
 				ing := k.initIngress(projectService, port)
 
-				Expect(ing.Spec.TLS).To(Equal([]networkingv1beta1.IngressTLS{
+				Expect(ing.Spec.TLS).To(Equal([]networkingv1.IngressTLS{
 					{
 						Hosts:      []string{"domain.name"},
 						SecretName: "my-tls-secret",
@@ -2013,7 +2016,7 @@ var _ = Describe("Transform", func() {
 		networkName := "foo"
 
 		It("creates network policy", func() {
-			Expect(k.createNetworkPolicy(projectServiceName, networkName)).To(Equal(&networking.NetworkPolicy{
+			Expect(k.createNetworkPolicy(projectServiceName, networkName)).To(Equal(&networkingv1.NetworkPolicy{
 				TypeMeta: meta.TypeMeta{
 					Kind:       "NetworkPolicy",
 					APIVersion: "networking.k8s.io/v1",
@@ -2021,12 +2024,12 @@ var _ = Describe("Transform", func() {
 				ObjectMeta: meta.ObjectMeta{
 					Name: networkName,
 				},
-				Spec: networking.NetworkPolicySpec{
+				Spec: networkingv1.NetworkPolicySpec{
 					PodSelector: meta.LabelSelector{
 						MatchLabels: map[string]string{NetworkLabel + "/" + networkName: "true"},
 					},
-					Ingress: []networking.NetworkPolicyIngressRule{{
-						From: []networking.NetworkPolicyPeer{{
+					Ingress: []networkingv1.NetworkPolicyIngressRule{{
+						From: []networkingv1.NetworkPolicyPeer{{
 							PodSelector: &meta.LabelSelector{
 								MatchLabels: map[string]string{NetworkLabel + "/" + networkName: "true"},
 							},
@@ -2171,6 +2174,8 @@ var _ = Describe("Transform", func() {
 
 					projectService.Extensions = map[string]interface{}{config.K8SExtensionKey: m}
 					projectService, err = NewProjectService(projectService.ServiceConfig)
+
+					Expect(err).NotTo(HaveOccurred())
 				})
 
 				It("doesn't include readiness probe definition in the pod spec", func() {
@@ -2184,7 +2189,7 @@ var _ = Describe("Transform", func() {
 
 	Describe("sortServicesFirst", func() {
 		objs := []runtime.Object{
-			&v1beta1.Deployment{
+			&v1apps.Deployment{
 				TypeMeta: meta.TypeMeta{
 					Kind: "Deployment",
 				},
@@ -2233,7 +2238,7 @@ var _ = Describe("Transform", func() {
 		})
 
 		Context("with non-duplicate objects", func() {
-			objs := append(objs, &v1beta1.Deployment{
+			objs := append(objs, &v1apps.Deployment{
 				TypeMeta: meta.TypeMeta{
 					Kind: "Deployment",
 				},
diff --git a/pkg/kev/converter/kubernetes/utils_test.go b/pkg/kev/converter/kubernetes/utils_test.go
index ebed9fe..c1d01bd 100644
--- a/pkg/kev/converter/kubernetes/utils_test.go
+++ b/pkg/kev/converter/kubernetes/utils_test.go
@@ -23,8 +23,8 @@ import (
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
 	"github.com/sirupsen/logrus"
+	v1apps "k8s.io/api/apps/v1"
 	v1 "k8s.io/api/core/v1"
-	"k8s.io/api/extensions/v1beta1"
 	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/apimachinery/pkg/runtime/schema"
@@ -70,10 +70,10 @@ var _ = Describe("Utils", func() {
 			})
 
 			Context("when schema group version is empty", func() {
-				o := &v1beta1.Deployment{
+				o := &v1apps.Deployment{
 					TypeMeta: meta.TypeMeta{
 						Kind:       "Deployment",
-						APIVersion: "extensions/v1beta1",
+						APIVersion: "apps/v1",
 					},
 				}
 				gv := schema.GroupVersion{}
@@ -84,8 +84,8 @@ var _ = Describe("Utils", func() {
 
 					info := versioned.DeepCopyObject().GetObjectKind().GroupVersionKind()
 					Expect(info.Kind).To(Equal("Deployment"))
-					Expect(info.Version).To(Equal("v1beta1"))
-					Expect(info.Group).To(Equal("extensions"))
+					Expect(info.Version).To(Equal("v1"))
+					Expect(info.Group).To(Equal("apps"))
 					Expect(err).ToNot(HaveOccurred())
 				})
 			})