Skip to content

Commit

Permalink
fix: allow FQDNs as controlPlaneEndpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
pborn-ionos committed Mar 26, 2024
1 parent c5fb0e4 commit 6cbd78a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
15 changes: 13 additions & 2 deletions internal/webhook/proxmoxcluster_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package webhook
import (
"context"
"fmt"
"net"
"net/netip"
"strings"

Expand Down Expand Up @@ -98,19 +99,24 @@ func validateIPs(cluster *infrav1.ProxmoxCluster) error {

endpointHostIP := ep.Host

if isValidFQDN(endpointHostIP) {
ipAddr, _ := net.ResolveIPAddr("ip", endpointHostIP)
endpointHostIP = ipAddr.String()
}

addr, err := netip.ParseAddr(endpointHostIP)
if err != nil {
return apierrors.NewInvalid(
gk,
name,
field.ErrorList{
field.Invalid(
field.NewPath("spec", "controlplaneEndpoint"), endpointHostIP, "provided endpoint address is not a valid IP"),
field.NewPath("spec", "controlplaneEndpoint"), endpointHostIP, "provided endpoint address is not a valid IP or FQDN"),
})
}
// If the passed control-plane endppoint is an IPv6 address, wrap it in [], so it can properly pass ParseAddrPort validation
if addr.Is6() {
endpointHostIP = fmt.Sprintf("[%s]", ep.Host)
endpointHostIP = fmt.Sprintf("[%s]", endpointHostIP)
}

ipAddr, err := netip.ParseAddrPort(fmt.Sprintf("%s:%d", endpointHostIP, ep.Port))
Expand Down Expand Up @@ -213,3 +219,8 @@ func buildSetFromAddresses(addresses []string) (*netipx.IPSet, error) {
func hasNoIPPoolConfig(cluster *infrav1.ProxmoxCluster) bool {
return cluster.Spec.IPv4Config == nil && cluster.Spec.IPv6Config == nil
}

func isValidFQDN(fqdn string) bool {
_, err := net.ResolveIPAddr("ip", fqdn)
return err == nil
}
12 changes: 12 additions & 0 deletions internal/webhook/proxmoxcluster_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,24 @@ var _ = Describe("Controller Test", func() {
g.Expect(k8sClient.Create(testEnv.GetContext(), &cluster)).To(MatchError(ContainSubstring("at least one ip config must be set")))
})

It("should disallow invalid/non-existing endpoint FQDN", func() {
cluster := invalidProxmoxCluster("test-cluster")
cluster.Spec.ControlPlaneEndpoint.Host = "this.does.not.exist.ionos.com"
g.Expect(k8sClient.Create(testEnv.GetContext(), &cluster)).To(MatchError(ContainSubstring("provided endpoint address is not a valid IP or FQDN")))
})

It("should disallow invalid endpoint IP", func() {
cluster := invalidProxmoxCluster("test-cluster")
cluster.Spec.ControlPlaneEndpoint.Host = "invalid"
g.Expect(k8sClient.Create(testEnv.GetContext(), &cluster)).To(MatchError(ContainSubstring("provided endpoint address is not a valid IP")))
})

It("should allow valid endpoint from FQDN", func() {
cluster := validProxmoxCluster("succeed-test-cluster-with-fqdn")
cluster.Spec.ControlPlaneEndpoint.Host = "ionos.com"
g.Expect(k8sClient.Create(testEnv.GetContext(), &cluster)).To(Succeed())
})

It("should disallow invalid endpoint IP + port combination", func() {
cluster := invalidProxmoxCluster("test-cluster")
cluster.Spec.ControlPlaneEndpoint.Host = "127.0.0.1"
Expand Down

0 comments on commit 6cbd78a

Please sign in to comment.