feat: Tekton/Gerrit interaction

This PS adds the basic gerrit<->tekton interaction, which consists of
two charts:
 * Jarvis-System: which launches a utility to scrape pending gerrit
   checks and rechecks, before forwarding requests to a tekton event-
   listener. This event listener then launches a pipeline that sets up
   the environment for the pipeline in the project repo to make use of.
 * Jarvis-Project: which launches a job, which sets up a repo in gerrit,
   configures the checks upon it, and addtionally sets up appropriate
   repos in harbor for oci images and helm charts.

Note: This change makes use of the Jarvis-Connector, which is hosted here:
 * https://github.com/att-comdev/jarvis-connector

Change-Id: I0ca023e357fb562b4f65e081a06ac6581471b4bc
Signed-off-by: Pete Birley <pete@port.direct>
This commit is contained in:
Pete Birley 2021-01-16 16:05:49 -06:00
parent ea909370ed
commit 2dab74898b
57 changed files with 1645 additions and 266 deletions

View File

@ -1,8 +1,9 @@
#NOTE(portdirect): we use the following images, untill https://gerrit-review.googlesource.com/c/k8s-gerrit/+/230465 is resolved.
# NOTE(portdirect): images from rebuilt on ubuntu, and have the checks plugin pre-installed
# https://github.com/portdirect/gerrit-k8s/commit/cbbe103d552af84885289aeb81dd09b1195c5e8b
images:
registry:
name: quay.io
version: v0.1-191-g251041b-dirty-3.3.0
version: v0.1-194-gcbbe103-3.3.1
gerrit:
images:
gerritInit: port/gerrit-init

View File

@ -0,0 +1 @@
values_overrides

View File

@ -0,0 +1,21 @@
apiVersion: v2
name: jarvis-project
description: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: 2.20.0

View File

@ -0,0 +1,24 @@
{{- define "Certificate-project" -}}
---
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: {{ template "helpers.labels.fullname" . }}-project
labels: {{- include "helpers.labels.labels" . | nindent 4 }}
spec:
secretName: {{ template "helpers.labels.fullname" . }}-project-tls
issuerRef:
name: {{ .Values.params.endpoints.tls.issuer.name }}
# We can reference ClusterIssuers by changing the kind here.
# The default value is Issuer (i.e. a locally namespaced Issuer)
kind: {{ .Values.params.endpoints.tls.issuer.kind }}
commonName: {{ .Values.params.endpoints.hostname }}
organization:
- Kubernetes API
dnsNames:
- {{ .Values.params.endpoints.hostname }}
...
{{- end -}}
{{- if .Values.params.endpoints.tls.cert_manager -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Certificate-project" ) }}
{{- end -}}

View File

@ -0,0 +1,80 @@
{{- define "Job-project" -}}
---
apiVersion: batch/v1
kind: Job
metadata:
name: {{ template "helpers.labels.fullname" . }}
labels: {{- include "helpers.labels.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-delete-policy": before-hook-creation
spec:
template:
metadata:
labels: {{- include "helpers.labels.labels" . | nindent 8 }}
spec:
restartPolicy: OnFailure
nodeSelector:
{{ include "helpers.pod.node_selector" ( dict "Global" $ "Application" "project" ) | nindent 8 }}
containers:
- name: project
image: {{ include "helpers.pod.container.image" ( dict "Global" $ "Application" "project" ) }}
imagePullPolicy: {{ .Values.images.pull.policy | quote }}
env:
- name: SSL_CERT_FILE
value: /usr/local/share/ca-certificates/ca.crt
- name: JARVIS_PROJECT_NAME
value: {{ .Release.Name }}
- name: GERRIT_USERNAME
valueFrom:
secretKeyRef:
name: {{ template "helpers.labels.fullname" . }}
key: gerrit-username
- name: GERRIT_HOST
value: {{ .Values.params.gerrit.host }}
- name: GERRIT_URL
value: "https://{{ .Values.params.gerrit.host }}"
command:
- sh
- -cex
- |
# Create gerrit repo
ssh -oStrictHostKeyChecking=accept-new -oUserKnownHostsFile=/dev/null -p 29418 -i /run/jarvis/secret/gerrit-ssh-key "${GERRIT_USERNAME}@${GERRIT_HOST}" gerrit ls-projects -r "^$JARVIS_PROJECT_NAME\$" | grep -q "^${JARVIS_PROJECT_NAME}\$" || \
ssh -oStrictHostKeyChecking=accept-new -oUserKnownHostsFile=/dev/null -p 29418 -i /run/jarvis/secret/gerrit-ssh-key ${GERRIT_USERNAME}@${GERRIT_HOST} gerrit create-project "${JARVIS_PROJECT_NAME}" --submit-type MERGE_IF_NECESSARY --owner Administrators --empty-commit
# Set up checks on the repo
jarvis-connector --auth_file /run/jarvis/gerrit-authfile --gerrit $GERRIT_URL --update --repo "${JARVIS_PROJECT_NAME}" --prefix jarvispipeline || \
jarvis-connector --auth_file /run/jarvis/gerrit-authfile --gerrit $GERRIT_URL --register --repo "${JARVIS_PROJECT_NAME}" --prefix jarvispipeline
# TODO: Add setup for harbor repo.
volumeMounts:
- name: gerrit-creds
mountPath: /run/jarvis/gerrit-authfile
subPath: gerrit-authfile
- name: gerrit-creds
mountPath: /run/jarvis/secret/gerrit-ssh-key
subPath: gerrit-ssh-key
- name: jarvis-ca-crt
mountPath: /usr/local/share/ca-certificates/ca.crt
subPath: ca.crt
volumes:
- name: gerrit-creds
secret:
secretName: {{ template "helpers.labels.fullname" . }}
defaultMode: 0400
items:
- key: gerrit-ssh-key
path: gerrit-ssh-key
- key: gerrit-authfile
path: gerrit-authfile
# NOTE: We are making the assumption that the ca for gerrit is the same as that for the tekton eventlistener
- name: jarvis-ca-crt
secret:
secretName: {{ template "helpers.labels.fullname" . }}-project-tls
items:
- key: ca.crt
path: ca.crt
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Job-project" ) }}

View File

@ -0,0 +1,14 @@
{{- define "Secret-project" -}}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ template "helpers.labels.fullname" . }}
labels: {{- include "helpers.labels.labels" . | nindent 4 }}
data:
gerrit-username: "{{ b64enc .Values.params.gerrit.user }}"
gerrit-authfile: "{{ b64enc ( printf "%s:%s" .Values.params.gerrit.user .Values.params.gerrit.password ) }}"
gerrit-ssh-key: "{{ b64enc ( .Values.params.gerrit.ssh_key ) }}"
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Secret-project" ) }}

View File

@ -0,0 +1,28 @@
{{- define "helpers.config.renderer" -}}
{{- $Global := index . "Global" -}}
{{- $key := index . "key" -}}
{{- $local := dict -}}
{{- $_ := set $local "templateRaw" ( index $Global.Values.config $key ) -}}
{{- with $Global -}}
{{- if not (kindIs "string" $local.templateRaw) -}}
{{- $_ := set $local "template" ( toString ( toPrettyJson ( $local.templateRaw ) ) ) -}}
{{- $_ := set $local "render" ( toString ( toYaml ( fromJson ( tpl $local.template . ) ) ) ) -}}
{{- else -}}
{{- $_ := set $local "template" $local.templateRaw -}}
{{- $_ := set $local "render" ( tpl $local.template . ) -}}
{{- end }}
{{ printf "%s: |" $key }}
{{ $local.render | indent 2 }}
{{- end -}}
{{- end -}}
{{- define "helpers.config.hash" -}}
{{- $name := index . "TemplateName" -}}
{{- $context := index . "Global" -}}
{{- $last := base $context.Template.Name }}
{{- $wtf := $context.Template.Name | replace $last $name -}}
{{- include $wtf $context | sha256sum | quote -}}
{{- end -}}

View File

@ -0,0 +1,49 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "helpers.labels.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "helpers.labels.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "helpers.labels.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Labels to use on {deploy|sts}.spec.selector.matchLabels and svc.spec.selector
*/}}
{{- define "helpers.labels.matchLabels" -}}
app.kubernetes.io/name: {{ include "helpers.labels.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "helpers.labels.labels" -}}
{{ include "helpers.labels.matchLabels" . }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
helm.sh/chart: {{ include "helpers.labels.chart" . }}
{{- end -}}

View File

@ -0,0 +1,22 @@
{{- define "helpers.pod.container.image" -}}
{{- $Global := index . "Global" -}}
{{- $Application := index . "Application" -}}
{{- with index $.Global.Values.images.applications $Application -}}
{{- printf "%s/%s:%s" .repo .name ( .tag | toString ) | quote -}}
{{- end -}}
{{- end -}}
{{- define "helpers.pod.node_selector" -}}
{{- $Global := index . "Global" -}}
{{- $Application := index . "Application" -}}
{{- with index $.Global.Values.node_labels $Application -}}
{{ if kindIs "slice" . }}
{{ range $k, $item := . }}
{{ $item.key }}: {{ $item.value | quote }}
{{ end }}
{{ else }}
{{ .key }}: {{ .value | quote }}
{{ end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,107 @@
{{- define "helpers.template.overlay" -}}
{{- $local := dict -}}
{{/*
By default we merge lists with a 'name' key's values
*/}}
{{- $_ := set $local "merge_same_named" true -}}
{{- if kindIs "map" $ -}}
{{- if hasKey $ "merge_same_named" -}}
{{- $_ := set $local "merge_same_named" $.merge_same_named -}}
{{- end -}}
{{- end -}}
{{- $_ := set $local "input" ( fromYaml ( toString ( include $.template_definition $.Global ) ) ) -}}
{{- $target := dict -}}
{{- $overlay_keys := regexSplit "-+" ( trimSuffix ".yaml" ( lower ( base $.Global.Template.Name ) ) ) 2 }}
{{- $_ := set $local "overlay" dict -}}
{{- if hasKey $.Global.Values.over_rides ( index $overlay_keys 0 ) -}}
{{- if hasKey ( index $.Global.Values.over_rides ( index $overlay_keys 0 ) ) ( index $overlay_keys 1 ) -}}
{{- $_ := set $local "overlay" ( index $.Global.Values.over_rides ( index $overlay_keys 0 ) ( index $overlay_keys 1 ) ) -}}
{{- end }}
{{- end }}
{{- range $item := tuple $local.input $local.overlay -}}
{{- $call := dict "target" $target "source" . "merge_same_named" $local.merge_same_named -}}
{{- $_ := include "helpers._merge" $call -}}
{{- $_ := set $local "result" $call.result -}}
{{- end -}}
{{- if kindIs "map" $ -}}
{{- $_ := set $ "result" $local.result -}}
{{- end -}}
{{ $target | toYaml }}
{{- end -}}
{{- define "helpers._merge" -}}
{{- $local := dict -}}
{{- $_ := set $ "result" $.source -}}
{{/*
TODO: Should we `fail` when trying to merge a collection (map or slice) with
either a different kind of collection or a scalar?
*/}}
{{- if and (kindIs "map" $.target) (kindIs "map" $.source) -}}
{{- range $key, $sourceValue := $.source -}}
{{- if not (hasKey $.target $key) -}}
{{- $_ := set $local "newTargetValue" $sourceValue -}}
{{- if kindIs "map" $sourceValue -}}
{{- $copy := dict -}}
{{- $call := dict "target" $copy "source" $sourceValue -}}
{{- $_ := include "helpers._merge.shallow" $call -}}
{{- $_ := set $local "newTargetValue" $copy -}}
{{- end -}}
{{- else -}}
{{- $targetValue := index $.target $key -}}
{{- $call := dict "target" $targetValue "source" $sourceValue "merge_same_named" $.merge_same_named -}}
{{- $_ := include "helpers._merge" $call -}}
{{- $_ := set $local "newTargetValue" $call.result -}}
{{- end -}}
{{- $_ := set $.target $key $local.newTargetValue -}}
{{- end -}}
{{- $_ := set $ "result" $.target -}}
{{- else if and (kindIs "slice" $.target) (kindIs "slice" $.source) -}}
{{- $call := dict "target" $.target "source" $.source -}}
{{- $_ := include "helpers._merge.append_slice" $call -}}
{{- if $.merge_same_named -}}
{{- $_ := set $local "result" list -}}
{{- $_ := set $local "named_items" dict -}}
{{- range $item := $call.result -}}
{{- $_ := set $local "has_name_key" false -}}
{{- if kindIs "map" $item -}}
{{- if hasKey $item "name" -}}
{{- $_ := set $local "has_name_key" true -}}
{{- end -}}
{{- end -}}
{{- if $local.has_name_key -}}
{{- if hasKey $local.named_items $item.name -}}
{{- $named_item := index $local.named_items $item.name -}}
{{- $call := dict "target" $named_item "source" $item "merge_same_named" $.merge_same_named -}}
{{- $_ := include "helpers._merge" $call -}}
{{- else -}}
{{- $copy := dict -}}
{{- $copy_call := dict "target" $copy "source" $item -}}
{{- $_ := include "helpers._merge.shallow" $copy_call -}}
{{- $_ := set $local.named_items $item.name $copy -}}
{{- $_ := set $local "result" (append $local.result $copy) -}}
{{- end -}}
{{- else -}}
{{- $_ := set $local "result" (append $local.result $item) -}}
{{- end -}}
{{- end -}}
{{- else -}}
{{- $_ := set $local "result" $call.result -}}
{{- end -}}
{{- $_ := set $ "result" (uniq $local.result) -}}
{{- end -}}
{{- end -}}
{{- define "helpers._merge.shallow" -}}
{{- range $key, $value := $.source -}}
{{- $_ := set $.target $key $value -}}
{{- end -}}
{{- end -}}
{{- define "helpers._merge.append_slice" -}}
{{- $local := dict -}}
{{- $_ := set $local "result" $.target -}}
{{- range $value := $.source -}}
{{- $_ := set $local "result" (append $local.result $value) -}}
{{- end -}}
{{- $_ := set $ "result" $local.result -}}
{{- end -}}

View File

@ -0,0 +1,93 @@
{
"$id": "https://example.com/arrays.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "A helm charts image references",
"type": "object",
"properties": {
"images": {
"type": "object",
"additionalProperties": false,
"required": [
"applications",
"pull"
],
"properties": {
"applications": {
"type": "object",
"additionalProperties": {
"type": "object",
"required": [
"tag",
"name",
"repo"
],
"additionalProperties": false,
"properties": {
"tag": {
"anyOf": [
{
"type": "object"
},
{
"type": "string"
}
],
"description": "The image tag."
},
"name": {
"type": "string",
"description": "The image name."
},
"repo": {
"type": "string",
"description": "The image repo."
}
}
}
},
"pull": {
"type": "object",
"additionalProperties": false,
"required": [
"policy"
],
"properties": {
"policy": {
"type": "string",
"enum": [
"Always",
"IfNotPresent",
"Never"
]
}
}
}
}
},
"config": {
"type": "object",
"additionalProperties": {
"anyOf": [
{
"type": "object"
},
{
"type": "string"
}
]
}
},
"params": {
"type": "object",
"additionalProperties": {
"type": "object"
}
},
"over_rides": {
"type": "object",
"additionalProperties": {
"type": "object"
}
}
}
}

View File

@ -0,0 +1,34 @@
# Default values for project-aio.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
images:
applications:
project:
tag: latest
name: attcomdev/jarvis-connector
repo: quay.io
pull:
policy: Always
node_labels:
project:
key: kubernetes.io/os
value: linux
over_rides: {}
params:
gerrit:
user: ""
password: ""
ssh_key: ""
host: gerrit.jarvis.local
endpoints:
hostname: localhost
tls:
cert_manager: true
issuer:
name: jarvis-ca-issuer
kind: ClusterIssuer

View File

@ -0,0 +1 @@
values_overrides

View File

@ -0,0 +1,21 @@
apiVersion: v2
name: jarvis-system
description: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: 2.20.0

View File

@ -0,0 +1,24 @@
{{- define "Certificate-el" -}}
---
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: {{ template "helpers.labels.fullname" . }}-el
labels: {{- include "helpers.labels.labels" . | nindent 4 }}
spec:
secretName: {{ template "helpers.labels.fullname" . }}-el-tls
issuerRef:
name: {{ .Values.params.endpoints.tls.issuer.name }}
# We can reference ClusterIssuers by changing the kind here.
# The default value is Issuer (i.e. a locally namespaced Issuer)
kind: {{ .Values.params.endpoints.tls.issuer.kind }}
commonName: {{ .Values.params.endpoints.hostname }}
organization:
- Kubernetes API
dnsNames:
- {{ .Values.params.endpoints.hostname }}
...
{{- end -}}
{{- if .Values.params.endpoints.tls.cert_manager -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Certificate-el" ) }}
{{- end -}}

View File

@ -1,7 +1,9 @@
{{- define "ClusterRole-el" -}}
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tekton-triggers-example-clusterrole
name: {{ template "helpers.labels.fullname" . }}-el
rules:
# Permissions for every EventListener deployment to function
- apiGroups: ["triggers.tekton.dev"]
@ -9,9 +11,15 @@ rules:
verbs: ["get", "list", "watch"]
- apiGroups: [""]
# secrets are only needed for GitHub/GitLab interceptors
resources: ["configmaps", "secrets"]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
# Permissions to create resources in associated TriggerTemplates
- apiGroups: ["tekton.dev"]
resources: ["pipelineruns", "pipelineresources", "taskruns"]
verbs: ["create"]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["impersonate"]
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "ClusterRole-el" ) }}

View File

@ -0,0 +1,17 @@
{{- define "ClusterRoleBinding-el" -}}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "helpers.labels.fullname" . }}-el
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "helpers.labels.fullname" . }}-el
subjects:
- kind: ServiceAccount
name: {{ template "helpers.labels.fullname" . }}-el
namespace: {{ $.Release.Namespace }}
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "ClusterRoleBinding-el" ) }}

View File

@ -0,0 +1,66 @@
{{- define "Deployment-connector" -}}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "helpers.labels.fullname" . }}
labels: {{- include "helpers.labels.labels" . | nindent 4 }}
spec:
replicas: 1
minReadySeconds: 30
strategy:
rollingUpdate:
maxUnavailable: 0
selector:
matchLabels: {{- include "helpers.labels.matchLabels" . | nindent 6 }}
template:
metadata:
labels: {{- include "helpers.labels.labels" . | nindent 8 }}
spec:
nodeSelector:
{{ include "helpers.pod.node_selector" ( dict "Global" $ "Application" "connector" ) | nindent 8 }}
containers:
- name: connector
image: {{ include "helpers.pod.container.image" ( dict "Global" $ "Application" "connector" ) }}
imagePullPolicy: {{ .Values.images.pull.policy | quote }}
env:
- name: SSL_CERT_FILE
value: /usr/local/share/ca-certificates/ca.crt
- name: GERRIT_URL
value: "https://{{ .Values.params.gerrit.host }}"
- name: EVENTLISTENER_URL
value: "http://el-{{ template "helpers.labels.fullname" . }}.{{ .Release.Namespace }}.svc:8080"
command:
- /usr/bin/jarvis-connector
args:
- --auth_file
- /run/jarvis/gerrit-authfile
- --gerrit
- "$(GERRIT_URL)"
- --event_listener
- "$(EVENTLISTENER_URL)"
volumeMounts:
- name: gerrit-authfile
mountPath: /run/jarvis/gerrit-authfile
subPath: gerrit-authfile
- name: jarvis-ca-crt
mountPath: /usr/local/share/ca-certificates/ca.crt
subPath: ca.crt
volumes:
- name: gerrit-authfile
secret:
secretName: {{ template "helpers.labels.fullname" . }}-gerrit
defaultMode: 0444
items:
- key: gerrit-authfile
path: gerrit-authfile
# NOTE: We are making the assumption that the ca for gerrit is the same as that for the tekton eventlistener
- name: jarvis-ca-crt
secret:
secretName: {{ template "helpers.labels.fullname" . }}-el-tls
items:
- key: ca.crt
path: ca.crt
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Deployment-connector" ) }}

View File

@ -0,0 +1,41 @@
{{- define "EventListener-system" -}}
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
name: {{ template "helpers.labels.fullname" . }}
spec:
serviceAccountName: {{ template "helpers.labels.fullname" . }}-el
triggers:
- name: jarvis-create
interceptors:
- cel:
filter: >-
header.match('X-Jarvis', 'create')
bindings:
- ref: {{ template "helpers.labels.fullname" . }}-create
template:
ref: {{ template "helpers.labels.fullname" . }}-create
- name: jarvis-create-success
interceptors:
- cel:
filter: >-
header.match('Ce-Type', 'dev.tekton.event.pipelinerun.successful.v1') &&
body.pipelineRun.metadata.labels['triggers.tekton.dev/trigger'] == 'jarvis-create'
bindings:
- ref: {{ template "helpers.labels.fullname" . }}-createresult
template:
ref: {{ template "helpers.labels.fullname" . }}-createsuccess
- name: jarvis-create-failure
interceptors:
- cel:
filter: >-
header.match('Ce-Type', 'dev.tekton.event.pipelinerun.failed.v1') &&
body.pipelineRun.metadata.labels['triggers.tekton.dev/trigger'] == 'jarvis-create'
bindings:
- ref: {{ template "helpers.labels.fullname" . }}-createresult
template:
ref: {{ template "helpers.labels.fullname" . }}-createfailure
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "EventListener-system" ) }}

View File

@ -0,0 +1,48 @@
{{- define "Pipeline-create" -}}
---
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: {{ template "helpers.labels.fullname" . }}-create
spec:
params:
- name: repoRoot
- name: project
- name: changeNumber
- name: patchSetNumber
- name: checkerUUID
workspaces:
- name: output
tasks:
- name: createregisterscheduled
taskRef:
name: {{ template "helpers.labels.fullname" . }}-createregisterscheduled
params:
- name: repoRoot
value: $(params.repoRoot)
- name: project
value: $(params.project)
- name: changeNumber
value: $(params.changeNumber)
- name: patchSetNumber
value: $(params.patchSetNumber)
- name: checkerUUID
value: $(params.checkerUUID)
- name: createcheckoutrepo
taskRef:
name: {{ template "helpers.labels.fullname" . }}-createcheckoutrepo
params:
- name: repoRoot
value: $(params.repoRoot)
- name: project
value: $(params.project)
- name: changeNumber
value: $(params.changeNumber)
- name: patchSetNumber
value: $(params.patchSetNumber)
workspaces:
- name: output
workspace: output
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Pipeline-create" ) }}

View File

@ -0,0 +1,31 @@
{{- define "Pipeline-createFailure" -}}
---
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: {{ template "helpers.labels.fullname" . }}-createfailure
spec:
params:
- name: repoRoot
- name: project
- name: changeNumber
- name: patchSetNumber
- name: checkerUUID
tasks:
- name: createfailure
taskRef:
name: {{ template "helpers.labels.fullname" . }}-createfailure
params:
- name: repoRoot
value: $(params.repoRoot)
- name: project
value: $(params.project)
- name: changeNumber
value: $(params.changeNumber)
- name: patchSetNumber
value: $(params.patchSetNumber)
- name: checkerUUID
value: $(params.checkerUUID)
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Pipeline-createFailure" ) }}

View File

@ -0,0 +1,31 @@
{{- define "Pipeline-createSuccess" -}}
---
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: {{ template "helpers.labels.fullname" . }}-createsuccess
spec:
params:
- name: repoRoot
- name: project
- name: changeNumber
- name: patchSetNumber
- name: checkerUUID
tasks:
- name: createsuccess
taskRef:
name: {{ template "helpers.labels.fullname" . }}-createsuccess
params:
- name: repoRoot
value: $(params.repoRoot)
- name: project
value: $(params.project)
- name: changeNumber
value: $(params.changeNumber)
- name: patchSetNumber
value: $(params.patchSetNumber)
- name: checkerUUID
value: $(params.checkerUUID)
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Pipeline-createSuccess" ) }}

View File

@ -0,0 +1,13 @@
{{- define "Secret-gerrit" -}}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ template "helpers.labels.fullname" . }}-gerrit
labels: {{- include "helpers.labels.labels" . | nindent 4 }}
data:
gerrit-authfile: "{{ b64enc ( printf "%s:%s" .Values.params.gerrit.user .Values.params.gerrit.password ) }}"
gerrit-netrc: "{{ b64enc ( printf "machine %s login %s password %s" "gerrit.jarvis.local" .Values.params.gerrit.user .Values.params.gerrit.password ) }}"
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Secret-gerrit" ) }}

View File

@ -0,0 +1,9 @@
{{- define "ServiceAccount-el" -}}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "helpers.labels.fullname" . }}-el
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "ServiceAccount-el" ) }}

View File

@ -0,0 +1,69 @@
{{- define "Task-createCheckoutRepo" -}}
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: {{ template "helpers.labels.fullname" . }}-createcheckoutrepo
spec:
params:
- name: repoRoot
- name: project
- name: changeNumber
- name: patchSetNumber
workspaces:
- name: output
description: The git repo will be cloned onto the volume backing this workspace
results:
- name: commit
description: The precise commit SHA that was fetched by this Task
steps:
- name: checkout-repo
image: {{ include "helpers.pod.container.image" ( dict "Global" $ "Application" "task_git" ) }}
script: |
#!/bin/sh
set -eu -o pipefail -x
# A change ref has the format refs/changes/X/Y/Z where X is
# the last two digits of the change number, Y is the entire
# change number, and Z is the patch set. For example, if
# the change number is 263270, the ref would be
# refs/changes/70/263270/2 for the second patch set.
change_ref="refs/changes/$(echo "0$(params.changeNumber)" | awk '{ print substr( $0, length($0) - 1, length($0) ) }')/$(params.changeNumber)/$(params.patchSetNumber)"
echo $change_ref
CHECKOUT_DIR="$(workspaces.output.path)"
cleandir() {
# Delete any existing contents of the repo directory if it exists.
#
# We don't just "rm -rf $CHECKOUT_DIR" because $CHECKOUT_DIR might be "/"
# or the root of a mounted volume.
if [[ -d "$CHECKOUT_DIR" ]] ; then
# Delete non-hidden files and directories
rm -rf "$CHECKOUT_DIR"/*
# Delete files and directories starting with . but excluding ..
rm -rf "$CHECKOUT_DIR"/.[!.]*
# Delete files and directories starting with .. plus any other character
rm -rf "$CHECKOUT_DIR"/..?*
fi
}
cleandir
cd ${CHECKOUT_DIR}
git init
git config http.sslVerify "false"
git config advice.detachedHead "false"
git fetch $(params.repoRoot)/$(params.project) $change_ref
git checkout FETCH_HEAD
RESULT_SHA="$(git rev-parse HEAD)"
EXIT_CODE="$?"
if [ "$EXIT_CODE" != 0 ] ; then
exit $EXIT_CODE
fi
echo -n "$RESULT_SHA" > $(results.commit.path)
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Task-createCheckoutRepo" ) }}

View File

@ -0,0 +1,60 @@
{{- define "Task-createFailure" -}}
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: {{ template "helpers.labels.fullname" . }}-createfailure
spec:
params:
- name: repoRoot
- name: project
- name: changeNumber
- name: patchSetNumber
- name: checkerUUID
steps:
- name: createfailure
image: {{ include "helpers.pod.container.image" ( dict "Global" $ "Application" "task_curl" ) }}
env:
- name: "JARVIS_TASKRUN_NAMESPACE"
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: "JARVIS_TASKRUN_NAME"
valueFrom:
fieldRef:
fieldPath: metadata.labels['tekton.dev/taskRun']
volumeMounts:
- name: gerrit-netrc
mountPath: /run/jarvis/gerrit-netrc
subPath: gerrit-netrc
script: |
#!/bin/sh
set -eu -o pipefail -x
curl \
--netrc-file /run/jarvis/gerrit-netrc \
--fail \
--insecure \
-L \
-H "Content-Type: application/json; charset=UTF-8" \
$(params.repoRoot)/a/changes/$(params.changeNumber)/revisions/$(params.patchSetNumber)/checks/ \
--data-binary @- << EOF
{
"checker_uuid": "$(params.checkerUUID)",
"state": "FAILED",
"url": "http://{{ .Values.params.tekton.dashboard.host }}/#/namespaces/${JARVIS_TASKRUN_NAMESPACE}/taskruns/${JARVIS_TASKRUN_NAME}",
"message": "Jarvis failed to process the run for change #$(params.changeNumber) ps #$(params.patchSetNumber) to the $(params.project) repo",
"finished": "$(date --utc '+%F %T.%N')"
}
EOF
volumes:
- name: gerrit-netrc
secret:
secretName: {{ template "helpers.labels.fullname" . }}-gerrit
defaultMode: 0444
items:
- key: gerrit-netrc
path: gerrit-netrc
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Task-createFailure" ) }}

View File

@ -0,0 +1,59 @@
{{- define "Task-createRegisterScheduled" -}}
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: {{ template "helpers.labels.fullname" . }}-createregisterscheduled
spec:
params:
- name: repoRoot
- name: project
- name: changeNumber
- name: patchSetNumber
- name: checkerUUID
steps:
- name: register-scheduled
image: {{ include "helpers.pod.container.image" ( dict "Global" $ "Application" "task_curl" ) }}
env:
- name: "JARVIS_TASKRUN_NAMESPACE"
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: "JARVIS_TASKRUN_NAME"
valueFrom:
fieldRef:
fieldPath: metadata.labels['tekton.dev/taskRun']
volumeMounts:
- name: gerrit-netrc
mountPath: /run/jarvis/gerrit-netrc
subPath: gerrit-netrc
script: |
#!/bin/sh
set -eu -o pipefail -x
curl \
--netrc-file /run/jarvis/gerrit-netrc \
--fail \
--insecure \
-L \
-H "Content-Type: application/json; charset=UTF-8" \
$(params.repoRoot)/a/changes/$(params.changeNumber)/revisions/$(params.patchSetNumber)/checks/ \
--data-binary @- << EOF
{
"checker_uuid": "$(params.checkerUUID)",
"state": "SCHEDULED",
"url": "http://{{ .Values.params.tekton.dashboard.host }}/#/namespaces/${JARVIS_TASKRUN_NAMESPACE}/taskruns/${JARVIS_TASKRUN_NAME}",
"message": "Jarvis has started to process the run for change #$(params.changeNumber) ps #$(params.patchSetNumber) to the $(params.project) repo"
}
EOF
volumes:
- name: gerrit-netrc
secret:
secretName: {{ template "helpers.labels.fullname" . }}-gerrit
defaultMode: 0444
items:
- key: gerrit-netrc
path: gerrit-netrc
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Task-createRegisterScheduled" ) }}

View File

@ -0,0 +1,59 @@
{{- define "Task-createSuccess" -}}
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: {{ template "helpers.labels.fullname" . }}-createsuccess
spec:
params:
- name: repoRoot
- name: project
- name: changeNumber
- name: patchSetNumber
- name: checkerUUID
steps:
- name: createsuccess
image: {{ include "helpers.pod.container.image" ( dict "Global" $ "Application" "task_curl" ) }}
env:
- name: "JARVIS_TASKRUN_NAMESPACE"
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: "JARVIS_TASKRUN_NAME"
valueFrom:
fieldRef:
fieldPath: metadata.labels['tekton.dev/taskRun']
volumeMounts:
- name: gerrit-netrc
mountPath: /run/jarvis/gerrit-netrc
subPath: gerrit-netrc
script: |
#!/bin/sh
set -eu -o pipefail -x
curl \
--netrc-file /run/jarvis/gerrit-netrc \
--fail \
--insecure \
-L \
-H "Content-Type: application/json; charset=UTF-8" \
$(params.repoRoot)/a/changes/$(params.changeNumber)/revisions/$(params.patchSetNumber)/checks/ \
--data-binary @- << EOF
{
"checker_uuid": "$(params.checkerUUID)",
"state": "SUCCESSFUL",
"url": "http://{{ .Values.params.tekton.dashboard.host }}/#/namespaces/${JARVIS_TASKRUN_NAMESPACE}/taskruns/${JARVIS_TASKRUN_NAME}",
"message": "Jarvis has successfully processed the run for change #$(params.changeNumber) ps #$(params.patchSetNumber) to the $(params.project) repo"
}
EOF
volumes:
- name: gerrit-netrc
secret:
secretName: {{ template "helpers.labels.fullname" . }}-gerrit
defaultMode: 0444
items:
- key: gerrit-netrc
path: gerrit-netrc
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Task-createSuccess" ) }}

View File

@ -0,0 +1,21 @@
{{- define "TriggerBinding-create" -}}
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
name: {{ template "helpers.labels.fullname" . }}-create
spec:
params:
- name: repoRoot
value: $(body.repoRoot)
- name: project
value: $(body.project)
- name: changeNumber
value: $(body.changeNumber)
- name: patchSetNumber
value: $(body.patchSetNumber)
- name: checkerUUID
value: $(body.checkerUUID)
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "TriggerBinding-create" ) }}

View File

@ -0,0 +1,21 @@
{{- define "TriggerBinding-createResult" -}}
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
name: {{ template "helpers.labels.fullname" . }}-createresult
spec:
params:
- name: repoRoot
value: $(body.pipelineRun.spec.params[?(@.name=='repoRoot')].value)
- name: project
value: $(body.pipelineRun.spec.params[?(@.name=='project')].value)
- name: changeNumber
value: $(body.pipelineRun.spec.params[?(@.name=='changeNumber')].value)
- name: patchSetNumber
value: $(body.pipelineRun.spec.params[?(@.name=='patchSetNumber')].value)
- name: checkerUUID
value: $(body.pipelineRun.spec.params[?(@.name=='checkerUUID')].value)
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "TriggerBinding-createResult" ) }}

View File

@ -0,0 +1,38 @@
{{- define "TriggerTemplate-create" -}}
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
name: {{ template "helpers.labels.fullname" . }}-create
spec:
params:
- name: repoRoot
- name: project
- name: changeNumber
- name: patchSetNumber
- name: checkerUUID
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: {{ template "helpers.labels.fullname" . }}-create-
spec:
pipelineRef:
name: {{ template "helpers.labels.fullname" . }}-create
params:
- name: repoRoot
value: $(tt.params.repoRoot)
- name: project
value: $(tt.params.project)
- name: changeNumber
value: $(tt.params.changeNumber)
- name: patchSetNumber
value: $(tt.params.patchSetNumber)
- name: checkerUUID
value: $(tt.params.checkerUUID)
workspaces:
- name: output
emptyDir: {}
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "TriggerTemplate-create" ) }}

View File

@ -0,0 +1,35 @@
{{- define "TriggerTemplate-createFailure" -}}
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
name: {{ template "helpers.labels.fullname" . }}-createfailure
spec:
params:
- name: repoRoot
- name: project
- name: changeNumber
- name: patchSetNumber
- name: checkerUUID
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: {{ template "helpers.labels.fullname" . }}-createfailure-
spec:
pipelineRef:
name: {{ template "helpers.labels.fullname" . }}-createfailure
params:
- name: repoRoot
value: $(tt.params.repoRoot)
- name: project
value: $(tt.params.project)
- name: changeNumber
value: $(tt.params.changeNumber)
- name: patchSetNumber
value: $(tt.params.patchSetNumber)
- name: checkerUUID
value: $(tt.params.checkerUUID)
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "TriggerTemplate-createFailure" ) }}

View File

@ -0,0 +1,35 @@
{{- define "TriggerTemplate-createSuccess" -}}
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
name: {{ template "helpers.labels.fullname" . }}-createsuccess
spec:
params:
- name: repoRoot
- name: project
- name: changeNumber
- name: patchSetNumber
- name: checkerUUID
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: {{ template "helpers.labels.fullname" . }}-createsuccess-
spec:
pipelineRef:
name: {{ template "helpers.labels.fullname" . }}-createsuccess
params:
- name: repoRoot
value: $(tt.params.repoRoot)
- name: project
value: $(tt.params.project)
- name: changeNumber
value: $(tt.params.changeNumber)
- name: patchSetNumber
value: $(tt.params.patchSetNumber)
- name: checkerUUID
value: $(tt.params.checkerUUID)
...
{{- end -}}
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "TriggerTemplate-createSuccess" ) }}

View File

@ -0,0 +1,28 @@
{{- define "helpers.config.renderer" -}}
{{- $Global := index . "Global" -}}
{{- $key := index . "key" -}}
{{- $local := dict -}}
{{- $_ := set $local "templateRaw" ( index $Global.Values.config $key ) -}}
{{- with $Global -}}
{{- if not (kindIs "string" $local.templateRaw) -}}
{{- $_ := set $local "template" ( toString ( toPrettyJson ( $local.templateRaw ) ) ) -}}
{{- $_ := set $local "render" ( toString ( toYaml ( fromJson ( tpl $local.template . ) ) ) ) -}}
{{- else -}}
{{- $_ := set $local "template" $local.templateRaw -}}
{{- $_ := set $local "render" ( tpl $local.template . ) -}}
{{- end }}
{{ printf "%s: |" $key }}
{{ $local.render | indent 2 }}
{{- end -}}
{{- end -}}
{{- define "helpers.config.hash" -}}
{{- $name := index . "TemplateName" -}}
{{- $context := index . "Global" -}}
{{- $last := base $context.Template.Name }}
{{- $wtf := $context.Template.Name | replace $last $name -}}
{{- include $wtf $context | sha256sum | quote -}}
{{- end -}}

View File

@ -0,0 +1,49 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "helpers.labels.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "helpers.labels.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "helpers.labels.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Labels to use on {deploy|sts}.spec.selector.matchLabels and svc.spec.selector
*/}}
{{- define "helpers.labels.matchLabels" -}}
app.kubernetes.io/name: {{ include "helpers.labels.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "helpers.labels.labels" -}}
{{ include "helpers.labels.matchLabels" . }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
helm.sh/chart: {{ include "helpers.labels.chart" . }}
{{- end -}}

View File

@ -0,0 +1,22 @@
{{- define "helpers.pod.container.image" -}}
{{- $Global := index . "Global" -}}
{{- $Application := index . "Application" -}}
{{- with index $.Global.Values.images.applications $Application -}}
{{- printf "%s/%s:%s" .repo .name ( .tag | toString ) | quote -}}
{{- end -}}
{{- end -}}
{{- define "helpers.pod.node_selector" -}}
{{- $Global := index . "Global" -}}
{{- $Application := index . "Application" -}}
{{- with index $.Global.Values.node_labels $Application -}}
{{ if kindIs "slice" . }}
{{ range $k, $item := . }}
{{ $item.key }}: {{ $item.value | quote }}
{{ end }}
{{ else }}
{{ .key }}: {{ .value | quote }}
{{ end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,107 @@
{{- define "helpers.template.overlay" -}}
{{- $local := dict -}}
{{/*
By default we merge lists with a 'name' key's values
*/}}
{{- $_ := set $local "merge_same_named" true -}}
{{- if kindIs "map" $ -}}
{{- if hasKey $ "merge_same_named" -}}
{{- $_ := set $local "merge_same_named" $.merge_same_named -}}
{{- end -}}
{{- end -}}
{{- $_ := set $local "input" ( fromYaml ( toString ( include $.template_definition $.Global ) ) ) -}}
{{- $target := dict -}}
{{- $overlay_keys := regexSplit "-+" ( trimSuffix ".yaml" ( lower ( base $.Global.Template.Name ) ) ) 2 }}
{{- $_ := set $local "overlay" dict -}}
{{- if hasKey $.Global.Values.over_rides ( index $overlay_keys 0 ) -}}
{{- if hasKey ( index $.Global.Values.over_rides ( index $overlay_keys 0 ) ) ( index $overlay_keys 1 ) -}}
{{- $_ := set $local "overlay" ( index $.Global.Values.over_rides ( index $overlay_keys 0 ) ( index $overlay_keys 1 ) ) -}}
{{- end }}
{{- end }}
{{- range $item := tuple $local.input $local.overlay -}}
{{- $call := dict "target" $target "source" . "merge_same_named" $local.merge_same_named -}}
{{- $_ := include "helpers._merge" $call -}}
{{- $_ := set $local "result" $call.result -}}
{{- end -}}
{{- if kindIs "map" $ -}}
{{- $_ := set $ "result" $local.result -}}
{{- end -}}
{{ $target | toYaml }}
{{- end -}}
{{- define "helpers._merge" -}}
{{- $local := dict -}}
{{- $_ := set $ "result" $.source -}}
{{/*
TODO: Should we `fail` when trying to merge a collection (map or slice) with
either a different kind of collection or a scalar?
*/}}
{{- if and (kindIs "map" $.target) (kindIs "map" $.source) -}}
{{- range $key, $sourceValue := $.source -}}
{{- if not (hasKey $.target $key) -}}
{{- $_ := set $local "newTargetValue" $sourceValue -}}
{{- if kindIs "map" $sourceValue -}}
{{- $copy := dict -}}
{{- $call := dict "target" $copy "source" $sourceValue -}}
{{- $_ := include "helpers._merge.shallow" $call -}}
{{- $_ := set $local "newTargetValue" $copy -}}
{{- end -}}
{{- else -}}
{{- $targetValue := index $.target $key -}}
{{- $call := dict "target" $targetValue "source" $sourceValue "merge_same_named" $.merge_same_named -}}
{{- $_ := include "helpers._merge" $call -}}
{{- $_ := set $local "newTargetValue" $call.result -}}
{{- end -}}
{{- $_ := set $.target $key $local.newTargetValue -}}
{{- end -}}
{{- $_ := set $ "result" $.target -}}
{{- else if and (kindIs "slice" $.target) (kindIs "slice" $.source) -}}
{{- $call := dict "target" $.target "source" $.source -}}
{{- $_ := include "helpers._merge.append_slice" $call -}}
{{- if $.merge_same_named -}}
{{- $_ := set $local "result" list -}}
{{- $_ := set $local "named_items" dict -}}
{{- range $item := $call.result -}}
{{- $_ := set $local "has_name_key" false -}}
{{- if kindIs "map" $item -}}
{{- if hasKey $item "name" -}}
{{- $_ := set $local "has_name_key" true -}}
{{- end -}}
{{- end -}}
{{- if $local.has_name_key -}}
{{- if hasKey $local.named_items $item.name -}}
{{- $named_item := index $local.named_items $item.name -}}
{{- $call := dict "target" $named_item "source" $item "merge_same_named" $.merge_same_named -}}
{{- $_ := include "helpers._merge" $call -}}
{{- else -}}
{{- $copy := dict -}}
{{- $copy_call := dict "target" $copy "source" $item -}}
{{- $_ := include "helpers._merge.shallow" $copy_call -}}
{{- $_ := set $local.named_items $item.name $copy -}}
{{- $_ := set $local "result" (append $local.result $copy) -}}
{{- end -}}
{{- else -}}
{{- $_ := set $local "result" (append $local.result $item) -}}
{{- end -}}
{{- end -}}
{{- else -}}
{{- $_ := set $local "result" $call.result -}}
{{- end -}}
{{- $_ := set $ "result" (uniq $local.result) -}}
{{- end -}}
{{- end -}}
{{- define "helpers._merge.shallow" -}}
{{- range $key, $value := $.source -}}
{{- $_ := set $.target $key $value -}}
{{- end -}}
{{- end -}}
{{- define "helpers._merge.append_slice" -}}
{{- $local := dict -}}
{{- $_ := set $local "result" $.target -}}
{{- range $value := $.source -}}
{{- $_ := set $local "result" (append $local.result $value) -}}
{{- end -}}
{{- $_ := set $ "result" $local.result -}}
{{- end -}}

View File

@ -0,0 +1,93 @@
{
"$id": "https://example.com/arrays.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "A helm charts image references",
"type": "object",
"properties": {
"images": {
"type": "object",
"additionalProperties": false,
"required": [
"applications",
"pull"
],
"properties": {
"applications": {
"type": "object",
"additionalProperties": {
"type": "object",
"required": [
"tag",
"name",
"repo"
],
"additionalProperties": false,
"properties": {
"tag": {
"anyOf": [
{
"type": "object"
},
{
"type": "string"
}
],
"description": "The image tag."
},
"name": {
"type": "string",
"description": "The image name."
},
"repo": {
"type": "string",
"description": "The image repo."
}
}
}
},
"pull": {
"type": "object",
"additionalProperties": false,
"required": [
"policy"
],
"properties": {
"policy": {
"type": "string",
"enum": [
"Always",
"IfNotPresent",
"Never"
]
}
}
}
}
},
"config": {
"type": "object",
"additionalProperties": {
"anyOf": [
{
"type": "object"
},
{
"type": "string"
}
]
}
},
"params": {
"type": "object",
"additionalProperties": {
"type": "object"
}
},
"over_rides": {
"type": "object",
"additionalProperties": {
"type": "object"
}
}
}
}

View File

@ -0,0 +1,43 @@
# Default values for dex-aio.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
images:
applications:
connector:
tag: latest
name: attcomdev/jarvis-connector
repo: quay.io
task_git:
tag: v0.18.1
name: tekton-releases/github.com/tektoncd/pipeline/cmd/git-init
repo: gcr.io
task_curl:
tag: "3.8"
name: evl.ms/curl
repo: quay.io
pull:
policy: Always
node_labels:
connector:
key: kubernetes.io/os
value: linux
over_rides: {}
params:
gerrit:
user: jarvis
password: password
host: gerrit.jarvis.local
tekton:
dashboard:
host: tekton.jarvis.local
endpoints:
hostname: el-jarvis-system.jarvis-system.svc.cluster.local
tls:
cert_manager: true
issuer:
name: jarvis-ca-issuer
kind: ClusterIssuer

View File

@ -0,0 +1,4 @@
controller:
conf:
defaults:
default_cloud_events_sink: http://el-jarvis-system.jarvis-system.svc.cluster.local:8080/

View File

@ -54,15 +54,15 @@ images:
tekton_controller:
name: tektoncd/triggers/cmd/controller
repo: gcr.io/tekton-releases/github.com
tag: v0.10.1
tag: v0.10.2
tekton_eventlistener:
name: tektoncd/triggers/cmd/eventlistenersink
repo: gcr.io/tekton-releases/github.com
tag: v0.10.1
tag: v0.10.2
tekton_webhook:
name: tektoncd/triggers/cmd/webhook
repo: gcr.io/tekton-releases/github.com
tag: v0.10.1
tag: v0.10.2
pull:
policy: IfNotPresent

View File

@ -40,5 +40,7 @@ Vagrant.configure("2") do |config|
./tools/gate/jarvis/400-deploy-harbor.sh
./tools/gate/jarvis/500-deploy-gerrit.sh
./tools/gate/jarvis/600-deploy-tekton.sh
./tools/gate/jarvis/700-deploy-jarvis-system.sh
./tools/gate/jarvis/800-deploy-jarvis-projects.sh
SHELL
end

View File

@ -15,6 +15,28 @@ function get_repo() {
}
get_repo "${gerrit_source}" "${repo_remote}" "${repo_sha}"
# TODO: This needs fixed upstream
patch ${gerrit_source}/helm-charts/gerrit/templates/gerrit.stateful-set.yaml <<'EOF'
--- /tmp/tmp.8ZADMTe64b/helm-charts/gerrit/templates/gerrit.stateful-set.yaml 2021-01-16 21:33:32.331105033 +0000
+++ /tmp/tmp.z8R6CX0Gqg/helm-charts/gerrit/templates/gerrit.stateful-set.yaml 2021-01-16 20:11:36.275929405 +0000
@@ -57,9 +57,14 @@
imagePullPolicy: {{ .Values.images.imagePullPolicy }}
command:
- /bin/ash
- - -ce
+ - -cex
args:
- |
+ python3 /var/tools/gerrit-initializer \
+ -c /var/config/gerrit-init.yaml \
+ -s /var/gerrit \
+ init
+
symlink_config_to_site(){
for file in /var/mnt/etc/config/* /var/mnt/etc/secret/*; do
ln -sf $file /var/gerrit/etc/$(basename $file)
EOF
function generate_ssh_host_key_override() {
local work_dir
work_dir="$(mktemp -d)"
@ -59,6 +81,7 @@ kubectl patch -n gerrit svc gerrit-gerrit-service --patch '{
]
}
}'
sleep 30
function gerrit_bootstrap() {
# Define creds to use for gerrit.
@ -118,6 +141,9 @@ EOF
# Give Admins, Service Users and Project Owners voting rights for the Verified Label
sed -i '/\[access "refs\/heads\/\*"\]/a\ \ \ \ \ \ \ \ label-Verified = -1..+1 group Administrators\n\ \ \ \ \ \ \ \ label-Verified = -1..+1 group Service Users\n\ \ \ \ \ \ \ \ label-Verified = -1..+1 group Project Owners' project.config
# Give Admins, Service Users and Project Owners voting rights for the Verified Label
sed -i '/\[capability\]/a\ \ \ \ \ \ \ \ checks-administrateCheckers = group Administrators' project.config
# Commit and push config
git add .
git commit -asm "Create Verified Label"

View File

@ -12,98 +12,4 @@ for chart in tekton-pipelines tekton-triggers tekton-dashboard; do
$(./tools/deployment/common/get-values-overrides.sh "${chart}")
done
function get_yq() {
version=$(curl --silent "https://api.github.com/repos/mikefarah/yq/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/')
sudo -E curl -L -o "/usr/local/bin/yq" "https://github.com/mikefarah/yq/releases/download/${version}/yq_linux_amd64"
sudo -E chmod +x "/usr/local/bin/yq"
ls "/usr/local/bin/yq"
}
./tools/deployment/common/wait-for-pods.sh tekton-pipelines
function validate() {
# if we are using the proxy we should place that into the template
if [ -n "${HTTP_PROXY}" ]; then
get_yq
# Note: This assume syntax of yq >= 4.x
yq eval '(.spec.resourcetemplates[].spec.params[] | select(.name=="httpProxy")).value |= env(HTTP_PROXY)' -i ./tools/gate/jarvis/resources/tekton/yaml/triggertemplates/triggertemplate.yaml
yq eval '(.spec.resourcetemplates[].spec.params[] | select(.name=="httpsProxy")).value |= env(HTTPS_PROXY)' -i ./tools/gate/jarvis/resources/tekton/yaml/triggertemplates/triggertemplate.yaml
yq eval '(.spec.resourcetemplates[].spec.params[] | select(.name=="noProxy")).value |= env(NO_PROXY)' -i ./tools/gate/jarvis/resources/tekton/yaml/triggertemplates/triggertemplate.yaml
fi
kubectl -n tekton-pipelines apply -f ./tools/gate/jarvis/resources/tekton/yaml/role-resources/secret.yaml
kubectl -n tekton-pipelines apply -f ./tools/gate/jarvis/resources/tekton/yaml/role-resources/serviceaccount.yaml
kubectl -n tekton-pipelines apply -f ./tools/gate/jarvis/resources/tekton/yaml/role-resources/clustertriggerbinding-roles
kubectl -n tekton-pipelines apply -f ./tools/gate/jarvis/resources/tekton/yaml/role-resources/triggerbinding-roles
kubectl -n tekton-pipelines apply -f ./tools/gate/jarvis/resources/tekton/yaml/triggertemplates/triggertemplate.yaml
kubectl -n tekton-pipelines apply -f ./tools/gate/jarvis/resources/tekton/yaml/triggerbindings/triggerbinding.yaml
kubectl -n tekton-pipelines apply -f ./tools/gate/jarvis/resources/tekton/yaml/triggerbindings/triggerbinding-message.yaml
kubectl -n tekton-pipelines apply -f ./tools/gate/jarvis/resources/tekton/yaml/eventlisteners/eventlistener.yaml
kubectl -n tekton-pipelines apply -f ./tools/gate/jarvis/resources/tekton/yaml/example-pipeline.yaml
# Install the pipeline
kubectl -n tekton-pipelines wait --for=condition=Ready pod --timeout=120s --all
# Define creds to use for gerrit.
ldap_username="jarvis"
ldap_password="password"
# Create repo for Jarvis sanity testing
ssh -p 29418 ${ldap_username}@gerrit.jarvis.local gerrit create-project jarvis-sanity --submit-type MERGE_IF_NECESSARY --owner Administrators --empty-commit
# Configure repo webhook
jarvis_sanity_repo=$(mktemp -d)
pushd "${jarvis_sanity_repo}"
git init
git remote add origin ssh://${ldap_username}@gerrit.jarvis.local:29418/jarvis-sanity.git
git fetch origin refs/meta/config:refs/remotes/origin/meta/config
git checkout meta/config
tee --append project.config <<EOF
[plugin "webhooks"]
connectionTimeout = 3000
maxTries = 300
retryInterval = 2000
socketTimeout = 2500
threadPoolSize = 3
EOF
tee webhooks.config <<EOF
[remote "Tekton"]
url = http://el-listener.tekton-pipelines.svc.cluster.local:8080/
maxTries = 3
sslVerify = false
event = patchset-created
event = patchset-updated
EOF
git add .
git commit -asm "Create Add PS Webhook Config"
git push origin HEAD:refs/meta/config
popd
# Create PS to repo to test webhook
jarvis_sanity_repo=$(mktemp -d)
git clone ssh://${ldap_username}@gerrit.jarvis.local:29418/jarvis-sanity.git "${jarvis_sanity_repo}"
pushd "${jarvis_sanity_repo}"
tee .gitreview <<EOF
[gerrit]
host=gerrit.jarvis.local
port=29418
project=jarvis-sanity.git
EOF
git review -s
git add .gitreview
git commit -asm "Add .gitreview"
git review
# Sleep for 5s to give time for webhook to fire, and be responded to
sleep 5
# Ensure the run is successful
kubectl -n tekton-pipelines wait --for=condition=Succeeded pipelineruns --timeout=120s --all
# Check the pipeline runs
kubectl -n tekton-pipelines get pipelinerun
}
validate
./tools/deployment/common/wait-for-pods.sh tekton-pipelines

View File

@ -0,0 +1,13 @@
#!/bin/bash
set -ex
# shellcheck disable=SC2046
helm upgrade \
--create-namespace \
--install \
--namespace=jarvis-system \
jarvis-system \
"./charts/jarvis-system" \
$(./tools/deployment/common/get-values-overrides.sh jarvis-system)
./tools/deployment/common/wait-for-pods.sh jarvis-system

View File

@ -0,0 +1,67 @@
#!/bin/bash
set -ex
function generate_gerrit_creds_override() {
local output_file
output_file="$(mktemp -d)/gerrit-host-rsa-key.yaml"
tee "${output_file}" <<EOF
params:
gerrit:
user: jarvis
password: password
ssh_key: |
$(awk '{ print " " $0 }' "${HOME}/.ssh/id_rsa")
EOF
export gerrit_creds_override="${output_file}"
}
generate_gerrit_creds_override
jarvis_project=jarvis-project
# shellcheck disable=SC2046
helm upgrade \
--create-namespace \
--install \
--namespace=jarvis-projects \
"${jarvis_project}" \
"./charts/jarvis-project" \
--values="${gerrit_creds_override}" \
$(./tools/deployment/common/get-values-overrides.sh jarvis-project)
./tools/deployment/common/wait-for-pods.sh jarvis-projects
sleep 60
# Define creds to use for gerrit.
ldap_username="jarvis"
# Create PS to repo to test jarvis
jarvis_sanity_repo=$(mktemp -d)
git clone ssh://${ldap_username}@gerrit.jarvis.local:29418/${jarvis_project}.git "${jarvis_sanity_repo}"
pushd "${jarvis_sanity_repo}"
tee .gitreview <<EOF
[gerrit]
host=gerrit.jarvis.local
port=29418
project=${jarvis_project}.git
EOF
git review -s
git add .gitreview
git commit -asm "Add .gitreview"
git review
popd
# Check jarvis pipeline run
end=$(date +%s)
timeout="900"
end=$((end + timeout))
while true; do
result="$(curl -L https://gerrit.jarvis.local/changes/1/revisions/1/checks | tail -1 | jq -r .[].state)"
[ $result == "SUCCESSFUL" ] && break || true
sleep 5
now=$(date +%s)
if [ $now -gt $end ] ; then
echo "Pipeline failed to complete $timeout seconds"
exit -1
fi
done

View File

@ -1,14 +0,0 @@
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
name: listener
spec:
serviceAccountName: tekton-triggers-example-sa
triggers:
- name: foo-trig
bindings:
- ref: pipeline-binding
- ref: message-binding
template:
ref: pipeline-template

View File

@ -1,43 +0,0 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: print-info
spec:
params:
- name: info
type: string
steps:
- name: print-info
image: bash
command: ["bash", "-c"]
args:
- echo -e '$(params.info)'
---
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: simple-pipeline
spec:
params:
- name: gitrepositoryurl
- name: gitrevision
- name: message
tasks:
- name: print-url
taskRef:
name: print-info
params:
- name: info
value: $(params.gitrepositoryurl)
- name: print-revision
taskRef:
name: print-info
params:
- name: info
value: $(params.gitrevision)
- name: print-message
taskRef:
name: print-info
params:
- name: info
value: $(params.message)

View File

@ -1,12 +0,0 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tekton-triggers-example-clusterbinding
subjects:
- kind: ServiceAccount
name: tekton-triggers-example-sa
namespace: tekton-pipelines
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: tekton-triggers-example-clusterrole

View File

@ -1,7 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: tekton-triggers-example-secret
type: Opaque
stringData:
secretToken: "1234567"

View File

@ -1,6 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-triggers-example-sa
secrets:
- name: tekton-triggers-example-secret

View File

@ -1,11 +0,0 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: tekton-triggers-example-binding
subjects:
- kind: ServiceAccount
name: tekton-triggers-example-sa
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: tekton-triggers-example-minimal

View File

@ -1,20 +0,0 @@
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tekton-triggers-example-minimal
rules:
# Permissions for every EventListener deployment to function
- apiGroups: ["triggers.tekton.dev"]
resources: ["eventlisteners", "triggerbindings", "triggertemplates", "triggers"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
# secrets are only needed for GitHub/GitLab interceptors
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch"]
# Permissions to create resources in associated TriggerTemplates
- apiGroups: ["tekton.dev"]
resources: ["pipelineruns", "pipelineresources", "taskruns"]
verbs: ["create"]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["impersonate"]

View File

@ -1,8 +0,0 @@
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
name: message-binding
spec:
params:
- name: message
value: Hello from the Triggers EventListener!

View File

@ -1,10 +0,0 @@
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
name: pipeline-binding
spec:
params:
- name: gitrevision
value: $(body.change.id)
- name: gitrepositoryurl
value: $(body.change.url)

View File

@ -1,33 +0,0 @@
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
name: pipeline-template
spec:
params:
- name: gitrevision
description: The git revision
- name: gitrepositoryurl
description: The git repository url
- name: message
description: The message to print
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: simple-pipeline-run-
spec:
pipelineRef:
name: simple-pipeline
params:
- name: gitrepositoryurl
value: $(tt.params.gitrepositoryurl)
- name: gitrevision
value: $(tt.params.gitrevision)
- name: message
value: $(tt.params.message)
- name: httpProxy
value: ""
- name: httpsProxy
value: ""
- name: noProxy
value: "172.28.0.2,localhost,127.0.0.1,10.96.0.0/12,192.168.49.0/24,192.168.99.0/24,107.124.202.156,10.0.2.15,10.244.0.0/16,.minikube.internal,.svc,.svc.cluster.local,jarvis.local,jarvis"

View File

@ -38,6 +38,8 @@
- ./tools/gate/jarvis/400-deploy-harbor.sh
- ./tools/gate/jarvis/500-deploy-gerrit.sh
- ./tools/gate/jarvis/600-deploy-tekton.sh
- ./tools/gate/jarvis/700-deploy-jarvis-system.sh
- ./tools/gate/jarvis/800-deploy-jarvis-projects.sh
- job:
name: airship-jarvis-sample-workload-validation