Skip to content

Commit

Permalink
Merge pull request #43 from keptn-sandbox/feature/42/sendFinishedEvent
Browse files Browse the repository at this point in the history
Allow sending a generic finished event
  • Loading branch information
christian-kreuzberger-dtx authored Oct 29, 2021
2 parents 18a8377 + 5374a45 commit 60e4f86
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 10 deletions.
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ You can find out the latest release on the [GitHub releases](https://github.com/
| 3.5 | 0.7.x | Keptn API Token now configurable via Jenkins Credentials |
| 4.0 | 0.8.0 | Now supporting Keptn 0.8.0 |
| 4.1 | 0.8.x, 0.9.x | Supporting Keptn 0.9.x, bug fixes |
| 5.0 | 0.9.x, 0.10.0 | Supporting Keptn 0.10.0, bug fixes, Cleanups |

Please make sure to always specify a version when including the library in your Jenkinsfile, e.g.
```groovy
@Library('keptn-library@4.1')
@Library('keptn-library@5.0')
import sh.keptn.Keptn
def keptn = new sh.keptn.Keptn()
```
Expand Down Expand Up @@ -77,7 +78,7 @@ The KEPTN_BRIDGE is the link to your keptn bridge so that the Library can genera
Once you have everything configured use it in your Jenkins Pipeline like this

```groovy
@Library('keptn-library@4.1')
@Library('keptn-library@5.0')
import sh.keptn.Keptn
def keptn = new sh.keptn.Keptn()
Expand Down Expand Up @@ -120,10 +121,18 @@ def keptnContext = keptn.sendStartEvaluationEvent starttime:"2019-06-07T07:00:00
// Example #4: Mark a starting timestamp before executing your tests
// Following example will fill starttime with the time when you called markEvaluationStartTime and as end is empty will default to Now()
keptn.markEvaluationStartTime()
... here is where you would execute any existing tests
// ...
// ^^^ here is where you would execute any existing tests
// Keptn 0.7.x and prior: send start evaluation event to Keptn
def keptnContext = keptn.sendStartEvaluationEvent starttime:"", endtime:""
echo "Open Keptns Bridge: ${keptn_bridge}/trace/${keptnContext}"
// Keptn 0.8.x and newer: Send a test.finished event
def keptnContext = keptn.sendFinishedEvent eventType: "test", keptnContext: "${params.shkeptncontext}", triggeredId: "${params.triggeredid}", result:"pass", status:"succeeded"
echo "Open Keptns Bridge: ${keptn_bridge}/trace/${keptnContext}"
// Performance Testing as a Service Use Case
// -------------------------------------------
Expand All @@ -132,15 +141,16 @@ echo "Open Keptns Bridge: ${keptn_bridge}/trace/${keptnContext}"
def keptnContext = keptn.sendDeploymentFinishedEvent testStrategy:"performance", deploymentURI:"http://yourapp.yourdomain.local"
echo "Open Keptns Bridge: ${keptn_bridge}/trace/${keptnContext}"
// Progressive Delivery Use Case
// -------------------------------------------
// Progressive Delivery Use Case (Keptn 0.7.x and prior)
// -------------------------------------------
// If you want Keptn to deploy, test and evaluate then we can simply inform Keptn about a new configuration (=container image) you have
// Typically you would use your Jenkins to build and push a container to your container registry. After that you notify Keptn about it
def keptnContext = keptn.sendDeliveryTriggeredEvent testStrategy:"${params.TestStrategy}", deploymentURI:"${params.DeploymentURI}"
String keptn_bridge = env.KEPTN_BRIDGE
echo "Open Keptns Bridge: ${keptn_bridge}/trace/${keptnContext}"
// --------------------------------------------
// Waiting for Quality Gate Result
// --------------------------------------------
def result = keptn.waitForEvaluationDoneEvent setBuildResult:true, waitTime:waitTime
Expand Down
108 changes: 103 additions & 5 deletions src/sh/keptn/Keptn.groovy
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package sh.keptn

import groovy.transform.Field
import java.time.temporal.ChronoUnit
import org.jenkinsci.plugins.plaincredentials.StringCredentials
import com.cloudbees.plugins.credentials.CredentialsProvider
import com.cloudbees.plugins.credentials.domains.DomainRequirement

@groovy.transform.Field
def KEPTN_SPEC_VERSION = "0.2.3"

@groovy.transform.Field
def KEPTN_EVENT_SOURCE = "jenkins-library"

/**
* Downloads a file from the given url and stores it in the local workspace
*/
Expand Down Expand Up @@ -209,7 +216,7 @@ def keptnInit(Map args) {
| "type": "${monitoring}"
|},
|"datacontenttype": "application/json",
| "source": "Jenkins",
| "source": "${KEPTN_EVENT_SOURCE}",
| "specversion": "1.0",
| "type": "sh.keptn.event.monitoring.configure"
|}
Expand Down Expand Up @@ -606,9 +613,10 @@ def sendStartEvaluationEvent(Map args) {
| "tag" : "${tag}",
| },
| "datacontenttype": "application/json",
| "source": "Jenkins",
| "source": "${KEPTN_EVENT_SOURCE}",
| "specversion": "1.0",
| "type": "sh.keptn.event.${stage}.evaluation.triggered"
| "type": "sh.keptn.event.${stage}.evaluation.triggered",
| "shkeptnspecversion": "${KEPTN_SPEC_VERSION}"
|}
""".stripMargin()

Expand Down Expand Up @@ -738,6 +746,94 @@ def waitForEvaluationDoneEvent(Map args) {
return score
}

/**
* sendFinishedEvent(KEPTN_INIT_PARAMS, keptnContext, eventType, triggeredId, [result, status, message, labels])
* Will send a finished event of type eventType (e.g., eventType.finished)
* will stores the API result in keptn.context.json
*/
def sendFinishedEvent(Map args) {
// load KEPTN_INIT_PARAMS such as project, service, stage, API endpoint, API token
def keptnInit = keptnLoadFromInit(args)

String keptn_endpoint = keptnInit['keptn_endpoint']
String keptn_api_token = keptnInit['keptn_api_token']
String project = keptnInit['project']
String stage = keptnInit['stage']
String service = keptnInit['service']

// load labels from args (if set)
def labels = args.containsKey('labels') ? args.labels : [:]

// verify keptnContext is set in args
if (!args.containsKey('keptnContext')) {
error("sendFinishedEvent requires keptnContext to be passed")
return ""
}

// verify eventType is set in args
if (!args.containsKey('eventType')) {
error("sendFinishedEvent requires eventType to be passed")
return ""
}

// verify triggeredID is set in args
if (!args.containsKey('triggeredId')) {
error("sendFinishedEvent requires triggeredId to be passed")
return ""
}

String KEPTN_CONTEXT = args.keptnContext
String eventType = args.eventType
String triggeredId = args.triggeredId

String result = args.containsKey('result') ? args.result : "pass"
String status = args.containsKey('status') ? args.status : "succeeded"
String message = args.containsKey('message') ? args.message : ""

echo "Sending a ${eventType}.finished event to Keptn for ${project}.${stage}.${service} (status=${status},result=${result})"

def requestBody = """{
| "data": {
| "project": "${project}",
| "stage": "${stage}",
| "service": "${service}",
| "labels": {
| "jobname" : "${JOB_NAME}",
| "buildNumber": "${BUILD_NUMBER}",
| "joburl" : "${BUILD_URL}"
| },
| "result": "${result}",
| "status": "${status}",
| "message": "${message}"
| },
| "datacontenttype": "application/json",
| "source": "${KEPTN_EVENT_SOURCE}",
| "specversion": "1.0",
| "shkeptncontext": "${KEPTN_CONTEXT}",
| "shkeptnspecversion": "${KEPTN_SPEC_VERSION}",
| "triggeredid": "${triggeredId}",
| "type": "sh.keptn.event.${eventType}.finished"
|}
""".stripMargin()

// lets add our custom labels
requestBody = addCustomLabels(requestBody, labels)

def response = httpRequest contentType: 'APPLICATION_JSON',
customHeaders: [[maskValue: true, name: 'x-token', value: "${keptn_api_token}"]],
httpMode: 'POST',
requestBody: requestBody,
responseHandle: 'STRING',
url: "${keptn_endpoint}/v1/event",
validResponseCodes: "100:404",
ignoreSslErrors: true

// write response to keptn.context.json & add to artifacts
def keptnContext = writeKeptnContextFiles(response)

return keptnContext
}

/**
* sendDeploymentFinishedEvent(project, stage, service, deploymentURI, testStrategy [labels, keptn_endpoint, keptn_api_token])
* Example: sendDeploymentFinishedEvent deploymentURI:"http://mysampleapp.mydomain.local" testStrategy:"performance"
Expand Down Expand Up @@ -787,7 +883,8 @@ def sendDeploymentFinishedEvent(Map args) {
| "datacontenttype": "application/json",
| "source": "jenkins-library",
| "specversion": "1.0",
| "type": "sh.keptn.event.deployment.finished"
| "type": "sh.keptn.event.deployment.finished",
| "shkeptnspecversion": "${KEPTN_SPEC_VERSION}"
|}
""".stripMargin()

Expand Down Expand Up @@ -860,7 +957,8 @@ def sendDeploymentTriggeredEvent(Map args) {
| "datacontenttype": "application/json",
| "source": "jenkins-library",
| "specversion": "1.0",
| "type": "sh.keptn.event.deployment.triggered"
| "type": "sh.keptn.event.deployment.triggered",
| "shkeptnspecversion": "${KEPTN_SPEC_VERSION}"
|}
""".stripMargin()

Expand Down

0 comments on commit 60e4f86

Please sign in to comment.