From 450e1d341435691dbb9aafbbf430dc3d4345f8a5 Mon Sep 17 00:00:00 2001 From: Balazs Nemeth Date: Mon, 28 Feb 2022 13:50:39 +0100 Subject: [PATCH] check version incompatibility (#762) * multus: entrypoint: disallow incompatible cni versions When top level CNI version is 0.4.0 or more, nested CNI version can't be less than 0.4.0 since these are incompatible. This closes issue #737. Signed-off-by: Balazs Nemeth * multus: thick: disallow incompatible cni versions Similarly to disallowing incompatible versions in entrypoint.sh, add the same logic in go for the thick plugin. Signed-off-by: Balazs Nemeth * multus: add unit test for incompatible cni versions Signed-off-by: Balazs Nemeth --- cmd/controller/main.go | 8 +++- go.mod | 1 + images/entrypoint.sh | 31 ++++++++++++-- pkg/config/generator.go | 50 +++++++++++++++++++--- pkg/config/generator_test.go | 82 ++++++++++++++++++++++++++++-------- pkg/config/manager.go | 13 +++--- pkg/config/manager_test.go | 2 +- vendor/modules.txt | 1 + 8 files changed, 153 insertions(+), 35 deletions(-) diff --git a/cmd/controller/main.go b/cmd/controller/main.go index 8a50cce58..a02578c09 100644 --- a/cmd/controller/main.go +++ b/cmd/controller/main.go @@ -139,10 +139,14 @@ func main() { configurationOptions = append( configurationOptions, config.WithReadinessFileIndicator(*readinessIndicator)) } - multusConfig := config.NewMultusConfig(multusPluginName, *cniVersion, *multusKubeconfig, configurationOptions...) + + multusConfig, err := config.NewMultusConfig(multusPluginName, *cniVersion, *multusKubeconfig, configurationOptions...) + if err != nil { + _ = logging.Errorf("Failed to create multus config: %v", err) + os.Exit(3) + } var configManager *config.Manager - var err error if *multusMasterCni == "" { configManager, err = config.NewManager(*multusConfig, *multusAutoconfigDir) } else { diff --git a/go.mod b/go.mod index b8208d6ac..5cb11793a 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module gopkg.in/k8snetworkplumbingwg/multus-cni.v3 go 1.16 require ( + github.com/blang/semver v3.5.1+incompatible github.com/containernetworking/cni v0.8.1 github.com/containernetworking/plugins v0.9.1 github.com/fsnotify/fsnotify v1.4.9 diff --git a/images/entrypoint.sh b/images/entrypoint.sh index fdd0d3c78..92e8cc426 100755 --- a/images/entrypoint.sh +++ b/images/entrypoint.sh @@ -87,6 +87,25 @@ if ! type python3 &> /dev/null; then alias python=python3 fi +function checkCniVersion { + cniversion_python_tmpfile=$(mktemp) + cat << EOF > $cniversion_python_tmpfile +import json, sys + +def version(v): + return [int(x) for x in v.split(".")] + +v_040 = version("0.4.0") +v_top_level = sys.argv[2] +with open(sys.argv[1], "r") as f: + v_nested = json.load(f)["cniVersion"] +if version(v_top_level) >= v_040 and version(v_nested) < v_040: + msg = "Multus cni version is %s while master plugin cni version is %s" + print(msg % (v_top_level, v_nested)) +EOF + python $cniversion_python_tmpfile $1 $2 +} + # Parse parameters given as arguments to this script. while [ "$1" != "" ]; do PARAM=`echo $1 | awk -F= '{print $1}'` @@ -317,7 +336,7 @@ if [ "$MULTUS_CONF_FILE" == "auto" ]; then *) error "Log levels should be one of: debug/verbose/error/panic, did not understand $MULTUS_LOG_LEVEL" usage - exit 1 + exit 1 esac LOG_LEVEL_STRING="\"logLevel\": \"$MULTUS_LOG_LEVEL\"," fi @@ -369,11 +388,17 @@ EOF NESTED_CAPABILITIES_STRING="$(cat $MULTUS_AUTOCONF_DIR/$MASTER_PLUGIN | \ python $capabilities_python_filter_tmpfile)" rm $capabilities_python_filter_tmpfile - log "Nested capabilities string: $NESTED_CAPABILITIES_STRING" + log "Nested capabilities string: $NESTED_CAPABILITIES_STRING" MASTER_PLUGIN_LOCATION=$MULTUS_AUTOCONF_DIR/$MASTER_PLUGIN MASTER_PLUGIN_JSON="$(cat $MASTER_PLUGIN_LOCATION)" log "Using $MASTER_PLUGIN_LOCATION as a source to generate the Multus configuration" + CHECK_CNI_VERSION=$(checkCniVersion $MASTER_PLUGIN_LOCATION $CNI_VERSION) + if [ "$CHECK_CNI_VERSION" != "" ] ; then + error "$CHECK_CNI_VERSION" + exit 1 + fi + CONF=$(cat <<-EOF { $CNI_VERSION_STRING @@ -399,7 +424,7 @@ EOF mv $tmpfile $CNI_CONF_DIR/00-multus.conf log "Config file created @ $CNI_CONF_DIR/00-multus.conf" echo $CONF - + # If we're not performing the cleanup on exit, we can safely rename the config file. if [ "$RENAME_SOURCE_CONFIG_FILE" == true ]; then mv ${MULTUS_AUTOCONF_DIR}/${MASTER_PLUGIN} ${MULTUS_AUTOCONF_DIR}/${MASTER_PLUGIN}.old diff --git a/pkg/config/generator.go b/pkg/config/generator.go index 5ec4530d5..32f022d5b 100644 --- a/pkg/config/generator.go +++ b/pkg/config/generator.go @@ -17,12 +17,15 @@ package config import ( "encoding/json" + "errors" "fmt" "io/ioutil" "path/filepath" "sort" "strings" "time" + + "github.com/blang/semver" ) const ( @@ -52,7 +55,7 @@ type MultusConf struct { // NewMultusConfig creates a basic configuration generator. It can be mutated // via the `With...` methods. -func NewMultusConfig(pluginName string, cniVersion string, kubeconfig string, configurationOptions ...Option) *MultusConf { +func NewMultusConfig(pluginName string, cniVersion string, kubeconfig string, configurationOptions ...Option) (*MultusConf, error) { multusConfig := &MultusConf{ Name: MultusDefaultNetworkName, CNIVersion: cniVersion, @@ -61,10 +64,45 @@ func NewMultusConfig(pluginName string, cniVersion string, kubeconfig string, co Kubeconfig: kubeconfig, Delegates: []interface{}{}, } - for _, configOption := range configurationOptions { - configOption(multusConfig) + + err := multusConfig.Mutate(configurationOptions...) + return multusConfig, err +} + +// CheckVersionCompatibility checks compatibilty of the +// top level cni version with the delegate cni version. +// Since version 0.4.0, CHECK was introduced, which +// causes incompatibility. +func CheckVersionCompatibility(mc *MultusConf) error { + const versionFmt = "delegate cni version is %s while top level cni version is %s" + v040, _ := semver.Make("0.4.0") + multusCNIVersion, err := semver.Make(mc.CNIVersion) + + if err != nil { + return errors.New("couldn't get top level cni version") } - return multusConfig + + if multusCNIVersion.GTE(v040) { + for _, delegate := range mc.Delegates { + delegatesMap, ok := delegate.(map[string]interface{}) + if !ok { + return errors.New("couldn't get cni version of delegate") + } + delegateVersion, ok := delegatesMap["cniVersion"].(string) + if !ok { + return errors.New("couldn't get cni version of delegate") + } + v, err := semver.Make(delegateVersion) + if err != nil { + return err + } + if v.LT(v040) { + return fmt.Errorf(versionFmt, delegateVersion, mc.CNIVersion) + } + } + } + + return nil } // Generate generates the multus configuration from whatever state is currently @@ -76,10 +114,12 @@ func (mc *MultusConf) Generate() (string, error) { // Mutate updates the MultusConf attributes according to the provided // configuration `Option`s -func (mc *MultusConf) Mutate(configurationOptions ...Option) { +func (mc *MultusConf) Mutate(configurationOptions ...Option) error { for _, configOption := range configurationOptions { configOption(mc) } + + return CheckVersionCompatibility(mc) } // WithNamespaceIsolation mutates the inner state to enable the diff --git a/pkg/config/generator_test.go b/pkg/config/generator_test.go index 0d1f82649..cc6c40d5c 100644 --- a/pkg/config/generator_test.go +++ b/pkg/config/generator_test.go @@ -45,46 +45,51 @@ var primaryCNIConfig = map[string]interface{}{ "logfile-maxage": 5, } -func newMultusConfigWithDelegates(pluginName string, cniVersion string, kubeconfig string, primaryCNIPluginConfig interface{}, configOptions ...Option) *MultusConf { - multusConfig := NewMultusConfig(pluginName, cniVersion, kubeconfig, configOptions...) - multusConfig.Delegates = []interface{}{primaryCNIPluginConfig} - return multusConfig +func newMultusConfigWithDelegates(pluginName string, cniVersion string, kubeconfig string, primaryCNIPluginConfig interface{}, configOptions ...Option) (*MultusConf, error) { + multusConfig, err := NewMultusConfig(pluginName, cniVersion, kubeconfig, configOptions...) + if err != nil { + return multusConfig, err + } + return multusConfig, multusConfig.Mutate(withDelegates(primaryCNIPluginConfig.(map[string]interface{}))) } func TestBasicMultusConfig(t *testing.T) { - multusConfig := newMultusConfigWithDelegates( + multusConfig, err := newMultusConfigWithDelegates( primaryCNIName, cniVersion, kubeconfig, primaryCNIConfig) + assertError(t, err, nil) expectedResult := "{\"cniVersion\":\"0.4.0\",\"delegates\":[{\"cniVersion\":\"1.0.0\",\"dns\":\"{}\",\"ipam\":\"{}\",\"logFile\":\"/var/log/ovn-kubernetes/ovn-k8s-cni-overlay.log\",\"logLevel\":\"5\",\"logfile-maxage\":5,\"logfile-maxbackups\":5,\"logfile-maxsize\":100,\"name\":\"ovn-kubernetes\",\"type\":\"ovn-k8s-cni-overlay\"}],\"kubeconfig\":\"/a/b/c/kubeconfig.kubeconfig\",\"name\":\"multus-cni-network\",\"type\":\"myCNI\"}" newTestCase(t, multusConfig.Generate).assertResult(expectedResult) } func TestMultusConfigWithNamespaceIsolation(t *testing.T) { - multusConfig := newMultusConfigWithDelegates( + multusConfig, err := newMultusConfigWithDelegates( primaryCNIName, cniVersion, kubeconfig, primaryCNIConfig, WithNamespaceIsolation()) + assertError(t, err, nil) expectedResult := "{\"cniVersion\":\"0.4.0\",\"delegates\":[{\"cniVersion\":\"1.0.0\",\"dns\":\"{}\",\"ipam\":\"{}\",\"logFile\":\"/var/log/ovn-kubernetes/ovn-k8s-cni-overlay.log\",\"logLevel\":\"5\",\"logfile-maxage\":5,\"logfile-maxbackups\":5,\"logfile-maxsize\":100,\"name\":\"ovn-kubernetes\",\"type\":\"ovn-k8s-cni-overlay\"}],\"kubeconfig\":\"/a/b/c/kubeconfig.kubeconfig\",\"name\":\"multus-cni-network\",\"namespaceIsolation\":true,\"type\":\"myCNI\"}" newTestCase(t, multusConfig.Generate).assertResult(expectedResult) } func TestMultusConfigWithReadinessIndicator(t *testing.T) { - multusConfig := newMultusConfigWithDelegates( + multusConfig, err := newMultusConfigWithDelegates( primaryCNIName, cniVersion, kubeconfig, primaryCNIConfig, WithReadinessFileIndicator("/a/b/u/it-lives")) + assertError(t, err, nil) expectedResult := "{\"cniVersion\":\"0.4.0\",\"delegates\":[{\"cniVersion\":\"1.0.0\",\"dns\":\"{}\",\"ipam\":\"{}\",\"logFile\":\"/var/log/ovn-kubernetes/ovn-k8s-cni-overlay.log\",\"logLevel\":\"5\",\"logfile-maxage\":5,\"logfile-maxbackups\":5,\"logfile-maxsize\":100,\"name\":\"ovn-kubernetes\",\"type\":\"ovn-k8s-cni-overlay\"}],\"kubeconfig\":\"/a/b/c/kubeconfig.kubeconfig\",\"name\":\"multus-cni-network\",\"readinessindicatorfile\":\"/a/b/u/it-lives\",\"type\":\"myCNI\"}" newTestCase(t, multusConfig.Generate).assertResult(expectedResult) } func TestMultusConfigWithLoggingConfiguration(t *testing.T) { - multusConfig := newMultusConfigWithDelegates( + multusConfig, err := newMultusConfigWithDelegates( primaryCNIName, cniVersion, kubeconfig, @@ -92,96 +97,104 @@ func TestMultusConfigWithLoggingConfiguration(t *testing.T) { WithLogLevel("notice"), WithLogToStdErr(), WithLogFile("/u/y/w/log.1")) + assertError(t, err, nil) expectedResult := "{\"cniVersion\":\"0.4.0\",\"delegates\":[{\"cniVersion\":\"1.0.0\",\"dns\":\"{}\",\"ipam\":\"{}\",\"logFile\":\"/var/log/ovn-kubernetes/ovn-k8s-cni-overlay.log\",\"logLevel\":\"5\",\"logfile-maxage\":5,\"logfile-maxbackups\":5,\"logfile-maxsize\":100,\"name\":\"ovn-kubernetes\",\"type\":\"ovn-k8s-cni-overlay\"}],\"logFile\":\"/u/y/w/log.1\",\"logLevel\":\"notice\",\"logToStderr\":true,\"kubeconfig\":\"/a/b/c/kubeconfig.kubeconfig\",\"name\":\"multus-cni-network\",\"type\":\"myCNI\"}" newTestCase(t, multusConfig.Generate).assertResult(expectedResult) } func TestMultusConfigWithGlobalNamespace(t *testing.T) { const globalNamespace = "come-along-ns" - multusConfig := newMultusConfigWithDelegates( + multusConfig, err := newMultusConfigWithDelegates( primaryCNIName, cniVersion, kubeconfig, primaryCNIConfig, WithGlobalNamespaces(globalNamespace)) + assertError(t, err, nil) expectedResult := "{\"cniVersion\":\"0.4.0\",\"delegates\":[{\"cniVersion\":\"1.0.0\",\"dns\":\"{}\",\"ipam\":\"{}\",\"logFile\":\"/var/log/ovn-kubernetes/ovn-k8s-cni-overlay.log\",\"logLevel\":\"5\",\"logfile-maxage\":5,\"logfile-maxbackups\":5,\"logfile-maxsize\":100,\"name\":\"ovn-kubernetes\",\"type\":\"ovn-k8s-cni-overlay\"}],\"kubeconfig\":\"/a/b/c/kubeconfig.kubeconfig\",\"name\":\"multus-cni-network\",\"globalNamespaces\":\"come-along-ns\",\"type\":\"myCNI\"}" newTestCase(t, multusConfig.Generate).assertResult(expectedResult) } func TestMultusConfigWithAdditionalBinDir(t *testing.T) { const anotherCNIBinDir = "a-dir-somewhere" - multusConfig := newMultusConfigWithDelegates( + multusConfig, err := newMultusConfigWithDelegates( primaryCNIName, cniVersion, kubeconfig, primaryCNIConfig, WithAdditionalBinaryFileDir(anotherCNIBinDir)) + assertError(t, err, nil) expectedResult := "{\"binDir\":\"a-dir-somewhere\",\"cniVersion\":\"0.4.0\",\"delegates\":[{\"cniVersion\":\"1.0.0\",\"dns\":\"{}\",\"ipam\":\"{}\",\"logFile\":\"/var/log/ovn-kubernetes/ovn-k8s-cni-overlay.log\",\"logLevel\":\"5\",\"logfile-maxage\":5,\"logfile-maxbackups\":5,\"logfile-maxsize\":100,\"name\":\"ovn-kubernetes\",\"type\":\"ovn-k8s-cni-overlay\"}],\"kubeconfig\":\"/a/b/c/kubeconfig.kubeconfig\",\"name\":\"multus-cni-network\",\"type\":\"myCNI\"}" newTestCase(t, multusConfig.Generate).assertResult(expectedResult) } func TestMultusConfigWithCapabilities(t *testing.T) { - multusConfig := newMultusConfigWithDelegates( + multusConfig, err := newMultusConfigWithDelegates( primaryCNIName, cniVersion, kubeconfig, primaryCNIConfig, withCapabilities( documentHelper(`{"capabilities": {"portMappings": true}}`))) + assertError(t, err, nil) expectedResult := "{\"capabilities\":{\"portMappings\":true},\"cniVersion\":\"0.4.0\",\"delegates\":[{\"cniVersion\":\"1.0.0\",\"dns\":\"{}\",\"ipam\":\"{}\",\"logFile\":\"/var/log/ovn-kubernetes/ovn-k8s-cni-overlay.log\",\"logLevel\":\"5\",\"logfile-maxage\":5,\"logfile-maxbackups\":5,\"logfile-maxsize\":100,\"name\":\"ovn-kubernetes\",\"type\":\"ovn-k8s-cni-overlay\"}],\"kubeconfig\":\"/a/b/c/kubeconfig.kubeconfig\",\"name\":\"multus-cni-network\",\"type\":\"myCNI\"}" newTestCase(t, multusConfig.Generate).assertResult(expectedResult) } func TestMultusConfigWithMultipleCapabilities(t *testing.T) { - multusConfig := newMultusConfigWithDelegates( + multusConfig, err := newMultusConfigWithDelegates( primaryCNIName, cniVersion, kubeconfig, primaryCNIConfig, withCapabilities( documentHelper(`{"capabilities": {"portMappings": true, "tuning": true}}`))) + assertError(t, err, nil) expectedResult := "{\"capabilities\":{\"portMappings\":true,\"tuning\":true},\"cniVersion\":\"0.4.0\",\"delegates\":[{\"cniVersion\":\"1.0.0\",\"dns\":\"{}\",\"ipam\":\"{}\",\"logFile\":\"/var/log/ovn-kubernetes/ovn-k8s-cni-overlay.log\",\"logLevel\":\"5\",\"logfile-maxage\":5,\"logfile-maxbackups\":5,\"logfile-maxsize\":100,\"name\":\"ovn-kubernetes\",\"type\":\"ovn-k8s-cni-overlay\"}],\"kubeconfig\":\"/a/b/c/kubeconfig.kubeconfig\",\"name\":\"multus-cni-network\",\"type\":\"myCNI\"}" newTestCase(t, multusConfig.Generate).assertResult(expectedResult) } func TestMultusConfigWithMultipleCapabilitiesFilterOnlyEnabled(t *testing.T) { - multusConfig := newMultusConfigWithDelegates( + multusConfig, err := newMultusConfigWithDelegates( primaryCNIName, cniVersion, kubeconfig, primaryCNIConfig, withCapabilities( documentHelper(`{"capabilities": {"portMappings": true, "tuning": false}}`))) + assertError(t, err, nil) expectedResult := "{\"capabilities\":{\"portMappings\":true},\"cniVersion\":\"0.4.0\",\"delegates\":[{\"cniVersion\":\"1.0.0\",\"dns\":\"{}\",\"ipam\":\"{}\",\"logFile\":\"/var/log/ovn-kubernetes/ovn-k8s-cni-overlay.log\",\"logLevel\":\"5\",\"logfile-maxage\":5,\"logfile-maxbackups\":5,\"logfile-maxsize\":100,\"name\":\"ovn-kubernetes\",\"type\":\"ovn-k8s-cni-overlay\"}],\"kubeconfig\":\"/a/b/c/kubeconfig.kubeconfig\",\"name\":\"multus-cni-network\",\"type\":\"myCNI\"}" newTestCase(t, multusConfig.Generate).assertResult(expectedResult) } func TestMultusConfigWithMultipleCapabilitiesDefinedOnAPlugin(t *testing.T) { - multusConfig := newMultusConfigWithDelegates( + multusConfig, err := newMultusConfigWithDelegates( primaryCNIName, cniVersion, kubeconfig, primaryCNIConfig, withCapabilities( documentHelper(`{"plugins": [ {"capabilities": {"portMappings": true, "tuning": true}} ] }`))) + assertError(t, err, nil) expectedResult := "{\"capabilities\":{\"portMappings\":true,\"tuning\":true},\"cniVersion\":\"0.4.0\",\"delegates\":[{\"cniVersion\":\"1.0.0\",\"dns\":\"{}\",\"ipam\":\"{}\",\"logFile\":\"/var/log/ovn-kubernetes/ovn-k8s-cni-overlay.log\",\"logLevel\":\"5\",\"logfile-maxage\":5,\"logfile-maxbackups\":5,\"logfile-maxsize\":100,\"name\":\"ovn-kubernetes\",\"type\":\"ovn-k8s-cni-overlay\"}],\"kubeconfig\":\"/a/b/c/kubeconfig.kubeconfig\",\"name\":\"multus-cni-network\",\"type\":\"myCNI\"}" newTestCase(t, multusConfig.Generate).assertResult(expectedResult) } func TestMultusConfigWithCapabilitiesDefinedOnMultiplePlugins(t *testing.T) { - multusConfig := newMultusConfigWithDelegates( + multusConfig, err := newMultusConfigWithDelegates( primaryCNIName, cniVersion, kubeconfig, primaryCNIConfig, withCapabilities( documentHelper(`{"plugins": [ {"capabilities": { "portMappings": true }}, {"capabilities": { "tuning": true }} ]}`))) + assertError(t, err, nil) expectedResult := "{\"capabilities\":{\"portMappings\":true,\"tuning\":true},\"cniVersion\":\"0.4.0\",\"delegates\":[{\"cniVersion\":\"1.0.0\",\"dns\":\"{}\",\"ipam\":\"{}\",\"logFile\":\"/var/log/ovn-kubernetes/ovn-k8s-cni-overlay.log\",\"logLevel\":\"5\",\"logfile-maxage\":5,\"logfile-maxbackups\":5,\"logfile-maxsize\":100,\"name\":\"ovn-kubernetes\",\"type\":\"ovn-k8s-cni-overlay\"}],\"kubeconfig\":\"/a/b/c/kubeconfig.kubeconfig\",\"name\":\"multus-cni-network\",\"type\":\"myCNI\"}" newTestCase(t, multusConfig.Generate).assertResult(expectedResult) } func TestMultusConfigWithCapabilitiesDefinedOnMultiplePluginsFilterOnlyEnabled(t *testing.T) { - multusConfig := newMultusConfigWithDelegates( + multusConfig, err := newMultusConfigWithDelegates( primaryCNIName, cniVersion, kubeconfig, @@ -202,13 +215,48 @@ func TestMultusConfigWithCapabilitiesDefinedOnMultiplePluginsFilterOnlyEnabled(t } ] }`))) + assertError(t, err, nil) expectedResult := "{\"capabilities\":{\"portMappings\":true},\"cniVersion\":\"0.4.0\",\"delegates\":[{\"cniVersion\":\"1.0.0\",\"dns\":\"{}\",\"ipam\":\"{}\",\"logFile\":\"/var/log/ovn-kubernetes/ovn-k8s-cni-overlay.log\",\"logLevel\":\"5\",\"logfile-maxage\":5,\"logfile-maxbackups\":5,\"logfile-maxsize\":100,\"name\":\"ovn-kubernetes\",\"type\":\"ovn-k8s-cni-overlay\"}],\"kubeconfig\":\"/a/b/c/kubeconfig.kubeconfig\",\"name\":\"multus-cni-network\",\"type\":\"myCNI\"}" newTestCase(t, multusConfig.Generate).assertResult(expectedResult) } +func assertError(t *testing.T, actual error, expected error) { + if actual != nil && expected != nil { + if actual.Error() != expected.Error() { + t.Fatalf("multus config generation failed.\nExpected:\n%v\nbut GOT:\n%v", expected.Error(), actual.Error()) + } + } + + if actual == nil && expected != nil { + t.Fatalf("multus config generation failed.\nExpected:\n%v\nbut didn't get error", expected.Error()) + } else if actual != nil && expected == nil { + t.Fatalf("multus config generation failed.\nDidn't expect error\nbut GOT: %v\n", actual.Error()) + } +} + +func invalidDelegateCNIVersion(delegateCNIVersion, multusCNIVersion string) error { + return fmt.Errorf("delegate cni version is %s while top level cni version is %s", delegateCNIVersion, multusCNIVersion) +} + +func TestVersionIncompatibility(t *testing.T) { + const delegateCNIVersion = "0.3.0" + + primaryCNIConfigOld := primaryCNIConfig + tmpVer := primaryCNIConfig["cniVersion"] + primaryCNIConfig["cniVersion"] = delegateCNIVersion + _, err := newMultusConfigWithDelegates( + primaryCNIName, + cniVersion, + kubeconfig, + primaryCNIConfigOld) + primaryCNIConfig["cniVersion"] = tmpVer + + assertError(t, invalidDelegateCNIVersion(delegateCNIVersion, cniVersion), err) +} + func TestMultusConfigWithOverriddenName(t *testing.T) { newNetworkName := "mega-net-2000" - multusConfig := newMultusConfigWithDelegates( + multusConfig, _ := newMultusConfigWithDelegates( primaryCNIName, cniVersion, kubeconfig, diff --git a/pkg/config/manager.go b/pkg/config/manager.go index 4120fef2a..8652f84b5 100644 --- a/pkg/config/manager.go +++ b/pkg/config/manager.go @@ -78,8 +78,9 @@ func newManager(config MultusConf, multusConfigDir string, defaultCNIPluginName } if err := configManager.loadPrimaryCNIConfigFromFile(); err != nil { - return nil, fmt.Errorf("failed to load the primary CNI configuration as a multus delegate") + return nil, fmt.Errorf("failed to load the primary CNI configuration as a multus delegate with error '%v'", err) } + return configManager, nil } @@ -88,8 +89,7 @@ func (m *Manager) loadPrimaryCNIConfigFromFile() error { if err != nil { return logging.Errorf("failed to access the primary CNI configuration from %s: %v", m.primaryCNIConfigPath, err) } - m.loadPrimaryCNIConfigurationData(primaryCNIConfigData) - return nil + return m.loadPrimaryCNIConfigurationData(primaryCNIConfigData) } // OverrideNetworkName overrides the name of the multus configuration with the @@ -104,15 +104,14 @@ func (m *Manager) OverrideNetworkName() error { if networkName == "" { return fmt.Errorf("the primary CNI Configuration does not feature the network name: %v", m.cniConfigData) } - m.multusConfig.Mutate(WithOverriddenName(networkName)) - return nil + return m.multusConfig.Mutate(WithOverriddenName(networkName)) } -func (m *Manager) loadPrimaryCNIConfigurationData(primaryCNIConfigData interface{}) { +func (m *Manager) loadPrimaryCNIConfigurationData(primaryCNIConfigData interface{}) error { cniConfigData := primaryCNIConfigData.(map[string]interface{}) m.cniConfigData = cniConfigData - m.multusConfig.Mutate( + return m.multusConfig.Mutate( withDelegates(cniConfigData), withCapabilities(cniConfigData)) } diff --git a/pkg/config/manager_test.go b/pkg/config/manager_test.go index 6df78f85f..389a529a7 100644 --- a/pkg/config/manager_test.go +++ b/pkg/config/manager_test.go @@ -61,7 +61,7 @@ var _ = Describe(suiteName, func() { defaultCniConfig = fmt.Sprintf("%s/%s", multusConfigDir, primaryCNIPluginName) Expect(ioutil.WriteFile(defaultCniConfig, []byte(primaryCNIPluginTemplate), userRWPermission)).To(Succeed()) - multusConf := NewMultusConfig( + multusConf, _ := NewMultusConfig( primaryCNIName, cniVersion, kubeconfig) diff --git a/vendor/modules.txt b/vendor/modules.txt index aedc372f7..a4c7c2761 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -4,6 +4,7 @@ github.com/Microsoft/go-winio/pkg/guid # github.com/beorn7/perks v1.0.1 github.com/beorn7/perks/quantile # github.com/blang/semver v3.5.1+incompatible +## explicit github.com/blang/semver # github.com/cespare/xxhash/v2 v2.1.1 github.com/cespare/xxhash/v2