Code Monkey home page Code Monkey logo

keptn-jenkins-library's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

keptn-jenkins-library's Issues

sendDeliveryTriggeredEvent does not trigger any delivery

With keptn-shared-library @ v5.0, the sendDeliveryTriggeredEvent function is not working as documented.

We end up not getting any sequence in Keptn:
image

Pipeline:

@Library('[email protected]')_
def keptn = new sh.keptn.Keptn()


node('jenkins-slave') {

    def commit_id

    def project = "nodejs-example"
    def service = "hello-service"
    def firststage = "dev"

    stage('Preparation') {
        checkout scm
        sh "git rev-parse --short HEAD > .git/commit-id"                        
        commit_id = readFile('.git/commit-id').trim()
    }

    stage('Docker build/push') {
      docker.withRegistry('https://index.docker.io/v1/', 'dockerhub') {
        def app = docker.build("christiankreuzbergerdtx/docker-nodejs-demo:${commit_id}", '.').push()
      }
    }

    stage('Initialize Keptn') {
        // Initialize the Keptn Project - ensures the Keptn Project is created with the passed shipyard
        keptn.keptnInit project:"${project}", service:"${service}", stage:"${firststage}", monitoring: "dynatrace", shipyard: ".keptn/shipyard.yaml"

        // Upload quality gate files
        //keptn.keptnAddResources('keptn/dynatrace/dynatrace.conf.yaml','dynatrace/dynatrace.conf.yaml')
        // Upload SLI and SLO files
        keptn.keptnAddResources('.keptn/dynatrace/sli.yaml','dynatrace/sli.yaml')
        keptn.keptnAddResources('.keptn/slo.yaml','slo.yaml')

        // Create Helm Chart .tgz
        sh 'tar cfvz .keptn/helm/hello-service.tgz .keptn/helm/hello-service'

        // Add Helm Chart for hello-service
        keptn.keptnAddResources('.keptn/helm/hello-service.tgz', 'helm/hello-service.tgz')
    }

    stage('Trigger Delivery') {
        def keptnContext = keptn.sendDeliveryTriggeredEvent image:"christiankreuzbergerdtx/docker-nodejs-demo:${commit_id}"
        String keptn_bridge = env.KEPTN_BRIDGE
        echo "Open Keptns Bridge: ${keptn_bridge}/trace/${keptnContext}"
    }

    stage('Wait for Result') {
        echo "Waiting until Keptn is done and returns the results"
        def result = keptn.waitForEvaluationDoneEvent setBuildResult:true, waitTime:5
        echo "${result}"
    }
}

shipyard.yaml

apiVersion: "spec.keptn.sh/0.2.0"
kind: "Shipyard"
metadata:
  name: "shipyard-sockshop"
spec:
  stages:
    - name: "dev"
      sequences:
        - name: "delivery"
          tasks:
            - name: "deployment"
              properties:
                deploymentstrategy: "direct"
            - name: "test"
              properties:
                teststrategy: "functional"
            - name: "evaluation"

    - name: "hardening"
      triggeredOn:
        - event: "dev.delivery.finished"
      sequences:
        - name: "delivery"
          tasks:
            - name: "deployment"
              properties:
                deploymentstrategy: "blue_green"
            - name: "test"
              properties:
                teststrategy: "performance"
            - name: "evaluation"

    - name: "production"
      sequences:
        - name: "delivery"
          triggeredOn:
            - event: "hardening.delivery.finished"
          tasks:
            - name: "approval"
            - name: "deployment"
              properties:
                deploymentstrategy: "blue_green"
            - name: "release"

Race condition when creating service too soon after create project

We have seen this behavior with some of our users that the "create service" failed with a "project not found" error becuase the previous "create project" hasnt yet fully complete

This is part of the keptn.init function where project and service are created within a very short timeframe
I suggest we do some polling and retries first to avoid this issue

Provide a way to allow configuration of global environment variables via another source

Currently the following global variables need to be set in jenkins:

  • KEPTN_API_TOKEN
  • KEPTN_BRIDGE
  • KEPTN_ENDPOINT

The problem with the global approach is that it bleeds into all builds on the jenkins instance.

For the KEPTN_ENDPOINT and KEPTN_BRIDGE the value could be directly set in the keptnInit method.

keptn.keptnInit ... keptn_endpoint:"https://keptn.dev/api", keptn_bridge:"https://keptn.dev/bridge ..."

KEPTN_API_TOKEN should be set in a secure way, maybe via jenkins credentials.

Jenkins job fails even if SLO Evalution passes [email protected]

The Jenkins job fails even if the SLO Evaluation passes.
This happens when keptn.waitForEvaluationDoneEvent is called with setBuildResult:true,
line 660: error("Keptn Score: ${score}, Result: ${result}")
this causes the the job to fail with call to error

keptn.waitForEvaluationDoneEvent returns the score and not the evaluation Result as pass/fail and therefore I cannot set the build result manually as a workaround , can we enhance this to return the Result and the score?

Tested with Jenkins ver. 2.121.3
Example from log:
Archived Keptn Evaluation Done Result details in keptn.evaluationresult.9ae556dd-3295-4e6a-b47c-63a8b83af5e8.json [Pipeline] readJSON [Pipeline] echo Retrieved Score: 91.666664, Result: pass [Pipeline] catchError [Pipeline] { [Pipeline] error [Pipeline] } ERROR: Keptn Score: 91.666664, Result: pass [Pipeline] // catchError [Pipeline] echo keptn result : 91.666664 [Pipeline] step Processing provided DSL script Existing user content: GeneratedUserContent{path='performance-test/cadev-vfull/data/error/errorList.csv'} [Pipeline] } [Pipeline] // stage [Pipeline] } [Pipeline] // node [Pipeline] End of Pipeline Finished: FAILURE

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • build(deps): update dependency com.lesfurets:jenkins-pipeline-unit to v1.20
  • build(deps): update dependency gradle to v8
  • build(deps): update dependency org.jenkins-ci.plugins:credentials to v1307
  • build(deps): update dependency org.jenkins-ci.plugins:plain-credentials to v179
  • build(deps): update dependency org.kohsuke.stapler:stapler to v1870
  • πŸ” Create all rate-limited PRs at once πŸ”

Edited/Blocked

These updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/pre-release.yml
  • actions/checkout v3.0.0
  • keptn/gh-automation v1.5.2
  • actions/checkout v3.0.0
.github/workflows/release.yml
  • actions/checkout v3.0.0
  • keptn/gh-automation v1.5.2
  • actions/checkout v3.0.0
.github/workflows/validate-semantic-pr.yml
  • keptn/gh-automation v1.5.2
gradle
settings.gradle
build.gradle
  • org.codehaus.groovy:groovy-all 3.0.8
  • org.apache.ivy:ivy 2.5.0
  • org.jenkins-ci.main:jenkins-core 2.332
  • org.kohsuke.stapler:stapler 1.263
  • org.jenkins-ci.plugins.workflow:workflow-step-api 2.24
  • org.jenkins-ci.plugins:pipeline-utility-steps 2.12.0
  • org.jenkins-ci.plugins:credentials 2.6.2
  • org.jenkins-ci.plugins:plain-credentials 1.8
  • com.lesfurets:jenkins-pipeline-unit 1.13
  • org.junit.jupiter:junit-jupiter-api 5.8.2
  • org.junit.jupiter:junit-jupiter-engine 5.8.2
gradle-wrapper
gradle/wrapper/gradle-wrapper.properties
  • gradle 7.3.3

  • Check this box to trigger a request for Renovate to run again on this repository

RFE: waitForEvaluationDoneEvent variable sleep time

Problem statement.
The waitForEvaluationDoneEvent function has a hard coded sleep time of 10 seconds between retries. Users would like to make this duration configurable. The current value of 10 seconds causes unnecessary outputs in the console logs and excessive API calls.

Describe the solution you'd like
Modify the sleep duration from 10 seconds to a variable that is set as an argument. If the argument is missing or equal to zero, then default to 10 seconds.

Describe alternatives you've considered
N/A

Additional context
N/A

Refactor check if a service exists to a basic GET request check without the stage

Right now we need to know project, service and stage in order to check whether a service exists:

def keptnProjectServiceExists(Map args) {
def keptnInit = keptnLoadFromInit(args)
def getProjectServiceResponse = httpRequest customHeaders: [[maskValue: true, name: 'x-token', value: "${keptnInit['keptn_api_token']}"]],
httpMode: 'GET',
responseHandle: 'STRING',
url: "${keptnInit['keptn_endpoint']}/controlPlane/v1/project/${keptnInit['project']}/stage/${keptnInit['stage']}/service/${keptnInit['service']}",
validResponseCodes: "100:404",
ignoreSslErrors: true
echo "Response from get project service: " + getProjectServiceResponse.content
return (getProjectServiceResponse.status == 200)
}

This is a known limitation in the Keptn API.

Definition of Done

  • Use a basic GET Endpoint without the stagename to check whether a service exists

Depends on keptn/TBD

Write a helper function to send a cloudevent

To avoid code duplication, a helper function that sends a CloudEvent to Keptn would be nice.

For instance, this is the code that is duplicated right now:

    def requestBody = """{
        |  "data": {
        |    "project": "${project}",
        |    "stage": "${stage}",
        |    "service": "${service}",
        |    "labels": {
        |      "buildId" : "${tag}",
        |      "jobname" : "${JOB_NAME}",
        |      "buildNumber": "${BUILD_NUMBER}",
        |      "joburl" : "${BUILD_URL}"
        |    },
        |    "deployment": {
        |      "deploymentstrategy": "direct",
        |      "deploymentURIsPublic": [
        |                "${deploymentURI}"
        |             ]
        |    }
        |  },
        |  "datacontenttype": "application/json",
        |  "source": "jenkins-library",
        |  "specversion": "1.0",
        |  "type": "sh.keptn.event.deployment.finished",
        |  "shkeptnspecversion": "${KEPTN_SPEC_VERSION}"
        |}
    """.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)

Optimizations

  • Adding project, service, stage, labels, specversion, shkeptnspecversion, source, datacontenttype, ... could be moved into the helper function
  • sending the http request could be moved into the helper function

Verbosity of the Library Log entries in Jenkins console log.

Hi,
We have multiple services in a keptn project and we find that there is a lot of log output in the Jenkins console log coming from the Jenkins Keptn Library. The root cause of this is some of the API calls to keptn that are using the Jenkins HttpRequest plugin are verbose so the response of the request is shown in the log.
eg:
The Get project and get stage functions in the library. Shows the result in the console:
/api/configuration-service/v1/project/my-project : shows the json Response from get project in the log and
/api/configuration-service/v1/project/v1-application-market/stage/mystage : shows the Json response in the log.
This results in 100s of lines in the log in our case.
Please add the property quiet: true (or make it optional) to the httpRequest call, so I can control the verbosity of the output in the log.https://www.jenkins.io/doc/pipeline/steps/http_request/
Thanks,
Leon

RFE: keptn.sendFinishedEvent need to take an additional input paramter for a type specific payload

Problem statement.
currently the keptn.sendFinishedEvent, does not take any input parameters for an event specific payload. If you want to finish a task and need some additional data for the succeeding task this is currently not possible.

e.g - Jenkins is doing some tests after a build and I'd like to inform keptn, that my test has finished through a keptn.sendFinishedEvent, I need a start and stop timestamp of my test in order to properly trigger my quality gate.

Describe the solution you'd like
The function keptn.sendFinishedEvent should take an optional array "eventTypePayload" which is passed to keptn when executing keptn.sendFnishedEvent

Additional context
Already filed a PR to solve this:
#105

best
RenΓ©

sendStartEvaluationEvent evaluates 0 as a negative number, incorrectly

sendStartEvaluationEvent evaluates 0 as a negative number

Environment

  • keptn-jenkins-library version: 6.1.0
  • Keptn Version (keptn version): 16.X (although it shouldn't be relevant)
  • Kubernetes Cloud Provider (e.g., GKE, AKS): N/A
  • Kubernetes version (kubectl version): N/A
  • Client OS (e.g., Linux, macOS, Windows): N/A
  • Client Browser: N/A

Affected Component
keptn-jenkins-library only

To Reproduce
Within Jenkins pipeline, call sendStartEvaluationEvent and pass argument(s) startime or endtime with a value of 0.

def keptnContext = keptn.sendStartEvaluationEvent starttime:"600", endtime:"0"

Results in a failure and the output of:

echo "No negative numbers allowed for endtime!"

The issue is with these code blocks:

591: if (seconds > 0) {
601: if (seconds > 0) {

The operator should be seconds >= 0 so that it includes 0, as 0 is neither positive nor negative, and a valid parameter for this function.

Expected behavior
Treat 0 as a valid parameter for this function.

Current behavior
Does not treat 0 as a valid parameter for this function.

Screenshots
N/A

Additional context
N/A

Change precedence of source for keptn api token

Currently for retrieving the keptn api token first the jenkins credential store is checked and then the environment. Jenkins uses a whitelist approach (script security plugin) for executing scripts, each method call, etc. is checked against a list of approved operations, if the operation is not approved the script execution is killed.

The method for retrieving the keptn api token from the credential store is not approved by default and an admin would need to approve it. If the keptn api token from the environment should be used, the credential store method would still need to be approved, even if the keptn api token is not in the credential store. Switching the order to first checking the environment and then the credential store improves the usability.

RFE: Separate `keptn configure monitoring` from `keptnInit` (Breaking change)

Problem statement.
As a user I would like to create a project, add some files (slo, sli, additional configuration), and then configure monitoring afterwards.

E.g.:

    stage('Initialize Keptn Project') {
        // Initialize the Keptn Project - ensures the Keptn Project is created with the passed shipyard
        keptn.keptnInit project:"${project}", service:"${service}", stage:"${firststage}", shipyard: ".keptn/shipyard.yaml"
    }

    stage('Add files to Keptn Project') {
        // Upload quality gate files
        keptn.keptnAddResources('keptn/dynatrace/dynatrace.conf.yaml','dynatrace/dynatrace.conf.yaml')
        // Upload SLI and SLO files
        keptn.keptnAddResources('.keptn/dynatrace/sli.yaml','dynatrace/sli.yaml')
        keptn.keptnAddResources('.keptn/slo.yaml','slo.yaml')
    }

    stage('Configure monitoring solution') {
        keptn.keptnConfigureMonitoring('dynatrace')
    }

Current functionality

At the moment this functionaltiy is hidden within the keptnInit function, e.g.:

        keptn.keptnInit project:"${project}", service:"${service}", stage:"${firststage}", monitoring: "dynatrace", shipyard: ".keptn/shipyard.yaml"

However, depending on the monitoring solution this might fail, because additional files are required (dynatrace.conf, sli.yaml, slo.yaml).

Definition of Done

  • New function keptnConfigureMonitoring implemented and documented in README
  • keptnInit parameter monitoring removed (BREAKING CHANGE)

Remove outdated functions (e.g., Keptn 0.5/0.6 related functions)

There are some functions that are most likely no longer needed or need to be renamed accordingly:

  • sendDeploymentFinishedEvent (could probably be solved using #42):
    /**
    * sendDeploymentFinishedEvent(project, stage, service, deploymentURI, testStrategy [labels, keptn_endpoint, keptn_api_token])
    * Example: sendDeploymentFinishedEvent deploymentURI:"http://mysampleapp.mydomain.local" testStrategy:"performance"
    * Will trigger a Continuous Performance Evaluation workflow in Keptn where Keptn will
    -> first: trigger a test execution against that URI with the specified testStrategy
    -> second: trigger an SLI/SLO evaluation!
    */
    def sendDeploymentFinishedEvent(Map args) {
    def keptnInit = keptnLoadFromInit(args)
    /* String project, String stage, String service, String deploymentURI, String testStrategy */
    String keptn_endpoint = keptnInit['keptn_endpoint']
    String keptn_api_token = keptnInit['keptn_api_token']
    def labels = args.containsKey('labels') ? args.labels : [:]
    String project = keptnInit['project']
    String stage = keptnInit['stage']
    String service = keptnInit['service']
    String deploymentURI = args.containsKey("deploymentURI") ? args.deploymentURI : ""
    String testStrategy = args.containsKey("testStrategy") ? args.testStrategy : ""
    // Allow image & tag to be passed as parameters - or default to JOB_NAME & BUILD_NUMBER
    String image = args.containsKey("image") ? args.image : "${JOB_NAME}"
    String tag = args.containsKey("tag") ? args.tag : "${BUILD_NUMBER}"
    echo "Sending a Deployment Finished event to Keptn for ${project}.${stage}.${service} on ${deploymentURI} with testStrategy ${testStrategy}"
    def requestBody = """{
    | "data": {
    | "project": "${project}",
    | "stage": "${stage}",
    | "service": "${service}",
    | "labels": {
    | "buildId" : "${tag}",
    | "jobname" : "${JOB_NAME}",
    | "buildNumber": "${BUILD_NUMBER}",
    | "joburl" : "${BUILD_URL}"
    | },
    | "deployment": {
    | "deploymentstrategy": "direct",
    | "deploymentURIsPublic": [
    | "${deploymentURI}"
    | ]
    | }
    | },
    | "datacontenttype": "application/json",
    | "source": "jenkins-library",
    | "specversion": "1.0",
    | "type": "sh.keptn.event.deployment.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
    }
  • sendConfigurationChangedEvent:
    /**
    * sendConfigurationChangedEvent(project, stage, service, image, [labels, keptn_endpoint, keptn_api_token])
    * Example: sendConfigurationChangedEvent image:"docker.io/grabnerandi/simplenodeservice:3.0.0"
    * Will trigger a full delivery workflow in keptn!
    * changed to delivery.triggered for keptn 0.8.0
    */
    def sendConfigurationChangedEvent(Map args) {
    def keptnInit = keptnLoadFromInit(args)
    /* String project, String stage, String service, String image, String tag */
    String keptn_endpoint = keptnInit['keptn_endpoint']
    String keptn_api_token = keptnInit['keptn_api_token']
    def labels = args.containsKey('labels') ? args.labels : [:]
    String project = keptnInit['project']
    String stage = keptnInit['stage']
    String service = keptnInit['service']
    String image = args.containsKey("image") ? args.image : ""
    String tag = args.containsKey("tag") ? args.tag : "${BUILD_NUMBER}"
    echo "Sending a Configuration Change event to Keptn for ${project}.${stage}.${service} for image ${image}"
    def requestBody = """{
    | "data": {
    | "project": "${project}",
    | "service": "${service}",
    | "stage": "${stage}",
    | "configurationChange": {
    | "values": {
    | "image": "${image}"
    | }
    | },
    | "deployment": {
    | "deploymentstrategy": "direct"
    | },
    | "labels": {
    | "buildId" : "${tag}",
    | "jobname" : "${JOB_NAME}",
    | "buildNumber": "${BUILD_NUMBER}",
    | "joburl" : "${BUILD_URL}"
    | }
    | },
    | "datacontenttype": "application/json",
    | "source": "jenkins-library",
    | "specversion": "1.0",
    | "type": "sh.keptn.event.${stage}.delivery.triggered"
    |}
    """.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
    }
  • sendConfigurationTriggered:
    /**
    * sendConfigurationTriggeredEvent(project, stage, service, image, [labels, keptn_endpoint, keptn_api_token])
    * Example: sendConfigurationTriggeredEvent
    * Will trigger a full delivery workflow in keptn!
    * changed to delivery.triggered for keptn 0.8.0
    */
    def sendConfigurationTriggeredEvent(Map args) {
    def keptnInit = keptnLoadFromInit(args)
    /* String project, String stage, String service, String image, String tag */
    String keptn_endpoint = keptnInit['keptn_endpoint']
    String keptn_api_token = keptnInit['keptn_api_token']
    def labels = args.containsKey('labels') ? args.labels : [:]
    String project = keptnInit['project']
    String stage = keptnInit['stage']
    String service = keptnInit['service']
    String image = args.containsKey("image") ? args.image : ""
    String deploymentURI = args.containsKey("deploymentURI") ? args.deploymentURI : ""
    String testStrategy = args.containsKey("testStrategy") ? args.testStrategy : ""
    String tag = args.containsKey("tag") ? args.tag : "${BUILD_NUMBER}"
    echo "Sending a Configuration triggered event to Keptn for ${project}.${stage}.${service}"
    def requestBody = """{
    | "data": {
    | "project": "${project}",
    | "service": "${service}",
    | "stage": "${stage}",
    | "teststrategy": "${testStrategy}",
    | "configurationChange": {
    | "values": {
    | "deploymentURIsPublic": "${deploymentURI}",
    | "teststrategy": "${testStrategy}"
    | }
    | },
    | "deployment": {
    | "deploymentstrategy": "direct",
    | "deploymentURIsPublic": [
    | "${deploymentURI}"
    | ]
    | },
    | "labels": {
    | "buildId" : "${tag}",
    | "jobname" : "${JOB_NAME}",
    | "buildNumber": "${BUILD_NUMBER}",
    | "joburl" : "${BUILD_URL}"
    | }
    | },
    | "datacontenttype": "application/json",
    | "source": "jenkins-library",
    | "specversion": "1.0",
    | "type": "sh.keptn.event.${stage}.delivery.triggered"
    |}
    """.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
    }

Definition of Done

Add Timezone parameter for evaluations

Feature Request

Need to pass in the timezone to allow timezones to match customers configuration with jenkins and keptn.

References

These features need a timezone,

markEvaluationStartTime()
sendStartEvaluationEvent()

If you think about adding a timezone option to the getNow.

def defineTZVariable(timezone) {
    if (timezone == null || timezone == "") {
      // use to set default timezone
      timezone = "UTC"     
    } else {
   	  timezone = timezone
    }
    def zid = ZoneId.of(timezone)
    echo "ZID: ${zid}"
    return zid
}

Then something like this,

def getNow() {
    // get timezone.
    def keptnInit = keptnLoadFromInit(args)
    String timezone = keptnInit['timezone']
    zid = defineTZVariable(timezone)
    // return java.time.LocalDateTime.now() 
    return java.time.Instant.now(zid)
}

You can also see this to use a timezone parameter,

def markEvaluationStartTime(timezone) {
    // get timezone.     
    zid = defineTZVariable(timezone)
    //def startTime = getNow().toString()       
    def LocalDateTime starttimelocal = LocalDateTime.now(zid)       
    // format time
    startTime = timestampFormatter(starttimelocal)

This in turn is basically adding a timezone to the timeformatter.

Thanks,
Jeff

Allow passing custom image and tag for all keptn helper functions

Right now the Jenkins Shared Library is using BUILD_NUMBER & JOB_NAME for image & tag parameter that get passed to the Keptn Cloud Native event.
It should be possible to define your own custom image & tag values that we can pass to a method such as sendStartEvaluationEvent

Here is an example:

keptn.sendStartEvaluationEvent image:"myimage", tag: "mytag"

Custom Labels

I would like to send through custom labels as part of the start evaluation event and this requirement will probably grow as we adopt more use cases.
Specifically, I am using custom labels set at Jenkins job runtime in my SLI tags which the library doesn't cater for at the moment.

README: No surch property: waitTime

In the example within the README,

def result = keptn.waitForEvaluationDoneEvent setBuildResult:true, waitTime:waitTime

we do not specify waitTime, which leads to the error message:

groovy.lang.MissingPropertyException: No such property: waitTime for class: groovy.lang.Binding
	at groovy.lang.Binding.getVariable(Binding.java:63)
	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:271)

Definition of Done

  • Change waitTime to an integer, document that it is wait time in minutes

Add wait-functionality for arbitrary step

For the performance test use case, it would be nice to have a wait step that listens for the completion of the test execution before going directly on to the wait for evaluation step. In a long running test unless you set the wait time to a very high number to avoid timeout the pipeline can fail waiting for the evaluation to complete.

The process should wait to receive a test finished event from keptn before waiting for the eval to complete

Issue with command sendDeliveryTriggeredEvent

While running the keptn.sendDeliveryTriggeredEvent in jenkins pipeline ,
We are getting below error

java.lang.NoSuchMethodError: No such DSL method 'sendDeliveryTriggeredEvent' found among steps [archive, bat, build, catchError, checkout, compareVersions, deleteDir, dir, dockerFingerprintFrom, dockerFingerprintRun, echo, emailext, emailextrecipients, envVarsForTool, error, fileExists, findBuildScans, findFiles, getContext, git, httpRequest, input, isUnix, junit, library, libraryResource, load, mail, milestone, node, nodesByLabel, parallel, powershell, prependToFile, properties,

Can you suggest which plugin is required to run the same command?

Research how to unit-test this shared Library

Currently, the code in this shared library is untested.

I found two resources on how to unit test a Jenkins shared-library, there is probably more available if you dig deeper:

Definition of Done

  • Research and try out how to write Unit Tests for a Jenkins Shared Library
  • Update #48 with this information
  • If possible, create a PR with a simple unit test

Failed to run keptnConfigureMonitoring

From @pcjeffmac (see original issue here: #80 (comment) )

I set my pipeline to use this release,

@Library('[email protected]')_
import sh.keptn.Keptn
def keptn = new sh.keptn.Keptn()

I changed my pipeline to use the new function,
keptn.keptnConfigureMonitoring monitoring:"dynatrace"

However, I get this error in the Jenkins console.

hudson.remoting.ProxyException: groovy.lang.MissingPropertyException: No such property: keptnEnrichedArgs for class: sh.keptn.Keptn
	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:66)
	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:471)
	at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.getProperty(DefaultInvoker.java:39)
	at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
	at sh.keptn.Keptn.keptnConfigureMonitoring(Keptn.groovy:222)
	at WorkflowScript.run(WorkflowScript:43)
	at ___cps.transform___(Native Method)
	at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:74)
	at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
	at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:66)
	at jdk.internal.reflect.GeneratedMethodAccessor300.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
	at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
	at com.cloudbees.groovy.cps.Next.step(Next.java:83)
	at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)
	at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)
	at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:136)
	at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:275)
	at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:18)
	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:51)
	at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:185)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:402)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$400(CpsThreadGroup.java:96)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:314)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:278)
	at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:67)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:139)
	at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
	at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:68)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)
Finished: FAILURE

Using addResource with a binary file (e.g., helm chart) does not work properly

When trying to upload a binary file, e.g., a helm-chart packaged as a .tgz, we run into an error as the uploaded file is not valid.

        // Package Helm Chart .tgz
        sh 'tar -cvzf .keptn/helm/hello-service.tgz -C .keptn/helm/ hello-service'

        // Add Helm Chart for hello-service
        keptn.keptnAddResources('.keptn/helm/hello-service.tgz', 'helm/hello-service.tgz')

I added some debug output to verify this:

request body={
            "resources" : [{"resourceURI": "helm/hello-service.tgz","resourceContent": "H++/vQgA77+9yothAAPvv71XW2/vv70wFO+/vTnvv73vv73vv71L77+9CCRA77+9Iu+/vQEB67qN77+9KO+/vTRNE3Lvv73vv73vv73EkWPvv73vv73vv73vv719di7vv71wKe+/vUpB77+977+977+977+977+9c3zvv71z77+977+9Tu+/vXVpOQQWERsq77+9N0FV77+977+9aO+/vV/vv73vv71v77+977+9UTfvv71m77+977+9MO+/vWbvv71q77+9Ne+/vV5C77+977+9OU4R77+9Y++/vVDvv71Ryp/vv73bp3/vv73vv70W77+977+977+9C1zvv70hPGgn77+977+977+977+977+9ae+/ve+/vR8D77+977+977+9QO+/vdKFBz7vv70X77+9c1/vv73vv70s77+9Re+/ve+/ve+/ve+/vWZD77+9Ru+/ve+/ve+/vVrvv71RQu+/vQPvv73vv70s77+977+977+977+977+9Ze+/ve+/ve+/vQILCe+/vS3vv73vv70g77+9RO+/vTYj77+9Y++/vc6yDTQPOHYwx5bvv73vv73vv70977+9UO+/vXfvv70wAFvvv71YQmwcWu+/ve+/vRHvv73YnUPvv73vv73vv70277+977+9HD09Ce+/vRBc77+9OWVyCUIe77+977+977+9K++/vQM3TARIHmR9C++/ve+/vQZNV2VHQu+/vRrvv73vv71h77+9D++/vXd6VAnvv73vv70cE1/vv73vv71J77+9W++/ve+/vVwSDz8I77+9WS7vv71YJO+/vTpbGu+/vR/vv70O77+977+977+9J++/vW8377+9QW8yHA3vv71LNULvv710I1xGSQ0u77+977+977+9FDPvv73vv71VEe+/vUVaI++/vdSORO+/vXAI77+9CBPvv71YJu+/vSrvv73vv71A77+9ZxBwfxIw77+9S++/ve+/vTJ377+9WO+/ve+/ve+/ve+/vWUa77+977+9Ze+/ve+/vVlyEe+/vRY777+977+9Je+/vVrvv70o77+977+9K10h77+9WeaGg86k77+977+9de+/vXPvv73vv71R77+977+9CRHvv70n77+9OiPvv70vSlPvv70Q77+9SHPvv70177+9dO+/ve+/vVnvv70777+9Ou+/ve+/ve+/ve+/ve+/vW/vv71n0qE/77+9VxHvv73vv73vv708Q3vvv70f77+977+977+977+977+977+917rvv704w77vv73vv73vv71877+9Du+/vX3vv71t77+977+977+977+9DidJ77+977+9Te+/vXLvv70IfAjvv70h77+9d++/ve+/vWzvv715cAXvv70YbBBHWSnvv70o77+9Fu+/ve+/vQs+JyY+77+9BO+/vR1w77+977+9Bu+/ve+/vTnvv71o77+9DAJg77+9OltV77+9eEDvv71877+977+9AXbvv707OO+/vS/vv70t77+977+977+977+977+977+977+9X++/ve+/ve+/vdWaUV/vv73vv70Lae+/ve+/ve+/vQjvv73vv73vv70l77+936Tvv71XINmd77+9L++/vXwRyLvvv70VKQV2LRlOTlUY65akKgZSWw3ch2Tvv70E77+9cGpT77+9Qu+/vXbCjO+/vSgP77+977+977+977+9XO+/vRgS77+977+977+977+9U++/ve+/vT3vv70477+9Ue+/vSjvv70Y77+9HO+/vc2/YRrvv73vv73vv70177+977+977+977+9Y0Dvv73esw7vv71n77+9dEIr77+977+977+9UO+/vT9jMO+/vXMHYhDvv73vv71/Vwrvv71i77+9NO+/vc+077+977+977+9Qu+/vXbvv70UXu+/ve+/ve+/vSfvv73vv70D77+977+977+977+9N++/ve+/ve+/ve+/vTcV77+9HwcF77+9N++/vUsgWO+/vTR077+9Qu+/vWoO77+9NiMB77+9ZS3vv70JXA/Zsk/vv709ZWtP77+9bc+D77+9VSAc77+9a0J60aJs77+977+9bu+/vQ1O77+9AgUFBQUFBQUFBQUFBQUFBe+/vX8afwHvv73vv70n77+9ACgAAA=="}]
        }

Here resourceContent should have been like this:

H4sIAAAAAAAAA+1Y3W/aMBDnOX+F1Zc+EUggZIrUBwSs69YCoqzSNE3ITa7FI4kjx6Cxqv/7bPJBUkCoGgV1868PUe8u5/s+hyn4Pq3GwBbEhVrlTVAXsG1LPg3bqhefGSpGU/wZttlsCTnDsuxmBVlvY04Z85hjhlDFnTGY/74H9ghsm9w+/jvFtJT/BfbnEOtLHPgHPEMmuNVq7sy/YRp5/q2GzL9tN+0Kqh/Qhp34z/OvkQA/goPOPOrOgOmE1twpIzEnOCx47PFftVKpOD7mEPMzjUHkExd36DzkDjK0Uzuk8CqU+59DEK0Se9BN8Jr532q0ZP9btqnm/zGwK/+eaGu6DCDkf78N9sx/07KsLP8Nw2hU6qYog6aa/8dAtVpFGo7IHbCY0NBBOIri2sLQZiT0HNTNy0ALgGMPc+xoCIU4EDujVDtaHIEreelCiB309IT0u+RGUdwS6PlZiMXgg8spk68gFGDuTq/xPfhxQkDSkJdHIJQVaPpWZhJK3/FLGnboEGenpkq4NOSYhML9jFLd6l6mMtuXBedWJOHVWS4E4WJtRKavO550vt6OBzeT4WgwzNkIrW5dQuUiycGFVN2ZYsb1NCtCtwjrguTckQgejkE8E2IisKLJs0oyfUGQ/BlEPJxEjP4Ucb8omL9i6CljLZk6vimZMgqSXPi/RY4nYUml1hNlU3TNK4Uxi9xw0J302ze9lzH7yGjgFIgIPRDwvRE8lKkpfYj5VIQ5qxpdKt88rNsbXg++3fT647c4M6nQ7+drj89/bNrQGfTH7at+bzS5umlfbtiwr/wyNV96w3FfVtvnXme8Q0lSaGmRrFX4ZAEhxPGQ0XsoejblPLoEXnY2WnlZK9MoExfChhjwBTIJibhZ+l3w8fIWRO95Yk5YBYEIGKHeVhYnAdA538JjgD3yDqw99bDfgl37P6Uc5FNw3/dfw2jm9z/btuX+N0xT7f9jYGP/56v/Nl18pSW7c/FLJl9Gcnb5IqTAruSGk10Vr3j5UhUNqa0b7kPSbmL5cOpS30HjTrIZRVIegQ+LXZnfGJJtv7nbTx3L94hy/yfL4MA//+ztf7PeWP/+YyXff4al+v8YKLW+KSZBlP9r6EZLr2sexC4jEV/R2ugT+AFyZZ2gB8pejIJt4yGZCkKx/ACQWrRFdkJdN8QBpw6BgoKCgoKCgoKCgoKCgoKCwj+NP0XE6FsAKAAA

In addition, adding this resource results in the following API response:

HttpMethod: POST
Content-Type: application/json
x-token: *****
Sending request to url: http://KEPTN_API/api/configuration-service/v1/project/nodejs-example/stage/dev/service/hello-service/resource
Response Code: HTTP/1.1 400 Bad Request

and the following error in Keptns configuration-service

{"timestamp":"2021-11-10T13:33:33.399596821Z","logLevel":"DEBUG","message":"Unarchive the Helm chart: helm/hello-service.tgz"}
{"timestamp":"2021-11-10T13:33:33.399848766Z","logLevel":"ERROR","message":"opening tar archive for reading: wrapping file reader: gzip: invalid header"}

Expected behaviour

Uploading binary files like helm-charts works.

Add files for a specific stage and service

Right now it is only possible to add files for pre-defined services and stages, e.g.:

        keptn.keptnInit project:"${project}", service:"${service}", stage:"dev", monitoring: "dynatrace", shipyard: ".keptn/shipyard.yaml"
        keptn.keptnAddResources('.keptn/dynatrace/sli.yaml','dynatrace/sli.yaml')
        keptn.keptnAddResources('.keptn/slo.yaml','slo.yaml')

would only add files to the specified stage dev.

However, in certain cases it makes sense to also allow adding files to other stages. Right now this would require calling keptnInit again, which is quite a heavy function (e.g., check if project exists, check if stage exists, check if service exists, ...).

It would be easier for the end-user to allow specifying a stage (and service) where files should be added to, e.g.:

        keptn.keptnAddResources('.keptn/slo.yaml','slo.yaml', stage: 'hardening', service: 'foobar-service')

Definition of Done

  • addResource function available for adding files to a specifc stage and service
  • Documentation/Example usage of this function is provided in README

Trigger Evaluation via API like from CLI

Hello,
I just have a quick question:
When i try "keptn trigger evaluation ..." from CLI everything works as expected and i dont need a starttime for that.
When trying with the API i didnt find a direct trigger event, just the "start-evaluation" type event where i need a time or timeframe. Is it possible to trigger without a starttime like i would do it via CLI? What is the equivalent event type to "trigger evaluation"?
Thanks and kind regards
Thilo

RFE: check if sh.keptn.event.configure-monitor.finished is available after calling keptnConfigureMonitoring

After #80 has been implemented, we should also check for sh.keptn.event.configure-monitor.finished cloudevent with result/status check, and print the message that is returned.

More insights

Right now we assume that monitoring is configured properly when the event endpoint of Keptn responds with HTTP status 200:

            if (configureMonitoringResponse.status == 200) {
                echo "Successfully configured monitoring for: ${monitoring}"
                echo "body: ${configureMonitoringBody}"
            } else {
                echo "Couldnt configure monitoring for ${monitoring}: " + configureMonitoringResponse.content
                echo "body: ${configureMonitoringBody}"
            }    

This could lead to problems, as Keptn will almost always accept the event (unless it's malformed).
HTTP Status 200 here does not indicate whether monitoring was configured properly.

This requires the respective service (e.g., prometheus-service, dynatrace-service) to respond with a sh.keptn.event.configure-monitor.finished CloudEvent).

Definition of Done

  • Implementation checks for the respective CloudEvent and prints message from CloudEvent
  • Pipeline fails if keptnConfigureMonitoring is called and no CloudEvent is retrieved, or status/result of CloudEvent indicate a failure/problem
  • FEATURES.md updated

Add unit-tests

Currently the code in this shared library is untested. Based on #50, create unit tests for this shared library to reach 80% code coverage.

Definition of Done

  • Reach 80% Code Coverage via Unit tests

Looking for "[]" in evaluation result results in never succeeding evaluation

Tested with Keptn 0.8.2, sli service 0.10.2 and library 4.0.

Evaluation never finishes because a check on response.content.contains("[]") is set so it waits and tries again.

if (response.status == 404 || response.content.contains("No Keptn sh.keptn.event.evaluation.finished event found for context") || response.content.contains("[]") ) {

Sample result below.

In my case it was due to an SLI not retrieving any data, but the evaluation does finish and gets a score.

@pcjeffmac Should it be changed to an equals check?

{"events":[{"data":{"evaluation":{"gitCommit":"","indicatorResults":[{"displayName":"Response Time 95th Percentile","keySli":false,"passTargets":[{"criteria":"\u003c=+10%","targetValue":0,"violated":false},{"criteria":"\u003c800","targetValue":800,"violated":false}],"score":1,"status":"pass","value":{"metric":"response_time_p95","success":true,"value":362.10801250000003},"warningTargets":[{"criteria":"\u003c=1000","targetValue":1000,"violated":false}]},{"displayName":"Response Time of InvokeAPI Method","keySli":false,"passTargets":[{"criteria":"\u003c=+10%","targetValue":0,"violated":true},{"criteria":"\u003c850000","targetValue":0,"violated":true}],"score":0,"status":"fail","value":{"message":"Dynatrace Metrics API returned 0 result values, expected 1 for query: https://DEDACTED/e/DEDACTED/api/v2/metrics/query/?entitySelector=tag%28keptn_project%3Asimplenodeproject%29%2Ctag%28keptn_stage%3Astaging%29%2Ctag%28keptn_service%3Asimplenodeservice%29%2Ctype%28SERVICE%29\u0026from=1620200968000\u0026metricSelector=calc%3Aservice.simplenode.staging%3Afilter%28eq%28method%2C%2Fapi%2Finvoke%29%29%3Amerge%280%29%3Apercentile%2895%29\u0026resolution=Inf\u0026to=1620201159000.\nPlease ensure the response contains exactly one value (e.g., by using :merge(0):avg for the metric). Here is the output for troubleshooting: {\"metricId\":\"calc:service.simplenode.staging:filter(eq(method,/api/invoke)):merge(0):percentile(95)\",\"data\":**[]**}","metric":"rt_invokeapi","success":false,"value":0},"warningTargets":[{"criteria":"\u003c=+20%","targetValue":0,"violated":true},{"criteria":"\u003c=1000000","targetValue":0,"violated":true}]},{"displayName":"Error Rate","keySli":false,"passTargets":[{"criteria":"\u003c=+5%","targetValue":0,"violated":false},{"criteria":"\u003c2","targetValue":2,"violated":false}],"score":1,"status":"pass","value":{"metric":"error_rate","success":true,"value":0},"warningTargets":[{"criteria":"\u003c5","targetValue":5,"violated":false}]},{"displayName":"Process Heap Suspension","keySli":false,"passTargets":null,"score":0,"status":"info","value":{"metric":"pg_heap_suspension","success":true,"value":22.83852994441986},"warningTargets":null},{"displayName":"Process CPU Usage","keySli":false,"passTargets":null,"score":0,"status":"info","value":{"metric":"pg_cpu_usage","success":true,"value":1.490294337272644},"warningTargets":null}],"result":"fail","score":50,"sloFileContent":"DEDACTED","timeEnd":"2021-05-05T07:52:39.503Z","timeStart":"2021-05-05T07:49:28.091Z"},"labels":{"DtCreds":"dynatrace","art_version":"1.0.0-df4ff8","buildId":"1","buildNumber":"1","component":"api","jobname":"ace-demo/3. Test","joburl":"http://jenkins.DEDACTEDnip.io/job/ace-demo/job/3.%20Test/1/","part_of":"simplenode-app"},"project":"simplenodeproject","result":"fail","service":"simplenodeservice","stage":"staging","status":"succeeded"},"id":"531ba48d-78b7-4558-bda9-4c733310bb1a","source":"lighthouse-service","specversion":"1.0","time":"2021-05-05T07:53:42.067Z","type":"sh.keptn.event.evaluation.finished","shkeptncontext":"d164dc02-2c19-4057-9881-4b6fec5d0b1a","triggeredid":"0fd69b3e-cded-4d63-8408-085115028a48"}],"pageSize":20,"totalCount":1}

Allow to send a parametrized .finished CloudEvent

As a user, I want to be able to execute tests in Jenkins and send a test.finished CloudEvent with a parametrized status and result.

This is true also for other events, e.g., deployment.finished, but really any string is okay (e.g., foobar.finished).

Definition of Done

  • Sending a ${eventType}.finished CloudEvent with parameters status and result is possible

Character limit issue.

Should we denote the 64 character limit.
If you combine project, stage and service, it can not exceed the 64 character limit due to the helm constraint.

Maybe just add this to the documentation for now?

Failed Quality Gate evaluation with Jenkins running on Java 11

When using markEvaluationStartTime() on a Jenkins running on Java 11, evaluation of the quality gate fails. This seems to come from the times in Java 11 being in microseconds instead of milliseconds in Java 8. Switching back to Java 8 resolves the problem.

Message in keptn is :
parsing time "2021-06-21T09:54:21.724374Z" as "2006-01-02T15:04:05.000Z": cannot parse "374Z" as "Z"

addResource functions do not fail even though a http status code 4xx or 5xx is returned

Sometimes adding a file does not work as expected, e.g.:

        // Package Helm Chart .tgz
        sh 'tar -cvzf .keptn/helm/hello-service.tgz -C .keptn/helm/ hello-service'

        // Add Helm Chart for hello-service
        keptn.keptnAddResources('.keptn/helm/hello-service.tgz', 'helm/hello-service.tgz')

results in

HttpMethod: POST
URL: http://KEPTN_API/api/configuration-service/v1/project/nodejs-example/stage/dev/service/hello-service/resource
Content-Type: application/json
x-token: *****
Sending request to url: http://34.69.219.13/api/configuration-service/v1/project/nodejs-example/stage/dev/service/hello-service/resource
Response Code: HTTP/1.1 400 Bad Request

However, the pipeline does not stop here, and just assumes everything is correct.

Expected behaviour

Pipeline needs to exit/stop/break if an add-resource request fails

sendDeploymentFinishedEvent ommits param: "testStrategy"

Hello everyone, @grabnerandi, @kristofre

Context

I am currently working on integrating Keptn qualitygates / performance as a self service with Jenkins and Dynatrace. Really enjoying the functionality of Keptn and its easy configuration.
However, at the moment I am facing problems with the "performance as a self service" part of things.

The comments above the sendDeploymentFinishedEvent function talk about, that this will trigger a test execution with subsequent SLO evaluation. I can imagine, that the deploymentFinishedEvent would trigger a teststep, specified in a shipyard file.

The Problem

How would Keptn know, which testStrategy I want to use?
The parameter is extracted and echoed to the console, but not added to the payload of the request.
Maybe I'm missing something.

Quick Question

As I read it, the sendDeploymentFinishedEvent is relying on a shipyard file to trigger the JMeter Tests. Is this correct?

Thanks in advance,
greetings from Vienna,

Michael

keptnInit should list should handle missing parameters with a better granularity

When using

    def project = "nodejs-example"
    def service = "hello-service"
    def firststage = "dev"
...
        // Initialize the Keptn Project - ensures the Keptn Project is created with the passed shipyard
        keptn.keptnInit project:"${project}", service:"${service}", stage:"${firststage}", monitoring: "dynatrace", shipyard: ".keptn/shipyard.yaml"

I get the following error:

ERROR: keptnInit requires project, stage, service, keptn_endpoint, keptn_bridge and keptn_api_token to be set. These values cant be empty!

This error message is not very helpful. I propose to change this to

Definition of Done

  • Error message for missing parameters is displayed per missing parameter
  • missing configuration for keptn_endpoint, keptn_bridge and keptn_api_token shows a message indicating that environment variables / secrets should be configured (as shown in https://github.com/keptn-sandbox/keptn-jenkins-library#usage )

Provide new evaluation function leveraging latest evaluation api endpoint

The current function sendStartEvaluationEvent sends a start.evaluation event to keptn usin the events api endpoint.
Since Keptn 0.7.3 we introduced a new endpoint /project/{projectName}/stage/{stageName}/service/{serviceName}/evaluation which provides better and easier handling of evaluation timeframe, start & end timestamps.

I suggest we introduce a new Jenkins Library function called "evaluation" that takes the same parameters as the new API endpoint and simply calls that endpoint to start the evaluation

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.