Skip to content

Commit

Permalink
Add Task to Trigger Jenkins Pipeline using Tekton
Browse files Browse the repository at this point in the history
The following task can be used to trigger an existing Jenkins pipeline from Tekton using the CURL request by providing the required parameters.

Signed-off-by: vinamra28 <[email protected]>
  • Loading branch information
vinamra28 authored and tekton-robot committed Jul 29, 2020
1 parent 30b8a95 commit f1317ea
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 0 deletions.
99 changes: 99 additions & 0 deletions task/trigger-jenkins-job/0.1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Trigger Jenkins Job

The following task can be used to trigger a Jenkins job using CURL request from a Tekton Task.

More details on Remote Access API can be found [here](https://www.jenkins.io/doc/book/using/remote-access-api/)

## Install the Task

```bash
kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/task/trigger-jenkins-job/0.1/trigger-jenkins-job.yaml
```

## Parameters

- **JENKINS_HOST_URL**: The URL on which Jenkins is running (**Required**)
- **JOB_NAME**: The Job name which needs to be triggered (**Required**)
- **JENKINS_SECRETS**: The name of the secret containing the username and API token for authenticating the Jenkins (_Default_: jenkins-credentials) (**Required**)
- **JOB_PARAMS**: Extra parameters which needs to be appended in the `CURL` request. (_Default_: ""). `JOB_PARAMS` is of type `array` so multiple arguments can be appended. `JOB_PARAMS` can be provided as follows:-

```yaml
params:
- name: JOB_PARAMS
value: |
- FILE_LOCATION_AS_SET_IN_JENKINS=@PATH_TO_FILE
```
## Workspaces
- **source**: In case any file needs to be provided to the Jenkins Job. (_Default_: `emptyDir: {}`)

## Secrets

Secrets containing `username`,`API token` and `crumb` that are used in the task for making the CURL request.

Crumb can be obtained using following command :-

```bash
$ wget -q --auth-no-challenge --user username --password password --output-document - 'http://${Jenkins_URL}/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'
```

This will give you something like `Jenkins-Crumb:44e7033af70da95a47403c3bed5c10f8`. Without crumb information, running curl command will result in example errors such as `HTTP/1.1 403 Forbidden` or `Error 403 No valid crumb was included in the request`.

```yaml
apiVersion: v1
kind: Secret
metadata:
name: jenkins-credentials
type: Opaque
stringData:
username: username
apitoken: api-token
crumb: crumb
```

## Usage

1. Without `JOB_PARAMS` parameters

```yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: trigger-jenkins-job-run
spec:
taskRef:
name: trigger-jenkins-job
params:
- name: JENKINS_HOST_URL
value: "http://localhost:8080"
- name: JOB_NAME
value: tekton
workspaces:
- name: source
emptyDir: {}
```

1. With `JOB_PARAMS` parameters

```yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: trigger-jenkins-job-run
spec:
taskRef:
name: trigger-jenkins-job
params:
- name: JENKINS_HOST_URL
value: "http://localhost:8080"
- name: JOB_NAME
value: tekton
- name: JOB_PARAMS
value:
- id=123
- verbosity=high
workspaces:
- name: source
emptyDir: {}
```
20 changes: 20 additions & 0 deletions task/trigger-jenkins-job/0.1/samples/run.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: trigger-jenkins-job-run
spec:
taskRef:
name: trigger-jenkins-job
params:
- name: JENKINS_HOST_URL
value: http://localhost:8080
- name: JOB_NAME
value: tekton
- name: JENKINS_SECRETS
value: jenkins-credentials
- name: JOB_PARAMS
value:
- id=123
workspaces:
- name: source
emptyDir: {}
9 changes: 9 additions & 0 deletions task/trigger-jenkins-job/0.1/samples/secrets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v1
kind: Secret
metadata:
name: jenkins-credentials
type: Opaque
stringData:
username: username
apitoken: api-token
crumb: crumb
110 changes: 110 additions & 0 deletions task/trigger-jenkins-job/0.1/trigger-jenkins-job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: trigger-jenkins-job
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/tags: jenkins, build
tekton.dev/displayName: "trigger jenkins job"
spec:
description: >-
The following task can be used to trigger a Jenkins job using
CURL request from a Tekton Task.
workspaces:
- name: source
description: >-
The workspace which can be used to mount files which can be
send via CURL request to Jenkins job.
params:
- name: JENKINS_HOST_URL
type: string
description: Server URL on which Jenkins is running
- name: JOB_NAME
type: string
description: Jenkins Job which needs to be triggered
- name: JENKINS_SECRETS
type: string
description: Jenkins secret containing credentials
default: jenkins-credentials
- name: JOB_PARAMS
type: array
description: Extra arguments to append as a part of CURL request
default: [""]
steps:
- name: trigger-pipeline
image: registry.access.redhat.com/ubi8/ubi:latest
workingDir: $(workspaces.source.path)
args:
- $(params.JOB_PARAMS)
script: |
#!/usr/libexec/platform-python
import os
import json
import sys
import base64
import urllib
import urllib.request
args = sys.argv[1:]
queryType = "buildWithParameters"
finalArgs=""
data={}
filename=""
for params in args:
if '@' in params:
filename+=params.split("=")[1][1:]
elif len(params) != 0:
keyValue=params.split("=")
data[keyValue[0]]=keyValue[1]
else:
queryType = "build"
url = "$(params.JENKINS_HOST_URL)"+"/job/"+"$(params.JOB_NAME)"+"/"+queryType
# creating Basic Authorization header
username=os.getenv('USERNAME')
apitoken=os.getenv('API_TOKEN')
credentials = ('%s:%s' % (username,apitoken))
base64string = base64.b64encode(credentials.encode('ascii'))
# Adding required Headers
requiredHeaders={
"Jenkins-Crumb": os.getenv('JENKINS_CRUMB'),
"Authorization": "Basic "+base64string.decode('ascii')
}
data = urllib.parse.urlencode(data)
data = data.encode('utf-8') # data should be bytes
request = urllib.request.Request(url, data=data, headers=requiredHeaders)
# Adding headers in case file is to be uploaded
if len(filename)!=0:
requiredHeaders['Content-Type']="multipart/form-data"
requiredHeaders['Content-Length']=os.stat(filename).st_size
request = urllib.request.Request(url, open(filename, 'rb'), headers=requiredHeaders)
opener = urllib.request.build_opener()
with opener.open(request) as f:
f.read().decode('utf-8')
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: $(params.JENKINS_SECRETS)
key: username
- name: API_TOKEN
valueFrom:
secretKeyRef:
name: $(params.JENKINS_SECRETS)
key: apitoken
- name: JENKINS_CRUMB
valueFrom:
secretKeyRef:
name: $(params.JENKINS_SECRETS)
key: crumb

0 comments on commit f1317ea

Please sign in to comment.