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

chore: 🧑‍💻 add development environement script #34

Merged
merged 3 commits into from
Aug 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.github/
ci/
kind/
.release-please-manifest.json
release-please-manifest.json
README.md
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
go.work
go.work.sum
tmp/
__pycache__
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Dev stage
FROM --platform=${BUILDPLATFORM:-linux/amd64} docker.io/golang:1.22.4 AS dev

RUN go install github.com/air-verse/air@latest
WORKDIR /go/src/app
COPY go.mod go.mod
Expand Down
117 changes: 117 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
SHELL := /bin/bash
DOCKER := $(shell type -p docker)
KIND := $(shell type -p kind)
HELM := $(shell type -p helm)
KUBECTL := $(shell type -p helm)

WEBHOOK_IMAGE := external-dns-midaas-webhook:dev
WEBHOOK_FOLDER := ./

MIDAAS_IMAGE := api-midaas:dev
MIDAAS_FOLDER := ./contribute/midaas-ws/

export MIDAAS_WS_URL ?= http://midaas.default:8080/ws/
export MIDAAS_DEV_SUFFIX ?= dev.local
export MIDAAS_ENV_KEYNAME ?= d1
export MIDAAS_ENV_KEYVALUE ?= test
export MIDAAS_ENV_ZONES ?= $(MIDAAS_ENV_KEYNAME).$(MIDAAS_DEV_SUFFIX)

KIND_CLUSTER_NAME ?= midaas
KIND_INGRESS_CONTROLLER = NGINX

# Commons targets

all: deploy-MIDAAS deploy-WEBHOOK create-test-ingress

clean: delete-cluster delete-image-MIDAAS delete-image-WEBHOOK

create-test-ingress: create-cluster check-prerequisites-kubectl
@kubectl apply -f ./contribute/ressources/ingress.yaml

logs-%:
@kubectl logs -f deployments/external-dns -c $*

midaas-get-zone:
@kubectl exec midaas cat /tmp/$(MIDAAS_ENV_KEYNAME).$(MIDAAS_DEV_SUFFIX) | jq

# Check prerequisites

check-prerequisites-docker:
ifeq ("$(wildcard ${DOCKER})","")
@echo "docker not found" ; exit 1
endif
check-prerequisites-kind:
ifeq ("$(wildcard ${KIND})","")
@echo "'kind' not found" ; exit 1
endif
check-prerequisites-kubectl:
ifeq ("$(wildcard ${KUBECTL})","")
@echo "'kubectl' not found" ; exit 1
endif
check-prerequisites-helm:
ifeq ("$(wildcard ${HELM})","")
@echo "'helm' not found" ; exit 1
endif

# Kind targets

create-cluster: check-prerequisites-kind
ifeq ($(shell kind get clusters |grep $(KIND_CLUSTER_NAME)), $(KIND_CLUSTER_NAME))
@echo "Kind cluster '$(KIND_CLUSTER_NAME)' already exists, skipping"
else
@kind create cluster --name $(KIND_CLUSTER_NAME) --config ./contribute/kind/kind-config.yaml
@kubectl config use-context kind-$(KIND_CLUSTER_NAME)
endif

delete-cluster: check-prerequisites-kind
ifeq ($(shell kind get clusters |grep $(KIND_CLUSTER_NAME)), $(KIND_CLUSTER_NAME))
@kind delete cluster --name $(KIND_CLUSTER_NAME)
endif

start-ingress-controller: create-cluster
ifeq ($(KIND_INGRESS_CONTROLLER), NGINX)
@if [ ! -s /tmp/external-dns-nginx.yaml ]; then curl -Ls https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml > /tmp/external-dns-nginx.yaml; fi
@kubectl apply -f /tmp/external-dns-nginx.yaml
@kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=90s
else ifeq ($(KIND_INGRESS_CONTROLLER), TRAEFIK)
@echo traefik
endif

# Docker build and push targets
build-%: check-prerequisites-docker
@if [ $* = WEBHOOK ]; then docker build --target dev ${OPTIONS} -t ${$*_IMAGE} ${$*_FOLDER}; else docker build ${OPTIONS} -t ${$*_IMAGE} ${$*_FOLDER}; fi

push-%: check-prerequisites-kind
kind load docker-image ${$*_IMAGE} --name $(KIND_CLUSTER_NAME)

delete-image-%: check-prerequisites-docker
docker rmi ${$*_IMAGE}

# Midaas deployment targets
delete-MIDAAS: create-cluster check-prerequisites-kubectl
@kubectl delete pod midaas --ignore-not-found
@kubectl delete svc midaas --ignore-not-found

deploy-MIDAAS: create-cluster check-prerequisites-kubectl build-MIDAAS push-MIDAAS delete-MIDAAS
@kubectl run --image $(MIDAAS_IMAGE) --expose=true --port 8080 \
--env "MIDAAS_KEYNAME=$(MIDAAS_ENV_KEYNAME)" \
--env "MIDAAS_KEYVALUE=$(MIDAAS_ENV_KEYVALUE)" \
--env "MIDAAS_ZONES=$(MIDAAS_ENV_ZONES)" midaas
@echo "Kubernetes midaas service is listening on port 8080"


# Webhook deployment targets

delete-WEBHOOK: create-cluster check-prerequisites-helm
@if [ "external-dns" == "$(shell helm ls -f external-dns -o json |jq -r .[].name)" ]; then helm delete external-dns; else echo "No external-dns release is currently running"; fi

deploy-WEBHOOK: start-ingress-controller check-prerequisites-helm build-WEBHOOK push-WEBHOOK delete-WEBHOOK
@echo "Adding repository"
@helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
@envsubst < ./contribute/ressources/external-dns-values.yaml > /tmp/external-dns-values.yaml
@helm upgrade --force --install external-dns external-dns/external-dns -f /tmp/external-dns-values.yaml
@echo "external DNS is running with webhook in sidecar"

68 changes: 63 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,22 @@ helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
1. Create the helm values file `external-dns-midaas-values.yaml`:

```yaml
sources:
- ingress
# -- How DNS records are synchronized between sources and providers; available values are `sync` & `upsert-only`.
policy: sync
# -- Specify the registry for storing ownership and labels.
# Valid values are `txt`, `aws-sd`, `dynamodb` & `noop`.
# If `noop` midaas manage all records on zone
registry: txt
# can restrict zone
domainFilters: ["subzone.d1.dev.example.com"]
domainFilters: []
provider:
name: webhook
webhook:
image: ghcr.io/titigmr/external-dns-midaas-webhook
tag: latest
image:
repository: ghcr.io/titigmr/external-dns-midaas-webhook
tag: latest
env:
- name: PROVIDER_DNS_ZONE_SUFFIX
value: "dev.example.com"
Expand All @@ -42,7 +45,7 @@ provider:
2. Create helm deployment:

```sh
helm install external-dns external-dns -f external-dns-midaas-values.yaml
helm install external-dns external-dns/external-dns -f external-dns-midaas-values.yaml
```

## Parameters references
Expand All @@ -64,7 +67,62 @@ For example, `TSIG_ZONE_d1` with `PROVIDER_DNS_ZONE_SUFFIX` with `dev.example.co

## Local development

🚧 Work in progress.
### Prerequisite

Download and install on your local machine:
- `make` in Debian/Ubuntu distrib with
```bash
sudo apt install build-essential
```
- [docker](https://docs.docker.com/engine/install/)
- [kubectl](https://github.com/kubernetes/kubectl)
- [kind](https://github.com/kubernetes-sigs/kind)
- [helm](https://github.com/helm/helm)

### Usage


You can create a development stack locally with this command:

```sh
make
```

This target do the following target successively:
- `create-cluster` : create a `kind` cluster locally with an ingress controller configured
- `deploy-MIDAAS` : build, push and deploy `midaas` [webservice mock](./contribute/midaas-ws/) in the cluster
- `deploy-WEBHOOK` : build, push and deploy `external-dns` with the midaas webhook in development mode. You can modify the code with hot reload.

For example, for restarting the webhook:

```bash
make deploy-WEBHOOK
```

Don't forget create an ingress for trigger `external-dns`, an [example](./contribute/ressources/ingress.yaml) can be created with:

```bash
make create-test-ingress
```

You can read the containers logs with:

```bash
make logs-webhook
```

or

```bash
make logs-external-dns
```

To clean all the components

```sh
make clean
```


## Contributions

Expand Down
38 changes: 38 additions & 0 deletions contribute/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Run all stack locally with docker

## Kind cluster

One single node is deployed but it can be customized in `./kind/kind-config.yml`. The cluster comes with [Traefik](https://doc.traefik.io/traefik/providers/kubernetes-ingress/) or [Nginx](https://kind.sigs.k8s.io/docs/user/ingress/#ingress-nginx) ingress controller installed with port mapping on both ports `8080` and `8443`.

The node is using `extraMounts` to provide a volume binding between host working directory and `/app` to give the ability to bind mount volumes into containers during development.


## Midaas Webservice

A wrapper of midaas is available for development on folder `./midaas-ws`. Note that tool not really do dns records. It only writes fake domain on container filesystem.

This webservice is written in python with `Fastapi` framework. The webservice listen on 3 endpoints:
- `GET` - `/ws/{domaine}` : retrieve all domains for a specific zone
- `PUT` - `/ws/{domaine}/{type}/{valeur}` : add or modify a DNS record
You must add this body in the request:
```json
{"ttl": 0, "keyname": "string", "keyvalue": "string"}
```
- `DELETE` - `/ws/{domaine}/{type}/{valeur}` : add or modify a DNS
You must add this body in the request:
```json
{"keyname": "string", "keyvalue": "string"}
```

The midaas webservice can be configured with the following environment variables:

| Name | Description | Default |
| --------------- | ---------------------- | --------- |
| MIDAAS_KEYNAME | TSIG Keyname | test |
| MIDAAS_KEYVALUE | TSIG Keyvalue | test |
| MIDAAS_ZONE | Zone managed by MiDaas | dev.local |


## External-DNS Locally

:construction:
21 changes: 21 additions & 0 deletions contribute/kind/kind-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 8080
protocol: TCP
- containerPort: 443
hostPort: 8443
protocol: TCP
extraMounts:
- hostPath: ./
containerPath: /app
17 changes: 17 additions & 0 deletions contribute/kind/traefik-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
providers:
kubernetesCRD:
enabled: false
kubernetesIngress:
namespaces:
- default
- ingress-traefik

ports:
web:
hostPort: 80
websecure:
hostPort: 443

service:
type: ClusterIP
7 changes: 7 additions & 0 deletions contribute/midaas-ws/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM python:3.9
WORKDIR /app
COPY ./requirements.txt .
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
COPY main.py .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080", "--reload"]

Loading