Skip to content

Commit

Permalink
Fix the VIP URL generation for IPv6
Browse files Browse the repository at this point in the history
When configuring Kubernetes with multiple nodes, EIB requires an IP address
to be used as a target for load balancing purposes. However, it assumes this
address to be in an IPv4 format, resulting in a broken mangling when IPv6 is
used instead.

Correct this problem by letting netip package do the handling of IP addresses,
hiding version specific issues. This also allows for easier and additional
input validation with minimal effort.

Signed-off-by: Marco Chiappero <[email protected]>
  • Loading branch information
mchiappero committed Aug 8, 2024
1 parent 789d69d commit dc10dc3
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 3 deletions.
2 changes: 2 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

## Bug Fixes

* [#512](https://github.com/suse-edge/edge-image-builder/issues/512) - EIB assumes apiVIP to be IPv4 only when creating the target URL

---

# v1.1.0-rc1
Expand Down
4 changes: 2 additions & 2 deletions docs/building-images.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,8 @@ kubernetes:
* `version` - Required; Specifies the version of a particular K3s or RKE2 release (e.g.`v1.28.8+k3s1` or `v1.28.8+rke2r1`)
* `network` - Required for multi-node clusters, optional for single-node clusters; Defines the network configuration
for bootstrapping a cluster.
* `apiVIP` - Required for multi-node clusters, optional for single-node clusters; Specifies the IP address which
will serve as the cluster LoadBalancer, backed by MetalLB.
* `apiVIP` - Required for multi-node clusters, optional for single-node clusters; Specifies the IPv4 or IPv6 address
which will serve as the cluster LoadBalancer, backed by MetalLB.
* `apiHost` - Optional; Specifies the domain address for accessing the cluster.
* `nodes` - Required for multi-node clusters; Defines a list of all nodes that form the cluster.
* `hostname` - Required; Indicates the fully qualified domain name (FQDN) to identify the particular node on which
Expand Down
8 changes: 7 additions & 1 deletion pkg/kubernetes/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"io/fs"
"net/netip"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -202,7 +203,12 @@ func setClusterAPIAddress(config map[string]any, apiAddress string, port uint16)
return
}

config[serverKey] = fmt.Sprintf("https://%s:%d", apiAddress, port)
ip, err := netip.ParseAddr(apiAddress)
if err != nil {
panic("Invalid Kubernetes VIP address")
}

config[serverKey] = fmt.Sprintf("https://%s", netip.AddrPortFrom(ip, port).String())
}

func setSELinux(config map[string]any) {
Expand Down
3 changes: 3 additions & 0 deletions pkg/kubernetes/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ func TestSetClusterAPIAddress(t *testing.T) {

setClusterAPIAddress(config, "192.168.122.50", 9345)
assert.Equal(t, "https://192.168.122.50:9345", config["server"])

setClusterAPIAddress(config, "FC00:1:2:3::50", 9345)
assert.Equal(t, "https://[fc00:1:2:3::50]:9345", config["server"])
}

func TestAppendClusterTLSSAN(t *testing.T) {
Expand Down

0 comments on commit dc10dc3

Please sign in to comment.