f-25: dhcp: fill db with dhcp data

Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
This commit is contained in:
GnomeZworc 2026-04-26 18:08:04 +02:00
commit 5ee2ba1669
Signed by: nicolas.boufideline
GPG key ID: 4406BBBF8845D632
5 changed files with 41 additions and 13 deletions

19
internal/dhcp/db.go Normal file
View file

@ -0,0 +1,19 @@
package dhcp
import (
"git.g3e.fr/syonad/two/pkg/db/kv"
"github.com/dgraph-io/badger/v4"
)
func StoreDHCPEntries(db *badger.DB, subnetName string, entries map[string]string) error {
for ip, mac := range entries {
if err := kv.AddInDB(db, "subnet/"+subnetName+"/dhcp/"+ip, mac); err != nil {
return err
}
}
return nil
}
func GetMACForIP(db *badger.DB, subnetName, ip string) (string, error) {
return kv.GetFromDB(db, "subnet/"+subnetName+"/dhcp/"+ip)
}

View file

@ -61,7 +61,7 @@ func newConf(t *testing.T, cidr string) Config {
func TestGenerateConfig_CreatesFile(t *testing.T) {
conf := newConf(t, "192.168.1.0/29") // 6 hôtes
path, err := GenerateConfig(conf)
path, _, err := GenerateConfig(conf)
if err != nil {
t.Fatalf("GenerateConfig a échoué : %v", err)
}
@ -73,7 +73,7 @@ func TestGenerateConfig_CreatesFile(t *testing.T) {
func TestGenerateConfig_FilenameMatchesName(t *testing.T) {
conf := newConf(t, "192.168.1.0/29")
path, err := GenerateConfig(conf)
path, _, err := GenerateConfig(conf)
if err != nil {
t.Fatalf("GenerateConfig a échoué : %v", err)
}
@ -86,7 +86,7 @@ func TestGenerateConfig_FilenameMatchesName(t *testing.T) {
func TestGenerateConfig_ContainsGateway(t *testing.T) {
conf := newConf(t, "192.168.1.0/29")
path, _ := GenerateConfig(conf)
path, _, _ := GenerateConfig(conf)
content, _ := os.ReadFile(path)
if !strings.Contains(string(content), "dhcp-option=3,192.168.1.1") {
@ -102,7 +102,7 @@ func TestGenerateConfig_ContainsDhcpRange(t *testing.T) {
Name: "vpc1",
ConfDir: t.TempDir(),
}
path, _ := GenerateConfig(conf)
path, _, _ := GenerateConfig(conf)
content, _ := os.ReadFile(path)
if !strings.Contains(string(content), "dhcp-range=10.10.0.0,static,255.255.255.0,12h") {
@ -113,7 +113,7 @@ func TestGenerateConfig_ContainsDhcpRange(t *testing.T) {
func TestGenerateConfig_OneHostEntryPerIP(t *testing.T) {
// /29 = réseau + broadcast + 6 hôtes → 8 adresses
conf := newConf(t, "10.0.0.0/29")
path, _ := GenerateConfig(conf)
path, _, _ := GenerateConfig(conf)
content, _ := os.ReadFile(path)
lines := strings.Split(string(content), "\n")
@ -131,7 +131,7 @@ func TestGenerateConfig_OneHostEntryPerIP(t *testing.T) {
func TestGenerateConfig_MACPrefix(t *testing.T) {
conf := newConf(t, "10.0.0.0/30") // 4 adresses
path, _ := GenerateConfig(conf)
path, _, _ := GenerateConfig(conf)
content, _ := os.ReadFile(path)
if !strings.Contains(string(content), "00:22:33:") {
@ -148,7 +148,7 @@ func TestGenerateConfig_CreatesConfDir(t *testing.T) {
Name: "net",
ConfDir: dir,
}
if _, err := GenerateConfig(conf); err != nil {
if _, _, err := GenerateConfig(conf); err != nil {
t.Fatalf("GenerateConfig devrait créer les répertoires manquants : %v", err)
}
if _, err := os.Stat(dir); os.IsNotExist(err) {

View file

@ -8,7 +8,7 @@ import (
"strings"
)
func GenerateConfig(c Config) (string, error) {
func GenerateConfig(c Config) (string, map[string]string, error) {
mask := fmt.Sprintf("%d.%d.%d.%d", c.Network.Mask[0], c.Network.Mask[1], c.Network.Mask[2], c.Network.Mask[3])
var sb strings.Builder
@ -17,18 +17,20 @@ func GenerateConfig(c Config) (string, error) {
fmt.Fprintf(&sb, "dhcp-option=3,%s\n", c.Gateway.String())
fmt.Fprintf(&sb, "dhcp-option=6,1.1.1.1,8.8.8.8\n\n")
entries := make(map[string]string)
i := 0
for ip := cloneIP(c.Network.IP); c.Network.Contains(ip); incrementIP(ip) {
fmt.Fprintf(&sb, "dhcp-host=00:22:33:%02X:%02X:%02X,%s\n",
(i>>16)&0xFF, (i>>8)&0xFF, i&0xFF, ip)
mac := fmt.Sprintf("00:22:33:%02X:%02X:%02X", (i>>16)&0xFF, (i>>8)&0xFF, i&0xFF)
fmt.Fprintf(&sb, "dhcp-host=%s,%s\n", mac, ip)
entries[ip.String()] = mac
i++
}
outPath := filepath.Join(c.ConfDir, c.Name+".conf")
if err := os.MkdirAll(c.ConfDir, 0755); err != nil {
return "", err
return "", nil, err
}
return outPath, os.WriteFile(outPath, []byte(sb.String()), 0644)
return outPath, entries, os.WriteFile(outPath, []byte(sb.String()), 0644)
}
func incrementIP(ip net.IP) {

View file

@ -101,9 +101,13 @@ func CreateSubnet(db *badger.DB, subnetName string) error {
Name: d.vpc + "_" + d.bridge,
ConfDir: "/etc/dnsmasq.d",
}
if _, err := dhcp.GenerateConfig(conf); err != nil {
_, entries, err := dhcp.GenerateConfig(conf)
if err != nil {
return fmt.Errorf("generate dhcp config: %w", err)
}
if err := dhcp.StoreDHCPEntries(db, subnetName, entries); err != nil {
return fmt.Errorf("store dhcp entries: %w", err)
}
svc, err := systemd.New()
if err != nil {

View file

@ -42,6 +42,9 @@ func DeleteSubnet(db *badger.DB, subnetName string) error {
if err := os.Remove("/etc/dnsmasq.d/" + d.vpc + "_" + d.bridge + ".conf"); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("remove dnsmasq config: %w", err)
}
if err := kv.DeleteInDB(db, "subnet/"+subnetName+"/dhcp"); err != nil {
return fmt.Errorf("delete dhcp entries: %w", err)
}
if err := ebtables.DeleteARPToGateway(d.bridge, d.gatewayIP.String()); err != nil {
return fmt.Errorf("delete ebtables arp rule: %w", err)