github.com/someshkoli/terratest@v0.41.1/modules/k8s/ingress.go (about)

     1  package k8s
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/require"
     9  	networkingv1 "k8s.io/api/networking/v1"
    10  	networkingv1beta1 "k8s.io/api/networking/v1beta1"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  
    13  	"github.com/gruntwork-io/terratest/modules/logger"
    14  	"github.com/gruntwork-io/terratest/modules/retry"
    15  	"github.com/gruntwork-io/terratest/modules/testing"
    16  )
    17  
    18  // ListIngresses will look for Ingress resources in the given namespace that match the given filters and return them.
    19  // This will fail the test if there is an error.
    20  func ListIngresses(t testing.TestingT, options *KubectlOptions, filters metav1.ListOptions) []networkingv1.Ingress {
    21  	ingresses, err := ListIngressesE(t, options, filters)
    22  	require.NoError(t, err)
    23  	return ingresses
    24  }
    25  
    26  // ListIngressesE will look for Ingress resources in the given namespace that match the given filters and return them.
    27  func ListIngressesE(t testing.TestingT, options *KubectlOptions, filters metav1.ListOptions) ([]networkingv1.Ingress, error) {
    28  	clientset, err := GetKubernetesClientFromOptionsE(t, options)
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  	resp, err := clientset.NetworkingV1().Ingresses(options.Namespace).List(context.Background(), filters)
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  	return resp.Items, nil
    37  
    38  }
    39  
    40  // GetIngress returns a Kubernetes Ingress resource in the provided namespace with the given name. This will fail the
    41  // test if there is an error.
    42  func GetIngress(t testing.TestingT, options *KubectlOptions, ingressName string) *networkingv1.Ingress {
    43  	ingress, err := GetIngressE(t, options, ingressName)
    44  	require.NoError(t, err)
    45  	return ingress
    46  }
    47  
    48  // GetIngressE returns a Kubernetes Ingress resource in the provided namespace with the given name.
    49  func GetIngressE(t testing.TestingT, options *KubectlOptions, ingressName string) (*networkingv1.Ingress, error) {
    50  	clientset, err := GetKubernetesClientFromOptionsE(t, options)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	return clientset.NetworkingV1().Ingresses(options.Namespace).Get(context.Background(), ingressName, metav1.GetOptions{})
    55  }
    56  
    57  // IsIngressAvailable returns true if the Ingress endpoint is provisioned and available.
    58  func IsIngressAvailable(ingress *networkingv1.Ingress) bool {
    59  	// Ingress is ready if it has at least one endpoint
    60  	endpoints := ingress.Status.LoadBalancer.Ingress
    61  	return len(endpoints) > 0
    62  }
    63  
    64  // WaitUntilIngressAvailable waits until the Ingress resource has an endpoint provisioned for it.
    65  func WaitUntilIngressAvailable(t testing.TestingT, options *KubectlOptions, ingressName string, retries int, sleepBetweenRetries time.Duration) {
    66  	statusMsg := fmt.Sprintf("Wait for ingress %s to be provisioned.", ingressName)
    67  	message := retry.DoWithRetry(
    68  		t,
    69  		statusMsg,
    70  		retries,
    71  		sleepBetweenRetries,
    72  		func() (string, error) {
    73  			ingress, err := GetIngressE(t, options, ingressName)
    74  			if err != nil {
    75  				return "", err
    76  			}
    77  			if !IsIngressAvailable(ingress) {
    78  				return "", IngressNotAvailable{ingress: ingress}
    79  			}
    80  			return "Ingress is now available", nil
    81  		},
    82  	)
    83  	logger.Logf(t, message)
    84  }
    85  
    86  // ListIngressesV1Beta1 will look for Ingress resources in the given namespace that match the given filters and return
    87  // them, using networking.k8s.io/v1beta1 API. This will fail the test if there is an error.
    88  func ListIngressesV1Beta1(t testing.TestingT, options *KubectlOptions, filters metav1.ListOptions) []networkingv1beta1.Ingress {
    89  	ingresses, err := ListIngressesV1Beta1E(t, options, filters)
    90  	require.NoError(t, err)
    91  	return ingresses
    92  }
    93  
    94  // ListIngressesV1Beta1E will look for Ingress resources in the given namespace that match the given filters and return
    95  // them, using networking.k8s.io/v1beta1 API.
    96  func ListIngressesV1Beta1E(t testing.TestingT, options *KubectlOptions, filters metav1.ListOptions) ([]networkingv1beta1.Ingress, error) {
    97  	clientset, err := GetKubernetesClientFromOptionsE(t, options)
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  	resp, err := clientset.NetworkingV1beta1().Ingresses(options.Namespace).List(context.Background(), filters)
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  	return resp.Items, nil
   106  
   107  }
   108  
   109  // GetIngressV1Beta1 returns a Kubernetes Ingress resource in the provided namespace with the given name, using
   110  // networking.k8s.io/v1beta1 API. This will fail the test if there is an error.
   111  func GetIngressV1Beta1(t testing.TestingT, options *KubectlOptions, ingressName string) *networkingv1beta1.Ingress {
   112  	ingress, err := GetIngressV1Beta1E(t, options, ingressName)
   113  	require.NoError(t, err)
   114  	return ingress
   115  }
   116  
   117  // GetIngressV1Beta1E returns a Kubernetes Ingress resource in the provided namespace with the given name, using
   118  // networking.k8s.io/v1beta1.
   119  func GetIngressV1Beta1E(t testing.TestingT, options *KubectlOptions, ingressName string) (*networkingv1beta1.Ingress, error) {
   120  	clientset, err := GetKubernetesClientFromOptionsE(t, options)
   121  	if err != nil {
   122  		return nil, err
   123  	}
   124  	return clientset.NetworkingV1beta1().Ingresses(options.Namespace).Get(context.Background(), ingressName, metav1.GetOptions{})
   125  }
   126  
   127  // IsIngressAvailableV1Beta1 returns true if the Ingress endpoint is provisioned and available, using
   128  // networking.k8s.io/v1beta1 API.
   129  func IsIngressAvailableV1Beta1(ingress *networkingv1beta1.Ingress) bool {
   130  	// Ingress is ready if it has at least one endpoint
   131  	endpoints := ingress.Status.LoadBalancer.Ingress
   132  	return len(endpoints) > 0
   133  }
   134  
   135  // WaitUntilIngressAvailableV1Beta1 waits until the Ingress resource has an endpoint provisioned for it, using
   136  // networking.k8s.io/v1beta1 API.
   137  func WaitUntilIngressAvailableV1Beta1(t testing.TestingT, options *KubectlOptions, ingressName string, retries int, sleepBetweenRetries time.Duration) {
   138  	statusMsg := fmt.Sprintf("Wait for ingress %s to be provisioned.", ingressName)
   139  	message := retry.DoWithRetry(
   140  		t,
   141  		statusMsg,
   142  		retries,
   143  		sleepBetweenRetries,
   144  		func() (string, error) {
   145  			ingress, err := GetIngressV1Beta1E(t, options, ingressName)
   146  			if err != nil {
   147  				return "", err
   148  			}
   149  			if !IsIngressAvailableV1Beta1(ingress) {
   150  				return "", IngressNotAvailableV1Beta1{ingress: ingress}
   151  			}
   152  			return "Ingress is now available", nil
   153  		},
   154  	)
   155  	logger.Logf(t, message)
   156  }