diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..40c58d9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,33 @@ +FROM rust:latest AS builder + +WORKDIR /app + +# Copy the Cargo.toml and build the project to cache dependencies +COPY Cargo.toml . +RUN mkdir src &&\ + echo "fn main() {}" > src/main.rs +RUN cargo build --release + +# Copy the rest of the source code then build the project +COPY src src +RUN touch src/main.rs +RUN cargo build --release + +# Strip the binaries to reduce size +RUN strip target/release/botdiscord +#FROM alpine:latest as release +FROM gcr.io/distroless/cc-debian12 + +WORKDIR /app + +# Copy each binary from the builder stage, all needed for different stages +COPY --from=builder /app/target/release/server . + +# Copy the resource folder that containt default configuration files +COPY ./resource ./resource + +ENV PORT 5437 + +EXPOSE 5437 + +CMD ["./botdiscord"] \ No newline at end of file diff --git a/chart/Chart.yaml b/chart/Chart.yaml new file mode 100644 index 0000000..8183d56 --- /dev/null +++ b/chart/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: bu-teammaker +description: A helm to deploy the app + +# 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. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.2 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.1" diff --git a/chart/templates/Deployment.surreal.yaml b/chart/templates/Deployment.surreal.yaml new file mode 100644 index 0000000..1526e55 --- /dev/null +++ b/chart/templates/Deployment.surreal.yaml @@ -0,0 +1,82 @@ +{{- $host_dev := printf "%s-bu-teammaker.dev.%s" .Values.image.tag .Values.ingress.host -}} +{{- $host_prod := printf "%s.%s" "bu-teammaker" .Values.ingress.host -}} +{{- $host := regexMatch "^v[0-9]+\\.[0-9]+\\.[0-9]+$" .Values.image.tag | ternary $host_prod $host_dev -}} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}-surrealdb" + labels: + app: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}-surrealdb" +{{- include "mychart.labels" . | nindent 2 }} + annotations: + deployment.kubernetes.io/revision: "{{ .Release.Revision }}-surrealdb" + deployment.git-branch: "{{ .Values.image.tag }}" + rollme: {{ randAlphaNum 5 | quote }} +spec: + replicas: 1 + selector: + matchLabels: + app: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}-surrealdb" + template: + metadata: + labels: + app: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}-surrealdb" + annotations: + rollme: {{ randAlphaNum 5 | quote }} + spec: + imagePullSecrets: + - name: harbor-pull + volumes: + - name: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}-surrealdb" + persistentVolumeClaim: + claimName: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}-surrealdb" + containers: + - name: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}-surrealdb" + image: "surrealdb/surrealdb:latest" + imagePullPolicy: Always + command: + - start + ports: + - containerPort: 8000 + name: http + env: + {{- range $env := .Values.env }} + - name: "{{ $env.name }}" + value: "{{ $env.value }}" + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: SURREAL_AUTH + value: "true" + - name: SURREAL_USER + envFrom: + secretRef: + name: "bot-discord-db" + key: "username" + - name: SURREAL_PASS + envFrom: + secretRef: + name: "bot-discord-db" + key: "password" + - name: SURREAL_PATH + value: "file:/appdata/bot.db" + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}-surrealdb" + mountPath: /appdata + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 5 + periodSeconds: 10 diff --git a/chart/templates/Deployment.yaml b/chart/templates/Deployment.yaml new file mode 100644 index 0000000..0ca844e --- /dev/null +++ b/chart/templates/Deployment.yaml @@ -0,0 +1,118 @@ +{{- $host_dev := printf "%s-bu-teammaker.dev.%s" .Values.image.tag .Values.ingress.host -}} +{{- $host_prod := printf "%s.%s" "bu-teammaker" .Values.ingress.host -}} +{{- $host := regexMatch "^v[0-9]+\\.[0-9]+\\.[0-9]+$" .Values.image.tag | ternary $host_prod $host_dev -}} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}" + labels: + app: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}" +{{- include "mychart.labels" . | nindent 2 }} + annotations: + deployment.kubernetes.io/revision: "{{ .Release.Revision }}" + deployment.git-branch: "{{ .Values.image.tag }}" + rollme: {{ randAlphaNum 5 | quote }} +spec: + replicas: 1 + selector: + matchLabels: + app: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}" + template: + metadata: + labels: + app: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}" + annotations: + rollme: {{ randAlphaNum 5 | quote }} + spec: + imagePullSecrets: + - name: harbor-pull + volumes: + - name: "base_image" + emptyDir: {} + - name: "ssh-key" + secret: + secretName: "bot-discord-pull" + initContainers: + - name: "init" + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: Always + command: ["sh", "-c", "cd /appdata && git clone git@git.weebo.fr:sandbox/base-image.git ."] + env: + - name: "GIT_SSH_COMMAND" + value: "ssh -o StrictHostKeyChecking=no" + volumeMounts: + - name: "base_image" + mountPath: "/appdata" + - name: "ssh-key" + mountPath: "/root/.ssh" + containers: + - name: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}" + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: Always + ports: + - containerPort: 5437 + name: http + env: + {{- range $env := .Values.env }} + - name: "{{ $env.name }}" + value: "{{ $env.value }}" + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: RUST_BACKTRACE + value: "1" + - name: PORT + value: "5437" + - name: IMAGE_PATH + value: "/appdata/" + - name: "DB_NAME" + envFrom: + secretRef: + name: "bot-discord-db" + key: "db_name" + - name: "DB_PASSWORD" + envFrom: + secretRef: + name: "bot-discord-db" + key: "password" + - name: "DB_USER" + envFrom: + secretRef: + name: "bot-discord-db" + key: "username" + - name: "DB_NAMESPACE" + envFrom: + secretRef: + name: "bot-discord-db" + key: "db_namespace" + - name: "BOT_TOKEN" + envFrom: + secretRef: + name: "botdiscord" + key: "token" + - name: RUST_ENV + {{- if regexMatch "^[0-9]+\\.[0-9]+\\.[0-9]+$" .Values.image.tag }} + value: "prod" + {{- else }} + value: "dev-{{ .Values.image.tag }}" + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: "base_image" + mountPath: "/appdata" + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 5 + periodSeconds: 10 diff --git a/chart/templates/Service.surreal.yaml b/chart/templates/Service.surreal.yaml new file mode 100644 index 0000000..6c7eb39 --- /dev/null +++ b/chart/templates/Service.surreal.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}-surrealdb" + labels: + app: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}-surrealdb" +{{- include "mychart.labels" . | nindent 2 }} + annotations: + deployment.kubernetes.io/revision: "{{ .Release.Revision }}" + deployment.git-branch: "{{ .Values.image.tag }}" +spec: + ports: + - port: 8000 + targetPort: 8000 + name: http + selector: + app: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}-surrealdb" + type: ClusterIP diff --git a/chart/templates/Service.yaml b/chart/templates/Service.yaml new file mode 100644 index 0000000..896e7e0 --- /dev/null +++ b/chart/templates/Service.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}" + labels: + app: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}" +{{- include "mychart.labels" . | nindent 2 }} + annotations: + deployment.kubernetes.io/revision: "{{ .Release.Revision }}" + deployment.git-branch: "{{ .Values.image.tag }}" +spec: + ports: + - port: 5437 + targetPort: 5437 + name: http + selector: + app: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}" + type: ClusterIP diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl new file mode 100644 index 0000000..38e85c9 --- /dev/null +++ b/chart/templates/_helpers.tpl @@ -0,0 +1,13 @@ +{{/* Generate object name */}} +{{- define "mychart.name" }} +{{- regexMatch "^v[0-9]+\\.[0-9]+\\.[0-9]+$" .Values.image.tag | ternary "prod" (regexReplaceAll "\\W+" .Values.image.tag "_") -}} +{{- end }} + +{{/* Generate labels */}} +{{- define "mychart.labels" -}} +{{- with .Values.labels }} +{{- range $key, $value := . }} + {{ $key }}: {{ tpl $value $ | quote }} +{{- end }} +{{- end }} +{{- end }} diff --git a/chart/templates/volume.surreal.yaml b/chart/templates/volume.surreal.yaml new file mode 100644 index 0000000..9282a9f --- /dev/null +++ b/chart/templates/volume.surreal.yaml @@ -0,0 +1,10 @@ +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: "{{ .Chart.Name }}-{{- template "mychart.name" . -}}-surrealdb" +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi diff --git a/chart/values.yaml b/chart/values.yaml new file mode 100644 index 0000000..9e783f5 --- /dev/null +++ b/chart/values.yaml @@ -0,0 +1,32 @@ +resources: # Need to be fine tunned in the futur + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 20m + memory: 16Mi + +env: + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: "http://tempo.monitoring.svc.cluster.local:4317" + - name: RUST_LOG + value: "debug" + - name: APP_NAME + value: "BotDiscord" + +ingress: + annotations: + kubernetes.io/ingress.class: "haproxy" + cert-manager.io/cluster-issuer: "letsencrypt-prod" + host: weebo.fr + +image: + repository: harbor.weebo.fr/bu_teammaker/botdiscord + pullPolicy: Always + tag: "v1.17.8" + +labels: + app.kubernetes.io/name: botdiscord + app.kubernetes.io/component: botdiscord + app.kubernetes.io/instance: "botdiscord-{{ .Release.Name }}" + app.kubernetes.io/part-of: "bot-discord" diff --git a/cicd/.helmignore b/cicd/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/cicd/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/cicd/Chart.yaml b/cicd/Chart.yaml new file mode 100644 index 0000000..54ec370 --- /dev/null +++ b/cicd/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: cicdv2 +description: A CICD pipeline for Kubernetes Tekton + +# 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. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.53 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/cicd/templates/dep/git-clone.yaml b/cicd/templates/dep/git-clone.yaml new file mode 100644 index 0000000..9b3d9f7 --- /dev/null +++ b/cicd/templates/dep/git-clone.yaml @@ -0,0 +1,238 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: git-clone + labels: + app.kubernetes.io/version: "0.8" + annotations: + tekton.dev/pipelines.minVersion: "0.29.0" + tekton.dev/categories: Git + tekton.dev/tags: git + tekton.dev/displayName: "git clone" + tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le,linux/arm64" +spec: + description: >- + These Tasks are Git tasks to work with repositories used by other tasks + in your Pipeline. + + The git-clone Task will clone a repo from the provided url into the + output Workspace. By default the repo will be cloned into the root of + your Workspace. You can clone into a subdirectory by setting this Task's + subdirectory param. This Task also supports sparse checkouts. To perform + a sparse checkout, pass a list of comma separated directory patterns to + this Task's sparseCheckoutDirectories param. + workspaces: + - name: output + description: The git repo will be cloned onto the volume backing this Workspace. + - name: ssh-directory + optional: true + description: | + A .ssh directory with private key, known_hosts, config, etc. Copied to + the user's home before git commands are executed. Used to authenticate + with the git remote when performing the clone. Binding a Secret to this + Workspace is strongly recommended over other volume types. + - name: basic-auth + optional: true + description: | + A Workspace containing a .gitconfig and .git-credentials file. These + will be copied to the user's home before any git commands are run. Any + other files in this Workspace are ignored. It is strongly recommended + to use ssh-directory over basic-auth whenever possible and to bind a + Secret to this Workspace over other volume types. + - name: ssl-ca-directory + optional: true + description: | + A workspace containing CA certificates, this will be used by Git to + verify the peer with when fetching or pushing over HTTPS. + params: + - name: url + description: Repository URL to clone from. + type: string + - name: revision + description: Revision to checkout. (branch, tag, sha, ref, etc...) + type: string + default: "" + - name: refspec + description: Refspec to fetch before checking out revision. + default: "" + - name: submodules + description: Initialize and fetch git submodules. + type: string + default: "true" + - name: depth + description: Perform a shallow clone, fetching only the most recent N commits. + type: string + default: "1" + - name: sslVerify + description: Set the `http.sslVerify` global git config. Setting this to `false` is not advised unless you are sure that you trust your git remote. + type: string + default: "true" + - name: crtFileName + description: file name of mounted crt using ssl-ca-directory workspace. default value is ca-bundle.crt. + type: string + default: "ca-bundle.crt" + - name: subdirectory + description: Subdirectory inside the `output` Workspace to clone the repo into. + type: string + default: "" + - name: sparseCheckoutDirectories + description: Define the directory patterns to match or exclude when performing a sparse checkout. + type: string + default: "" + - name: deleteExisting + description: Clean out the contents of the destination directory if it already exists before cloning. + type: string + default: "true" + - name: httpProxy + description: HTTP proxy server for non-SSL requests. + type: string + default: "" + - name: httpsProxy + description: HTTPS proxy server for SSL requests. + type: string + default: "" + - name: noProxy + description: Opt out of proxying HTTP/HTTPS requests. + type: string + default: "" + - name: verbose + description: Log the commands that are executed during `git-clone`'s operation. + type: string + default: "true" + - name: gitInitImage + description: The image providing the git-init binary that this Task runs. + type: string + default: "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.29.0" + - name: userHome + description: | + Absolute path to the user's home directory. + type: string + default: "/tekton/home" + results: + - name: commit + description: The precise commit SHA that was fetched by this Task. + - name: url + description: The precise URL that was fetched by this Task. + steps: + - name: clone + image: "$(params.gitInitImage)" + env: + - name: HOME + value: "$(params.userHome)" + - name: PARAM_URL + value: $(params.url) + - name: PARAM_REVISION + value: $(params.revision) + - name: PARAM_REFSPEC + value: $(params.refspec) + - name: PARAM_SUBMODULES + value: $(params.submodules) + - name: PARAM_DEPTH + value: $(params.depth) + - name: PARAM_SSL_VERIFY + value: $(params.sslVerify) + - name: PARAM_CRT_FILENAME + value: $(params.crtFileName) + - name: PARAM_SUBDIRECTORY + value: $(params.subdirectory) + - name: PARAM_DELETE_EXISTING + value: $(params.deleteExisting) + - name: PARAM_HTTP_PROXY + value: $(params.httpProxy) + - name: PARAM_HTTPS_PROXY + value: $(params.httpsProxy) + - name: PARAM_NO_PROXY + value: $(params.noProxy) + - name: PARAM_VERBOSE + value: $(params.verbose) + - name: PARAM_SPARSE_CHECKOUT_DIRECTORIES + value: $(params.sparseCheckoutDirectories) + - name: PARAM_USER_HOME + value: $(params.userHome) + - name: WORKSPACE_OUTPUT_PATH + value: $(workspaces.output.path) + - name: WORKSPACE_SSH_DIRECTORY_BOUND + value: $(workspaces.ssh-directory.bound) + - name: WORKSPACE_SSH_DIRECTORY_PATH + value: $(workspaces.ssh-directory.path) + - name: WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND + value: $(workspaces.basic-auth.bound) + - name: WORKSPACE_BASIC_AUTH_DIRECTORY_PATH + value: $(workspaces.basic-auth.path) + - name: WORKSPACE_SSL_CA_DIRECTORY_BOUND + value: $(workspaces.ssl-ca-directory.bound) + - name: WORKSPACE_SSL_CA_DIRECTORY_PATH + value: $(workspaces.ssl-ca-directory.path) + securityContext: + runAsNonRoot: true + runAsUser: 65532 + script: | + #!/usr/bin/env sh + set -eu + + if [ "${PARAM_VERBOSE}" = "true" ] ; then + set -x + fi + + + if [ "${WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND}" = "true" ] ; then + cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.git-credentials" "${PARAM_USER_HOME}/.git-credentials" + cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.gitconfig" "${PARAM_USER_HOME}/.gitconfig" + chmod 400 "${PARAM_USER_HOME}/.git-credentials" + chmod 400 "${PARAM_USER_HOME}/.gitconfig" + fi + + if [ "${WORKSPACE_SSH_DIRECTORY_BOUND}" = "true" ] ; then + cp -R "${WORKSPACE_SSH_DIRECTORY_PATH}" "${PARAM_USER_HOME}"/.ssh + chmod 700 "${PARAM_USER_HOME}"/.ssh + chmod -R 400 "${PARAM_USER_HOME}"/.ssh/* + fi + + if [ "${WORKSPACE_SSL_CA_DIRECTORY_BOUND}" = "true" ] ; then + export GIT_SSL_CAPATH="${WORKSPACE_SSL_CA_DIRECTORY_PATH}" + if [ "${PARAM_CRT_FILENAME}" != "" ] ; then + export GIT_SSL_CAINFO="${WORKSPACE_SSL_CA_DIRECTORY_PATH}/${PARAM_CRT_FILENAME}" + fi + fi + CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}/${PARAM_SUBDIRECTORY}" + + 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 + } + + if [ "${PARAM_DELETE_EXISTING}" = "true" ] ; then + cleandir + fi + + test -z "${PARAM_HTTP_PROXY}" || export HTTP_PROXY="${PARAM_HTTP_PROXY}" + test -z "${PARAM_HTTPS_PROXY}" || export HTTPS_PROXY="${PARAM_HTTPS_PROXY}" + test -z "${PARAM_NO_PROXY}" || export NO_PROXY="${PARAM_NO_PROXY}" + + /ko-app/git-init \ + -url="${PARAM_URL}" \ + -revision="${PARAM_REVISION}" \ + -refspec="${PARAM_REFSPEC}" \ + -path="${CHECKOUT_DIR}" \ + -sslVerify="${PARAM_SSL_VERIFY}" \ + -submodules="${PARAM_SUBMODULES}" \ + -depth="${PARAM_DEPTH}" \ + -sparseCheckoutDirectories="${PARAM_SPARSE_CHECKOUT_DIRECTORIES}" + cd "${CHECKOUT_DIR}" + RESULT_SHA="$(git rev-parse HEAD)" + EXIT_CODE="$?" + if [ "${EXIT_CODE}" != 0 ] ; then + exit "${EXIT_CODE}" + fi + printf "%s" "${RESULT_SHA}" > "$(results.commit.path)" + printf "%s" "${PARAM_URL}" > "$(results.url.path)" diff --git a/cicd/templates/dep/helm-upgrade-from-source.yaml b/cicd/templates/dep/helm-upgrade-from-source.yaml new file mode 100644 index 0000000..7bf3c4a --- /dev/null +++ b/cicd/templates/dep/helm-upgrade-from-source.yaml @@ -0,0 +1,60 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: helm-upgrade-from-source + labels: + app.kubernetes.io/version: "0.3" + annotations: + tekton.dev/pipelines.minVersion: "0.12.1" + tekton.dev/categories: Deployment + tekton.dev/tags: helm + tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le,linux/arm64" +spec: + description: >- + These tasks will install / upgrade a helm chart into your Kubernetes / + OpenShift Cluster using Helm + + params: + - name: charts_dir + description: The directory in source that contains the helm chart + - name: release_version + description: The helm release version in semantic versioning format + default: "v1.0.0" + - name: release_name + description: The helm release name + default: "helm-release" + - name: release_namespace + description: The helm release namespace + default: "" + - name: overwrite_values + description: "Specify the values you want to overwrite, comma separated: autoscaling.enabled=true,replicas=1" + default: "" + - name: values_file + description: "The values file to be used" + default: "values.yaml" + - name: helm_image + description: "helm image to be used" + default: "docker.io/lachlanevenson/k8s-helm:v3.10.2" #tag: v3.6.0 + - name: upgrade_extra_params + description: "Extra parameters passed for the helm upgrade command" + default: "" + workspaces: + - name: source + - name: kubeconfig-dir + optional: true + steps: + - name: upgrade + image: $(params.helm_image) + workingDir: /workspace/source + script: | + echo "Setting up kubeconfig..." + [[ "$(workspaces.kubeconfig-dir.bound)" == "true" ]] && \ + [[ -f $(workspaces.kubeconfig-dir.path)/kubeconfig ]] && \ + export KUBECONFIG=$(workspaces.kubeconfig-dir.path)/kubeconfig + echo "Setting up variables..." + release_name="$(echo '$(params.release_name)' | tr '[:upper:]' '[:lower:]')" + echo "Release name: $release_name" + echo "Getting helm dependencies..." + helm dependency build "$(params.charts_dir)" + echo "installing helm chart..." + helm upgrade --install --wait --values "$(params.charts_dir)/$(params.values_file)" --namespace "$(params.release_namespace)" --version "$(params.release_version)" "$release_name" "$(params.charts_dir)" --debug --set "$(params.overwrite_values)" $(params.upgrade_extra_params) diff --git a/cicd/templates/dep/kubernetes-action.yaml b/cicd/templates/dep/kubernetes-action.yaml new file mode 100644 index 0000000..10cde71 --- /dev/null +++ b/cicd/templates/dep/kubernetes-action.yaml @@ -0,0 +1,54 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: kubernetes-actions + labels: + app.kubernetes.io/version: "0.2" + annotations: + tekton.dev/pipelines.minVersion: "0.17.0" + tekton.dev/categories: Kubernetes + tekton.dev/tags: CLI, kubectl + tekton.dev/displayName: "kubernetes actions" + tekton.dev/platforms: "linux/amd64" +spec: + description: >- + This task is the generic kubectl CLI task which can be used + to run all kinds of k8s commands + workspaces: + - name: manifest-dir + optional: true + - name: kubeconfig-dir + optional: true + results: + - name: output-result + description: some result can be emitted if someone wants to. + params: + - name: script + description: The Kubernetes CLI script to run + type: string + default: "kubectl $@" + - name: args + description: The Kubernetes CLI arguments to run + type: array + default: + - "help" + - name: image + default: gcr.io/cloud-builders/kubectl@sha256:8ab94be8b2b4f3d117f02d868b39540fddd225447abf4014f7ba4765cb39f753 #image is huge + description: Kubectl wrapper image + steps: + - name: kubectl + image: $(params.image) + script: | + #!/usr/bin/env bash + + [[ "$(workspaces.manifest-dir.bound)" == "true" ]] && \ + cd $(workspaces.manifest-dir.path) + + [[ "$(workspaces.kubeconfig-dir.bound)" == "true" ]] && \ + [[ -f $(workspaces.kubeconfig-dir.path)/kubeconfig ]] && \ + export KUBECONFIG=$(workspaces.kubeconfig-dir.path)/kubeconfig + + $(params.script) + + args: + - "$(params.args)" diff --git a/cicd/templates/dep/sonarqube.yaml b/cicd/templates/dep/sonarqube.yaml new file mode 100644 index 0000000..3483a8c --- /dev/null +++ b/cicd/templates/dep/sonarqube.yaml @@ -0,0 +1,179 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: sonarqube-scanner + labels: + app.kubernetes.io/version: "0.5" + annotations: + tekton.dev/pipelines.minVersion: "0.17.0" + tekton.dev/categories: Security + tekton.dev/tags: security + tekton.dev/displayName: "sonarqube scanner" + tekton.dev/platforms: "linux/amd64" +spec: + description: >- + The following task can be used to perform static analysis on the source code + provided the SonarQube server is hosted + + SonarQube is the leading tool for continuously inspecting the Code Quality and Security + of your codebases, all while empowering development teams. Analyze over 25 popular + programming languages including C#, VB.Net, JavaScript, TypeScript and C++. It detects + bugs, vulnerabilities and code smells across project branches and pull requests. + This version has been tweeked in order to handle the token authentication method. + + workspaces: + - name: source + description: "Workspace containing the code which needs to be scanned by SonarQube" + - name: sonar-settings + description: "Optional workspace where SonarQube properties can be mounted" + optional: true + - name: sonar-credentials + description: | + A workspace containing a login or password for use within sonarqube. + optional: true + params: + - name: SONAR_HOST_URL + description: SonarQube server URL + default: "" + - name: SONAR_PROJECT_KEY + description: Project's unique key + default: "" + - name: PROJECT_VERSION + description: "Version of the project. Default: 1.0" + default: "1.0" + - name: SOURCE_TO_SCAN + description: "Comma-separated paths to directories containing main source files" + default: "." + - name: SONAR_ORGANIZATION + description: "The organization in sonarqube where the project exists" + default: "" + - name: SONAR_SCANNER_IMAGE + description: "The sonarqube scanner CLI image which will run the scan" + default: "docker.io/sonarsource/sonar-scanner-cli:4.6@sha256:7a976330a8bad1beca6584c1c118e946e7a25fdc5b664d5c0a869a6577d81b4f" + - name: SONAR_LOGIN_KEY + description: Name of the file of the login within the sonarqube credentials workspace + default: "login" + - name: SONAR_PASSWORD_KEY + description: Name of the file of the password within the sonarqube credentials workspace + default: "password" + - name: SONAR_TOKEN_KEY + description: Name of the file of the token within the sonarqube credentials workspace + default: "token" + steps: + - name: sonar-properties-create + image: registry.access.redhat.com/ubi8/ubi-minimal:8.2 + workingDir: $(workspaces.source.path) + env: + - name: SONAR_HOST_URL + value: $(params.SONAR_HOST_URL) + - name: SONAR_PROJECT_KEY + value: $(params.SONAR_PROJECT_KEY) + - name: PROJECT_VERSION + value: $(params.PROJECT_VERSION) + - name: SOURCE_TO_SCAN + value: $(params.SOURCE_TO_SCAN) + - name: SONAR_ORGANIZATION + value: $(params.SONAR_ORGANIZATION) + script: | + #!/usr/bin/env bash + + replaceValues() { + filename=$1 + thekey=$2 + newvalue=$3 + + if ! grep -R "^[#]*\s*${thekey}=.*" $filename >/dev/null; then + echo "APPENDING because '${thekey}' not found" + echo "" >>$filename + echo "$thekey=$newvalue" >>$filename + else + echo "SETTING because '${thekey}' found already" + sed -ir "s|^[#]*\s*${thekey}=.*|$thekey=$newvalue|" $filename + fi + } + + if [[ "$(workspaces.sonar-settings.bound)" == "true" ]]; then + if [[ -f $(workspaces.sonar-settings.path)/sonar-project.properties ]]; then + echo "using user provided sonar-project.properties file" + cp -RL $(workspaces.sonar-settings.path)/sonar-project.properties $(workspaces.source.path)/sonar-project.properties + fi + fi + + if [[ -f $(workspaces.source.path)/sonar-project.properties ]]; then + if [[ -n "${SONAR_HOST_URL}" ]]; then + echo "replacing sonar host URL" + replaceValues $(workspaces.source.path)/sonar-project.properties sonar.host.url "${SONAR_HOST_URL}" + fi + if [[ -n "${SONAR_PROJECT_KEY}" ]]; then + echo "replacing sonar project key" + replaceValues $(workspaces.source.path)/sonar-project.properties sonar.projectKey "${SONAR_PROJECT_KEY}" + fi + echo "Values in sonar-project.properties file replaced successfully..." + else + echo "Creating sonar-project.properties file..." + touch sonar-project.properties + [[ -n "${SONAR_PROJECT_KEY}" ]] && { + echo "sonar.projectKey=${SONAR_PROJECT_KEY}" >> sonar-project.properties + } || { + echo "missing property SONAR_PROJECT_KEY" + exit 1 + } + + [[ -n "${SONAR_HOST_URL}" ]] && { + echo "sonar.host.url=${SONAR_HOST_URL}" >> sonar-project.properties + } || { + echo "missing property SONAR_HOST_URL" + exit 1 + } + + [[ -n "${PROJECT_VERSION}" ]] && { + echo "sonar.projectVersion=${PROJECT_VERSION}" >> sonar-project.properties + } || { + echo "missing property PROJECT_VERSION" + exit 1 + } + + [[ -n "${SONAR_ORGANIZATION}" ]] && { + echo "sonar.organization=${SONAR_ORGANIZATION}" >> sonar-project.properties + } || { + echo "missing property SONAR_ORGANIZATION" + exit 1 + } + echo "sonar.sources=${SOURCE_TO_SCAN}" >> sonar-project.properties + echo "---------------------------" + cat $(workspaces.source.path)/sonar-project.properties + fi + + if [[ "$(workspaces.sonar-credentials.bound)" == "true" ]]; then + if [[ -f $(workspaces.sonar-credentials.path)/$(params.SONAR_PASSWORD_KEY) ]]; then + SONAR_PASSWORD=`cat $(workspaces.sonar-credentials.path)/$(params.SONAR_PASSWORD_KEY)` + replaceValues $(workspaces.source.path)/sonar-project.properties sonar.password "${SONAR_PASSWORD}" + fi + if [[ -f $(workspaces.sonar-credentials.path)/$(params.SONAR_LOGIN_KEY) ]]; then + SONAR_LOGIN=`cat $(workspaces.sonar-credentials.path)/$(params.SONAR_LOGIN_KEY)` + replaceValues $(workspaces.source.path)/sonar-project.properties sonar.login "${SONAR_LOGIN}" + fi + if [[ -f $(workspaces.sonar-credentials.path)/$(params.SONAR_TOKEN_KEY) ]]; then + SONAR_TOKEN=`cat $(workspaces.sonar-credentials.path)/$(params.SONAR_TOKEN_KEY)` + replaceValues $(workspaces.source.path)/sonar-project.properties sonar.token "${SONAR_TOKEN}" + replaceValues $(workspaces.source.path)/sonar-project.properties sonar.login "${SONAR_TOKEN}" + fi + fi + {{- if .Values.config.sonarqube.additionalScript.enabled}} + - name: prepare-cli + image: {{ .Values.config.sonarqube.additionalScript.image}} + workingDir: $(workspaces.source.path) + command: + - /bin/sh + args: + - -c + - | + {{- .Values.config.sonarqube.additionalScript.script | nindent 10}} + {{- end}} + - name: sonar-scan + image: $(params.SONAR_SCANNER_IMAGE) + workingDir: $(workspaces.source.path) + command: + - sonar-scanner + +# TODO: mise en place result https://tekton.dev/docs/pipelines/tasks/#emitting-results https://tekton.dev/docs/pipelines/pipelines/#adding-finally-to-the-pipeline \ No newline at end of file diff --git a/cicd/templates/dep/task.build.yaml b/cicd/templates/dep/task.build.yaml new file mode 100644 index 0000000..828442a --- /dev/null +++ b/cicd/templates/dep/task.build.yaml @@ -0,0 +1,56 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: build +spec: + description: | + This task builds all dockerfile in a repo based on a yaml file. + workspaces: + - name: shared-data + description: | + This workspace contains the cloned repo files, so they can be read by the + next task. + - name: dockerconfig + description: | + This workspace contains the docker config.json file, so it can be used by + the next task. + params: + - name: registrydns + type: string + description: The registry dns name. + default: harbor.weebo.fr + - name: buildctl_tcp + type: string + description: The buildctl tcp address. + default: tcp://buildkitd.buildkit.svc.cluster.local:1234 + - name: repo-branch + type: string + description: The git repo branch to clone from. + default: main + - name: path-dockerfile + type: string + description: The folder where the dockerfile are. + default: . + - name: context-dockerfile + type: string + description: The context where the dockerfile are. + default: . + - name: DOCKERFILE + type: string + description: The dockerfile to build. + default: Dockerfile + - name: IMAGE + type: string + description: The image name to build (repo/imagename). + steps: + - image: harbor.weebo.fr/cache/moby/buildkit:v0.11.4 + name: build-all + env: + - name: DOCKER_CONFIG + value: $(workspaces.dockerconfig.path) + workingDir: $(workspaces.shared-data.path) + script: | + #!/usr/bin/env ash + buildctl --addr $(params.buildctl_tcp) build --progress=plain --frontend dockerfile.v0 --local context=$(params.context-dockerfile) --local dockerfile=$(params.path-dockerfile) --opt filename=$(params.DOCKERFILE) --output type=image,name=$(params.registrydns)/$(params.IMAGE):$(params.repo-branch),push=true + +# https://tekton.dev/docs/pipelines/tasks/#specifying-workspaces diff --git a/cicd/templates/eventListener.yaml b/cicd/templates/eventListener.yaml new file mode 100644 index 0000000..b49e23c --- /dev/null +++ b/cicd/templates/eventListener.yaml @@ -0,0 +1,34 @@ +apiVersion: triggers.tekton.dev/v1alpha1 +kind: EventListener +metadata: + name: {{.Values.config.prefix}}-event-listener +spec: + serviceAccountName: {{.Values.config.prefix}}-sa + triggers: + - name: {{.Values.config.prefix}}-trigger + interceptors: + - ref: + name: "gitea" + kind: ClusterInterceptor + apiVersion: triggers.tekton.dev + params: + - name: secretRef + value: + secretName: {{.Values.config.prefix}}-gitea-secret + secretKey: secretToken + - name: eventTypes + value: + - push + - ref: + name: "cel" + params: + - name: filter + value: "body.ref.startsWith('refs/heads/')" + - name: overlays + value: + - key: branch_name + expression: "body.ref.split('/')[2]" + bindings: + - ref: {{.Values.config.prefix}}-trigger-binding + template: + ref: {{.Values.config.prefix}}-pipeline-template diff --git a/cicd/templates/ingress.yaml b/cicd/templates/ingress.yaml new file mode 100644 index 0000000..0690c41 --- /dev/null +++ b/cicd/templates/ingress.yaml @@ -0,0 +1,20 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: "{{.Values.config.prefix}}-webhook" + annotations: + nginx.ingress.kubernetes.io/ssl-redirect: "false" + haproxy-ingress.github.io/ssl-redirect: "false" + kubernetes.io/ingress.class: "{{.Values.config.ingress.class}}" +spec: + rules: + - host: "{{.Values.config.ingress.domain}}" + http: + paths: + - path: "/{{.Values.config.name}}/{{.Values.config.prefix}}" + pathType: Exact + backend: + service: + name: "el-{{.Values.config.prefix}}-event-listener" + port: + number: 8080 diff --git a/cicd/templates/job-kubeconfig.yaml b/cicd/templates/job-kubeconfig.yaml new file mode 100644 index 0000000..ab7a1a3 --- /dev/null +++ b/cicd/templates/job-kubeconfig.yaml @@ -0,0 +1,43 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: "terra-job" + labels: + app.kubernetes.io/managed-by: "{{ .Release.Service }}" + app.kubernetes.io/instance: "{{ .Release.Name }}" + app.kubernetes.io/version: "{{ .Chart.AppVersion }}" + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" +spec: + schedule: "0 0 1 * *" + jobTemplate: + spec: + template: + metadata: + name: "{{ .Release.Name }}" + labels: + app.kubernetes.io/managed-by: "{{ .Release.Service }}" + app.kubernetes.io/instance: "{{ .Release.Name }}" + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + spec: + restartPolicy: Never + serviceAccountName: "{{.Values.config.prefix}}-sa" + containers: + - name: apply-terraform + image: hashicorp/terraform:latest + imagePullPolicy: IfNotPresent + command: + - /bin/sh + - -c + - cd /terraform && touch anotherNAmeThatsoudnothing.tf && rm *.tf && cp /app/*.tf . && terraform init && terraform apply -auto-approve + volumeMounts: + - name: terra-job + mountPath: /terraform + - name: terraform-sa + mountPath: /app/ + volumes: + - name: terra-job + persistentVolumeClaim: + claimName: terra-job + - name: terraform-sa + configMap: + name: terraform-sa diff --git a/cicd/templates/job-volume.yaml b/cicd/templates/job-volume.yaml new file mode 100644 index 0000000..ff4b8ff --- /dev/null +++ b/cicd/templates/job-volume.yaml @@ -0,0 +1,11 @@ +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: terra-job +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: local-path diff --git a/cicd/templates/pipeline.yaml b/cicd/templates/pipeline.yaml new file mode 100644 index 0000000..d35f932 --- /dev/null +++ b/cicd/templates/pipeline.yaml @@ -0,0 +1,111 @@ +apiVersion: tekton.dev/v1beta1 +kind: Pipeline +metadata: + name: {{.Values.config.prefix}}-pipeline +spec: + ## TODO https://tekton.dev/docs/pipelines/pipelines/#using-execution-status-of-pipelinetask + description: | + This pipeline builds batleforc template-rust. + params: + - name: repo-url + type: string + description: The git repo URL to clone from. + - name: repo-branch + type: string + default: main + description: The git repo branch to clone from. + - name: repo-revision + type: string + default: main + description: The git repo revision to clone from. + workspaces: + - name: shared-data + description: | + This workspace contains the cloned repo files, so they can be read by the + next task. + - name: dockerconfig + description: | + This workspace contains the docker config.json file, so it can be used by + the next task. + - name: kubeconfig + description: | + This workspace contains the kubeconfig file, it define the namespace to rollout. + {{- if .Values.config.sonarqube.useToken }} + - name: sonarqube + description: | + This workspace contains the sonarqube credentials. + {{- end }} + tasks: + - name: fetch-source + taskRef: + name: git-clone + workspaces: + - name: output + workspace: shared-data + params: + - name: url + value: $(params.repo-url) + - name: revision + value: $(params.repo-revision) + - name: build-docker + runAfter: ["fetch-source"] + taskRef: + name: build + workspaces: + - name: shared-data + workspace: shared-data + - name: dockerconfig + workspace: dockerconfig + params: + - name: path-dockerfile + value: . + - name: context-dockerfile + value: . + - name: IMAGE + value: {{.Values.config.registry.imageName}} + - name: repo-branch + value: $(params.repo-branch) + {{ if .Values.config.sonarqube.enabled }} + - name: sonarqube-scan + runAfter: ["build-docker"] + taskRef: + name: sonarqube-scanner + workspaces: + - name: source + workspace: shared-data + {{ if .Values.config.sonarqube.useToken }} + - name: sonar-credentials + workspace: sonarqube + {{ end }} + params: + - name: SONAR_HOST_URL + value: {{.Values.config.sonarqube.host}} + - name: SONAR_SCANNER_IMAGE + value: {{.Values.config.sonarqube.image}} + {{ if .Values.config.sonarqube.useToken }} + - name: SONAR_TOKEN_KEY + value: token + {{ end }} + {{ end }} + - name: helm-upgrade + {{ if .Values.config.sonarqube.enabled }} + runAfter: ["sonarqube-scan"] + {{ else }} + runAfter: ["build-docker"] + {{ end }} + taskRef: + name: helm-upgrade-from-source + workspaces: + - name: source + workspace: shared-data + - name: kubeconfig-dir + workspace: kubeconfig + params: + - name: charts_dir + value: ./chart + - name: release_name + value: $(params.repo-branch) + - name: release_namespace + value: {{.Release.Namespace}} + - name: overwrite_values + value: "image.tag=$(params.repo-branch)" \ No newline at end of file diff --git a/cicd/templates/rbac.yaml b/cicd/templates/rbac.yaml new file mode 100644 index 0000000..63048a0 --- /dev/null +++ b/cicd/templates/rbac.yaml @@ -0,0 +1,74 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{.Values.config.prefix}}-sa +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{.Values.config.prefix}}-sa +rules: + - apiGroups: ["apps"] + resources: ["deployments", "statefulsets", "daemonsets", "replicasets"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: [""] + resources: ["services"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{.Values.config.prefix}}-sa +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{.Values.config.prefix}}-sa +subjects: + - kind: ServiceAccount + name: {{.Values.config.prefix}}-sa +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{.Values.config.prefix}}-sa-binding-2 +subjects: + - kind: ServiceAccount + name: {{.Values.config.prefix}}-sa + namespace: {{.Release.Namespace}} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: tekton-triggers-eventlistener-roles +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{.Values.config.prefix}}-sa-clusterbinding +subjects: + - kind: ServiceAccount + name: {{.Values.config.prefix}}-sa + namespace: {{.Release.Namespace}} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: tekton-triggers-eventlistener-clusterroles +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{.Values.config.prefix}}-sa + annotations: + kubernetes.io/service-account.name: {{.Values.config.prefix}}-sa +type: kubernetes.io/service-account-token diff --git a/cicd/templates/terraform-sa.yaml b/cicd/templates/terraform-sa.yaml new file mode 100644 index 0000000..e2a6afd --- /dev/null +++ b/cicd/templates/terraform-sa.yaml @@ -0,0 +1,61 @@ +# Configmap containing Terraform file +apiVersion: v1 +kind: ConfigMap +metadata: + name: terraform-sa +data: + main.tf: | + terraform { + required_providers { + harbor = { + source = "goharbor/harbor" + version = "3.9.4" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = "2.22.0" + } + } + } + + variable "kubepath" { + type = string + default = "/var/run/secrets/kubernetes.io/serviceaccount" + } + + provider "kubernetes" { + host = "https://kubernetes.default.svc" + token = file("${var.kubepath}/token") + cluster_ca_certificate = file("${var.kubepath}/ca.crt") + } + + resource "kubernetes_secret_v1" "kubeconfig" { + metadata { + name = "kubeconfig" + namespace = "{{.Release.Namespace}}" + } + data = { + "kubeconfig" = <- + ${base64encode(file("${var.kubepath}/ca.crt"))} + users: + - name: tpl + user: + token: >- + ${file("${var.kubepath}/token")} + contexts: + - name: tpl + context: + user: tpl + cluster: tpl + namespace: {{.Release.Namespace}} + current-context: tpl + EOF + } + } diff --git a/cicd/templates/triggerBinding.yaml b/cicd/templates/triggerBinding.yaml new file mode 100644 index 0000000..186be5c --- /dev/null +++ b/cicd/templates/triggerBinding.yaml @@ -0,0 +1,12 @@ +apiVersion: triggers.tekton.dev/v1alpha1 +kind: TriggerBinding +metadata: + name: {{.Values.config.prefix}}-trigger-binding +spec: + params: + - name: gitrepositoryurl + value: $(body.repository.clone_url) + - name: gitrevision + value: $(body.head_commit.id) + - name: gitbranch + value: $(extensions.branch_name) diff --git a/cicd/templates/triggerTemplate.yaml b/cicd/templates/triggerTemplate.yaml new file mode 100644 index 0000000..18217db --- /dev/null +++ b/cicd/templates/triggerTemplate.yaml @@ -0,0 +1,50 @@ +apiVersion: triggers.tekton.dev/v1alpha1 +kind: TriggerTemplate +metadata: + name: {{.Values.config.prefix}}-pipeline-template +spec: + params: + - name: gitrevision + description: The git revision (SHA) + default: master + - name: gitbranch + description: The git branch + default: master + - name: gitrepositoryurl + description: The git repository url ("https://github.com/batleforc/rust-template") + resourcetemplates: + - apiVersion: tekton.dev/v1beta1 + kind: PipelineRun + metadata: + generateName: {{.Values.config.prefix}}-pipeline-run- + spec: + pipelineRef: + name: {{.Values.config.prefix}}-pipeline + workspaces: + - name: shared-data + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi + storageClassName: local-path + - name: dockerconfig + secret: + secretName: harbor-auth + - name: kubeconfig + secret: + secretName: kubeconfig + {{- if .Values.config.sonarqube.useToken }} + - name: sonarqube + secret: + secretName: tpl-bu-sonarqube + {{ end }} + params: + - name: repo-revision + value: $(tt.params.gitrevision) + - name: repo-branch + value: $(tt.params.gitbranch) + - name: repo-url + value: $(tt.params.gitrepositoryurl) diff --git a/cicd/values.yaml b/cicd/values.yaml new file mode 100644 index 0000000..5fe7d76 --- /dev/null +++ b/cicd/values.yaml @@ -0,0 +1,24 @@ +config: + prefix: botdiscord + name: batleforc + ingress: + class: haproxy + domain: webhook.weebo.fr + registry: + imageName: batleforc/botdiscord + sonarqube: + enabled: false + host: https://qube.weebo.fr + image: harbor.weebo.fr/sonar/rust:v1.17.12 + useToken: false + additionalScript: + enabled: false + image: harbor.weebo.fr/sonar/rust:v1.17.12-prepare + script: | + set -x + git config --global --add safe.directory /workspace/source + git fetch --unshallow + cargo clippy --message-format=json > clippy-report.json + cargo audit --json > audit-report.json + cargo outdated --depth 1 --format json > outdated-report.json + cargo sonar --clippy --clippy-path clippy-report.json --audit --audit-path audit-report.json --outdated --outdated-path outdated-report.json diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..c47af38 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,10 @@ +sonar.projectKey=BotDiscord +sonar.projectname=botdiscord +sonar.projectversion=1.0 +sonar.sources=. +sonar.projectDescription=Bot Discord +sonar.links.homepage=https://git.weebo.fr/sandbox/BotDiscord +sonar.links.ci=https://cicd.weebo.fr/#/namespaces/bot-discord/pipelineruns +sonar.externalIssuesReportPaths=sonar-issues.json +#community.rust.clippy.reportPaths=clippy-report.json +sonar.exclusions=deploy/**,compose.yaml,devfile.yaml,cog.toml \ No newline at end of file