Skip to content

Commit

Permalink
Implement new configuration strategy for HTTPBOOT plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
kkumar authored and damyan committed Jan 8, 2025
1 parent fe7caa8 commit 888221c
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 24 deletions.
1 change: 1 addition & 0 deletions example/httpboot_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bootServer: http://[2001:db8::1]/image.uki
8 changes: 8 additions & 0 deletions internal/api/httpboot_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors
// SPDX-License-Identifier: MIT

package api

type HttpBootConfig struct {
BootServer string `yaml:"bootServer"`
}
1 change: 1 addition & 0 deletions plugins/httpboot/custom_httpboot_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bootServer: "bootservice:http://[::1]:8888/httpboot"
1 change: 1 addition & 0 deletions plugins/httpboot/httpboot_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bootServer: "https://[2001:db8::1]/boot.uki"
1 change: 1 addition & 0 deletions plugins/httpboot/malformed_httpboot_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bootServer: ftp://www.example.com/boot.uki
39 changes: 34 additions & 5 deletions plugins/httpboot/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ import (
"io"
"net/http"
"net/url"
"os"
"strings"

"github.com/coredhcp/coredhcp/handler"
"github.com/coredhcp/coredhcp/logger"
"github.com/coredhcp/coredhcp/plugins"
"github.com/insomniacslk/dhcp/dhcpv4"
"github.com/insomniacslk/dhcp/dhcpv6"
"github.com/ironcore-dev/fedhcp/internal/api"
"gopkg.in/yaml.v2"
)

var bootFile4 string
Expand All @@ -33,11 +36,19 @@ var Plugin = plugins.Plugin{

const httpClient = "HTTPClient"

func parseArgs(args ...string) (*url.URL, bool, error) {
func parseArgs(args ...string) (string, error) {
if len(args) != 1 {
return nil, false, fmt.Errorf("exactly one argument must be passed to the httpboot plugin, got %d", len(args))
return "", fmt.Errorf("exactly one argument must be passed to the httpboot plugin, got %d", len(args))
}
arg := args[0]
return args[0], nil
}

func parseConfig(args ...string) (*url.URL, bool, error) {
httpbootConfig, err := loadConfig(args...)
if err != nil {
return nil, false, fmt.Errorf("erorr loading httpboot plugin config: %v", err)
}
arg := httpbootConfig.BootServer
useBootService := strings.HasPrefix(arg, "bootservice:")
if useBootService {
arg = strings.TrimPrefix(arg, "bootservice:")
Expand All @@ -52,8 +63,26 @@ func parseArgs(args ...string) (*url.URL, bool, error) {
return parsedURL, useBootService, nil
}

func loadConfig(args ...string) (*api.HttpBootConfig, error) {
path, err := parseArgs(args...)
if err != nil {
return nil, fmt.Errorf("invalid configuration: %v", err)
}

log.Debugf("Reading httpboot config file %s", path)
configData, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to read config file: %v", err)
}
config := &api.HttpBootConfig{}
if err = yaml.Unmarshal(configData, config); err != nil {
return nil, fmt.Errorf("failed to parse config file: %v", err)
}
return config, nil
}

func setup6(args ...string) (handler.Handler6, error) {
u, ubs, err := parseArgs(args...)
u, ubs, err := parseConfig(args...)
if err != nil {
return nil, fmt.Errorf("invalid configuration: %v", err)
}
Expand All @@ -64,7 +93,7 @@ func setup6(args ...string) (handler.Handler6, error) {
}

func setup4(args ...string) (handler.Handler4, error) {
u, ubs, err := parseArgs(args...)
u, ubs, err := parseConfig(args...)
if err != nil {
return nil, fmt.Errorf("invalid configuration: %v", err)
}
Expand Down
41 changes: 22 additions & 19 deletions plugins/httpboot/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,20 @@ const (
)

var (
expectedHTTPClient = []byte("HTTPClient")
expectedHTTPClient = []byte("HTTPClient")
httpbootFilePath = []string{"httpboot_config.yaml"}
customHttpbootFilePath = []string{"custom_httpboot_config.yaml"}
)

func Init4(bootURL string) {
_, err := setup4(bootURL)
func Init4(bootFileUrl ...string) {
_, err := setup4(bootFileUrl...)
if err != nil {
log.Fatal(err)
}
}

func Init6(bootURL string) {
_, err := setup6(bootURL)
func Init6(bootFileUrl ...string) {
_, err := setup6(bootFileUrl...)
if err != nil {
log.Fatal(err)
}
Expand All @@ -51,12 +53,12 @@ func Init6(bootURL string) {
/* parametrization */

func TestWrongNumberArgs(t *testing.T) {
_, _, err := parseArgs("foo", "bar")
_, err := parseArgs("foo", "bar")
if err == nil {
t.Fatal("no error occurred when providing wrong number of args (2), but it should have")
}

_, _, err = parseArgs()
_, err = parseArgs()
if err == nil {
t.Fatal("no error occurred when providing wrong number of args (0), but it should have")
}
Expand All @@ -69,12 +71,13 @@ func TestWrongArgs(t *testing.T) {
"bootfail:https://www.example.com/boot.uki",
"bootservice:tftp://www.example.com/boot.uki"}

malformedHttpbootFilePath := []string{"malformed_httpboot_config.yaml"}
for _, wrongURL := range malformedBootURL {
_, err := setup4(wrongURL)
_, err := setup4(malformedHttpbootFilePath...)
if err == nil {
t.Fatalf("no error occurred when parsing wrong boot param %s, but it should have", wrongURL)
}
_, err = setup6(wrongURL)
_, err = setup6(malformedHttpbootFilePath...)
if err == nil {
t.Fatalf("no error occurred when parsing wrong boot param %s, but it should have", wrongURL)
}
Expand All @@ -83,7 +86,7 @@ func TestWrongArgs(t *testing.T) {

/* IPv6 */
func TestGenericHTTPBootRequested6(t *testing.T) {
Init6(expectedGenericBootURL)
Init6(httpbootFilePath...)

req, err := dhcpv6.NewMessage()
if err != nil {
Expand Down Expand Up @@ -141,7 +144,7 @@ func TestGenericHTTPBootRequested6(t *testing.T) {
}

func TestMalformedHTTPBootRequested6(t *testing.T) {
Init6(expectedGenericBootURL)
Init6(httpbootFilePath...)

req, err := dhcpv6.NewMessage()
if err != nil {
Expand Down Expand Up @@ -210,7 +213,7 @@ func TestMalformedHTTPBootRequested6(t *testing.T) {
}

func TestHTTPBootNotRequested6(t *testing.T) {
Init6(expectedGenericBootURL)
Init6(httpbootFilePath...)

req, err := dhcpv6.NewMessage()
if err != nil {
Expand Down Expand Up @@ -251,7 +254,7 @@ func TestHTTPBootNotRequested6(t *testing.T) {
}

func TestHTTPBootNotRelayedMsg6(t *testing.T) {
Init6(expectedGenericBootURL)
Init6(httpbootFilePath...)

req, err := dhcpv6.NewMessage()
if err != nil {
Expand Down Expand Up @@ -287,7 +290,7 @@ func TestHTTPBootNotRelayedMsg6(t *testing.T) {

/* IPv4 */
func TestGenericHTTPBootRequested4(t *testing.T) {
Init4(expectedGenericBootURL)
Init4(httpbootFilePath...)

req, err := dhcpv4.NewDiscovery(net.HardwareAddr{
0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
Expand Down Expand Up @@ -325,7 +328,7 @@ func TestGenericHTTPBootRequested4(t *testing.T) {
}

func TestMalformedHTTPBootRequested4(t *testing.T) {
Init4(expectedGenericBootURL)
Init4(httpbootFilePath...)

req, err := dhcpv4.NewDiscovery(net.HardwareAddr{
0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
Expand Down Expand Up @@ -393,7 +396,7 @@ func TestMalformedHTTPBootRequested4(t *testing.T) {
}

func TestHTTPBootNotRequested4(t *testing.T) {
Init4(expectedGenericBootURL)
Init4(httpbootFilePath...)

req, err := dhcpv4.NewDiscovery(net.HardwareAddr{
0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
Expand Down Expand Up @@ -434,7 +437,7 @@ func TestCustomHTTPBootRequestedKnownIP(t *testing.T) {
go startBootServiceMock()
time.Sleep(time.Second * 1)

Init6(fmt.Sprintf(bootServiceEndpoint, bootServicePort))
Init6(customHttpbootFilePath...)
req, err := dhcpv6.NewMessage()
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -570,7 +573,7 @@ func TestCustomHTTPBootRequestedUnknownClient(t *testing.T) {
}

func createHTTPBootRequest(t *testing.T) (error, *dhcpv6.RelayMessage) {
Init6(fmt.Sprintf(bootServiceEndpoint, bootServicePort))
Init6(customHttpbootFilePath...)
req, err := dhcpv6.NewMessage()
if err != nil {
t.Fatal(err)
Expand All @@ -596,7 +599,7 @@ func createHTTPBootRequest(t *testing.T) (error, *dhcpv6.RelayMessage) {
}

func TestNoRelayCustomHTTPBootRequested(t *testing.T) {
Init6(fmt.Sprintf(bootServiceEndpoint, bootServicePort))
Init6(customHttpbootFilePath...)

req, err := dhcpv6.NewMessage()
if err != nil {
Expand Down

0 comments on commit 888221c

Please sign in to comment.