Skip to content

Commit

Permalink
Implement new configuration strategy for OOB plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
damyan committed Nov 25, 2024
1 parent 8918f4b commit 72fd7a1
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 15 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,16 @@ prefixDelegation:
- can be used standalone or (in combination with the `ipam` plugin) in kubernetes

## OOB
The OOB plugin leases an IP object to an out-of-band client, based on a subnet detection. The plugin is an equivalent of the metal+ipam kombination, meant to be used in IronCore's out-of-band network.
The OOB plugin leases an IP address to an out-of-band client, based on a subnet detection. For each a corresponding IPAM IP object is created. Thus, the plugin is an equivalent of the onmetal+ipam combination, though it is meant to be used in IronCore's out-of-band network.

An IP object with a random IP address from the subnet's vacant list is created in IPAM, the IP address is then leased back to the client. Currently no cleanup-on-release is performed, so clients with stable identifiers are guaranteed to become stable IP addresses.
An IP object with a random IP address from the subnet's vacant list is created in IPAM, the IP address is then leased back to the client. Currently, no cleanup-on-release is performed, so clients with stable identifiers are guaranteed to become stable IP addresses.
### Configuration
As for in-band, a kubernetes namespace shall be passed as a parameter. Further, a subnet label list in the form `value:key` shall be passed, it is used for subnet detection.
Providing those in `oob_config.yaml` goes as follows:
```yaml
namespace: oob-ns
subnetLabel: subnet=dhcp
```
### Notes
- supports both IPv4 and IPv6
- IPv6 relays are supported, IPv4 are not
Expand Down
2 changes: 2 additions & 0 deletions example/oob_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
namespace: oob-ns
subnetLabel: subnet=dhcp
9 changes: 9 additions & 0 deletions internal/api/oob_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors
// SPDX-License-Identifier: MIT

package api

type OOBConfig struct {
Namespace string `yaml:"namespace"`
SubnetLabel string `yaml:"subnetLabel"`
}
52 changes: 39 additions & 13 deletions plugins/oob/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ package oob
import (
"fmt"
"net"
"os"
"strings"
"time"

"github.com/ironcore-dev/fedhcp/internal/api"
"gopkg.in/yaml.v3"

ipamv1alpha1 "github.com/ironcore-dev/ipam/api/ipam/v1alpha1"

"github.com/coredhcp/coredhcp/handler"
Expand Down Expand Up @@ -35,24 +40,45 @@ const (
UNKNOWN_IP = "0.0.0.0"
)

func parseArgs(args ...string) (string, string, error) {
if len(args) < 2 {
return "", "", fmt.Errorf("at least two arguments must be passed to ipam plugin, a namespace and a "+
"OOB subnet label, got %d", len(args))
// 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 metal plugin, got %d", len(args))
}
return args[0], nil
}

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

namespace := args[0]
oobLabel := args[1]
return namespace, oobLabel, nil
log.Debugf("Reading ipam 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.OOBConfig{}
if err = yaml.Unmarshal(configData, config); err != nil {
return nil, fmt.Errorf("failed to parse config file: %v", err)
}

// TODO remove after https://github.com/ironcore-dev/FeDHCP/issues/221 is implemented
if !strings.Contains(config.SubnetLabel, "=") {
return nil, fmt.Errorf("invalid subnet label: %s, should be 'key=value'", config.SubnetLabel)
}
return config, nil
}

func setup6(args ...string) (handler.Handler6, error) {
namespace, oobLabel, err := parseArgs(args...)
oobConfig, err := loadConfig(args...)
if err != nil {
return nil, err
return nil, fmt.Errorf("invalid configuration: %v", err)
}

k8sClient, err = NewK8sClient(namespace, oobLabel)
k8sClient, err = NewK8sClient(oobConfig.Namespace, oobConfig.SubnetLabel)
if err != nil {
return nil, fmt.Errorf("failed to create k8s client: %w", err)
}
Expand Down Expand Up @@ -117,12 +143,12 @@ func handler6(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
}

func setup4(args ...string) (handler.Handler4, error) {
namespace, oobLabel, err := parseArgs(args...)
oobConfig, err := loadConfig(args...)
if err != nil {
return nil, err
return nil, fmt.Errorf("invalid configuration: %v", err)
}

k8sClient, err = NewK8sClient(namespace, oobLabel)
k8sClient, err = NewK8sClient(oobConfig.Namespace, oobConfig.SubnetLabel)
if err != nil {
return nil, fmt.Errorf("failed to create k8s client: %w", err)
}
Expand Down

0 comments on commit 72fd7a1

Please sign in to comment.