Skip to content

Commit

Permalink
Migrate to metal-toolbox (#42)
Browse files Browse the repository at this point in the history
* Some cleanup

* docker login for ghcr

Signed-off-by: Sarah Funkhouser <[email protected]>
  • Loading branch information
sfunkhouser authored Jul 17, 2023
1 parent 8eb215d commit 881a6d0
Show file tree
Hide file tree
Showing 25 changed files with 407 additions and 175 deletions.
70 changes: 7 additions & 63 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
@@ -1,52 +1,32 @@
env:
# APP_NAME is normally the same as your pipeline slug
# if that isn't true, update here
APP_NAME: ${BUILDKITE_PIPELINE_SLUG}
DEPLOYMENT_REPO: ${OVERRIDE_DEPLOY_REPO:-k8s-$APP_NAME}
QUAY_REPO: quay.io/equinixmetal/${APP_NAME}
GOPRIVATE: github.com/equinixmetal/*,go.equinixmetal.net
IMAGE_REPO: ghcr.io/metal-toolbox/${APP_NAME}
IMAGE_TAG: ${BUILDKITE_BUILD_NUMBER}-${BUILDKITE_COMMIT:0:8}
COSIGN_KEY_PATH: cosign.key

steps:
- label: ":golangci-lint: lint :lint-roller:"
key: "lint"
plugins:
- docker#v5.7.0:
image: "registry.hub.docker.com/golangci/golangci-lint:v1.51-alpine"
command: ["golangci-lint", "run", "-v"]
volumes:
- "/var/lib/buildkite-agent/.gitconfig/:/root/.gitconfig/"
command: ["golangci-lint", "run", "-v", "--timeout", "5m"]

- label: ":test_tube: test"
key: "test"
plugins:
- ssh://[email protected]/packethost/ssm-buildkite-plugin#v1.0.3:
parameters:
GITHUB_TOKEN: /buildkite/github/personal-access-token/v1
- docker#v5.7.0:
image: "golang:1.20"
environment:
- "GOPRIVATE"
- "GITHUB_TOKEN"
entrypoint: ./scripts/ci_entrypoint.sh
command: ["go", "test", "-cover" ,"-race", "./..."]

- label: ":golang: build"
key: "gobuild"
artifact_paths: "bin/${APP_NAME}"
plugins:
- ssh://[email protected]/packethost/ssm-buildkite-plugin#v1.0.3:
parameters:
GITHUB_TOKEN: /buildkite/github/personal-access-token/v1
- docker#v5.7.0:
image: "golang:1.20"
environment:
- GOPRIVATE
- GITHUB_TOKEN
- CGO_ENABLED=0
- GOOS=linux
entrypoint: ./scripts/ci_entrypoint.sh
command: ["go", "build", "-buildvcs=false", "-mod=mod", "-a", "-o", "bin/$APP_NAME"]

- label: ":docker: docker build and publish"
Expand All @@ -61,58 +41,22 @@ steps:
# make sure it is executable
chmod +x bin/${APP_NAME}
ls -la
# Save COSIGN_KEY_SECRET to a file
echo "\$COSIGN_KEY_SECRET" > ${COSIGN_KEY_PATH}
plugins:
- ssh://[email protected]/packethost/ssm-buildkite-plugin#v1.0.3:
parameters:
# Buildkite redacts secrets from the logs as long as
# they have the *_SECRET, *_PASSWORD and *_TOKEN suffixes.
COSIGN_KEY_SECRET: /buildkite/cosign/cosign-priv-key/v1
# COSIGN_PASSWORD is an environment variable that's
# expected by cosign
COSIGN_PASSWORD: /buildkite/cosign/cosign-priv-key-pass/v1
- docker-login#v2.1.0:
username: metal-buildkite
password-env: SECRET_GHCR_PUBLISH_TOKEN
server: ghcr.io
- equinixmetal-buildkite/docker-metadata#v1.0.0:
images:
- "${QUAY_REPO}"
- "${IMAGE_REPO}"
extra_tags:
- "${IMAGE_TAG}"
- equinixmetal-buildkite/docker-build#v1.1.0:
push: true
build-args:
- NAME=${APP_NAME}
- equinixmetal-buildkite/cosign#main:
image: "${QUAY_REPO}:${IMAGE_TAG}"
keyless: false
keyed_config:
key: "${COSIGN_KEY_PATH}"
- equinixmetal-buildkite/trivy#v1.18.2:
severity: CRITICAL,HIGH
ignore-unfixed: true
security-checks: config,secret,vuln
skip-files: 'cosign.key'

# For main commits, pull-requests will be created to bump the image in the deployment manifest
- label: "Bump image tag for main branch builds"
depends_on: "build"
if: build.branch == 'main'
plugins:
- first-aml/git-clone:
repository: [email protected]:equinixmetal/$DEPLOYMENT_REPO.git
- ssh://[email protected]/packethost/ssm-buildkite-plugin#v1.0.3:
parameters:
GITHUB_TOKEN: /buildkite/github/personal-access-token/v1
- ssh://[email protected]/packethost/yaml-update-buildkite-plugin#v1.0.1:
dir: $DEPLOYMENT_REPO
file: values.yaml
values:
- .deployment.image.tag=$IMAGE_TAG
- ssh://[email protected]/equinixmetal/github-pr-template-buildkite-plugin#v0.2.0: {}
# Create Pull Request to main using commit from previous step
- envato/github-pull-request#v0.4.0:
title: "[buildkite] bump image tag to $IMAGE_TAG"
head: buildkite-yaml-update-$BUILDKITE_BUILD_NUMBER
base: main
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
bin/*
gov-slack-addon
coverage.out
*.exe
*.exe~
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

This addon handles the create/delete/update of Slack user groups in Slack Enterprise Grid.

`gov-slack-addon` subscribes to the Governor event stream where change events are published. The events published by Governor contain the group id that changed and the type of action. Events are published on NATS subjects dedicated to the resource type ie. `equinixmetal.governor.events.groups` for group events. When `gov-slack-addon` receives an event, it first checks that it's associated with a `slack` application in Governor, and then requests additional information from Governor about the included resource IDs and tries to match them to corresponding groups in Slack.
`gov-slack-addon` subscribes to the Governor event stream where change events are published. The events published by Governor contain the group id that changed and the type of action. Events are published on NATS subjects dedicated to the resource type ie. `governor.events.groups` for group events. When `gov-slack-addon` receives an event, it first checks that it's associated with a `slack` application in Governor, and then requests additional information from Governor about the included resource IDs and tries to match them to corresponding groups in Slack.

Slack Enterprise Grid acts as a parent organization for multiple workspaces (also called teams in Slack). For this reason `gov-slack-addon` needs a Slack token with organization-level permissions, and it also needs to be explicitly allowed in any workspaces that should be managed by the addon. In Governor, for each Slack workspace where you want to manage groups you need to create an application with type `slack` and a name that exactly matches the name of the Slack workspace, then associate that app with any Governor groups which should exist in Slack. You can associate one group with multiple slack applications and it will be created in all of the corresponding workspaces (with a `[Governor]` prefix).

Expand All @@ -16,7 +16,7 @@ As a side-note, users in Slack Enterprise Grid exist at the organization level b

### Pre-requisites for running locally

Follow the directions [here](https://github.com/equinixmetal/governor/blob/main/README.md#running-governor-locally) for starting the governor-api devcontainer.
Follow the directions [here](https://github.com/metal-toolbox/governor-api/blob/main/README.md#running-governor-locally) for starting the governor-api devcontainer.

The **first time** you'll need to create a local hydra client for `gov-slack-addon-governor` and copy the nats creds file. After that you can just export the env variables.

Expand Down Expand Up @@ -92,3 +92,7 @@ Start the addon (adjust the flags as needed):
```sh
go run . serve --audit-log-path=audit.log --nats-creds-file user.local.creds --pretty --debug --dry-run
```

## License

[Apache License, Version 2.0](LICENSE)
23 changes: 23 additions & 0 deletions chart/gov-slack-addon/.helmignore
Original file line number Diff line number Diff line change
@@ -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/
6 changes: 6 additions & 0 deletions chart/gov-slack-addon/Chart.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dependencies:
- name: common
repository: https://charts.bitnami.com/bitnami
version: 2.4.0
digest: sha256:215af03467c0fc41346b62755c5b96f40f71f9b0877205a0f970605c306c1846
generated: "2023-06-26T19:44:24.743629002Z"
13 changes: 13 additions & 0 deletions chart/gov-slack-addon/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: v2
appVersion: "1.0"
description: A Helm chart for deploying gov-slack-addon
name: gov-slack-addon
version: 1.0.0
kubeVersion: ">=1.21"

dependencies:
- name: common
repository: https://charts.bitnami.com/bitnami
tags:
- bitnami-common
version: 2.4.0
Binary file added chart/gov-slack-addon/charts/common-2.4.0.tgz
Binary file not shown.
6 changes: 6 additions & 0 deletions chart/gov-slack-addon/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{{/*
Template ingress hostname
*/}}
{{- define "ingress.hostname.rendered" -}}
{{- printf "%s" (tpl .Values.ingress.host $) -}}
{{- end -}}
18 changes: 18 additions & 0 deletions chart/gov-slack-addon/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "common.names.fullname" . }}-config
labels: {{- include "common.labels.standard" . | nindent 4 }}
data:
GSA_DRYRUN: "{{ .Values.dryrun }}"
GSA_LOGGING_DEBUG: "{{ .Values.debug }}"
GSA_LOGGING_PRETTY: "{{ .Values.pretty }}"
GSA_GOVERNOR_AUDIENCE: "{{ .Values.governor.audience }}"
GSA_GOVERNOR_CLIENT_ID: "{{ .Values.governor.clientId }}"
GSA_GOVERNOR_URL: "{{ .Values.governor.url }}"
GSA_GOVERNOR_TOKEN_URL: "{{ .Values.hydra.url }}"
GSA_NATS_URL: "{{ .Values.nats.url }}"
GSA_NATS_CREDS_FILE: "{{ .Values.nats.credsPath }}/{{ template "common.names.fullname" . }}-nats-client-creds"
GSA_RECONCILER_INTERVAL: "{{ .Values.reconciler.interval }}"
GSA_RECONCILER_LOCKING: "{{ .Values.reconciler.locking }}"
122 changes: 122 additions & 0 deletions chart/gov-slack-addon/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }}
kind: Deployment
metadata:
name: {{ template "common.names.fullname" . }}
labels: {{- include "common.labels.standard" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.deployment.replicas }}
{{- end }}
revisionHistoryLimit: 3
selector:
matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }}
template:
metadata:
labels: {{- include "common.labels.standard" . | nindent 8 }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
spec:
{{- with .Values.podSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.audit.enabled }}
initContainers:
# Optional: Pre-creates the `/app-audit/audit.log` named pipe.
- image: "{{ .Values.audit.auditImage.registry }}/{{ .Values.audit.auditImage.repository }}:{{ .Values.audit.auditImage.tag | default .Chart.AppVersion }}"
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 10 }}
{{- end }}
args:
- 'init'
- '-f'
- '/app-audit/audit.log'
name: init-audit-logs
imagePullPolicy: Always
volumeMounts:
- mountPath: /app-audit
name: audit-logs
{{- with .Values.audit.init.resources }}
resources:
{{- toYaml . | nindent 10 }}
{{- end }}
{{- end }}
containers:
- name: {{ template "common.names.fullname" . }}
args:
- serve
envFrom:
- configMapRef:
name: {{ template "common.names.fullname" . }}-config
- secretRef:
name: {{ template "common.names.fullname" . }}-creds
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
image: "{{ .Values.deployment.image.registry }}/{{ .Values.deployment.image.repository }}:{{ .Values.deployment.image.tag | default .Chart.AppVersion }}"
{{- with .Values.deployment.image.pullPolicy }}
imagePullPolicy: {{ . }}
{{- end }}
{{- with .Values.deployment.ports }}
ports:
{{- toYaml . | nindent 12 }}
{{- end }}
livenessProbe:
httpGet:
path: /healthz/liveness
port: http
readinessProbe:
httpGet:
path: /healthz/readiness
port: http
{{- with .Values.deployment.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
- name: natscreds
mountPath: "/nats"
readOnly: true
{{- if .Values.audit.enabled }} # Begin audittail toggle
# This is mounted in the 1st container
- name: audit-logs
mountPath: /app-audit
# This is the audit container
- name: {{ template "common.names.fullname" . }}-audit
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
args:
- -f
- /app-audit/audit.log
image: "{{ .Values.audit.auditImage.registry }}/{{ .Values.audit.auditImage.repository }}:{{ .Values.audit.auditImage.tag | default .Chart.AppVersion }}"
volumeMounts:
- name: audit-logs
mountPath: /app-audit
{{- with .Values.audit.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- end }} # End audittail toggle
restartPolicy: Always
terminationGracePeriodSeconds: 30
volumes:
- name: natscreds
secret:
secretName: {{ template "common.names.fullname" . }}-nats-creds
defaultMode: 0444
{{- if .Values.audit.enabled }}
- name: audit-logs
emptyDir: {}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
31 changes: 31 additions & 0 deletions chart/gov-slack-addon/templates/ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{{- if .Values.ingress.enabled -}}
apiVersion: {{ include "common.capabilities.ingress.apiVersion" . }}
kind: Ingress
metadata:
name: {{ template "common.names.fullname" . }}
{{- with .Values.ingress.labels }}
labels:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (include "common.ingress.supportsIngressClassname" .) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
rules:
- host: {{ include "ingress.hostname.rendered" . | quote }}
http:
paths:
- path: /
pathType: ImplementationSpecific
backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" $) "servicePort" "http" "context" $) | nindent 14 }}
{{- if .Values.ingress.tls }}
tls:
- hosts:
- {{ include "ingress.hostname.rendered" . | quote }}
secretName: {{include "ingress.hostname.rendered" . | quote }}
{{- end }}
{{- end }}
13 changes: 13 additions & 0 deletions chart/gov-slack-addon/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: {{ template "common.names.fullname" . }}
labels: {{- include "common.labels.standard" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector: {{ include "common.labels.matchLabels" . | nindent 4 }}
Loading

0 comments on commit 881a6d0

Please sign in to comment.