keptn-sandbox / keptn-jenkins-library Goto Github PK
View Code? Open in Web Editor NEWJenkins shared library for integrating Keptn Use Cases with your Jenkins Pipelines
License: Apache License 2.0
Jenkins shared library for integrating Keptn Use Cases with your Jenkins Pipelines
License: Apache License 2.0
With keptn-shared-library @ v5.0, the sendDeliveryTriggeredEvent
function is not working as documented.
We end up not getting any sequence in Keptn:
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"
If the shipyard file is update with a new stage or an additional stage in the yaml configure it's not being apply to the existing 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
Currently the following global variables need to be set in jenkins:
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.
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
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates are currently rate-limited. Click on a checkbox below to force their creation now.
These updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
org.junit.jupiter:junit-jupiter-engine
, org.junit.jupiter:junit-jupiter-api
).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
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.properties
gradle 7.3.3
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
Right now we need to know project, service and stage in order to check whether a service exists:
keptn-jenkins-library/src/sh/keptn/Keptn.groovy
Lines 286 to 299 in 60e4f86
This is a known limitation in the Keptn API.
Depends on keptn/TBD
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)
project
, service
, stage
, labels
, specversion
, shkeptnspecversion
, source
, datacontenttype
, ... could be moved into the helper functionHi,
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
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
Environment
keptn version
): 16.X (although it shouldn't be relevant)kubectl version
): N/AAffected 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
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.
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).
keptnConfigureMonitoring
implemented and documented in READMEkeptnInit
parameter monitoring
removed (BREAKING CHANGE)There are some functions that are most likely no longer needed or need to be renamed accordingly:
sendDeploymentFinishedEvent
(could probably be solved using #42): keptn-jenkins-library/src/sh/keptn/Keptn.groovy
Lines 741 to 810 in 788e157
sendConfigurationChangedEvent
: keptn-jenkins-library/src/sh/keptn/Keptn.groovy
Lines 959 to 1026 in 788e157
sendConfigurationTriggered
: keptn-jenkins-library/src/sh/keptn/Keptn.groovy
Lines 1027 to 1100 in 788e157
Need to pass in the timezone to allow timezones to match customers configuration with jenkins and keptn.
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
Right now creating a release is manual work.
Take a look at https://github.com/keptn-contrib/dynatrace-service and https://github.com/keptn/go-utils to get some release automation using Github actions.
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"
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.
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)
waitTime
to an integer, document that it is wait time in minutesFor 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
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?
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:
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
I think Keptn expects the time in UTC, so this line needs to be replaced by:
def startTime = java.time.LocalDateTime.now(ZoneOffset.UTC).toString()
Same needs to be done in line #495
BR
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"}
Uploading binary files like helm-charts works.
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')
addResource
function available for adding files to a specifc stage and serviceHello,
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
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.
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).
keptnConfigureMonitoring
is called and no CloudEvent is retrieved, or status/result of CloudEvent indicate a failure/problemCurrently the code in this shared library is untested. Based on #50, create unit tests for this shared library to reach 80% code coverage.
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.
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}
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
).
status
and result
is possibleShould 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?
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"
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.
Pipeline needs to exit/stop/break if an add-resource request fails
Hello everyone, @grabnerandi, @kristofre
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.
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.
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
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
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.