From 7f1403929f928fc741668cdd44c370f278bc92a1 Mon Sep 17 00:00:00 2001 From: Manuel Alejandro de Brito Fontes Date: Tue, 31 Mar 2020 11:14:03 -0300 Subject: [PATCH] Migrate ingress.class annotation to new IngressClassName field --- cmd/nginx/flags.go | 4 ++-- cmd/nginx/main.go | 6 ++++- internal/ingress/annotations/class/main.go | 19 +++++++++------- .../ingress/annotations/class/main_test.go | 6 ++--- .../ingress/controller/controller_test.go | 6 +++-- internal/ingress/controller/store/store.go | 10 +++++++++ internal/k8s/main.go | 22 +++++++++---------- 7 files changed, 46 insertions(+), 27 deletions(-) diff --git a/cmd/nginx/flags.go b/cmd/nginx/flags.go index d2ead6b4746a..3c3464234a2f 100644 --- a/cmd/nginx/flags.go +++ b/cmd/nginx/flags.go @@ -59,8 +59,8 @@ requests to the first port of this Service.`) ingressClass = flags.String("ingress-class", "", `Name of the ingress class this controller satisfies. -The class of an Ingress object is set using the annotation "kubernetes.io/ingress.class". -All ingress classes are satisfied if this parameter is left empty.`) +The class of an Ingress object is set using the field IngressClassName. +All ingress classes are satisfied if this parameter is not set.`) configMap = flags.String("configmap", "", `Name of the ConfigMap containing custom global configurations for the controller.`) diff --git a/cmd/nginx/main.go b/cmd/nginx/main.go index e954de502ac1..b6811d394f25 100644 --- a/cmd/nginx/main.go +++ b/cmd/nginx/main.go @@ -102,11 +102,15 @@ func main() { conf.FakeCertificate = ssl.GetFakeSSLCert() klog.Infof("SSL fake certificate created %v", conf.FakeCertificate.PemFileName) - k8s.IsNetworkingIngressAvailable = k8s.NetworkingIngressAvailable(kubeClient) + k8s.IsNetworkingIngressAvailable, k8s.IsIngressV1Ready = k8s.NetworkingIngressAvailable(kubeClient) if !k8s.IsNetworkingIngressAvailable { klog.Warningf("Using deprecated \"k8s.io/api/extensions/v1beta1\" package because Kubernetes version is < v1.14.0") } + if !k8s.IsIngressV1Ready { + klog.Infof("Enabling new Ingress features availables since v1.18.0") + } + conf.Client = kubeClient reg := prometheus.NewRegistry() diff --git a/internal/ingress/annotations/class/main.go b/internal/ingress/annotations/class/main.go index fab3a9655860..a20507d135cf 100644 --- a/internal/ingress/annotations/class/main.go +++ b/internal/ingress/annotations/class/main.go @@ -17,8 +17,6 @@ limitations under the License. package class import ( - "k8s.io/klog" - networking "k8s.io/api/networking/v1beta1" ) @@ -43,10 +41,7 @@ var ( // the ingress.class annotation, or it's set to the configured in the // ingress controller. func IsValid(ing *networking.Ingress) bool { - ingress, ok := ing.GetAnnotations()[IngressKey] - if !ok { - klog.V(3).Infof("annotation %v is not present in ingress %v/%v", IngressKey, ing.Namespace, ing.Name) - } + className := ing.Spec.IngressClassName // we have 2 valid combinations // 1 - ingress with default class | blank annotation on ingress @@ -55,9 +50,17 @@ func IsValid(ing *networking.Ingress) bool { // and 2 invalid combinations // 3 - ingress with default class | fixed annotation on ingress // 4 - ingress with specific class | different annotation on ingress - if ingress == "" && IngressClass == DefaultClass { + if className != nil { + return *className == IngressClass + } + + if IngressClass == DefaultClass { + return true + } + + if IngressClass == "" { return true } - return ingress == IngressClass + return false } diff --git a/internal/ingress/annotations/class/main_test.go b/internal/ingress/annotations/class/main_test.go index f38eeb790d3b..c4c95e39ebec 100644 --- a/internal/ingress/annotations/class/main_test.go +++ b/internal/ingress/annotations/class/main_test.go @@ -54,10 +54,10 @@ func TestIsValidClass(t *testing.T) { }, } - data := map[string]string{} - ing.SetAnnotations(data) for _, test := range tests { - ing.Annotations[IngressKey] = test.ingress + if test.ingress != "" { + ing.Spec.IngressClassName = &test.ingress + } IngressClass = test.controller DefaultClass = test.defClass diff --git a/internal/ingress/controller/controller_test.go b/internal/ingress/controller/controller_test.go index 356c088a2678..ac56542985ac 100644 --- a/internal/ingress/controller/controller_test.go +++ b/internal/ingress/controller/controller_test.go @@ -190,7 +190,8 @@ func TestCheckIngress(t *testing.T) { } t.Run("When the ingress class differs from nginx", func(t *testing.T) { - ing.ObjectMeta.Annotations["kubernetes.io/ingress.class"] = "different" + class := "different" + ing.Spec.IngressClassName = &class nginx.command = testNginxTestCommand{ t: t, err: fmt.Errorf("test error"), @@ -201,7 +202,8 @@ func TestCheckIngress(t *testing.T) { }) t.Run("when the class is the nginx one", func(t *testing.T) { - ing.ObjectMeta.Annotations["kubernetes.io/ingress.class"] = "nginx" + class := "nginx" + ing.Spec.IngressClassName = &class nginx.command = testNginxTestCommand{ t: t, err: nil, diff --git a/internal/ingress/controller/store/store.go b/internal/ingress/controller/store/store.go index 3cd17ca383df..478185664827 100644 --- a/internal/ingress/controller/store/store.go +++ b/internal/ingress/controller/store/store.go @@ -949,12 +949,22 @@ func toIngress(obj interface{}) (*networkingv1beta1.Ingress, bool) { return nil, false } + ing.Spec.IngressClassName = extractClassName(ing) return ing, true } if ing, ok := obj.(*networkingv1beta1.Ingress); ok { + ing.Spec.IngressClassName = extractClassName(ing) return ing, true } return nil, false } + +func extractClassName(ing *networkingv1beta1.Ingress) *string { + if c, ok := ing.Annotations[class.IngressKey]; ok { + return &c + } + + return nil +} diff --git a/internal/k8s/main.go b/internal/k8s/main.go index 8cee61ecc28b..a62bcf5310a2 100644 --- a/internal/k8s/main.go +++ b/internal/k8s/main.go @@ -118,26 +118,26 @@ func MetaNamespaceKey(obj interface{}) string { // IsNetworkingIngressAvailable indicates if package "k8s.io/api/networking/v1beta1" is available or not var IsNetworkingIngressAvailable bool -// NetworkingIngressAvailable checks if the package "k8s.io/api/networking/v1beta1" is available or not -func NetworkingIngressAvailable(client clientset.Interface) bool { +// IsIngressV1Ready indicates if the running Kubernetes version is at least v1.18.0 +var IsIngressV1Ready bool + +// NetworkingIngressAvailable checks if the package "k8s.io/api/networking/v1beta1" +// is available or not and if Ingress V1 is supported (k8s >= v1.18.0) +func NetworkingIngressAvailable(client clientset.Interface) (bool, bool) { // check kubernetes version to use new ingress package or not - version114, err := version.ParseGeneric("v1.14.0") - if err != nil { - klog.Errorf("unexpected error parsing version: %v", err) - return false - } + version114, _ := version.ParseGeneric("v1.14.0") + version118, _ := version.ParseGeneric("v1.18.0") serverVersion, err := client.Discovery().ServerVersion() if err != nil { - klog.Errorf("unexpected error parsing Kubernetes version: %v", err) - return false + return false, false } runningVersion, err := version.ParseGeneric(serverVersion.String()) if err != nil { klog.Errorf("unexpected error parsing running Kubernetes version: %v", err) - return false + return false, false } - return runningVersion.AtLeast(version114) + return runningVersion.AtLeast(version114), runningVersion.AtLeast(version118) }