Skip to content

Commit

Permalink
Merge pull request #279 from uselagoon/local-dev-tools
Browse files Browse the repository at this point in the history
chore: add local-dev tools
  • Loading branch information
shreddedbacon authored Jan 15, 2025
2 parents 45fff5a + 95233f0 commit ffab3c1
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 69 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/remote-controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ jobs:
- name: Configure node IP in kind-config.yaml
run: |
docker network create remote-controller
LAGOON_KIND_CIDR_BLOCK=$(docker network inspect remote-controller | jq '. [0].IPAM.Config[0].Subnet' | tr -d '"')
docker network create kind
LAGOON_KIND_CIDR_BLOCK=$(docker network inspect kind | jq '. [0].IPAM.Config[0].Subnet' | tr -d '"')
export KIND_NODE_IP=$(echo ${LAGOON_KIND_CIDR_BLOCK%???} | awk -F'.' '{print $1,$2,$3,240}' OFS='.')
envsubst < test-resources/test-suite.kind-config.yaml.tpl > test-resources/test-suite.kind-config.yaml
Expand All @@ -110,7 +110,7 @@ jobs:

- name: Check node IP matches kind configuration
run: |
LAGOON_KIND_CIDR_BLOCK=$(docker network inspect remote-controller | jq '. [0].IPAM.Config[0].Subnet' | tr -d '"')
LAGOON_KIND_CIDR_BLOCK=$(docker network inspect kind | jq '. [0].IPAM.Config[0].Subnet' | tr -d '"')
NODE_IP=$(echo ${LAGOON_KIND_CIDR_BLOCK%???} | awk -F'.' '{print $1,$2,$3,240}' OFS='.')
echo Checking for NODE_IP "$NODE_IP"
grep $NODE_IP test-resources/test-suite.kind-config.yaml
Expand All @@ -127,4 +127,4 @@ jobs:

- name: Run github/test-e2e
run: |
make github/test-e2e HARBOR_VERSION=${{matrix.harbor}} OVERRIDE_BUILD_DEPLOY_DIND_IMAGE="${{matrix.lagoon_build_image}}"
make github/test-e2e HARBOR_VERSION=${{matrix.harbor}} OVERRIDE_BUILD_DEPLOY_DIND_IMAGE="${{matrix.lagoon_build_image}}" KIND_NETWORK=kind
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ bin
*~

test-resources/test-suite.kind-config.yaml
test-resources/test-suite.metallb-pool.yaml
test-resources/test-suite.metallb-pool.yaml

local-dev
171 changes: 134 additions & 37 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
SHELL := /bin/bash

# Image URL to use all building/pushing image targets
IMG ?= controller:latest
Expand All @@ -18,11 +19,115 @@ INGRESS_VERSION=4.9.1
HARBOR_VERSION=1.14.3

KIND_CLUSTER ?= remote-controller
KIND_NETWORK ?= remote-controller

TIMEOUT = 30m
HELM = helm
KUBECTL = kubectl
JQ = jq

KIND_VERSION = v0.25.0
KUBECTL_VERSION := v1.31.0
HELM_VERSION := v3.16.1
GOJQ_VERSION = v0.12.16
KUSTOMIZE_VERSION := v5.4.3

HELM = $(realpath ./local-dev/helm)
KUBECTL = $(realpath ./local-dev/kubectl)
JQ = $(realpath ./local-dev/jq)
KIND = $(realpath ./local-dev/kind)
KUSTOMIZE = $(realpath ./local-dev/kustomize)

ARCH := $(shell uname | tr '[:upper:]' '[:lower:]')


.PHONY: local-dev/kind
local-dev/kind:
ifeq ($(KIND_VERSION), $(shell kind version 2>/dev/null | sed -nE 's/kind (v[0-9.]+).*/\1/p'))
$(info linking local kind version $(KIND_VERSION))
ln -sf $(shell command -v kind) ./local-dev/kind
else
ifneq ($(KIND_VERSION), $(shell ./local-dev/kind version 2>/dev/null | sed -nE 's/kind (v[0-9.]+).*/\1/p'))
$(info downloading kind version $(KIND_VERSION) for $(ARCH))
mkdir -p local-dev
rm local-dev/kind || true
curl -sSLo local-dev/kind https://kind.sigs.k8s.io/dl/$(KIND_VERSION)/kind-$(ARCH)-amd64
chmod a+x local-dev/kind
endif
endif

.PHONY: local-dev/kustomize
local-dev/kustomize:
ifeq ($(KUSTOMIZE_VERSION), $(shell kustomize version 2>/dev/null | sed -nE 's/(v[0-9.]+).*/\1/p'))
$(info linking local kustomize version $(KUSTOMIZE_VERSION))
ln -sf $(shell command -v kind) ./local-dev/kind
else
ifneq ($(KUSTOMIZE_VERSION), $(shell ./local-dev/kustomize version 2>/dev/null | sed -nE 's/(v[0-9.]+).*/\1/p'))
$(info downloading kustomize version $(KUSTOMIZE_VERSION) for $(ARCH))
rm local-dev/kustomize || true
curl -sSL https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F$(KUSTOMIZE_VERSION)/kustomize_$(KUSTOMIZE_VERSION)_$(ARCH)_amd64.tar.gz | tar -xzC local-dev
chmod a+x local-dev/kustomize
endif
endif

.PHONY: local-dev/helm
local-dev/helm:
ifeq ($(HELM_VERSION), $(shell helm version --short --client 2>/dev/null | sed -nE 's/(v[0-9.]+).*/\1/p'))
$(info linking local helm version $(HELM_VERSION))
ln -sf $(shell command -v helm) ./local-dev/helm
else
ifneq ($(HELM_VERSION), $(shell ./local-dev/helm version --short --client 2>/dev/null | sed -nE 's/(v[0-9.]+).*/\1/p'))
$(info downloading helm version $(HELM_VERSION) for $(ARCH))
rm local-dev/helm || true
curl -sSL https://get.helm.sh/helm-$(HELM_VERSION)-$(ARCH)-amd64.tar.gz | tar -xzC local-dev --strip-components=1 $(ARCH)-amd64/helm
chmod a+x local-dev/helm
endif
endif

.PHONY: local-dev/jq
local-dev/jq:
ifeq ($(GOJQ_VERSION), $(shell gojq -v 2>/dev/null | sed -nE 's/gojq ([0-9.]+).*/v\1/p'))
$(info linking local gojq version $(GOJQ_VERSION))
ln -sf $(shell command -v gojq) ./local-dev/jq
else
ifneq ($(GOJQ_VERSION), $(shell ./local-dev/jq -v 2>/dev/null | sed -nE 's/gojq ([0-9.]+).*/v\1/p'))
$(info downloading gojq version $(GOJQ_VERSION) for $(ARCH))
rm local-dev/jq || true
ifeq ($(ARCH), darwin)
TMPDIR=$$(mktemp -d) \
&& curl -sSL https://github.com/itchyny/gojq/releases/download/$(GOJQ_VERSION)/gojq_$(GOJQ_VERSION)_$(ARCH)_arm64.zip -o $$TMPDIR/gojq.zip \
&& (cd $$TMPDIR && unzip gojq.zip) && cp $$TMPDIR/gojq_$(GOJQ_VERSION)_$(ARCH)_arm64/gojq ./local-dev/jq && rm -rf $$TMPDIR
else
curl -sSL https://github.com/itchyny/gojq/releases/download/$(GOJQ_VERSION)/gojq_$(GOJQ_VERSION)_$(ARCH)_amd64.tar.gz | tar -xzC local-dev --strip-components=1 gojq_$(GOJQ_VERSION)_$(ARCH)_amd64/gojq
mv ./local-dev/{go,}jq
endif
chmod a+x local-dev/jq
endif
endif

.PHONY: local-dev/kubectl
local-dev/kubectl:
ifeq ($(KUBECTL_VERSION), $(shell kubectl version --client 2>/dev/null | grep Client | sed -E 's/Client Version: (v[0-9.]+).*/\1/'))
$(info linking local kubectl version $(KUBECTL_VERSION))
ln -sf $(shell command -v kubectl) ./local-dev/kubectl
else
ifneq ($(KUBECTL_VERSION), $(shell ./local-dev/kubectl version --client 2>/dev/null | grep Client | sed -E 's/Client Version: (v[0-9.]+).*/\1/'))
$(info downloading kubectl version $(KUBECTL_VERSION) for $(ARCH))
rm local-dev/kubectl || true
curl -sSLo local-dev/kubectl https://storage.googleapis.com/kubernetes-release/release/$(KUBECTL_VERSION)/bin/$(ARCH)/amd64/kubectl
chmod a+x local-dev/kubectl
endif
endif

.PHONY: local-dev/tools
local-dev/tools: local-dev/kind local-dev/kustomize local-dev/kubectl local-dev/jq local-dev/helm

.PHONY: helm/repos
helm/repos: local-dev/helm
# install repo dependencies required by the charts
$(HELM) repo add lagoon https://uselagoon.github.io/lagoon-charts/
$(HELM) repo add harbor https://helm.goharbor.io
$(HELM) repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
$(HELM) repo add jetstack https://charts.jetstack.io
$(HELM) repo add metallb https://metallb.github.io/metallb
$(HELM) repo update

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
Expand Down Expand Up @@ -72,45 +177,45 @@ run: generate fmt vet manifests
# Install CRDs into a cluster
.PHONY: install
install: manifests
kustomize build config/crd | kubectl apply -f -
$(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f -

.PHONY: outputcrds
outputcrds: manifests
kustomize build config/crd
$(KUSTOMIZE) build config/crd

.PHONY: uninstall
# Uninstall CRDs from a cluster
uninstall: manifests
kustomize build config/crd | kubectl delete -f -
$(KUSTOMIZE) build config/crd | $(KUBECTL) delete -f -

# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
.PHONY: preview
preview: manifests
cd config/manager && kustomize edit set image controller=${IMG}
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
@export HARBOR_URL="https://registry.$$($(KUBECTL) -n ingress-nginx get services ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}' || echo 127.0.0.1).nip.io" && \
echo "OVERRIDE_BUILD_DEPLOY_DIND_IMAGE=${OVERRIDE_BUILD_DEPLOY_DIND_IMAGE}" > config/default/config.properties && \
echo "HARBOR_URL=$${HARBOR_URL}" >> config/default/config.properties && \
echo "HARBOR_API=$${HARBOR_URL}/api" >> config/default/config.properties
OVERRIDE_BUILD_DEPLOY_DIND_IMAGE=${OVERRIDE_BUILD_DEPLOY_DIND_IMAGE} kustomize build config/default
OVERRIDE_BUILD_DEPLOY_DIND_IMAGE=${OVERRIDE_BUILD_DEPLOY_DIND_IMAGE} $(KUSTOMIZE) build config/default
cp config/default/config.properties.default config/default/config.properties

# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
# this is only used locally for development or in the test suite
.PHONY: deploy
deploy: manifests
cd config/manager && kustomize edit set image controller=${IMG}
@if kind get clusters | grep -q $(KIND_CLUSTER); then \
kind export kubeconfig --name=$(KIND_CLUSTER) \
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
@if $(KIND) get clusters | grep -q $(KIND_CLUSTER); then \
$(KIND) export kubeconfig --name=$(KIND_CLUSTER) \
&& export HARBOR_URL="https://registry.$$($(KUBECTL) -n ingress-nginx get services ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}').nip.io"; \
fi && \
echo "OVERRIDE_BUILD_DEPLOY_DIND_IMAGE=${OVERRIDE_BUILD_DEPLOY_DIND_IMAGE}" > config/default/config.properties && \
echo "HARBOR_URL=$${HARBOR_URL}" >> config/default/config.properties && \
echo "HARBOR_API=$${HARBOR_URL}/api" >> config/default/config.properties
OVERRIDE_BUILD_DEPLOY_DIND_IMAGE=${OVERRIDE_BUILD_DEPLOY_DIND_IMAGE} kustomize build config/default | kubectl apply -f -
OVERRIDE_BUILD_DEPLOY_DIND_IMAGE=${OVERRIDE_BUILD_DEPLOY_DIND_IMAGE} $(KUSTOMIZE) build config/default | $(KUBECTL) apply -f -
cp config/default/config.properties.default config/default/config.properties

.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
manifests: controller-gen local-dev/tools ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases

# Build the docker image
Expand Down Expand Up @@ -140,7 +245,7 @@ endif

.PHONY: install-metallb
install-metallb:
LAGOON_KIND_CIDR_BLOCK=$$(docker network inspect $(KIND_CLUSTER) | $(JQ) '. [0].IPAM.Config[0].Subnet' | tr -d '"') && \
LAGOON_KIND_CIDR_BLOCK=$$(docker network inspect $(KIND_NETWORK) | $(JQ) '. [0].IPAM.Config[0].Subnet' | tr -d '"') && \
export LAGOON_KIND_NETWORK_RANGE=$$(echo $${LAGOON_KIND_CIDR_BLOCK%???} | awk -F'.' '{print $$1,$$2,$$3,240}' OFS='.')/29 && \
$(HELM) upgrade \
--install \
Expand All @@ -152,7 +257,7 @@ install-metallb:
metallb \
metallb/metallb && \
$$(envsubst < test-resources/test-suite.metallb-pool.yaml.tpl > test-resources/test-suite.metallb-pool.yaml) && \
$(KUBECTL) apply -f test-resources/test-suite.metallb-pool.yaml \
$(KUBECTL) apply -f test-resources/test-suite.metallb-pool.yaml

# cert-manager is used to allow self-signed certificates to be generated automatically by ingress in the same way lets-encrypt would
.PHONY: install-certmanager
Expand Down Expand Up @@ -233,41 +338,33 @@ install-lagoon-remote: install-registry
lagoon \
lagoon/lagoon-remote

# .PHONY: create-kind-cluster
# create-kind-cluster:
# @if ! kind get clusters | grep -q $(KIND_CLUSTER); then \
# docker network inspect $(KIND_CLUSTER) >/dev/null 2>&1 || docker network create $(KIND_CLUSTER) \
# && export KIND_NODE_IP=$$(docker run --network $(KIND_CLUSTER) --rm alpine ip -o addr show eth0 | sed -nE 's/.* ([0-9.]{7,})\/.*/\1/p') \
# && envsubst < test-resources/test-suite.kind-config.yaml.tpl > test-resources/test-suite.kind-config.yaml \
# && kind create cluster --wait=60s --name=$(KIND_CLUSTER) --config=test-resources/test-suite.kind-config.yaml; \
# else \
# echo "Cluster $(KIND_CLUSTER) already exists"; \
# fi

.PHONY: create-kind-cluster
create-kind-cluster:
docker network inspect $(KIND_CLUSTER) >/dev/null || docker network create $(KIND_CLUSTER) \
&& LAGOON_KIND_CIDR_BLOCK=$$(docker network inspect $(KIND_CLUSTER) | $(JQ) '. [0].IPAM.Config[0].Subnet' | tr -d '"') \
create-kind-cluster: local-dev/tools helm/repos
docker network inspect $(KIND_NETWORK) >/dev/null || docker network create $(KIND_NETWORK) \
&& LAGOON_KIND_CIDR_BLOCK=$$(docker network inspect $(KIND_NETWORK) | $(JQ) '. [0].IPAM.Config[0].Subnet' | tr -d '"') \
&& export KIND_NODE_IP=$$(echo $${LAGOON_KIND_CIDR_BLOCK%???} | awk -F'.' '{print $$1,$$2,$$3,240}' OFS='.') \
&& envsubst < test-resources/test-suite.kind-config.yaml.tpl > test-resources/test-suite.kind-config.yaml \
&& kind create cluster --wait=60s --name=$(KIND_CLUSTER) --config=test-resources/test-suite.kind-config.yaml
&& export KIND_EXPERIMENTAL_DOCKER_NETWORK=$(KIND_NETWORK) \
&& $(KIND) create cluster --wait=60s --name=$(KIND_CLUSTER) --config=test-resources/test-suite.kind-config.yaml

# Create a kind cluster locally and run the test e2e test suite against it
.PHONY: kind/test-e2e # Run the e2e tests against a Kind k8s instance that is spun up locally
kind/test-e2e: create-kind-cluster install-lagoon-remote kind/re-test-e2e

.PHONY: local-kind/test-e2e # Run the e2e tests against a Kind k8s instance that is spun up locally
kind/re-test-e2e:
export KIND_PATH=$(KIND) && \
export KUBECTL_PATH=$(KUBECTL) && \
export KIND_CLUSTER=$(KIND_CLUSTER) && \
kind export kubeconfig --name=$(KIND_CLUSTER) && \
$(KIND) export kubeconfig --name=$(KIND_CLUSTER) && \
export HARBOR_VERSION=$(HARBOR_VERSION) && \
export OVERRIDE_BUILD_DEPLOY_DIND_IMAGE=$(OVERRIDE_BUILD_DEPLOY_DIND_IMAGE) && \
$(MAKE) test-e2e

.PHONY: clean
kind/clean:
docker compose down && \
kind delete cluster --name=$(KIND_CLUSTER) && docker network rm $(KIND_CLUSTER)
$(KIND) delete cluster --name=$(KIND_CLUSTER) && docker network rm $(KIND_NETWORK)

# Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors.
.PHONY: test-e2e # Run the e2e tests against a Kind k8s instance that is spun up inside github action.
Expand All @@ -277,19 +374,19 @@ test-e2e:
go test ./test/e2e/ -v -ginkgo.v

.PHONY: github/test-e2e
github/test-e2e: install-lagoon-remote test-e2e
github/test-e2e: local-dev/tools install-lagoon-remote test-e2e

.PHONY: kind/set-kubeconfig
kind/set-kubeconfig:
export KIND_CLUSTER=$(KIND_CLUSTER) && \
kind export kubeconfig --name=$(KIND_CLUSTER)
$(KIND) export kubeconfig --name=$(KIND_CLUSTER)

.PHONY: kind/logs-remote-controller
kind/logs-remote-controller:
export KIND_CLUSTER=$(KIND_CLUSTER) && \
kind export kubeconfig --name=$(KIND_CLUSTER) && \
kubectl -n remote-controller-system logs -f \
$$(kubectl -n remote-controller-system get pod -l control-plane=controller-manager -o jsonpath="{.items[0].metadata.name}") \
$(KIND) export kubeconfig --name=$(KIND_CLUSTER) && \
$(KUBECTL) -n remote-controller-system logs -f \
$$($(KUBECTL) -n remote-controller-system get pod -l control-plane=controller-manager -o jsonpath="{.items[0].metadata.name}") \
-c manager

# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist
Expand Down
Loading

0 comments on commit ffab3c1

Please sign in to comment.