github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/pkg/environment.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 pkg
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"os"
    10  	"strings"
    11  
    12  	"github.com/verrazzano/verrazzano/pkg/k8sutil"
    13  	v1 "k8s.io/api/core/v1"
    14  	networkingv1 "k8s.io/api/networking/v1"
    15  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    16  )
    17  
    18  const (
    19  	// ClusterTypeKind represents a Kind cluster
    20  	ClusterTypeKind = "kind"
    21  	// ClusterTypeOlcne represents an OCNE cluster
    22  	ClusterTypeOlcne     = "OCNE"
    23  	istioSystemNamespace = "istio-system"
    24  )
    25  
    26  // Ingress returns the ingress address
    27  func Ingress() string {
    28  	clusterType, ok := os.LookupEnv("TEST_ENV")
    29  	if !ok {
    30  		clusterType = ClusterTypeKind
    31  	}
    32  
    33  	if clusterType == ClusterTypeKind {
    34  		return loadBalancerIngress()
    35  	} else if clusterType == ClusterTypeOlcne {
    36  		return externalLoadBalancerIngress()
    37  	} else {
    38  		return loadBalancerIngress()
    39  	}
    40  }
    41  
    42  // loadBalancerIngress returns the ingress load balancer address
    43  func loadBalancerIngress() string {
    44  	fmt.Println("Obtaining ingressgateway info ...")
    45  	ingressgateway, err := findIstioIngressGatewaySvc(true)
    46  	if err != nil {
    47  		Log(Error, fmt.Sprintf("Error finding Istio ingress gateway service: %v", err))
    48  		return ""
    49  	}
    50  	for i := range ingressgateway.Status.LoadBalancer.Ingress {
    51  		ingress := ingressgateway.Status.LoadBalancer.Ingress[i]
    52  		fmt.Println("Ingress: ", ingress, "hostname: ", ingress.Hostname, "IP: ", ingress.IP)
    53  		if ingress.Hostname != "" {
    54  			fmt.Println("Returning Ingress Hostname: ", ingress.Hostname)
    55  			return ingress.Hostname
    56  		} else if ingress.IP != "" {
    57  			fmt.Println("Returning Ingress IP: ", ingress.IP)
    58  			return ingress.IP
    59  		}
    60  	}
    61  	return ""
    62  }
    63  
    64  // externalLoadBalancerIngress returns the ingress external load balancer address
    65  func externalLoadBalancerIngress() string {
    66  	fmt.Println("Obtaining ingressgateway info ...")
    67  	// Test a service for a dynamic address (.status.loadBalancer.ingress[0].ip),
    68  	// 	if that's not present then use .spec.externalIPs[0]
    69  	lbIngressgateway, err := findIstioIngressGatewaySvc(true)
    70  	if err != nil {
    71  		Log(Error, fmt.Sprintf("Error finding Istio ingress gateway service: %v", err))
    72  		return ""
    73  	}
    74  	for i := range lbIngressgateway.Status.LoadBalancer.Ingress {
    75  		ingress := lbIngressgateway.Status.LoadBalancer.Ingress[i]
    76  		if ingress.Hostname != "" {
    77  			fmt.Println("Returning Ingress Hostname: ", ingress.Hostname)
    78  			return ingress.Hostname
    79  		} else if ingress.IP != "" {
    80  			fmt.Println("Returning Ingress IP: ", ingress.IP)
    81  			return ingress.IP
    82  		}
    83  	}
    84  	// Nothing found in .status, check .spec
    85  	ingressgateway, err := findIstioIngressGatewaySvc(false)
    86  	if err != nil {
    87  		Log(Error, fmt.Sprintf("Error finding Istio ingress gateway service: %v", err))
    88  		return ""
    89  	}
    90  	for i := range ingressgateway.Spec.ExternalIPs {
    91  		ingress := ingressgateway.Spec.ExternalIPs[i]
    92  		fmt.Println("Returning Ingress IP: ", ingress)
    93  		return ingress
    94  	}
    95  	return ""
    96  }
    97  
    98  // findIstioIngressGatewaySvc retrieves the address of the istio ingress gateway
    99  func findIstioIngressGatewaySvc(requireLoadBalancer bool) (*v1.Service, error) {
   100  	svcList, err := ListServices(istioSystemNamespace)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	var ingressgateway v1.Service
   105  	for i := range svcList.Items {
   106  		svc := svcList.Items[i]
   107  		fmt.Println("Service name: ", svc.Name, ", LoadBalancer: ", svc.Status.LoadBalancer, ", Ingress: ", svc.Status.LoadBalancer.Ingress)
   108  		if strings.Contains(svc.Name, "ingressgateway") {
   109  			if !requireLoadBalancer {
   110  				fmt.Println("Found ingress gateway: ", svc.Name)
   111  				ingressgateway = svc
   112  			} else {
   113  				if svc.Status.LoadBalancer.Ingress != nil {
   114  					fmt.Println("Found ingress gateway: ", svc.Name)
   115  					ingressgateway = svc
   116  				}
   117  			}
   118  		}
   119  	}
   120  	return &ingressgateway, nil
   121  }
   122  
   123  // ListIngresses lists ingresses in namespace
   124  func ListIngresses(namespace string) (*networkingv1.IngressList, error) {
   125  	clientset, err := k8sutil.GetKubernetesClientset()
   126  	if err != nil {
   127  		return nil, err
   128  	}
   129  	ingresses, err := clientset.NetworkingV1().Ingresses(namespace).List(context.TODO(), metav1.ListOptions{})
   130  	if err != nil {
   131  		return nil, err
   132  	}
   133  	// dump out namespace data to file
   134  	logData := ""
   135  	for i := range ingresses.Items {
   136  		logData = logData + ingresses.Items[i].Name + "\n"
   137  	}
   138  	// this seems to be used for debugging, so if there's an error, just log it but don't bubble it up
   139  	filename := fmt.Sprintf("%v-ingresses", namespace)
   140  	if err := CreateLogFile(filename, logData); err != nil {
   141  		Log(Info, fmt.Sprintf("Could not create output file: %s, error: %v", filename, err))
   142  	}
   143  	return ingresses, nil
   144  }