github.com/kubeshop/testkube@v1.17.23/pkg/triggers/event.go (about)

     1  package triggers
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  	"time"
     8  
     9  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    10  	"k8s.io/client-go/kubernetes"
    11  
    12  	testtriggersv1 "github.com/kubeshop/testkube-operator/api/testtriggers/v1"
    13  	"github.com/kubeshop/testkube-operator/pkg/validation/tests/v1/testtrigger"
    14  	"github.com/kubeshop/testkube/pkg/mapper/daemonsets"
    15  	"github.com/kubeshop/testkube/pkg/mapper/deployments"
    16  	"github.com/kubeshop/testkube/pkg/mapper/pods"
    17  	"github.com/kubeshop/testkube/pkg/mapper/services"
    18  	"github.com/kubeshop/testkube/pkg/mapper/statefulsets"
    19  )
    20  
    21  type conditionsGetterFn func() ([]testtriggersv1.TestTriggerCondition, error)
    22  
    23  type addressGetterFn func(ctx context.Context, delay time.Duration) (string, error)
    24  
    25  type watcherEvent struct {
    26  	resource         testtrigger.ResourceType
    27  	name             string
    28  	namespace        string
    29  	labels           map[string]string
    30  	object           metav1.Object
    31  	eventType        testtrigger.EventType
    32  	causes           []testtrigger.Cause
    33  	conditionsGetter conditionsGetterFn
    34  	addressGetter    addressGetterFn
    35  }
    36  
    37  type watcherOpts func(*watcherEvent)
    38  
    39  func withCauses(causes []testtrigger.Cause) watcherOpts {
    40  	return func(w *watcherEvent) {
    41  		w.causes = causes
    42  	}
    43  }
    44  
    45  func withConditionsGetter(conditionsGetter conditionsGetterFn) watcherOpts {
    46  	return func(w *watcherEvent) {
    47  		w.conditionsGetter = conditionsGetter
    48  	}
    49  }
    50  
    51  func withAddressGetter(addressGetter addressGetterFn) watcherOpts {
    52  	return func(w *watcherEvent) {
    53  		w.addressGetter = addressGetter
    54  	}
    55  }
    56  
    57  func newWatcherEvent(
    58  	eventType testtrigger.EventType,
    59  	object metav1.Object,
    60  	resource testtrigger.ResourceType,
    61  	opts ...watcherOpts,
    62  ) *watcherEvent {
    63  	w := &watcherEvent{
    64  		resource:  resource,
    65  		name:      object.GetName(),
    66  		namespace: object.GetNamespace(),
    67  		labels:    object.GetLabels(),
    68  		object:    object,
    69  		eventType: eventType,
    70  	}
    71  
    72  	for _, opt := range opts {
    73  		opt(w)
    74  	}
    75  
    76  	return w
    77  }
    78  
    79  func getPodConditions(ctx context.Context, clientset kubernetes.Interface, object metav1.Object) ([]testtriggersv1.TestTriggerCondition, error) {
    80  	pod, err := clientset.CoreV1().Pods(object.GetNamespace()).Get(ctx, object.GetName(), metav1.GetOptions{})
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  
    85  	return pods.MapCRDConditionsToAPI(pod.Status.Conditions, time.Now()), nil
    86  }
    87  
    88  func getPodAdress(ctx context.Context, clientset kubernetes.Interface, object metav1.Object, delay time.Duration) (string, error) {
    89  	podIP := ""
    90  outerLoop:
    91  	for {
    92  		select {
    93  		case <-ctx.Done():
    94  			return "", ctx.Err()
    95  		default:
    96  			pod, err := clientset.CoreV1().Pods(object.GetNamespace()).Get(ctx, object.GetName(), metav1.GetOptions{})
    97  			if err != nil {
    98  				return "", err
    99  			}
   100  
   101  			podIP = pod.Status.PodIP
   102  			if podIP != "" {
   103  				break outerLoop
   104  			}
   105  
   106  			time.Sleep(delay)
   107  		}
   108  	}
   109  
   110  	return fmt.Sprintf("%s.%s.pod.cluster.local", strings.ReplaceAll(podIP, ".", "-"), object.GetNamespace()), nil
   111  }
   112  
   113  func getDeploymentConditions(
   114  	ctx context.Context,
   115  	clientset kubernetes.Interface,
   116  	object metav1.Object,
   117  ) ([]testtriggersv1.TestTriggerCondition, error) {
   118  	deployment, err := clientset.AppsV1().Deployments(object.GetNamespace()).Get(ctx, object.GetName(), metav1.GetOptions{})
   119  	if err != nil {
   120  		return nil, err
   121  	}
   122  
   123  	return deployments.MapCRDConditionsToAPI(deployment.Status.Conditions, time.Now()), nil
   124  }
   125  
   126  func getDaemonSetConditions(
   127  	ctx context.Context,
   128  	clientset kubernetes.Interface,
   129  	object metav1.Object,
   130  ) ([]testtriggersv1.TestTriggerCondition, error) {
   131  	daemonset, err := clientset.AppsV1().DaemonSets(object.GetNamespace()).Get(ctx, object.GetName(), metav1.GetOptions{})
   132  	if err != nil {
   133  		return nil, err
   134  	}
   135  
   136  	return daemonsets.MapCRDConditionsToAPI(daemonset.Status.Conditions, time.Now()), nil
   137  }
   138  
   139  func getStatefulSetConditions(
   140  	ctx context.Context,
   141  	clientset kubernetes.Interface,
   142  	object metav1.Object,
   143  ) ([]testtriggersv1.TestTriggerCondition, error) {
   144  	statefulset, err := clientset.AppsV1().StatefulSets(object.GetNamespace()).Get(ctx, object.GetName(), metav1.GetOptions{})
   145  	if err != nil {
   146  		return nil, err
   147  	}
   148  
   149  	return statefulsets.MapCRDConditionsToAPI(statefulset.Status.Conditions, time.Now()), nil
   150  }
   151  
   152  func getServiceConditions(
   153  	ctx context.Context,
   154  	clientset kubernetes.Interface,
   155  	object metav1.Object,
   156  ) ([]testtriggersv1.TestTriggerCondition, error) {
   157  	service, err := clientset.CoreV1().Services(object.GetNamespace()).Get(ctx, object.GetName(), metav1.GetOptions{})
   158  	if err != nil {
   159  		return nil, err
   160  	}
   161  
   162  	return services.MapCRDConditionsToAPI(service.Status.Conditions, time.Now()), nil
   163  }
   164  
   165  func getServiceAdress(ctx context.Context, clientset kubernetes.Interface, object metav1.Object) (string, error) {
   166  	return fmt.Sprintf("%s.%s.svc.cluster.local", object.GetName(), object.GetNamespace()), nil
   167  }