Skip to content

Commit

Permalink
add CIDR assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
k8s-bot committed Jun 5, 2024
1 parent 341845b commit 0897424
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 24 deletions.
6 changes: 5 additions & 1 deletion src/k8s/pkg/k8sd/features/calico/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,9 @@ var (
// tigeraOperatorVersion is the version to use for the tigera-operator image.
tigeraOperatorVersion = "v1.34.0"

// TODO: define calicoctl image and version https://artifacthub.io/packages/helm/projectcalico/tigera-operator?modal=values
// calicoCtlImage represents the image to fetch for calicoctl.
// TODO: use ROCKs instead of upstream
calicoCtlImage = "docker.io/calico/ctl"
// calicoCtlTag represents the tag to use for the calicoctl image.
calicoCtlTag = "v3.28.0"
)
43 changes: 41 additions & 2 deletions src/k8s/pkg/k8sd/features/calico/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/canonical/k8s/pkg/client/helm"
"github.com/canonical/k8s/pkg/k8sd/types"
"github.com/canonical/k8s/pkg/snap"
"github.com/canonical/k8s/pkg/utils"
)

// ApplyNetwork will deploy Calico when cfg.Enabled is true.
Expand All @@ -22,14 +23,52 @@ func ApplyNetwork(ctx context.Context, snap snap.Snap, cfg types.Network, _ type
return nil
}

podIpPools := []map[string]any{}
ipv4PodCIDR, ipv6PodCIDR, err := utils.ParseCIDRs(cfg.GetPodCIDR())
if err != nil {
return fmt.Errorf("invalid pod cidr: %v", err)
}
if ipv4PodCIDR != "" {
podIpPools = append(podIpPools, map[string]any{
"name": "ipv4-ippool",
"cidr": ipv4PodCIDR,
})
}
if ipv6PodCIDR != "" {
podIpPools = append(podIpPools, map[string]any{
"name": "ipv6-ippool",
"cidr": ipv6PodCIDR,
})
}

serviceCIDRs := []string{}
ipv4ServiceCIDR, ipv6ServiceCIDR, err := utils.ParseCIDRs(cfg.GetPodCIDR())
if err != nil {
return fmt.Errorf("invalid service cidr: %v", err)
}
if ipv4ServiceCIDR != "" {
serviceCIDRs = append(serviceCIDRs, ipv4ServiceCIDR)
}
if ipv6ServiceCIDR != "" {
serviceCIDRs = append(serviceCIDRs, ipv6ServiceCIDR)
}

values := map[string]any{
"tigeraOperator": map[string]any{
"registry": tigeraOperatorRegistry,
"image": tigeraOperatorImage,
"version": tigeraOperatorVersion,
},
// TODO: configure calicoctl image and version
// TODO: configure kubernetesServiceEndpoint (port)
"calicoctl": map[string]any{
"image": calicoCtlImage,
"tag": calicoCtlTag,
},
"installation": map[string]any{
"calicoNetwork": map[string]any{
"ipPools": podIpPools,
},
},
"serviceCIDRs": serviceCIDRs,
}

if _, err := m.Apply(ctx, chartCalico, helm.StatePresent, values); err != nil {
Expand Down
24 changes: 3 additions & 21 deletions src/k8s/pkg/k8sd/features/cilium/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"context"
"fmt"
"log"
"net"
"strings"

"github.com/canonical/k8s/pkg/client/helm"
"github.com/canonical/k8s/pkg/k8sd/types"
Expand All @@ -29,25 +27,9 @@ func ApplyNetwork(ctx context.Context, snap snap.Snap, cfg types.Network, _ type
return nil
}

clusterCIDRs := strings.Split(cfg.GetPodCIDR(), ",")
if v := len(clusterCIDRs); v != 1 && v != 2 {
return fmt.Errorf("invalid kube-proxy --cluster-cidr value: %v", clusterCIDRs)
}

var (
ipv4CIDR string
ipv6CIDR string
)
for _, cidr := range clusterCIDRs {
_, parsed, err := net.ParseCIDR(cidr)
switch {
case err != nil:
return fmt.Errorf("failed to parse cidr: %w", err)
case parsed.IP.To4() != nil:
ipv4CIDR = cidr
default:
ipv6CIDR = cidr
}
ipv4CIDR, ipv6CIDR, err := utils.ParseCIDRs(cfg.GetPodCIDR())
if err != nil {
return fmt.Errorf("invalid kube-proxy --cluster-cidr value: %v", err)
}

values := map[string]any{
Expand Down
25 changes: 25 additions & 0 deletions src/k8s/pkg/utils/cidr.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,28 @@ func GetKubernetesServiceIPsFromServiceCIDRs(serviceCIDR string) ([]net.IP, erro
}
return firstIPs, nil
}

// ParseCIDRs parses the given CIDR string and returns the respective IPv4 and IPv6 CIDRs.
func ParseCIDRs(CIDRstring string) (string, string, error) {
clusterCIDRs := strings.Split(CIDRstring, ",")
if v := len(clusterCIDRs); v != 1 && v != 2 {
return "", "", fmt.Errorf("invalid CIDR list: %v", clusterCIDRs)
}

var (
ipv4CIDR string
ipv6CIDR string
)
for _, cidr := range clusterCIDRs {
_, parsed, err := net.ParseCIDR(cidr)
switch {
case err != nil:
return "", "", fmt.Errorf("failed to parse cidr: %w", err)
case parsed.IP.To4() != nil:
ipv4CIDR = cidr
default:
ipv6CIDR = cidr
}
}
return ipv4CIDR, ipv6CIDR, nil
}
52 changes: 52 additions & 0 deletions src/k8s/pkg/utils/cidr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,55 @@ func TestGetKubernetesServiceIPsFromServiceCIDRs(t *testing.T) {
}
})
}

func TestParseCIDRs(t *testing.T) {
RegisterTestingT(t)

testCases := []struct {
input string
expectedIPv4 string
expectedIPv6 string
expectedErr bool
}{
{
input: "192.168.1.0/24",
expectedIPv4: "192.168.1.0/24",
expectedIPv6: "",
},
{
input: "2001:db8::/32",
expectedIPv4: "",
expectedIPv6: "2001:db8::/32",
},
{
input: "192.168.1.0/24,2001:db8::/32",
expectedIPv4: "192.168.1.0/24",
expectedIPv6: "2001:db8::/32",
},
{
input: "192.168.1.0/24,invalidCIDR",
expectedIPv4: "",
expectedIPv6: "",
expectedErr: true,
},
{
input: "192.168.1.0/24,2001:db8::/32,10.0.0.0/8",
expectedIPv4: "",
expectedIPv6: "",
expectedErr: true,
},
}

for _, tc := range testCases {
t.Run(tc.input, func(t *testing.T) {
ipv4CIDR, ipv6CIDR, err := utils.ParseCIDRs(tc.input)
if tc.expectedErr {
Expect(err).To(HaveOccurred())
} else {
Expect(err).To(BeNil())
Expect(ipv4CIDR).To(Equal(tc.expectedIPv4))
Expect(ipv6CIDR).To(Equal(tc.expectedIPv6))
}
})
}
}

0 comments on commit 0897424

Please sign in to comment.