maatma: implement associated domains
This commit is contained in:
parent
955e263d39
commit
5f83c5cd2c
3 changed files with 161 additions and 12 deletions
|
@ -1,10 +1,28 @@
|
|||
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()
|
||||
}))
|
||||
|
@ -13,6 +31,97 @@ func init() {
|
|||
}))
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -155,5 +155,51 @@ angular.module("AdLinApp")
|
|||
})
|
||||
|
||||
.controller("DomainsController", function($scope, $http, $interval) {
|
||||
$scope.updateAssociationD = function() {
|
||||
$http({
|
||||
method: 'GET',
|
||||
url: "/api/adomains/",
|
||||
headers: {
|
||||
'Authorization': "Bearer " + sessionStorage.token
|
||||
},
|
||||
}).then(function(response) {
|
||||
$scope.adomains = [];
|
||||
response.data.forEach(function(domain) {
|
||||
$http({
|
||||
method: 'GET',
|
||||
url: "/api/adomains/" + domain,
|
||||
headers: {
|
||||
'Authorization': "Bearer " + sessionStorage.token
|
||||
},
|
||||
}).then(function(response) {
|
||||
response.data.forEach(function(rr) {
|
||||
$scope.adomains.push(rr);
|
||||
|
||||
});
|
||||
});
|
||||
}, function(response) {
|
||||
alert(response.data.errmsg);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.updateAssociationD();
|
||||
|
||||
$scope.newAssociationD = function() {
|
||||
$scope.pleaseWaitNewAssociation = true;
|
||||
$http({
|
||||
method: 'POST',
|
||||
url: "/api/adomains/",
|
||||
headers: {
|
||||
'Authorization': "Bearer " + sessionStorage.token
|
||||
},
|
||||
}).then(function(response) {
|
||||
$scope.updateAssociationD();
|
||||
$scope.pleaseWaitNewAssociation = false;
|
||||
}, function(response) {
|
||||
alert(response.data.errmsg);
|
||||
$scope.pleaseWaitNewAssociation = false;
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
|
|
|
@ -14,23 +14,17 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody style="font-family: monospace">
|
||||
<tr>
|
||||
<td>{{ isLogged.login }}.adlin2020.p0m.fr</td>
|
||||
<td>900</td>
|
||||
<td>A</td>
|
||||
<td>82.64.31.248</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ isLogged.login }}.adlin2020.p0m.fr</td>
|
||||
<td>900</td>
|
||||
<td>AAAA</td>
|
||||
<td>2a01:e0a:2b:2252:{{ isLogged.id.toString(16) }}::1</td>
|
||||
<tr ng-repeat="ad in adomains">
|
||||
<td>{{ ad.domain }}</td>
|
||||
<td>{{ ad.ttl }}</td>
|
||||
<td>{{ ad.rr }}</td>
|
||||
<td><span ng-repeat="val in ad.values">{{ val }} </span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<button class="btn btn-primary" ng-click="newAssociation()">
|
||||
<button class="btn btn-primary" ng-click="newAssociationD()">
|
||||
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true" ng-show="pleaseWaitNewAssociation"></span>
|
||||
Demander un nouveau nom de domaine
|
||||
</button>
|
||||
|
|
Reference in a new issue