From a2e57a3dc1c354d7939fb9ac7ba60d5ffcab3e8e Mon Sep 17 00:00:00 2001 From: Carlos Tadeu Panato Junior Date: Sun, 21 May 2023 10:44:35 +0200 Subject: [PATCH] add helm chart (#99) Signed-off-by: cpanato --- .github/workflows/helm-release.yml | 58 +++++++++++++ .github/workflows/helm-test.yml | 47 ++++++++++ charts/github-exporter/.helmignore | 22 +++++ charts/github-exporter/Chart.yaml | 8 ++ charts/github-exporter/ci/ci-values.yaml | 6 ++ charts/github-exporter/templates/NOTES.txt | 5 ++ charts/github-exporter/templates/_helpers.tpl | 32 +++++++ .../github-exporter/templates/deployment.yaml | 86 +++++++++++++++++++ charts/github-exporter/templates/ingress.yaml | 31 +++++++ charts/github-exporter/templates/secret.yaml | 19 ++++ charts/github-exporter/templates/service.yaml | 57 ++++++++++++ .../templates/servicemonitor.yaml | 64 ++++++++++++++ charts/github-exporter/values.yaml | 73 ++++++++++++++++ ct.yaml | 7 ++ 14 files changed, 515 insertions(+) create mode 100644 .github/workflows/helm-release.yml create mode 100644 .github/workflows/helm-test.yml create mode 100644 charts/github-exporter/.helmignore create mode 100644 charts/github-exporter/Chart.yaml create mode 100644 charts/github-exporter/ci/ci-values.yaml create mode 100644 charts/github-exporter/templates/NOTES.txt create mode 100644 charts/github-exporter/templates/_helpers.tpl create mode 100644 charts/github-exporter/templates/deployment.yaml create mode 100644 charts/github-exporter/templates/ingress.yaml create mode 100644 charts/github-exporter/templates/secret.yaml create mode 100644 charts/github-exporter/templates/service.yaml create mode 100644 charts/github-exporter/templates/servicemonitor.yaml create mode 100644 charts/github-exporter/values.yaml create mode 100644 ct.yaml diff --git a/.github/workflows/helm-release.yml b/.github/workflows/helm-release.yml new file mode 100644 index 0000000..4e3e753 --- /dev/null +++ b/.github/workflows/helm-release.yml @@ -0,0 +1,58 @@ +name: Release Charts + +on: + push: + branches: + - main + paths: + - "charts/**" + +jobs: + release: + permissions: + contents: write + + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + + - name: Set up Helm + uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3.5 + with: + version: v3.12.0 + + - name: Run chart-releaser + uses: helm/chart-releaser-action@be16258da8010256c6e82849661221415f031968 # v1.5.0 + env: + CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + + - name: Login to GitHub Container Registry + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Install Cosign + uses: sigstore/cosign-installer@204a51a57a74d190b284a0ce69b44bc37201f343 # v3.0.3 + + - name: Publish and Sign OCI Charts + run: | + for chart in `find .cr-release-packages -name '*.tgz' -print`; do + helm push ${chart} oci://ghcr.io/${GITHUB_REPOSITORY} |& tee helm-push-output.log + file_name=${chart##*/} + chart_name=${file_name%-*} + digest=$(awk -F "[, ]+" '/Digest/{print $NF}' < helm-push-output.log) + cosign sign "ghcr.io/${GITHUB_REPOSITORY}/${chart_name}@${digest}" + done + env: + COSIGN_YES: true diff --git a/.github/workflows/helm-test.yml b/.github/workflows/helm-test.yml new file mode 100644 index 0000000..07478e0 --- /dev/null +++ b/.github/workflows/helm-test.yml @@ -0,0 +1,47 @@ +name: helm + +on: + pull_request: + paths: + - "charts/**" + +jobs: + test-chart: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + with: + fetch-depth: 0 + + - name: Set up Helm + uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3.5 + with: + version: v3.12.0 + + - uses: actions/setup-python@57ded4d7d5e986d7296eab16560982c6dd7c923b # v4.6.0 + with: + python-version: 3.8 + + - name: Set up chart-testing + uses: helm/chart-testing-action@e8788873172cb653a90ca2e819d79d65a66d4e76 # v2.4.0 + + - name: Run chart-testing (list-changed) + id: list-changed + run: | + changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }}) + if [[ -n "$changed" ]]; then + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + + - name: Run chart-testing (lint) + if: steps.list-changed.outputs.changed == 'true' + run: ct lint --target-branch ${{ github.event.repository.default_branch }} --config ct.yaml + + - name: Create kind cluster + if: steps.list-changed.outputs.changed == 'true' + uses: helm/kind-action@fa81e57adff234b2908110485695db0f181f3c67 # v1.7.0 + + - name: Run chart-testing (install) + if: steps.list-changed.outputs.changed == 'true' + run: ct install --target-branch ${{ github.event.repository.default_branch }} --config ct.yaml diff --git a/charts/github-exporter/.helmignore b/charts/github-exporter/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/charts/github-exporter/.helmignore @@ -0,0 +1,22 @@ +# 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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/github-exporter/Chart.yaml b/charts/github-exporter/Chart.yaml new file mode 100644 index 0000000..2c5034f --- /dev/null +++ b/charts/github-exporter/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +description: GitHub exporter +name: github-exporter +version: 0.1.0 +appVersion: 0.4.0 +home: https://github.com/cpanato/github_actions_exporter +maintainers: + - name: cpanato diff --git a/charts/github-exporter/ci/ci-values.yaml b/charts/github-exporter/ci/ci-values.yaml new file mode 100644 index 0000000..ff0f7ba --- /dev/null +++ b/charts/github-exporter/ci/ci-values.yaml @@ -0,0 +1,6 @@ +config: + org: "fake-honk" + +secret: + githubToken: "fake-token" + githubWebhookToken: "fake-token" diff --git a/charts/github-exporter/templates/NOTES.txt b/charts/github-exporter/templates/NOTES.txt new file mode 100644 index 0000000..8211436 --- /dev/null +++ b/charts/github-exporter/templates/NOTES.txt @@ -0,0 +1,5 @@ +1.To see the metrics +{{- if contains "ClusterIP" .Values.service.type }} + kubectl port-forward svc/{{ include "github-exporter.fullname" . }} {{ .Values.service.portMetrics }} + echo "Visit http://127.0.0.1:{{ .Values.service.portMetrics }}/metrics to check the metrics" +{{- end }} diff --git a/charts/github-exporter/templates/_helpers.tpl b/charts/github-exporter/templates/_helpers.tpl new file mode 100644 index 0000000..5f2d4ae --- /dev/null +++ b/charts/github-exporter/templates/_helpers.tpl @@ -0,0 +1,32 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "github-exporter.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). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "github-exporter.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 "github-exporter.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/charts/github-exporter/templates/deployment.yaml b/charts/github-exporter/templates/deployment.yaml new file mode 100644 index 0000000..cba9912 --- /dev/null +++ b/charts/github-exporter/templates/deployment.yaml @@ -0,0 +1,86 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "github-exporter.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "github-exporter.name" . }} + helm.sh/chart: {{ include "github-exporter.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if .Values.labels -}} + {{ .Values.labels | toYaml | nindent 4 -}} + {{- end }} +spec: + replicas: {{ .Values.deployment.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "github-exporter.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "github-exporter.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + helm.sh/chart: {{ include "github-exporter.chart" . }} + {{- if .Values.podLabels -}} + {{ .Values.podLabels | toYaml | nindent 8 -}} + {{- end }} + spec: + containers: + - name: github-exporter + image: "{{ .Values.deployment.image.repository }}:{{ .Values.deployment.image.tag }}@{{ .Values.deployment.image.digest }}" + imagePullPolicy: {{ .Values.deployment.image.pullPolicy }} + args: + - --gh.github-api-token=$(GITHUB_TOKEN) + - --gh.github-webhook-token=$(GITHUB_WEBHOOK_TOKEN) + - --gh.github-org={{ .Values.config.org }} + - --gh.billing-poll-seconds={{ .Values.config.pollSeconds }} + envFrom: + - secretRef: + {{- if not .Values.secret.existingSecretName }} + name: {{ include "github-exporter.fullname" . }} + {{- else }} + name: {{ .Values.secret.existingSecretName }} + {{- end }} + ports: + - name: metrics + containerPort: {{ .Values.service.portMetrics }} + protocol: TCP + - name: http + containerPort: {{ .Values.service.portHttp }} + protocol: TCP + livenessProbe: + failureThreshold: 1 + httpGet: + path: /healthz + port: http + scheme: HTTP + initialDelaySeconds: 3 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 9 + readinessProbe: + failureThreshold: 1 + httpGet: + path: /healthz + port: http + scheme: HTTP + initialDelaySeconds: 3 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 9 + resources: + {{- toYaml .Values.deployment.resources | nindent 12 }} + {{- with .Values.deployment.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/github-exporter/templates/ingress.yaml b/charts/github-exporter/templates/ingress.yaml new file mode 100644 index 0000000..6444fa3 --- /dev/null +++ b/charts/github-exporter/templates/ingress.yaml @@ -0,0 +1,31 @@ +{{- if .Values.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + labels: + app.kubernetes.io/name: {{ include "github-exporter.name" . }} + helm.sh/chart: {{ include "github-exporter.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if .Values.ingress.extraLabels }} + {{ .Values.ingress.extraLabels | toYaml | nindent 4 -}} + {{- end }} + {{- if .Values.ingress.annotations }} + annotations: + {{ .Values.ingress.annotations | toYaml | nindent 4 -}} + {{- end }} + name: {{ include "github-exporter.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + rules: + - host: {{ .Values.ingress.host }} + http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: {{ include "github-exporter.name" . }}-ingress + port: + number: {{ .Values.service.portHttp }} +{{- end }} \ No newline at end of file diff --git a/charts/github-exporter/templates/secret.yaml b/charts/github-exporter/templates/secret.yaml new file mode 100644 index 0000000..fe70712 --- /dev/null +++ b/charts/github-exporter/templates/secret.yaml @@ -0,0 +1,19 @@ +{{- if not .Values.secret.existingSecretName }} +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/name: {{ include "github-exporter.name" . }} + helm.sh/chart: {{ include "github-exporter.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if .Values.labels }} + {{ .Values.labels | toYaml | nindent 4 -}} + {{- end }} + name: {{ include "github-exporter.fullname" . }} + namespace: {{ .Release.Namespace }} +data: + GITHUB_TOKEN: {{ .Values.secret.githubToken | b64enc }} + GITHUB_WEBHOOK_TOKEN: {{ .Values.secret.githubWebhookToken | b64enc }} +type: Opaque +{{- end }} diff --git a/charts/github-exporter/templates/service.yaml b/charts/github-exporter/templates/service.yaml new file mode 100644 index 0000000..cfbde3d --- /dev/null +++ b/charts/github-exporter/templates/service.yaml @@ -0,0 +1,57 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: {{ include "github-exporter.name" . }} + helm.sh/chart: {{ include "github-exporter.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if .Values.service.extraLabels -}} + {{ .Values.service.extraLabels | toYaml | nindent 4 -}} + {{- end }} + {{- if .Values.service.annotationsMetrics }} + annotations: + {{ .Values.service.annotationsMetrics | toYaml | nindent 4 -}} + {{- end }} + name: {{ include "github-exporter.name" . }}-metrics + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.portMetrics }} + targetPort: metrics + protocol: TCP + name: metrics + selector: + app.kubernetes.io/name: {{ include "github-exporter.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +--- +{{- if .Values.ingress.enabled }} +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: {{ include "github-exporter.name" . }} + helm.sh/chart: {{ include "github-exporter.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if .Values.service.extraLabels -}} + {{ .Values.service.extraLabels | toYaml | nindent 4 -}} + {{- end }} + {{- if .Values.service.annotationsIngress }} + annotations: + {{ .Values.service.annotationsIngress | toYaml | nindent 4 -}} + {{- end }} + name: {{ include "github-exporter.name" . }}-ingress + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.portHttp }} + targetPort: http + protocol: TCP + name: http + selector: + app.kubernetes.io/name: {{ include "github-exporter.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} \ No newline at end of file diff --git a/charts/github-exporter/templates/servicemonitor.yaml b/charts/github-exporter/templates/servicemonitor.yaml new file mode 100644 index 0000000..5714153 --- /dev/null +++ b/charts/github-exporter/templates/servicemonitor.yaml @@ -0,0 +1,64 @@ +{{- if .Values.prometheus.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "github-exporter.fullname" . }} + {{- if .Values.prometheus.serviceMonitor.namespace }} + namespace: {{ .Values.prometheus.serviceMonitor.namespace }} + {{- end }} + labels: + app.kubernetes.io/name: {{ include "github-exporter.name" . }} + helm.sh/chart: {{ include "github-exporter.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if .Values.labels -}} + {{ .Values.labels | toYaml | nindent 4 -}} + {{- end }} + {{- if .Values.prometheus.serviceMonitor.additionalLabels }} +{{ toYaml .Values.prometheus.serviceMonitor.additionalLabels | indent 4 -}} + {{- end }} +spec: + jobLabel: jobLabel + selector: + matchLabels: + app.kubernetes.io/name: {{ include "github-exporter.name" . }} + helm.sh/chart: {{ include "github-exporter.chart" . }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + endpoints: + - port: metrics + interval: {{ .Values.prometheus.serviceMonitor.interval }} + {{- if .Values.prometheus.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.prometheus.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 4 }} + {{- end }} +{{- else if .Values.prometheus.gcpManagedPrometheus.enabled }} +apiVersion: monitoring.googleapis.com/v1 +kind: PodMonitoring +metadata: + name: {{ include "github-exporter.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "github-exporter.name" . }} + helm.sh/chart: {{ include "github-exporter.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if .Values.labels -}} + {{ .Values.labels | toYaml | nindent 4 -}} + {{- end }} + {{- if .Values.prometheus.serviceMonitor.additionalLabels }} +{{ toYaml .Values.prometheus.serviceMonitor.additionalLabels | indent 4 -}} + {{- end }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ include "github-exporter.name" . }} + helm.sh/chart: {{ include "github-exporter.chart" . }} + endpoints: + - port: metrics + path: /metrics + interval: 30s +{{- end }} diff --git a/charts/github-exporter/values.yaml b/charts/github-exporter/values.yaml new file mode 100644 index 0000000..7d783ed --- /dev/null +++ b/charts/github-exporter/values.yaml @@ -0,0 +1,73 @@ +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +--- +nameOverride: "" +fullnameOverride: "" + +labels: {} + +config: + org: "" + pollSeconds: 30 + +secret: + existingSecretName: "" + githubToken: "" + githubWebhookToken: "" + +deployment: + replicaCount: 1 + image: + repository: ghcr.io/cpanato/github_actions_exporter + tag: v0.6.1 + digest: sha256:39d4c45327d2ec0f4fbac3197f5a862da49d66f775d7844c899f5158db95f37e + pullPolicy: IfNotPresent + + podLabels: {} + + resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + nodeSelector: {} + + tolerations: [] + + affinity: {} + +service: + type: ClusterIP + portMetrics: 9101 + portHttp: 8065 + extraLabels: {} + annotationsMetrics: {} + annotationsIngress: {} + +ingress: + # if you set a webhook token you might want to setup the ingress to receive + # the webhook message + enabled: false + host: + extraLabels: {} + annotations: {} + + +prometheus: + serviceMonitor: + enabled: false + namespace: monitoring + interval: "5m" + scrapeTimeout: 2m + additionalLabels: + app: github-exporter + metricRelabelings: {} + gcpManagedPrometheus: + enabled: false diff --git a/ct.yaml b/ct.yaml new file mode 100644 index 0000000..9657573 --- /dev/null +++ b/ct.yaml @@ -0,0 +1,7 @@ +--- +chart-dirs: + - charts +validate-maintainers: false +validate-yaml: true +remote: origin +target-branch: main