github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/verify-install/thanos/thanos_test.go (about)

     1  // Copyright (c) 2023, 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 thanos
     5  
     6  import (
     7  	"fmt"
     8  	"time"
     9  
    10  	"github.com/Jeffail/gabs/v2"
    11  	. "github.com/onsi/ginkgo/v2"
    12  	. "github.com/onsi/gomega"
    13  	"github.com/verrazzano/verrazzano/pkg/k8sutil"
    14  	"github.com/verrazzano/verrazzano/pkg/vzcr"
    15  	"github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1beta1"
    16  	"github.com/verrazzano/verrazzano/platform-operator/constants"
    17  	"github.com/verrazzano/verrazzano/tests/e2e/pkg"
    18  	"github.com/verrazzano/verrazzano/tests/e2e/pkg/test/framework"
    19  )
    20  
    21  const (
    22  	waitTimeout     = 3 * time.Minute
    23  	pollingInterval = 10 * time.Second
    24  )
    25  
    26  var t = framework.NewTestFramework("thanos")
    27  
    28  var (
    29  	isThanosSupported     bool
    30  	isThanosInstalled     bool
    31  	isStoreGatewayEnabled bool
    32  	isCompactorEnabled    bool
    33  	isRulerEnabled        bool
    34  	inClusterVZ           *v1beta1.Verrazzano
    35  )
    36  
    37  func getKubeConfigOrAbort() string {
    38  	kubeconfigPath, err := k8sutil.GetKubeConfigLocation()
    39  	if err != nil {
    40  		AbortSuite(fmt.Sprintf("Failed to get default kubeconfig path: %s", err.Error()))
    41  	}
    42  	return kubeconfigPath
    43  }
    44  
    45  var beforeSuite = t.BeforeSuiteFunc(func() {
    46  	var err error
    47  	kubeconfigPath := getKubeConfigOrAbort()
    48  	isThanosSupported, err = pkg.IsVerrazzanoMinVersion("1.6.0", kubeconfigPath)
    49  	if err != nil {
    50  		AbortSuite(fmt.Sprintf("Failed to check Verrazzano version 1.6.0: %v", err))
    51  	}
    52  
    53  	inClusterVZ, err = pkg.GetVerrazzanoInstallResourceInClusterV1beta1(kubeconfigPath)
    54  	if err != nil {
    55  		AbortSuite(fmt.Sprintf("Failed to get Verrazzano from the cluster: %v", err))
    56  	}
    57  	isThanosInstalled = vzcr.IsThanosEnabled(inClusterVZ)
    58  
    59  	if isThanosInstalled {
    60  		// check if storegateway component is enabled
    61  		isStoreGatewayEnabled, err = isThanosComponentEnabledInOverrides(inClusterVZ.Spec.Components.Thanos.InstallOverrides.ValueOverrides, "storegateway")
    62  		if err != nil {
    63  			AbortSuite(fmt.Sprintf("Failed to process VZ CR Thanos overrides for the Store Gateway: %v", err))
    64  		}
    65  		// check if compactor component is enabled
    66  		isCompactorEnabled, err = isThanosComponentEnabledInOverrides(inClusterVZ.Spec.Components.Thanos.InstallOverrides.ValueOverrides, "compactor")
    67  		if err != nil {
    68  			AbortSuite(fmt.Sprintf("Failed to process VZ CR Thanos overrides for the Compactor: %v", err))
    69  		}
    70  		isRulerEnabled, err = isThanosComponentEnabledInOverrides(inClusterVZ.Spec.Components.Thanos.InstallOverrides.ValueOverrides, "ruler")
    71  		if err != nil {
    72  			AbortSuite(fmt.Sprintf("Failed to process VZ CR Thanos overrides for the Ruler: %v", err))
    73  		}
    74  	}
    75  })
    76  
    77  // isThanosComponentEnabledInOverrides returns true if the specified Thanos component is enabled in the VZ CR overrides
    78  func isThanosComponentEnabledInOverrides(overrides []v1beta1.Overrides, thanosCompName string) (bool, error) {
    79  	for _, override := range inClusterVZ.Spec.Components.Thanos.InstallOverrides.ValueOverrides {
    80  		if override.Values != nil {
    81  			jsonString, err := gabs.ParseJSON(override.Values.Raw)
    82  			if err != nil {
    83  				return false, err
    84  			}
    85  			if container := jsonString.Path(fmt.Sprintf("%s.enabled", thanosCompName)); container != nil {
    86  				if enabled, ok := container.Data().(bool); ok {
    87  					return enabled, nil
    88  				}
    89  			}
    90  		}
    91  	}
    92  	return false, nil
    93  }
    94  
    95  var _ = BeforeSuite(beforeSuite)
    96  
    97  // 'It' Wrapper to only run spec if the Thanos is supported on the current Verrazzano version and is installed
    98  func WhenThanosInstalledIt(description string, f func()) {
    99  	t.It(description, func() {
   100  		if isThanosSupported && isThanosInstalled {
   101  			f()
   102  		} else {
   103  			t.Logs.Infof("Skipping check '%v', Thanos is not installed on this cluster", description)
   104  		}
   105  	})
   106  }
   107  
   108  var _ = t.Describe("Thanos", Label("f:platform-lcm.install"), func() {
   109  	t.Context("after successful installation", func() {
   110  		// GIVEN the Thanos is installed
   111  		// WHEN we check to make sure the pods exist
   112  		// THEN we successfully find the pods in the cluster
   113  		WhenThanosInstalledIt("expected pods are running", func() {
   114  			pods := []string{"thanos-query", "thanos-query-frontend"}
   115  			if isStoreGatewayEnabled {
   116  				pods = append(pods, "thanos-storegateway")
   117  			}
   118  			if isCompactorEnabled {
   119  				pods = append(pods, "thanos-compactor")
   120  			}
   121  			if isRulerEnabled {
   122  				pods = append(pods, "thanos-ruler")
   123  			}
   124  			t.Logs.Infof("Expected Thanos pods: %v", pods)
   125  
   126  			Eventually(func() (bool, error) {
   127  				result, err := pkg.PodsRunning(constants.VerrazzanoMonitoringNamespace, pods)
   128  				if err != nil {
   129  					t.Logs.Errorf("Pods %v are not running in the namespace: %v, error: %v", pods, constants.VerrazzanoMonitoringNamespace, err)
   130  				}
   131  				return result, err
   132  			}, waitTimeout, pollingInterval).Should(BeTrue(), "Expected Thanos Pods should be running")
   133  		})
   134  
   135  		// GIVEN the Thanos is installed
   136  		// WHEN we check to make sure the ingresses have been created
   137  		// THEN we successfully find the ingresses in the cluster
   138  		WhenThanosInstalledIt("Thanos ingresses exist", func() {
   139  			ingresses := []string{"thanos-query-frontend", "thanos-query-store"}
   140  			if isRulerEnabled {
   141  				ingresses = append(ingresses, "thanos-ruler")
   142  			}
   143  
   144  			t.Logs.Infof("Expected Thanos ingresses %v", ingresses)
   145  			Eventually(func() (bool, error) {
   146  				return pkg.IngressesExist(inClusterVZ, constants.VerrazzanoSystemNamespace, ingresses)
   147  			}, waitTimeout, pollingInterval).Should(BeTrue(), "Expected Thanos Ingresses should exist")
   148  		})
   149  
   150  		// GIVEN the Thanos is installed
   151  		// WHEN the ingresses exist
   152  		// THEN they should be accessible
   153  		WhenThanosInstalledIt("Thanos ingresses should be accessible", func() {
   154  			if pkg.IsManagedClusterProfile() {
   155  				Skip("Skip verifying ingress accessibility for managed clusters")
   156  			}
   157  			httpClient := pkg.EventuallyVerrazzanoRetryableHTTPClient()
   158  			creds := pkg.EventuallyGetSystemVMICredentials()
   159  			urls := []*string{
   160  				inClusterVZ.Status.VerrazzanoInstance.ThanosQueryURL,
   161  			}
   162  			if isRulerEnabled {
   163  				urls = append(urls, inClusterVZ.Status.VerrazzanoInstance.ThanosRulerURL)
   164  			}
   165  
   166  			Eventually(func() bool {
   167  				for _, url := range urls {
   168  					if !pkg.AssertURLAccessibleAndAuthorized(httpClient, *url, creds) {
   169  						return false
   170  					}
   171  				}
   172  				return true
   173  			}).WithPolling(pollingInterval).WithTimeout(waitTimeout).Should(BeTrue())
   174  		})
   175  
   176  		// GIVEN the Thanos is installed
   177  		// WHEN the ruler is enabled
   178  		// THEN the rule data from Prometheus should be synced
   179  		WhenThanosInstalledIt("Thanos ruler should contain rules populated from Prometheus", func() {
   180  			if !isRulerEnabled {
   181  				Skip("Skipping Rule verification because Ruler is not enabled")
   182  			}
   183  
   184  			kubeconfigPath := getKubeConfigOrAbort()
   185  			Eventually(func() (interface{}, error) {
   186  				return pkg.GetRulesFromThanosRuler(kubeconfigPath)
   187  			}).WithPolling(pollingInterval).WithTimeout(waitTimeout).ShouldNot(BeNil())
   188  		})
   189  	})
   190  })