github.com/verrazzano/verrazzano-monitoring-operator@v0.0.30/pkg/vmo/configmap_test.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  	"fmt"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/prometheus/client_golang/prometheus/testutil"
    13  	"github.com/verrazzano/verrazzano-monitoring-operator/pkg/config"
    14  	"github.com/verrazzano/verrazzano-monitoring-operator/pkg/metricsexporter"
    15  	"github.com/verrazzano/verrazzano-monitoring-operator/pkg/resources"
    16  	"github.com/verrazzano/verrazzano-monitoring-operator/pkg/resources/configmaps"
    17  	"github.com/verrazzano/verrazzano-monitoring-operator/pkg/util/logs/vzlog"
    18  
    19  	"github.com/verrazzano/verrazzano-monitoring-operator/pkg/constants"
    20  	corelistersv1 "k8s.io/client-go/listers/core/v1"
    21  
    22  	"github.com/stretchr/testify/assert"
    23  	vmctl "github.com/verrazzano/verrazzano-monitoring-operator/pkg/apis/vmcontroller/v1"
    24  	v1 "k8s.io/api/core/v1"
    25  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    26  	"k8s.io/apimachinery/pkg/labels"
    27  	"k8s.io/client-go/kubernetes"
    28  
    29  	"k8s.io/client-go/kubernetes/fake"
    30  )
    31  
    32  func TestCreateConfigmaps(t *testing.T) {
    33  	client := fake.NewSimpleClientset()
    34  	controller := &Controller{
    35  		kubeclientset:   client,
    36  		configMapLister: &simpleConfigMapLister{kubeClient: client},
    37  		secretLister:    &simpleSecretLister{kubeClient: client},
    38  		log:             vzlog.DefaultLogger(),
    39  	}
    40  	vmo := &vmctl.VerrazzanoMonitoringInstance{}
    41  	vmo.Name = constants.VMODefaultName
    42  	vmo.Namespace = constants.VerrazzanoSystemNamespace
    43  	vmo.Spec.URI = "vmi.system.v8o-env.oracledx.com"
    44  	vmo.Spec.Grafana.DashboardsConfigMap = "myDashboardsConfigMap"
    45  	vmo.Spec.Grafana.DatasourcesConfigMap = "myDatasourcesConfigMap"
    46  
    47  	previousCount := testutil.ToFloat64(metricsexporter.TestDelegate.GetCounterMetric(metricsexporter.NamesConfigMap))
    48  
    49  	err := CreateConfigmaps(controller, vmo)
    50  	t.Logf("Error is %v", err)
    51  	assert.Nil(t, err)
    52  	all, _ := client.CoreV1().ConfigMaps(vmo.Namespace).List(context.TODO(), metav1.ListOptions{})
    53  	assert.Equal(t, 2, len(all.Items))
    54  
    55  	newCount := testutil.ToFloat64(metricsexporter.TestDelegate.GetCounterMetric(metricsexporter.NamesConfigMap))
    56  	newTimeStamp := testutil.ToFloat64(metricsexporter.TestDelegate.GetTimestampMetric(metricsexporter.NamesConfigMap).WithLabelValues(fmt.Sprintf("%v", newCount)))
    57  	assert.Equal(t, previousCount+1, newCount)
    58  	assert.LessOrEqual(t, int64(newTimeStamp*10)/10, time.Now().Unix())
    59  }
    60  
    61  // simple ConfigMapLister implementation
    62  type simpleConfigMapLister struct {
    63  	kubeClient kubernetes.Interface
    64  }
    65  
    66  // lists all ConfigMaps
    67  func (s *simpleConfigMapLister) List(selector labels.Selector) ([]*v1.ConfigMap, error) {
    68  	namespaces, err := s.kubeClient.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	var pods []*v1.ConfigMap
    73  	for _, namespace := range namespaces.Items {
    74  
    75  		list, err := s.ConfigMaps(namespace.Name).List(selector)
    76  		if err != nil {
    77  			return nil, err
    78  		}
    79  		pods = append(pods, list...)
    80  	}
    81  	return pods, nil
    82  }
    83  
    84  // ConfigMaps returns an object that can list and get ConfigMaps.
    85  func (s *simpleConfigMapLister) ConfigMaps(namespace string) corelistersv1.ConfigMapNamespaceLister {
    86  	return simpleConfigMapNamespaceLister{
    87  		namespace:  namespace,
    88  		kubeClient: s.kubeClient,
    89  	}
    90  }
    91  
    92  // configMapNamespaceLister implements the ConfigMapNamespaceLister
    93  // interface.
    94  type simpleConfigMapNamespaceLister struct {
    95  	namespace  string
    96  	kubeClient kubernetes.Interface
    97  }
    98  
    99  // List lists all ConfigMaps for a given namespace.
   100  func (s simpleConfigMapNamespaceLister) List(selector labels.Selector) ([]*v1.ConfigMap, error) {
   101  	var configMaps []*v1.ConfigMap
   102  
   103  	list, err := s.kubeClient.CoreV1().ConfigMaps(s.namespace).List(context.TODO(), metav1.ListOptions{})
   104  	if err != nil {
   105  		return nil, err
   106  	}
   107  	for i := range list.Items {
   108  		if selector.Matches(labels.Set(list.Items[i].Labels)) {
   109  			configMaps = append(configMaps, &list.Items[i])
   110  		}
   111  	}
   112  	return configMaps, nil
   113  }
   114  
   115  // Get retrieves the ConfigMap for a given namespace and name.
   116  func (s simpleConfigMapNamespaceLister) Get(name string) (*v1.ConfigMap, error) {
   117  	return s.kubeClient.CoreV1().ConfigMaps(s.namespace).Get(context.TODO(), name, metav1.GetOptions{})
   118  }
   119  
   120  // simple SecretLister implementation
   121  type simpleSecretLister struct {
   122  	kubeClient kubernetes.Interface
   123  }
   124  
   125  // lists all Secrets
   126  func (s *simpleSecretLister) List(selector labels.Selector) ([]*v1.Secret, error) {
   127  	namespaces, err := s.kubeClient.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
   128  	if err != nil {
   129  		return nil, err
   130  	}
   131  	var secrets []*v1.Secret
   132  	for _, namespace := range namespaces.Items {
   133  
   134  		list, err := s.Secrets(namespace.Name).List(selector)
   135  		if err != nil {
   136  			return nil, err
   137  		}
   138  		secrets = append(secrets, list...)
   139  	}
   140  	return secrets, nil
   141  }
   142  
   143  // Secrets returns an object that can get Secrets.
   144  func (s *simpleSecretLister) Secrets(namespace string) corelistersv1.SecretNamespaceLister {
   145  	return simpleSecretNamespaceLister{
   146  		namespace:  namespace,
   147  		kubeClient: s.kubeClient,
   148  	}
   149  }
   150  
   151  // simpleSecretNamespaceLister implements the SecretNamespaceLister
   152  // interface.
   153  type simpleSecretNamespaceLister struct {
   154  	namespace  string
   155  	kubeClient kubernetes.Interface
   156  }
   157  
   158  // List lists all Secrets for a given namespace.
   159  func (s simpleSecretNamespaceLister) List(selector labels.Selector) ([]*v1.Secret, error) {
   160  	var secrets []*v1.Secret
   161  
   162  	list, err := s.kubeClient.CoreV1().Secrets(s.namespace).List(context.TODO(), metav1.ListOptions{})
   163  	if err != nil {
   164  		return nil, err
   165  	}
   166  	for i := range list.Items {
   167  		if selector.Matches(labels.Set(list.Items[i].Labels)) {
   168  			secrets = append(secrets, &list.Items[i])
   169  		}
   170  	}
   171  	return secrets, nil
   172  }
   173  
   174  // Get retrieves the Secret for a given namespace and name.
   175  func (s simpleSecretNamespaceLister) Get(name string) (*v1.Secret, error) {
   176  	return s.kubeClient.CoreV1().Secrets(s.namespace).Get(context.TODO(), name, metav1.GetOptions{})
   177  }
   178  
   179  // TestCreateUpdateDatasourcesConfigMap tests the createUpdateDatasourcesConfigMap function
   180  func TestCreateUpdateDatasourcesConfigMap(t *testing.T) {
   181  	const configMapName = "myDatasourcesConfigMap"
   182  
   183  	// GIVEN a Grafana datasources configmap exists and the Prometheus URL is the legacy URL
   184  	//  WHEN we call the createUpdateDatasourcesConfigMap
   185  	//  THEN the configmap is updated and the Prometheus URL points to the new Prometheus instance
   186  	vmo := &vmctl.VerrazzanoMonitoringInstance{}
   187  	vmo.Name = constants.VMODefaultName
   188  	vmo.Namespace = constants.VerrazzanoSystemNamespace
   189  
   190  	// set the Prometheus URL to the legacy URL
   191  	replaceMap := map[string]string{constants.GrafanaTmplPrometheusURI: resources.GetMetaName(vmo.Name, config.Prometheus.Name),
   192  		constants.GrafanaTmplAlertManagerURI: ""}
   193  	dataSourceTemplate, err := asDashboardTemplate(constants.DataSourcesTmpl, replaceMap)
   194  	assert.NoError(t, err)
   195  
   196  	cm := configmaps.NewConfig(vmo, configMapName, map[string]string{datasourceYAMLKey: dataSourceTemplate})
   197  
   198  	client := fake.NewSimpleClientset(cm)
   199  	controller := &Controller{
   200  		kubeclientset:   client,
   201  		configMapLister: &simpleConfigMapLister{kubeClient: client},
   202  		secretLister:    &simpleSecretLister{kubeClient: client},
   203  		log:             vzlog.DefaultLogger(),
   204  	}
   205  
   206  	err = createUpdateDatasourcesConfigMap(controller, vmo, configMapName, map[string]string{})
   207  	assert.NoError(t, err)
   208  
   209  	// fetch the configmap, the Prometheus URL should now be the new Prometheus URL
   210  	cm, err = client.CoreV1().ConfigMaps(vmo.Namespace).Get(context.TODO(), configMapName, metav1.GetOptions{})
   211  	assert.NoError(t, err)
   212  	assert.Contains(t, cm.Data[datasourceYAMLKey], "url: http://"+prometheusOperatorPrometheusHost+":9090")
   213  }