github.com/verrazzano/verrazzano@v1.7.1/tools/psr/backend/pkg/opensearch/opensearch.go (about)

     1  // Copyright (c) 2022, 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 opensearch
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	vmov1 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/apis/vmcontroller/v1"
    10  	"github.com/verrazzano/verrazzano/pkg/k8s/ready"
    11  	"github.com/verrazzano/verrazzano/pkg/log/vzlog"
    12  	vzv1alpha1 "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1"
    13  	"github.com/verrazzano/verrazzano/platform-operator/constants"
    14  	"github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/opensearch"
    15  	"github.com/verrazzano/verrazzano/tools/psr/backend/config"
    16  	corev1 "k8s.io/api/core/v1"
    17  	"k8s.io/apimachinery/pkg/labels"
    18  	"k8s.io/apimachinery/pkg/selection"
    19  	"sigs.k8s.io/controller-runtime/pkg/client"
    20  
    21  	"k8s.io/apimachinery/pkg/types"
    22  )
    23  
    24  const (
    25  	nodeNamePrefix = "vmi-system-%s"
    26  	componentName  = "opensearch"
    27  
    28  	MasterTier = "master"
    29  	DataTier   = "data"
    30  	IngestTier = "ingest"
    31  )
    32  
    33  // IsOSReady checks if the OpenSearch resources are ready
    34  func IsOSReady(ctrlRuntimeClient client.Client, cr *vzv1alpha1.Verrazzano) bool {
    35  	prefix := fmt.Sprintf("Component %s", componentName)
    36  	for _, node := range cr.Spec.Components.Elasticsearch.Nodes {
    37  		if !IsOSNodeReady(ctrlRuntimeClient, node, prefix) {
    38  			return false
    39  		}
    40  	}
    41  	//	return common.IsVMISecretReady(ctx)
    42  	return true
    43  }
    44  
    45  // IsOSNodeReady returns true if the OpenSearch tier is ready
    46  func IsOSNodeReady(client client.Client, node vzv1alpha1.OpenSearchNode, prefix string) bool {
    47  	if node.Replicas == nil || *node.Replicas < 1 {
    48  		return true
    49  	}
    50  	nodeControllerName := getNodeControllerName(node)
    51  
    52  	// If a node has the master role, it is a statefulset
    53  	if hasRole(node.Roles, vmov1.MasterRole) {
    54  		return opensearch.AreOpensearchStsReady(vzlog.DefaultLogger(), client, []types.NamespacedName{{
    55  			Name:      nodeControllerName,
    56  			Namespace: constants.VerrazzanoSystemNamespace,
    57  		}}, *node.Replicas, prefix)
    58  	}
    59  
    60  	// Data nodes have N = node.Replicas number of deployment objects.
    61  	if hasRole(node.Roles, vmov1.DataRole) {
    62  		return ready.DeploymentsAreReady(vzlog.DefaultLogger(), client, dataDeploymentObjectKeys(node, nodeControllerName), 1, prefix)
    63  	}
    64  
    65  	// Ingest nodes can be handled like normal deployments
    66  	return ready.DeploymentsAreReady(vzlog.DefaultLogger(), client, []types.NamespacedName{{
    67  		Name:      nodeControllerName,
    68  		Namespace: constants.VerrazzanoSystemNamespace,
    69  	}}, *node.Replicas, prefix)
    70  }
    71  
    72  func getNodeControllerName(node vzv1alpha1.OpenSearchNode) string {
    73  	return fmt.Sprintf(nodeNamePrefix, node.Name)
    74  }
    75  
    76  func hasRole(roles []vmov1.NodeRole, roleToHave vmov1.NodeRole) bool {
    77  	for _, role := range roles {
    78  		if role == roleToHave {
    79  			return true
    80  		}
    81  	}
    82  	return false
    83  }
    84  
    85  func dataDeploymentObjectKeys(node vzv1alpha1.OpenSearchNode, nodeControllerName string) []types.NamespacedName {
    86  	var dataDeployments []types.NamespacedName
    87  	if node.Replicas == nil {
    88  		return dataDeployments
    89  	}
    90  	var i int32
    91  	for i = 0; i < *node.Replicas; i++ {
    92  		dataDeploymentName := fmt.Sprintf("%s-%d", nodeControllerName, i)
    93  		dataDeployments = append(dataDeployments, types.NamespacedName{
    94  			Name:      dataDeploymentName,
    95  			Namespace: constants.VerrazzanoSystemNamespace,
    96  		})
    97  	}
    98  	return dataDeployments
    99  }
   100  
   101  // GetPodsForTier returns pods for a given tier
   102  func GetPodsForTier(ctrlRuntimeClient client.Client, tier string) ([]corev1.Pod, error) {
   103  	var label string
   104  	switch tier {
   105  	case MasterTier:
   106  		label = "opensearch.verrazzano.io/role-master"
   107  	case DataTier:
   108  		label = "opensearch.verrazzano.io/role-data"
   109  	case IngestTier:
   110  		label = "opensearch.verrazzano.io/role-ingest"
   111  	}
   112  	req, _ := labels.NewRequirement(label, selection.Equals, []string{"true"})
   113  	//	req, _ := labels.NewRequirement(label, selection.Exists, []string{})
   114  
   115  	pods, err := getPodsByLabels(ctrlRuntimeClient, constants.VerrazzanoSystemNamespace, *req)
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  	return pods, nil
   120  }
   121  
   122  // getConfigMapsByLabels gets the configmaps by label
   123  func getPodsByLabels(ctrlRuntimeClient client.Client, namespace string, requirements ...labels.Requirement) ([]corev1.Pod, error) {
   124  	// Find the scenario configmaps in the cluster
   125  	selector := labels.NewSelector()
   126  	for _, req := range requirements {
   127  		selector = selector.Add(req)
   128  	}
   129  	podList := corev1.PodList{}
   130  	err := ctrlRuntimeClient.List(context.TODO(), &podList, &client.ListOptions{Namespace: namespace, LabelSelector: selector})
   131  	if err != nil {
   132  		return nil, err
   133  	}
   134  	return podList.Items, nil
   135  }
   136  
   137  // ValidateOpenSeachTier validates the envvar is a correct opensearch tier
   138  func ValidateOpenSeachTier(opensearchTierEnvVar string) (string, error) {
   139  	tier := config.PsrEnv.GetEnv(opensearchTierEnvVar)
   140  	if tier != MasterTier && tier != DataTier && tier != IngestTier {
   141  		return "", fmt.Errorf("error, %s not a valid OpenSearch tier to restart", tier)
   142  	}
   143  	return tier, nil
   144  }