Save zones into DB
This commit is contained in:
parent
a5e7f79b18
commit
0b55b5fed3
112
api/zones.go
112
api/zones.go
|
@ -10,6 +10,8 @@ import (
|
|||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.nemunai.re/libredns/struct"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -22,29 +24,20 @@ func init() {
|
|||
router.DELETE("/api/zones/:zone/rr", apiHandler(zoneHandler(delRR)))
|
||||
}
|
||||
|
||||
var tmpZones = []string{}
|
||||
|
||||
func getZones(p httprouter.Params, body io.Reader) Response {
|
||||
return APIResponse{
|
||||
response: tmpZones,
|
||||
}
|
||||
}
|
||||
|
||||
func existsZone(zone string) bool {
|
||||
for _, z := range tmpZones {
|
||||
if z == zone {
|
||||
return true
|
||||
if zones, err := libredns.GetZones(); err != nil {
|
||||
return APIErrorResponse{
|
||||
err: err,
|
||||
}
|
||||
} else {
|
||||
return APIResponse{
|
||||
response: zones,
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type uploadedZone struct {
|
||||
Zone string `json:"domainName"`
|
||||
}
|
||||
|
||||
func addZone(p httprouter.Params, body io.Reader) Response {
|
||||
var uz uploadedZone
|
||||
var uz libredns.Zone
|
||||
err := json.NewDecoder(body).Decode(&uz)
|
||||
if err != nil {
|
||||
return APIErrorResponse{
|
||||
|
@ -52,72 +45,69 @@ func addZone(p httprouter.Params, body io.Reader) Response {
|
|||
}
|
||||
}
|
||||
|
||||
if uz.Zone[len(uz.Zone)-1] != '.' {
|
||||
uz.Zone = uz.Zone + "."
|
||||
if len(uz.DomainName) <= 2 {
|
||||
return APIErrorResponse{
|
||||
err: errors.New("The given zone is invalid."),
|
||||
}
|
||||
}
|
||||
|
||||
if existsZone(uz.Zone) {
|
||||
if uz.DomainName[len(uz.DomainName)-1] != '.' {
|
||||
uz.DomainName = uz.DomainName + "."
|
||||
}
|
||||
|
||||
if libredns.ZoneExists(uz.DomainName) {
|
||||
return APIErrorResponse{
|
||||
err: errors.New("This zone already exists."),
|
||||
}
|
||||
} else {
|
||||
tmpZones = append(tmpZones, uz.Zone)
|
||||
return getZone(uz.Zone, body)
|
||||
}
|
||||
}
|
||||
|
||||
func delZone(zone string, body io.Reader) Response {
|
||||
index := -1
|
||||
|
||||
for i := range tmpZones {
|
||||
if tmpZones[i] == zone {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if index == -1 {
|
||||
} else if zone, err := uz.NewZone(); err != nil {
|
||||
return APIErrorResponse{
|
||||
err: errors.New("This zone doesn't exist."),
|
||||
err: err,
|
||||
}
|
||||
} else {
|
||||
return APIResponse{
|
||||
response: zone,
|
||||
}
|
||||
}
|
||||
|
||||
tmpZones = append(tmpZones[:index], tmpZones[index+1:]...)
|
||||
|
||||
return APIResponse{
|
||||
response: true,
|
||||
}
|
||||
}
|
||||
|
||||
func zoneHandler(f func(string, io.Reader) Response) func(httprouter.Params, io.Reader) Response {
|
||||
return func(ps httprouter.Params, body io.Reader) Response {
|
||||
zone := ps.ByName("zone")
|
||||
func delZone(zone libredns.Zone, body io.Reader) Response {
|
||||
if _, err := zone.Delete(); err != nil {
|
||||
return APIErrorResponse{
|
||||
err: err,
|
||||
}
|
||||
} else {
|
||||
return APIResponse{
|
||||
response: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !existsZone(zone) {
|
||||
func zoneHandler(f func(libredns.Zone, io.Reader) Response) func(httprouter.Params, io.Reader) Response {
|
||||
return func(ps httprouter.Params, body io.Reader) Response {
|
||||
if zone, err := libredns.GetZoneByDN(ps.ByName("zone")); err != nil {
|
||||
return APIErrorResponse{
|
||||
status: http.StatusNotFound,
|
||||
err: errors.New("Domain not found"),
|
||||
}
|
||||
} else {
|
||||
return f(zone, body)
|
||||
}
|
||||
|
||||
return f(zone, body)
|
||||
}
|
||||
}
|
||||
|
||||
func getZone(zone string, body io.Reader) Response {
|
||||
func getZone(zone libredns.Zone, body io.Reader) Response {
|
||||
return APIResponse{
|
||||
response: map[string]interface{}{
|
||||
"dn": zone,
|
||||
},
|
||||
response: zone,
|
||||
}
|
||||
}
|
||||
|
||||
func axfrZone(zone string, body io.Reader) Response {
|
||||
func axfrZone(zone libredns.Zone, body io.Reader) Response {
|
||||
t := new(dns.Transfer)
|
||||
|
||||
m := new(dns.Msg)
|
||||
m.SetEdns0(4096, true)
|
||||
t.TsigSecret = map[string]string{"ddns.": "so6ZGir4GPAqINNh9U5c3A=="}
|
||||
m.SetAxfr(zone)
|
||||
m.SetAxfr(zone.DomainName)
|
||||
m.SetTsig("ddns.", dns.HmacSHA256, 300, time.Now().Unix())
|
||||
|
||||
c, err := t.In(m, DefaultNameServer)
|
||||
|
@ -151,7 +141,7 @@ type uploadedRR struct {
|
|||
RR string `json:"string"`
|
||||
}
|
||||
|
||||
func addRR(zone string, body io.Reader) Response {
|
||||
func addRR(zone libredns.Zone, body io.Reader) Response {
|
||||
var urr uploadedRR
|
||||
err := json.NewDecoder(body).Decode(&urr)
|
||||
if err != nil {
|
||||
|
@ -160,7 +150,7 @@ func addRR(zone string, body io.Reader) Response {
|
|||
}
|
||||
}
|
||||
|
||||
rr, err := dns.NewRR(fmt.Sprintf("$ORIGIN %s\n$TTL %d\n%s", zone, 3600, urr.RR))
|
||||
rr, err := dns.NewRR(fmt.Sprintf("$ORIGIN %s\n$TTL %d\n%s", zone.DomainName, 3600, urr.RR))
|
||||
if err != nil {
|
||||
return APIErrorResponse{
|
||||
err: err,
|
||||
|
@ -171,7 +161,7 @@ func addRR(zone string, body io.Reader) Response {
|
|||
m.Id = dns.Id()
|
||||
m.Opcode = dns.OpcodeUpdate
|
||||
m.Question = make([]dns.Question, 1)
|
||||
m.Question[0] = dns.Question{zone, dns.TypeSOA, dns.ClassINET}
|
||||
m.Question[0] = dns.Question{zone.DomainName, dns.TypeSOA, dns.ClassINET}
|
||||
|
||||
m.Insert([]dns.RR{rr})
|
||||
|
||||
|
@ -196,7 +186,7 @@ func addRR(zone string, body io.Reader) Response {
|
|||
}
|
||||
}
|
||||
|
||||
func delRR(zone string, body io.Reader) Response {
|
||||
func delRR(zone libredns.Zone, body io.Reader) Response {
|
||||
var urr uploadedRR
|
||||
err := json.NewDecoder(body).Decode(&urr)
|
||||
if err != nil {
|
||||
|
@ -216,7 +206,7 @@ func delRR(zone string, body io.Reader) Response {
|
|||
m.Id = dns.Id()
|
||||
m.Opcode = dns.OpcodeUpdate
|
||||
m.Question = make([]dns.Question, 1)
|
||||
m.Question[0] = dns.Question{zone, dns.TypeSOA, dns.ClassINET}
|
||||
m.Question[0] = dns.Question{zone.DomainName, dns.TypeSOA, dns.ClassINET}
|
||||
|
||||
m.Remove([]dns.RR{rr})
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<tbody>
|
||||
<tr v-for="(zone, index) in zones" v-bind:key="index">
|
||||
<td @click="show(zone)" class="text-monospace">
|
||||
{{ zone }}
|
||||
{{ zone.domain }}
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" @click="show(zone)" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></button>
|
||||
|
@ -80,14 +80,22 @@ export default {
|
|||
attachZone (dn) {
|
||||
axios
|
||||
.post('/api/zones', {
|
||||
domainName: this.toAttachDN
|
||||
domain: this.toAttachDN
|
||||
})
|
||||
.then(response => (this.zones.push(response.data.dn)))
|
||||
.then(
|
||||
(response) => {
|
||||
if (this.zones == null) this.zones = []
|
||||
this.zones.push(response.data)
|
||||
},
|
||||
(error) => {
|
||||
alert('Unable to attach the given zone: ' + error.response.data.errmsg)
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
deleteZone (dn) {
|
||||
deleteZone (zone) {
|
||||
axios
|
||||
.delete('/api/zones/' + dn)
|
||||
.delete('/api/zones/' + zone.domain)
|
||||
.then(response => (
|
||||
axios
|
||||
.get('/api/zones')
|
||||
|
@ -95,8 +103,8 @@ export default {
|
|||
))
|
||||
},
|
||||
|
||||
show (dn) {
|
||||
this.$router.push('/zones/' + dn)
|
||||
show (zone) {
|
||||
this.$router.push('/zones/' + zone.domain)
|
||||
},
|
||||
|
||||
modalShown () {
|
||||
|
|
9
main.go
9
main.go
|
@ -9,6 +9,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"git.nemunai.re/libredns/api"
|
||||
"git.nemunai.re/libredns/struct"
|
||||
)
|
||||
|
||||
type ResponseWriterPrefix struct {
|
||||
|
@ -55,7 +56,7 @@ func main() {
|
|||
// Read parameters from command line
|
||||
flag.StringVar(&DevProxy, "dev", DevProxy, "Proxify traffic to this host for static assets")
|
||||
var bind = flag.String("bind", ":8081", "Bind port/socket")
|
||||
var dsn = flag.String("dsn", DSNGenerator(), "DSN to connect to the MySQL server")
|
||||
var dsn = flag.String("dsn", libredns.DSNGenerator(), "DSN to connect to the MySQL server")
|
||||
var baseURL = flag.String("baseurl", "/", "URL prepended to each URL")
|
||||
flag.StringVar(&api.DefaultNameServer, "defaultns", api.DefaultNameServer, "Adress to the default name server")
|
||||
flag.Parse()
|
||||
|
@ -71,13 +72,13 @@ func main() {
|
|||
|
||||
// Initialize contents
|
||||
log.Println("Opening database...")
|
||||
if err := DBInit(*dsn); err != nil {
|
||||
if err := libredns.DBInit(*dsn); err != nil {
|
||||
log.Fatal("Cannot open the database: ", err)
|
||||
}
|
||||
defer DBClose()
|
||||
defer libredns.DBClose()
|
||||
|
||||
log.Println("Creating database...")
|
||||
if err := DBCreate(); err != nil {
|
||||
if err := libredns.DBCreate(); err != nil {
|
||||
log.Fatal("Cannot create database: ", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package main
|
||||
package libredns
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
@ -59,9 +59,10 @@ func DBCreate() error {
|
|||
if _, err := db.Exec(`
|
||||
CREATE TABLE IF NOT EXISTS users(
|
||||
id_user INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
username VARCHAR(255) NOT NULL,
|
||||
email VARCHAR(255) NOT NULL UNIQUE,
|
||||
password BINARY(64) NOT NULL,
|
||||
email VARCHAR(255) NOT NULL
|
||||
salt BINARY(8) NOT NULL,
|
||||
registration_time TIMESTAMP NOT NULL
|
||||
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
|
||||
`); err != nil {
|
||||
return err
|
|
@ -0,0 +1,89 @@
|
|||
package libredns
|
||||
|
||||
import (
|
||||
)
|
||||
|
||||
type Zone struct {
|
||||
Id int64 `json:"id"`
|
||||
DomainName string `json:"domain"`
|
||||
Server string `json:"server,omitempty"`
|
||||
KeyName string `json:"keyname,omitempty"`
|
||||
KeyBlob []byte `json:"keyblob,omitempty"`
|
||||
}
|
||||
|
||||
func GetZones() (zones []Zone, err error) {
|
||||
if rows, errr := DBQuery("SELECT id_zone, domain, server, key_name, key_blob FROM zones"); errr != nil {
|
||||
return nil, errr
|
||||
} else {
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var z Zone
|
||||
if err = rows.Scan(&z.Id, &z.DomainName, &z.Server, &z.KeyName, &z.KeyBlob); err != nil {
|
||||
return
|
||||
}
|
||||
zones = append(zones, z)
|
||||
}
|
||||
if err = rows.Err(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func GetZone(id int) (z Zone, err error) {
|
||||
err = DBQueryRow("SELECT id_user, domain, server, key_name, key_blob FROM zones WHERE id_zone=?", id).Scan(&z.Id, &z.DomainName, &z.Server, &z.KeyName, &z.KeyBlob)
|
||||
return
|
||||
}
|
||||
|
||||
func GetZoneByDN(dn string) (z Zone, err error) {
|
||||
err = DBQueryRow("SELECT id_zone, domain, server, key_name, key_blob FROM zones WHERE domain=?", dn).Scan(&z.Id, &z.DomainName, &z.Server, &z.KeyName, &z.KeyBlob)
|
||||
return
|
||||
}
|
||||
|
||||
func ZoneExists(dn string) bool {
|
||||
var z int
|
||||
err := DBQueryRow("SELECT 1 FROM zones WHERE domain=?", dn).Scan(&z)
|
||||
return err == nil && z == 1
|
||||
}
|
||||
|
||||
func (z *Zone) NewZone() (Zone, error) {
|
||||
if res, err := DBExec("INSERT INTO zones (domain, server, key_name, key_blob) VALUES (?, ?, ?, ?)", z.DomainName, z.Server, z.KeyName, z.KeyBlob); err != nil {
|
||||
return *z, err
|
||||
} else if z.Id, err = res.LastInsertId(); err != nil {
|
||||
return *z, err
|
||||
} else {
|
||||
return *z, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (z *Zone) Update() (int64, error) {
|
||||
if res, err := DBExec("UPDATE zones SET domain = ? WHERE id_zone = ?", z.DomainName, z.Id); err != nil {
|
||||
return 0, err
|
||||
} else if nb, err := res.RowsAffected(); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return nb, err
|
||||
}
|
||||
}
|
||||
|
||||
func (z *Zone) Delete() (int64, error) {
|
||||
if res, err := DBExec("DELETE FROM zones WHERE id_zone = ?", z.Id); err != nil {
|
||||
return 0, err
|
||||
} else if nb, err := res.RowsAffected(); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return nb, err
|
||||
}
|
||||
}
|
||||
|
||||
func ClearZones() (int64, error) {
|
||||
if res, err := DBExec("DELETE FROM zones"); err != nil {
|
||||
return 0, err
|
||||
} else if nb, err := res.RowsAffected(); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return nb, err
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue