f-33: net: add multi net in dispatch et vms #33
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
This commit is contained in:
parent
1ec1d44c1a
commit
0237acba81
15 changed files with 753 additions and 146 deletions
|
|
@ -4,7 +4,9 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
configuration "git.g3e.fr/syonad/two/internal/config/agent"
|
||||
"git.g3e.fr/syonad/two/internal/netns"
|
||||
|
|
@ -46,33 +48,65 @@ func CheckVMs(db *badger.DB, cfg *configuration.Config, u unitChecker, n notify.
|
|||
}
|
||||
|
||||
func checkVM(db *badger.DB, cfg *configuration.Config, name string, u unitChecker, n notify.Notifier) {
|
||||
subnetName, err := kv.GetFromDB(db, prefixVM+name+"/subnet")
|
||||
entries, err := kv.ListByPrefix(db, prefixVM+name+"/nic/")
|
||||
if err != nil {
|
||||
n.Notify(kindVM, name, fmt.Sprintf("subnet unreadable in database: %v", err))
|
||||
n.Notify(kindVM, name, fmt.Sprintf("interfaces unreadable in database: %v", err))
|
||||
return
|
||||
}
|
||||
indexes := nicIndexes(entries, prefixVM+name+"/nic/")
|
||||
if len(indexes) == 0 {
|
||||
n.Notify(kindVM, name, "no interface in database")
|
||||
return
|
||||
}
|
||||
|
||||
vpc, err := kv.GetFromDB(db, prefixSubnet+subnetName+"/vpc")
|
||||
if err != nil {
|
||||
n.Notify(kindVM, name, fmt.Sprintf("vpc of subnet %s unreadable in database: %v", subnetName, err))
|
||||
return
|
||||
for _, idx := range indexes {
|
||||
prefix := fmt.Sprintf("%s%s/nic/%d/", prefixVM, name, idx)
|
||||
subnetName := entries[prefix+"subnet"]
|
||||
if subnetName == "" {
|
||||
n.Notify(kindVM, name, fmt.Sprintf("interface %d has no subnet in database", idx))
|
||||
continue
|
||||
}
|
||||
vpc, err := kv.GetFromDB(db, prefixSubnet+subnetName+"/vpc")
|
||||
if err != nil {
|
||||
n.Notify(kindVM, name, fmt.Sprintf("vpc of subnet %s unreadable in database: %v", subnetName, err))
|
||||
continue
|
||||
}
|
||||
checkVMTap(entries[prefix+"tap_id"], name, vpc, idx, n)
|
||||
}
|
||||
|
||||
checkVMTap(db, name, vpc, n)
|
||||
checkVMQemu(cfg, name, n)
|
||||
checkUnit(kindVM, name, "metadata@"+name+".service", u, n)
|
||||
checkUnit(kindVM, name, qemu.ScopeName(name), u, n)
|
||||
}
|
||||
|
||||
func checkVMTap(db *badger.DB, name, vpc string, n notify.Notifier) {
|
||||
raw, err := kv.GetFromDB(db, prefixVM+name+"/tap_id")
|
||||
if err != nil {
|
||||
n.Notify(kindVM, name, fmt.Sprintf("tap_id unreadable in database: %v", err))
|
||||
// nicIndexes retourne les index d'interface présents en base, triés.
|
||||
func nicIndexes(entries map[string]string, prefix string) []int {
|
||||
seen := make(map[int]bool)
|
||||
for key := range entries {
|
||||
parts := strings.Split(strings.TrimPrefix(key, prefix), "/")
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
if idx, err := strconv.Atoi(parts[0]); err == nil {
|
||||
seen[idx] = true
|
||||
}
|
||||
}
|
||||
indexes := make([]int, 0, len(seen))
|
||||
for idx := range seen {
|
||||
indexes = append(indexes, idx)
|
||||
}
|
||||
sort.Ints(indexes)
|
||||
return indexes
|
||||
}
|
||||
|
||||
func checkVMTap(raw, name, vpc string, idx int, n notify.Notifier) {
|
||||
if raw == "" {
|
||||
n.Notify(kindVM, name, fmt.Sprintf("interface %d has no tap_id in database", idx))
|
||||
return
|
||||
}
|
||||
tapID, err := strconv.Atoi(raw)
|
||||
if err != nil {
|
||||
n.Notify(kindVM, name, fmt.Sprintf("invalid tap_id %q: %v", raw, err))
|
||||
n.Notify(kindVM, name, fmt.Sprintf("interface %d has an invalid tap_id %q: %v", idx, raw, err))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,11 @@ func testCfg(t *testing.T) *configuration.Config {
|
|||
func seedVM(t *testing.T, db *badger.DB, name, subnetName, vpc, tapID string) {
|
||||
t.Helper()
|
||||
seedResource(t, db, prefixVM, name, state.Running)
|
||||
seedKV(t, db, prefixVM+name+"/subnet", subnetName)
|
||||
seedKV(t, db, prefixVM+name+"/nic/0/subnet", subnetName)
|
||||
seedKV(t, db, prefixVM+name+"/nic/0/primary", "true")
|
||||
seedKV(t, db, prefixSubnet+subnetName+"/vpc", vpc)
|
||||
if tapID != "" {
|
||||
seedKV(t, db, prefixVM+name+"/tap_id", tapID)
|
||||
seedKV(t, db, prefixVM+name+"/nic/0/tap_id", tapID)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +74,7 @@ func TestCheckVMs_IgnoreLesEtatsNonRunning(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCheckVMs_SubnetManquantEnBase(t *testing.T) {
|
||||
func TestCheckVMs_AucuneInterfaceEnBase(t *testing.T) {
|
||||
db := newTestDB(t)
|
||||
seedResource(t, db, prefixVM, "i-test1", state.Running)
|
||||
r := &recorder{}
|
||||
|
|
@ -86,15 +87,16 @@ func TestCheckVMs_SubnetManquantEnBase(t *testing.T) {
|
|||
if len(got) != 1 {
|
||||
t.Fatalf("attendu 1 notification, obtenu %d : %v", len(got), got)
|
||||
}
|
||||
if !strings.Contains(got[0].problem, "subnet unreadable") {
|
||||
t.Errorf("problem = %q, devrait porter sur le subnet", got[0].problem)
|
||||
if !strings.Contains(got[0].problem, "no interface") {
|
||||
t.Errorf("problem = %q, devrait signaler l'absence d'interface", got[0].problem)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckVMs_VPCDuSubnetManquant(t *testing.T) {
|
||||
db := newTestDB(t)
|
||||
seedResource(t, db, prefixVM, "i-test1", state.Running)
|
||||
seedKV(t, db, prefixVM+"i-test1/subnet", "br-000042")
|
||||
seedKV(t, db, prefixVM+"i-test1/nic/0/subnet", "br-000042")
|
||||
seedKV(t, db, prefixVM+"i-test1/nic/0/primary", "true")
|
||||
r := &recorder{}
|
||||
|
||||
if err := CheckVMs(db, testCfg(t), newFakeUnits(), r); err != nil {
|
||||
|
|
@ -115,8 +117,8 @@ func TestCheckVMs_TapIDManquant(t *testing.T) {
|
|||
t.Fatalf("erreur inattendue: %v", err)
|
||||
}
|
||||
|
||||
if !r.hasProblemContaining("tap_id unreadable") {
|
||||
t.Errorf("devrait signaler un tap_id illisible, obtenu %v", r.calls)
|
||||
if !r.hasProblemContaining("has no tap_id") {
|
||||
t.Errorf("devrait signaler un tap_id absent, obtenu %v", r.calls)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue