From c0ff178f199e1acf88ff074b066ba6d903157b79 Mon Sep 17 00:00:00 2001 From: kkumar Date: Tue, 24 Dec 2024 12:52:47 +0530 Subject: [PATCH 1/2] Implement new configuration strategy for `Bluefield` plugin --- README.md | 8 ++++++- example/bluefield_config.yaml | 1 + internal/api/bulefield_config.go | 8 +++++++ plugins/bluefield/plugin.go | 38 ++++++++++++++++++++++++++++---- 4 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 example/bluefield_config.yaml create mode 100644 internal/api/bulefield_config.go diff --git a/README.md b/README.md index 304d660..27c2ae9 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,13 @@ Leases a single IP address to a single client as a [non temporary IPv6 address]( Meant to be used in 1:1 client-server connection scenarios, for example a smartnic (Bluefield) leasing a single address to the host. ### Configuration -The IP address to lease shall be passed as a string. +The IP address to lease shall be passed as a string in `bulefield_config.yaml` goes as follows: + +```yaml +bulefieldIP: 2001:db8::1 +``` + + ### Notes - supports IPv6 addresses only - IPv6 relays are supported diff --git a/example/bluefield_config.yaml b/example/bluefield_config.yaml new file mode 100644 index 0000000..3118ffd --- /dev/null +++ b/example/bluefield_config.yaml @@ -0,0 +1 @@ +bulefieldIP: 2001:db8::1 \ No newline at end of file diff --git a/internal/api/bulefield_config.go b/internal/api/bulefield_config.go new file mode 100644 index 0000000..f1cefd4 --- /dev/null +++ b/internal/api/bulefield_config.go @@ -0,0 +1,8 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors +// SPDX-License-Identifier: MIT + +package api + +type BluefieldIPConfig struct { + BulefieldIP string `yaml:"bulefieldIP"` +} diff --git a/plugins/bluefield/plugin.go b/plugins/bluefield/plugin.go index ba2105f..9ce9db1 100644 --- a/plugins/bluefield/plugin.go +++ b/plugins/bluefield/plugin.go @@ -6,6 +6,7 @@ package bluefield import ( "fmt" "net" + "os" "time" "github.com/coredhcp/coredhcp/handler" @@ -13,6 +14,8 @@ import ( "github.com/coredhcp/coredhcp/plugins" "github.com/insomniacslk/dhcp/dhcpv6" "github.com/insomniacslk/dhcp/iana" + "github.com/ironcore-dev/fedhcp/internal/api" + "gopkg.in/yaml.v2" ) var log = logger.GetLogger("plugins/bluefield") @@ -23,12 +26,39 @@ var Plugin = plugins.Plugin{ } var ipaddr net.IP -// setupPlugin initializes the plugin with given arguments. +// args[0] = path to config file +func parseArgs(args ...string) (string, error) { + if len(args) != 1 { + return "", fmt.Errorf("exactly one argument must be passed to the bluefield plugin, got %d", len(args)) + } + return args[0], nil +} + +func loadConfig(args ...string) (*api.BluefieldIPConfig, error) { + path, err := parseArgs(args...) + if err != nil { + return nil, fmt.Errorf("invalid configuration: %v", err) + } + + log.Debugf("Reading bluefield 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.BluefieldIPConfig{} + if err = yaml.Unmarshal(configData, config); err != nil { + return nil, fmt.Errorf("failed to parse config file: %v", err) + } + return config, nil +} + +// setupPlugin initializes the plugin with given bluefield config. func setupPlugin(args ...string) (handler.Handler6, error) { - if len(args) < 1 { - return nil, fmt.Errorf("plugin bluefield requires at least one argument (static IPv6 address)") + bluefieldIPConfig, err := loadConfig(args...) + if err != nil { + return nil, err } - ipaddr = net.ParseIP(args[0]) + ipaddr = net.ParseIP(bluefieldIPConfig.BulefieldIP) if ipaddr == nil { return nil, fmt.Errorf("invalid IPv6 address: %s", args[0]) } From d0acc6e24f30229ca3ff74fe79c2b4f4e3bb0add Mon Sep 17 00:00:00 2001 From: kkumar Date: Wed, 25 Dec 2024 14:53:23 +0530 Subject: [PATCH 2/2] Sanity --- example/config.yaml | 2 +- internal/api/{bulefield_config.go => bluefield_config.go} | 2 +- plugins/bluefield/plugin.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename internal/api/{bulefield_config.go => bluefield_config.go} (85%) diff --git a/example/config.yaml b/example/config.yaml index 53e7fc5..20b1ae7 100644 --- a/example/config.yaml +++ b/example/config.yaml @@ -6,7 +6,7 @@ server6: # mandatory for RFC compliance - server_id: LL 00:de:ad:be:ef:00 # always provide the same IP address, no matter who's asking: - # - bluefield: 2001:db8::1 + # - bluefield: bluefield_config.yaml # implement HTTPBoot - httpboot: http://[2001:db8::1]/image.uki # add leased IPs to ironcore's IPAM diff --git a/internal/api/bulefield_config.go b/internal/api/bluefield_config.go similarity index 85% rename from internal/api/bulefield_config.go rename to internal/api/bluefield_config.go index f1cefd4..6aeacb6 100644 --- a/internal/api/bulefield_config.go +++ b/internal/api/bluefield_config.go @@ -3,6 +3,6 @@ package api -type BluefieldIPConfig struct { +type BluefieldConfig struct { BulefieldIP string `yaml:"bulefieldIP"` } diff --git a/plugins/bluefield/plugin.go b/plugins/bluefield/plugin.go index 9ce9db1..2db2942 100644 --- a/plugins/bluefield/plugin.go +++ b/plugins/bluefield/plugin.go @@ -34,7 +34,7 @@ func parseArgs(args ...string) (string, error) { return args[0], nil } -func loadConfig(args ...string) (*api.BluefieldIPConfig, error) { +func loadConfig(args ...string) (*api.BluefieldConfig, error) { path, err := parseArgs(args...) if err != nil { return nil, fmt.Errorf("invalid configuration: %v", err) @@ -45,7 +45,7 @@ func loadConfig(args ...string) (*api.BluefieldIPConfig, error) { if err != nil { return nil, fmt.Errorf("failed to read config file: %v", err) } - config := &api.BluefieldIPConfig{} + config := &api.BluefieldConfig{} if err = yaml.Unmarshal(configData, config); err != nil { return nil, fmt.Errorf("failed to parse config file: %v", err) }