Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support Custom Resource Test Triggers using dynamic informers #4161

Draft
wants to merge 21 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,14 @@ video:

ffmpeg -y -r 30 -f image2pipe -vcodec ppm -i stream.out -b 65536K movie.mp4

nats-tunnel:
kubectl run nats-tunnel-$$USER \
-it --image=alpine/socat \
--tty --rm --expose=true --port=4222 \
tcp-listen:4222,fork,reuseaddr tcp-connect:testkube-nats:4222

port-forward-nats:
kubectl port-forward svc/nats-tunnel-$$USER 4222:4222 -ntestkube

port-forward-minio:
kubectl port-forward svc/testkube-minio-service-testkube 9090:9090 -ntestkube
Expand Down
6 changes: 6 additions & 0 deletions cmd/api-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ func main() {
ui.ExitOnError("Creating k8s clientset", err)
}

dynamicClientSet, err := k8sclient.ConnectToK8sDynamic()
if err != nil {
ui.ExitOnError("Creating k8s clientset", err)
}

k8sCfg, err := k8sclient.GetK8sClientConfig()
if err != nil {
ui.ExitOnError("Getting k8s client config", err)
Expand Down Expand Up @@ -431,6 +436,7 @@ func main() {
triggerService := triggers.NewService(
sched,
clientset,
dynamicClientSet,
testkubeClientset,
testsuitesClientV3,
testsClientV3,
Expand Down
1 change: 1 addition & 0 deletions pkg/keymap/triggers/triggers.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@ func getSupportedEvents() map[string][]string {
m[testtrigger.ResourceIngress] = []string{string(testtrigger.EventCreated), string(testtrigger.EventModified), string(testtrigger.EventDeleted)}
m[testtrigger.ResourceEvent] = []string{string(testtrigger.EventCreated), string(testtrigger.EventModified), string(testtrigger.EventDeleted)}
m[testtrigger.ResourceConfigMap] = []string{string(testtrigger.EventCreated), string(testtrigger.EventModified), string(testtrigger.EventDeleted)}
m[testtrigger.ResourceCustomResource] = []string{string(testtrigger.EventCreated), string(testtrigger.EventModified), string(testtrigger.EventDeleted)}
return m
}
39 changes: 39 additions & 0 deletions pkg/mapper/customresources/mapper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package customresources

import (
"fmt"
"time"

testtriggersv1 "github.com/kubeshop/testkube-operator/apis/testtriggers/v1"
)

// MapCRDConditionsToAPI maps CRD conditions to OpenAPI spec TestTriggerConditions
func MapCRDConditionsToAPI(conditions []interface{}, currentTime time.Time) []testtriggersv1.TestTriggerCondition {
// TODO: find a way to generically map conditions to TriggerSpec
var results []testtriggersv1.TestTriggerCondition
for _, condition := range conditions {
c := make(map[string]string)
for key, value := range condition.(map[string]interface{}) {
strKey := fmt.Sprintf("%v", key)
strValue := fmt.Sprintf("%v", value)

c[strKey] = strValue
}

// TODO: confirm appropriate layout
layout := time.RFC3339
t, err := time.Parse(layout, c["lastTransitionTime"])
if err != nil {
fmt.Println("Error parsing time:", err)
}
status := c["status"]
results = append(results, testtriggersv1.TestTriggerCondition{
Type_: string(c["type"]),
Status: (*testtriggersv1.TestTriggerConditionStatuses)(&status),
Reason: c["reason"],
Ttl: int32(currentTime.Sub(t) / time.Second),
})
}

return results
}
22 changes: 22 additions & 0 deletions pkg/triggers/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ package triggers

import (
"context"
"github.com/kubeshop/testkube/pkg/mapper/customresources"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -125,3 +129,21 @@ func getServiceConditions(

return services.MapCRDConditionsToAPI(service.Status.Conditions, time.Now()), nil
}

func getCustomResourceConditions(
ctx context.Context,
dynamicClientset dynamic.Interface,
object metav1.Object,
gvr schema.GroupVersionResource,
) ([]testtriggersv1.TestTriggerCondition, error) {
customresource, err := dynamicClientset.Resource(gvr).Namespace(object.GetNamespace()).Get(ctx, object.GetName(), metav1.GetOptions{})
if err != nil {
return nil, err
}

objWithConditions, _, err := unstructured.NestedSlice(customresource.Object, "status", "conditions")
if err != nil {
return nil, err
}
return customresources.MapCRDConditionsToAPI(objWithConditions, time.Now()), nil
}
6 changes: 5 additions & 1 deletion pkg/triggers/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package triggers
import (
"context"
"fmt"
"k8s.io/client-go/dynamic"
"os"
"strings"
"time"
Expand Down Expand Up @@ -52,6 +53,7 @@ type Service struct {
triggerStatus map[statusKey]*triggerStatus
scheduler *scheduler.Scheduler
clientset kubernetes.Interface
dynamicClientset dynamic.Interface
testKubeClientset testkubeclientsetv1.Interface
testSuitesClient testsuitesclientv3.Interface
testsClient testsclientv3.Interface
Expand All @@ -69,6 +71,7 @@ type Option func(*Service)
func NewService(
scheduler *scheduler.Scheduler,
clientset kubernetes.Interface,
dynamicClientset dynamic.Interface,
testKubeClientset testkubeclientsetv1.Interface,
testSuitesClient testsuitesclientv3.Interface,
testsClient testsclientv3.Interface,
Expand All @@ -91,6 +94,7 @@ func NewService(
defaultConditionsCheckBackoff: defaultConditionsCheckBackoff,
scheduler: scheduler,
clientset: clientset,
dynamicClientset: dynamicClientset,
testKubeClientset: testKubeClientset,
testSuitesClient: testSuitesClient,
testsClient: testsClient,
Expand All @@ -111,7 +115,7 @@ func NewService(
opt(s)
}

s.informers = newK8sInformers(clientset, testKubeClientset, s.testkubeNamespace, s.watcherNamespaces)
s.informers = newK8sInformers(clientset, dynamicClientset, testKubeClientset, s.testkubeNamespace, s.watcherNamespaces, logger)

return s
}
Expand Down
1 change: 1 addition & 0 deletions pkg/triggers/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ func TestService_Run(t *testing.T) {
s := NewService(
sched,
fakeClientset,
nil,
fakeTestkubeClientset,
mockTestSuitesClient,
mockTestsClient,
Expand Down
Loading