Skip to content

Commit f0774a5

Browse files
authored
Merge pull request #1 from Lirt/initial-implementation
Initial implementation
2 parents eddb48e + 8db2226 commit f0774a5

File tree

15 files changed

+1203
-1
lines changed

15 files changed

+1203
-1
lines changed

.github/workflows/release.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
name: release
3+
run-name: Release new tagged version
4+
on:
5+
push:
6+
tags:
7+
- 'v[0-9]+.[0-9]+.[0-9]+*'
8+
jobs:
9+
release:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Set up Docker Buildx
13+
uses: docker/setup-buildx-action@v2
14+
- name: Login to Docker Hub
15+
uses: docker/login-action@v2
16+
with:
17+
username: ${{ secrets.DOCKERHUB_USERNAME }}
18+
password: ${{ secrets.DOCKERHUB_TOKEN }}
19+
- name: Build and push Docker image
20+
uses: docker/build-push-action@v4.0.0
21+
with:
22+
push: true
23+
tags: "lirt/k8s-secret-replicator:${{ github.ref_name }}"
24+
file: "docker/Dockerfile"
25+
platforms: "linux/amd64,linux/arm,linux/arm64"
26+
no-cache: true
27+
build-args: |
28+
VERSION=${{ github.ref_name }}
29+
GIT_SHA=${{ github.sha }}

.github/workflows/tests.yaml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
name: Tests
3+
on: [pull_request]
4+
jobs:
5+
lint:
6+
name: "Linters (go v${{ matrix.go-version }})"
7+
runs-on: ubuntu-20.04
8+
strategy:
9+
matrix:
10+
go-version: [ '1.20' ]
11+
steps:
12+
- name: Checkout k8s-secret-replicator
13+
uses: actions/checkout@v3
14+
- name: Setup Go ${{ matrix.go-version }}
15+
uses: actions/setup-go@v3
16+
with:
17+
go-version: ${{ matrix.go-version }}
18+
- name: Check formatting
19+
run: |
20+
test -z $(gofmt -l -s ./)
21+
- name: Check go vet
22+
run: |
23+
go vet ./...
24+
- name: Verify dependencies
25+
run: |
26+
go mod verify
27+
- name: Check if plugin can be built
28+
run: |
29+
go build -v .
30+
unit-test:
31+
name: "Unit tests (go v${{ matrix.go-version }})"
32+
needs: lint
33+
runs-on: ubuntu-20.04
34+
strategy:
35+
matrix:
36+
go-version: [ '1.20' ]
37+
steps:
38+
- name: Checkout k8s-secret-replicator
39+
uses: actions/checkout@v3
40+
- name: Setup Go ${{ matrix.go-version }}
41+
uses: actions/setup-go@v3
42+
with:
43+
go-version: ${{ matrix.go-version }}
44+
- name: Run unit tests
45+
run: |
46+
go test -v ./...

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@
1919

2020
# Go workspace file
2121
go.work
22+
23+
bin
24+
k8s-secret-replicator

Dockerfile

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# syntax = docker/dockerfile:1.3
2+
FROM --platform=$BUILDPLATFORM golang:1.20-alpine AS builder
3+
4+
ARG REPOSITORY=Lirt
5+
ARG PLUGIN=k8s-secret-replicator
6+
ARG PKG=github.com/Lirt/k8s-secret-replicator
7+
ARG VERSION=0.0.0
8+
ARG GIT_SHA=nil
9+
10+
ARG TARGETOS
11+
ARG TARGETARCH
12+
ARG TARGETVARIANT
13+
14+
ARG GOOS=linux
15+
ARG GOARCH=amd64
16+
17+
ENV GOOS=${TARGETOS}
18+
ENV GOARCH=${TARGETARCH}
19+
ENV GOARM=${TARGETVARIANT}
20+
21+
ENV GOPROXY=https://proxy.golang.org
22+
23+
24+
WORKDIR /build
25+
COPY . .
26+
27+
RUN \
28+
export GOARM=$( echo "${GOARM}" | cut -c2-) && \
29+
CGO_ENABLED=0 \
30+
go build \
31+
-ldflags "-s -w" \
32+
-o bin/k8s-secret-replicator \
33+
.
34+
35+
# Use distroless as minimal base image to package the k8s-secret-replicator binary
36+
# Refer to https://github.com/GoogleContainerTools/distroless for more details
37+
FROM gcr.io/distroless/static:nonroot
38+
WORKDIR /
39+
40+
COPY --from=builder /build/bin/k8s-secret-replicator ./k8s-secret-replicator
41+
42+
USER 65532
43+
ENTRYPOINT [ "/k8s-secret-replicator" ]

README.md

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,68 @@
1-
# k8s-secret-replicator
1+
# K8s Secret Replicator
2+
23
K8s Secret Replicator is used to replicate one source secret to all namespaces in a Kubernetes cluster.
4+
5+
This is useful for example for replicating image pull secret to all namespaces without knowing which namespaces will exist in advance.
6+
7+
When content of source secret is changed, secrets with the same name will also be updated in all namespaces.
8+
9+
## Usage
10+
11+
First create or prepare docker-registry secret. Here is example:
12+
```bash
13+
kubectl create secret \
14+
docker-registry \
15+
my-secret-to-replicate \
16+
--docker-server=https://index.docker.io/v1/ \
17+
--docker-username=user \
18+
--docker-password=password
19+
```
20+
21+
### Production
22+
23+
Install via helm chart or use your favorite continuous deployment tool:
24+
25+
```bash
26+
helm upgrade \
27+
--install \
28+
--create-namespace \
29+
--version 0.1.0 \
30+
--namespace kube-system \
31+
--set app.sourceSecretName=my-secret-to-replicate \
32+
--set app.sourceSecretNamespace=kube-system \
33+
--wait \
34+
k8s-secret-replicator \
35+
chart
36+
```
37+
38+
Official image is built and pushed to dockerhub https://hub.docker.com/repository/docker/lirt/k8s-secret-replicator/.
39+
40+
### Development
41+
42+
In production in-cluster config will be consumed. For testing you can set kubeconfig to point to a cluster where you want to test it.
43+
44+
```bash
45+
export KUBECONFIG="~/.kube/configs/my-awesome-cluster.yaml"
46+
export SOURCE_SECRET_NAME=my-secret-to-replicate
47+
export SOURCE_SECRET_NAMESPACE=kube-system
48+
go run main.go
49+
```
50+
51+
## Build
52+
53+
### Go
54+
55+
```bash
56+
go build
57+
```
58+
59+
### Docker
60+
61+
```bash
62+
docker buildx build \
63+
--platform linux/amd64,linux/arm,linux/arm64 \
64+
--tag lirt/k8s-secret-replicator:v0.1.0 \
65+
--no-cache \
66+
--push \
67+
.
68+
```

chart/.helmignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
# Common VCS dirs
6+
.git/
7+
.gitignore
8+
.bzr/
9+
.bzrignore
10+
.hg/
11+
.hgignore
12+
.svn/
13+
# Common backup files
14+
*.swp
15+
*.bak
16+
*.tmp
17+
*.orig
18+
*~
19+
# Various IDEs
20+
.project
21+
.idea/
22+
*.tmproj
23+
.vscode/

chart/Chart.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: v2
2+
name: k8s-secret-replicator
3+
description: Secret Replicator is used to replicate one source secret to all namespaces in a Kubernetes cluster.
4+
type: application
5+
version: 0.1.0
6+
appVersion: "0.1.0"

chart/templates/_helpers.tpl

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
{{/*
2+
Expand the name of the chart.
3+
*/}}
4+
{{- define "k8s-secret-replicator.name" -}}
5+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
6+
{{- end }}
7+
8+
{{/*
9+
Create a default fully qualified app name.
10+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
11+
If release name contains chart name it will be used as a full name.
12+
*/}}
13+
{{- define "k8s-secret-replicator.fullname" -}}
14+
{{- if .Values.fullnameOverride }}
15+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
16+
{{- else }}
17+
{{- $name := default .Chart.Name .Values.nameOverride }}
18+
{{- if contains $name .Release.Name }}
19+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
20+
{{- else }}
21+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
22+
{{- end }}
23+
{{- end }}
24+
{{- end }}
25+
26+
{{/*
27+
Create chart name and version as used by the chart label.
28+
*/}}
29+
{{- define "k8s-secret-replicator.chart" -}}
30+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
31+
{{- end }}
32+
33+
{{/*
34+
Common labels
35+
*/}}
36+
{{- define "k8s-secret-replicator.labels" -}}
37+
helm.sh/chart: {{ include "k8s-secret-replicator.chart" . }}
38+
{{ include "k8s-secret-replicator.selectorLabels" . }}
39+
{{- if .Chart.AppVersion }}
40+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
41+
{{- end }}
42+
app.kubernetes.io/managed-by: {{ .Release.Service }}
43+
{{- end }}
44+
45+
{{/*
46+
Selector labels
47+
*/}}
48+
{{- define "k8s-secret-replicator.selectorLabels" -}}
49+
app.kubernetes.io/name: {{ include "k8s-secret-replicator.name" . }}
50+
app.kubernetes.io/instance: {{ .Release.Name }}
51+
{{- end }}
52+
53+
{{/*
54+
Create the name of the service account to use
55+
*/}}
56+
{{- define "k8s-secret-replicator.serviceAccountName" -}}
57+
{{- if .Values.serviceAccount.create }}
58+
{{- default (include "k8s-secret-replicator.fullname" .) .Values.serviceAccount.name }}
59+
{{- else }}
60+
{{- default "default" .Values.serviceAccount.name }}
61+
{{- end }}
62+
{{- end }}
63+
64+
{{/*
65+
Template image tag.
66+
*/}}
67+
{{- define "image-template" }}
68+
{{- if .repository -}}
69+
{{- printf "%s/%s/%s:%s" (required (printf "missing %s.%s" . .registry) (trimSuffix "/" .registry)) (trimAll "/" .repository) (required (printf "missing %s.%s" . .name) (trimAll "/" .name)) (required (printf "missing %s.%s" . .tag) .tag) }}
70+
{{- else -}}
71+
{{- printf "%s/%s:%s" (required (printf "missing %s.%s" . .registry) (trimSuffix "/" .registry)) (required (printf "missing %s.%s" . .name) (trimAll "/" .name)) (required (printf "missing %s.%s" . .tag) .tag) }}
72+
{{- end }}
73+
{{- end }}

chart/templates/deployment.yaml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
apiVersion: apps/v1
3+
kind: Deployment
4+
metadata:
5+
name: {{ include "k8s-secret-replicator.fullname" . }}
6+
labels:
7+
{{- include "k8s-secret-replicator.labels" . | nindent 4 }}
8+
spec:
9+
replicas: {{ .Values.replicaCount }}
10+
selector:
11+
matchLabels:
12+
{{- include "k8s-secret-replicator.selectorLabels" . | nindent 6 }}
13+
template:
14+
metadata:
15+
{{- with .Values.podAnnotations }}
16+
annotations:
17+
{{- toYaml . | nindent 8 }}
18+
{{- end }}
19+
labels:
20+
{{- include "k8s-secret-replicator.selectorLabels" . | nindent 8 }}
21+
spec:
22+
{{- with .Values.imagePullSecrets }}
23+
imagePullSecrets:
24+
{{- toYaml . | nindent 8 }}
25+
{{- end }}
26+
serviceAccountName: {{ include "k8s-secret-replicator.serviceAccountName" . }}
27+
securityContext:
28+
{{- toYaml .Values.podSecurityContext | nindent 8 }}
29+
containers:
30+
- name: {{ .Chart.Name }}
31+
securityContext:
32+
{{- toYaml .Values.securityContext | nindent 12 }}
33+
image: '{{ include "image-template" .Values.image }}'
34+
imagePullPolicy: {{ .Values.image.pullPolicy }}
35+
env:
36+
- name: SOURCE_SECRET_NAME
37+
value: {{ required "Please specify app.sourceSecretName to tell replicator how to identify source secret" .Values.app.sourceSecretName }}
38+
- name: SOURCE_SECRET_NAMESPACE
39+
value: {{ required "Please specify app.sourceSecretNamespace to tell replicator how to identify source secret" .Values.app.sourceSecretNamespace }}
40+
resources:
41+
{{- toYaml .Values.resources | nindent 12 }}
42+
{{- with .Values.nodeSelector }}
43+
nodeSelector:
44+
{{- toYaml . | nindent 8 }}
45+
{{- end }}
46+
{{- with .Values.affinity }}
47+
affinity:
48+
{{- toYaml . | nindent 8 }}
49+
{{- end }}
50+
{{- with .Values.tolerations }}
51+
tolerations:
52+
{{- toYaml . | nindent 8 }}
53+
{{- end }}

0 commit comments

Comments
 (0)