Skip to content

Commit

Permalink
Add support for passing poolNames and poolType as CNI Args
Browse files Browse the repository at this point in the history
Signed-off-by: Yury Kulazhenkov <ykulazhenkov@nvidia.com>
  • Loading branch information
ykulazhenkov committed Jun 13, 2024
1 parent 7b4934c commit fb98825
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 9 deletions.
42 changes: 33 additions & 9 deletions pkg/cni/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ type NetConf struct {

// IPAMArgs holds arguments from stdin args["cni"]
type IPAMArgs struct {
IPs []string `json:"ips"`
IPs []string `json:"ips"`
PoolNames []string `json:"poolNames"`
PoolType string `json:"poolType"`
}

// IPAMEnvArgs holds arguments from CNI_ARGS env variable
Expand Down Expand Up @@ -171,15 +173,13 @@ func (cl *confLoader) LoadConf(args *skel.CmdArgs) (*NetConf, error) {
return nil, err
}

n.IPAM.Pools, err = parsePoolName(n.IPAM.PoolName)
n.IPAM.Pools, err = getPools(n)
if err != nil {
return nil, err
}

n.IPAM.PoolType = strings.ToLower(n.IPAM.PoolType)
if n.IPAM.PoolType != common.PoolTypeIPPool && n.IPAM.PoolType != common.PoolTypeCIDRPool {
return nil, fmt.Errorf("unsupported poolType %s, supported values: %s, %s",
n.IPAM.PoolType, common.PoolTypeIPPool, common.PoolTypeCIDRPool)
n.IPAM.PoolType, err = getPoolType(n)
if err != nil {
return nil, err
}
return n, nil
}
Expand Down Expand Up @@ -219,8 +219,15 @@ func parseIP(s string) net.IP {
return net.ParseIP(s)
}

func parsePoolName(poolName string) ([]string, error) {
pools := strings.Split(poolName, ",")
// returns list of pools that should be used by the plugin.
// STDIN field "args[cni][poolNames]" has the highest priority
func getPools(n *NetConf) ([]string, error) {
var pools []string
if n.Args != nil && len(n.Args.ArgsCNI.PoolNames) > 0 {
pools = n.Args.ArgsCNI.PoolNames
} else {
pools = strings.Split(n.IPAM.PoolName, ",")
}
if len(pools) > 2 {
return nil, fmt.Errorf("pool field can't contain more then two entries")
}
Expand All @@ -232,6 +239,23 @@ func parsePoolName(poolName string) ([]string, error) {
return pools, nil
}

// returns poolType that should be used by the plugin.
// STDIN field "args[cni][poolType]" has the highest priority
func getPoolType(n *NetConf) (string, error) {
var poolType string
if n.Args != nil && n.Args.ArgsCNI.PoolType != "" {
poolType = n.Args.ArgsCNI.PoolType
} else {
poolType = n.IPAM.PoolType
}
poolType = strings.ToLower(poolType)
if poolType != common.PoolTypeIPPool && poolType != common.PoolTypeCIDRPool {
return "", fmt.Errorf("unsupported poolType %s, supported values: %s, %s",
poolType, common.PoolTypeIPPool, common.PoolTypeCIDRPool)
}
return poolType, nil
}

// loadFromConfFile returns *IPAMConf with values from config file located in filePath.
func (cl *confLoader) loadFromConfFile(filePath string) (*IPAMConf, error) {
data, err := os.ReadFile(filePath)
Expand Down
55 changes: 55 additions & 0 deletions pkg/cni/types/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,5 +158,60 @@ var _ = Describe("Types Tests", func() {
"runtimeConfig": {"ips": ["adfdsaf"]}, "ipam": {"confDir": %q}}`, "",
nil, false),
)
DescribeTable("PoolName",
func(fileContent string, stdinContent string, expectedValue []string, isValid bool) {
Expect(os.WriteFile(path.Join(testConfDir, cniTypes.ConfFileName),
[]byte(fileContent), 0o644)).NotTo(HaveOccurred())
stdinContent = fmt.Sprintf(stdinContent, testConfDir)
conf, err := cniTypes.NewConfLoader().LoadConf(&skel.CmdArgs{StdinData: []byte(stdinContent), Args: testArgs})
if isValid {
Expect(err).NotTo(HaveOccurred())
Expect(conf.IPAM.Pools).To(Equal(expectedValue))
} else {
Expect(err).To(HaveOccurred())
}
},
Entry("use network name if not set",
`{}`,
`{"name": "my-net", "ipam": {"confDir": %q}}`,
[]string{"my-net"}, true),
Entry("from conf file",
`{"poolName": "fromFile"}`,
`{"name": "my-net", "ipam": {"confDir": %q}}`,
[]string{"fromFile"}, true),
Entry("from STDIN",
`{"poolName": "fromFile"}`,
`{"name": "my-net", "ipam": {"confDir": %q, "poolName": "fromSTDIN"}}`,
[]string{"fromSTDIN"}, true),
Entry("from STDIN CNI args",
`{"poolName": "fromFile"}`,
`{"name": "my-net", "args":{"cni": {"poolNames": ["fromArgs", "fromArgs2"]}},
"ipam": {"confDir": %q, "poolName": "fromSTDIN"}}`,
[]string{"fromArgs", "fromArgs2"}, true),
Entry("too many pools",
`{}`,
`{"name": "my-net", "ipam": {"confDir": %q, "poolName": "pool1,pool2,pool3"}}`,
[]string{}, false),
)
DescribeTable("PoolType",
func(fileContent string, stdinContent string, expectedValue string, isValid bool) {
Expect(os.WriteFile(path.Join(testConfDir, cniTypes.ConfFileName),
[]byte(fileContent), 0o644)).NotTo(HaveOccurred())
stdinContent = fmt.Sprintf(stdinContent, testConfDir)
conf, err := cniTypes.NewConfLoader().LoadConf(&skel.CmdArgs{StdinData: []byte(stdinContent), Args: testArgs})
if isValid {
Expect(err).NotTo(HaveOccurred())
Expect(conf.IPAM.PoolType).To(Equal(expectedValue))
} else {
Expect(err).To(HaveOccurred())
}
},
Entry("use IPPool by default", `{}`, `{"name": "my-net", "ipam": {"confDir": %q}}`, "ippool", true),
Entry("from conf file", `{"poolType": "CIDRPool"}`, `{"name": "my-net", "ipam": {"confDir": %q}}`, "cidrpool", true),
Entry("from STDIN", `{}`, `{"name": "my-net", "ipam": {"confDir": %q, "poolType": "cidrPool"}}`, "cidrpool", true),
Entry("from STDIN CNI Args", `{}`, `{"name": "my-net",
"args": {"cni": {"poolType":"cidrpool"}}, "ipam": {"confDir": %q}}`, "cidrpool", true),
Entry("unknown type", `{}`, `{"name": "my-net", "ipam": {"confDir": %q, "poolType": "foobar"}}`, "", false),
)
})
})

0 comments on commit fb98825

Please sign in to comment.