Skip to content

Commit 455c465

Browse files
committed
Initial stab at supporting subdirectory-based plugin conf loading
Signed-off-by: Benjamin Leggett <[email protected]>
1 parent b62753a commit 455c465

File tree

9 files changed

+239
-141
lines changed

9 files changed

+239
-141
lines changed

Diff for: SPEC.md

+52-38
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,14 @@ A network configuration consists of a JSON object with the following keys:
109109

110110
- `cniVersion` (string): [Semantic Version 2.0](https://semver.org) of CNI specification to which this configuration list and all the individual configurations conform. Currently "1.1.0"
111111
- `cniVersions` (string list): List of all CNI versions which this configuration supports. See [version selection](#version-selection) below.
112-
- `name` (string): Network name. This should be unique across all network configurations on a host (or other administrative domain). Must start with an alphanumeric character, optionally followed by any combination of one or more alphanumeric characters, underscore, dot (.) or hyphen (-).
112+
- `name` (string): Network name. This should be unique across all network configurations on a host (or other administrative domain). Must start with an alphanumeric character, optionally followed by any combination of one or more alphanumeric characters, underscore, dot (.) or hyphen (-). Must not contain characters disallowed in file paths. A path segment (such as a filesystem directory) with the same name as the network name, containing one or more plugin configuration JSON objects for that network, should exist at the same level as the network configuration object itself.
113113
- `disableCheck` (boolean): Either `true` or `false`. If `disableCheck` is `true`, runtimes must not call `CHECK` for this network configuration list. This allows an administrator to prevent `CHECK`ing where a combination of plugins is known to return spurious errors.
114-
- `plugins` (list): A list of CNI plugins and their configuration, which is a list of plugin configuration objects.
114+
<!-- - `plugins` (list): A list of CNI plugins and their configuration, which is a list of plugin configuration objects. -->
115115

116116
#### Plugin configuration objects:
117-
Plugin configuration objects may contain additional fields than the ones defined here.
118-
The runtime MUST pass through these fields, unchanged, to the plugin, as defined in section 3.
117+
All plugin configuration objects present in a directory with the same name as a valid network configuration must be parsed, and each plugin with a parsable configuration object must be invoked.
118+
119+
Plugin configuration objects may contain additional fields beyond the ones defined here. The runtime MUST pass through these fields, unchanged, to the invoked plugin, as defined in section 3.
119120

120121
**Required keys:**
121122
- `type` (string): Matches the name of the CNI plugin binary on disk. Must not contain characters disallowed in file paths for the system (e.g. / or \\).
@@ -146,48 +147,61 @@ Plugins that consume any of these configuration keys should respect their intend
146147
Plugins may define additional fields that they accept and may generate an error if called with unknown fields. Runtimes must preserve unknown fields in plugin configuration objects when transforming for execution.
147148

148149
#### Example configuration
150+
151+
`/etc/cni/net.d/10-dbnet.conf`:
149152
```jsonc
150153
{
151154
"cniVersion": "1.1.0",
152155
"cniVersions": ["0.3.1", "0.4.0", "1.0.0", "1.1.0"],
153156
"name": "dbnet",
154-
"plugins": [
155-
{
156-
"type": "bridge",
157-
// plugin specific parameters
158-
"bridge": "cni0",
159-
"keyA": ["some more", "plugin specific", "configuration"],
160-
161-
"ipam": {
162-
"type": "host-local",
163-
// ipam specific
164-
"subnet": "10.1.0.0/16",
165-
"gateway": "10.1.0.1",
166-
"routes": [
167-
{"dst": "0.0.0.0/0"}
168-
]
169-
},
170-
"dns": {
171-
"nameservers": [ "10.1.0.1" ]
172-
}
173-
},
174-
{
175-
"type": "tuning",
176-
"capabilities": {
177-
"mac": true
178-
},
179-
"sysctl": {
180-
"net.core.somaxconn": "500"
181-
}
182-
},
183-
{
184-
"type": "portmap",
185-
"capabilities": {"portMappings": true}
186-
}
187-
]
188157
}
189158
```
190159

160+
`/etc/cni/net.d/dbnet/5-bridge.conf`:
161+
```jsonc
162+
{
163+
"type": "bridge",
164+
// plugin specific parameters
165+
"bridge": "cni0",
166+
"keyA": ["some more", "plugin specific", "configuration"],
167+
168+
"ipam": {
169+
"type": "host-local",
170+
// ipam specific
171+
"subnet": "10.1.0.0/16",
172+
"gateway": "10.1.0.1",
173+
"routes": [
174+
{"dst": "0.0.0.0/0"}
175+
]
176+
},
177+
"dns": {
178+
"nameservers": [ "10.1.0.1" ]
179+
}
180+
},
181+
```
182+
183+
`/etc/cni/net.d/dbnet/10-tuning.conf`:
184+
```jsonc
185+
{
186+
"type": "tuning",
187+
"capabilities": {
188+
"mac": true
189+
},
190+
"sysctl": {
191+
"net.core.somaxconn": "500"
192+
}
193+
},
194+
```
195+
196+
`/etc/cni/net.d/dbnet/15-portmap.conf`:
197+
```jsonc
198+
{
199+
"type": "portmap",
200+
"capabilities": {"portMappings": true}
201+
}
202+
203+
```
204+
191205
### Version considerations
192206

193207
CNI runtimes, plugins, and network configurations may support multiple CNI specification versions independently. Plugins indicate their set of supported versions through the VERSION command, while network configurations indicate their set of supported versions through the `cniVersion` and `cniVersions` fields.

Diff for: libcni/api.go

+27-23
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,20 @@ type RuntimeConf struct {
6666
CacheDir string
6767
}
6868

69-
type NetworkConfig struct {
70-
Network *types.NetConf
69+
// Deprecated: Use PluginConfig instead of NetworkConfig, the NetworkConfig
70+
// backwards-compat alias will be removed in a future release.
71+
type NetworkConfig = PluginConfig
72+
73+
type PluginConfig struct {
74+
Network *types.PluginConf
7175
Bytes []byte
7276
}
7377

7478
type NetworkConfigList struct {
7579
Name string
7680
CNIVersion string
7781
DisableCheck bool
78-
Plugins []*NetworkConfig
82+
Plugins []*PluginConfig
7983
Bytes []byte
8084
}
8185

@@ -104,14 +108,14 @@ type CNI interface {
104108
GetNetworkListCachedResult(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
105109
GetNetworkListCachedConfig(net *NetworkConfigList, rt *RuntimeConf) ([]byte, *RuntimeConf, error)
106110

107-
AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
108-
CheckNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
109-
DelNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
110-
GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
111-
GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error)
111+
AddNetwork(ctx context.Context, net *PluginConfig, rt *RuntimeConf) (types.Result, error)
112+
CheckNetwork(ctx context.Context, net *PluginConfig, rt *RuntimeConf) error
113+
DelNetwork(ctx context.Context, net *PluginConfig, rt *RuntimeConf) error
114+
GetNetworkCachedResult(net *PluginConfig, rt *RuntimeConf) (types.Result, error)
115+
GetNetworkCachedConfig(net *PluginConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error)
112116

113117
ValidateNetworkList(ctx context.Context, net *NetworkConfigList) ([]string, error)
114-
ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error)
118+
ValidateNetwork(ctx context.Context, net *PluginConfig) ([]string, error)
115119

116120
GCNetworkList(ctx context.Context, net *NetworkConfigList, args *GCArgs) error
117121
GetStatusNetworkList(ctx context.Context, net *NetworkConfigList) error
@@ -147,7 +151,7 @@ func NewCNIConfigWithCacheDir(path []string, cacheDir string, exec invoke.Exec)
147151
}
148152
}
149153

150-
func buildOneConfig(name, cniVersion string, orig *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (*NetworkConfig, error) {
154+
func buildOneConfig(name, cniVersion string, orig *PluginConfig, prevResult types.Result, rt *RuntimeConf) (*PluginConfig, error) {
151155
var err error
152156

153157
inject := map[string]interface{}{
@@ -183,7 +187,7 @@ func buildOneConfig(name, cniVersion string, orig *NetworkConfig, prevResult typ
183187
// capabilities include "portMappings", and the CapabilityArgs map includes a
184188
// "portMappings" key, that key and its value are added to the "runtimeConfig"
185189
// dictionary to be passed to the plugin's stdin.
186-
func injectRuntimeConfig(orig *NetworkConfig, rt *RuntimeConf) (*NetworkConfig, error) {
190+
func injectRuntimeConfig(orig *PluginConfig, rt *RuntimeConf) (*PluginConfig, error) {
187191
var err error
188192

189193
rc := make(map[string]interface{})
@@ -404,7 +408,7 @@ func (c *CNIConfig) GetNetworkListCachedResult(list *NetworkConfigList, rt *Runt
404408

405409
// GetNetworkCachedResult returns the cached Result of the previous
406410
// AddNetwork() operation for a network, or an error.
407-
func (c *CNIConfig) GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) {
411+
func (c *CNIConfig) GetNetworkCachedResult(net *PluginConfig, rt *RuntimeConf) (types.Result, error) {
408412
return c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
409413
}
410414

@@ -416,7 +420,7 @@ func (c *CNIConfig) GetNetworkListCachedConfig(list *NetworkConfigList, rt *Runt
416420

417421
// GetNetworkCachedConfig copies the input RuntimeConf to output
418422
// RuntimeConf with fields updated with info from the cached Config.
419-
func (c *CNIConfig) GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error) {
423+
func (c *CNIConfig) GetNetworkCachedConfig(net *PluginConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error) {
420424
return c.getCachedConfig(net.Network.Name, rt)
421425
}
422426

@@ -479,7 +483,7 @@ func (c *CNIConfig) GetCachedAttachments(containerID string) ([]*NetworkAttachme
479483
return attachments, nil
480484
}
481485

482-
func (c *CNIConfig) addNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (types.Result, error) {
486+
func (c *CNIConfig) addNetwork(ctx context.Context, name, cniVersion string, net *PluginConfig, prevResult types.Result, rt *RuntimeConf) (types.Result, error) {
483487
c.ensureExec()
484488
pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path)
485489
if err != nil {
@@ -521,7 +525,7 @@ func (c *CNIConfig) AddNetworkList(ctx context.Context, list *NetworkConfigList,
521525
return result, nil
522526
}
523527

524-
func (c *CNIConfig) checkNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) error {
528+
func (c *CNIConfig) checkNetwork(ctx context.Context, name, cniVersion string, net *PluginConfig, prevResult types.Result, rt *RuntimeConf) error {
525529
c.ensureExec()
526530
pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path)
527531
if err != nil {
@@ -563,7 +567,7 @@ func (c *CNIConfig) CheckNetworkList(ctx context.Context, list *NetworkConfigLis
563567
return nil
564568
}
565569

566-
func (c *CNIConfig) delNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) error {
570+
func (c *CNIConfig) delNetwork(ctx context.Context, name, cniVersion string, net *PluginConfig, prevResult types.Result, rt *RuntimeConf) error {
567571
c.ensureExec()
568572
pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path)
569573
if err != nil {
@@ -603,7 +607,7 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList,
603607
return nil
604608
}
605609

606-
func pluginDescription(net *types.NetConf) string {
610+
func pluginDescription(net *types.PluginConf) string {
607611
if net == nil {
608612
return "<missing>"
609613
}
@@ -617,7 +621,7 @@ func pluginDescription(net *types.NetConf) string {
617621
}
618622

619623
// AddNetwork executes the plugin with the ADD command
620-
func (c *CNIConfig) AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error) {
624+
func (c *CNIConfig) AddNetwork(ctx context.Context, net *PluginConfig, rt *RuntimeConf) (types.Result, error) {
621625
result, err := c.addNetwork(ctx, net.Network.Name, net.Network.CNIVersion, net, nil, rt)
622626
if err != nil {
623627
return nil, err
@@ -631,7 +635,7 @@ func (c *CNIConfig) AddNetwork(ctx context.Context, net *NetworkConfig, rt *Runt
631635
}
632636

633637
// CheckNetwork executes the plugin with the CHECK command
634-
func (c *CNIConfig) CheckNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error {
638+
func (c *CNIConfig) CheckNetwork(ctx context.Context, net *PluginConfig, rt *RuntimeConf) error {
635639
// CHECK was added in CNI spec version 0.4.0 and higher
636640
if gtet, err := version.GreaterThanOrEqualTo(net.Network.CNIVersion, "0.4.0"); err != nil {
637641
return err
@@ -647,7 +651,7 @@ func (c *CNIConfig) CheckNetwork(ctx context.Context, net *NetworkConfig, rt *Ru
647651
}
648652

649653
// DelNetwork executes the plugin with the DEL command
650-
func (c *CNIConfig) DelNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error {
654+
func (c *CNIConfig) DelNetwork(ctx context.Context, net *PluginConfig, rt *RuntimeConf) error {
651655
var cachedResult types.Result
652656

653657
// Cached result on DEL was added in CNI spec version 0.4.0 and higher
@@ -707,7 +711,7 @@ func (c *CNIConfig) ValidateNetworkList(ctx context.Context, list *NetworkConfig
707711
// ValidateNetwork checks that a configuration is reasonably valid.
708712
// It uses the same logic as ValidateNetworkList)
709713
// Returns a list of capabilities
710-
func (c *CNIConfig) ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error) {
714+
func (c *CNIConfig) ValidateNetwork(ctx context.Context, net *PluginConfig) ([]string, error) {
711715
caps := []string{}
712716
for c, ok := range net.Network.Capabilities {
713717
if ok {
@@ -819,7 +823,7 @@ func (c *CNIConfig) GCNetworkList(ctx context.Context, list *NetworkConfigList,
819823
return joinErrors(errs...)
820824
}
821825

822-
func (c *CNIConfig) gcNetwork(ctx context.Context, net *NetworkConfig) error {
826+
func (c *CNIConfig) gcNetwork(ctx context.Context, net *PluginConfig) error {
823827
c.ensureExec()
824828
pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path)
825829
if err != nil {
@@ -854,7 +858,7 @@ func (c *CNIConfig) GetStatusNetworkList(ctx context.Context, list *NetworkConfi
854858
return nil
855859
}
856860

857-
func (c *CNIConfig) getStatusNetwork(ctx context.Context, net *NetworkConfig) error {
861+
func (c *CNIConfig) getStatusNetwork(ctx context.Context, net *PluginConfig) error {
858862
c.ensureExec()
859863
pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path)
860864
if err != nil {

Diff for: libcni/api_test.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ var _ = Describe("Invoking plugins", func() {
176176
pluginConfig []byte
177177
cniConfig *libcni.CNIConfig
178178
runtimeConfig *libcni.RuntimeConf
179-
netConfig *libcni.NetworkConfig
179+
netConfig *libcni.PluginConfig
180180
ctx context.Context
181181
)
182182

@@ -295,7 +295,7 @@ var _ = Describe("Invoking plugins", func() {
295295
debug *noop_debug.Debug
296296
pluginConfig string
297297
cniConfig *libcni.CNIConfig
298-
netConfig *libcni.NetworkConfig
298+
netConfig *libcni.PluginConfig
299299
runtimeConfig *libcni.RuntimeConf
300300
ctx context.Context
301301

@@ -1625,7 +1625,7 @@ var _ = Describe("Invoking plugins", func() {
16251625
cniBinPath string
16261626
pluginConfig string
16271627
cniConfig *libcni.CNIConfig
1628-
netConfig *libcni.NetworkConfig
1628+
netConfig *libcni.PluginConfig
16291629
runtimeConfig *libcni.RuntimeConf
16301630
netConfigList *libcni.NetworkConfigList
16311631
)
@@ -1798,7 +1798,7 @@ var _ = Describe("Invoking plugins", func() {
17981798
cniBinPath string
17991799
pluginConfig string
18001800
cniConfig *libcni.CNIConfig
1801-
netConfig *libcni.NetworkConfig
1801+
netConfig *libcni.PluginConfig
18021802
runtimeConfig *libcni.RuntimeConf
18031803

18041804
ctx context.Context
@@ -1920,14 +1920,14 @@ var _ = Describe("Invoking plugins", func() {
19201920
Context("when the RuntimeConf is incomplete", func() {
19211921
var (
19221922
testRt *libcni.RuntimeConf
1923-
testNetConf *libcni.NetworkConfig
1923+
testNetConf *libcni.PluginConfig
19241924
testNetConfList *libcni.NetworkConfigList
19251925
)
19261926

19271927
BeforeEach(func() {
19281928
testRt = &libcni.RuntimeConf{}
1929-
testNetConf = &libcni.NetworkConfig{
1930-
Network: &types.NetConf{},
1929+
testNetConf = &libcni.PluginConfig{
1930+
Network: &types.PluginConf{},
19311931
}
19321932
testNetConfList = &libcni.NetworkConfigList{}
19331933
})

0 commit comments

Comments
 (0)