From 21c30ebb760490fd9980a186bbcf05e43eaadc1b Mon Sep 17 00:00:00 2001 From: 3u13r Date: Fri, 24 May 2024 15:14:16 +0200 Subject: [PATCH] metadata-api: support dnsmasq (#3115) --- hack/qemu-metadata-api/BUILD.bazel | 3 +- hack/qemu-metadata-api/dhcp/BUILD.bazel | 8 ++ .../virtwrapper.go => dhcp/dhcp.go} | 4 +- .../dhcp/dnsmasq/BUILD.bazel | 24 ++++ .../qemu-metadata-api/dhcp/dnsmasq/dnsmasq.go | 56 +++++++++ .../dhcp/dnsmasq/dnsmasq_test.go | 40 +++++++ .../{ => dhcp}/virtwrapper/BUILD.bazel | 7 +- .../dhcp/virtwrapper/virtwrapper.go | 7 ++ .../dhcp/virtwrapper/virtwrapper_cgo.go | 60 ++++++++++ .../dhcp/virtwrapper/virtwrapper_cross.go | 24 ++++ hack/qemu-metadata-api/main.go | 25 +++-- hack/qemu-metadata-api/server/BUILD.bazel | 11 +- hack/qemu-metadata-api/server/server.go | 31 ++--- .../server/server_cgo_test.go | 41 ------- .../server/server_cross_test.go | 31 ----- hack/qemu-metadata-api/server/server_test.go | 106 ++++++++---------- .../virtwrapper/virtwrapper_cgo.go | 56 --------- .../virtwrapper/virtwrapper_cross.go | 40 ------- 18 files changed, 304 insertions(+), 270 deletions(-) create mode 100644 hack/qemu-metadata-api/dhcp/BUILD.bazel rename hack/qemu-metadata-api/{virtwrapper/virtwrapper.go => dhcp/dhcp.go} (67%) create mode 100644 hack/qemu-metadata-api/dhcp/dnsmasq/BUILD.bazel create mode 100644 hack/qemu-metadata-api/dhcp/dnsmasq/dnsmasq.go create mode 100644 hack/qemu-metadata-api/dhcp/dnsmasq/dnsmasq_test.go rename hack/qemu-metadata-api/{ => dhcp}/virtwrapper/BUILD.bazel (68%) create mode 100644 hack/qemu-metadata-api/dhcp/virtwrapper/virtwrapper.go create mode 100644 hack/qemu-metadata-api/dhcp/virtwrapper/virtwrapper_cgo.go create mode 100644 hack/qemu-metadata-api/dhcp/virtwrapper/virtwrapper_cross.go delete mode 100644 hack/qemu-metadata-api/server/server_cgo_test.go delete mode 100644 hack/qemu-metadata-api/server/server_cross_test.go delete mode 100644 hack/qemu-metadata-api/virtwrapper/virtwrapper_cgo.go delete mode 100644 hack/qemu-metadata-api/virtwrapper/virtwrapper_cross.go diff --git a/hack/qemu-metadata-api/BUILD.bazel b/hack/qemu-metadata-api/BUILD.bazel index 67811771c..2cfbeb83a 100644 --- a/hack/qemu-metadata-api/BUILD.bazel +++ b/hack/qemu-metadata-api/BUILD.bazel @@ -13,8 +13,9 @@ go_library( importpath = "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api", visibility = ["//visibility:private"], deps = [ + "//hack/qemu-metadata-api/dhcp/dnsmasq", + "//hack/qemu-metadata-api/dhcp/virtwrapper", "//hack/qemu-metadata-api/server", - "//hack/qemu-metadata-api/virtwrapper", "//internal/logger", "@org_libvirt_go_libvirt//:libvirt", ], diff --git a/hack/qemu-metadata-api/dhcp/BUILD.bazel b/hack/qemu-metadata-api/dhcp/BUILD.bazel new file mode 100644 index 000000000..21ba5404c --- /dev/null +++ b/hack/qemu-metadata-api/dhcp/BUILD.bazel @@ -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"], +) diff --git a/hack/qemu-metadata-api/virtwrapper/virtwrapper.go b/hack/qemu-metadata-api/dhcp/dhcp.go similarity index 67% rename from hack/qemu-metadata-api/virtwrapper/virtwrapper.go rename to hack/qemu-metadata-api/dhcp/dhcp.go index 4e5fb6732..6474b6666 100644 --- a/hack/qemu-metadata-api/virtwrapper/virtwrapper.go +++ b/hack/qemu-metadata-api/dhcp/dhcp.go @@ -4,9 +4,9 @@ Copyright (c) Edgeless Systems GmbH SPDX-License-Identifier: AGPL-3.0-only */ -package virtwrapper +package dhcp -// NetworkDHCPLease abstracts a libvirt DHCP lease. +// NetworkDHCPLease abstracts a DHCP lease. type NetworkDHCPLease struct { IPaddr string Hostname string diff --git a/hack/qemu-metadata-api/dhcp/dnsmasq/BUILD.bazel b/hack/qemu-metadata-api/dhcp/dnsmasq/BUILD.bazel new file mode 100644 index 000000000..ab5bbd249 --- /dev/null +++ b/hack/qemu-metadata-api/dhcp/dnsmasq/BUILD.bazel @@ -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", + ], +) diff --git a/hack/qemu-metadata-api/dhcp/dnsmasq/dnsmasq.go b/hack/qemu-metadata-api/dhcp/dnsmasq/dnsmasq.go new file mode 100644 index 000000000..1e75e2abd --- /dev/null +++ b/hack/qemu-metadata-api/dhcp/dnsmasq/dnsmasq.go @@ -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 +} diff --git a/hack/qemu-metadata-api/dhcp/dnsmasq/dnsmasq_test.go b/hack/qemu-metadata-api/dhcp/dnsmasq/dnsmasq_test.go new file mode 100644 index 000000000..66a4483cd --- /dev/null +++ b/hack/qemu-metadata-api/dhcp/dnsmasq/dnsmasq_test.go @@ -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) +} diff --git a/hack/qemu-metadata-api/virtwrapper/BUILD.bazel b/hack/qemu-metadata-api/dhcp/virtwrapper/BUILD.bazel similarity index 68% rename from hack/qemu-metadata-api/virtwrapper/BUILD.bazel rename to hack/qemu-metadata-api/dhcp/virtwrapper/BUILD.bazel index c1ad3b7c9..762c0b301 100644 --- a/hack/qemu-metadata-api/virtwrapper/BUILD.bazel +++ b/hack/qemu-metadata-api/dhcp/virtwrapper/BUILD.bazel @@ -7,7 +7,10 @@ go_library( "virtwrapper_cgo.go", "virtwrapper_cross.go", ], - importpath = "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/virtwrapper", + importpath = "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/dhcp/virtwrapper", visibility = ["//visibility:public"], - deps = ["@org_libvirt_go_libvirt//:libvirt"], + deps = [ + "//hack/qemu-metadata-api/dhcp", + "@org_libvirt_go_libvirt//:libvirt", + ], ) diff --git a/hack/qemu-metadata-api/dhcp/virtwrapper/virtwrapper.go b/hack/qemu-metadata-api/dhcp/virtwrapper/virtwrapper.go new file mode 100644 index 000000000..fa77b81de --- /dev/null +++ b/hack/qemu-metadata-api/dhcp/virtwrapper/virtwrapper.go @@ -0,0 +1,7 @@ +/* +Copyright (c) Edgeless Systems GmbH + +SPDX-License-Identifier: AGPL-3.0-only +*/ + +package virtwrapper diff --git a/hack/qemu-metadata-api/dhcp/virtwrapper/virtwrapper_cgo.go b/hack/qemu-metadata-api/dhcp/virtwrapper/virtwrapper_cgo.go new file mode 100644 index 000000000..bacd3c81f --- /dev/null +++ b/hack/qemu-metadata-api/dhcp/virtwrapper/virtwrapper_cgo.go @@ -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 +} diff --git a/hack/qemu-metadata-api/dhcp/virtwrapper/virtwrapper_cross.go b/hack/qemu-metadata-api/dhcp/virtwrapper/virtwrapper_cross.go new file mode 100644 index 000000000..58e12f0f7 --- /dev/null +++ b/hack/qemu-metadata-api/dhcp/virtwrapper/virtwrapper_cross.go @@ -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") +} diff --git a/hack/qemu-metadata-api/main.go b/hack/qemu-metadata-api/main.go index dd5be683c..5169200b3 100644 --- a/hack/qemu-metadata-api/main.go +++ b/hack/qemu-metadata-api/main.go @@ -13,29 +13,38 @@ import ( "log/slog" "os" + "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/dhcp/dnsmasq" + "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/dhcp/virtwrapper" "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/server" - "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/virtwrapper" "github.com/edgelesssys/constellation/v2/internal/logger" "libvirt.org/go/libvirt" ) func main() { bindPort := flag.String("port", "8080", "Port to bind to") - targetNetwork := flag.String("network", "constellation-network", "Name of the network in QEMU to use") + targetNetwork := flag.String("network", "constellation-network", "Name of the network in libvirt") libvirtURI := flag.String("libvirt-uri", "qemu:///system", "URI of the libvirt connection") + leasesFileName := flag.String("dnsmasq-leases", "", "Path to the dnsmasq leases file") initSecretHash := flag.String("initsecrethash", "", "brcypt hash of the init secret") flag.Parse() log := logger.NewJSONLogger(slog.LevelInfo) - conn, err := libvirt.NewConnect(*libvirtURI) - if err != nil { - log.With(slog.Any("error", err)).Error("Failed to connect to libvirt") - os.Exit(1) + var leaseGetter server.LeaseGetter + if *leasesFileName == "" { + conn, err := libvirt.NewConnect(*libvirtURI) + if err != nil { + log.With(slog.Any("error", err)).Error("Failed to connect to libvirt") + os.Exit(1) + } + defer conn.Close() + leaseGetter = virtwrapper.New(conn, *targetNetwork) + } else { + log.Info("Using dnsmasq leases file") + leaseGetter = dnsmasq.New(*leasesFileName) } - defer conn.Close() - serv := server.New(log, *targetNetwork, *initSecretHash, &virtwrapper.Connect{Conn: conn}) + serv := server.New(log, *targetNetwork, *initSecretHash, leaseGetter) if err := serv.ListenAndServe(*bindPort); err != nil { log.With(slog.Any("error", err)).Error("Failed to serve") os.Exit(1) diff --git a/hack/qemu-metadata-api/server/BUILD.bazel b/hack/qemu-metadata-api/server/BUILD.bazel index 5def36c03..683ec416a 100644 --- a/hack/qemu-metadata-api/server/BUILD.bazel +++ b/hack/qemu-metadata-api/server/BUILD.bazel @@ -10,7 +10,7 @@ go_library( ], visibility = ["//visibility:public"], deps = [ - "//hack/qemu-metadata-api/virtwrapper", + "//hack/qemu-metadata-api/dhcp", "//internal/cloud/metadata", "//internal/role", ], @@ -18,22 +18,17 @@ go_library( go_test( name = "server_test", - srcs = [ - "server_cgo_test.go", - "server_cross_test.go", - "server_test.go", - ], + srcs = ["server_test.go"], embed = [":server"], # keep pure = "on", # keep race = "off", deps = [ - "//hack/qemu-metadata-api/virtwrapper", + "//hack/qemu-metadata-api/dhcp", "//internal/cloud/metadata", "//internal/logger", "@com_github_stretchr_testify//assert", "@com_github_stretchr_testify//require", - "@org_libvirt_go_libvirt//:libvirt", ], ) diff --git a/hack/qemu-metadata-api/server/server.go b/hack/qemu-metadata-api/server/server.go index 4f0cad9e9..2b3817247 100644 --- a/hack/qemu-metadata-api/server/server.go +++ b/hack/qemu-metadata-api/server/server.go @@ -14,7 +14,7 @@ import ( "net/http" "strings" - "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/virtwrapper" + "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/dhcp" "github.com/edgelesssys/constellation/v2/internal/cloud/metadata" "github.com/edgelesssys/constellation/v2/internal/role" ) @@ -22,16 +22,16 @@ import ( // Server that provides QEMU metadata. type Server struct { log *slog.Logger - virt virConnect + dhcpLeaseGetter LeaseGetter network string initSecretHashVal []byte } // New creates a new Server. -func New(log *slog.Logger, network, initSecretHash string, conn virConnect) *Server { +func New(log *slog.Logger, network, initSecretHash string, getter LeaseGetter) *Server { return &Server{ log: log, - virt: conn, + dhcpLeaseGetter: getter, network: network, initSecretHashVal: []byte(initSecretHash), } @@ -139,15 +139,7 @@ func (s *Server) getEndpoint(w http.ResponseWriter, r *http.Request) { log := s.log.With(slog.String("peer", r.RemoteAddr)) log.Info("Serving GET request for /endpoint") - net, err := s.virt.LookupNetworkByName(s.network) - if err != nil { - log.With(slog.Any("error", err)).Error("Failed to lookup network") - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - defer net.Free() - - leases, err := net.GetDHCPLeases() + leases, err := s.dhcpLeaseGetter.GetDHCPLeases() if err != nil { log.With(slog.Any("error", err)).Error("Failed to get DHCP leases") http.Error(w, err.Error(), http.StatusInternalServerError) @@ -172,13 +164,7 @@ func (s *Server) getEndpoint(w http.ResponseWriter, r *http.Request) { // listAll returns a list of all active peers. func (s *Server) listAll() ([]metadata.InstanceMetadata, error) { - net, err := s.virt.LookupNetworkByName(s.network) - if err != nil { - return nil, err - } - defer net.Free() - - leases, err := net.GetDHCPLeases() + leases, err := s.dhcpLeaseGetter.GetDHCPLeases() if err != nil { return nil, err } @@ -201,6 +187,7 @@ func (s *Server) listAll() ([]metadata.InstanceMetadata, error) { return peers, nil } -type virConnect interface { - LookupNetworkByName(name string) (*virtwrapper.Network, error) +// LeaseGetter is an interface for getting DHCP leases. +type LeaseGetter interface { + GetDHCPLeases() ([]dhcp.NetworkDHCPLease, error) } diff --git a/hack/qemu-metadata-api/server/server_cgo_test.go b/hack/qemu-metadata-api/server/server_cgo_test.go deleted file mode 100644 index 59c569535..000000000 --- a/hack/qemu-metadata-api/server/server_cgo_test.go +++ /dev/null @@ -1,41 +0,0 @@ -//go:build cgo - -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package server - -import ( - "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/virtwrapper" - "libvirt.org/go/libvirt" -) - -type stubNetwork struct { - leases []libvirt.NetworkDHCPLease - getLeaseErr error -} - -func newStubNetwork(leases []virtwrapper.NetworkDHCPLease, getLeaseErr error) stubNetwork { - libvirtLeases := make([]libvirt.NetworkDHCPLease, len(leases)) - for i, l := range leases { - libvirtLeases[i] = libvirt.NetworkDHCPLease{ - IPaddr: l.IPaddr, - Hostname: l.Hostname, - } - } - return stubNetwork{ - leases: libvirtLeases, - getLeaseErr: getLeaseErr, - } -} - -func (n stubNetwork) GetDHCPLeases() ([]libvirt.NetworkDHCPLease, error) { - return n.leases, n.getLeaseErr -} - -func (n stubNetwork) Free() error { - return nil -} diff --git a/hack/qemu-metadata-api/server/server_cross_test.go b/hack/qemu-metadata-api/server/server_cross_test.go deleted file mode 100644 index 3f4488b26..000000000 --- a/hack/qemu-metadata-api/server/server_cross_test.go +++ /dev/null @@ -1,31 +0,0 @@ -//go:build !cgo - -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package server - -import "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/virtwrapper" - -type stubNetwork struct { - leases []virtwrapper.NetworkDHCPLease - getLeaseErr error -} - -func newStubNetwork(leases []virtwrapper.NetworkDHCPLease, getLeaseErr error) stubNetwork { - return stubNetwork{ - leases: leases, - getLeaseErr: getLeaseErr, - } -} - -func (n stubNetwork) GetDHCPLeases() ([]virtwrapper.NetworkDHCPLease, error) { - return n.leases, n.getLeaseErr -} - -func (n stubNetwork) Free() error { - return nil -} diff --git a/hack/qemu-metadata-api/server/server_test.go b/hack/qemu-metadata-api/server/server_test.go index 3b04d214d..363cb3ed2 100644 --- a/hack/qemu-metadata-api/server/server_test.go +++ b/hack/qemu-metadata-api/server/server_test.go @@ -9,13 +9,12 @@ package server import ( "context" "encoding/json" - "errors" "io" "net/http" "net/http/httptest" "testing" - "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/virtwrapper" + "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/dhcp" "github.com/edgelesssys/constellation/v2/internal/cloud/metadata" "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/stretchr/testify/assert" @@ -23,15 +22,13 @@ import ( ) func TestListAll(t *testing.T) { - someErr := errors.New("error") - testCases := map[string]struct { - wantErr bool - connect *stubConnect + wantErr bool + stubLeaseGetter *stubLeaseGetter }{ "success": { - connect: &stubConnect{ - network: newStubNetwork([]virtwrapper.NetworkDHCPLease{ + stubLeaseGetter: &stubLeaseGetter{ + leases: []dhcp.NetworkDHCPLease{ { IPaddr: "192.0.100.1", Hostname: "control-plane-0", @@ -44,20 +41,12 @@ func TestListAll(t *testing.T) { IPaddr: "192.0.200.1", Hostname: "worker-0", }, - }, nil), + }, }, }, - "LookupNetworkByName error": { - connect: &stubConnect{ - getNetworkErr: someErr, - }, - wantErr: true, - }, "GetDHCPLeases error": { - connect: &stubConnect{ - network: stubNetwork{ - getLeaseErr: someErr, - }, + stubLeaseGetter: &stubLeaseGetter{ + getErr: assert.AnError, }, wantErr: true, }, @@ -67,7 +56,7 @@ func TestListAll(t *testing.T) { t.Run(name, func(t *testing.T) { assert := assert.New(t) - server := New(logger.NewTest(t), "test", "initSecretHash", tc.connect) + server := New(logger.NewTest(t), "test", "initSecretHash", tc.stubLeaseGetter) res, err := server.listAll() @@ -76,58 +65,56 @@ func TestListAll(t *testing.T) { return } assert.NoError(err) - assert.Len(tc.connect.network.leases, len(res)) + assert.Len(tc.stubLeaseGetter.leases, len(res)) }) } } func TestListSelf(t *testing.T) { - someErr := errors.New("error") - testCases := map[string]struct { - remoteAddr string - connect *stubConnect - wantErr bool + remoteAddr string + stubLeaseGetter *stubLeaseGetter + wantErr bool }{ "success": { remoteAddr: "192.0.100.1:1234", - connect: &stubConnect{ - network: newStubNetwork([]virtwrapper.NetworkDHCPLease{ + stubLeaseGetter: &stubLeaseGetter{ + leases: []dhcp.NetworkDHCPLease{ { IPaddr: "192.0.100.1", Hostname: "control-plane-0", }, - }, nil), + }, }, }, "listAll error": { remoteAddr: "192.0.100.1:1234", - connect: &stubConnect{ - getNetworkErr: someErr, + stubLeaseGetter: &stubLeaseGetter{ + getErr: assert.AnError, }, wantErr: true, }, "remoteAddr error": { remoteAddr: "", - connect: &stubConnect{ - network: newStubNetwork([]virtwrapper.NetworkDHCPLease{ + stubLeaseGetter: &stubLeaseGetter{ + leases: []dhcp.NetworkDHCPLease{ { IPaddr: "192.0.100.1", Hostname: "control-plane-0", }, - }, nil), + }, }, wantErr: true, }, "peer not found": { remoteAddr: "192.0.200.1:1234", - connect: &stubConnect{ - network: newStubNetwork([]virtwrapper.NetworkDHCPLease{ + stubLeaseGetter: &stubLeaseGetter{ + leases: []dhcp.NetworkDHCPLease{ { IPaddr: "192.0.100.1", Hostname: "control-plane-0", }, - }, nil), + }, }, wantErr: true, }, @@ -138,7 +125,7 @@ func TestListSelf(t *testing.T) { assert := assert.New(t) require := require.New(t) - server := New(logger.NewTest(t), "test", "initSecretHash", tc.connect) + server := New(logger.NewTest(t), "test", "initSecretHash", tc.stubLeaseGetter) req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "http://192.0.0.1/self", nil) require.NoError(err) @@ -157,22 +144,22 @@ func TestListSelf(t *testing.T) { var metadata metadata.InstanceMetadata require.NoError(json.Unmarshal(metadataRaw, &metadata)) - assert.Equal(tc.connect.network.leases[0].Hostname, metadata.Name) - assert.Equal(tc.connect.network.leases[0].IPaddr, metadata.VPCIP) + assert.Equal(tc.stubLeaseGetter.leases[0].Hostname, metadata.Name) + assert.Equal(tc.stubLeaseGetter.leases[0].IPaddr, metadata.VPCIP) }) } } func TestListPeers(t *testing.T) { testCases := map[string]struct { - remoteAddr string - connect *stubConnect - wantErr bool + remoteAddr string + stubNetworkGetter *stubLeaseGetter + wantErr bool }{ "success": { remoteAddr: "192.0.100.1:1234", - connect: &stubConnect{ - network: newStubNetwork([]virtwrapper.NetworkDHCPLease{ + stubNetworkGetter: &stubLeaseGetter{ + leases: []dhcp.NetworkDHCPLease{ { IPaddr: "192.0.100.1", Hostname: "control-plane-0", @@ -181,13 +168,13 @@ func TestListPeers(t *testing.T) { IPaddr: "192.0.200.1", Hostname: "worker-0", }, - }, nil), + }, }, }, "listAll error": { remoteAddr: "192.0.100.1:1234", - connect: &stubConnect{ - getNetworkErr: errors.New("error"), + stubNetworkGetter: &stubLeaseGetter{ + getErr: assert.AnError, }, wantErr: true, }, @@ -198,7 +185,7 @@ func TestListPeers(t *testing.T) { assert := assert.New(t) require := require.New(t) - server := New(logger.NewTest(t), "test", "initSecretHash", tc.connect) + server := New(logger.NewTest(t), "test", "initSecretHash", tc.stubNetworkGetter) req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "http://192.0.0.1/peers", nil) require.NoError(err) @@ -217,22 +204,23 @@ func TestListPeers(t *testing.T) { var metadata []metadata.InstanceMetadata require.NoError(json.Unmarshal(metadataRaw, &metadata)) - assert.Len(metadata, len(tc.connect.network.leases)) + assert.Len(metadata, len(tc.stubNetworkGetter.leases)) }) } } func TestInitSecretHash(t *testing.T) { - defaultConnect := &stubConnect{ - network: newStubNetwork([]virtwrapper.NetworkDHCPLease{ + defaultConnect := &stubLeaseGetter{ + leases: []dhcp.NetworkDHCPLease{ { IPaddr: "192.0.100.1", Hostname: "control-plane-0", }, - }, nil), + }, } + testCases := map[string]struct { - connect *stubConnect + connect *stubLeaseGetter method string wantHash string wantErr bool @@ -272,11 +260,11 @@ func TestInitSecretHash(t *testing.T) { } } -type stubConnect struct { - network stubNetwork - getNetworkErr error +type stubLeaseGetter struct { + leases []dhcp.NetworkDHCPLease + getErr error } -func (c stubConnect) LookupNetworkByName(_ string) (*virtwrapper.Network, error) { - return &virtwrapper.Network{Net: c.network}, c.getNetworkErr +func (c stubLeaseGetter) GetDHCPLeases() ([]dhcp.NetworkDHCPLease, error) { + return c.leases, c.getErr } diff --git a/hack/qemu-metadata-api/virtwrapper/virtwrapper_cgo.go b/hack/qemu-metadata-api/virtwrapper/virtwrapper_cgo.go deleted file mode 100644 index cda0bed96..000000000 --- a/hack/qemu-metadata-api/virtwrapper/virtwrapper_cgo.go +++ /dev/null @@ -1,56 +0,0 @@ -//go:build cgo - -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package virtwrapper - -import "libvirt.org/go/libvirt" - -// Connect wraps a libvirt connection. -type Connect struct { - Conn *libvirt.Connect -} - -// LookupNetworkByName looks up a network by name. -func (c *Connect) LookupNetworkByName(name string) (*Network, error) { - net, err := c.Conn.LookupNetworkByName(name) - if err != nil { - return nil, err - } - return &Network{Net: net}, nil -} - -// Network wraps a libvirt network. -type Network struct { - Net virNetwork -} - -// GetDHCPLeases returns the underlying DHCP leases. -func (n *Network) GetDHCPLeases() ([]NetworkDHCPLease, error) { - leases, err := n.Net.GetDHCPLeases() - if err != nil { - return nil, err - } - ret := make([]NetworkDHCPLease, len(leases)) - for i, l := range leases { - ret[i] = NetworkDHCPLease{ - IPaddr: l.IPaddr, - Hostname: l.Hostname, - } - } - return ret, nil -} - -// Free the network resource. -func (n *Network) Free() { - _ = n.Net.Free() -} - -type virNetwork interface { - GetDHCPLeases() ([]libvirt.NetworkDHCPLease, error) - Free() error -} diff --git a/hack/qemu-metadata-api/virtwrapper/virtwrapper_cross.go b/hack/qemu-metadata-api/virtwrapper/virtwrapper_cross.go deleted file mode 100644 index 2faa95961..000000000 --- a/hack/qemu-metadata-api/virtwrapper/virtwrapper_cross.go +++ /dev/null @@ -1,40 +0,0 @@ -//go:build !cgo - -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package virtwrapper - -import "errors" - -// Connect wraps a libvirt connection. -type Connect struct{} - -// LookupNetworkByName looks up a network by name. -// This function errors if CGO is disabled. -func (c *Connect) LookupNetworkByName(_ string) (*Network, error) { - return nil, errors.New("using virtwrapper requires building with CGO") -} - -// Network wraps a libvirt network. -type Network struct { - Net Net -} - -// GetDHCPLeases returns the underlying DHCP leases. -// This function errors if CGO is disabled. -func (n *Network) GetDHCPLeases() ([]NetworkDHCPLease, error) { - return n.Net.GetDHCPLeases() -} - -// Free the network resource. -// This function does nothing if CGO is disabled. -func (n *Network) Free() {} - -// Net is a libvirt Network. -type Net interface { - GetDHCPLeases() ([]NetworkDHCPLease, error) -}