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

     1  package k8s
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/require"
     9  	corev1 "k8s.io/api/core/v1"
    10  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    11  
    12  	"github.com/gruntwork-io/terratest/modules/logger"
    13  	"github.com/gruntwork-io/terratest/modules/retry"
    14  	"github.com/gruntwork-io/terratest/modules/testing"
    15  )
    16  
    17  // GetNodes queries Kubernetes for information about the worker nodes registered to the cluster. If anything goes wrong,
    18  // the function will automatically fail the test.
    19  func GetNodes(t testing.TestingT, options *KubectlOptions) []corev1.Node {
    20  	nodes, err := GetNodesE(t, options)
    21  	require.NoError(t, err)
    22  	return nodes
    23  }
    24  
    25  // GetNodesE queries Kubernetes for information about the worker nodes registered to the cluster.
    26  func GetNodesE(t testing.TestingT, options *KubectlOptions) ([]corev1.Node, error) {
    27  	return GetNodesByFilterE(t, options, metav1.ListOptions{})
    28  }
    29  
    30  // GetNodesByFilterE queries Kubernetes for information about the worker nodes registered to the cluster, filtering the
    31  // list of nodes using the provided ListOptions.
    32  func GetNodesByFilterE(t testing.TestingT, options *KubectlOptions, filter metav1.ListOptions) ([]corev1.Node, error) {
    33  	logger.Logf(t, "Getting list of nodes from Kubernetes")
    34  
    35  	clientset, err := GetKubernetesClientFromOptionsE(t, options)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  
    40  	nodes, err := clientset.CoreV1().Nodes().List(context.Background(), filter)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	return nodes.Items, err
    45  }
    46  
    47  // GetReadyNodes queries Kubernetes for information about the worker nodes registered to the cluster and only returns
    48  // those that are in the ready state. If anything goes wrong, the function will automatically fail the test.
    49  func GetReadyNodes(t testing.TestingT, options *KubectlOptions) []corev1.Node {
    50  	nodes, err := GetReadyNodesE(t, options)
    51  	require.NoError(t, err)
    52  	return nodes
    53  }
    54  
    55  // GetReadyNodesE queries Kubernetes for information about the worker nodes registered to the cluster and only returns
    56  // those that are in the ready state.
    57  func GetReadyNodesE(t testing.TestingT, options *KubectlOptions) ([]corev1.Node, error) {
    58  	nodes, err := GetNodesE(t, options)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  	logger.Logf(t, "Filtering list of nodes from Kubernetes for Ready nodes")
    63  	nodesFiltered := []corev1.Node{}
    64  	for _, node := range nodes {
    65  		if IsNodeReady(node) {
    66  			nodesFiltered = append(nodesFiltered, node)
    67  		}
    68  	}
    69  	return nodesFiltered, nil
    70  }
    71  
    72  // IsNodeReady takes a Kubernetes Node information object and checks if the Node is in the ready state.
    73  func IsNodeReady(node corev1.Node) bool {
    74  	for _, condition := range node.Status.Conditions {
    75  		if condition.Type == corev1.NodeReady {
    76  			return condition.Status == corev1.ConditionTrue
    77  		}
    78  	}
    79  	return false
    80  }
    81  
    82  // WaitUntilAllNodesReady continuously polls the Kubernetes cluster until all nodes in the cluster reach the ready
    83  // state, or runs out of retries. Will fail the test immediately if it times out.
    84  func WaitUntilAllNodesReady(t testing.TestingT, options *KubectlOptions, retries int, sleepBetweenRetries time.Duration) {
    85  	err := WaitUntilAllNodesReadyE(t, options, retries, sleepBetweenRetries)
    86  	require.NoError(t, err)
    87  }
    88  
    89  // WaitUntilAllNodesReadyE continuously polls the Kubernetes cluster until all nodes in the cluster reach the ready
    90  // state, or runs out of retries.
    91  func WaitUntilAllNodesReadyE(t testing.TestingT, options *KubectlOptions, retries int, sleepBetweenRetries time.Duration) error {
    92  	message, err := retry.DoWithRetryE(
    93  		t,
    94  		"Wait for all Kube Nodes to be ready",
    95  		retries,
    96  		sleepBetweenRetries,
    97  		func() (string, error) {
    98  			_, err := AreAllNodesReadyE(t, options)
    99  			if err != nil {
   100  				return "", err
   101  			}
   102  			return "All nodes ready", nil
   103  		},
   104  	)
   105  	logger.Logf(t, message)
   106  	return err
   107  }
   108  
   109  // AreAllNodesReady checks if all nodes are ready in the Kubernetes cluster targeted by the current config context
   110  func AreAllNodesReady(t testing.TestingT, options *KubectlOptions) bool {
   111  	nodesReady, _ := AreAllNodesReadyE(t, options)
   112  	return nodesReady
   113  }
   114  
   115  // AreAllNodesReadyE checks if all nodes are ready in the Kubernetes cluster targeted by the current config context. If
   116  // false, returns an error indicating the reason.
   117  func AreAllNodesReadyE(t testing.TestingT, options *KubectlOptions) (bool, error) {
   118  	nodes, err := GetNodesE(t, options)
   119  	if err != nil {
   120  		return false, err
   121  	}
   122  	if len(nodes) == 0 {
   123  		return false, errors.New("No nodes available")
   124  	}
   125  	for _, node := range nodes {
   126  		if !IsNodeReady(node) {
   127  			return false, errors.New("Not all nodes ready")
   128  		}
   129  	}
   130  	return true, nil
   131  }