github.com/verrazzano/verrazzano-monitoring-operator@v0.0.30/pkg/vmo/service.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  
    10  	"github.com/verrazzano/pkg/diff"
    11  	vmcontrollerv1 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/apis/vmcontroller/v1"
    12  	"github.com/verrazzano/verrazzano-monitoring-operator/pkg/constants"
    13  	"github.com/verrazzano/verrazzano-monitoring-operator/pkg/metricsexporter"
    14  	"github.com/verrazzano/verrazzano-monitoring-operator/pkg/resources/services"
    15  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    16  	"k8s.io/apimachinery/pkg/labels"
    17  	"k8s.io/apimachinery/pkg/util/runtime"
    18  )
    19  
    20  // CreateServices creates/updates/deletes VMO service k8s resources
    21  func CreateServices(controller *Controller, vmo *vmcontrollerv1.VerrazzanoMonitoringInstance) error {
    22  	counter, counterErr := metricsexporter.GetCounterMetrics(metricsexporter.NamesServices)
    23  	if counterErr != nil {
    24  		return counterErr
    25  	}
    26  	counter.Inc()
    27  
    28  	useNodeRoleSelectors, err := clusterHasNodeRoleSelectors(controller, vmo)
    29  	if err != nil {
    30  		controller.log.Errorf("Failed to check node role selectors when creating services for VMI %s: %s", vmo.Name, err)
    31  		return err
    32  	}
    33  
    34  	svcList, err := services.New(vmo, useNodeRoleSelectors)
    35  	if err != nil {
    36  		controller.log.Errorf("Failed to create Services for VMI %s: %v", vmo.Name, err)
    37  		return err
    38  	}
    39  	var serviceNames []string
    40  	controller.log.Oncef("Creating/updating Services for VMI %s", vmo.Name)
    41  	for _, curService := range svcList {
    42  		serviceName := curService.Name
    43  		serviceNames = append(serviceNames, serviceName)
    44  		if serviceName == "" {
    45  			// We choose to absorb the error here as the worker would requeue the
    46  			// resource otherwise. Instead, the next time the resource is updated
    47  			// the resource will be queued again.
    48  			runtime.HandleError(errors.New("service name must be specified"))
    49  			return nil
    50  		}
    51  
    52  		controller.log.Debugf("Applying Service '%s' in namespace '%s' for VMI '%s'\n", serviceName, vmo.Namespace, vmo.Name)
    53  		existingService, err := controller.serviceLister.Services(vmo.Namespace).Get(serviceName)
    54  		if existingService != nil {
    55  			specDiffs := diff.Diff(existingService, curService)
    56  			if specDiffs != "" {
    57  				controller.log.Debugf("Service %s : Spec differences %s", curService.Name, specDiffs)
    58  				err = controller.kubeclientset.CoreV1().Services(vmo.Namespace).Delete(context.TODO(), serviceName, metav1.DeleteOptions{})
    59  				if err != nil {
    60  					controller.log.Errorf("Failed to delete service %s: %v", serviceName, err)
    61  				}
    62  				_, err = controller.kubeclientset.CoreV1().Services(vmo.Namespace).Create(context.TODO(), curService, metav1.CreateOptions{})
    63  			}
    64  		} else {
    65  			_, err = controller.kubeclientset.CoreV1().Services(vmo.Namespace).Create(context.TODO(), curService, metav1.CreateOptions{})
    66  		}
    67  
    68  		if err != nil {
    69  			controller.log.Errorf("Failed to apply Service for VMI %s: %v", vmo.Name, err)
    70  			return err
    71  		}
    72  		controller.log.Debugf("Successfully applied Service '%s'\n", serviceName)
    73  		metric, metricErr := metricsexporter.GetCounterMetrics(metricsexporter.NamesServicesCreated)
    74  		if metricErr != nil {
    75  			return metricErr
    76  		}
    77  		metric.Inc()
    78  	}
    79  
    80  	// Delete services that shouldn't exist
    81  	selector := labels.SelectorFromSet(map[string]string{constants.VMOLabel: vmo.Name})
    82  	existingServicesList, err := controller.serviceLister.Services(vmo.Namespace).List(selector)
    83  	if err != nil {
    84  		return err
    85  	}
    86  	for _, service := range existingServicesList {
    87  		if !contains(serviceNames, service.Name) {
    88  			controller.log.Debugf("Deleting service %s", service.Name)
    89  			err := controller.kubeclientset.CoreV1().Services(vmo.Namespace).Delete(context.TODO(), service.Name, metav1.DeleteOptions{})
    90  			if err != nil {
    91  				controller.log.Errorf("Failed to delete service %s: %v", service.Name, err)
    92  				return err
    93  			}
    94  		}
    95  	}
    96  	metric, metricErr := metricsexporter.GetTimestampMetrics(metricsexporter.NamesServices)
    97  	if metricErr != nil {
    98  		return metricErr
    99  	}
   100  	metric.SetLastTime()
   101  	return nil
   102  }
   103  
   104  func clusterHasNodeRoleSelectors(controller *Controller, vmo *vmcontrollerv1.VerrazzanoMonitoringInstance) (bool, error) {
   105  	selector := services.OpenSearchPodSelector(vmo.Name)
   106  	pods, err := controller.kubeclientset.CoreV1().Pods(vmo.Namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: selector})
   107  	if err != nil {
   108  		return false, err
   109  	}
   110  	return services.UseNodeRoleSelector(pods), nil
   111  }