Skip to content

Commit 6932b72

Browse files
feat: add e2e testing (#78)
* feat: add e2e testing Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> * feat: add e2e testing Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> * chore: add custom base image Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> * chore: add custom base image Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> --------- Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
1 parent 5c9392d commit 6932b72

62 files changed

Lines changed: 2335 additions & 747 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/configs/lintconf.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ ignore:
55
- charts/**/templates/
66
- docs/**
77
- hack/**
8+
- e2e/testdata/**
89
rules:
910
truthy:
1011
level: warning

.github/workflows/docker-build.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ jobs:
2424
steps:
2525
- name: Checkout
2626
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
27+
- name: Setup QEMU
28+
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
29+
- name: Setup Docker Buildx
30+
id: buildx
31+
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
2732
- name: ko build
2833
run: VERSION=${{ github.sha }} make ko-build-all
2934
- name: Trivy Scan Image

.github/workflows/docker-publish.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ jobs:
2727
echo "version=$VERSION" >> $GITHUB_OUTPUT
2828
- name: Install Cosign
2929
uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
30+
31+
- name: Setup QEMU
32+
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
33+
- name: Setup Docker Buildx
34+
id: buildx
35+
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
36+
3037
- name: Publish with KO
3138
id: publish
3239
uses: peak-scale/github-actions/make-ko-publish@a441cca016861c546ab7e065277e40ce41a3eb84 # v0.2.0

.github/workflows/e2e.yaml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ concurrency:
2323
jobs:
2424
kind:
2525
name: Kubernetes
26-
strategy:
27-
fail-fast: false
28-
matrix:
29-
k8s-version:
30-
- "v1.31.0"
3126
runs-on: ubuntu-24.04
3227
steps:
3328
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -40,4 +35,4 @@ jobs:
4035
with:
4136
version: v3.14.2
4237
- name: e2e testing
43-
run: KIND_K8S_VERSION="${{ matrix.k8s-version }}" make e2e
38+
run: make e2e

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# Output of the go coverage tool, specifically when used with LiteIDE
1515
*.out
1616
config
17+
.DS_Store
1718

1819
# Dependency directories (remove the comment below to include it)
1920
# vendor/

Dockerfile.base

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM docker.io/library/alpine:3.21
2+
3+
RUN apk --no-cache add ca-certificates gnupg \
4+
&& update-ca-certificates
5+
6+
USER 65534:65534
7+
8+
ENV GNUPGHOME=/tmp

Makefile

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ IMG ?= $(IMG_BASE):$(VERSION)
1818
FULL_IMG ?= $(REGISTRY)/$(IMG_BASE)
1919

2020
## Kubernetes Version Support
21-
KUBERNETES_SUPPORTED_VERSION ?= "v1.33.0"
21+
KUBERNETES_SUPPORTED_VERSION ?= v1.32.0
2222

2323
## Tool Binaries
2424
KUBECTL ?= kubectl
@@ -127,6 +127,11 @@ ifdef VERSION
127127
KO_TAGS := $(KO_TAGS),$(VERSION)
128128
endif
129129

130+
BASE_DOCKERFILE ?= Dockerfile.base
131+
BASE_IMAGE_TAG ?= ko.local/peak-scale/sops-operator:base
132+
BASE_BUILD_ARGS ?= --load
133+
KO_DEFAULTBASEIMAGE := $(BASE_IMAGE_TAG)
134+
130135
LD_FLAGS := "-X main.Version=$(VERSION) \
131136
-X main.GitCommit=$(GIT_HEAD_COMMIT) \
132137
-X main.GitTag=$(VERSION) \
@@ -137,14 +142,21 @@ LD_FLAGS := "-X main.Version=$(VERSION) \
137142
# Docker Image Build
138143
# ------------------
139144

145+
.PHONY: build-base-image
146+
build-base-image: ## Build base image using Docker Buildx
147+
@docker buildx build ${BASE_BUILD_ARGS} \
148+
--platform=$(KO_PLATFORM) \
149+
--tag ${BASE_IMAGE_TAG} \
150+
--file $(BASE_DOCKERFILE) .
151+
140152
.PHONY: ko-build-controller
141-
ko-build-controller: ko
153+
ko-build-controller: ko build-base-image
142154
@echo Building Controller $(FULL_IMG) - $(KO_TAGS) >&2
143-
@LD_FLAGS=$(LD_FLAGS) KOCACHE=$(KOCACHE) KO_DOCKER_REPO=$(FULL_IMG) \
155+
@LD_FLAGS=$(LD_FLAGS) KOCACHE=$(KOCACHE) KO_DOCKER_REPO=$(FULL_IMG) KO_DEFAULTBASEIMAGE=$(BASE_IMAGE_TAG) \
144156
$(KO) build ./cmd/ --bare --tags=$(KO_TAGS) --push=false --local --platform=$(KO_PLATFORM)
145157

146158
.PHONY: ko-build-all
147-
ko-build-all: ko-build-controller
159+
ko-build-all: ko-build-controller
148160

149161
# Docker Image Publish
150162
# ------------------
@@ -199,7 +211,7 @@ CLUSTER_NAME ?= "sops-operator"
199211
e2e: e2e-build e2e-exec e2e-destroy
200212

201213
e2e-build: kind
202-
$(KIND) create cluster --wait=60s --name $(CLUSTER_NAME) --image=kindest/node:$(KUBERNETES_SUPPORTED_VERSION)
214+
$(KIND) create cluster --wait=60s --config e2e/kind.yaml --name $(CLUSTER_NAME) --image=kindest/node:$(KUBERNETES_SUPPORTED_VERSION)
203215
$(MAKE) e2e-install
204216

205217
e2e-exec: ginkgo
@@ -208,7 +220,7 @@ e2e-exec: ginkgo
208220
e2e-destroy: kind
209221
$(KIND) delete cluster --name $(CLUSTER_NAME)
210222

211-
e2e-install: e2e-load-image e2e-install-addon-helm
223+
e2e-install: e2e-load-image e2e-install-addon-helm e2e-install-distro
212224

213225
e2e-install-addon-helm:
214226
helm upgrade \
@@ -224,6 +236,11 @@ e2e-install-addon-helm:
224236
sops-operator \
225237
./charts/sops-operator
226238

239+
e2e-install-distro:
240+
@$(KUBECTL) kustomize e2e/manifests/flux/ | kubectl apply -f -
241+
@$(KUBECTL) kustomize e2e/manifests/distro/ | kubectl apply -f -
242+
@$(MAKE) wait-for-helmreleases
243+
227244
.PHONY: e2e-load-image
228245
e2e-load-image: ko-build-all
229246
kind load docker-image --name $(CLUSTER_NAME) $(FULL_IMG):$(VERSION)
@@ -313,6 +330,14 @@ ko:
313330
@test -s $(KO) && $(KO) -h | grep -q $(KO_VERSION) || \
314331
$(call go-install-tool,$(KO),github.com/$(KO_LOOKUP)@$(KO_VERSION))
315332

333+
BUILDAH := $(LOCALBIN)/buildah
334+
BUILDAH_VERSION := v1.40.0
335+
BUILDAH_LOOKUP := containers/buildah
336+
buildah:
337+
@test -s $(BUILDAH) && $(BUILDAH) -h | grep -q $(BUILDAH_VERSION) || \
338+
$(call go-install-tool,$(BUILDAH),github.com/$(BUILDAH_LOOKUP)/cmd/buildah@$(BUILDAH_VERSION))
339+
340+
316341
GOLANGCI_LINT := $(LOCALBIN)/golangci-lint
317342
GOLANGCI_LINT_VERSION := v2.1.5
318343
GOLANGCI_LINT_LOOKUP := golangci/golangci-lint
@@ -328,6 +353,20 @@ apidocs-gen: ## Download crdoc locally if necessary.
328353
@test -s $(APIDOCS_GEN) && $(APIDOCS_GEN) --version | grep -q $(APIDOCS_GEN_VERSION) || \
329354
$(call go-install-tool,$(APIDOCS_GEN),fybrik.io/crdoc@$(APIDOCS_GEN_VERSION))
330355

356+
AGE_KEYGEN := $(LOCALBIN)/age-keygen
357+
AGE := $(LOCALBIN)/age
358+
AGE_VERSION := v1.2.1
359+
AGE_LOOKUP := FiloSottile/age
360+
age:
361+
@$(call go-install-tool,$(AGE_KEYGEN),filippo.io/age/cmd/age-keygen@$(AGE_VERSION))
362+
@$(call go-install-tool,$(AGE),filippo.io/age/cmd/age@$(AGE_VERSION))
363+
364+
SOPS := $(LOCALBIN)/sops
365+
SOPS_VERSION := v3.10.2
366+
SOPS_LOOKUP := getsops/sops
367+
sops:
368+
@$(call go-install-tool,$(SOPS),github.com/$(SOPS_LOOKUP)/v3/cmd/sops@$(SOPS_VERSION))
369+
331370
# go-install-tool will 'go install' any package $2 and install it to $1.
332371
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
333372
define go-install-tool

README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,25 @@
1111
</a>
1212
</p>
1313

14-
> This project is currently in public beta and under active development. Please report any issues you encounter.
14+
> [!IMPORTANT]
15+
> Regarding the code, most of the SOPS implementation was taken from the [Flux kustomize-constroller](https://github.com/fluxcd/kustomize-controller/blob/main/internal/decryptor/decryptor.go) project. We have left the License-Header as-is, if further attribution is wished, please open an issue. We go the idea from the existing [sops-operator](https://github.com/isindir/sops-secrets-operator). However the implementation was not optimal for our use-cases, that's why we decided to release our own solution.
1516
1617
# SOPS-Operator ❤️
1718

1819
![SOPS](https://avatars.githubusercontent.com/u/129185620?s=48&v=4)
1920

20-
We have always loved how [Flux handles Secrets with SOPS](https://fluxcd.io/flux/guides/mozilla-sops/), it's such a seamless experience. However we have noticed, that it's kind of hard to actually distribute keys to users in a kubernetes native way. That's why we built this operator. It introduces [Providers](docs/usage.md#providers), which essentially match Kubernetes resources which represent Keys or access to KMS stores. On the Provides you also declare, which [Secrets](docs/usage.md#secrets) you want to encrypt with that provider. **Currently only works with PGP and AGE for n-secrets** That leaves open that, N-providers can load private keys for one Secret, in complex scenarios.
21+
We have always loved how [Flux handles Secrets with SOPS](https://fluxcd.io/flux/guides/mozilla-sops/), it's such a seamless experience. However we have noticed, that it's kind of hard to actually distribute keys to users in a kubernetes native way. That's why we built this operator. It introduces [Providers](docs/usage.md#providers), which essentially match Kubernetes resources which represent Keys or access to KMS stores. On the Provides you also declare, which [Secrets](docs/usage.md#secrets) you want to encrypt with that provider. **Currently only works with PGP and AGE for n-secrets** That leaves open that, N-providers can load private keys for one Secret, in complex scenarios. Also we want to provide a general solution to decrypting secrets, not a solution which is dependent on a gitops engine.
22+
23+
24+
## Concept
25+
26+
This Operators introduces the concept of [SopsProviders](./docs/usage.md#providers). `SopsProviders` are created by Cluster-Administrators and are essentially a connecting-piece for collecting private-keys and [`SopsSecrets`](./docs/usage.md#sopssecrets), which can use these keys for decryption.
27+
28+
With this option an Kubernetes users may manage their own keys and [`SopsSecrets`](./docs/usage.md#sopssecrets). The implementation of `SopsSecrets` allows them to be applied to the Kubernetes API with sops encryption-meta. The entire decryption happens within the cluster. So a `SopsSecret` is applied the way it's stored eg. in git.
29+
30+
31+
![Sops Operator](./docs/assets/sops-operator.gif)
2132

22-
> Regarding the code, most of the SOPS implementation was taken from the [Flux kustomize-constroller](https://github.com/fluxcd/kustomize-controller/blob/main/internal/decryptor/decryptor.go) project. We have left the License-Header as-is, if further attribution is wished, please open an issue. We go the idea from the existing [sops-operator](https://github.com/isindir/sops-secrets-operator). However the implementation was not optimal for our use-cases, that's why we decided to release our own solution.
2333

2434
## Documentation
2535

api/v1alpha1/sopsprovider_status.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ func (ms *SopsProviderStatus) GetInstance(stat *SopsProviderItemStatus) *SopsPro
3636
func (ms *SopsProviderStatus) UpdateInstance(stat *SopsProviderItemStatus) {
3737
for i, source := range ms.Providers {
3838
if ms.instancequal(source, stat) {
39+
if source.Type == stat.Type &&
40+
source.Status == stat.Status &&
41+
source.Reason == stat.Reason && source.Message == stat.Message {
42+
return
43+
}
44+
3945
ms.Providers[i] = stat
4046

4147
return

charts/sops-operator/crds/addons.projectcapsule.dev_sopsproviders.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,9 @@ spec:
379379
namespace:
380380
description: namespace of Object
381381
type: string
382+
uid:
383+
description: namespace of Object
384+
type: string
382385
required:
383386
- name
384387
type: object

0 commit comments

Comments
 (0)