github.com/k8snetworkplumbingwg/sriov-network-operator@v1.2.1-0.20240408194816-2d2e5a45d453/test/util/namespaces/namespaces.go (about)

     1  package namespaces
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  	"time"
     8  
     9  	k8sv1 "k8s.io/api/core/v1"
    10  	k8serrors "k8s.io/apimachinery/pkg/api/errors"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	"k8s.io/apimachinery/pkg/util/wait"
    13  	"k8s.io/utils/pointer"
    14  	runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
    15  
    16  	sriovv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1"
    17  	testclient "github.com/k8snetworkplumbingwg/sriov-network-operator/test/util/client"
    18  )
    19  
    20  // Test is the namespace to be use for testing
    21  const Test = "sriov-conformance-testing"
    22  
    23  var inhibitSecurityAdmissionLabels = map[string]string{
    24  	"pod-security.kubernetes.io/audit":               "privileged",
    25  	"pod-security.kubernetes.io/enforce":             "privileged",
    26  	"pod-security.kubernetes.io/warn":                "privileged",
    27  	"security.openshift.io/scc.podSecurityLabelSync": "false",
    28  }
    29  
    30  // WaitForDeletion waits until the namespace will be removed from the cluster
    31  func WaitForDeletion(cs *testclient.ClientSet, nsName string, timeout time.Duration) error {
    32  	return wait.PollImmediate(time.Second, timeout, func() (bool, error) {
    33  		_, err := cs.Namespaces().Get(context.Background(), nsName, metav1.GetOptions{})
    34  		if k8serrors.IsNotFound(err) {
    35  			return true, nil
    36  		}
    37  		return false, nil
    38  	})
    39  }
    40  
    41  // Create creates a new namespace with the given name.
    42  // If the namespace exists, it returns.
    43  func Create(namespace string, cs *testclient.ClientSet) error {
    44  	_, err := cs.Namespaces().Create(context.Background(), &k8sv1.Namespace{
    45  		ObjectMeta: metav1.ObjectMeta{
    46  			Name:   namespace,
    47  			Labels: inhibitSecurityAdmissionLabels,
    48  		}}, metav1.CreateOptions{})
    49  
    50  	if k8serrors.IsAlreadyExists(err) {
    51  		return nil
    52  	}
    53  	return err
    54  }
    55  
    56  // DeleteAndWait deletes a namespace and waits until it is deleted
    57  func DeleteAndWait(cs *testclient.ClientSet, namespace string, timeout time.Duration) error {
    58  	err := cs.Namespaces().Delete(context.Background(), namespace, metav1.DeleteOptions{})
    59  	if k8serrors.IsNotFound(err) {
    60  		return nil
    61  	}
    62  
    63  	if err != nil {
    64  		return fmt.Errorf("failed to delete namespace [%s]: %w", namespace, err)
    65  	}
    66  
    67  	return WaitForDeletion(cs, namespace, timeout)
    68  }
    69  
    70  // Exists tells whether the given namespace exists
    71  func Exists(namespace string, cs *testclient.ClientSet) bool {
    72  	_, err := cs.Namespaces().Get(context.Background(), namespace, metav1.GetOptions{})
    73  	return err == nil || !k8serrors.IsNotFound(err)
    74  }
    75  
    76  // CleanPods deletes all pods in namespace
    77  func CleanPods(namespace string, cs *testclient.ClientSet) error {
    78  	if !Exists(namespace, cs) {
    79  		return nil
    80  	}
    81  	err := cs.Pods(namespace).DeleteCollection(context.Background(), metav1.DeleteOptions{
    82  		GracePeriodSeconds: pointer.Int64Ptr(0),
    83  	}, metav1.ListOptions{})
    84  	if err != nil {
    85  		return fmt.Errorf("failed to delete pods %v", err)
    86  	}
    87  	return err
    88  }
    89  
    90  // CleanPolicies deletes all SriovNetworkNodePolicies in operatorNamespace
    91  func CleanPolicies(operatorNamespace string, cs *testclient.ClientSet) error {
    92  	policies := sriovv1.SriovNetworkNodePolicyList{}
    93  	err := cs.List(context.Background(),
    94  		&policies,
    95  		runtimeclient.InNamespace(operatorNamespace),
    96  	)
    97  	if err != nil {
    98  		return err
    99  	}
   100  	for _, p := range policies.Items {
   101  		if p.Name != "default" && strings.HasPrefix(p.Name, "test-") {
   102  			err := cs.Delete(context.Background(), &p)
   103  			if err != nil {
   104  				return fmt.Errorf("failed to delete policy %v", err)
   105  			}
   106  		}
   107  	}
   108  	return err
   109  }
   110  
   111  // CleanNetworks deletes all network in operatorNamespace
   112  func CleanNetworks(operatorNamespace string, cs *testclient.ClientSet) error {
   113  	networks := sriovv1.SriovNetworkList{}
   114  	err := cs.List(context.Background(),
   115  		&networks,
   116  		runtimeclient.InNamespace(operatorNamespace))
   117  	if err != nil {
   118  		return err
   119  	}
   120  	for _, n := range networks.Items {
   121  		if strings.HasPrefix(n.Name, "test-") {
   122  			err := cs.Delete(context.Background(), &n)
   123  			if err != nil {
   124  				return fmt.Errorf("failed to delete network %v", err)
   125  			}
   126  		}
   127  	}
   128  	return waitForSriovNetworkDeletion(operatorNamespace, cs, 15*time.Second)
   129  }
   130  
   131  func waitForSriovNetworkDeletion(operatorNamespace string, cs *testclient.ClientSet, timeout time.Duration) error {
   132  	return wait.PollImmediate(time.Second, timeout, func() (bool, error) {
   133  		networks := sriovv1.SriovNetworkList{}
   134  		err := cs.List(context.Background(),
   135  			&networks,
   136  			runtimeclient.InNamespace(operatorNamespace))
   137  		if err != nil {
   138  			return false, err
   139  		}
   140  		for _, network := range networks.Items {
   141  			if strings.HasPrefix(network.Name, "test-") {
   142  				return false, nil
   143  			}
   144  		}
   145  		return true, nil
   146  	})
   147  }
   148  
   149  // Clean cleans all dangling objects from the given namespace.
   150  func Clean(operatorNamespace, namespace string, cs *testclient.ClientSet, discoveryEnabled bool) error {
   151  	err := CleanPods(namespace, cs)
   152  	if err != nil {
   153  		return err
   154  	}
   155  	err = CleanNetworks(operatorNamespace, cs)
   156  	if err != nil {
   157  		return err
   158  	}
   159  	if discoveryEnabled {
   160  		return nil
   161  	}
   162  	err = CleanPolicies(operatorNamespace, cs)
   163  	if err != nil {
   164  		return err
   165  	}
   166  	return nil
   167  }