Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zarf agent mutating webhook #306

Merged
merged 42 commits into from
May 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
e5cfdf4
post multi-distro pki cleanup
jeff-mccoy Feb 10, 2022
635f4e0
initial zarf agent work
jeff-mccoy Feb 10, 2022
2c994cb
Merge branch 'fix/cleanup-pki-flow' into zarf-agent
jeff-mccoy Feb 10, 2022
19eed9e
Merge branch 'master' into zarf-agent
YrrepNoj Mar 8, 2022
5407304
Merge branch 'master' into feature/zarf-agent
jeff-mccoy Mar 12, 2022
776c225
Merge branch 'master' into zarf-agent
jeff-mccoy Mar 13, 2022
49bd485
Merge branch 'master' into zarf-agent
YrrepNoj Mar 15, 2022
add2c01
wip: start to convert makefile to real code
jeff-mccoy Mar 17, 2022
e4037d9
Merge branch 'master' into zarf-agent
jeff-mccoy Mar 21, 2022
558995e
Merge branch 'master' into feature/zarf-agent
jeff-mccoy Mar 22, 2022
ae4f20e
Merge branch 'master' into zarf-agent
jeff-mccoy Mar 22, 2022
0c13d1c
more worky
jeff-mccoy Mar 28, 2022
313ab63
Merge branch 'master' into feature/zarf-agent
jeff-mccoy Mar 31, 2022
7986691
Merge branch 'master' into zarf-agent
jeff-mccoy Apr 4, 2022
3bc0820
Merge branch 'master' into feature/zarf-agent
jeff-mccoy Apr 5, 2022
49d75c8
Merge branch 'master' into feature/zarf-agent
jeff-mccoy May 4, 2022
dc05547
Merge branch 'master' into feature/zarf-agent
jeff-mccoy May 7, 2022
8ceab42
giant wip
jeff-mccoy May 8, 2022
528fa11
rebase onto docker scratch
jeff-mccoy May 9, 2022
8f52625
happy test, happy life
jeff-mccoy May 9, 2022
648994b
create a zarf-agent build stage
jeff-mccoy May 9, 2022
7b57732
update github action, thx bad docs
jeff-mccoy May 9, 2022
a404b84
avoid qemu super slowness w/gobuild
jeff-mccoy May 10, 2022
185abc6
bump agent image version
jeff-mccoy May 10, 2022
3aec417
make go caching consistent
jeff-mccoy May 10, 2022
c461131
Merge branch 'master' into feature/zarf-agent
jeff-mccoy May 10, 2022
a5c8eeb
sigh gitkraken..
jeff-mccoy May 10, 2022
9d087ff
agent code cleanup
jeff-mccoy May 11, 2022
359f029
wip use private-registry & stub out flux hook
jeff-mccoy May 11, 2022
ee48044
add zarf agent docs
jeff-mccoy May 12, 2022
9311dda
implement Flux GitRepo mutations for zarf git server
jeff-mccoy May 13, 2022
c634766
fix kube-system namespace exclusion matching
jeff-mccoy May 13, 2022
e486acd
dont mutate kind's local-path-storage ns
jeff-mccoy May 13, 2022
82cd7f7
auto-inject "private-git-server" secret & mutate GitRepo CRD to use it
jeff-mccoy May 13, 2022
df3c796
BB 1.33 / PLG Validation
jeff-mccoy May 17, 2022
232d255
fix git urls
jeff-mccoy May 17, 2022
57364d0
general PR cleanup
jeff-mccoy May 17, 2022
eb3cab5
make pipelines happy
jeff-mccoy May 17, 2022
614d0f2
Add Zarf Agent ADR
jeff-mccoy May 18, 2022
a72dd59
Run 2 replicas for zarf agent (very low resources)
jeff-mccoy May 18, 2022
0c2b263
final PR cleanup / version bump
jeff-mccoy May 18, 2022
4ff7075
fix bb gatekeeper wrecking the world for kind
jeff-mccoy May 19, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/build-rust-injector.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ jobs:
- name: "Install cosign"
uses: sigstore/[email protected]


- name: "Install Rust And Build"
uses: gmiam/[email protected]
with:
Expand Down
29 changes: 25 additions & 4 deletions .github/workflows/build-zarf-agent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,50 @@ on:
default: "master"

jobs:
build-injector:
build-agent:
runs-on: ubuntu-latest
steps:
- name: "Install GoLang"
uses: actions/setup-go@v2
with:
go-version: 1.18.x

- name: "Checkout Repo"
uses: actions/checkout@v2
with:
ref: ${{ github.event.inputs.branchName }}

- name: "Setup caching"
uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-

- name: "Install cosign"
uses: sigstore/[email protected]

- name: Set up Docker Buildx
- name: "Set up Docker Buildx"
id: buildx
uses: docker/setup-buildx-action@v2

- name: Login to Docker Hub
- name: "Login to Docker Hub"
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: "Build zarf binaries"
run: make build-cli-linux

- name: "Rename binaries for packaging"
run: mv build/zarf build/zarf-linux-amd64 && mv build/zarf-arm build/zarf-linux-arm64

- name: "Build and Publish the Image"
run: buildx build --push --platform linux/arm64/v8,linux/amd64 --tag defenseunicorns/zarf-agent:${{ github.event.inputs.versionTag }} .
run: docker buildx build --push --platform linux/arm64/v8,linux/amd64 --tag defenseunicorns/zarf-agent:${{ github.event.inputs.versionTag }} .

- name: "Sign the Image"
run: cosign sign --key awskms:///${{ secrets.COSIGN_AWS_KMS_KEY }} -a release-engineer=https://github.com/${{ github.actor }} -a version=${{ github.event.inputs.versionTag }} defenseunicorns/zarf-agent:${{ github.event.inputs.versionTag }}
Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,33 @@ jobs:
uses: actions/setup-go@v2
with:
go-version: 1.18.x

- name: Checkout Repo
uses: actions/checkout@v2

- name: "Setup caching"
uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-

- name: Build Things For Release
run: make build-cli init-package

- name: Set AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_GOV_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_GOV_SECRET_ACCESS_KEY }}
aws-region: us-gov-west-1

- name: Push Release Artifacts to S3 Bucket
run: aws s3 cp build s3://zarf-public/release/${{ github.ref_name }} --region us-gov-west-1 --recursive

- name: Create a Release For This Tag
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/test-k3d.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,26 @@ jobs:
uses: actions/setup-go@v2
with:
go-version: 1.18.x

- name: "Checkout Repo"
uses: actions/checkout@v2

- name: "Setup caching"
uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-

- name: "Build CLI"
run: make build-cli-linux

- name: "Make Packages"
run: make init-package package-example-game package-example-data-injection package-example-gitops-data package-example-compose

- name: "Run Tests"
# NOTE: This test run will create its own K3d cluster. A single cluster will be used throughout the test run.
run: TESTDISTRO=k3d make test-e2e
14 changes: 14 additions & 0 deletions .github/workflows/test-k3s.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,26 @@ jobs:
uses: actions/setup-go@v2
with:
go-version: 1.18.x

- name: "Checkout Repo"
uses: actions/checkout@v2

- name: "Setup caching"
uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-

- name: "Build CLI"
run: make build-cli-linux

- name: "Make Packages"
run: make init-package package-example-game package-example-data-injection package-example-gitops-data package-example-compose

- name: "Run Tests"
# NOTE: "PATH=$PATH" preserves the default user $PATH. This is needed to maintain the version of go installed
# in a previous step. This test run will use Zarf to create a K3s cluster, and a brand new cluster will be
Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/test-kind.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,29 @@ jobs:
uses: actions/setup-go@v2
with:
go-version: 1.18.x

- name: "Checkout Repo"
uses: actions/checkout@v2

- name: "Create k8s Kind Cluster"
uses: helm/[email protected]

- name: "Setup caching"
uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-

- name: "Build CLI"
run: make build-cli-linux

- name: "Make Packages"
run: make init-package package-example-game package-example-data-injection package-example-gitops-data package-example-compose

- name: "Run Tests"
# NOTE: We want to test providing a cluster to the test framework so this one creates its own KinD cluster
# rather than having the test suite do it. The K3d tests do a self-provisioned cluster and the K3s tests
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ test/tf/public-ec2-instance/.terraform
terraform.tfstate
terraform.tfstate.backup
.terraform.lock.hcl
cosign.key
.zarf*
zarf-pki
.scratch/
Expand Down
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM scratch
ARG TARGETARCH

ADD "build/zarf-linux-$TARGETARCH" /zarf
EXPOSE 8443

ENV USER=zarf

CMD ["/zarf", "agent", "-l=trace"]
30 changes: 25 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ ifneq ($(UNAME_S),Linux)
endif
endif

CLI_VERSION := $(if $(shell git describe --tags), $(shell git describe --tags), "UnknownVersion")
BUILD_ARGS := -s -w -X 'github.com/defenseunicorns/zarf/src/config.CLIVersion=$(CLI_VERSION)'
.DEFAULT_GOAL := help

.PHONY: help
Expand All @@ -38,17 +40,35 @@ vm-destroy: ## Destroy the VM
clean: ## Clean the build dir
rm -rf build

build-cli-linux: build-injector-registry ## Build the Linux CLI
cd src && $(MAKE) build
build-cli-linux-amd: build-injector-registry
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="$(BUILD_ARGS)" -o build/zarf src/main.go

build-cli-mac: build-injector-registry ## Build the Mac CLI
cd src && $(MAKE) build-mac
build-cli-linux-arm: build-injector-registry
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="$(BUILD_ARGS)" -o build/zarf-arm src/main.go

build-cli: build-injector-registry build-cli-linux build-cli-mac ## Build the CLI
build-cli-mac-intel: build-injector-registry
GOOS=darwin GOARCH=amd64 go build -ldflags="$(BUILD_ARGS)" -o build/zarf-mac-intel src/main.go

build-cli-mac-apple: build-injector-registry
GOOS=darwin GOARCH=arm64 go build -ldflags="$(BUILD_ARGS)" -o build/zarf-mac-apple src/main.go

build-cli-linux: build-cli-linux-amd build-cli-linux-arm

build-cli: build-cli-linux-amd build-cli-linux-arm build-cli-mac-intel build-cli-mac-apple ## Build the CLI

build-injector-registry:
cd src/injector/stage2 && $(MAKE) build-bootstrap-registry

# Inject and deploy a new dev version of zarf agent for testing (should have an existing zarf agent deployemt)
# @todo: find a clean way to support Kind or k3d: k3d image import $(tag)
dev-agent-image:
$(eval tag := defenseunicorns/dev-zarf-agent:$(shell date +%s))
$(eval arch := $(shell uname -m))
CGO_ENABLED=0 GOOS=linux go build -o build/zarf-linux-$(arch) src/main.go
DOCKER_BUILDKIT=1 docker build --tag $(tag) --build-arg TARGETARCH=$(arch) . && \
kind load docker-image zarf-agent:$(tag) && \
kubectl -n zarf set image deployment/agent-hook server=$(tag)

init-package: ## Create the zarf init package, macos "brew install coreutils" first
$(ZARF_BIN) package create --confirm --architecture amd64
$(ZARF_BIN) package create --confirm --architecture arm64
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ Zarf is written entirely in [go](https://go.dev/), except for a single 400Kb bin
- The OCI Registries used are both from [Docker](https://github.com/distribution/distribution)
- Currently, the Registry and Git servers _are not HA_, see [#375](https://github.com/defenseunicorns/zarf/issues/376) and [#376](https://github.com/defenseunicorns/zarf/issues/376) for discussion on this
- To avoid TLS issues, Zarf binds to `127.0.0.1:31999` on each node as a [NodePort](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport) to allow all nodes to access the pod(s) in the cluster
- Until [#306](https://github.com/defenseunicorns/zarf/pull/306) is merged, during helm install/upgrade a [Helm PostRender](https://helm.sh/docs/topics/advanced/#post-rendering) function is called to mutate images and [ImagePullSecrets](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod) so the deployed resources use the NodePort binding
- A [mutating webhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) we call the Zarf Agent handles updating pod's [ImagePullSecrets](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod) so the deployed resources use the NodePort binding
- Zarf uses a custom injector system to bootstrap a new cluster. See the PR [#329](https://github.com/defenseunicorns/zarf/pull/329) and [ADR](docs/adr/0003-image-injection-into-remote-clusters-without-native-support.md) for more details on how we came to this solution. The general steps are listed below:
- Get a list of images in the cluster
- Attempt to create an ephemeral pod using an image from the list
Expand All @@ -301,5 +301,4 @@ Zarf is written entirely in [go](https://go.dev/), except for a single 400Kb bin
### Zarf Architecture
![Architecture Diagram](./docs/architecture.drawio.svg)


[Source DrawIO](docs/architecture.drawio.svg)
21 changes: 21 additions & 0 deletions docs/adr/0005-mutating-webhook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 5. Mutating Webhook

Date: 2022-05-18

## Status

Accepted

## Context

Currently Zarf leverages [Helm Post Rendering](https://helm.sh/docs/topics/advanced/#post-rendering) to mutate image paths and secrets for K8s to use the internal [Zarf Registry](../../packages/zarf-registry/README.md). This works well for simple K8s deployments where Zarf is performing the actual manifest apply but fails when using a secondary gitops tools suchs as [Flux](https://github.com/fluxcd/flux2), [ArgoCD](https://argo-cd.readthedocs.io/en/stable/), etc. At that point, Zarf is unable to provide mutation and it is dependent on the package author to do the mutations themselves using rudimentary templating. Further, this issue also exists when for CRDs that references the [git server](../../packages/gitea/README.md). A `zarf prepare` command was added previously to make this less painful, but it still requires additional burden on package authors to do something we are able to prescribe in code.

## Decision

A [mutating webhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) is standard practice in K8s and there [are a lot of them](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#what-does-each-admission-controller-do). Using the normal Zarf componenet structure and deployment strategy we can leverage a mutating webhook to perform automatic imagePullSecret binding and image path updates as well as add additional as-needed mutations such as updating the [GitRepository](https://fluxcd.io/docs/components/source/gitrepositories/) CRD with the appropriate secret and custom URL for the git server if someone is using Flux.

## Consequences

While deploying the webhook will greatly reduce the package development burden, the nature of how helm manages resources still means we will have to be careful how we apply secrets that could collide with secrets deployed by helm with other tools. Additionally, to keep the webhook simple we are foregoing any side-effects in this iteration such as creating secrets on-demand in a namespace as it is created. Adding side effects carries with it the need to roll those back on failure, handle additional RBAC in the cluster and integrate with the K8s API in the webhook. Therefore, some care will have to be taken for now with how registry and git secrets are generated in a namespace. For example, in the case of [Big Bang](https://repo1.dso.mil/platform-one/big-bang/bigbang) these secrets can be created by those helm charts if we pass in the proper configuration.

Another benefit of this approach is another layer security for Zarf clusters. The Zarf Agent will act as an intermediary not allowing images not in the Zarf Registry or git repos not stored in the internal git server.
2 changes: 1 addition & 1 deletion docs/architecture.drawio.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Zarf's work necessitates that some components are "always on" (a.k.a. required &
| | Description |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
| container-seed-registry | Adds a container registry so Zarf can bootstrap itself into the cluster. |
| container-registry | Adds a container registry service—[docker registry](https://docs.docker.com/registry/)—into the cluster. |
| zarf-registry | Adds a container registry service—[docker registry](https://docs.docker.com/registry/)—into the cluster. |

 

Expand Down
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ To test create a virtual area to test all examples, you can run `make all` or `m

| Example | Description |
|------------------------------------------------------------------|-------------|
| [big-bang](./big-bang/README.md) | Demo BigBang v1.28.0 with all of its core services |
| [big-bang](./big-bang/README.md) | Demo BigBang v1.33.0 with all of its core services |
| [composable-packages](./composable-packages/README.md) | Demo building packages using components from other packages |
| [data-injection](./data-injection/README.md) | Demo injecting data into a pod running on cluster |
| [game](./game/README.md) | Demo deploying old-school DOS games |
Expand Down
9 changes: 0 additions & 9 deletions examples/big-bang/kustomization/git-secret.yaml

This file was deleted.

17 changes: 1 addition & 16 deletions examples/big-bang/kustomization/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,24 +1,9 @@
bases:
- git::https://repo1.dso.mil/platform-one/big-bang/bigbang.git/base?ref=tags/1.28.0
- git::https://repo1.dso.mil/platform-one/big-bang/bigbang.git/base?ref=tags/1.33.0

configMapGenerator:
- name: common
namespace: bigbang
behavior: merge
files:
- values.yaml

resources:
- git-secret.yaml

patchesStrategicMerge:
- |-
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: bigbang
namespace: bigbang
spec:
url: http://zarf-gitea-http.zarf.svc.cluster.local:3000/zarf-git-user/mirror__repo1.dso.mil__platform-one__big-bang__bigbang.git
secretRef:
name: zarf-git-secret
Loading