diff --git a/chartmuseum-config/chartmuseum-secret.yaml b/chartmuseum-config/chartmuseum-secret.yaml new file mode 100644 index 0000000..02a5d02 --- /dev/null +++ b/chartmuseum-config/chartmuseum-secret.yaml @@ -0,0 +1,11 @@ +#secret for basic auth +apiVersion: v1 +kind: Secret +metadata: + name: chartmuseum-secret + namespace: chartmuseum +type: Opaque +stringData: + CHARTMUSEUM_USERNAME: "chartmuseum_username" + CHARTMUSEUM_PASSWORD: "chartmuseum_password" + diff --git a/chartmuseum/Chart.yaml b/chartmuseum/Chart.yaml new file mode 100644 index 0000000..7ce59a6 --- /dev/null +++ b/chartmuseum/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 +name: chartmuseum +description: Install chartmuseum on Openshift clusters +# 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.0 \ No newline at end of file diff --git a/chartmuseum/templates/chartmuseum.yaml b/chartmuseum/templates/chartmuseum.yaml new file mode 100644 index 0000000..829994c --- /dev/null +++ b/chartmuseum/templates/chartmuseum.yaml @@ -0,0 +1,37 @@ +{{- $relname := .Release.Name -}} +{{- $targetNamespace := .Values.argocdConfig.targetNamespace -}} +{{- $project := .Values.argocdConfig.project.name -}} +{{- $repourl := .Values.chartmuseum.repository.url -}} +{{- $repoversion := .Values.chartmuseum.repository.version -}} +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: "{{ $relname }}-chartmuseum" + +spec: + generators: +{{ toYaml .Values.argocdConfig.generators | nindent 4 }} + + template: + metadata: + name: 'chartmuseum-{{ "{{" }}name{{ "}}" }}' + spec: + destination: + namespace: 'chartmuseum' + server: '{{ "{{" }}server{{ "}}" }}' + project: '{{ $project }}' + source: + repoURL: 'https://chartmuseum.github.io/charts' #'{{ $repourl }}' + targetRevision: '{{ $repoversion }}' + chart: chartmuseum + + helm: + releaseName: 'chartmuseum' + values: | +{{ toYaml .Values.chartmuseum.config | indent 12 }} + + syncPolicy: + automated: + prune: true + syncOptions: + - CreateNamespace=true diff --git a/chartmuseum/values.yaml b/chartmuseum/values.yaml new file mode 100644 index 0000000..2947cd2 --- /dev/null +++ b/chartmuseum/values.yaml @@ -0,0 +1,43 @@ +chartmuseum: + repository: + version: 3.1.0 + config: + env: + open: + # storage backend, can be one of: local, alibaba, amazon, google, microsoft, oracle + STORAGE: local + DISABLE_API: false + # allow anonymous GET operations when auth is used + AUTH_ANONYMOUS_GET: false + # enable bearer auth + BEARER_AUTH: false + # auth realm used for bearer auth + AUTH_REALM: + # auth service used for bearer auth + AUTH_SERVICE: + existingSecret: chartmuseum-secret + existingSecretMappings: + # username for basic http authentication + BASIC_AUTH_USER: CHARTMUSEUM_USERNAME + # password for basic http authentication + BASIC_AUTH_PASS: CHARTMUSEUM_PASSWORD + bearerAuth: + secret: + enabled: false + publicKeySecret: chartmuseum-public-key + securityContext: + enabled: true + fsGroup: null + runAsNonRoot: true + persistence: + enabled: true + accessMode: ReadWriteOnce + size: 8Gi + storageClass: "gp2" + + +argocdConfig: + generators: [] + project: + create: false + name: default diff --git a/helm-pipelines/Chart.yaml b/helm-pipelines/Chart.yaml new file mode 100644 index 0000000..b9a3363 --- /dev/null +++ b/helm-pipelines/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 +name: helm-pipelines +description: Install all the necessary ressources to automate helm charts pipeline on Openshift clusters +# 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.0 \ No newline at end of file diff --git a/README.md b/helm-pipelines/README.md similarity index 98% rename from README.md rename to helm-pipelines/README.md index 255a84b..29a76cf 100644 --- a/README.md +++ b/helm-pipelines/README.md @@ -1,4 +1,4 @@ -# helm-pipelines +# helm-pipelines ## ARGO helm package registry diff --git a/helm-pipelines/templates/event-source/github-route.yaml b/helm-pipelines/templates/event-source/github-route.yaml new file mode 100644 index 0000000..3a11f45 --- /dev/null +++ b/helm-pipelines/templates/event-source/github-route.yaml @@ -0,0 +1,20 @@ + {{- if eq .Values.github.webhook.route "true" }} +kind: Route +apiVersion: route.openshift.io/v1 +metadata: + name: {{ .Release.Name }}-github-event + labels: + app.kubernetes.io/instance: helm-pipeline + controller: eventsource-controller + eventsource-name: {{ .Release.Name }}-github-events + +spec: + host: {{ .Values.github.webhook.url }} + to: + kind: Service + name: {{ .Release.Name }}-github-events-eventsource-svc + weight: 100 + port: + targetPort: 12000 + wildcardPolicy: None + {{- end }} diff --git a/helm-pipelines/templates/event-source/github.yaml b/helm-pipelines/templates/event-source/github.yaml new file mode 100644 index 0000000..7c4ecbf --- /dev/null +++ b/helm-pipelines/templates/event-source/github.yaml @@ -0,0 +1,105 @@ +# Info on GitHub Webhook: https://developer.github.com/v3/repos/hooks/#create-a-hook +apiVersion: argoproj.io/v1alpha1 +kind: EventSource +metadata: + name: {{ .Release.Name }}-github-events +spec: + eventBusName: {{ if eq .Values.eventbus.enabled "true" }}{{ .Release.Name }}-default{{ else }}{{ .Values.eventbus.eventbusName }}{{ end }} + service: + ports: + - port: 12000 + targetPort: 12000 + github: + push: + repositories: + - owner: {{ .Values.github.repository.owner }} + names: + - {{ .Values.github.repository.name }} + # Github will send events to following port and endpoint + webhook: + # endpoint to listen to events on + endpoint: /push + # port to run internal HTTP server on + port: "12000" + # HTTP request method to allow. In this case, only POST requests are accepted + method: POST + # url the event-source will use to register at Github. + # This url must be reachable from outside the cluster. + # The name for the service is in `-eventsource-svc` format. + # You will need to create an Ingress or Openshift Route for the event-source service so that it can be reached from GitHub. + url: http://{{ .Values.github.webhook.url }} + # type of events to listen to. + # following listens to everything, hence * + # You can find more info on https://developer.github.com/v3/activity/events/types/ + events: + - "push" + - "pull_request" + # apiToken refers to K8s secret that stores the github api token + # if apiToken is provided controller will create webhook on GitHub repo + # +optional + apiToken: + # Name of the K8s secret that contains the access token + name: git-secret + # Key within the K8s secret whose corresponding value (must be base64 encoded) is access token + key: GIT_TOKEN + +# # webhookSecret refers to K8s secret that stores the github hook secret +# # +optional +# webhookSecret: +# # Name of the K8s secret that contains the hook secret +# name: github-access +# # Key within the K8s secret whose corresponding value (must be base64 encoded) is hook secret +# key: secret + + # type of the connection between event-source and Github. + # You should set it to false to avoid man-in-the-middle and other attacks. + insecure: true + # Determines if notifications are sent when the webhook is triggered + active: true + # The media type used to serialize the payloads + contentType: json + +# example-without-api-credentials: +# owner: "argoproj" +# repository: "argo" +# webhook: +# endpoint: "/push" +# port: "13000" +# method: "POST" +# events: +# - "*" +# webhookSecret: +# name: github-access +# key: secret +# insecure: true +# active: true +# contentType: "json" + +# example-with-secure-connection: +# owner: "argoproj" +# repository: "argo" +# webhook: +# endpoint: "/push" +# port: "13000" +# method: "POST" +# url: "http://myargofakeurl.fake" +# # k8s secret that contains the cert +# serverCertSecret: +# name: my-secret +# key: cert-key +# # k8s secret that contains the private key +# serverKeySecret: +# name: my-secret +# key: pk-key +# events: +# - "push" +# - "delete" +# apiToken: +# name: github-access +# key: token +# webhookSecret: +# name: github-access +# key: secret +# insecure: true +# active: true +# contentType: "json" \ No newline at end of file diff --git a/helm-pipelines/templates/eventbus/eventBus.yaml b/helm-pipelines/templates/eventbus/eventBus.yaml new file mode 100644 index 0000000..b4c9756 --- /dev/null +++ b/helm-pipelines/templates/eventbus/eventBus.yaml @@ -0,0 +1,23 @@ + {{- if eq .Values.eventbus.enabled "true" }} +apiVersion: argoproj.io/v1alpha1 +kind: EventBus +metadata: + name: {{ .Release.Name }}-default +spec: + nats: + native: + # Optional, defaults to 3. If it is < 3, set it to 3, that is the minimal requirement. + replicas: {{ .Values.eventbus.replicas }} + # Optional, authen strategy, "none" or "token", defaults to "none" + auth: token + containerTemplate: +{{ toYaml .Values.eventbus.containerTemplate | indent 8 }} + +# metricsContainerTemplate: +# resources: +# requests: +# cpu: "10m" +# antiAffinity: false + persistence: +{{ toYaml .Values.eventbus.persistence | indent 8 }} + {{- end }} \ No newline at end of file diff --git a/helm-pipelines/templates/rbac/RBAC-default.yaml b/helm-pipelines/templates/rbac/RBAC-default.yaml new file mode 100644 index 0000000..dc81d1b --- /dev/null +++ b/helm-pipelines/templates/rbac/RBAC-default.yaml @@ -0,0 +1,39 @@ + {{- if eq .Values.rbac.default "true" }} +# Similarly you can use a Role and RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Release.Name }}-workflow-cluster-role +rules: + # pod get/watch is used to identify the container IDs of the current pod + # pod patch is used to annotate the step's outputs back to controller (e.g. artifact location) + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - watch + - patch + # logs get/watch are used to get the pods logs for script outputs, and for log archival + - apiGroups: + - "" + resources: + - pods/log + verbs: + - get + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ .Release.Name }}-workflow-role-cluster-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }}-workflow-cluster-role +subjects: + - kind: ServiceAccount + name: default + namespace: {{ .Release.Namespace }} + {{- end }} \ No newline at end of file diff --git a/helm-pipelines/templates/rbac/sa-sensor.yaml b/helm-pipelines/templates/rbac/sa-sensor.yaml new file mode 100644 index 0000000..4291186 --- /dev/null +++ b/helm-pipelines/templates/rbac/sa-sensor.yaml @@ -0,0 +1,65 @@ + {{- if eq .Values.rbac.operateWorkflow "true" }} +#sa used by the sensor to create workflows +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-operate-workflow-sa +--- +# Similarly you can use a Role and RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Release.Name }}-operate-workflow-cluster-role +rules: + - apiGroups: + - argoproj.io + verbs: + - "*" + resources: + - workflows + - workflowtemplates + - cronworkflows + - clusterworkflowtemplates + - apiGroups: + - "" + resources: + - namespaces + verbs: + - create + - get + - watch + - apiGroups: + - "rbac.authorization.k8s.io" + resources: + - rolebindings + verbs: + - create + - get + - watch + - apiGroups: + - "" + resources: + - secrets + verbs: + - create + - get + - watch + - apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterroles"] + verbs: ["bind"] + # omit resourceNames to allow binding any ClusterRole + resourceNames: ["{{ .Release.Name }}-workflow-cluster-role"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }}-operate-workflow-cluster-role-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }}-operate-workflow-cluster-role +subjects: + - kind: ServiceAccount + name: {{ .Release.Name }}-operate-workflow-sa + namespace: {{ .Release.Namespace }} + {{- end }} \ No newline at end of file diff --git a/helm-pipelines/templates/secrets/git-secret.yaml b/helm-pipelines/templates/secrets/git-secret.yaml new file mode 100644 index 0000000..8598450 --- /dev/null +++ b/helm-pipelines/templates/secrets/git-secret.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Secret +metadata: + name: git-secret + annotations: + vault.security.banzaicloud.io/vault-addr: '{{ .Values.vault.address }}' + vault.security.banzaicloud.io/vault-path: {{ .Values.vault.path }} + vault.security.banzaicloud.io/vault-role: {{ .Values.vault.role }} + vault.security.banzaicloud.io/vault-skip-verify: '{{ .Values.vault.skipVerify }}' +type: Opaque +stringData: + GIT_TOKEN: vault:{{ .Values.vault.secrets.git.location }}#{{ .Values.vault.secrets.git.gitToken }} \ No newline at end of file diff --git a/helm-pipelines/templates/sensor/github-push.yaml b/helm-pipelines/templates/sensor/github-push.yaml new file mode 100644 index 0000000..94b61fd --- /dev/null +++ b/helm-pipelines/templates/sensor/github-push.yaml @@ -0,0 +1,199 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Sensor +metadata: + name: {{ .Release.Name }}-github-push +spec: + eventBusName: {{ if eq .Values.eventbus.enabled "true" }}{{ .Release.Name }}-default{{ else }}{{ .Values.eventbus.eventbusName }}{{ end }} + template: + serviceAccountName: {{ if eq .Values.rbac.operateWorkflow "true" }}{{ .Release.Name }}-operate-workflow-sa{{ else }}{{ .Values.rbac.operateWorkflowSaName }}{{ end }} + dependencies: + - name: github-push-event + eventSourceName: {{ .Release.Name }}-github-events + eventName: push + filters: + data: + # Name of the event that triggered the delivery: [pull_request, push, yadayadayada] + # https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads + - path: body.X-GitHub-Event + type: string + value: + - push +# - path: body.ref +# type: string +# value: +# - refs/heads/{{ .Values.github.repository.branch }} + + + triggers: + - template: + name: main + k8s: + group: argoproj.io + version: v1alpha1 + resource: workflows + source: + resource: + + apiVersion: argoproj.io/v1alpha1 + kind: Workflow + metadata: + generateName: workflow-of-workflows- + spec: + serviceAccountName: helm-pipeline-operate-workflow-sa + entrypoint: main + podGC: + strategy: OnPodSuccess + + arguments: + parameters: + - name: git-branch + value: "git_branch" + - name: ns-name + value: "ns_name" + + templates: + - name: main + steps: + - - name: create-namespace + template: create-namespace + + - - name: create-secret + template: create-secret + + - - name: bind-cluster-role + template: bind-cluster-role + + - - name: launch-helm-pipeline + template: launch-helm-pipeline + + - name: create-namespace + resource: + action: create + manifest: | + apiVersion: v1 + kind: Namespace + metadata: + name: {{ .Release.Name }}-push-{{ "{{" }} workflow.parameters.ns-name {{ "}}" }} + labels: + app: helm-pipelines + successCondition: status.phase = Active + failureCondition: status.phase in (Failed, Error) + + - name: create-secret + resource: + action: create + manifest: | + apiVersion: v1 + kind: Secret + metadata: + name: {{ .Release.Name }}-secret + namespace: {{ .Release.Name }}-push-{{ "{{" }} workflow.parameters.ns-name {{ "}}" }} + annotations: + vault.security.banzaicloud.io/vault-addr: '{{ .Values.vault.address }}' + vault.security.banzaicloud.io/vault-path: {{ .Values.vault.path }} + vault.security.banzaicloud.io/vault-role: {{ .Values.vault.role }} + vault.security.banzaicloud.io/vault-skip-verify: '{{ .Values.vault.skipVerify }}' + type: Opaque + stringData: + GIT_TOKEN: vault:{{ .Values.vault.secrets.git.location }}#{{ .Values.vault.secrets.git.gitToken }} + CHARTMUSEUM_USERNAME: vault:{{ .Values.vault.secrets.chartmuseum.location }}#{{ .Values.vault.secrets.chartmuseum.chartmuseumUsername }} + CHARTMUSEUM_PASSWORD: vault:{{ .Values.vault.secrets.chartmuseum.location }}#{{ .Values.vault.secrets.chartmuseum.chartmuseumPassword }} + #OCI_USERNAME: vault:{{ .Values.vault.secrets.oci.location }}#{{ .Values.vault.secrets.oci.ociUsername }} + #OCI_PASSWORD: vault:{{ .Values.vault.secrets.oci.location }}#{{ .Values.vault.secrets.oci.ociPassword }} + successCondition: metadata.name = {{ .Release.Name }}-secret + #failureCondition: status.phase in (Failed, Error) + + - name: bind-cluster-role + resource: + action: create + manifest: | + apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: {{ .Release.Name }}-workflow-role-cluster-binding + namespace: {{ .Release.Name }}-push-{{ "{{" }} workflow.parameters.ns-name {{ "}}" }} + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }}-workflow-cluster-role + subjects: + - kind: ServiceAccount + name: default + namespace: {{ .Release.Name }}-push-{{ "{{" }} workflow.parameters.ns-name {{ "}}" }} + successCondition: metadata.name = {{ .Release.Name }}-workflow-role-cluster-binding + #failureCondition: status.phase in (Failed, Error) + + - name: launch-helm-pipeline + resource: + action: create + manifest: | + apiVersion: argoproj.io/v1alpha1 + kind: Workflow + metadata: + name: {{ .Release.Name }}-push-{{ "{{" }} workflow.parameters.ns-name {{ "}}" }} + namespace: {{ .Release.Name }}-push-{{ "{{" }} workflow.parameters.ns-name {{ "}}" }} + spec: + entrypoint: call-push-to-registry-template + + volumeClaimTemplates: + - metadata: + name: workdir + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 1Gi + + arguments: + parameters: + - name: git-owner + value: {{ .Values.github.repository.owner }} + + - name: git-repository + value: {{ .Values.github.repository.name }} + + - name: git-branch + value: {{ "{{" }} workflow.parameters.git-branch {{ "}}" }} + + - name: ns-name + value: "ns_name" + + - name: git-repository-type + value: {{ .Values.github.repository.type }} + + - name: git-path + value: {{ .Values.github.repository.path }} + + - name: registry-type + value: {{ .Values.registry.type }} + + - name: registry + value: {{ .Values.registry.url }} + + - name: chartname + value: "chart_name" + + templates: + - name: call-push-to-registry-template + dag: + tasks: + - name: call-push-to-registry-template + templateRef: + name: {{ .Release.Name }}-push-to-registry-template + template: helm-pipeline + clusterScope: true + + successCondition: status.phase == Succeeded + failureCondition: status.phase in (Failed, Error) + + + parameters: + - src: + dependencyName: github-push-event + dataTemplate: '{{ "{{" }} base .Input.body.ref {{ "}}" }}' + dest: spec.arguments.parameters.0.value + - src: + dependencyName: github-push-event + dataKey: body.after + dest: spec.arguments.parameters.1.value + \ No newline at end of file diff --git a/helm-pipelines/templates/workflow-template/workflow-template.yaml b/helm-pipelines/templates/workflow-template/workflow-template.yaml new file mode 100644 index 0000000..f9e26d8 --- /dev/null +++ b/helm-pipelines/templates/workflow-template/workflow-template.yaml @@ -0,0 +1,162 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ClusterWorkflowTemplate +metadata: + name: {{ .Release.Name }}-push-to-registry-template +spec: + arguments: + parameters: + + - name: git-owner + value: {{ .Values.github.repository.owner }} + + - name: git-repository + value: {{ .Values.github.repository.name }} + + - name: git-repository-type + value: {{ .Values.github.repository.type }} + + - name: git-url + value: "git_url" + + - name: git-path + value: {{ .Values.github.repository.path }} + + - name: registry-type + value: {{ .Values.registry.type }} + + - name: registry + value: {{ .Values.registry.url }} + + - name: chartname + value: "chart_name" + + + entrypoint: generate-token + volumeClaimTemplates: + - metadata: + name: workdir + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 1Gi + + templates: + - name: helm-pipeline + steps: + - - name: pull-repo + template: pull-repo + + - - name: oci-registry + template: oci-registry + when: "{{ "{{" }} workflow.parameters.registry-type {{ "}}" }} == oci_registry" + + - - name: helm-package + template: helm-package + when: "{{ "{{" }} workflow.parameters.registry-type {{ "}}" }} == chartmuseum" + + - - name: push-to-chartmuseum + template: push-to-chartmuseum + when: "{{ "{{" }} workflow.parameters.registry-type {{ "}}" }} == chartmuseum" + + - name: pull-repo + script: + image: bitnami/git:2.32.0 + imagePullPolicy: IfNotPresent + command: [bash] + source: | + if [[ {{ "{{" }} workflow.parameters.git-repository-type {{ "}}" }} == "private" ]] + then + cd /mnt/vol && git clone --branch {{ "{{" }} workflow.parameters.git-branch {{ "}}" }} https://$git_token:x-oauth-basic@github.com/{{ "{{" }} workflow.parameters.git-owner {{ "}}" }}/{{ "{{" }} workflow.parameters.git-repository {{ "}}" }}.git git-local-dir + else + cd /mnt/vol && git clone --branch {{ "{{" }} workflow.parameters.git-branch {{ "}}" }} https://github.com/{{ "{{" }} workflow.parameters.git-owner {{ "}}" }}/{{ "{{" }} workflow.parameters.git-repository {{ "}}" }}.git git-local-dir + fi + echo {{ "{{" }} workflow.parameters.git-path {{ "}}" }} > git-path.txt + + env: + - name: git_token + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-secret + key: GIT_TOKEN + volumeMounts: + - name: workdir + mountPath: /mnt/vol + + + - name: oci-registry + script: + image: alpine/helm:3.5.4 + imagePullPolicy: IfNotPresent + command: [sh] + source: | + export HELM_EXPERIMENTAL_OCI=1 + helm registry login {{ "{{" }} workflow.parameters.registry {{ "}}" }} --username $registry_username --password $registry_password + cd /mnt/vol/git-local-dir +# helm chart save . {{ "{{" }} workflow.parameters.chartname {{ "}}" }} +# helm chart push {{ "{{" }} workflow.parameters.chartname {{ "}}" }} + + env: + - name: registry_username + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-secret + key: OCI_USERNAME + - name: registry_password + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-secret + key: OCI_PASSWORD + volumeMounts: + - name: workdir + mountPath: /mnt/vol + + - name: helm-package + script: + image: alpine/helm:3.5.4 + imagePullPolicy: IfNotPresent + command: [sh] + source: | + cd /mnt/vol/git-local-dir + cat ../git-path.txt + for line in $(cat ../git-path.txt); do + if [[ -s "$line"/Chart.yaml ]]; then + cd "$line" + helm package . + cd .. + fi + done + + volumeMounts: + - name: workdir + mountPath: /mnt/vol + + - name: push-to-chartmuseum + script: + image: curlimages/curl + imagePullPolicy: IfNotPresent + command: [sh] + source: | + cd /mnt/vol/git-local-dir + for line in $(cat ../git-path.txt); do + if [[ -s "$line"/Chart.yaml ]]; then + cd "$line" + curl --user $registry_username:$registry_password --data-binary "@$(grep -A0 '^name:' ./Chart.yaml | awk '{ print $2}')-$(grep -A0 '^version:' ./Chart.yaml | awk '{ print $2}').tgz" {{ "{{" }} workflow.parameters.registry {{ "}}" }}/api/charts + cd .. + fi + done + + env: + - name: registry_username + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-secret + key: CHARTMUSEUM_USERNAME + - name: registry_password + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-secret + key: CHARTMUSEUM_PASSWORD + volumeMounts: + - name: workdir + mountPath: /mnt/vol diff --git a/helm-pipelines/values.yaml b/helm-pipelines/values.yaml new file mode 100644 index 0000000..b5b3791 --- /dev/null +++ b/helm-pipelines/values.yaml @@ -0,0 +1,52 @@ +github: + repository: + type: private # Can be private or public accordingly, private creds to be stored in a secret + owner: owner_of_repo + name: name_of_repo + path: path_to_helm_chart + + webhook: + # url the event-source will use to register at Github. + # This url must be reachable from outside the cluster. + url: github-event.apps.sandbox.thadvatys.com + route: "true" # if set to true, an openshift route will be created + +registry: + type: chartmuseum # Can be "aws", "private_registry" or "chartmuseum" + url: http://chartmuseum.apps.sandbox.thadvatys.com + +vault: + address: "http://vault.vault.svc.cluster.local:8200" + path: kubernetes + role: webhook + skipVerify: "true" + secrets: + git: + location: secret/data/git/config #git secrets' path in vault + gitToken: git_token_vault_key + chartmuseum: + location: secret/data/chartmuseum/config #chartmuseum secrets' path in vault + chartmuseumUsername: chartmuseum_username_vault_key + chartmuseumPassword: chartmuseum_password_vault_key + oci: + location: secret/data/oci/config #oci secrets' path in vault + ociUsername: oci_username_vault_key + ociPassword: oci_password_vault_key + +eventbus: + enabled: "true" + replicas: 3 + persistence: + storageClassName: gp2 + accessMode: ReadWriteOnce + volumeSize: 2Gi + containerTemplate: + resources: + requests: + cpu: "10m" + eventbusName: # Required if eventbus.enabled is set to false. Ignored otherwise. + +rbac: + default: "true" # grant namespace's default sa the privileges required by argo-workflow to watch pods and get logs. Set to false if already granted + operateWorkflow: "true" # create the sa and RBACs used by argo-events' sensor to create workflows. Set to false if already created. + operateWorkflowSaName: # Required if operateWorkflow is set to false. Ignored otherwise. \ No newline at end of file diff --git a/templates/events/event-bind.yaml b/templates/events/event-bind.yaml deleted file mode 100644 index 3379a84..0000000 --- a/templates/events/event-bind.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: WorkflowEventBinding -metadata: - name: event-bind-workflow -spec: - event: - selector: "true" - submit: - workflowTemplateRef: - name: push-to-registry-template diff --git a/templates/secrets/secret-role-binding.yaml b/templates/secrets/secret-role-binding.yaml deleted file mode 100644 index 9735fc3..0000000 --- a/templates/secrets/secret-role-binding.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: github.com -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: submit-workflow-template -subjects: - - kind: ServiceAccount - name: github.com diff --git a/templates/secrets/secret-svc.yaml b/templates/secrets/secret-svc.yaml deleted file mode 100644 index 7e42d02..0000000 --- a/templates/secrets/secret-svc.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: github.com diff --git a/templates/secrets/secret.yaml b/templates/secrets/secret.yaml deleted file mode 100644 index a848d04..0000000 --- a/templates/secrets/secret.yaml +++ /dev/null @@ -1,17 +0,0 @@ -kind: Secret -apiVersion: v1 -metadata: - name: argo-workflows-webhook-clients -stringData: - bitbucket.org: | - type: bitbucket - secret: "my-uuid" - bitbucketserver: | - type: bitbucketserver - secret: "shh!" - github.com: | - type: github - secret: "{ SECRET NEEDS TO BE PROVIDED }" - gitlab.com: | - type: gitlab - secret: "shh!" diff --git a/templates/workflow-template/secrets/aws-secret.yaml b/templates/workflow-template/secrets/aws-secret.yaml deleted file mode 100644 index 9959bac..0000000 --- a/templates/workflow-template/secrets/aws-secret.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: aws-secret -type: Opaque -stringData: - AWS_SECRET: "aws_secret_key" - AWS_ACCESS: "aws_accesss_key" - USERNAME: "registry_username" - PASSWORD: "registry_password" diff --git a/templates/workflow-template/secrets/git-secret.yaml b/templates/workflow-template/secrets/git-secret.yaml deleted file mode 100644 index ca9da12..0000000 --- a/templates/workflow-template/secrets/git-secret.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: git-secret -type: Opaque -stringData: - GIT_USERNAME: "git_username" - GIT_TOKEN: "git_token" - REPO_NAME: "repo_name" # Provide only the name of the repo diff --git a/templates/workflow-template/workflow-template.yaml b/templates/workflow-template/workflow-template.yaml deleted file mode 100644 index 7967b3c..0000000 --- a/templates/workflow-template/workflow-template.yaml +++ /dev/null @@ -1,163 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - name: push-to-registry-template -spec: - arguments: - parameters: - - name: git-repository-type - value: "private" # Can be private or public accordingly, private creds to be stored in a secret - - - name: git-url - value: "git_url" - - - name: registry-type - value: "private_registry" # Can be "aws" or "private_registry" - - - name: region # Set when registry type is aws - value: "region_name" - - - name: registry - value: "registry_name" - - - name: chartname - value: "chart_name" - - entrypoint: generate-token - volumeClaimTemplates: - - metadata: - name: workdir - spec: - accessModes: [ "ReadWriteOnce" ] - resources: - requests: - storage: 1Gi - - volumes: - - name: aws-secrets - secret: - secretName: aws-secret - - templates: - - name: generate-token - steps: - - - name: pull-repo - template: pull-repo - - - - name: create-token - template: gen-token-bash - when: "{{ workflow.parameters.registry-type }} == aws" - - - - name: aws-login - template: login - when: "{{ workflow.parameters.registry-type }} == aws" - arguments: - parameters: - - name: token - value: "{{steps.create-token.outputs.result}}" - - - - name: private-registry - template: private-registry - when: "{{ workflow.parameters.registry-type }} == private_registry" - - - name: pull-repo - script: - image: alpine/git:v2.30.2 - imagePullPolicy: IfNotPresent - command: [sh] - source: | - if [[ {{ workflow.parameters.git-repository-type }} == "private" ]] - then - cd /mnt/vol && git clone https://$git_token:x-oauth-basic@github.com/$git_username/$repo_name.git git-local-dir - else - cd /mnt/vol && git clone {{ workflow.parameters.git-url }} git-local-dir - fi - - env: - - name: git_username - valueFrom: - secretKeyRef: - name: git-secret - key: GIT_USERNAME - - name: git_token - valueFrom: - secretKeyRef: - name: git-secret - key: GIT_TOKEN - - name: repo_name - valueFrom: - secretKeyRef: - name: git-secret - key: REPO_NAME - volumeMounts: - - name: workdir - mountPath: /mnt/vol - - - name: gen-token-bash - script: - image: amazon/aws-cli:2.2.4 - imagePullPolicy: IfNotPresent - command: [bash] - source: | - export AWS_ACCESS_KEY_ID=$access_key - export AWS_SECRET_ACCESS_KEY=$secret_key - export AWS_DEFAULT_REGION={{ workflow.parameters.region }} - /usr/local/bin/aws ecr-public get-login-password --region {{ workflow.parameters.region }} - - env: - - name: access_key - valueFrom: - secretKeyRef: - name: aws-secret - key: AWS_ACCESS - - name: secret_key - valueFrom: - secretKeyRef: - name: aws-secret - key: AWS_SECRET - - - name: login - inputs: - parameters: - - name: token - script: - image: alpine/helm:3.5.4 - imagePullPolicy: IfNotPresent - command: [sh] - source: | - export HELM_EXPERIMENTAL_OCI=1 - echo {{ inputs.parameters.token }} | helm registry login --username AWS --password-stdin {{ workflow.parameters.registry }} - cd /mnt/vol/git-local-dir - helm chart save . {{ workflow.parameters.chartname }} - helm chart push {{ workflow.parameters.chartname }} - - volumeMounts: - - name: workdir - mountPath: /mnt/vol - - - name: private-registry - script: - image: alpine/helm:3.5.4 - imagePullPolicy: IfNotPresent - command: [sh] - source: | - export HELM_EXPERIMENTAL_OCI=1 - helm registry login {{ workflow.parameters.registry }} --username $registry_username --password $registry_password - cd /mnt/vol/git-local-dir - helm chart save . {{ workflow.parameters.chartname }} - helm chart push {{ workflow.parameters.chartname }} - - env: - - name: registry_username - valueFrom: - secretKeyRef: - name: password - key: USERNAME - - name: registry_password - valueFrom: - secretKeyRef: - name: aws-secret - key: password - volumeMounts: - - name: workdir - mountPath: /mnt/vol