diff --git a/pkg/apis/k0s/v1beta1/network.go b/pkg/apis/k0s/v1beta1/network.go index f75d3b4204d4..eb5f2e97c839 100644 --- a/pkg/apis/k0s/v1beta1/network.go +++ b/pkg/apis/k0s/v1beta1/network.go @@ -18,8 +18,10 @@ package v1beta1 import ( "encoding/json" + "errors" "fmt" "net" + "slices" "k8s.io/apimachinery/pkg/util/validation/field" utilnet "k8s.io/utils/net" @@ -129,9 +131,14 @@ func (n *Network) DNSAddress() (string, error) { return "", fmt.Errorf("failed to parse service CIDR %q: %w", n.ServiceCIDR, err) } - address := ipnet.IP.To4() - if IsIPv6String(ipnet.IP.String()) { - address = ipnet.IP.To16() + address := slices.Clone(ipnet.IP.To4()) + if address == nil { + // The network address is not an IPv4 address. This can only happen if + // k0s is running in IPv6-only mode, which is currently not a supported + // configuration. In dual-stack mode, the IPv6 CIDR is stored in + // n.DualStack.IPv6ServiceCIDR. Error out until it is clear how to + // properly calculate the DNS address for a v6 network. + return "", fmt.Errorf("%w: DNS address calculation for non-v4 CIDR: %s", errors.ErrUnsupported, n.ServiceCIDR) } prefixlen, _ := ipnet.Mask.Size() @@ -142,7 +149,7 @@ func (n *Network) DNSAddress() (string, error) { } if !ipnet.Contains(address) { - return "", fmt.Errorf("failed to calculate a valid DNS address: %q", address.String()) + return "", fmt.Errorf("failed to calculate DNS address: CIDR too narrow: %s", n.ServiceCIDR) } return address.String(), nil diff --git a/pkg/apis/k0s/v1beta1/network_test.go b/pkg/apis/k0s/v1beta1/network_test.go index e0217ac21570..50f8f0d5bca8 100644 --- a/pkg/apis/k0s/v1beta1/network_test.go +++ b/pkg/apis/k0s/v1beta1/network_test.go @@ -17,6 +17,7 @@ limitations under the License. package v1beta1 import ( + "errors" "testing" "github.com/stretchr/testify/suite" @@ -40,6 +41,19 @@ func (s *NetworkSuite) TestAddresses() { s.Require().NoError(err) s.Equal("10.96.0.250", dns) }) + s.Run("DNS_service_cidr_too_narrow", func() { + n := Network{ServiceCIDR: "192.168.178.0/31"} + dns, err := n.DNSAddress() + s.Zero(dns) + s.ErrorContains(err, "failed to calculate DNS address: CIDR too narrow: 192.168.178.0/31") + }) + s.Run("DNS_rejects_v6_service_cidr", func() { + n := Network{ServiceCIDR: "fd00:abcd:1234::/64"} + dns, err := n.DNSAddress() + s.Zero(dns) + s.ErrorIs(err, errors.ErrUnsupported) + s.ErrorContains(err, "unsupported operation: DNS address calculation for non-v4 CIDR: fd00:abcd:1234::/64") + }) s.T().Run("Internal_api_address_default", func(t *testing.T) { n := DefaultNetwork() api, err := n.InternalAPIAddresses()