metadata-api: support dnsmasq (#3115)

This commit is contained in:
3u13r 2024-05-24 15:14:16 +02:00 committed by GitHub
parent 37e46b98c2
commit 21c30ebb76
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 304 additions and 270 deletions

View file

@ -0,0 +1,8 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "dhcp",
srcs = ["dhcp.go"],
importpath = "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/dhcp",
visibility = ["//visibility:public"],
)

View file

@ -0,0 +1,13 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package dhcp
// NetworkDHCPLease abstracts a DHCP lease.
type NetworkDHCPLease struct {
IPaddr string
Hostname string
}

View file

@ -0,0 +1,24 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//bazel/go:go_test.bzl", "go_test")
go_library(
name = "dnsmasq",
srcs = ["dnsmasq.go"],
importpath = "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/dhcp/dnsmasq",
visibility = ["//visibility:public"],
deps = [
"//hack/qemu-metadata-api/dhcp",
"@com_github_spf13_afero//:afero",
],
)
go_test(
name = "dnsmasq_test",
srcs = ["dnsmasq_test.go"],
embed = [":dnsmasq"],
deps = [
"@com_github_spf13_afero//:afero",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
],
)

View file

@ -0,0 +1,56 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package dnsmasq
import (
"bufio"
"strings"
"github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/dhcp"
"github.com/spf13/afero"
)
// DNSMasq is a DHCP lease getter for dnsmasq.
type DNSMasq struct {
leasesFileName string
fs *afero.Afero
}
// New creates a new DNSMasq.
func New(leasesFileName string) *DNSMasq {
return &DNSMasq{
leasesFileName: leasesFileName,
fs: &afero.Afero{Fs: afero.NewOsFs()},
}
}
// GetDHCPLeases returns the underlying DHCP leases.
func (d *DNSMasq) GetDHCPLeases() ([]dhcp.NetworkDHCPLease, error) {
file, err := d.fs.Open(d.leasesFileName)
if err != nil {
return nil, err
}
defer file.Close()
// read file
var leases []dhcp.NetworkDHCPLease
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
// split by whitespace
fields := strings.Fields(line)
leases = append(leases, dhcp.NetworkDHCPLease{
IPaddr: fields[2],
Hostname: fields[3],
})
}
if err := scanner.Err(); err != nil {
return nil, err
}
return leases, nil
}

View file

@ -0,0 +1,40 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package dnsmasq
import (
"testing"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGetDHCPLeases(t *testing.T) {
require := require.New(t)
assert := assert.New(t)
fs := afero.NewMemMapFs()
leasesFileName := "dnsmasq.leases"
leasesFile, err := fs.Create(leasesFileName)
require.NoError(err)
_, err = leasesFile.WriteString("1716219737 52:54:af:a1:98:9f 10.42.2.1 worker0 ff:c2:72:f6:09:00:02:00:00:ab:11:18:fc:48:85:40:3f:bc:41\n")
require.NoError(err)
_, err = leasesFile.WriteString("1716219735 52:54:7f:8f:ba:91 10.42.1.1 controlplane0 ff:c2:72:f6:09:00:02:00:00:ab:11:21:7c:b5:14:ec:43:b7:43\n")
require.NoError(err)
leasesFile.Close()
d := DNSMasq{leasesFileName: leasesFileName, fs: &afero.Afero{Fs: fs}}
leases, err := d.GetDHCPLeases()
require.NoError(err)
assert.Len(leases, 2)
assert.Equal("10.42.2.1", leases[0].IPaddr)
assert.Equal("worker0", leases[0].Hostname)
assert.Equal("10.42.1.1", leases[1].IPaddr)
assert.Equal("controlplane0", leases[1].Hostname)
}

View file

@ -0,0 +1,16 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "virtwrapper",
srcs = [
"virtwrapper.go",
"virtwrapper_cgo.go",
"virtwrapper_cross.go",
],
importpath = "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/dhcp/virtwrapper",
visibility = ["//visibility:public"],
deps = [
"//hack/qemu-metadata-api/dhcp",
"@org_libvirt_go_libvirt//:libvirt",
],
)

View file

@ -0,0 +1,7 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package virtwrapper

View file

@ -0,0 +1,60 @@
//go:build cgo
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package virtwrapper
import (
"github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/dhcp"
"libvirt.org/go/libvirt"
)
// Connect wraps a libvirt connection.
type Connect struct {
conn *libvirt.Connect
networkName string
}
// New creates a new libvirt Connct wrapper.
func New(conn *libvirt.Connect, networkName string) *Connect {
return &Connect{
conn: conn,
networkName: networkName,
}
}
// LookupNetworkByName looks up a network by name.
func (c *Connect) lookupNetworkByName(name string) (*libvirt.Network, error) {
net, err := c.conn.LookupNetworkByName(name)
if err != nil {
return nil, err
}
return net, nil
}
// GetDHCPLeases returns the underlying DHCP leases.
func (c *Connect) GetDHCPLeases() ([]dhcp.NetworkDHCPLease, error) {
net, err := c.lookupNetworkByName(c.networkName)
if err != nil {
return nil, err
}
defer net.Free()
leases, err := net.GetDHCPLeases()
if err != nil {
return nil, err
}
ret := make([]dhcp.NetworkDHCPLease, len(leases))
for i, l := range leases {
ret[i] = dhcp.NetworkDHCPLease{
IPaddr: l.IPaddr,
Hostname: l.Hostname,
}
}
return ret, nil
}

View file

@ -0,0 +1,24 @@
//go:build !cgo
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package virtwrapper
import (
"errors"
"github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/dhcp"
)
// Connect wraps a libvirt connection.
type Connect struct{}
// GetDHCPLeases returns the underlying DHCP leases.
// This function errors if CGO is disabled.
func (n *Connect) GetDHCPLeases() ([]dhcp.NetworkDHCPLease, error) {
return nil, errors.New("using virtwrapper requires building with CGO")
}