Compare commits

..

16 commits

Author SHA1 Message Date
ddcbd2b6fa
f-50: docs: lab livré, routeur Linux par choix, écrire un scénario #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 21:51:54 +02:00
909b4110c2
f-50: lab: résultats d'E5, contrôle DHCP de s1 sur les couples MAC/IP, perte du route reflector #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 21:17:48 +02:00
b4660c95d3
f-50: lab: scénarios E5, configuration de l'agent par hyperviseur, release 0.2.0rc003 #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 20:43:53 +02:00
f9aadc00fc
f-50: lab: seedfrom avec barre oblique finale, push sans propriétaire, résultats d'E4 #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 19:37:57 +02:00
bc05fd9c89
f-50: docs: route reflector — adressage et configuration FRR validés dans le lab #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 17:57:11 +02:00
50fb84dc85
f-50: docs: adresses 192.168.14.0/24 du route reflector et de la passerelle sur le schéma #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 17:49:09 +02:00
6bf0435ea4
f-50: docs: schéma d'architecture du cluster — routeurs, route reflector, hyperviseurs, plans de données et de contrôle #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 17:44:49 +02:00
4410f30afa
f-50: lab: déploiement de two sur les hyperviseurs et provisionnement en un script #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 17:36:15 +02:00
b348652995
f-50: lab: rôles des nœuds, adresses du lien, loopback et installation de FRR #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 17:17:02 +02:00
32940c57b4
f-50: deploy: exit 0 when the deployment succeeds
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 16:34:27 +02:00
90d8128b6c
f-50: lab: préparation du serveur, dépôt de lab et validation sur Scaleway #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 16:31:14 +02:00
1146d13d45
f-50: lab: lancement, état, arrêt et accès SSH des VM #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 14:49:34 +02:00
d1cd943d86
f-50: lab: image vérifiée, disques et seeds des VM #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 14:21:20 +02:00
99ecb59aad
f-50: lab: arguments QEMU et seeds cloud-init des VM #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 01:17:12 +02:00
a706e24b1c
f-50: lab: topologie et calcul du plan #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 00:49:21 +02:00
28ce00cfa3
f-50: lab: cycle de vie du serveur de lab Scaleway #50
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
2026-10-04 00:16:20 +02:00
2 changed files with 0 additions and 92 deletions

View file

@ -1,31 +1,14 @@
package netif
import (
"fmt"
"net"
"syscall"
"github.com/vishvananda/netlink"
)
const (
scopeUniverse = 0
addressSecondary = 0x01
)
func CreateVxlan(name string, vxlanID int, localIface string, mtu int) error {
link, err := netlink.LinkByName(localIface)
if err != nil {
return err
}
addrs, err := netlink.AddrList(link, syscall.AF_INET)
if err != nil {
return err
}
local, err := vtepAddress(localIface, addrs)
if err != nil {
return err
}
vxlan := &netlink.Vxlan{
LinkAttrs: netlink.LinkAttrs{
Name: name,
@ -34,18 +17,7 @@ func CreateVxlan(name string, vxlanID int, localIface string, mtu int) error {
VxlanId: vxlanID,
Port: 4789,
VtepDevIndex: link.Attrs().Index,
SrcAddr: local,
Learning: false,
}
return netlink.LinkAdd(vxlan)
}
func vtepAddress(iface string, addrs []netlink.Addr) (net.IP, error) {
for _, a := range addrs {
if a.IPNet == nil || a.IP.To4() == nil || a.Scope != scopeUniverse || a.Flags&addressSecondary != 0 {
continue
}
return a.IP.To4(), nil
}
return nil, fmt.Errorf("no primary global IPv4 address on %s for the VXLAN local endpoint", iface)
}

View file

@ -1,64 +0,0 @@
package netif
import (
"net"
"strings"
"testing"
"github.com/vishvananda/netlink"
)
func addr(cidr string, scope, flags int) netlink.Addr {
ip, network, err := net.ParseCIDR(cidr)
if err != nil {
panic(err)
}
network.IP = ip
return netlink.Addr{IPNet: network, Scope: scope, Flags: flags}
}
func TestVtepAddress_PicksThePrimaryGlobalIPv4(t *testing.T) {
addrs := []netlink.Addr{
addr("127.0.0.1/8", 254, 0),
addr("169.254.0.3/28", 0, 0x01),
addr("192.168.14.11/24", 0, 0x80),
addr("192.168.14.99/24", 0, 0x01),
}
got, err := vtepAddress("br-000000", addrs)
if err != nil || got.String() != "192.168.14.11" {
t.Errorf("vtepAddress = %v, %v, want 192.168.14.11", got, err)
}
}
func TestVtepAddress_SkipsLinkScopeAndSecondaryAddresses(t *testing.T) {
addrs := []netlink.Addr{
addr("169.254.0.3/28", 253, 0),
addr("192.168.14.99/24", 0, 0x01),
addr("192.168.14.12/24", 0, 0),
}
got, err := vtepAddress("br-000000", addrs)
if err != nil || got.String() != "192.168.14.12" {
t.Errorf("vtepAddress = %v, %v, want 192.168.14.12", got, err)
}
}
func TestVtepAddress_RefusesAnInterfaceWithoutUsableAddress(t *testing.T) {
for name, addrs := range map[string][]netlink.Addr{
"no address": nil,
"only secondary": {addr("192.168.14.99/24", 0, 0x01)},
"only link": {addr("169.254.0.3/28", 253, 0)},
"only IPv6": {addr("fd00::11/64", 0, 0)},
} {
_, err := vtepAddress("br-000000", addrs)
if err == nil || !strings.Contains(err.Error(), "no primary global IPv4 address on br-000000") {
t.Errorf("%s: error = %v", name, err)
}
}
}
func TestVtepAddress_ReturnsAFourByteAddress(t *testing.T) {
got, err := vtepAddress("br-000000", []netlink.Addr{addr("192.168.14.11/24", 0, 0)})
if err != nil || len(got) != 4 {
t.Errorf("vtepAddress = %v (%d bytes), %v", got, len(got), err)
}
}