Skip to content

Commit 9d183fc

Browse files
committed
Event APIs
```/events```: returns list of all EventTriggers ```/event?name=<eventTrigger Name>````: returns details about a specific eventTrigger instance
1 parent a364732 commit 9d183fc

File tree

20 files changed

+2258
-27
lines changed

20 files changed

+2258
-27
lines changed

Makefile

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ fv: $(KUBECTL) $(GINKGO) ## Run Sveltos Controller tests using existing cluster
188188
create-cluster: $(KIND) $(CLUSTERCTL) $(KUBECTL) $(ENVSUBST) ## Create a new kind cluster designed for development
189189
$(MAKE) create-control-cluster
190190

191+
$(KUBECTL) apply -f test/servicemonitor_crd.yaml
192+
191193
@echo wait for capd-system pod
192194
$(KUBECTL) wait --for=condition=Available deployment/capd-controller-manager -n capd-system --timeout=$(TIMEOUT)
193195
$(KUBECTL) wait --for=condition=Available deployment/capi-kubeadm-control-plane-controller-manager -n capi-kubeadm-control-plane-system --timeout=$(TIMEOUT)
@@ -249,23 +251,8 @@ deploy-projectsveltos: $(KUSTOMIZE)
249251
@echo 'Load projectsveltos image into cluster'
250252
$(MAKE) load-image
251253

252-
@echo 'Install libsveltos CRDs'
253-
$(KUBECTL) apply -f https://raw.githubusercontent.com/projectsveltos/libsveltos/$(TAG)/config/crd/bases/lib.projectsveltos.io_debuggingconfigurations.yaml
254-
$(KUBECTL) apply -f https://raw.githubusercontent.com/projectsveltos/libsveltos/$(TAG)/config/crd/bases/lib.projectsveltos.io_sveltosclusters.yaml
255-
$(KUBECTL) apply -f https://raw.githubusercontent.com/projectsveltos/libsveltos/$(TAG)/config/crd/bases/lib.projectsveltos.io_clustersets.yaml
256-
$(KUBECTL) apply -f https://raw.githubusercontent.com/projectsveltos/libsveltos/$(TAG)/config/crd/bases/lib.projectsveltos.io_sets.yaml
257-
$(KUBECTL) apply -f https://raw.githubusercontent.com/projectsveltos/libsveltos/$(TAG)/config/crd/bases/lib.projectsveltos.io_sveltoslicenses.yaml
258-
$(KUBECTL) apply -f https://raw.githubusercontent.com/projectsveltos/libsveltos/$(TAG)/config/crd/bases/lib.projectsveltos.io_classifiers.yaml
259-
$(KUBECTL) apply -f https://raw.githubusercontent.com/projectsveltos/libsveltos/$(TAG)/config/crd/bases/lib.projectsveltos.io_debuggingconfigurations.yaml
260-
261-
@echo 'Install register-mgmt-cluster'
262-
$(KUBECTL) apply -f https://raw.githubusercontent.com/projectsveltos/register-mgmt-cluster/$(TAG)/manifest/manifest.yaml
263-
264-
# Install addon-controller
265-
$(KUBECTL) apply -f https://raw.githubusercontent.com/projectsveltos/addon-controller/$(TAG)/manifest/manifest.yaml
266-
267-
# Install sveltoscluster-manager
268-
$(KUBECTL) apply -f https://raw.githubusercontent.com/projectsveltos/sveltoscluster-manager/$(TAG)/manifest/manifest.yaml
254+
@echo 'Install projectsveltos'
255+
$(KUBECTL) apply -f https://raw.githubusercontent.com/projectsveltos/sveltos/$(TAG)/manifest/agents_in_mgmt_cluster_manifest.yaml
269256

270257
# Install projectsveltos ui-backend components
271258
@echo 'Install projectsveltos ui-backend-manager components'

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,35 @@ spec:
405405
helmChartAction: Install
406406
```
407407

408+
### Get list of EventTriggers
409+
410+
```/events```
411+
412+
This API supports pagination. Use:
413+
414+
. ```limit=<int>``` to specify the number of Kubernetes resources the API will return
415+
416+
. ```skip=<int>``` to specify from which Kubernetes resources to start (Kubernetes resources are ordered by lastAppliedTime)
417+
418+
```json
419+
{"totalEvents":1,"eventTriggers":[{"name":"service-network-policy","matchingClusters":1}]}%
420+
```
421+
422+
### Get EventTrigger Details
423+
424+
```event?name=<eventTrigger name>```
425+
426+
Response contains:
427+
428+
- Name: name of the eventTrigger
429+
- clusterSelector: eventTrigger's clusterSelector
430+
- referenced EventSource
431+
- MatchingClusters: list of clusters matching this profile. This list contains *only* the clusters users has permission for. For each cluster, list of resources matching the event
432+
433+
```json
434+
{"eventTriggerName":"service-network-policy","clusterSelector":{"matchLabels":{"env":"fv"}},"eventSource":{"kind":"EventSource","apiVersion":"lib.projectsveltos.io/v1beta1","metadata":{"name":"sveltos-service"},"spec":{"resourceSelectors":[{"group":"","version":"v1","kind":"Service","labelFilters":[{"key":"sveltos","operation":"Equal","value":"fv"}]}],"collectResources":true}},"clusterEventMatches":[{"clusterNamespace":"default","clusterName":"clusterapi-workload","clusterKind":"Cluster","labels":{"cluster.x-k8s.io/cluster-name":"clusterapi-workload","env":"fv","sveltos-agent":"present","topology.cluster.x-k8s.io/owned":""},"version":"v1.35.0","ready":true,"paused":true,"failureMessage":null,"resources":[{"name":"my-service","namespace":"default","group":"","kind":"Service","version":"","profileNames":null}]}]}
435+
```
436+
408437
### How to get token
409438

410439
First, create a service account in the desired namespace:

cmd/main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ const (
8888
//+kubebuilder:rbac:groups=lib.projectsveltos.io,resources=debuggingconfigurations,verbs=get;list;watch
8989
//+kubebuilder:rbac:groups=config.projectsveltos.io,resources=clusterconfigurations,verbs=get;list;watch
9090

91+
//+kubebuilder:rbac:groups=lib.projectsveltos.io,resources=eventtriggers,verbs=get;list;watch
92+
//+kubebuilder:rbac:groups=lib.projectsveltos.io,resources=eventtriggers/status,verbs=get;list;watch
93+
//+kubebuilder:rbac:groups=lib.projectsveltos.io,resources=eventsources,verbs=get;list;watch
94+
//+kubebuilder:rbac:groups=lib.projectsveltos.io,resources=eventsources/status,verbs=get;list;watch
95+
//+kubebuilder:rbac:groups=lib.projectsveltos.io,resources=eventreports,verbs=get;list;watch
96+
//+kubebuilder:rbac:groups=lib.projectsveltos.io,resources=eventreports/status,verbs=get;list;watch
97+
9198
func main() {
9299
scheme, err := controller.InitScheme()
93100
if err != nil {

config/rbac/role.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ rules:
5151
- lib.projectsveltos.io
5252
resources:
5353
- debuggingconfigurations
54+
- eventreports
55+
- eventreports/status
56+
- eventsources
57+
- eventsources/status
58+
- eventtriggers
59+
- eventtriggers/status
5460
- sveltosclusters
5561
- sveltosclusters/status
5662
verbs:

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ require (
1111
github.com/onsi/ginkgo/v2 v2.27.3
1212
github.com/onsi/gomega v1.38.3
1313
github.com/pkg/errors v0.9.1
14-
github.com/projectsveltos/addon-controller v1.3.0
15-
github.com/projectsveltos/libsveltos v1.3.0
14+
github.com/projectsveltos/addon-controller v1.3.1
15+
github.com/projectsveltos/event-manager v1.3.1
16+
github.com/projectsveltos/libsveltos v1.3.1
1617
github.com/spf13/pflag v1.0.10
1718
k8s.io/api v0.34.3
1819
k8s.io/apiextensions-apiserver v0.34.3

go.sum

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,12 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
174174
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
175175
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
176176
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
177-
github.com/projectsveltos/addon-controller v1.3.0 h1:qPcmcY5xbqNxy4KfnXkHZjV8CTvSpy24O93tS7Sqowc=
178-
github.com/projectsveltos/addon-controller v1.3.0/go.mod h1:vMvqrDbK/RoFo27gsvsDJwaMkKVZJLnf/PZEK1zh0Z8=
179-
github.com/projectsveltos/libsveltos v1.3.0 h1:m0AEG+HqTSkl93Wa9rizedH6nqTwUbrCeBdz4VGloNc=
180-
github.com/projectsveltos/libsveltos v1.3.0/go.mod h1:At1G0itHPdELlMuQh+v2rLtA/Kji9xMV8K1k0l/sQ1Q=
177+
github.com/projectsveltos/addon-controller v1.3.1 h1:FaZo6mWem7cAmd2lq/t5icuCRXgzMuHv8X2W+tmQ+P4=
178+
github.com/projectsveltos/addon-controller v1.3.1/go.mod h1:zc/2+QnzDCmyy1E4d3hrJ18GGSk1ZU6K2hV5PB9IZEc=
179+
github.com/projectsveltos/event-manager v1.3.1 h1:+5HwBHcFPOvR3m1q+QDa7UI2r2WZAGRpZ1o4ZdA/uXQ=
180+
github.com/projectsveltos/event-manager v1.3.1/go.mod h1:YJ1m8k83j6KTTrrgdzSOWqcFRN+wDksXvrcNInh5p7o=
181+
github.com/projectsveltos/libsveltos v1.3.1 h1:uUQ7YRwhWnxxBUjBmf6WJprwSsHJDJAPyHkUmQ+DyXI=
182+
github.com/projectsveltos/libsveltos v1.3.1/go.mod h1:At1G0itHPdELlMuQh+v2rLtA/Kji9xMV8K1k0l/sQ1Q=
181183
github.com/projectsveltos/lua-utils/glua-json v0.0.0-20251212200258-2b3cdcb7c0f5 h1:khnc+994UszxZYu69J+R5FKiLA/Nk1JQj0EYAkwTWz0=
182184
github.com/projectsveltos/lua-utils/glua-json v0.0.0-20251212200258-2b3cdcb7c0f5/go.mod h1:yVL8KQFa9tmcxgwl9nwIMtKgtmIVC1zaFRSCfOwYvPY=
183185
github.com/projectsveltos/lua-utils/glua-runes v0.0.0-20251212200258-2b3cdcb7c0f5 h1:YbsebwRwTRhV8QacvEAdFqxcxHdeu7JTVtsBovbkgos=

internal/controller/suite_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
ctrl "sigs.k8s.io/controller-runtime"
3232

3333
configv1beta1 "github.com/projectsveltos/addon-controller/api/v1beta1"
34+
eventv1beta1 "github.com/projectsveltos/event-manager/api/v1beta1"
3435
libsveltosv1beta1 "github.com/projectsveltos/libsveltos/api/v1beta1"
3536
)
3637

@@ -74,6 +75,9 @@ func setupScheme() (*runtime.Scheme, error) {
7475
if err := configv1beta1.AddToScheme(s); err != nil {
7576
return nil, err
7677
}
78+
if err := eventv1beta1.AddToScheme(s); err != nil {
79+
return nil, err
80+
}
7781

7882
return s, nil
7983
}

internal/controller/utils.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
2424

2525
configv1beta1 "github.com/projectsveltos/addon-controller/api/v1beta1"
26+
eventv1beta1 "github.com/projectsveltos/event-manager/api/v1beta1"
2627
libsveltosv1beta1 "github.com/projectsveltos/libsveltos/api/v1beta1"
2728
)
2829

@@ -43,6 +44,9 @@ func InitScheme() (*runtime.Scheme, error) {
4344
if err := apiextensionsv1.AddToScheme(s); err != nil {
4445
return nil, err
4546
}
47+
if err := eventv1beta1.AddToScheme(s); err != nil {
48+
return nil, err
49+
}
4650

4751
return s, nil
4852
}

internal/mcpclient/client.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,99 @@ func CheckClusterDeploymentStatuses(ctx context.Context, url string, clusterRef
301301

302302
return &deploymentResult, nil
303303
}
304+
305+
type EventPipelineStatus struct {
306+
// Stage 1: Detection
307+
ClusterReady bool `json:"clusterReady"`
308+
ClusterPaused bool `json:"clusterPaused"`
309+
ClusterMatched bool `json:"clusterMatched"`
310+
ClusterProvisioned bool `json:"clusterProvisioned"`
311+
EventSourceName string `json:"eventSourceName"`
312+
EventSourceFoundInControlCluster bool `json:"eventSourceFoundInControlCluster"`
313+
EventSourceFoundInManagedCluster bool `json:"eventSourceFoundInManagedCluster"`
314+
EventReportFoundInManagedCluster bool `json:"eventReportFoundInManagedCluster"`
315+
EventReportFoundInControlCluster bool `json:"eventReportFoundInControlCluster"`
316+
ResourcesDetected int `json:"resourcesDetected"`
317+
LastEventReportTime string `json:"lastEventReportTime,omitempty"`
318+
319+
// Stage 2: Result
320+
InstantiatedProfile string `json:"instantiatedProfile,omitempty"`
321+
322+
// Issue Reporting: contains all detected issues
323+
Issues []string `json:"issues,omitempty"`
324+
}
325+
326+
func AnalyzeEventPipeline(ctx context.Context, url string, clusterRef *corev1.ObjectReference,
327+
eventTriggerName string, logger logr.Logger) ([]string, error) {
328+
329+
session, err := connect(ctx, url, logger)
330+
if err != nil {
331+
logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to connect: %v", err))
332+
return nil, err
333+
}
334+
defer session.Close()
335+
336+
input := map[string]interface{}{
337+
"clusterRef": map[string]string{
338+
"namespace": clusterRef.Namespace,
339+
"name": clusterRef.Name,
340+
"apiVersion": clusterRef.APIVersion,
341+
"kind": clusterRef.Kind,
342+
},
343+
"eventTriggerName": eventTriggerName,
344+
}
345+
346+
result, err := session.CallTool(ctx, &mcp.CallToolParams{
347+
Name: "analyze_event_deployment_pipeline",
348+
Arguments: input,
349+
})
350+
351+
if err != nil {
352+
logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to invoked analyze_event_deployment_pipeline tool: %v", err))
353+
return nil, err
354+
}
355+
356+
if result.IsError {
357+
errorMsg := fmt.Sprintf("MCP analyze_event_deployment_pipeline returned error: %v", result.Content)
358+
logger.V(logs.LogInfo).Info(errorMsg)
359+
return nil, errors.New(errorMsg)
360+
}
361+
362+
// Check for structured content. It should contain our result.
363+
if result.StructuredContent == nil {
364+
errorMsg := noStructureContentError
365+
logger.V(logs.LogInfo).Info(errorMsg)
366+
return nil, errors.New(errorMsg)
367+
}
368+
369+
// Marshal the StructuredContent to JSON and then unmarshal it into our struct.
370+
// This is a common pattern for converting `any` to a specific type.
371+
data, err := json.Marshal(result.StructuredContent)
372+
if err != nil {
373+
errorMsg := fmt.Sprintf("failed to marshal structured content: %v", err)
374+
logger.V(logs.LogInfo).Info(errorMsg)
375+
return nil, errors.New(errorMsg)
376+
}
377+
378+
// Unmarshal into the status struct
379+
var status EventPipelineStatus
380+
if err := json.Unmarshal(data, &status); err != nil {
381+
errorMsg := fmt.Sprintf("failed to unmarshal result into EventPipelineStatus: %v", err)
382+
logger.V(logs.LogInfo).Info(errorMsg)
383+
return nil, errors.New(errorMsg)
384+
}
385+
386+
logger.V(logs.LogInfo).Info(fmt.Sprintf("analyze_profile_deployment result: %v", status))
387+
388+
if len(status.Issues) == 0 {
389+
logger.V(logs.LogInfo).Info(fmt.Sprintf("eventTrigger %s successfully deployed on cluster %s %s/%s",
390+
eventTriggerName, clusterRef.Kind, clusterRef.Namespace, clusterRef.Namespace))
391+
return []string{}, nil
392+
}
393+
394+
for i := range status.Issues {
395+
logger.V(logs.LogInfo).Info(fmt.Sprintf("Issue: %s", status.Issues[i]))
396+
}
397+
398+
return status.Issues, nil
399+
}

0 commit comments

Comments
 (0)