This commit is contained in:
parent
47e81fd011
commit
fba129ec43
0
.dockerignore
Normal file
0
.dockerignore
Normal file
46
.github/workflows/image_creation.yaml
vendored
Normal file
46
.github/workflows/image_creation.yaml
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
name: Build Push
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ secrets.TOKEN }}
|
||||||
|
USERNAME: ${{ vars.USERNAME }}
|
||||||
|
TAG_VERSION: ${{ github.ref_name }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Quemu
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set Up BuildX
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Login to Docker
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: https://git.maximotejeda.com
|
||||||
|
username: ${{ vars.USERNAME }}
|
||||||
|
password: ${{ secrets.PWD }}
|
||||||
|
|
||||||
|
- name: calculate short sha
|
||||||
|
id: calculate-sha
|
||||||
|
run: |
|
||||||
|
echo "shortsha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: git.maximotejeda.com/maximo/ddns:${{ github.ref_name }}
|
||||||
|
build-args: |
|
||||||
|
version=${{ github.ref_name }}
|
||||||
|
SHORTSHA=${{ steps.calculate-sha.outputs.shortsha }}
|
||||||
49
.github/workflows/tags.yml
vendored
49
.github/workflows/tags.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: Go-tags
|
name: Generic Build
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
@ -6,25 +6,42 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ secrets.TOKEN }}
|
||||||
|
USERNAME: ${{ vars.USERNAME }}
|
||||||
|
TAG_VERSION: ${{ github.ref_name }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- name: Checkout Code
|
||||||
|
uses: actions/checkout@v4
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.23.x'
|
go-version: '1.23.x'
|
||||||
- name: install dependencies
|
- name: install dependencies
|
||||||
run: go get .
|
run: go mod tidy
|
||||||
- name: Build
|
|
||||||
env:
|
- name: set shortsha
|
||||||
TAG_VERSION: ${{ github.ref_name }}
|
id: set-sha
|
||||||
run: |
|
run: |
|
||||||
go build -v -o ./bin/ddnser-$TAG_VERSION ./cmd/...
|
echo "shortsha=$(git rev-parse --short HEAD)" >> GITHUB_OUTPUT
|
||||||
zip -r ddnser-$TAG_VERSION ./bin/ddnser-$TAG_VERSION
|
|
||||||
- name: Push to gitea
|
- name: Build amd64
|
||||||
env:
|
run: |
|
||||||
USERNAME: ${{ vars.USERNAME }}
|
shortsha=${{ steps.set-sha.outputs.shortsha }} GOOS=linux GOARCH=amd64 go build -o bin/ddns_amd64_$TAG_VERSION -ldflags "-X main.Shortsha=$shortsha -X main.Version=$TAG_VERSION -X main.Aarch=amd64" ./cmd/...
|
||||||
TOKEN: ${{ secrets.TOKEN }}
|
|
||||||
TAG_VERSION: ${{ github.ref_name }}
|
- name: Build arm64
|
||||||
run: curl --user $USERNAME:$TOKEN \
|
run: |
|
||||||
--upload-file ./bin/ddnser-$TAG_VERSION.zip \
|
shortsha=${{ steps.set-sha.outputs.shortsha }} GOOS=linux GOARCH=arm64 go build -o bin/ddns_arm64_$TAG_VERSION -ldflags "-X main.Shortsha=$shortsha -X main.Version=$TAG_VERSION -X main.Aarch=arm64" ./cmd/...
|
||||||
http://10.0.0.171/api/packages/$USERNAME/go/upload
|
|
||||||
|
- name: push generic registry amd64
|
||||||
|
run: |
|
||||||
|
curl --user $USERNAME:${{ secrets.TOKEN }} --upload-file bin/ddns_amd64_$TAG_VERSION https://git.maximotejeda.com/api/packages/$USERNAME/generic/ddns/amd64_$TAG_VERSION/ddns
|
||||||
|
|
||||||
|
- name: push generic registry arm64
|
||||||
|
run: |
|
||||||
|
curl --user $USERNAME:${{ secrets.TOKEN }} --upload-file bin/ddns_arm64_$TAG_VERSION https://git.maximotejeda.com/api/packages/$USERNAME/generic/ddns/arm64_$TAG_VERSION/ddns
|
||||||
|
|
||||||
|
- name: test env download path
|
||||||
|
run: |
|
||||||
|
echo "curl -OJ http://gitea/api/packages/$USERNAME/generic/ddns/arm64_$TAG_VERSION/ddns"
|
||||||
|
|
||||||
|
|||||||
16
Dockerfile
Normal file
16
Dockerfile
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
FROM golang:alpine AS builder
|
||||||
|
ARG TARGETARCH
|
||||||
|
ARG version=not-set
|
||||||
|
ARG SHORTSHA=not-set
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
# https://stackoverflow.com/questions/70369368/check-architecture-in-dockerfile-to-get-amd-arm
|
||||||
|
RUN go build -o bin/ddns \
|
||||||
|
-ldflags "-X main.Shortsha=${SHORTSHA} \
|
||||||
|
-X main.Version=${version} \
|
||||||
|
-X main.Aarch=${TARGETARCH}" ./cmd
|
||||||
|
|
||||||
|
FROM alpine AS runner
|
||||||
|
COPY --from=builder /app/bin/ddns /usr/bin/
|
||||||
|
ENTRYPOINT /usr/bin/ddns
|
||||||
14
README.org
14
README.org
@ -1,3 +1,12 @@
|
|||||||
|
|
||||||
|
#+CAPTION: Gh badge
|
||||||
|
#+NAME: fig:gh-badge
|
||||||
|
[[https://git.maximotejeda.com/maximo/ddns/actions/workflows/tags.yml/badge.svg?branch=master]]
|
||||||
|
|
||||||
|
#+begin_src markdown
|
||||||
|

|
||||||
|
#+end_src
|
||||||
|
|
||||||
Working creating Request
|
Working creating Request
|
||||||
#+begin_src shell
|
#+begin_src shell
|
||||||
curl --request POST \
|
curl --request POST \
|
||||||
@ -63,3 +72,8 @@ check config for a zone
|
|||||||
|
|
||||||
#+RESULTS:
|
#+RESULTS:
|
||||||
| {"result":{"nameservers":{"type":"cloudflare.standard"} | foundation_dns:false | multi_provider:false | secondary_overrides:false | soa:{"mname":null | rname:"dns.cloudflare.com" | refresh:10000 | retry:2400 | expire:604800 | min_ttl:1800 | ttl:3600} | ns_ttl:86400 | zone_mode:"standard" | internal_dns:{"reference_zone_id":null} | flatten_all_cnames:false} | success:true | errors:[] | messages:[]} |
|
| {"result":{"nameservers":{"type":"cloudflare.standard"} | foundation_dns:false | multi_provider:false | secondary_overrides:false | soa:{"mname":null | rname:"dns.cloudflare.com" | refresh:10000 | retry:2400 | expire:604800 | min_ttl:1800 | ttl:3600} | ns_ttl:86400 | zone_mode:"standard" | internal_dns:{"reference_zone_id":null} | flatten_all_cnames:false} | success:true | errors:[] | messages:[]} |
|
||||||
|
|
||||||
|
To Download bin from gitea instance
|
||||||
|
#+begin_src shell
|
||||||
|
curl -OJ http://gitea/api/packages/maximo/generic/ddns/arm64_v0.0.0-13/ddns
|
||||||
|
#+end_src
|
||||||
|
|||||||
15
cmd/main.go
15
cmd/main.go
@ -20,7 +20,11 @@ var (
|
|||||||
proxied bool
|
proxied bool
|
||||||
helpMsg string
|
helpMsg string
|
||||||
provider string
|
provider string
|
||||||
rID string
|
rID string
|
||||||
|
comment string
|
||||||
|
Version string
|
||||||
|
Shortsha string
|
||||||
|
Aarch string
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -40,20 +44,21 @@ func init() {
|
|||||||
flag.StringVar(&provider, "pv", "cf", "Dns records provider")
|
flag.StringVar(&provider, "pv", "cf", "Dns records provider")
|
||||||
flag.StringVar(&rID, "rid", "", "Select record id (shorthand)")
|
flag.StringVar(&rID, "rid", "", "Select record id (shorthand)")
|
||||||
flag.StringVar(&rID, "record-id", "", "Select record id")
|
flag.StringVar(&rID, "record-id", "", "Select record id")
|
||||||
|
flag.StringVar(&comment, "comment", "", "comment")
|
||||||
|
flag.StringVar(&comment, "c", "", "comment operation")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
lvl := new(slog.LevelVar)
|
lvl := new(slog.LevelVar)
|
||||||
switch os.Getenv("ENV"){
|
switch os.Getenv("ENV") {
|
||||||
case "debug", "dev":
|
case "debug", "dev":
|
||||||
lvl.Set(slog.LevelDebug)
|
lvl.Set(slog.LevelDebug)
|
||||||
case "prod":
|
case "prod":
|
||||||
lvl.Set(slog.LevelInfo)
|
lvl.Set(slog.LevelInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
log := slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: lvl}))
|
log := slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: lvl}))
|
||||||
|
log = log.With("version", Version, "shortsha", Shortsha, "aarch", Aarch)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
helpmsg := "required flag not provided "
|
helpmsg := "required flag not provided "
|
||||||
if tok == "" {
|
if tok == "" {
|
||||||
@ -89,7 +94,7 @@ func main() {
|
|||||||
fmt.Println(zid)
|
fmt.Println(zid)
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
app.Operation(operation, name, tipe, ip, proxied, rID)
|
app.Operation(operation, name, tipe, ip, rID, comment, proxied)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
4
compose.yaml
Normal file
4
compose.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
services:
|
||||||
|
ddns:
|
||||||
|
image: ddns
|
||||||
|
env_file: ".env"
|
||||||
@ -66,7 +66,7 @@ func (c *client) Do() (res *Response, err error) {
|
|||||||
|
|
||||||
ipSTR, err := io.ReadAll(resp.Body)
|
ipSTR, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.log.Error("reading body", err)
|
c.log.Error("reading body", "error", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
ipi := net.ParseIP(string(ipSTR))
|
ipi := net.ParseIP(string(ipSTR))
|
||||||
|
|||||||
@ -1,14 +1,2 @@
|
|||||||
package provider
|
package provider
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetSettings(t *testing.T) {
|
|
||||||
os.Setenv("ENVIRONMENT", "dev")
|
|
||||||
s := GetSettingsFile("")
|
|
||||||
if s != nil {
|
|
||||||
t.Errorf("empty settings: %v", s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -129,7 +129,7 @@ func (app *Application) Create(rBody cf.RequestBody) (res *cf.DetailsResult, err
|
|||||||
|
|
||||||
// Overwrite
|
// Overwrite
|
||||||
func (app *Application) Overwrite(re *cf.Result, rBody *cf.RequestBody) {
|
func (app *Application) Overwrite(re *cf.Result, rBody *cf.RequestBody) {
|
||||||
rBody.Comment = "Overwrite from app cli tool"
|
rBody.Comment = rBody.Comment + " Overwrite from app cli tool"
|
||||||
res, err := app.client.Overwrite(*rBody, re.ID)
|
res, err := app.client.Overwrite(*rBody, re.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.log.Error("[Overwrite]", "error", err)
|
app.log.Error("[Overwrite]", "error", err)
|
||||||
@ -150,7 +150,7 @@ func (app Application) Delete(re *cf.Result) {
|
|||||||
|
|
||||||
// Operation
|
// Operation
|
||||||
// expose required
|
// expose required
|
||||||
func (app *Application) Operation(op string, name, tipo, ipSTR string, proxied bool, rID string) {
|
func (app *Application) Operation(op string, name, tipo, ipSTR,rID, comment string, proxied bool) {
|
||||||
var (
|
var (
|
||||||
res *checker.Response
|
res *checker.Response
|
||||||
err error
|
err error
|
||||||
@ -205,7 +205,7 @@ func (app *Application) Operation(op string, name, tipo, ipSTR string, proxied b
|
|||||||
if dn == "*" {
|
if dn == "*" {
|
||||||
for _, rec := range app.zoneRecords {
|
for _, rec := range app.zoneRecords {
|
||||||
if rec.Content != app.publicIP.String() {
|
if rec.Content != app.publicIP.String() {
|
||||||
rBody = app.GenerateReqBody(rec.Name, res.Type, app.publicIP.String(), proxied)
|
rBody = app.GenerateReqBody(rec.Name, res.Type, app.publicIP.String(), comment, proxied)
|
||||||
app.Update(&rec, *rBody)
|
app.Update(&rec, *rBody)
|
||||||
} else {
|
} else {
|
||||||
app.log.Info("same ip for", "record", rec.Name, "DstIP", rec.Content, "NewIP", app.publicIP)
|
app.log.Info("same ip for", "record", rec.Name, "DstIP", rec.Content, "NewIP", app.publicIP)
|
||||||
@ -216,7 +216,7 @@ func (app *Application) Operation(op string, name, tipo, ipSTR string, proxied b
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if rs.Content != app.publicIP.String() {
|
if rs.Content != app.publicIP.String() {
|
||||||
rBody = app.GenerateReqBody(name, res.Type, app.publicIP.String(), proxied)
|
rBody = app.GenerateReqBody(name, res.Type, app.publicIP.String(),comment, proxied)
|
||||||
app.Update(rs, *rBody)
|
app.Update(rs, *rBody)
|
||||||
} else {
|
} else {
|
||||||
app.log.Error("same ip on dns record")
|
app.log.Error("same ip on dns record")
|
||||||
@ -228,7 +228,7 @@ func (app *Application) Operation(op string, name, tipo, ipSTR string, proxied b
|
|||||||
panic("name cant be empty for op create")
|
panic("name cant be empty for op create")
|
||||||
}
|
}
|
||||||
fmt.Printf("domain name: %s", dn)
|
fmt.Printf("domain name: %s", dn)
|
||||||
rBody = app.GenerateReqBody(dn, tipo, app.publicIP.String(), proxied)
|
rBody = app.GenerateReqBody(dn, tipo, app.publicIP.String(),comment, proxied)
|
||||||
app.Create(*rBody)
|
app.Create(*rBody)
|
||||||
case "delete":
|
case "delete":
|
||||||
if name == "" {
|
if name == "" {
|
||||||
@ -248,7 +248,7 @@ func (app *Application) Operation(op string, name, tipo, ipSTR string, proxied b
|
|||||||
|
|
||||||
app.log.Error(fmt.Sprintf("could not find record: %s -> %s", name, dn), "operation", "overwrite")
|
app.log.Error(fmt.Sprintf("could not find record: %s -> %s", name, dn), "operation", "overwrite")
|
||||||
} else {
|
} else {
|
||||||
rBody = app.GenerateReqBody(dn, tipo, app.publicIP.String(), proxied)
|
rBody = app.GenerateReqBody(dn, tipo, app.publicIP.String(), comment, proxied)
|
||||||
app.Overwrite(rs, rBody)
|
app.Overwrite(rs, rBody)
|
||||||
}
|
}
|
||||||
case "details":
|
case "details":
|
||||||
@ -257,7 +257,7 @@ func (app *Application) Operation(op string, name, tipo, ipSTR string, proxied b
|
|||||||
}
|
}
|
||||||
|
|
||||||
if rs != nil {
|
if rs != nil {
|
||||||
rBody = app.GenerateReqBody(dn, tipo, app.publicIP.String(), proxied)
|
rBody = app.GenerateReqBody(dn, tipo, app.publicIP.String(), comment, proxied)
|
||||||
app.Details(rs.ID)
|
app.Details(rs.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,8 +293,9 @@ func (app *Application) SelectNameAndType(name, tipo string) (rec *cf.Result, er
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *Application) GenerateReqBody(name, tipo, ipSTR string, proxied bool) (rBody *cf.RequestBody) {
|
func (app *Application) GenerateReqBody(name, tipo, ipSTR, comment string, proxied bool) (rBody *cf.RequestBody) {
|
||||||
rBody = &cf.RequestBody{}
|
rBody = &cf.RequestBody{}
|
||||||
|
rBody.Comment = comment
|
||||||
rBody.DomainName = name
|
rBody.DomainName = name
|
||||||
rBody.Type = tipo
|
rBody.Type = tipo
|
||||||
rBody.Content = ipSTR
|
rBody.Content = ipSTR
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user