Skip to content

Commit

Permalink
move impl. to k8sd api
Browse files Browse the repository at this point in the history
  • Loading branch information
eaudetcobello committed Sep 27, 2024
1 parent b70219f commit cfc3f25
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 60 deletions.
60 changes: 0 additions & 60 deletions src/k8s/cmd/k8s/k8s_bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"bytes"
"fmt"
"io"
"net"
"os"
"slices"
"strings"
Expand Down Expand Up @@ -128,13 +127,6 @@ func newBootstrapCmd(env cmdutil.ExecutionEnvironment) *cobra.Command {
}
}

if bootstrapConfig.PodCIDR != nil && bootstrapConfig.ServiceCIDR != nil {
if err = validateCIDROverlapAndSize(*bootstrapConfig.PodCIDR, *bootstrapConfig.ServiceCIDR); err != nil {
cmd.PrintErrf("Error: Failed to validate the CIDR configuration.\n\nThe error was: %v\n", err)
env.Exit(1)
return
}
}

cmd.PrintErrln("Bootstrapping the cluster. This may take a few seconds, please wait.")

Expand Down Expand Up @@ -278,55 +270,3 @@ func askQuestion(stdin io.Reader, stdout io.Writer, stderr io.Writer, question s
return s
}
}

// validateCIDROverlapAndSize checks for overlap and size constraints between pod and service CIDRs.
// It parses the provided podCIDR and serviceCIDR strings, checks for IPv4 and IPv6 overlaps, and ensures
// that the service IPv6 CIDR does not have a prefix length of 64 or more.
func validateCIDROverlapAndSize(podCIDR string, serviceCIDR string) error {
// Parse the CIDRs
podIPv4CIDR, podIPv6CIDR, err := utils.ParseCIDRs(podCIDR)
if err != nil {
return err
}

svcIPv4CIDR, svcIPv6CIDR, err := utils.ParseCIDRs(serviceCIDR)
if err != nil {
return err
}

// Check for IPv4 overlap
if podIPv4CIDR != "" && svcIPv4CIDR != "" {
if overlap, err := utils.CIDRsOverlap(podIPv4CIDR, svcIPv4CIDR); err != nil {
return err
} else if overlap {
return fmt.Errorf("pod CIDR %q and service CIDR %q overlap", podCIDR, serviceCIDR)
}
}

// Check for IPv6 overlap
if podIPv6CIDR != "" && svcIPv6CIDR != "" {
if overlap, err := utils.CIDRsOverlap(podIPv6CIDR, svcIPv6CIDR); err != nil {
return err
} else if overlap {
return fmt.Errorf("pod CIDR %q and service CIDR %q overlap", podCIDR, serviceCIDR)
}
}

// Check CIDR size
// Ref: https://documentation.ubuntu.com/canonical-kubernetes/latest/snap/howto/networking/dualstack/#cidr-size-limitations
if svcIPv6CIDR != "" {
_, ipv6Net, err := net.ParseCIDR(svcIPv6CIDR)
if err != nil {
// Should not happen, as we already parsed the CIDR
return fmt.Errorf("invalid service CIDR %q: %w", svcIPv6CIDR, err)
}

prefixLength, _ := ipv6Net.Mask.Size()

if prefixLength >= 64 {
return fmt.Errorf("service CIDR %q cannot have a prefix length of 64 or more", svcIPv6CIDR)
}
}

return nil
}
58 changes: 58 additions & 0 deletions src/k8s/pkg/k8sd/app/hooks_bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,12 @@ func (a *App) onBootstrapControlPlane(ctx context.Context, s state.State, bootst
return fmt.Errorf("failed to get IP address(es) from ServiceCIDR %q: %w", cfg.Network.GetServiceCIDR(), err)
}

if cfg.Network.GetPodCIDR() != "" && cfg.Network.GetServiceCIDR() != "" {
if err = validateCIDROverlapAndSize(cfg.Network.GetPodCIDR(), cfg.Network.GetServiceCIDR()); err != nil {
return fmt.Errorf("failed to validate the CIDR configuration: %w", err)
}
}

// NOTE: Set the notBefore certificate time to the current time.
notBefore := time.Now()

Expand Down Expand Up @@ -494,3 +500,55 @@ func (a *App) onBootstrapControlPlane(ctx context.Context, s state.State, bootst
a.NotifyUpdateNodeConfigController()
return nil
}

// validateCIDROverlapAndSize checks for overlap and size constraints between pod and service CIDRs.
// It parses the provided podCIDR and serviceCIDR strings, checks for IPv4 and IPv6 overlaps, and ensures
// that the service IPv6 CIDR does not have a prefix length of 64 or more.
func validateCIDROverlapAndSize(podCIDR string, serviceCIDR string) error {
// Parse the CIDRs
podIPv4CIDR, podIPv6CIDR, err := utils.ParseCIDRs(podCIDR)
if err != nil {
return err
}

svcIPv4CIDR, svcIPv6CIDR, err := utils.ParseCIDRs(serviceCIDR)
if err != nil {
return err
}

// Check for IPv4 overlap
if podIPv4CIDR != "" && svcIPv4CIDR != "" {
if overlap, err := utils.CIDRsOverlap(podIPv4CIDR, svcIPv4CIDR); err != nil {
return err
} else if overlap {
return fmt.Errorf("pod CIDR %q and service CIDR %q overlap", podCIDR, serviceCIDR)
}
}

// Check for IPv6 overlap
if podIPv6CIDR != "" && svcIPv6CIDR != "" {
if overlap, err := utils.CIDRsOverlap(podIPv6CIDR, svcIPv6CIDR); err != nil {
return err
} else if overlap {
return fmt.Errorf("pod CIDR %q and service CIDR %q overlap", podCIDR, serviceCIDR)
}
}

// Check CIDR size
// Ref: https://documentation.ubuntu.com/canonical-kubernetes/latest/snap/howto/networking/dualstack/#cidr-size-limitations
if svcIPv6CIDR != "" {
_, ipv6Net, err := net.ParseCIDR(svcIPv6CIDR)
if err != nil {
// Should not happen, as we already parsed the CIDR
return fmt.Errorf("invalid service CIDR %q: %w", svcIPv6CIDR, err)
}

prefixLength, _ := ipv6Net.Mask.Size()

if prefixLength >= 64 {
return fmt.Errorf("service CIDR %q cannot have a prefix length of 64 or more", svcIPv6CIDR)
}
}

return nil
}

0 comments on commit cfc3f25

Please sign in to comment.