-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#20 Added new cloud-events, triggered events, better logging
Signed-off-by: Christian Kreuzberger <[email protected]>
- Loading branch information
1 parent
676ea10
commit ef804f6
Showing
7 changed files
with
727 additions
and
210 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,169 +1,255 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"github.com/cloudevents/sdk-go/pkg/cloudevents" | ||
cloudevents "github.com/cloudevents/sdk-go/v2" // make sure to use v2 cloudevents here | ||
keptn "github.com/keptn/go-utils/pkg/lib" | ||
keptnv2 "github.com/keptn/go-utils/pkg/lib/v0_2_0" | ||
) | ||
|
||
/** | ||
* Here are all the handler functions for the individual event | ||
See https://github.com/keptn/spec/blob/0.1.3/cloudevents.md for details on the payload | ||
-> "sh.keptn.event.configuration.change" | ||
-> "sh.keptn.events.deployment-finished" | ||
-> "sh.keptn.events.tests-finished" | ||
-> "sh.keptn.event.start-evaluation" | ||
-> "sh.keptn.events.evaluation-done" | ||
-> "sh.keptn.event.problem.open" | ||
-> "sh.keptn.events.problem" | ||
-> "sh.keptn.event.action.triggered" | ||
*/ | ||
|
||
// Handles ConfigureMonitoringEventType = "sh.keptn.event.monitoring.configure" | ||
func HandleConfigureMonitoringEvent(myKeptn *keptn.Keptn, incomingEvent cloudevents.Event, data *keptn.ConfigureMonitoringEventData) error { | ||
log.Printf("Handling Configure Monitoring Event: %s", incomingEvent.Context.GetID()) | ||
* See https://github.com/keptn/spec/blob/0.8.0-alpha/cloudevents.md for details on the payload | ||
**/ | ||
|
||
// GenericLogKeptnCloudEventHandler is a generic handler for Keptn Cloud Events that logs the CloudEvent | ||
func GenericLogKeptnCloudEventHandler(myKeptn *keptnv2.Keptn, incomingEvent cloudevents.Event, data interface{}) error { | ||
log.Printf("Handling %s Event: %s", incomingEvent.Type(), incomingEvent.Context.GetID()) | ||
log.Printf("CloudEvent %T: %v", data, data) | ||
|
||
return nil | ||
} | ||
|
||
// | ||
// Handles ConfigurationChangeEventType = "sh.keptn.event.configuration.change" | ||
// OldHandleConfigureMonitoringTriggeredEvent handles old configure-monitoring events | ||
// TODO: add in your handler code | ||
// | ||
func HandleConfigurationChangeEvent(myKeptn *keptn.Keptn, incomingEvent cloudevents.Event, data *keptn.ConfigurationChangeEventData) error { | ||
log.Printf("Handling Configuration Changed Event: %s", incomingEvent.Context.GetID()) | ||
func OldHandleConfigureMonitoringTriggeredEvent(myKeptn *keptnv2.Keptn, incomingEvent cloudevents.Event, data *keptn.ConfigureMonitoringEventData) error { | ||
log.Printf("Handling old configure-monitoring Event: %s", incomingEvent.Context.GetID()) | ||
|
||
return nil | ||
} | ||
|
||
// | ||
// Handles DeploymentFinishedEventType = "sh.keptn.events.deployment-finished" | ||
// HandleConfigureMonitoringTriggeredEvent handles configure-monitoring.triggered events | ||
// TODO: add in your handler code | ||
// | ||
func HandleDeploymentFinishedEvent(myKeptn *keptn.Keptn, incomingEvent cloudevents.Event, data *keptn.DeploymentFinishedEventData) error { | ||
log.Printf("Handling Deployment Finished Event: %s", incomingEvent.Context.GetID()) | ||
|
||
// capture start time for tests | ||
// startTime := time.Now() | ||
func HandleConfigureMonitoringTriggeredEvent(myKeptn *keptnv2.Keptn, incomingEvent cloudevents.Event, data *keptnv2.ConfigureMonitoringTriggeredEventData) error { | ||
log.Printf("Handling configure-monitoring.triggered Event: %s", incomingEvent.Context.GetID()) | ||
|
||
// run tests | ||
// ToDo: Implement your tests here | ||
|
||
// Send Test Finished Event | ||
// return myKeptn.SendTestsFinishedEvent(&incomingEvent, "", "", startTime, "pass", nil, "keptn-service-template-go") | ||
return nil | ||
} | ||
|
||
// | ||
// Handles TestsFinishedEventType = "sh.keptn.events.tests-finished" | ||
// HandleDeploymentTriggeredEvent handles deployment.triggered events | ||
// TODO: add in your handler code | ||
// | ||
func HandleTestsFinishedEvent(myKeptn *keptn.Keptn, incomingEvent cloudevents.Event, data *keptn.TestsFinishedEventData) error { | ||
log.Printf("Handling Tests Finished Event: %s", incomingEvent.Context.GetID()) | ||
func HandleDeploymentTriggeredEvent(myKeptn *keptnv2.Keptn, incomingEvent cloudevents.Event, data *keptnv2.DeploymentTriggeredEventData) error { | ||
log.Printf("Handling deployment.triggered Event: %s", incomingEvent.Context.GetID()) | ||
|
||
return nil | ||
} | ||
|
||
// | ||
// Handles EvaluationDoneEventType = "sh.keptn.events.evaluation-done" | ||
// HandleTestTriggeredEvent handles test.triggered events | ||
// TODO: add in your handler code | ||
// | ||
func HandleStartEvaluationEvent(myKeptn *keptn.Keptn, incomingEvent cloudevents.Event, data *keptn.StartEvaluationEventData) error { | ||
log.Printf("Handling Start Evaluation Event: %s", incomingEvent.Context.GetID()) | ||
func HandleTestTriggeredEvent(myKeptn *keptnv2.Keptn, incomingEvent cloudevents.Event, data *keptnv2.TestTriggeredEventData) error { | ||
log.Printf("Handling test.triggered Event: %s", incomingEvent.Context.GetID()) | ||
|
||
return nil | ||
} | ||
|
||
// | ||
// Handles DeploymentFinishedEventType = "sh.keptn.events.deployment-finished" | ||
// HandleEvaluationTriggeredEvent handles evaluation.triggered events | ||
// TODO: add in your handler code | ||
// | ||
func HandleEvaluationDoneEvent(myKeptn *keptn.Keptn, incomingEvent cloudevents.Event, data *keptn.EvaluationDoneEventData) error { | ||
log.Printf("Handling Evaluation Done Event: %s", incomingEvent.Context.GetID()) | ||
func HandleEvaluationTriggeredEvent(myKeptn *keptnv2.Keptn, incomingEvent cloudevents.Event, data *keptnv2.EvaluationTriggeredEventData) error { | ||
log.Printf("Handling evaluation.triggered Event: %s", incomingEvent.Context.GetID()) | ||
|
||
return nil | ||
} | ||
|
||
// | ||
// Handles InternalGetSLIEventType = "sh.keptn.internal.event.get-sli" | ||
// TODO: add in your handler code | ||
// | ||
func HandleInternalGetSLIEvent(myKeptn *keptn.Keptn, incomingEvent cloudevents.Event, data *keptn.InternalGetSLIEventData) error { | ||
log.Printf("Handling Internal Get SLI Event: %s", incomingEvent.Context.GetID()) | ||
// sendGetSliFinishedCloudEvent is a helper function to send a get-sli.finished event | ||
func sendGetSliFinishedCloudEvent(myKeptn *keptnv2.Keptn, incomingEvent cloudevents.Event, data *keptnv2.GetSLITriggeredEventData, | ||
status keptnv2.StatusType, result keptnv2.ResultType, message string) error { | ||
log.Printf("Sending getSli Finished Cloud Event with status=%s and result=%s back to Keptn (%s)", status, result, message) | ||
getSliFinishedEventData := keptnv2.GetSLIFinishedEventData{} | ||
|
||
getSliFinishedEventData.EventData = data.EventData | ||
getSliFinishedEventData.Status = status | ||
getSliFinishedEventData.Result = result | ||
getSliFinishedEventData.Message = message | ||
|
||
// Convert To CloudEvent | ||
finishedEvent := cloudevents.NewEvent() | ||
finishedEvent.SetType(keptnv2.GetFinishedEventType(keptnv2.GetSLITaskName)) | ||
finishedEvent.SetData(cloudevents.ApplicationJSON, getSliFinishedEventData) | ||
|
||
return SendEvent(myKeptn, finishedEvent, incomingEvent) | ||
} | ||
|
||
incomingGetSLIEventData := &keptn.InternalGetSLIEventData{} | ||
incomingEvent.DataAs(incomingGetSLIEventData) | ||
// HandleGetSliEvent handles get-sli events | ||
// TODO: adapt handler code to your needs | ||
func HandleGetSliEvent(myKeptn *keptnv2.Keptn, incomingEvent cloudevents.Event, data *keptnv2.GetSLITriggeredEventData) error { | ||
log.Printf("Handling get-sli.triggered Event: %s", incomingEvent.Context.GetID()) | ||
|
||
// Step 1 - Do we need to do something? | ||
// Lets make sure we are only processing an event that really belongs to our SLI Provider | ||
/* if incomingGetSLIEventData.SLIProvider != "keptn-service-template-go" { | ||
if data.GetSLI.SLIProvider != "keptn-service-template-go" { | ||
log.Printf("Not handling get-sli event as it is meant for %s", data.GetSLI.SLIProvider) | ||
return nil | ||
}*/ | ||
} | ||
|
||
// Step 2 - Send out a get-sli.started CloudEvent | ||
// The get-sli.started cloud-event is new since Keptn 0.8.0 and is required for the task to start | ||
getSliStartedData := keptnv2.GetSLIStartedEventData{} | ||
|
||
getSliStartedData.EventData = data.EventData | ||
getSliStartedData.Status = keptnv2.StatusSucceeded // alternative: keptnv2.StatusErrored | ||
getSliStartedData.Result = keptnv2.ResultPass // alternative: keptnv2.ResultFailed | ||
|
||
// Step 2 - prep-work | ||
// Get any additional input / configuration data, e.g | ||
// Labels: get the incoming labels for potential config data and use it to pass more labels on result, e.g: links | ||
// SLI.yaml: if your service uses SLI.yaml to store query definitions for SLIs get that file from Keptn | ||
/* labels := incomingGetSLIEventData.Labels | ||
// Convert To CloudEvent | ||
startedEvent := cloudevents.NewEvent() | ||
startedEvent.SetType(keptnv2.GetStartedEventType(keptnv2.GetSLITaskName)) | ||
startedEvent.SetData(cloudevents.ApplicationJSON, getSliStartedData) | ||
|
||
// send action.started event | ||
SendEvent(myKeptn, startedEvent, incomingEvent) | ||
|
||
// Step 4 - prep-work | ||
// Get any additional input / configuration data | ||
// - Labels: get the incoming labels for potential config data and use it to pass more labels on result, e.g: links | ||
// - SLI.yaml: if your service uses SLI.yaml to store query definitions for SLIs get that file from Keptn | ||
labels := data.Labels | ||
if labels == nil { | ||
labels = make(map[string]string) | ||
} | ||
testRunID := labels["testRunId"]*/ | ||
testRunID := labels["testRunId"] | ||
|
||
// Step 5 - get SLI Config File | ||
// Get SLI File from keptn-service-template-go subdirectory of the config repo - to add the file use: | ||
// keptn add-resource --project=PROJECT --stage=STAGE --service=SERVICE --resource=my-sli-config.yaml --resourceUri=keptn-service-template-go/sli.yaml | ||
sliFile := "keptn-service-template-go/sli.yaml" | ||
sliConfigFileContent, err := myKeptn.GetKeptnResource(sliFile) | ||
|
||
if err != nil { | ||
// failed to fetch sli config file | ||
errMsg := fmt.Sprintf("Failed to fetch SLI file %s from config repo: %s", sliFile, err.Error()) | ||
log.Println(errMsg) | ||
// send a get-sli.finished event with status=error and result=failed back to Keptn | ||
return sendGetSliFinishedCloudEvent(myKeptn, incomingEvent, data, keptnv2.StatusErrored, keptnv2.ResultFailed, errMsg) | ||
} | ||
|
||
// sliConfigFileContent, err := myKeptn.GetKeptnResource("keptn-service-template-go/sli.yaml") | ||
fmt.Println(sliConfigFileContent) | ||
|
||
// Step 3 - do your work - iterate through the list of requested indicators and return their values | ||
// Step 6 - do your work - iterate through the list of requested indicators and return their values | ||
// Indicators: this is the list of indicators as requested in the SLO.yaml | ||
// SLIResult: this is the array that will receive the results | ||
/* indicators := incomingGetSLIEventData.Indicators | ||
sliResults := []*keptn.SLIResult{} | ||
indicators := data.GetSLI.Indicators | ||
sliResults := []*keptnv2.SLIResult{} | ||
|
||
for _, indicatorName := range indicators { | ||
sliResult := &keptn.SLIResult{ | ||
sliResult := &keptnv2.SLIResult{ | ||
Metric: indicatorName, | ||
Value: 123.4, | ||
Value: 123.4, // ToDo: Fetch the values from your monitoring tool here | ||
} | ||
sliResults = append(sliResults, sliResult) | ||
}*/ | ||
} | ||
|
||
// Step 4 - add additional context via labels | ||
// labels["Link to Data Source"] = "https://mydatasource/myquery?testRun=" + testRunID | ||
// Step 7 - add additional context via labels (e.g., a backlink to the monitoring or CI tool) | ||
labels["Link to Data Source"] = "https://mydatasource/myquery?testRun=" + testRunID | ||
|
||
// Step 8 - Build get-sli.finished event data | ||
getSliFinishedEventData := keptnv2.GetSLIFinishedEventData{ | ||
EventData: keptnv2.EventData{ | ||
Project: data.Project, | ||
Stage: data.Stage, | ||
Service: data.Service, | ||
Labels: labels, | ||
Status: keptnv2.StatusSucceeded, | ||
Result: keptnv2.ResultPass, | ||
}, | ||
GetSLI: struct { | ||
Start string `json:"start"` | ||
End string `json:"end"` | ||
IndicatorValues []*keptnv2.SLIResult `json:"indicatorValues"` | ||
}{ | ||
IndicatorValues: sliResults, | ||
Start: data.GetSLI.Start, | ||
End: data.GetSLI.End, | ||
}, | ||
} | ||
|
||
// Step 4 - send results back to Keptn | ||
// return myKeptn.SendInternalGetSLIDoneEvent(incomingGetSLIEventData, sliResults, labels, err, "keptn-service-template-go") | ||
// Step 8 - Convert To CloudEvent | ||
finishedEvent := cloudevents.NewEvent() | ||
finishedEvent.SetType(keptnv2.GetFinishedEventType(keptnv2.GetSLITaskName)) | ||
finishedEvent.SetData(cloudevents.ApplicationJSON, getSliFinishedEventData) | ||
|
||
return nil | ||
// Step 9 - send action.finished CloudEvent back to Keptn | ||
return SendEvent(myKeptn, finishedEvent, incomingEvent) | ||
} | ||
|
||
// | ||
// Handles ProblemOpenEventType = "sh.keptn.event.problem.open" | ||
// Handles ProblemEventType = "sh.keptn.events.problem" | ||
// HandleProblemEvent handles two problem events: | ||
// - ProblemOpenEventType = "sh.keptn.event.problem.open" | ||
// - ProblemEventType = "sh.keptn.events.problem" | ||
// TODO: add in your handler code | ||
// | ||
func HandleProblemEvent(myKeptn *keptn.Keptn, incomingEvent cloudevents.Event, data *keptn.ProblemEventData) error { | ||
func HandleProblemEvent(myKeptn *keptnv2.Keptn, incomingEvent cloudevents.Event, data *keptn.ProblemEventData) error { | ||
log.Printf("Handling Problem Event: %s", incomingEvent.Context.GetID()) | ||
|
||
// Deprecated since Keptn 0.7.0 - use the HandleActionTriggeredEvent instead | ||
|
||
return nil | ||
} | ||
|
||
// | ||
// Handles ActionTriggeredEventType = "sh.keptn.event.action.triggered" | ||
// HandleActionTriggeredEvent handles action.triggered events | ||
// TODO: add in your handler code | ||
// | ||
func HandleActionTriggeredEvent(myKeptn *keptn.Keptn, incomingEvent cloudevents.Event, data *keptn.ActionTriggeredEventData) error { | ||
func HandleActionTriggeredEvent(myKeptn *keptnv2.Keptn, incomingEvent cloudevents.Event, data *keptnv2.ActionTriggeredEventData) error { | ||
log.Printf("Handling Action Triggered Event: %s", incomingEvent.Context.GetID()) | ||
log.Printf("Action=%s\n", data.Action.Action) | ||
|
||
// check if action is supported | ||
if data.Action.Action == "action-xyz" { | ||
//myKeptn.SendActionStartedEvent() | ||
// ----------------------------------------------------- | ||
// 1. Send Action.Started Cloud-Event | ||
// ----------------------------------------------------- | ||
|
||
// generate an action.started event | ||
actionStartedData := keptnv2.ActionStartedEventData{} | ||
|
||
actionStartedData.EventData = data.EventData | ||
actionStartedData.Status = keptnv2.StatusSucceeded // alternative: keptnv2.StatusErrored | ||
actionStartedData.Result = keptnv2.ResultPass // alternative: keptnv2.ResultFailed | ||
|
||
// Convert To CloudEvent | ||
startedEvent := cloudevents.NewEvent() | ||
startedEvent.SetType(keptnv2.GetStartedEventType(keptnv2.ActionTaskName)) | ||
startedEvent.SetData(cloudevents.ApplicationJSON, actionStartedData) | ||
|
||
// send action.started event | ||
SendEvent(myKeptn, startedEvent, incomingEvent) | ||
|
||
// Implement your remediation action here | ||
// ----------------------------------------------------- | ||
// 2. Implement your remediation action here | ||
// ----------------------------------------------------- | ||
time.Sleep(5 * time.Second) // Example: Wait 5 seconds. Maybe the problem fixes itself. | ||
|
||
//myKeptn.SendActionFinishedEvent() | ||
// ----------------------------------------------------- | ||
// 3. Send Action.Finished Cloud-Event | ||
// ----------------------------------------------------- | ||
|
||
// generate an action.finished event | ||
actionFinishedData := keptnv2.ActionFinishedEventData{} | ||
|
||
actionFinishedData.EventData = data.EventData | ||
actionFinishedData.Status = keptnv2.StatusSucceeded // alternative: keptnv2.StatusErrored | ||
actionFinishedData.Result = keptnv2.ResultPass // alternative: keptnv2.ResultFailed | ||
actionFinishedData.Message = "Successfully sleeped!" | ||
|
||
// Convert To CloudEvent | ||
finishedEvent := cloudevents.NewEvent() | ||
finishedEvent.SetType(keptnv2.GetFinishedEventType(keptnv2.ActionTaskName)) | ||
finishedEvent.SetData(cloudevents.ApplicationJSON, actionFinishedData) | ||
|
||
// send action.finished event | ||
SendEvent(myKeptn, finishedEvent, incomingEvent) | ||
|
||
} else { | ||
log.Printf("Retrieved unknown action %s, skipping...", data.Action.Action) | ||
return nil | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.