host-local: support custom IPs allocation through runtime configuration

Signed-off-by: Bruce Ma <brucema19901024@gmail.com>
This commit is contained in:
Bruce Ma 2021-03-10 17:41:30 +08:00
parent 7da1c84919
commit 028fc2f219
2 changed files with 39 additions and 3 deletions

View File

@ -21,6 +21,8 @@ import (
"github.com/containernetworking/cni/pkg/types" "github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/version" "github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ip"
) )
// The top-level network config - IPAM plugins are passed the full configuration // The top-level network config - IPAM plugins are passed the full configuration
@ -29,8 +31,10 @@ type Net struct {
Name string `json:"name"` Name string `json:"name"`
CNIVersion string `json:"cniVersion"` CNIVersion string `json:"cniVersion"`
IPAM *IPAMConfig `json:"ipam"` IPAM *IPAMConfig `json:"ipam"`
RuntimeConfig struct { // The capability arg RuntimeConfig struct {
// The capability arg
IPRanges []RangeSet `json:"ipRanges,omitempty"` IPRanges []RangeSet `json:"ipRanges,omitempty"`
IPs []*ip.IP `json:"ips,omitempty"`
} `json:"runtimeConfig,omitempty"` } `json:"runtimeConfig,omitempty"`
Args *struct { Args *struct {
A *IPAMArgs `json:"cni"` A *IPAMArgs `json:"cni"`
@ -48,7 +52,7 @@ type IPAMConfig struct {
DataDir string `json:"dataDir"` DataDir string `json:"dataDir"`
ResolvConf string `json:"resolvConf"` ResolvConf string `json:"resolvConf"`
Ranges []RangeSet `json:"ranges"` Ranges []RangeSet `json:"ranges"`
IPArgs []net.IP `json:"-"` // Requested IPs from CNI_ARGS and args IPArgs []net.IP `json:"-"` // Requested IPs from CNI_ARGS, args and capabilities
} }
type IPAMEnvArgs struct { type IPAMEnvArgs struct {
@ -80,7 +84,8 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
return nil, "", fmt.Errorf("IPAM config missing 'ipam' key") return nil, "", fmt.Errorf("IPAM config missing 'ipam' key")
} }
// Parse custom IP from both env args *and* the top-level args config // Parse custom IP from env args, the top-level args config and capabilities
// in runtime configuration
if envArgs != "" { if envArgs != "" {
e := IPAMEnvArgs{} e := IPAMEnvArgs{}
err := types.LoadArgs(envArgs, &e) err := types.LoadArgs(envArgs, &e)
@ -97,6 +102,12 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
n.IPAM.IPArgs = append(n.IPAM.IPArgs, n.Args.A.IPs...) n.IPAM.IPArgs = append(n.IPAM.IPArgs, n.Args.A.IPs...)
} }
if len(n.RuntimeConfig.IPs) > 0 {
for _, i := range n.RuntimeConfig.IPs {
n.IPAM.IPArgs = append(n.IPAM.IPArgs, i.ToIP())
}
}
for idx := range n.IPAM.IPArgs { for idx := range n.IPAM.IPArgs {
if err := canonicalizeIP(&n.IPAM.IPArgs[idx]); err != nil { if err := canonicalizeIP(&n.IPAM.IPArgs[idx]); err != nil {
return nil, "", fmt.Errorf("cannot understand ip: %v", err) return nil, "", fmt.Errorf("cannot understand ip: %v", err)

View File

@ -379,4 +379,29 @@ var _ = Describe("IPAM config", func() {
_, _, err := LoadIPAMConfig([]byte(input), "") _, _, err := LoadIPAMConfig([]byte(input), "")
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
}) })
It("Should parse custom IPs from runtime configuration", func() {
input := `{
"cniVersion": "0.3.1",
"name": "mynet",
"type": "ipvlan",
"master": "foo0",
"runtimeConfig": {
"ips": ["192.168.0.1", "192.168.0.5/24", "2001:db8::1/64"]
},
"ipam": {
"type": "host-local",
"subnet": "10.1.2.0/24"
}
}`
conf, version, err := LoadIPAMConfig([]byte(input), "")
Expect(err).NotTo(HaveOccurred())
Expect(version).Should(Equal("0.3.1"))
Expect(conf.IPArgs).To(Equal([]net.IP{
net.IPv4(192, 168, 0, 1).To4(),
net.IPv4(192, 168, 0, 5).To4(),
net.ParseIP("2001:db8::1"),
}))
})
}) })