From b03d23a4fa2ee560f5a2ab1d26033eb947fe31ea Mon Sep 17 00:00:00 2001 From: Casey Callendrello Date: Fri, 8 Dec 2017 13:15:16 +0100 Subject: [PATCH] ipam/host-local: Accept ip ranges as a runtime argument This allows for the runtime to dynamically request IP ranges. Fixes: #95 --- plugins/ipam/host-local/README.md | 4 ++++ .../host-local/backend/allocator/config.go | 19 ++++++++++++++----- .../backend/allocator/config_test.go | 19 ++++++++++++++++++- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/plugins/ipam/host-local/README.md b/plugins/ipam/host-local/README.md index 7deb3555..ee81c864 100644 --- a/plugins/ipam/host-local/README.md +++ b/plugins/ipam/host-local/README.md @@ -120,6 +120,10 @@ The following [args conventions](https://github.com/containernetworking/cni/blob * `ips` (array of strings): A list of custom IPs to attempt to allocate +The following [Capability Args](https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md) are supported: + +* `ipRanges`: The exact same as the `ranges` array - a list of address pools + ### Custom IP allocation For every requested custom IP, the `host-local` allocator will request that IP if it falls within one of the `range` objects. Thus it is possible to specify diff --git a/plugins/ipam/host-local/backend/allocator/config.go b/plugins/ipam/host-local/backend/allocator/config.go index 845dad0b..004054fe 100644 --- a/plugins/ipam/host-local/backend/allocator/config.go +++ b/plugins/ipam/host-local/backend/allocator/config.go @@ -23,12 +23,16 @@ import ( types020 "github.com/containernetworking/cni/pkg/types/020" ) -// The top-level network config, just so we can get the IPAM block +// The top-level network config - IPAM plugins are passed the full configuration +// of the calling plugin, not just the IPAM section. type Net struct { - Name string `json:"name"` - CNIVersion string `json:"cniVersion"` - IPAM *IPAMConfig `json:"ipam"` - Args *struct { + Name string `json:"name"` + CNIVersion string `json:"cniVersion"` + IPAM *IPAMConfig `json:"ipam"` + RuntimeConfig struct { // The capability arg + IPRanges []RangeSet `json:"ipRanges,omitempty"` + } `json:"runtimeConfig,omitempty"` + Args *struct { A *IPAMArgs `json:"cni"` } `json:"args"` } @@ -106,6 +110,11 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) { } n.IPAM.Range = nil + // If a range is supplied as a runtime config, prepend it to the Ranges + if len(n.RuntimeConfig.IPRanges) > 0 { + n.IPAM.Ranges = append(n.RuntimeConfig.IPRanges, n.IPAM.Ranges...) + } + if len(n.IPAM.Ranges) == 0 { return nil, "", fmt.Errorf("no IP ranges specified") } diff --git a/plugins/ipam/host-local/backend/allocator/config_test.go b/plugins/ipam/host-local/backend/allocator/config_test.go index 4631123b..cbae3d15 100644 --- a/plugins/ipam/host-local/backend/allocator/config_test.go +++ b/plugins/ipam/host-local/backend/allocator/config_test.go @@ -132,12 +132,18 @@ var _ = Describe("IPAM config", func() { })) }) - It("Should parse a mixed config", func() { + It("Should parse a mixed config with runtime args", func() { input := `{ "cniVersion": "0.3.1", "name": "mynet", "type": "ipvlan", "master": "foo0", + "runtimeConfig": { + "irrelevant": "a", + "ipRanges": [ + [{ "subnet": "12.1.3.0/24" }] + ] + }, "ipam": { "type": "host-local", "subnet": "10.1.2.0/24", @@ -162,6 +168,17 @@ var _ = Describe("IPAM config", func() { Name: "mynet", Type: "host-local", Ranges: []RangeSet{ + { // The RuntimeConfig should always be first + { + RangeStart: net.IP{12, 1, 3, 1}, + RangeEnd: net.IP{12, 1, 3, 254}, + Gateway: net.IP{12, 1, 3, 1}, + Subnet: types.IPNet{ + IP: net.IP{12, 1, 3, 0}, + Mask: net.CIDRMask(24, 32), + }, + }, + }, { { RangeStart: net.IP{10, 1, 2, 9},