Skip to content

Commit

Permalink
feat: First version
Browse files Browse the repository at this point in the history
  • Loading branch information
dploeger committed Jun 18, 2024
1 parent 5f1fef9 commit a78ce40
Show file tree
Hide file tree
Showing 18 changed files with 924 additions and 1 deletion.
36 changes: 36 additions & 0 deletions .github/workflows/chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Release Charts

on:
push:
branches:
- main
paths:
- helm-charts/**

jobs:
release:
# depending on default permission settings for your org (contents being read-only or read-write for workloads), you will have to add permissions
# see: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "[email protected]"
- name: Install Helm
uses: azure/setup-helm@v4
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

- name: Run chart-releaser
uses: helm/[email protected]
env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
90 changes: 90 additions & 0 deletions .github/workflows/container.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Container

on:
push:
branches: [ "main" ]
tags: [ 'v*.*.*' ]
pull_request:
branches: [ "main" ]

env:
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}


jobs:
build:

runs-on: ubuntu-latest
permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 #v3.5.0
with:
cosign-release: 'v2.2.4'

# Set up BuildKit Docker container builder to be able to build
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0

# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

# Sign the resulting Docker image digest except on PRs.
# This will only write to the public Rekor transparency log when the Docker
# repository is public to avoid leaking data. If you would like to publish
# transparency data even for private images, pass --force to cosign below.
# https://github.com/sigstore/cosign
- name: Sign the published Docker image
if: ${{ github.event_name != 'pull_request' }}
env:
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
TAGS: ${{ steps.meta.outputs.tags }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
# This step uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
20 changes: 20 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM golang:1.22-alpine as builder

COPY . /app
WORKDIR /app
RUN GOOS=linux go build cmd/cloudflare-ddns-update.go

FROM golang:1.22-alpine

COPY --from=builder /app/cloudflare-ddns-update /

ENTRYPOINT ["/cloudflare-ddns-update"]

LABEL io.artifacthub.package.readme-url=https://github.com/dploeger/cloudflare-ddns-update
LABEL org.opencontainers.image.created=2024-06-06
LABEL org.opencontainers.image.description="Dyn API to update Cloudflare DNS records"
LABEL org.opencontainers.image.documentation=https://github.com/dploeger/cloudflare-ddns-update
LABEL org.opencontainers.image.source=https://github.com/dploeger/cloudflare-ddns-update
LABEL org.opencontainers.image.title="cloudflare-ddns-update"
LABEL org.opencontainers.image.url=https://github.com/dploeger/cloudflare-ddns-update
LABEL org.opencontainers.image.vendor="Dennis Plöger"
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,33 @@
# cloudflare-ddns-update
# cloudflare-ddns-update - Dyn v3 API that manages DNS entries in cloudflare

## Introduction

The [Dyn v3 API](https://help.dyn.com/remote-access-api/perform-update/) to update dynamic DNS records is used in
multiple routers on the market. This tool allows to provide this API while managing the dynamic DNS records in cloudflare.

## Configuration

The tool requires the following environment variables to be set:

* CLOUDFLARE_API_TOKEN: The API token used to authenticate against the cloudflare API
* CLOUDFLARE_ZONE: The name of the DNS zone to manage
* AUTH_USERNAME: A username that is required to be used for the Dyn API
* AUTH_PASSWORD: A password that is required to be used for the Dyn API

Optionally, DEBUG can be set to anything to enable logging of cloudflare requests and responses.

## Usage

After setting the environment variables, simply run the tool

./cloudflare-ddns-update

## Container image / Docker

This is also available as a container image, e.g. via Docker:

docker run -e CLOUDFLARE_API_TOKEN=secret -e CLOUDFLARE_ZONE=example.com -e AUTH_USERNAME=testuser -e AUTH_PASSWORD=secret ghcr.io/dploeger/cloudflare-ddns-update:latest

## Helm chart

TODO
44 changes: 44 additions & 0 deletions cmd/cloudflare-ddns-update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package main

import (
"github.com/dploeger/cloudflare-ddns-update/pkg"
"github.com/gin-gonic/gin"
"log"
"os"
)

func main() {
_, isDebug := os.LookupEnv("DEBUG")

if _, ok := os.LookupEnv("CLOUDFLARE_API_TOKEN"); !ok {
log.Fatalf("Missing CLOUDFLARE_API_TOKEN env variable")
}
if _, ok := os.LookupEnv("CLOUDFLARE_ZONE"); !ok {
log.Fatalf("Missing CLOUDFLARE_ZONE env variable")
}
if _, ok := os.LookupEnv("AUTH_USERNAME"); !ok {
log.Fatalf("Missing AUTH_USERNAME env variable")
}
if _, ok := os.LookupEnv("AUTH_PASSWORD"); !ok {
log.Fatalf("Missing AUTH_USERNAME env variable")
}

var api pkg.API
if a, err := pkg.NewAPI(os.Getenv("CLOUDFLARE_API_TOKEN"), os.Getenv("CLOUDFLARE_ZONE"), isDebug); err != nil {
log.Fatalf(err.Error())
} else {
api = *a
}

r := gin.Default()
r.GET("/health", func(c *gin.Context) {
c.JSON(200, gin.H{
"status": "running",
})
})
v3 := r.Group("v3", gin.BasicAuth(gin.Accounts{os.Getenv("AUTH_USERNAME"): os.Getenv("AUTH_PASSWORD")}))
v3.GET("/update", api.DDNSUpdate)
if err := r.Run(); err != nil {
log.Fatalf("Can not run service: %s", err)
}
}
47 changes: 47 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module github.com/dploeger/cloudflare-ddns-update

go 1.22.0

require (
github.com/cloudflare/cloudflare-go/v2 v2.2.0
github.com/gin-gonic/gin v1.10.0
)

require (
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.20.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/google/go-cmp v0.5.8 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/tidwall/gjson v1.14.4 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit a78ce40

Please sign in to comment.