136 lines
3.4 KiB
Go
136 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/julienschmidt/httprouter"
|
|
)
|
|
|
|
func init() {
|
|
router.GET("/api/adomains/", apiAuthHandler(func (student Student, ps httprouter.Params, body []byte) (interface{}, error) {
|
|
return student.GetAssociatedDomains(), nil
|
|
}))
|
|
router.POST("/api/adomains/", apiAuthHandler(func (student Student, ps httprouter.Params, body []byte) (interface{}, error) {
|
|
return true, student.AddAssociatedDomains()
|
|
}))
|
|
router.GET("/api/adomains/:dn", apiAuthHandler(func (student Student, ps httprouter.Params, body []byte) (interface{}, error) {
|
|
return student.GetAssociatedDomain(ps.ByName("dn"))
|
|
}))
|
|
|
|
router.GET("/api/ddomains/", apiAuthHandler(func (student Student, ps httprouter.Params, body []byte) (interface{}, error) {
|
|
return student.GetDelegatedDomains()
|
|
}))
|
|
router.GET("/api/ddomains/:dn", apiAuthHandler(func (student Student, ps httprouter.Params, body []byte) (interface{}, error) {
|
|
return student.GetDelegatedDomain(ps.ByName("dn"))
|
|
}))
|
|
}
|
|
|
|
type Entry struct {
|
|
Domain string `json:"domain"`
|
|
TTL uint64 `json:"ttl"`
|
|
RR string `json:"rr"`
|
|
Values []string `json:"values"`
|
|
}
|
|
|
|
func runKnotc(args ...string) (out []byte, err error) {
|
|
cmd := exec.Command("knotc", args...)
|
|
cmd.Env = append(os.Environ(),
|
|
"LD_PRELOAD=/usr/lib/gcc/armv5tel-softfloat-linux-gnueabi/8.2.0/libgcc_s.so.1",
|
|
)
|
|
|
|
return cmd.CombinedOutput()
|
|
}
|
|
|
|
func parseKnotZoneRead(args ...string) (rr []Entry, err error) {
|
|
var out []byte
|
|
args = append([]string{"zone-read"}, args...)
|
|
out, err = runKnotc(args...)
|
|
|
|
for _, line := range strings.Split(string(out), "\n") {
|
|
cols := strings.Fields(line)
|
|
if len(cols) >= 5 {
|
|
var ttl uint64
|
|
ttl, err = strconv.ParseUint(cols[2], 10, 64)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
rr = append(rr, Entry{cols[1], ttl, cols[3], cols[4:]})
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (student Student) myAssociatedDomain() (string) {
|
|
return fmt.Sprintf("%s.adlin2020.p0m.fr.", student.Login)
|
|
}
|
|
|
|
func (student Student) GetAssociatedDomains() (ds []string) {
|
|
studentDomain := student.myAssociatedDomain()
|
|
|
|
if _, err := parseKnotZoneRead("adlin2020.p0m.fr", studentDomain); err == nil {
|
|
ds = append(ds, studentDomain)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (student Student) GetAssociatedDomain(dn string) (rrs []Entry, err error) {
|
|
domains := student.GetAssociatedDomains()
|
|
found := false
|
|
for _, d := range domains {
|
|
if d == dn {
|
|
found = true
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
err = errors.New(fmt.Sprintf("Unable to find domain %q.", dn))
|
|
}
|
|
|
|
rrs, err = parseKnotZoneRead("adlin2020.p0m.fr", dn)
|
|
|
|
return
|
|
}
|
|
|
|
func (student Student) AddAssociatedDomains() (err error) {
|
|
for _, d := range []string{student.myAssociatedDomain()} {
|
|
for _, cmd := range [][]string{
|
|
[]string{"zone-begin", "adlin2020.p0m.fr"},
|
|
[]string{"zone-set", "adlin2020.p0m.fr", d, "900", "A", "82.64.31.248"},
|
|
[]string{"zone-set", "adlin2020.p0m.fr", d, "900", "AAAA", studentIP(student.Id) + "1"},
|
|
[]string{"zone-commit", "adlin2020.p0m.fr"},
|
|
} {
|
|
var out []byte
|
|
out, err = runKnotc(cmd...)
|
|
if err != nil {
|
|
err = errors.New(fmt.Sprintf("An error occurs on command '%s': %s", strings.Join(cmd, " "), err.Error()))
|
|
log.Println(string(out))
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
|
|
type DelegatedDomain struct {
|
|
|
|
}
|
|
|
|
func (student Student) GetDelegatedDomain(dn string) (d DelegatedDomain, err error) {
|
|
return
|
|
}
|
|
|
|
func (student Student) GetDelegatedDomains() (ds []DelegatedDomain, err error) {
|
|
return
|
|
}
|