github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/pkg/weblogic/weblogic.go (about)

     1  // Copyright (c) 2021, 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 weblogic
     5  
     6  import (
     7  	"context"
     8  	"encoding/json"
     9  	"errors"
    10  	"fmt"
    11  	"reflect"
    12  
    13  	"github.com/verrazzano/verrazzano/tests/e2e/pkg"
    14  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    15  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    16  	"k8s.io/apimachinery/pkg/runtime/schema"
    17  	"k8s.io/client-go/util/jsonpath"
    18  )
    19  
    20  const Healthy = "ok"
    21  const overallHealth = "overallHealth"
    22  
    23  // GetDomain returns a WebLogic domains in unstructured format
    24  func GetDomain(namespace string, name string) (*unstructured.Unstructured, error) {
    25  	client, err := pkg.GetDynamicClient()
    26  	if err != nil {
    27  		return nil, err
    28  	}
    29  	domain, err := client.Resource(getScheme()).Namespace(namespace).Get(context.TODO(), name, metav1.GetOptions{})
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  	return domain, nil
    34  }
    35  
    36  // GetDomainInCluster returns a WebLogic domains in unstructured format
    37  func GetDomainInCluster(namespace string, name string, kubeconfigPath string) (*unstructured.Unstructured, error) {
    38  	client, err := pkg.GetDynamicClientInCluster(kubeconfigPath)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	domain, err := client.Resource(getScheme()).Namespace(namespace).Get(context.TODO(), name, metav1.GetOptions{})
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  	return domain, nil
    47  }
    48  
    49  // GetHealthOfServers returns a slice of strings, each item representing the health of a server in the domain
    50  func GetHealthOfServers(uDomain *unstructured.Unstructured) ([]string, error) {
    51  	// jsonpath template used to extract the server info
    52  	const template = `{.status.servers[*].health}`
    53  
    54  	// Get the string that has the server status health
    55  	results, err := findData(uDomain, template)
    56  
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  
    61  	var serverHealth []string
    62  	for i := range results {
    63  		for j := range results[i] {
    64  			if results[i][j].CanInterface() {
    65  				// Get the underlying interface object out of the reflect.Value object in results[i][j]
    66  				serverHealthIntf := results[i][j].Interface()
    67  
    68  				// Cast the interface{} object to a map[string]interface{} (since we know that is what the health object is)
    69  				// (if type is wrong, instead of panicking the cast will return false for the 2nd return value)
    70  				healthMap, ok := serverHealthIntf.(map[string]interface{})
    71  				if !ok {
    72  					pkg.Log(pkg.Error, fmt.Sprintf("Could not get WebLogic server result # %d as a map, its type is %v", i, reflect.TypeOf(serverHealthIntf)))
    73  					continue
    74  				}
    75  				// append the overallHealth value ("ok" or otherwise) to a string slice, one entry per server.
    76  				serverHealth = append(serverHealth, healthMap[overallHealth].(string))
    77  			} else {
    78  				pkg.Log(pkg.Error, fmt.Sprintf("Could not convert WebLogic server result # %d to an interface, its type is %s", i, results[i][j].Type().String()))
    79  			}
    80  		}
    81  	}
    82  
    83  	if len(serverHealth) == 0 {
    84  		return nil, errors.New("No WebLogic servers found in domain CR")
    85  	}
    86  	return serverHealth, nil
    87  }
    88  
    89  // getScheme returns the WebLogic scheme needed to get unstructured data
    90  func getScheme() schema.GroupVersionResource {
    91  	return schema.GroupVersionResource{
    92  		Group:    "weblogic.oracle",
    93  		Version:  "v9",
    94  		Resource: "domains",
    95  	}
    96  }
    97  
    98  // findData returns the results for the specified value from the unstructured domain that matches the template
    99  func findData(uDomain *unstructured.Unstructured, template string) ([][]reflect.Value, error) {
   100  	// Convert the unstructured domain into domain object that can be parsed
   101  	jsonDomain, err := uDomain.MarshalJSON()
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  	var domain interface{}
   106  	err = json.Unmarshal([]byte(jsonDomain), &domain)
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  	// Parse the template
   111  	j := jsonpath.New("domain")
   112  	err = j.Parse(template)
   113  	if err != nil {
   114  		return nil, err
   115  	}
   116  
   117  	return j.FindResults(domain)
   118  }