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  }