Merge pull request #1 from benjaminbear/add-multidomain-support

add support for multiple domains
This commit is contained in:
benjaminbear 2020-04-27 20:47:09 +02:00 committed by GitHub
commit 0993b7fdcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 34 additions and 26 deletions

View File

@ -32,7 +32,7 @@ docker run -it -d \
-v /somefolder:/var/cache/bind \
-v /someotherfolder:/root/dyndns/database \
-e DDNS_ADMIN_LOGIN=admin:123455546. \
-e DDNS_DOMAIN=dyndns.example.com \
-e DDNS_DOMAINS=dyndns.example.com \
-e DDNS_PARENT_NS=ns.example.com \
-e DDNS_DEFAULT_TTL=3600 \
--name=dyndns \
@ -54,7 +54,7 @@ If you want to embed this into a docker-compose.yml you have to double the dolla
echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
```
`DDNS_DOMAIN` is the domain of the webservice and the domain zone of your dyndns server (see DNS Setup) i.e. `dyndns.example.com`
`DDNS_DOMAINS` are the domains of the webservice and the domain zones of your dyndns server (see DNS Setup) i.e. `dyndns.example.com,dyndns.example.org` (comma separated list)
`DDNS_PARENT_NS` is the parent name server of your domain i.e. `ns.example.com`

View File

@ -20,7 +20,7 @@ type Handler struct {
type Envs struct {
AdminLogin string
Domain string
Domains []string
}
type CustomValidator struct {
@ -83,9 +83,9 @@ func (h *Handler) ParseEnvs() error {
return fmt.Errorf("environment variable DDNS_ADMIN_LOGIN has to be set")
}
h.Config.Domain = os.Getenv("DDNS_DOMAIN")
if h.Config.Domain == "" {
return fmt.Errorf("environment variable DDNS_DOMAIN has to be set")
h.Config.Domains = strings.Split(os.Getenv("DDNS_DOMAINS"), ",")
if len(h.Config.Domains) < 1 {
return fmt.Errorf("environment variable DDNS_DOMAINS has to be set")
}
return nil

View File

@ -41,8 +41,7 @@ func (h *Handler) ListHosts(c echo.Context) (err error) {
}
return c.Render(http.StatusOK, "listhosts", echo.Map{
"hosts": hosts,
"config": h.Config,
"hosts": hosts,
})
}
@ -104,7 +103,7 @@ func (h *Handler) CreateHost(c echo.Context) (err error) {
return c.JSON(http.StatusBadRequest, &Error{fmt.Sprintf("ip %s is not a valid ip", host.Ip)})
}
if err = h.updateRecord(host.Hostname, host.Ip, ipType, host.Ttl); err != nil {
if err = h.updateRecord(host.Hostname, host.Ip, ipType, host.Domain, host.Ttl); err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
}
@ -148,7 +147,7 @@ func (h *Handler) UpdateHost(c echo.Context) (err error) {
return c.JSON(http.StatusBadRequest, &Error{fmt.Sprintf("ip %s is not a valid ip", host.Ip)})
}
if err = h.updateRecord(host.Hostname, host.Ip, ipType, host.Ttl); err != nil {
if err = h.updateRecord(host.Hostname, host.Ip, ipType, host.Domain, host.Ttl); err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
}
@ -186,7 +185,7 @@ func (h *Handler) DeleteHost(c echo.Context) (err error) {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
if err = h.deleteRecord(host.Hostname); err != nil {
if err = h.deleteRecord(host.Hostname, host.Domain); err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
@ -216,7 +215,7 @@ func (h *Handler) UpdateIP(c echo.Context) (err error) {
// Validate hostname
hostname := c.QueryParam("hostname")
if hostname == "" || hostname != h.AuthHost.Hostname+"."+h.Config.Domain {
if hostname == "" || hostname != h.AuthHost.Hostname+"."+h.AuthHost.Domain {
if err = h.CreateLogEntry(log); err != nil {
fmt.Println(err)
}
@ -239,7 +238,7 @@ func (h *Handler) UpdateIP(c echo.Context) (err error) {
}
// add/update DNS record
if err = h.updateRecord(log.Host.Hostname, log.SentIP, ipType, log.Host.Ttl); err != nil {
if err = h.updateRecord(log.Host.Hostname, log.SentIP, ipType, log.Host.Domain, log.Host.Ttl); err != nil {
if err = h.CreateLogEntry(log); err != nil {
fmt.Println(err)
}

View File

@ -47,7 +47,6 @@ func (h *Handler) ShowHostLogs(c echo.Context) (err error) {
}
return c.Render(http.StatusOK, "listlogs", echo.Map{
"logs": logs,
"config": h.Config,
"logs": logs,
})
}

View File

@ -14,7 +14,7 @@ import (
"strings"
)
func (h *Handler) updateRecord(hostname string, ipAddr string, addrType string, ttl int) error {
func (h *Handler) updateRecord(hostname string, ipAddr string, addrType string, zone string, ttl int) error {
fmt.Printf("%s record update request: %s -> %s\n", addrType, hostname, ipAddr)
f, err := ioutil.TempFile(os.TempDir(), "dyndns")
@ -26,9 +26,9 @@ func (h *Handler) updateRecord(hostname string, ipAddr string, addrType string,
w := bufio.NewWriter(f)
w.WriteString(fmt.Sprintf("server %s\n", "localhost"))
w.WriteString(fmt.Sprintf("zone %s\n", h.Config.Domain))
w.WriteString(fmt.Sprintf("update delete %s.%s %s\n", hostname, h.Config.Domain, addrType))
w.WriteString(fmt.Sprintf("update add %s.%s %v %s %s\n", hostname, h.Config.Domain, ttl, addrType, ipAddr))
w.WriteString(fmt.Sprintf("zone %s\n", zone))
w.WriteString(fmt.Sprintf("update delete %s.%s %s\n", hostname, zone, addrType))
w.WriteString(fmt.Sprintf("update add %s.%s %v %s %s\n", hostname, zone, ttl, addrType, ipAddr))
w.WriteString("send\n")
w.Flush()
@ -51,7 +51,7 @@ func (h *Handler) updateRecord(hostname string, ipAddr string, addrType string,
return nil
}
func (h *Handler) deleteRecord(hostname string) error {
func (h *Handler) deleteRecord(hostname string, zone string) error {
fmt.Printf("record delete request: %s\n", hostname)
f, err := ioutil.TempFile(os.TempDir(), "dyndns")
@ -63,8 +63,8 @@ func (h *Handler) deleteRecord(hostname string) error {
w := bufio.NewWriter(f)
w.WriteString(fmt.Sprintf("server %s\n", "localhost"))
w.WriteString(fmt.Sprintf("zone %s\n", h.Config.Domain))
w.WriteString(fmt.Sprintf("update delete %s.%s\n", hostname, h.Config.Domain))
w.WriteString(fmt.Sprintf("zone %s\n", zone))
w.WriteString(fmt.Sprintf("update delete %s.%s\n", hostname, zone))
w.WriteString("send\n")
w.Flush()

View File

@ -8,7 +8,8 @@ import (
type Host struct {
gorm.Model
Hostname string `gorm:"unique;not null" form:"hostname" validate:"required,hostname"`
Hostname string `gorm:"unique_index:idx_host_domain;not null" form:"hostname" validate:"required,hostname"`
Domain string `gorm:"unique_index:idx_host_domain;not null" validate:"required,hostname"`
Ip string `form:"ip" validate:"omitempty,ipv4"`
Ttl int `form:"ttl" validate:"required,min=20,max=86400"`
LastUpdate time.Time `form:"lastupdate"`

View File

@ -38,6 +38,8 @@ $("button.add, button.edit").click(function () {
action = "edit";
}
$('#domain').prop('disabled', false);
$.ajax({
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
data: $('#editHostForm').serialize(),

View File

@ -8,7 +8,14 @@
<div class="col-8 input-group">
<input type="text" class="form-control" placeholder="Enter hostname" name="hostname" value="{{.host.Hostname}}" {{if eq .addEdit "edit" }}readonly{{end}}>
<div class="input-group-append">
<span class="input-group-text" id="basic-addon2">.{{.config.Domain}}</span>
<select class="custom-select" name="domain" id="domain">
{{if eq .addEdit "add"}}
<option selected>Choose...</option>
{{end}}
{{range $domain := .config.Domains}}
<a class="dropdown-item"><option {{if eq $.addEdit "edit"}}disabled="true" {{if eq $.host.Domain $domain}}selected{{end}}{{end}} value="{{$domain}}">{{$domain}}</option></a>
{{end}}
</select>
</div>
</div>
<div class="col-1"></div>

View File

@ -14,7 +14,7 @@
<tbody>
{{range .hosts}}
<tr>
<td>{{.Hostname}}.{{$.config.Domain}}</td>
<td>{{.Hostname}}.{{.Domain}}</td>
<td>{{.Ip}}</td>
<td>{{.Ttl}}</td>
<td>{{.LastUpdate.Format "01/02/2006 15:04 MEZ"}}</td>

View File

@ -16,7 +16,7 @@
{{range .logs}}
<tr>
<td class="align-middle mx-auto"><div class="{{if .Status}}bg-success{{else}}bg-danger{{end}}" style="width: 16px; height: 16px; margin: auto"></div></td>
<td>{{.Host.Hostname}}.{{$.config.Domain}}</td>
<td>{{.Host.Hostname}}.{{.Host.Domain}}</td>
<td>{{.SentIP}}</td>
<td>{{.CreatedAt.Format "01/02/2006 15:04"}}</td>
<td>{{.UserAgent}}</td>