github.com/verrazzano/verrazzano-monitoring-operator@v0.0.30/pkg/vmo/ingress.go (about) 1 // Copyright (C) 2020, 2022, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package vmo 5 6 import ( 7 "context" 8 "errors" 9 "github.com/verrazzano/pkg/diff" 10 vmcontrollerv1 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/apis/vmcontroller/v1" 11 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/constants" 12 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/metricsexporter" 13 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/resources/ingresses" 14 netv1 "k8s.io/api/networking/v1" 15 k8serrors "k8s.io/apimachinery/pkg/api/errors" 16 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 17 "k8s.io/apimachinery/pkg/labels" 18 "k8s.io/apimachinery/pkg/util/runtime" 19 ) 20 21 // CreateIngresses create/update VMO ingress k8s resources 22 func CreateIngresses(controller *Controller, vmo *vmcontrollerv1.VerrazzanoMonitoringInstance) error { 23 functionMetric, functionError := metricsexporter.GetFunctionMetrics(metricsexporter.NamesIngress) 24 if functionError == nil { 25 functionMetric.LogStart() 26 defer functionMetric.LogEnd(false) 27 } else { 28 return functionError 29 } 30 //Get existing ingresses from the cluster 31 selector := labels.SelectorFromSet(map[string]string{constants.VMOLabel: vmo.Name}) 32 existingIngressList, err := controller.ingressLister.Ingresses(vmo.Namespace).List(selector) 33 if err != nil { 34 functionMetric.IncError() 35 return err 36 } 37 38 ingList, err := ingresses.New(vmo, getExistingIngresses(existingIngressList, vmo)) 39 if err != nil { 40 controller.log.Errorf("Failed to create Ingress specs for VMI %s: %v", vmo.Name, err) 41 functionMetric.IncError() 42 return err 43 } 44 if vmo.Spec.IngressTargetDNSName == "" { 45 controller.log.Debugf("No Ingress target specified, using default Ingress target: '%s'", controller.operatorConfig.DefaultIngressTargetDNSName) 46 vmo.Spec.IngressTargetDNSName = controller.operatorConfig.DefaultIngressTargetDNSName 47 } 48 var ingressNames []string 49 controller.log.Oncef("Creating/updating Ingresses for VMI %s", vmo.Name) 50 for _, curIngress := range ingList { 51 ingName := curIngress.Name 52 ingressNames = append(ingressNames, ingName) 53 if ingName == "" { 54 // We choose to absorb the error here as the worker would requeue the 55 // resource otherwise. Instead, the next time the resource is updated 56 // the resource will be queued again. 57 runtime.HandleError(errors.New("ingress name must be specified")) 58 functionMetric.IncError() 59 return nil 60 } 61 controller.log.Debugf("Applying Ingress '%s' in namespace '%s' for VMI '%s'\n", ingName, vmo.Namespace, vmo.Name) 62 existingIngress, err := controller.ingressLister.Ingresses(vmo.Namespace).Get(ingName) 63 if existingIngress != nil { 64 specDiffs := diff.Diff(existingIngress, curIngress) 65 if specDiffs != "" { 66 controller.log.Debugf("Ingress %s : Spec differences %s", curIngress.Name, specDiffs) 67 _, err = controller.kubeclientset.NetworkingV1().Ingresses(vmo.Namespace).Update(context.TODO(), curIngress, metav1.UpdateOptions{}) 68 } 69 } else if k8serrors.IsNotFound(err) { 70 _, err = controller.kubeclientset.NetworkingV1().Ingresses(vmo.Namespace).Create(context.TODO(), curIngress, metav1.CreateOptions{}) 71 } else { 72 controller.log.Errorf("Failed getting existing Ingress %s/%s: %v", vmo.Namespace, ingName, err) 73 functionMetric.IncError() 74 return err 75 } 76 77 if err != nil { 78 controller.log.Errorf("Failed to create/update Ingress %s/%s: %v", vmo.Namespace, ingName, err) 79 functionMetric.IncError() 80 return err 81 } 82 } 83 // Delete ingresses that shouldn't exist 84 controller.log.Oncef("Deleting unwanted Ingresses for VMI %s", vmo.Name) 85 for _, ingress := range existingIngressList { 86 if !contains(ingressNames, ingress.Name) { 87 controller.log.Oncef("Deleting ingress %s", ingress.Name) 88 err := controller.kubeclientset.NetworkingV1().Ingresses(vmo.Namespace).Delete(context.TODO(), ingress.Name, metav1.DeleteOptions{}) 89 if err != nil { 90 controller.log.Errorf("Failed to delete Ingress %s/%s: %v", vmo.Namespace, ingress.Name, err) 91 return err 92 } 93 metric, metricErr := metricsexporter.GetCounterMetrics(metricsexporter.NamesIngressDeleted) 94 if metricErr != nil { 95 return metricErr 96 } 97 metric.Inc() 98 } 99 } 100 return nil 101 } 102 103 // getExistingIngresses retrieves the required ingress objects 104 func getExistingIngresses(existingIngressList []*netv1.Ingress, vmo *vmcontrollerv1.VerrazzanoMonitoringInstance) map[string]*netv1.Ingress { 105 existingIngressMap := make(map[string]*netv1.Ingress) 106 107 for _, ingress := range existingIngressList { 108 existingIngressMap[ingress.Name] = ingress 109 } 110 return existingIngressMap 111 }