Support ips capability in static and mac capability in tuning
This change introduces new capability flag to change MAC address and to specify IP addresses by tuning and static.
This commit is contained in:
parent
2b6808807f
commit
660685a8af
@ -52,3 +52,7 @@ The following [CNI_ARGS](https://github.com/containernetworking/cni/blob/master/
|
|||||||
* `GATEWAY`: request a specific gateway address
|
* `GATEWAY`: request a specific gateway address
|
||||||
|
|
||||||
(example: CNI_ARGS="IP=10.10.0.1/24;GATEWAY=10.10.0.254")
|
(example: CNI_ARGS="IP=10.10.0.1/24;GATEWAY=10.10.0.254")
|
||||||
|
|
||||||
|
The plugin also support following [capability argument](https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md).
|
||||||
|
|
||||||
|
* `ips`: Pass IP addresses for CNI interface
|
||||||
|
@ -34,6 +34,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 {
|
||||||
|
IPs []string `json:"ips,omitempty"`
|
||||||
|
} `json:"runtimeConfig,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type IPAMConfig struct {
|
type IPAMConfig struct {
|
||||||
@ -134,6 +138,14 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
|
|||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(n.RuntimeConfig.IPs) != 0 {
|
||||||
|
// args IP overwrites IP, so clear IPAM Config
|
||||||
|
n.IPAM.Addresses = make([]Address, 0, len(n.RuntimeConfig.IPs))
|
||||||
|
for _, addr := range n.RuntimeConfig.IPs {
|
||||||
|
n.IPAM.Addresses = append(n.IPAM.Addresses, Address{AddressStr: addr})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if n.IPAM == nil {
|
if n.IPAM == nil {
|
||||||
return nil, "", fmt.Errorf("IPAM config missing 'ipam' key")
|
return nil, "", fmt.Errorf("IPAM config missing 'ipam' key")
|
||||||
}
|
}
|
||||||
|
@ -265,6 +265,75 @@ var _ = Describe("static Operations", func() {
|
|||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("allocates and releases multiple addresses with ADD/DEL, from RuntimeConfig", func() {
|
||||||
|
const ifname string = "eth0"
|
||||||
|
const nspath string = "/some/where"
|
||||||
|
|
||||||
|
conf := `{
|
||||||
|
"cniVersion": "0.3.1",
|
||||||
|
"name": "mynet",
|
||||||
|
"type": "ipvlan",
|
||||||
|
"master": "foo0",
|
||||||
|
"capabilities": {"ips": true},
|
||||||
|
"ipam": {
|
||||||
|
"type": "static",
|
||||||
|
"routes": [
|
||||||
|
{ "dst": "0.0.0.0/0", "gw": "10.10.0.254" },
|
||||||
|
{ "dst": "3ffe:ffff:0:01ff::1/64",
|
||||||
|
"gw": "3ffe:ffff:0::1" } ],
|
||||||
|
"dns": {
|
||||||
|
"nameservers" : ["8.8.8.8"],
|
||||||
|
"domain": "example.com",
|
||||||
|
"search": [ "example.com" ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"RuntimeConfig": {
|
||||||
|
"ips" : ["10.10.0.1/24", "3ffe:ffff:0:01ff::1/64"]
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
args := &skel.CmdArgs{
|
||||||
|
ContainerID: "dummy",
|
||||||
|
Netns: nspath,
|
||||||
|
IfName: ifname,
|
||||||
|
StdinData: []byte(conf),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate the IP
|
||||||
|
r, raw, err := testutils.CmdAddWithArgs(args, func() error {
|
||||||
|
return cmdAdd(args)
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(strings.Index(string(raw), "\"version\":")).Should(BeNumerically(">", 0))
|
||||||
|
|
||||||
|
result, err := current.GetResult(r)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Gomega is cranky about slices with different caps
|
||||||
|
Expect(*result.IPs[0]).To(Equal(
|
||||||
|
current.IPConfig{
|
||||||
|
Version: "4",
|
||||||
|
Address: mustCIDR("10.10.0.1/24"),
|
||||||
|
}))
|
||||||
|
Expect(*result.IPs[1]).To(Equal(
|
||||||
|
current.IPConfig{
|
||||||
|
Version: "6",
|
||||||
|
Address: mustCIDR("3ffe:ffff:0:01ff::1/64"),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
Expect(len(result.IPs)).To(Equal(2))
|
||||||
|
Expect(result.Routes).To(Equal([]*types.Route{
|
||||||
|
{Dst: mustCIDR("0.0.0.0/0"), GW: net.ParseIP("10.10.0.254")},
|
||||||
|
{Dst: mustCIDR("3ffe:ffff:0:01ff::1/64"), GW: net.ParseIP("3ffe:ffff:0::1")},
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Release the IP
|
||||||
|
err = testutils.CmdDelWithArgs(args, func() error {
|
||||||
|
return cmdDel(args)
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
func mustCIDR(s string) net.IPNet {
|
func mustCIDR(s string) net.IPNet {
|
||||||
|
@ -61,3 +61,6 @@ The following [CNI_ARGS](https://github.com/containernetworking/cni/blob/master/
|
|||||||
|
|
||||||
Note: You may add `IgnoreUnknown=true` to allow loose CNI argument verification (see CNI's issue[#560](https://github.com/containernetworking/cni/issues/560)).
|
Note: You may add `IgnoreUnknown=true` to allow loose CNI argument verification (see CNI's issue[#560](https://github.com/containernetworking/cni/issues/560)).
|
||||||
|
|
||||||
|
The plugin also support following [capability argument](https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md).
|
||||||
|
|
||||||
|
* `mac`: Pass MAC addresses for CNI interface
|
||||||
|
@ -43,9 +43,14 @@ type TuningConf struct {
|
|||||||
Mac string `json:"mac,omitempty"`
|
Mac string `json:"mac,omitempty"`
|
||||||
Promisc bool `json:"promisc,omitempty"`
|
Promisc bool `json:"promisc,omitempty"`
|
||||||
Mtu int `json:"mtu,omitempty"`
|
Mtu int `json:"mtu,omitempty"`
|
||||||
|
|
||||||
|
RuntimeConfig struct {
|
||||||
|
Mac string `json:"mac,omitempty"`
|
||||||
|
} `json:"runtimeConfig,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MACEnvArgs struct {
|
// MacEnvArgs represents CNI_ARG
|
||||||
|
type MacEnvArgs struct {
|
||||||
types.CommonArgs
|
types.CommonArgs
|
||||||
MAC types.UnmarshallableString `json:"mac,omitempty"`
|
MAC types.UnmarshallableString `json:"mac,omitempty"`
|
||||||
}
|
}
|
||||||
@ -56,9 +61,9 @@ func parseConf(data []byte, envArgs string) (*TuningConf, error) {
|
|||||||
return nil, fmt.Errorf("failed to load netconf: %v", err)
|
return nil, fmt.Errorf("failed to load netconf: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse custom MAC from both env args
|
// Parse custom Mac from both env args
|
||||||
if envArgs != "" {
|
if envArgs != "" {
|
||||||
e := MACEnvArgs{}
|
e := MacEnvArgs{}
|
||||||
err := types.LoadArgs(envArgs, &e)
|
err := types.LoadArgs(envArgs, &e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -69,6 +74,11 @@ func parseConf(data []byte, envArgs string) (*TuningConf, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse custom Mac from RuntimeConfig
|
||||||
|
if conf.RuntimeConfig.Mac != "" {
|
||||||
|
conf.Mac = conf.RuntimeConfig.Mac
|
||||||
|
}
|
||||||
|
|
||||||
return &conf, nil
|
return &conf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +240,7 @@ func cmdCheck(args *skel.CmdArgs) error {
|
|||||||
|
|
||||||
err = ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
|
err = ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
|
||||||
// Check each configured value vs what's currently in the container
|
// Check each configured value vs what's currently in the container
|
||||||
for key, conf_value := range tuningConf.SysCtl {
|
for key, confValue := range tuningConf.SysCtl {
|
||||||
fileName := filepath.Join("/proc/sys", strings.Replace(key, ".", "/", -1))
|
fileName := filepath.Join("/proc/sys", strings.Replace(key, ".", "/", -1))
|
||||||
fileName = filepath.Clean(fileName)
|
fileName = filepath.Clean(fileName)
|
||||||
|
|
||||||
@ -238,9 +248,9 @@ func cmdCheck(args *skel.CmdArgs) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cur_value := strings.TrimSuffix(string(contents), "\n")
|
curValue := strings.TrimSuffix(string(contents), "\n")
|
||||||
if conf_value != cur_value {
|
if confValue != curValue {
|
||||||
return fmt.Errorf("Error: Tuning configured value of %s is %s, current value is %s", fileName, conf_value, cur_value)
|
return fmt.Errorf("Error: Tuning configured value of %s is %s, current value is %s", fileName, confValue, curValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,6 +379,7 @@ var _ = Describe("tuning plugin", func() {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
hw, err := net.ParseMAC("c2:11:22:33:44:66")
|
hw, err := net.ParseMAC("c2:11:22:33:44:66")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
fmt.Printf("%v, %v\n", link.Attrs().HardwareAddr, hw)
|
||||||
Expect(link.Attrs().HardwareAddr).To(Equal(hw))
|
Expect(link.Attrs().HardwareAddr).To(Equal(hw))
|
||||||
|
|
||||||
err = testutils.CmdDel(originalNS.Path(),
|
err = testutils.CmdDel(originalNS.Path(),
|
||||||
@ -681,4 +682,67 @@ var _ = Describe("tuning plugin", func() {
|
|||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("configures and deconfigures mac address (from RuntimeConfig) with ADD/DEL", func() {
|
||||||
|
conf := []byte(`{
|
||||||
|
"name": "test",
|
||||||
|
"type": "iplink",
|
||||||
|
"cniVersion": "0.3.1",
|
||||||
|
"capabilities": {"mac": true},
|
||||||
|
"RuntimeConfig": {
|
||||||
|
"mac": "c2:11:22:33:44:55"
|
||||||
|
},
|
||||||
|
"prevResult": {
|
||||||
|
"interfaces": [
|
||||||
|
{"name": "dummy0", "sandbox":"netns"}
|
||||||
|
],
|
||||||
|
"ips": [
|
||||||
|
{
|
||||||
|
"version": "4",
|
||||||
|
"address": "10.0.0.2/24",
|
||||||
|
"gateway": "10.0.0.1",
|
||||||
|
"interface": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
|
||||||
|
args := &skel.CmdArgs{
|
||||||
|
ContainerID: "dummy",
|
||||||
|
Netns: originalNS.Path(),
|
||||||
|
IfName: IFNAME,
|
||||||
|
StdinData: conf,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := originalNS.Do(func(ns.NetNS) error {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
|
||||||
|
r, _, err := testutils.CmdAddWithArgs(args, func() error {
|
||||||
|
return cmdAdd(args)
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
result, err := current.GetResult(r)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
Expect(len(result.Interfaces)).To(Equal(1))
|
||||||
|
Expect(result.Interfaces[0].Name).To(Equal(IFNAME))
|
||||||
|
Expect(len(result.IPs)).To(Equal(1))
|
||||||
|
Expect(result.IPs[0].Address.String()).To(Equal("10.0.0.2/24"))
|
||||||
|
|
||||||
|
link, err := netlink.LinkByName(IFNAME)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
hw, err := net.ParseMAC("c2:11:22:33:44:55")
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(link.Attrs().HardwareAddr).To(Equal(hw))
|
||||||
|
|
||||||
|
err = testutils.CmdDel(originalNS.Path(),
|
||||||
|
args.ContainerID, "", func() error { return cmdDel(args) })
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user