add cname managment, check for used hostnames, fix menu button highlighting
This commit is contained in:
parent
3884ff5a09
commit
dbc137366e
@ -116,6 +116,10 @@ func (h *Handler) InitDB() (err error) {
|
|||||||
h.DB.CreateTable(&model.Host{})
|
h.DB.CreateTable(&model.Host{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !h.DB.HasTable(&model.CName{}) {
|
||||||
|
h.DB.CreateTable(&model.CName{})
|
||||||
|
}
|
||||||
|
|
||||||
if !h.DB.HasTable(&model.Log{}) {
|
if !h.DB.HasTable(&model.Log{}) {
|
||||||
h.DB.CreateTable(&model.Log{})
|
h.DB.CreateTable(&model.Log{})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -106,6 +106,10 @@ func (h *Handler) CreateHost(c echo.Context) (err error) {
|
|||||||
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
|
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = h.checkUniqueHostname(host.Hostname, host.Domain); err != nil {
|
||||||
|
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
|
||||||
|
}
|
||||||
|
|
||||||
if err = h.DB.Create(host).Error; err != nil {
|
if err = h.DB.Create(host).Error; err != nil {
|
||||||
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
|
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
|
||||||
}
|
}
|
||||||
@ -198,6 +202,10 @@ func (h *Handler) DeleteHost(c echo.Context) (err error) {
|
|||||||
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
|
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = tx.Where(&model.CName{TargetID: uint(id)}).Delete(&model.CName{}).Error; err != nil {
|
||||||
|
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -282,3 +290,28 @@ func (h *Handler) UpdateIP(c echo.Context) (err error) {
|
|||||||
|
|
||||||
return c.String(http.StatusOK, "good\n")
|
return c.String(http.StatusOK, "good\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handler) checkUniqueHostname(hostname, domain string) error {
|
||||||
|
fmt.Println(hostname, domain)
|
||||||
|
hosts := new([]model.Host)
|
||||||
|
if err := h.DB.Where(&model.Host{Hostname: hostname, Domain: domain}).Find(hosts).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(*hosts) > 0 {
|
||||||
|
return fmt.Errorf("hostname already exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
cnames := new([]model.CName)
|
||||||
|
if err := h.DB.Preload("Target").Where(&model.CName{Hostname: hostname}).Find(cnames).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cname := range *cnames {
|
||||||
|
if cname.Target.Domain == domain {
|
||||||
|
return fmt.Errorf("hostname already exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import (
|
|||||||
"github.com/benjaminbear/docker-ddns-server/dyndns/handler"
|
"github.com/benjaminbear/docker-ddns-server/dyndns/handler"
|
||||||
"github.com/foolin/goview/supports/echoview-v4"
|
"github.com/foolin/goview/supports/echoview-v4"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
|
|
||||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
@ -53,6 +52,8 @@ func main() {
|
|||||||
e.GET("/hosts/add", h.AddHost)
|
e.GET("/hosts/add", h.AddHost)
|
||||||
e.GET("/hosts/edit/:id", h.EditHost)
|
e.GET("/hosts/edit/:id", h.EditHost)
|
||||||
e.GET("/hosts", h.ListHosts)
|
e.GET("/hosts", h.ListHosts)
|
||||||
|
e.GET("/cnames/add", h.AddCName)
|
||||||
|
e.GET("/cnames", h.ListCNames)
|
||||||
e.GET("/logs", h.ShowLogs)
|
e.GET("/logs", h.ShowLogs)
|
||||||
e.GET("/logs/host/:id", h.ShowHostLogs)
|
e.GET("/logs/host/:id", h.ShowHostLogs)
|
||||||
|
|
||||||
@ -60,6 +61,8 @@ func main() {
|
|||||||
e.POST("/hosts/add", h.CreateHost)
|
e.POST("/hosts/add", h.CreateHost)
|
||||||
e.POST("/hosts/edit/:id", h.UpdateHost)
|
e.POST("/hosts/edit/:id", h.UpdateHost)
|
||||||
e.GET("/hosts/delete/:id", h.DeleteHost)
|
e.GET("/hosts/delete/:id", h.DeleteHost)
|
||||||
|
e.POST("/cnames/add", h.CreateCName)
|
||||||
|
e.GET("/cnames/delete/:id", h.DeleteCName)
|
||||||
|
|
||||||
// dyndns compatible api
|
// dyndns compatible api
|
||||||
e.GET("/update", h.UpdateIP)
|
e.GET("/update", h.UpdateIP)
|
||||||
|
|||||||
@ -10,8 +10,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// UpdateRecord builds a nsupdate file and updates a record by executing it with nsupdate.
|
// UpdateRecord builds a nsupdate file and updates a record by executing it with nsupdate.
|
||||||
func UpdateRecord(hostname string, ipAddr string, addrType string, zone string, ttl int) error {
|
func UpdateRecord(hostname string, target string, addrType string, zone string, ttl int) error {
|
||||||
fmt.Printf("%s record update request: %s -> %s\n", addrType, hostname, ipAddr)
|
fmt.Printf("%s record update request: %s -> %s\n", addrType, hostname, target)
|
||||||
|
|
||||||
f, err := ioutil.TempFile(os.TempDir(), "dyndns")
|
f, err := ioutil.TempFile(os.TempDir(), "dyndns")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -24,7 +24,7 @@ func UpdateRecord(hostname string, ipAddr string, addrType string, zone string,
|
|||||||
w.WriteString(fmt.Sprintf("server %s\n", "localhost"))
|
w.WriteString(fmt.Sprintf("server %s\n", "localhost"))
|
||||||
w.WriteString(fmt.Sprintf("zone %s\n", zone))
|
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 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(fmt.Sprintf("update add %s.%s %v %s %s\n", hostname, zone, ttl, addrType, target))
|
||||||
w.WriteString("send\n")
|
w.WriteString("send\n")
|
||||||
|
|
||||||
w.Flush()
|
w.Flush()
|
||||||
|
|||||||
@ -38,15 +38,24 @@ $("button.add, button.edit").click(function () {
|
|||||||
action = "edit";
|
action = "edit";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let type;
|
||||||
|
if ($(this).hasClass("host")) {
|
||||||
|
type = "hosts";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($(this).hasClass("cname")) {
|
||||||
|
type = "cnames";
|
||||||
|
}
|
||||||
|
|
||||||
$('#domain').prop('disabled', false);
|
$('#domain').prop('disabled', false);
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
|
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||||
data: $('#editHostForm').serialize(),
|
data: $('#editHostForm').serialize(),
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/hosts/'+action+id,
|
url: '/'+type+'/'+action+id,
|
||||||
}).done(function(data, textStatus, jqXHR) {
|
}).done(function(data, textStatus, jqXHR) {
|
||||||
location.href="/hosts";
|
location.href="/"+type;
|
||||||
}).fail(function(jqXHR, textStatus, errorThrown) {
|
}).fail(function(jqXHR, textStatus, errorThrown) {
|
||||||
alert("Error: " + $.parseJSON(jqXHR.responseText).message);
|
alert("Error: " + $.parseJSON(jqXHR.responseText).message);
|
||||||
});
|
});
|
||||||
@ -79,6 +88,29 @@ $("#logout").click(function (){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("button.addCName").click(function () {
|
||||||
|
location.href='/cnames/add';
|
||||||
|
});
|
||||||
|
|
||||||
|
$("button.deleteCName").click(function () {
|
||||||
|
$.ajax({
|
||||||
|
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||||
|
type: 'GET',
|
||||||
|
url: "/cnames/delete/" + $(this).attr('id')
|
||||||
|
}).done(function(data, textStatus, jqXHR) {
|
||||||
|
location.href="/cnames";
|
||||||
|
}).fail(function(jqXHR, textStatus, errorThrown) {
|
||||||
|
alert("Error: " + $.parseJSON(jqXHR.responseText).message);
|
||||||
|
location.reload()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function newTargetSelected() {
|
||||||
|
var sel = document.getElementById("target_id");
|
||||||
|
var x = sel.options[sel.selectedIndex].label.replace(sel.options[sel.selectedIndex].text, '');
|
||||||
|
document.getElementById("domain_mirror").value = x;
|
||||||
|
}
|
||||||
|
|
||||||
$("button.copyToClipboard").click(function () {
|
$("button.copyToClipboard").click(function () {
|
||||||
let id;
|
let id;
|
||||||
if ($(this).hasClass('username')) {
|
if ($(this).hasClass('username')) {
|
||||||
@ -122,4 +154,10 @@ $(document).ready(function(){
|
|||||||
return $(this).prop('title');
|
return $(this).prop('title');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
urlPath = new URL(window.location.href).pathname.split("/")[1];
|
||||||
|
if (urlPath === "") {
|
||||||
|
urlPath = "hosts"
|
||||||
|
}
|
||||||
|
document.getElementsByClassName("nav-"+urlPath)[0].classList.add("active");
|
||||||
});
|
});
|
||||||
|
|||||||
@ -68,7 +68,7 @@
|
|||||||
<div class="col-1"></div>
|
<div class="col-1"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt-3">
|
<div class="row mt-3">
|
||||||
<div class="col-11 d-flex justify-content-end"><button id="{{.host.ID}}" class="{{.addEdit}} btn btn-primary">{{if eq .addEdit "edit" }}Edit{{else if eq .addEdit "add" }}Add{{end}} Host Entry</button></div>
|
<div class="col-11 d-flex justify-content-end"><button id="{{.host.ID}}" class="{{.addEdit}} host btn btn-primary">{{if eq .addEdit "edit" }}Edit{{else if eq .addEdit "add" }}Add{{end}} Host Entry</button></div>
|
||||||
<div class="col-1"></div>
|
<div class="col-1"></div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -27,13 +27,16 @@
|
|||||||
<nav>
|
<nav>
|
||||||
<ul class="nav nav-pills float-right">
|
<ul class="nav nav-pills float-right">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link active" href="/hosts">Hosts <span class="sr-only">(current)</span></a>
|
<a class="nav-link nav-hosts" href="/hosts">Hosts</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="/logs">Logs</a>
|
<a class="nav-link nav-cnames" href="/cnames">CNames</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="" id="logout">Logout</a>
|
<a class="nav-link nav-logs" href="/logs">Logs</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link nav-logout" href="" id="logout">Logout</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
@ -44,7 +47,7 @@
|
|||||||
{{template "content" .}}
|
{{template "content" .}}
|
||||||
|
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<p>© TheBBCloud 2020</p>
|
<p>© TheBBCloud 2021</p>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
</div> <!-- /container -->
|
</div> <!-- /container -->
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user