github.com/verrazzano/verrazzano-monitoring-operator@v0.0.30/pkg/resources/deployments/deployment_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 deployments
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	vmcontrollerv1 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/apis/vmcontroller/v1"
    13  	"github.com/verrazzano/verrazzano-monitoring-operator/pkg/config"
    14  	"github.com/verrazzano/verrazzano-monitoring-operator/pkg/constants"
    15  	"github.com/verrazzano/verrazzano-monitoring-operator/pkg/resources"
    16  	"github.com/verrazzano/verrazzano-monitoring-operator/pkg/resources/nodes"
    17  	appsv1 "k8s.io/api/apps/v1"
    18  	"k8s.io/apimachinery/pkg/api/resource"
    19  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    20  	"k8s.io/client-go/kubernetes/fake"
    21  )
    22  
    23  func TestVMOEmptyDeploymentSize(t *testing.T) {
    24  	vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{}
    25  	operatorConfig := &config.OperatorConfig{}
    26  	expected, err := New(vmo, fake.NewSimpleClientset(), operatorConfig, map[string]string{})
    27  	if err != nil {
    28  		t.Error(err)
    29  	}
    30  	deployments := expected.Deployments
    31  	assert.Equal(t, 1, len(deployments), "Length of generated deployments")
    32  }
    33  
    34  func TestVMOFullDeploymentSize(t *testing.T) {
    35  	vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{
    36  		Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{
    37  			CascadingDelete: true,
    38  			Grafana: vmcontrollerv1.Grafana{
    39  				Enabled: true,
    40  			},
    41  			Kibana: vmcontrollerv1.Kibana{
    42  				Enabled: true,
    43  			},
    44  			Elasticsearch: vmcontrollerv1.Elasticsearch{
    45  				Enabled:    true,
    46  				IngestNode: vmcontrollerv1.ElasticsearchNode{Replicas: 1},
    47  				MasterNode: vmcontrollerv1.ElasticsearchNode{Replicas: 1},
    48  				DataNode:   vmcontrollerv1.ElasticsearchNode{Replicas: 1},
    49  			},
    50  		},
    51  	}
    52  	expected, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{})
    53  	if err != nil {
    54  		t.Error(err)
    55  	}
    56  	deployments := expected.Deployments
    57  	deployments = append(deployments, NewOpenSearchDashboardsDeployment(vmo))
    58  	assert.Equal(t, 5, len(deployments), "Length of generated deployments")
    59  	assert.Equal(t, constants.VMOKind, deployments[0].ObjectMeta.OwnerReferences[0].Kind, "OwnerReferences is not set by default")
    60  }
    61  
    62  func TestVMODevProfileFullDeploymentSize(t *testing.T) {
    63  
    64  	vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{
    65  		Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{
    66  			CascadingDelete: true,
    67  			Grafana: vmcontrollerv1.Grafana{
    68  				Enabled: true,
    69  			},
    70  			Kibana: vmcontrollerv1.Kibana{
    71  				Enabled: true,
    72  			},
    73  			Elasticsearch: vmcontrollerv1.Elasticsearch{
    74  				Enabled:    true,
    75  				IngestNode: vmcontrollerv1.ElasticsearchNode{Replicas: 0},
    76  				MasterNode: vmcontrollerv1.ElasticsearchNode{
    77  					Replicas: 1,
    78  					Roles: []vmcontrollerv1.NodeRole{
    79  						vmcontrollerv1.MasterRole,
    80  						vmcontrollerv1.IngestRole,
    81  						vmcontrollerv1.DataRole,
    82  					},
    83  				},
    84  				DataNode: vmcontrollerv1.ElasticsearchNode{Replicas: 0},
    85  			},
    86  		},
    87  	}
    88  	assert.True(t, nodes.IsSingleNodeCluster(vmo), "Single node ES setup, expected IsDevProfile to be true")
    89  	expected, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{})
    90  	if err != nil {
    91  		t.Error(err)
    92  	}
    93  	deployments := expected.Deployments
    94  	deployments = append(deployments, NewOpenSearchDashboardsDeployment(vmo))
    95  	assert.Equal(t, 3, len(deployments), "Length of generated deployments")
    96  	assert.Equal(t, constants.VMOKind, deployments[0].ObjectMeta.OwnerReferences[0].Kind, "OwnerReferences is not set by default")
    97  }
    98  
    99  func TestVMODevProfileInvalidESTopology(t *testing.T) {
   100  
   101  	vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{
   102  		Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{
   103  			CascadingDelete: true,
   104  			Grafana: vmcontrollerv1.Grafana{
   105  				Enabled: true,
   106  			},
   107  			Kibana: vmcontrollerv1.Kibana{
   108  				Enabled: true,
   109  			},
   110  			Elasticsearch: vmcontrollerv1.Elasticsearch{
   111  				Enabled:    true,
   112  				IngestNode: vmcontrollerv1.ElasticsearchNode{Replicas: 0},
   113  				MasterNode: vmcontrollerv1.ElasticsearchNode{Replicas: 0},
   114  				DataNode:   vmcontrollerv1.ElasticsearchNode{Replicas: 0},
   115  			},
   116  		},
   117  	}
   118  	assert.False(t, nodes.IsSingleNodeCluster(vmo), "Invalid single node ES setup, expected IsDevProfile to be false")
   119  	_, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{})
   120  	assert.Nil(t, err)
   121  }
   122  
   123  func TestVMOWithCascadingDelete(t *testing.T) {
   124  	// With CascadingDelete
   125  	vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{
   126  		Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{
   127  			CascadingDelete: true,
   128  			Grafana: vmcontrollerv1.Grafana{
   129  				Enabled: true,
   130  			},
   131  			Kibana: vmcontrollerv1.Kibana{
   132  				Enabled: true,
   133  			},
   134  			Elasticsearch: vmcontrollerv1.Elasticsearch{
   135  				Enabled:    true,
   136  				MasterNode: vmcontrollerv1.ElasticsearchNode{Replicas: 1},
   137  			},
   138  		},
   139  	}
   140  	expected, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{})
   141  	if err != nil {
   142  		t.Error(err)
   143  	}
   144  	deployments := expected.Deployments
   145  	assert.True(t, len(deployments) > 0, "Non-zero length generated deployments")
   146  	for _, deployment := range deployments {
   147  		assert.Equal(t, 1, len(deployment.ObjectMeta.OwnerReferences), "OwnerReferences is not set with CascadingDelete true")
   148  	}
   149  
   150  	// Without CascadingDelete
   151  	vmo.Spec.CascadingDelete = false
   152  	expected, err = New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{})
   153  	if err != nil {
   154  		t.Error(err)
   155  	}
   156  	deployments = expected.Deployments
   157  	assert.True(t, len(deployments) > 0, "Non-zero length generated deployments")
   158  	for _, deployment := range deployments {
   159  		assert.Equal(t, 0, len(deployment.ObjectMeta.OwnerReferences), "OwnerReferences is set even with CascadingDelete false")
   160  	}
   161  }
   162  
   163  func TestVMOWithResourceConstraints(t *testing.T) {
   164  	vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{
   165  		ObjectMeta: v1.ObjectMeta{
   166  			Name: "system",
   167  		},
   168  		Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{
   169  			Grafana: vmcontrollerv1.Grafana{
   170  				Enabled: true,
   171  				Resources: vmcontrollerv1.Resources{
   172  					LimitCPU:      "500m",
   173  					LimitMemory:   "120Mi",
   174  					RequestCPU:    "200m",
   175  					RequestMemory: "60Mi",
   176  				},
   177  			},
   178  			Kibana: vmcontrollerv1.Kibana{
   179  				Enabled: true,
   180  				Resources: vmcontrollerv1.Resources{
   181  					LimitCPU:      "0.53",
   182  					LimitMemory:   "123M",
   183  					RequestCPU:    "0.23",
   184  					RequestMemory: "63M",
   185  				},
   186  			},
   187  			Elasticsearch: vmcontrollerv1.Elasticsearch{
   188  				Enabled: true,
   189  				IngestNode: vmcontrollerv1.ElasticsearchNode{
   190  					Name:     config.ElasticsearchIngest.Name,
   191  					Replicas: 1,
   192  					Resources: vmcontrollerv1.Resources{
   193  						LimitCPU:      "0.54",
   194  						LimitMemory:   "124M",
   195  						RequestCPU:    "0.24",
   196  						RequestMemory: "64M",
   197  					},
   198  					Roles: []vmcontrollerv1.NodeRole{vmcontrollerv1.IngestRole},
   199  				},
   200  				DataNode: vmcontrollerv1.ElasticsearchNode{
   201  					Name:     config.ElasticsearchData.Name,
   202  					Replicas: 1,
   203  					Roles:    []vmcontrollerv1.NodeRole{vmcontrollerv1.DataRole},
   204  				},
   205  				MasterNode: vmcontrollerv1.ElasticsearchNode{Replicas: 1},
   206  			},
   207  		},
   208  	}
   209  	expected, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{})
   210  	if err != nil {
   211  		t.Error(err)
   212  	}
   213  
   214  	for _, deployment := range expected.Deployments {
   215  		esDataName := resources.GetMetaName(vmo.Name, config.ElasticsearchData.Name)
   216  		if deployment.Name == resources.GetMetaName(vmo.Name, config.Grafana.Name) {
   217  			assert.Equal(t, resource.MustParse("500m"), *deployment.Spec.Template.Spec.Containers[0].Resources.Limits.Cpu(), "Granfana Limit CPU")
   218  			assert.Equal(t, resource.MustParse("120Mi"), *deployment.Spec.Template.Spec.Containers[0].Resources.Limits.Memory(), "Granfana Limit Memory")
   219  			assert.Equal(t, resource.MustParse("200m"), *deployment.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu(), "Granfana Request CPU")
   220  			assert.Equal(t, resource.MustParse("60Mi"), *deployment.Spec.Template.Spec.Containers[0].Resources.Requests.Memory(), "Granfana Request Memory")
   221  		} else if deployment.Name == resources.GetMetaName(vmo.Name, config.Kibana.Name) {
   222  			assert.Equal(t, resource.MustParse("0.53"), *deployment.Spec.Template.Spec.Containers[0].Resources.Limits.Cpu(), "Granfana Limit CPU")
   223  			assert.Equal(t, resource.MustParse("123M"), *deployment.Spec.Template.Spec.Containers[0].Resources.Limits.Memory(), "Granfana Limit Memory")
   224  			assert.Equal(t, resource.MustParse("0.23"), *deployment.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu(), "Granfana Request CPU")
   225  			assert.Equal(t, resource.MustParse("63M"), *deployment.Spec.Template.Spec.Containers[0].Resources.Requests.Memory(), "Granfana Request Memory")
   226  		} else if deployment.Name == resources.GetMetaName(vmo.Name, config.ElasticsearchIngest.Name) {
   227  			assert.Equal(t, resource.MustParse("0.54"), *deployment.Spec.Template.Spec.Containers[0].Resources.Limits.Cpu(), "Granfana Limit CPU")
   228  			assert.Equal(t, resource.MustParse("124M"), *deployment.Spec.Template.Spec.Containers[0].Resources.Limits.Memory(), "Granfana Limit Memory")
   229  			assert.Equal(t, resource.MustParse("0.24"), *deployment.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu(), "Granfana Request CPU")
   230  			assert.Equal(t, resource.MustParse("64M"), *deployment.Spec.Template.Spec.Containers[0].Resources.Requests.Memory(), "Granfana Request Memory")
   231  		} else if deployment.Name == resources.GetMetaName(vmo.Name, config.ElasticsearchMaster.Name) {
   232  			// No resources specified on this endpoint
   233  		} else if strings.Contains(deployment.Name, resources.GetMetaName(vmo.Name, config.ElasticsearchData.Name)) {
   234  			// No resources specified on this endpoint
   235  		} else if deployment.Name == resources.GetMetaName(vmo.Name, config.API.Name) {
   236  			// No resources specified on API endpoint
   237  		} else if deployment.Name == resources.OidcProxyMetaName(vmo.Name, config.ElasticsearchIngest.Name) {
   238  			// No resources specified on OIDC proxy
   239  		} else {
   240  			t.Log("ESDataName: " + esDataName)
   241  			t.Error("Unknown Deployment Name: " + deployment.Name)
   242  		}
   243  	}
   244  }
   245  
   246  func TestVMOWithReplicas(t *testing.T) {
   247  	vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{
   248  		Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{
   249  			API: vmcontrollerv1.API{
   250  				Replicas: 2,
   251  			},
   252  			Kibana: vmcontrollerv1.Kibana{
   253  				Enabled:  true,
   254  				Replicas: 4,
   255  			},
   256  		},
   257  	}
   258  	expected, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{})
   259  	if err != nil {
   260  		t.Error(err)
   261  	}
   262  	deployments := expected.Deployments
   263  	deployments = append(deployments, NewOpenSearchDashboardsDeployment(vmo))
   264  	assert.Equal(t, 2, len(deployments), "Length of generated deployments")
   265  	for _, deployment := range deployments {
   266  		if deployment.Name == resources.GetMetaName(vmo.Name, config.API.Name) {
   267  			assert.Equal(t, *resources.NewVal(2), *deployment.Spec.Replicas, "Api replicas")
   268  		} else if deployment.Name == resources.GetMetaName(vmo.Name, config.OpenSearchDashboards.Name) {
   269  			assert.Equal(t, *resources.NewVal(4), *deployment.Spec.Replicas, "Kibana replicas")
   270  		}
   271  	}
   272  }
   273  
   274  func TestGetAdForPvcIndex(t *testing.T) {
   275  	m1 := map[string]string{}
   276  	m2 := map[string]string{"pvc1": "ad1", "pvc2": "ad2"}
   277  	s1 := vmcontrollerv1.Storage{
   278  		Size:     "50Gi",
   279  		PvcNames: []string{"pvc1", "pvc2", "pvc3"},
   280  	}
   281  	assert.Equal(t, "", getAvailabilityDomainForPvcIndex(nil, m1, 0), "With nil storage")
   282  	assert.Equal(t, "", getAvailabilityDomainForPvcIndex(nil, m2, 0), "With nil storage")
   283  	assert.Equal(t, "", getAvailabilityDomainForPvcIndex(&s1, m1, 0), "With empty AD map")
   284  	assert.Equal(t, "ad1", getAvailabilityDomainForPvcIndex(&s1, m2, 0), "With valid PVC")
   285  	assert.Equal(t, "ad2", getAvailabilityDomainForPvcIndex(&s1, m2, 1), "With valid PVC")
   286  	assert.Equal(t, "", getAvailabilityDomainForPvcIndex(&s1, m2, 2), "With non-existent PVC")
   287  	assert.Equal(t, "", getAvailabilityDomainForPvcIndex(&s1, m2, 3), "With PVC index out of bounds")
   288  }
   289  
   290  func TestAPIWithNatGatewayIPs(t *testing.T) {
   291  	vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{
   292  		ObjectMeta: v1.ObjectMeta{
   293  			Name: "my-vmo",
   294  		},
   295  		Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{
   296  			NatGatewayIPs: []string{"1.1.1.1", "2.1.1.1"},
   297  		},
   298  	}
   299  	expected, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{})
   300  	if err != nil {
   301  		t.Error(err)
   302  	}
   303  	deployments := expected.Deployments
   304  	apiDeployment, err := getDeploymentByName(constants.VMOServiceNamePrefix+"my-vmo-api", deployments)
   305  	if err != nil {
   306  		t.Error(err)
   307  	}
   308  	assert.Equal(t, []string{"--natGatewayIPs=1.1.1.1,2.1.1.1"}, apiDeployment.Spec.Template.Spec.Containers[0].Args, "API args with NAT GW")
   309  }
   310  
   311  // Returns the deployment with the given name from the given list of deployments, returning an error if not found
   312  func getDeploymentByName(deploymentName string, deploymentList []*appsv1.Deployment) (*appsv1.Deployment, error) {
   313  	for _, deployment := range deploymentList {
   314  		if deployment.Name == deploymentName {
   315  			return deployment, nil
   316  		}
   317  	}
   318  	return nil, fmt.Errorf("deployment %s not found", deploymentName)
   319  }