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

docs Add contributors guide #2

Merged
merged 19 commits into from
Apr 16, 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
10 changes: 5 additions & 5 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
project_name: external-dns-stackit-webhook
project_name: external-dns-selectel-webhook
snapshot:
name_template: '{{ .Tag }}-SNAPSHOT'
builds:
- id: external-dns-stackit-webhook
- id: external-dns-selectel-webhook
goos:
- linux
- windows
Expand All @@ -11,7 +11,7 @@ builds:
- amd64
- arm64
main: ./cmd/webhook
binary: external-dns-stackit-webhook
binary: external-dns-selectel-webhook
env:
- CGO_ENABLED=0
ldflags:
Expand All @@ -36,7 +36,7 @@ archives:
- goos: windows
format: zip
dockers:
- id: external-dns-stackit-webhook
- id: external-dns-selectel-webhook
use: buildx
image_templates:
- "{{ .Env.REGISTRY }}/{{ .Env.IMAGE_NAME }}:{{ .Tag }}"
Expand All @@ -46,7 +46,7 @@ dockers:
goarch: amd64
build_flag_templates:
- --label=org.opencontainers.image.title={{ .ProjectName }}
- --label=org.opencontainers.image.description=stackit DNS webhook for external-dns
- --label=org.opencontainers.image.description=selectel DNS webhook for external-dns
- --label=org.opencontainers.image.url=https://{{ .Env.GITHUB_SERVER_URL }}/{{ .Env.GITHUB_REPOSITORY}}
- --label=org.opencontainers.image.source=https://{{ .Env.GITHUB_SERVER_URL }}/{{ .Env.GITHUB_REPOSITORY}}
- --label=org.opencontainers.image.version={{ .Version }}
Expand Down
19 changes: 8 additions & 11 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
# Contributing to External DNS STACKIT Webhook
# Contributing to External DNS Selectel Webhook

Welcome and thank you for making it this far and considering contributing to external-dns-stackit-webhook.
Welcome and thank you for making it this far and considering contributing to external-dns-selectel-webhook.
We always appreciate any contributions by raising issues, improving the documentation, fixing bugs in the CLI or adding new features.

Before opening a PR please read through this document.
If you want to contribute but don't know how to start or have any questions feel free to reach out to us on [Github Discussions](https://github.com/stackitcloud/external-dns-stackit-webhook/discussions). Answering any questions or discussions there is also a great way to contribute to the community.

## Process of making an addition

> Please keep in mind to open an issue whenever you plan to make an addition to features to discuss it before implementing it.

To contribute any code to this repository just do the following:

1. Make sure you have Go's latest version installed
1. Make sure you have a Go version installed that is similar to the version of this project
2. Fork this repository
3. Run `make build` to make sure everything's setup correctly
4. Make your changes
Expand All @@ -28,10 +25,10 @@ To contribute any code to this repository just do the following:
> If any linting issues occur please fix them.
> Using a nolint directive should only be used as a last resort.
6. Open a PR and make sure the CI pipelines succeed.
> Your PR needs to have a semantic title, which can look like: `type(scope) Short Description`
> All available `scopes` & `types` are defined in [semantic.yml](https://github.com/stackitcloud/external-dns-stackit-webhook/blob/main/.github/semantic.yml)
> Your PR needs to have a semantic title, which can look like: `type(scope) Short description`
> All available `scopes` & `types` are defined in [semantic.yml](https://github.com/selectel/external-dns-selectel-webhook/blob/main/.github/semantic.yml)
>
> A example PR tile for adding a new feature for the CLI would looks like: `cli(feat) Add saving output to file`
7. Wait for one of the maintainers to review your code and react to the comments.
8. After approval merge the PR
> An example PR tile for adding a new feature for the CLI would look like: `cli(feat) Add saving output to file`
7. Wait for two of the maintainers to review your code and react to the comments.
8. After two approvals merge the PR
9. Thank you for your contribution! :)
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM gcr.io/distroless/static-debian11:nonroot

COPY external-dns-stackit-webhook /external-dns-stackit-webhook
COPY external-dns-selectel-webhook /external-dns-selectel-webhook

ENTRYPOINT ["/external-dns-stackit-webhook"]
ENTRYPOINT ["/external-dns-selectel-webhook"]
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ GOLANGCI_VERSION = 1.53.3
LICENCES_IGNORE_LIST = $(shell cat licenses/licenses-ignore-list.txt)

VERSION ?= 0.0.1
IMAGE_TAG_BASE ?= stackitcloud/external-dns-stackit-webhook
IMAGE_TAG_BASE ?= selectel/external-dns-selectel-webhook
IMG ?= $(IMAGE_TAG_BASE):$(VERSION)

BUILD_VERSION ?= $(shell git branch --show-current)
Expand All @@ -17,7 +17,7 @@ download:

.PHONY: build
build:
CGO_ENABLED=0 go build -ldflags "-s -w" -o ./bin/external-dns-stackit-webhook -v cmd/webhook/main.go
CGO_ENABLED=0 go build -ldflags "-s -w" -o ./bin/external-dns-selectel-webhook -v cmd/webhook/main.go

.PHONY: docker-build
docker-build:
Expand Down Expand Up @@ -67,7 +67,7 @@ $(GO_RELEASER):

.PHONY: release-check
release-check: $(GO_RELEASER) ## Check if the release will work
GITHUB_SERVER_URL=github.com GITHUB_REPOSITORY=stackitcloud/external-dns-stackit-webhook REGISTRY=$(REGISTRY) IMAGE_NAME=$(IMAGE_NAME) $(GO_RELEASER) release --snapshot --clean --skip-publish
GITHUB_SERVER_URL=github.com GITHUB_REPOSITORY=selectel/external-dns-selectel-webhook REGISTRY=$(REGISTRY) IMAGE_NAME=$(IMAGE_NAME) $(GO_RELEASER) release --snapshot --clean --skip-publish

GO_LICENSES = bin/go-licenses
$(GO_LICENSES):
Expand Down
166 changes: 37 additions & 129 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,36 @@
# STACKIT Webhook - ExternalDNS
# Selectel Webhook - ExternalDNS

[![GoTemplate](https://img.shields.io/badge/go/template-black?logo=go)](https://github.com/golang-standards/project-layout)
[![CI](https://github.com/stackitcloud/external-dns-stackit-webhook/actions/workflows/main.yml/badge.svg)](https://github.com/stackitcloud/external-dns-stackit-webhook/actions/workflows/main.yml)
[![Go Report Card](https://goreportcard.com/badge/github.com/stackitcloud/external-dns-stackit-webhook)](https://goreportcard.com/report/github.com/stackitcloud/external-dns-stackit-webhook)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![GitHub release](https://img.shields.io/github/release/stackitcloud/external-dns-stackit-webhook.svg)](https://github.com/stackitcloud/external-dns-stackit-webhook/releases)
[![Last Commit](https://img.shields.io/github/last-commit/stackitcloud/external-dns-stackit-webhook/main.svg)](https://github.com/stackitcloud/external-dns-stackit-webhook/commits/main)
[![GitHub issues](https://img.shields.io/github/issues/stackitcloud/external-dns-stackit-webhook.svg)](https://github.com/stackitcloud/external-dns-stackit-webhook/issues)
[![GitHub pull requests](https://img.shields.io/github/issues-pr/stackitcloud/external-dns-stackit-webhook.svg)](https://github.com/stackitcloud/external-dns-stackit-webhook/pulls)
[![GitHub stars](https://img.shields.io/github/stars/stackitcloud/external-dns-stackit-webhook.svg?style=social&label=Star&maxAge=2592000)](https://github.com/stackitcloud/external-dns-stackit-webhook/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/stackitcloud/external-dns-stackit-webhook.svg?style=social&label=Fork&maxAge=2592000)](https://github.com/stackitcloud/external-dns-stackit-webhook/network)
[![CI](https://github.com/selectel/external-dns-selectel-webhook/actions/workflows/main.yml/badge.svg)](https://github.com/selectel/external-dns-selectel-webhook/actions/workflows/main.yml)
[![Go Report Card](https://goreportcard.com/badge/github.com/selectel/external-dns-selectel-webhook)](https://goreportcard.com/report/github.com/selectel/external-dns-selectel-webhook)
[![GitHub release](https://img.shields.io/github/release/selectel/external-dns-selectel-webhook.svg)](https://github.com/selectel/external-dns-selectel-webhook/releases)
[![Last Commit](https://img.shields.io/github/last-commit/selectel/external-dns-selectel-webhook/main.svg)](https://github.com/selectel/external-dns-selectel-webhook/commits/main)
[![GitHub issues](https://img.shields.io/github/issues/selectel/external-dns-selectel-webhook.svg)](https://github.com/selectel/external-dns-selectel-webhook/issues)
[![GitHub pull requests](https://img.shields.io/github/issues-pr/selectel/external-dns-selectel-webhook.svg)](https://github.com/selectel/external-dns-selectel-webhook/pulls)
[![GitHub stars](https://img.shields.io/github/stars/selectel/external-dns-selectel-webhook.svg?style=social&label=Star&maxAge=2592000)](https://github.com/selectel/external-dns-selectel-webhook/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/selectel/external-dns-selectel-webhook.svg?style=social&label=Fork&maxAge=2592000)](https://github.com/selectel/external-dns-selectel-webhook/network)

ExternalDNS serves as an add-on for Kubernetes designed to automate the management of Domain Name System (DNS)
records for Kubernetes services by utilizing various DNS providers. While Kubernetes traditionally manages DNS
records internally, ExternalDNS augments this functionality by transferring the responsibility of DNS records
management to an external DNS provider such as STACKIT. Consequently, the STACKIT webhook enables the management
of your STACKIT domains within your Kubernetes cluster using
management to an external DNS provider such as Selectel. Consequently, the Selectel webhook enables the management
of your Selectel domains within your Kubernetes cluster using
[ExternalDNS](https://github.com/kubernetes-sigs/external-dns).

For utilizing ExternalDNS with STACKIT, it is mandatory to establish a STACKIT project, a service account
within the project, generate an authentication token for the service account, authorize the service account
to create and read dns zones, and finally, establish a STACKIT zone.
For utilizing ExternalDNS with Selectel, it is mandatory to establish a Selectel project, a service account
within the project, and finally, establish a Selectel zone.

## Kubernetes Deployment

The STACKIT webhook is presented as a standard Open Container Initiative (OCI) image released in the
[GitHub container registry](https://github.com/stackitcloud/external-dns-stackit-webhook/pkgs/container/external-dns-stackit-webhook).
The Selectel webhook is presented as a standard Open Container Initiative (OCI) image released in the
[GitHub container registry](https://github.com/selectel/external-dns-selectel-webhook/pkgs/container/external-dns-selectel-webhook).
The deployment is compatible with all Kubernetes-supported methods. The subsequent example
demonstrates the deployment as a
[sidecar container](https://kubernetes.io/docs/concepts/workloads/pods/#workload-resources-for-managing-pods)
within the ExternalDNS pod.

```shell
# We create a Secret from an auth token. Alternatively, you can also
# use keys to authenticate the webhook - see "Authentication" below.
kubectl create secret generic external-dns-stackit-webhook --from-literal=auth-token='<Your-Token>'
```shell
kubectl create secret generic external-dns-webhook --from-literal=password='<Service-User-Password>'
```

```shell
Expand Down Expand Up @@ -178,10 +174,12 @@ spec:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65534
image: ghcr.io/stackitcloud/external-dns-stackit-webhook:v0.2.0
image: ghcr.io/selectel/external-dns-selectel-webhook:v0.1.0
imagePullPolicy: IfNotPresent
args:
- --project-id=c158c736-0300-4044-95c4-b7d404279b35 # your project id
- --account-id=000000 # your account id
- --username=Username # your service user's name
ports:
- name: http
protocol: TCP
Expand All @@ -205,136 +203,46 @@ spec:
successThreshold: 1
timeoutSeconds: 5
env:
- name: AUTH_TOKEN
- name: PASSWORD
valueFrom:
secretKeyRef:
name: external-dns-stackit-webhook
key: auth-token
name: external-dns-webhook
key: password
EOF
```

## Configuration

The configuration of the STACKIT webhook can be accomplished through command line arguments and environment variables.
Below are the options that are available.
The configuration of the Selectel webhook can be accomplished through command line arguments and environment variables.
Below are the options that are available in format `--cli-argument`/`ENVIRONMENT_VARIABLE`.

- `--project-id`/`PROJECT_ID` (required): Specifies the project id of the STACKIT project.
- `--auth-token`/`AUTH_TOKEN` (required if `auth-key-path` is not set): Defines the authentication token for the STACKIT API. Mutually exclusive with 'auth-key-path'.
- `--auth-key-path`/`AUTH_KEY_PATH` (required if `auth-token` is not set): Defines the file path of the service account key for the STACKIT API. Mutually exclusive with 'auth-token'.
- `--project-id`/`PROJECT_ID` (required): Specifies the project id to authorize.
- `--account-id`/`ACCOUNT_ID` (required): Specifies the account id to authorize.
- `--username`/`USERNAME` (required): Specifies the username of your service user to authorize.
- `--password`/`PASSWORD` (required): Specifies the password of your service user to authorize.
- `--worker`/`WORKER` (optional): Specifies the number of workers to employ for querying the API. Given that we
need to iterate over all zones and records, it can be parallelized. However, it is important to avoid
setting this number excessively high to prevent receiving 429 rate limiting from the API (default 10).
- `--base-url`/`BASE_URL` (optional): Identifies the Base URL for utilizing the API (
default "https://dns.api.stackit.cloud").
- `--base-url`/`BASE_URL` (optional): Identifies the Base URL for utilizing the API
(default "https://api.selectel.ru/domains/v2"). The full list of Selectel API URLs you can
see [here](https://developers.selectel.ru/docs/control-panel/urls/).
- `--auth-url`/`AUTH_URL` (optional): Identifies the URL for utilizing the API to receive keystone-token
(default "https://cloud.api.selcloud.ru/identity/v3").
- `--api-port`/`API_PORT` (optional): Specifies the port to listen on (default 8888).
- `--domain-filter`/`DOMAIN_FILER` (optional): Establishes a filter for DNS zone names (default []).
- `--dry-run`/`DRY_RUN` (optional): Specifies whether to perform a dry run (default false).
- `--log-level`/`LOG_LEVEL` (optional): Defines the log level (default "info"). Possible values are: debug, info, warn,
error.

## FAQ

### 1. Issue with Creating Service using External DNS Annotation

If your zone is `example.runs.onstackit.cloud` and you're trying to create a service with the following external DNS
annotation:

```yaml
apiVersion: v1
kind: Service
metadata:
annotations:
external-dns.alpha.kubernetes.io/hostname: example.runs.onstackit.cloud
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/component: controller
name: nginx-ingress-controller
namespace: nginx-ingress-controller
spec:
type: LoadBalancer
externalTrafficPolicy: Local
ipFamilyPolicy: SingleStack
ipFamilies:
- IPv4
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: nginx
app.kubernetes.io/name: ingress-nginx
```

<b>Why isn't it working?</b>

<b>Answer</b>: The External DNS will try to create a TXT record named `a-example.runs.onstackit.cloud`, which will fail
because you can't establish a record outside the zone. The solution is to use a name that's within the zone, such as
`nginx.example.runs.onstackit.cloud`.

### 2. Issues with Creating Ingresses not in the Zone

For a project containing the zone `example.runs.onstackit.cloud`, suppose you've created these two ingress:

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: nginx
name: example-ingress-external-dns
namespace: default
spec:
rules:
- host: test.example.runs.onstackit.cloud
http:
paths:
- backend:
service:
name: example
port:
number: 80
path: /
pathType: Prefix
- host: test.example.stackit.rocks
http:
paths:
- backend:
service:
name: example
port:
number: 80
path: /
pathType: Prefix
```

<b>Why isn't it working?</b>

<b>Answer</b>: External DNS will attempt to establish a record set for `test.example.stackit.rocks`. As the zone
`example.stackit.rocks` isn't within the project, it'll fail. There are two potential fixes:

- Incorporate the zone `example.stackit.rocks` into the project.
- Adjust the domain filter to `example.runs.onstackit.cloud` by setting the domain filter
flag `--domain-filter="example.runs.onstackit.cloud"`. This will exclude `test.example.stackit.rocks` and only
generate
the record set for `test.example.runs.onstackit.cloud`.

## Development

Run the app:

```bash
export BASE_URL="https://dns.api.stackit.cloud"
export PROJECT_ID="c158c736-0300-4044-95c4-b7d404279b35"
export AUTH_TOKEN="your-auth-token"
export ACCOUNT_ID="123456"
export USERNAME="username"
export PASSWORD ="password"

make run
```
Expand Down
Loading
Loading