Skip to content

Commit

Permalink
Add support for pools
Browse files Browse the repository at this point in the history
Add pod annotations to enable them:
```
spec:
  template:
    metadata:
      annotations:
        cni.calico/ipv4pools: [<ip-pool-1>, <ip-pool-2>]
        cni.calico/ipv6pools: [<ip-pool-1>, <ip-pool-2>]
```

Signed-off-by: Doug Davis <[email protected]>
  • Loading branch information
Doug Davis committed Dec 7, 2016
1 parent a076fd1 commit 316a9d8
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 24 deletions.
10 changes: 6 additions & 4 deletions calico_cni_ipam_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,13 @@ var _ = Describe("Calico IPAM Tests", func() {
"etcd_endpoints": "http://%s:2379",
"ipam": {
"type": "%s",
"assign_ipv4": "true",
"ipv4_pools": [ "192.168.0.0/16" ]
"assign_ipv4": "true",
"ipv4_pools": [ "192.168.0.0/16" ]
}
}`, os.Getenv("ETCD_IP"), plugin)
_, _, _, _, _, _, err := CreateContainer(netconf)
_, _, _, _, addr, _, err := CreateContainer(netconf)
Expect(err).ShouldNot(HaveOccurred())
Expect(addr[0].IP.String()).Should(HavePrefix("192.168."))
})
})

Expand All @@ -116,11 +117,12 @@ var _ = Describe("Calico IPAM Tests", func() {
"ipv4_pools": [ "192.169.1.0/24", "192.168.0.0/16" ]
}
}`, os.Getenv("ETCD_IP"), plugin)
_, _, session, _, _, _, err := CreateContainer(netconf)
_, _, session, _, addr, _, err := CreateContainer(netconf)
if err != nil {
fmt.Printf("Session Err: %v\n", string(session.Err.Contents()))
}
Expect(err).ShouldNot(HaveOccurred())
Expect(addr[0].IP.String()).Should(Or(HavePrefix("192.168."), HavePrefix("192.169.1")))
})
})

Expand Down
73 changes: 54 additions & 19 deletions k8s/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,54 @@ func CmdAddK8s(args *skel.CmdArgs, conf utils.NetConf, hostname string, calicoCl
logger.WithField("stdin", args.StdinData).Debug("Updated stdin data")
}

// Only used by K8s so if its null then we're not doing k8s stuff
var labels map[string]string
var annot map[string]string

// Only attempt to fetch the labels and annotations from Kubernetes
// if the policy type has been set to "k8s". This allows users to
// run the plugin under Kubernetes without needing it to access the
// Kubernetes API
if conf.Policy.PolicyType == "k8s" {
var err error

labels, annot, err = getK8sLabelsAnnotations(client, k8sArgs)
if err != nil {
// Cleanup IP allocation and return the error.
utils.ReleaseIPAllocation(logger, conf.IPAM.Type, args.StdinData)
return nil, err
}
logger.WithField("labels", labels).Debug("Fetched K8s labels")
logger.WithField("annotations", annot).Debug("Fetched K8s annotations")

v4pools := annot["cni.calico/ipv4pools"]
v6pools := annot["cni.calico/ipv6pools"]

if len(v4pools) != 0 || len(v6pools) != 0 {
var stdinData map[string]interface{}
if err := json.Unmarshal(args.StdinData, &stdinData); err != nil {
utils.ReleaseIPAllocation(logger, conf.IPAM.Type, args.StdinData)
return nil, err
}
stdinData["ipam"].(map[string]interface{})["ipv4pools"] = v4pools
stdinData["ipam"].(map[string]interface{})["ipv6pools"] = v6pools

if len(v4pools) > 0 {
fmt.Fprintf(os.Stderr, "Calico CNI setting ipv4pools to %q", v4pools)
}
if len(v6pools) > 0 {
fmt.Fprintf(os.Stderr, "Calico CNI setting ipv6pools to %q", v6pools)
}
newData, err := json.Marshal(stdinData)
if err != nil {
utils.ReleaseIPAllocation(logger, conf.IPAM.Type, args.StdinData)
return nil, err
}
args.StdinData = newData
logger.WithField("stdin", args.StdinData).Debug("Updated stdin data")
}
}

// Run the IPAM plugin
logger.Debugf("Calling IPAM plugin %s", conf.IPAM.Type)
result, err = ipam.ExecAdd(conf.IPAM.Type, args.StdinData)
Expand All @@ -117,7 +165,7 @@ func CmdAddK8s(args *skel.CmdArgs, conf utils.NetConf, hostname string, calicoCl
endpoint.Metadata.Node = hostname
endpoint.Metadata.Orchestrator = orchestrator
endpoint.Metadata.Workload = workload
endpoint.Metadata.Labels = make(map[string]string)
endpoint.Metadata.Labels = labels // Only when policy type == k8s

// Set the profileID according to whether Kubernetes policy is required.
// If it's not, then just use the network name (which is the normal behavior)
Expand All @@ -135,19 +183,6 @@ func CmdAddK8s(args *skel.CmdArgs, conf utils.NetConf, hostname string, calicoCl
return nil, err
}
logger.WithField("endpoint", endpoint).Info("Populated endpoint")

// Only attempt to fetch the labels from Kubernetes if the policy type has been set to "k8s"
// This allows users to run the plugin under Kubernetes without needing it to access the Kubernetes API
if conf.Policy.PolicyType == "k8s" {
labels, err := getK8sLabels(client, k8sArgs)
if err != nil {
// Cleanup IP allocation and return the error.
utils.ReleaseIPAllocation(logger, conf.IPAM.Type, args.StdinData)
return nil, err
}
logger.WithField("labels", labels).Info("Fetched K8s labels")
endpoint.Metadata.Labels = labels
}
}
fmt.Fprintf(os.Stderr, "Calico CNI using IPs: %s\n", endpoint.Spec.IPNetworks)

Expand Down Expand Up @@ -232,20 +267,20 @@ func newK8sClient(conf utils.NetConf, logger *log.Entry) (*kubernetes.Clientset,
return kubernetes.NewForConfig(config)
}

func getK8sLabels(client *kubernetes.Clientset, k8sargs utils.K8sArgs) (map[string]string, error) {
pods, err := client.Pods(string(k8sargs.K8S_POD_NAMESPACE)).Get(fmt.Sprintf("%s", k8sargs.K8S_POD_NAME))
func getK8sLabelsAnnotations(client *kubernetes.Clientset, k8sargs utils.K8sArgs) (map[string]string, map[string]string, error) {
pod, err := client.Pods(string(k8sargs.K8S_POD_NAMESPACE)).Get(fmt.Sprintf("%s", k8sargs.K8S_POD_NAME))
if err != nil {
return nil, err
return nil, nil, err
}

labels := pods.Labels
labels := pod.Labels
if labels == nil {
labels = make(map[string]string)
}

labels["calico/k8s_ns"] = fmt.Sprintf("%s", k8sargs.K8S_POD_NAMESPACE)

return labels, nil
return labels, pod.Annotations, nil
}

func getPodCidr(client *kubernetes.Clientset, conf utils.NetConf, hostname string) (string, error) {
Expand Down
2 changes: 1 addition & 1 deletion utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ func ParsePools(pools []string, isv4 bool) ([]cnet.IPNet, error) {
return nil, fmt.Errorf("%q isn't a IPv4 address", ip)
}
if !isv4 && ip.To4() != nil {
return nil, fmt.Errorf("%q isn't a IPv16 address", ip)
return nil, fmt.Errorf("%q isn't a IPv6 address", ip)
}
result = append(result, cnet.IPNet{*cidr})
}
Expand Down

0 comments on commit 316a9d8

Please sign in to comment.