Home / Keptn v1 Docs / Release 0.8.7 / Custom Integrations / Migrate existing Keptn integration
This guide will provide information for migrating an existing Keptn 0.7.x service to a Keptn 0.8.x service based on our Go package keptn/go-utils as well as our keptn-service-template-go. If you are using a different framework/programming language, please try to apply the changes described as best as you can.
Note: If you are using the latest version of go-utils
(v0.8.0 at the time of writing), this is handled automatically for you in our new helper functions (see below).
With Keptn 0.8.x, we have upgraded to CloudEvents spec 1.0. Please upgrade your relevant CloudEvents and set "specversion": "1.0"
where adequate, e.g.:
{
"type": "sh.keptn.events.deployment-finished",
"specversion": "1.0",
...
}
Also, don’t forget to update the respective CloudEvents SDK/package.
Note: Most of the following is automatically handled if you are using the latest version of go-utils
.
In addition to CloudEvents itself, Keptn is shipping a whole new spec for Keptn specific CloudEvents (see https://github.com/keptn/spec/blob/0.2.0/cloudevents.md for current version).
The most important changes are:
sh.keptn.event.
(used to be sh.keptn.events
for some older events)deployment.finished
)deployment
, test
, evaluation
, get-sli
) and its status: .triggered
, .started
, .status.changed
and .finished
(e.g., deployment.finished
, test.triggered
, …)"shkeptnspecversion": "0.2.0"
.triggered
event, it is expected to respond with a .started
event, and eventually a .finished
event..started
, .status.changed
and .finished
require a triggeredid
in the CloudEvents extension.triggered
event (they should no longer listen to events like deployment-finished
or tests-finished
to do what they need to do)To make the migration easier, here is a table that maps 0.7.x CloudEvents with 0.8.x CloudEvents depending on the use case:
Description / Use case | Keptn 0.7.x | Keptn 0.8.x |
---|---|---|
A configuration-change was triggered (e.g., via CLI) | sh.keptn.event.configuration.change |
sh.keptn.event.${STAGE}.${SEQUENCE}.triggered , e.g., sh.keptn.event.dev.artifact-delivery.triggered |
A deployment has started | - | sh.keptn.event.deployment.started |
A deployment has finished, notify another service (e.g. slack) about it | sh.keptn.events.deployment-finished |
sh.keptn.event.deployment.finished |
A deployment has finished, start tests | sh.keptn.events.deployment-finished |
sh.keptn.event.test.triggered |
Tests have started | - | sh.keptn.event.test.started |
Tests have finished, notify another service (e.g., slack) about it | sh.keptn.events.tests-finished |
sh.keptn.event.test.finished |
Tests have finished, start evaluation | sh.keptn.events.tests-finished |
sh.keptn.event.evaluation.triggered |
An evaluation is manually triggered (e.g., via CLI) | sh.keptn.event.start-evaluation |
sh.keptn.event.evaluation.triggered |
Evaluation has started | - | sh.keptn.event.evaluation.started |
Evaluation has finished, do next step or alike | sh.keptn.events.evaluation-done |
sh.keptn.event.evaluation.finished |
Invalidate evaluation | sh.keptn.events.evaluation.invalidated |
sh.keptn.event.evaluation.invalidated |
Start retrieving SLIs (known as internal Get-SLI event) | sh.keptn.internal.event.get-sli |
sh.keptn.event.get-sli.triggered |
Retrieving SLIs has started | - | sh.keptn.event.get-sli.started |
Retrieving SLIs has finished | sh.keptn.internal.event.get-sli.done |
sh.keptn.event.get-sli.finished |
Trigger an approval | sh.keptn.event.approval.triggered |
sh.keptn.event.approval.triggered |
Approval has started | - | sh.keptn.event.approval.started |
Approval has finished | sh.keptn.event.approval.finished |
sh.keptn.event.approval.finished |
Remedation triggered | sh.keptn.event.remediation.triggered |
sh.keptn.event.remediation.triggered |
Remediation started | sh.keptn.event.remediation.started |
sh.keptn.event.remediation.started |
Remediation status changed | sh.keptn.event.remediation.status.changed |
sh.keptn.event.remediation.status.changed |
Remediation finished | sh.keptn.event.remediation.finished |
sh.keptn.event.remediation.finished |
(Remediation) Action triggered | sh.keptn.event.action.triggered |
sh.keptn.event.action.triggered |
(Remediation) Action started | sh.keptn.event.action.started |
sh.keptn.event.action.started |
(Remediation) Action finished | sh.keptn.event.action.finished |
sh.keptn.event.action.finished |
Configure Monitoring | sh.keptn.event.monitoring.configure |
sh.keptn.event.configure-monitoring (pending changes) |
Configure Monitoring Finished | - | sh.keptn.event.configure-monitoring.finished |
Project was created | sh.keptn.internal.event.project.create |
Ongoing discussion |
Project was deleted | sh.keptn.internal.event.project.delete |
Ongoing discussion |
Service was created | sh.keptn.internal.event.service.create |
Ongoing discussion |
Service was deleted | sh.keptn.internal.event.service.delete |
Ongoing discussion |
Please note, that even if the name stayed the same, the payloads might have changed. You will need to consult the respective CloudEvents doc, e.g.,
action.triggered
on Keptn 0.7.x (spec 0.1.7): https://github.com/keptn/spec/blob/0.1.7/cloudevents.md#action-triggeredaction.triggered
on Keptn 0.8.x (spec 0.2.0): https://github.com/keptn/spec/blob/0.2.0/cloudevents.md#action-triggeredAs already described above, we have significantly changed the way Keptn executes a sequence e.g. for continuous-delivery. Therefore we are providing some more guidance on how the workflow has changed in certain scenarios below.
In Keptn 0.7.x we relied on a configuration-changed
event to start deployments:
sh.keptn.event.configuration.change (e.g., sent via Keptn CLI)
-> helm-service creates a helm-release and upgrades it on the Kubernetes Cluster
-> helm-service sends sh.keptn.events.deployment-finished
In Keptn 0.8.x this has significantly changed, as we introduced specific .triggered
, .started
, .finished
events for this:
sh.keptn.event.deployment.triggered (sent by shipyard-controller)
-> helm-service reacts
-> helm-service sends sh.keptn.event.deployment.started
-> helm-service creates a helm-release and upgrades it on the Kubernetes Cluster
-> helm-service sends sh.keptn.event.deployment.finished (result: pass/fail)
In Keptn 0.7.x we relied on a deployment-finished
event to start tests:
sh.keptn.events.deployment-finished (e.g., sent by helm-service)
-> jmeter-service executes tests
-> jmeter-service sends sh.keptn.events.tests-finished (result: pass/fail)
In Keptn 0.8.x this has significantly changed, as we introduced specific .triggered
, .started
, .finished
events for this:
sh.keptn.event.test.triggered (sent by shipyard-controller)
-> jmeter-service reacts
-> jmeter-service sends sh.keptn.event.test.started
-> jmeter-service executes tests
-> jmeter-service sends sh.keptn.events.test.finished (result: pass/fail)
In Keptn 0.7.x we relied on internal get-sli
event to fetch SLIs:
sh.keptn.internal.event.get-sli (e.g., sent by lighthouse-service)
-> SLI provider (e.g., prometheus-sli-service) starts fetching values from monitoring tool
-> SLI Provider (e.g., prometheus-sli-service) sends sh.keptn.internal.event.get-sli.done
In Keptn 0.8.x we have slightly adapted this behaviour, and enhanced it with specific .triggered
, .started
, .finished
events for this:
sh.keptn.event.get-sli.triggered (e.g., sent by lighthouse-service)
-> SLI provider (e.g., prometheus-sli-service) reacts
-> SLI provider (e.g., prometheus-sli-service) sends sh.keptn.event.get-sli.started
-> SLI provider (e.g., prometheus-sli-service) starts fetching values from monitoring tool
-> SLI Provider (e.g., prometheus-sli-service) sends sh.keptn.event.get-sli.finished
Note: This is based on https://github.com/keptn-sandbox/keptn-service-template-go/pull/24
If you have been using go-utils
without our keptn-service-template-go
, please upgrade go-utils manually using
go get github.com/keptn/go-utils@v0.8.0
go mod tidy
There are many breaking changes introduced, most notably:
github.com/keptn/go-utils/pkg/lib/v0_2_0
instead of github.com/keptn/go-utils/pkg/lib
github.com/cloudevents/sdk-go/v2
instead of github.com/cloudevents/sdk-go/pkg/cloudevents
github.com/keptn/go-utils/pkg/lib/v0_2_0
.started
and .finished
CloudEvent with triggeredid
set to the original event id.finished
CloudEvent)What does this mean for your code?
Previously, you might have had the following import in your Go Code:
import (
keptn "github.com/keptn/go-utils/pkg/lib"
)
Change this to:
import (
keptnv2 "github.com/keptn/go-utils/pkg/lib/v0_2_0"
)
If you want to have both, we recommend using it like this:
import (
keptn "github.com/keptn/go-utils/pkg/lib"
keptn "github.com/keptn/go-utils/pkg/lib"
keptnv2 "github.com/keptn/go-utils/pkg/lib/v0_2_0"
)
Make sure to adapt all occurrences where you used keptn.
(e.g., keptn.Keptn
and keptn.NewKeptn
) accordingly, e.g.:
myKeptn, err := keptn.NewKeptn(&event, keptnOptions)
should now be
myKeptn, err := keptnv2.NewKeptn(&event, keptnOptions)
Also, for functions, you should change it accordingly, e.g.:
func HandleGetSLIEvent(myKeptn *keptn.Keptn, incomingEvent cloudevents.Event, data *keptn.InternalGetSLIEventData) error {
...
}
should be adapted to
func HandleGetSLIEvent(myKeptn *keptnv2.Keptn, incomingEvent cloudevents.Event, data *keptnv2.GetSLITriggeredEventData) error {
...
}
As a best practice, it’s good to have serviceName in a const:
// ServiceName specifies the current services name (e.g., used as source when sending CloudEvents)
const ServiceName = "your-service-name"
github.com/cloudevents/sdk-go/v2
This change is required to be compatible with the latest Keptn CloudEvents spec. All you need to do is replace your imports, e.g.:
import (
"github.com/cloudevents/sdk-go/pkg/cloudevents"
)
should be replaced with
import (
cloudevents "github.com/cloudevents/sdk-go/v2" // make sure to use v2 cloudevents here
)
Considering you have imported the updated go-utils and CloudEvents like this
import (
"context"
"errors"
"fmt"
"log"
"os"
cloudevents "github.com/cloudevents/sdk-go/v2" // make sure to use v2 cloudevents here
keptnv2 "github.com/keptn/go-utils/pkg/lib/v0_2_0"
)
// ServiceName specifies the current services name (e.g., used as source when sending CloudEvents)
const ServiceName = "keptn-service-template-go"
a series of constants, functions, and structs will be available for processing Keptn CloudEvents, which is demonstrated by the following example:
func parseKeptnCloudEventPayload(event cloudevents.Event, data interface{}) error {
err := event.DataAs(data)
if err != nil {
log.Fatalf("Got Data Error: %s", err.Error())
return err
}
return nil
}
func processKeptnCloudEvent(ctx context.Context, event cloudevents.Event) error {
switch event.Type() {
// sh.keptn.event.get-sli
case keptnv2.GetTriggeredEventType(keptnv2.GetSLITaskName): // sh.keptn.event.get-sli.triggered
log.Printf("Processing Get-SLI.Triggered Event")
eventData := &keptnv2.GetSLITriggeredEventData{} // Data Structure for Get-SLI Triggered Event
parseKeptnCloudEventPayload(event, eventData)
return HandleGetSliTriggeredEvent(myKeptn, event, eventData)
// sh.keptn.event.deployment
case keptnv2.GetTriggeredEventType(keptnv2.DeploymentTaskName): // sh.keptn.event.deployment.triggered
log.Printf("Processing Deployment.Triggered Event")
eventData := &keptnv2.DeploymentTriggeredEventData{}
parseKeptnCloudEventPayload(event, eventData)
return HandleDeploymentTriggeredEvent(myKeptn, event, eventData)
}
return nil
}
func HandleGetSliTriggeredEvent(myKeptn *keptnv2.Keptn, incomingEvent cloudevents.Event, data *keptnv2.GetSLITriggeredEventData) error {
log.Printf("Handling get-sli.triggered Event: %s", incomingEvent.Context.GetID())
return nil
}
func HandleDeploymentTriggeredEvent(myKeptn *keptnv2.Keptn, incomingEvent cloudevents.Event, data *keptnv2.DeploymentTriggeredEventData) error {
log.Printf("Handling deployment.triggered Event: %s", incomingEvent.Context.GetID())
return nil
}
Note: The full source code of those examples is available in our keptn-service-template-go.
While in keptn/go-utils 0.7.x you had to take care of sending CloudEvents in the correct format, helper functions in keptn/go-utils v0.8.0 hide this complexity now.
For instance, sending a deployment-finished event in 0.7.x looked like this:
source, _ := url.Parse("helm-service")
contentType := "application/json"
var deploymentStrategyOldIdentifier string
if deploymentStrategy == keptnevents.Duplicate {
deploymentStrategyOldIdentifier = "blue_green_service"
} else {
deploymentStrategyOldIdentifier = "direct"
}
depFinishedEvent := keptnevents.DeploymentFinishedEventData{
Project: keptnHandler.KeptnBase.Project,
Stage: keptnHandler.KeptnBase.Stage,
Service: keptnHandler.KeptnBase.Service,
TestStrategy: testStrategy,
DeploymentStrategy: deploymentStrategyOldIdentifier,
Image: image,
Tag: tag,
Labels: labels,
DeploymentURILocal: [],
DeploymentURIPublic: []
}
event := cloudevents.Event{
Context: cloudevents.EventContextV02{
ID: uuid.New().String(),
Time: &types.Timestamp{Time: time.Now()},
Type: keptnevents.DeploymentFinishedEventType,
Source: types.URLRef{URL: *source},
ContentType: &contentType,
Extensions: map[string]interface{}{"shkeptncontext": keptnHandler.KeptnContext},
}.AsV02(),
Data: depFinishedEvent,
}
err := keptnHandler.SendCloudEvent(event)
if err != nil {
errMsg := fmt.Sprintf("Failed to send task finished CloudEvent (%s), aborting...", err.Error())
log.Println(errMsg)
}
With 0.8.x it looks like this:
ServiceName := "helm-service"
deploymentFinishedEventData := &keptnv2.DeploymentFinishedData{
DeploymentURIsLocal: ["http://a.b.c.d/foobar"],
}
_, err = myKeptn.SendTaskFinishedEvent(deploymentFinishedEventData, ServiceName)
if err != nil {
errMsg := fmt.Sprintf("Failed to send task finished CloudEvent (%s), aborting...", err.Error())
log.Println(errMsg)
}
Processing Keptn CloudEvents requires sending a .started
and .finished
CloudEvent with triggeredid
set to the original event id.
Continuing on the previous example, if you were to implement the HandleGetSliTriggeredEvent
, you are required to send a get-sli.started
event when you start, and a get-sli.finished
event when you have finished handling (and optionally, there is also a get-sli.status.changed
event, if you need/want it).
The following is a shortened example for handling an sh.keptn.event.action.triggered
event:
// HandleActionTriggeredEvent handles action.triggered events
// TODO: add in your handler code
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" {
// -----------------------------------------------------
// 1. Send Action.Started Cloud-Event
// -----------------------------------------------------
myKeptn.SendTaskStartedEvent(data, ServiceName)
// -----------------------------------------------------
// 2. Implement your remediation action here
// -----------------------------------------------------
time.Sleep(5 * time.Second) // Example: Wait 5 seconds. Maybe the problem fixes itself.
// -----------------------------------------------------
// 3. Send Action.Finished Cloud-Event
// -----------------------------------------------------
myKeptn.SendTaskFinishedEvent(&keptnv2.EventData{
Status: keptnv2.StatusSucceeded, // alternative: keptnv2.StatusErrored
Result: keptnv2.ResultPass, // alternative: keptnv2.ResultFailed
Message: "Successfully slept!",
}, ServiceName)
} else {
log.Printf("Retrieved unknown action %s, skipping...", data.Action.Action)
return nil
}
return nil
}
The following is a more comprehensive example for an SLI provider that provides dummy values:
// HandleGetSliTriggeredEvent handles get-sli.triggered events if SLIProvider == keptn-service-template-go
// This function acts as an example showing how to handle get-sli events by sending .started and .finished events
// TODO: adapt handler code to your needs
func HandleGetSliTriggeredEvent(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 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 to be send when the task is started
_, err := myKeptn.SendTaskStartedEvent(data, ServiceName)
if err != nil {
errMsg := fmt.Sprintf("Failed to send task started CloudEvent (%s), aborting...", err.Error())
log.Println(errMsg)
return err
}
// 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"]
// 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)
// FYI you do not need to "fail" if sli.yaml is missing, you can also assume smart defaults like we do
// in keptn-contrib/dynatrace-service and keptn-contrib/prometheus-service
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
_, err = myKeptn.SendTaskFinishedEvent(&keptnv2.EventData{
Status: keptnv2.StatusErrored,
Result: keptnv2.ResultFailed,
}, ServiceName)
return err
}
fmt.Println(sliConfigFileContent)
// 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 := data.GetSLI.Indicators
sliResults := []*keptnv2.SLIResult{}
for _, indicatorName := range indicators {
sliResult := &keptnv2.SLIResult{
Metric: indicatorName,
Value: 123.4, // ToDo: Fetch the values from your monitoring tool here
}
sliResults = append(sliResults, sliResult)
}
// 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{
Status: keptnv2.StatusSucceeded,
Result: keptnv2.ResultPass,
},
GetSLI: keptnv2.GetSLIFinished{
IndicatorValues: sliResults,
Start: data.GetSLI.Start,
End: data.GetSLI.End,
},
}
_, err = myKeptn.SendTaskFinishedEvent(getSliFinishedEventData, ServiceName)
if err != nil {
errMsg := fmt.Sprintf("Failed to send task finished CloudEvent (%s), aborting...", err.Error())
log.Println(errMsg)
return err
}
return nil
}
Note: The full source code of those examples is available in our keptn-service-template-go.
Fetching resources using go-utils works as it used to before. What’s new is that you should send a .finished
event with status=error and result=failed in case you require the file to continue:
myKeptn, err := keptnv2.NewKeptn(&event, keptnOptions)
sliFile := "keptn-service-template-go/sli.yaml"
sliConfigFileContent, err := myKeptn.GetKeptnResource(sliFile)
// FYI you do not need to "fail" if sli.yaml is missing, you can also assume smart defaults like we do
// in keptn-contrib/dynatrace-service and keptn-contrib/prometheus-service
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
_, err = myKeptn.SendTaskFinishedEvent(&keptnv2.EventData{
Status: keptnv2.StatusErrored,
Result: keptnv2.ResultFailed,
}, ServiceName)
return err
}
You can safely remove any occurrence of EventBroker (envConfig
and keptnOptions
).
type envConfig struct {
// Port on which to listen for cloudevents
Port int `envconfig:"RCV_PORT" default:"8080"`
// Path to which cloudevents are sent
Path string `envconfig:"RCV_PATH" default:"/"`
// Whether we are running locally (e.g., for testing) or on production
Env string `envconfig:"ENV" default:"local"`
// URL of the Keptn configuration service (this is where we can fetch files from the config repo)
ConfigurationServiceUrl string `envconfig:"CONFIGURATION_SERVICE" default:""`
}
...
keptnOptions.ConfigurationServiceURL = env.ConfigurationServiceUrl
Make sure to also remove the environment variable from deploy/service.yaml, e.g.,
env:
- name: EVENTBROKER
value: 'http://event-broker.keptn.svc.cluster.local/keptn'
- name: CONFIGURATION_SERVICE
value: 'http://configuration-service.keptn.svc.cluster.local:8080'
should become
env:
- name: CONFIGURATION_SERVICE
value: 'http://configuration-service.keptn.svc.cluster.local:8080'
The keptn/distributor connects a Keptn-microservice with our message-queue NATS (for external services this is handled via the Keptn API).
For 0.8.0, most notably we have introduced the following changes:
keptn/distributor:0.8.0
, e.g.: https://github.com/keptn-contrib/prometheus-service/blob/2ab67e937a0d2663f5fc9dae43f64293d2fbb932/deploy/service.yaml#L224-L225sh.keptn.events.
to sh.keptn.event.
) - make sure to subscribe to the correct types (e.g., all types using PUBSUB_TOPIC="sh.keptn.>"
)You can also just copy the following code snippet into your Kubernetes manifest to use the distributor:
...
- name: distributor
image: keptn/distributor:0.8.0
livenessProbe:
httpGet:
path: /health
port: 10999
initialDelaySeconds: 5
periodSeconds: 5
imagePullPolicy: Always
ports:
- containerPort: 8080
resources:
requests:
memory: "16Mi"
cpu: "25m"
limits:
memory: "32Mi"
cpu: "50m"
env:
- name: PUBSUB_URL
value: 'nats://keptn-nats-cluster'
- name: PUBSUB_TOPIC
value: 'sh.keptn.>'
- name: PUBSUB_RECIPIENT
value: '127.0.0.1'
Note: Depending on the complexity of your service it might be easier to start over from https://github.com/keptn-sandbox/keptn-service-template-go and just modify the relevant event handlers.
Heavy refactoring was done in main.go. If you can, copy the content from https://github.com/keptn-sandbox/keptn-service-template-go. If not, here is a short guide on what has changed:
envConfig
and in keptnOptions
// ServiceName specifies the current services name (e.g., used as source when sending CloudEvents)
const ServiceName = "keptn-service-template-go" // replace with your service name
/**
* Parses a Keptn Cloud Event payload (data attribute)
*/
func parseKeptnCloudEventPayload(event cloudevents.Event, data interface{}) error {
err := event.DataAs(data)
if err != nil {
log.Fatalf("Got Data Error: %s", err.Error())
return err
}
return nil
}
import (
keptnv2 "github.com/keptn/go-utils/pkg/lib/v0_2_0"
)
myKeptn, err := keptnv2.NewKeptn(&event, keptnOptions)
switch event.Type() {
// -------------------------------------------------------
case keptnv2.GetTriggeredEventType(keptnv2.TestTaskName): // sh.keptn.event.test.triggered
log.Printf("Processing Test.Triggered Event")
eventData := &keptnv2.TestTriggeredEventData{}
parseKeptnCloudEventPayload(event, eventData)
return HandleTestsTriggered(myKeptn, event, eventData)
...
}
func _main(args []string, env envConfig) int {
// configure keptn options
if env.Env == "local" {
log.Println("env=local: Running with local filesystem to fetch resources")
keptnOptions.UseLocalFileSystem = true
}
keptnOptions.ConfigurationServiceURL = env.ConfigurationServiceUrl
ctx := context.Background()
ctx = cloudevents.WithEncodingStructured(ctx)
// configure http server to receive cloudevents
p, err := cloudevents.NewHTTP(cloudevents.WithPath(env.Path), cloudevents.WithPort(env.Port))
if err != nil {
log.Fatalf("failed to create client, %v", err)
}
c, err := cloudevents.NewClient(p)
if err != nil {
log.Fatalf("failed to create client, %v", err)
}
log.Printf("Starting receiver")
log.Fatal(c.StartReceiver(ctx, processKeptnCloudEvent))
return 0
}
We have introduced a new helper function to log CloudEvents to console:
// 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
}
Other than that, please follow the changes detailed above for Keptn CloudEvents, go-utils
and distributor
.
The most important changes when migrating an SLI provider from 0.7.x to 0.8.x are:
sh.keptn.event.get-sli.started
and sh.keptn.event.get-sli.finished
event (e.g., using myKeptn.SendTaskStartedEvent
) - see keptn-service-template-go/eventhandlers.go)Please refer to the changes shown above regarding go-utils.
Prior to 0.8.x, action providers already needed to send sh.keptn.event.action.started
and sh.keptn.event.action.finished
events.
We recommend upgrading to the latest version of keptn/go-utils to be compatible with Keptn CloudEvents and its structures. Please refer to the changes shown above regarding go-utils.
In case your integration has been using the CLI or the API, please refer to the official release notes for more details.
github.com/cloudevents/sdk-go/v2