mirror of
https://github.com/k8snetworkplumbingwg/multus-cni.git
synced 2025-08-17 07:41:32 +00:00
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 <bnemeth@redhat.com> * 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 <bnemeth@redhat.com> * multus: add unit test for incompatible cni versions Signed-off-by: Balazs Nemeth <bnemeth@redhat.com>
This commit is contained in:
parent
6dd45f38f9
commit
450e1d3414
@ -139,10 +139,14 @@ func main() {
|
|||||||
configurationOptions = append(
|
configurationOptions = append(
|
||||||
configurationOptions, config.WithReadinessFileIndicator(*readinessIndicator))
|
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 configManager *config.Manager
|
||||||
var err error
|
|
||||||
if *multusMasterCni == "" {
|
if *multusMasterCni == "" {
|
||||||
configManager, err = config.NewManager(*multusConfig, *multusAutoconfigDir)
|
configManager, err = config.NewManager(*multusConfig, *multusAutoconfigDir)
|
||||||
} else {
|
} else {
|
||||||
|
1
go.mod
1
go.mod
@ -3,6 +3,7 @@ module gopkg.in/k8snetworkplumbingwg/multus-cni.v3
|
|||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/blang/semver v3.5.1+incompatible
|
||||||
github.com/containernetworking/cni v0.8.1
|
github.com/containernetworking/cni v0.8.1
|
||||||
github.com/containernetworking/plugins v0.9.1
|
github.com/containernetworking/plugins v0.9.1
|
||||||
github.com/fsnotify/fsnotify v1.4.9
|
github.com/fsnotify/fsnotify v1.4.9
|
||||||
|
@ -87,6 +87,25 @@ if ! type python3 &> /dev/null; then
|
|||||||
alias python=python3
|
alias python=python3
|
||||||
fi
|
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.
|
# Parse parameters given as arguments to this script.
|
||||||
while [ "$1" != "" ]; do
|
while [ "$1" != "" ]; do
|
||||||
PARAM=`echo $1 | awk -F= '{print $1}'`
|
PARAM=`echo $1 | awk -F= '{print $1}'`
|
||||||
@ -374,6 +393,12 @@ EOF
|
|||||||
MASTER_PLUGIN_LOCATION=$MULTUS_AUTOCONF_DIR/$MASTER_PLUGIN
|
MASTER_PLUGIN_LOCATION=$MULTUS_AUTOCONF_DIR/$MASTER_PLUGIN
|
||||||
MASTER_PLUGIN_JSON="$(cat $MASTER_PLUGIN_LOCATION)"
|
MASTER_PLUGIN_JSON="$(cat $MASTER_PLUGIN_LOCATION)"
|
||||||
log "Using $MASTER_PLUGIN_LOCATION as a source to generate the Multus configuration"
|
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
|
CONF=$(cat <<-EOF
|
||||||
{
|
{
|
||||||
$CNI_VERSION_STRING
|
$CNI_VERSION_STRING
|
||||||
|
@ -17,12 +17,15 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/blang/semver"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -52,7 +55,7 @@ type MultusConf struct {
|
|||||||
|
|
||||||
// NewMultusConfig creates a basic configuration generator. It can be mutated
|
// NewMultusConfig creates a basic configuration generator. It can be mutated
|
||||||
// via the `With...` methods.
|
// 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{
|
multusConfig := &MultusConf{
|
||||||
Name: MultusDefaultNetworkName,
|
Name: MultusDefaultNetworkName,
|
||||||
CNIVersion: cniVersion,
|
CNIVersion: cniVersion,
|
||||||
@ -61,10 +64,45 @@ func NewMultusConfig(pluginName string, cniVersion string, kubeconfig string, co
|
|||||||
Kubeconfig: kubeconfig,
|
Kubeconfig: kubeconfig,
|
||||||
Delegates: []interface{}{},
|
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
|
// 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
|
// Mutate updates the MultusConf attributes according to the provided
|
||||||
// configuration `Option`s
|
// configuration `Option`s
|
||||||
func (mc *MultusConf) Mutate(configurationOptions ...Option) {
|
func (mc *MultusConf) Mutate(configurationOptions ...Option) error {
|
||||||
for _, configOption := range configurationOptions {
|
for _, configOption := range configurationOptions {
|
||||||
configOption(mc)
|
configOption(mc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return CheckVersionCompatibility(mc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithNamespaceIsolation mutates the inner state to enable the
|
// WithNamespaceIsolation mutates the inner state to enable the
|
||||||
|
@ -45,46 +45,51 @@ var primaryCNIConfig = map[string]interface{}{
|
|||||||
"logfile-maxage": 5,
|
"logfile-maxage": 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMultusConfigWithDelegates(pluginName string, cniVersion string, kubeconfig string, primaryCNIPluginConfig interface{}, configOptions ...Option) *MultusConf {
|
func newMultusConfigWithDelegates(pluginName string, cniVersion string, kubeconfig string, primaryCNIPluginConfig interface{}, configOptions ...Option) (*MultusConf, error) {
|
||||||
multusConfig := NewMultusConfig(pluginName, cniVersion, kubeconfig, configOptions...)
|
multusConfig, err := NewMultusConfig(pluginName, cniVersion, kubeconfig, configOptions...)
|
||||||
multusConfig.Delegates = []interface{}{primaryCNIPluginConfig}
|
if err != nil {
|
||||||
return multusConfig
|
return multusConfig, err
|
||||||
|
}
|
||||||
|
return multusConfig, multusConfig.Mutate(withDelegates(primaryCNIPluginConfig.(map[string]interface{})))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBasicMultusConfig(t *testing.T) {
|
func TestBasicMultusConfig(t *testing.T) {
|
||||||
multusConfig := newMultusConfigWithDelegates(
|
multusConfig, err := newMultusConfigWithDelegates(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig,
|
kubeconfig,
|
||||||
primaryCNIConfig)
|
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\"}"
|
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)
|
newTestCase(t, multusConfig.Generate).assertResult(expectedResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultusConfigWithNamespaceIsolation(t *testing.T) {
|
func TestMultusConfigWithNamespaceIsolation(t *testing.T) {
|
||||||
multusConfig := newMultusConfigWithDelegates(
|
multusConfig, err := newMultusConfigWithDelegates(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig,
|
kubeconfig,
|
||||||
primaryCNIConfig,
|
primaryCNIConfig,
|
||||||
WithNamespaceIsolation())
|
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\"}"
|
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)
|
newTestCase(t, multusConfig.Generate).assertResult(expectedResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultusConfigWithReadinessIndicator(t *testing.T) {
|
func TestMultusConfigWithReadinessIndicator(t *testing.T) {
|
||||||
multusConfig := newMultusConfigWithDelegates(
|
multusConfig, err := newMultusConfigWithDelegates(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig,
|
kubeconfig,
|
||||||
primaryCNIConfig,
|
primaryCNIConfig,
|
||||||
WithReadinessFileIndicator("/a/b/u/it-lives"))
|
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\"}"
|
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)
|
newTestCase(t, multusConfig.Generate).assertResult(expectedResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultusConfigWithLoggingConfiguration(t *testing.T) {
|
func TestMultusConfigWithLoggingConfiguration(t *testing.T) {
|
||||||
multusConfig := newMultusConfigWithDelegates(
|
multusConfig, err := newMultusConfigWithDelegates(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig,
|
kubeconfig,
|
||||||
@ -92,96 +97,104 @@ func TestMultusConfigWithLoggingConfiguration(t *testing.T) {
|
|||||||
WithLogLevel("notice"),
|
WithLogLevel("notice"),
|
||||||
WithLogToStdErr(),
|
WithLogToStdErr(),
|
||||||
WithLogFile("/u/y/w/log.1"))
|
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\"}"
|
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)
|
newTestCase(t, multusConfig.Generate).assertResult(expectedResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultusConfigWithGlobalNamespace(t *testing.T) {
|
func TestMultusConfigWithGlobalNamespace(t *testing.T) {
|
||||||
const globalNamespace = "come-along-ns"
|
const globalNamespace = "come-along-ns"
|
||||||
multusConfig := newMultusConfigWithDelegates(
|
multusConfig, err := newMultusConfigWithDelegates(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig,
|
kubeconfig,
|
||||||
primaryCNIConfig,
|
primaryCNIConfig,
|
||||||
WithGlobalNamespaces(globalNamespace))
|
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\"}"
|
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)
|
newTestCase(t, multusConfig.Generate).assertResult(expectedResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultusConfigWithAdditionalBinDir(t *testing.T) {
|
func TestMultusConfigWithAdditionalBinDir(t *testing.T) {
|
||||||
const anotherCNIBinDir = "a-dir-somewhere"
|
const anotherCNIBinDir = "a-dir-somewhere"
|
||||||
multusConfig := newMultusConfigWithDelegates(
|
multusConfig, err := newMultusConfigWithDelegates(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig,
|
kubeconfig,
|
||||||
primaryCNIConfig,
|
primaryCNIConfig,
|
||||||
WithAdditionalBinaryFileDir(anotherCNIBinDir))
|
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\"}"
|
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)
|
newTestCase(t, multusConfig.Generate).assertResult(expectedResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultusConfigWithCapabilities(t *testing.T) {
|
func TestMultusConfigWithCapabilities(t *testing.T) {
|
||||||
multusConfig := newMultusConfigWithDelegates(
|
multusConfig, err := newMultusConfigWithDelegates(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig,
|
kubeconfig,
|
||||||
primaryCNIConfig,
|
primaryCNIConfig,
|
||||||
withCapabilities(
|
withCapabilities(
|
||||||
documentHelper(`{"capabilities": {"portMappings": true}}`)))
|
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\"}"
|
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)
|
newTestCase(t, multusConfig.Generate).assertResult(expectedResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultusConfigWithMultipleCapabilities(t *testing.T) {
|
func TestMultusConfigWithMultipleCapabilities(t *testing.T) {
|
||||||
multusConfig := newMultusConfigWithDelegates(
|
multusConfig, err := newMultusConfigWithDelegates(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig,
|
kubeconfig,
|
||||||
primaryCNIConfig,
|
primaryCNIConfig,
|
||||||
withCapabilities(
|
withCapabilities(
|
||||||
documentHelper(`{"capabilities": {"portMappings": true, "tuning": true}}`)))
|
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\"}"
|
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)
|
newTestCase(t, multusConfig.Generate).assertResult(expectedResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultusConfigWithMultipleCapabilitiesFilterOnlyEnabled(t *testing.T) {
|
func TestMultusConfigWithMultipleCapabilitiesFilterOnlyEnabled(t *testing.T) {
|
||||||
multusConfig := newMultusConfigWithDelegates(
|
multusConfig, err := newMultusConfigWithDelegates(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig,
|
kubeconfig,
|
||||||
primaryCNIConfig,
|
primaryCNIConfig,
|
||||||
withCapabilities(
|
withCapabilities(
|
||||||
documentHelper(`{"capabilities": {"portMappings": true, "tuning": false}}`)))
|
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\"}"
|
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)
|
newTestCase(t, multusConfig.Generate).assertResult(expectedResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultusConfigWithMultipleCapabilitiesDefinedOnAPlugin(t *testing.T) {
|
func TestMultusConfigWithMultipleCapabilitiesDefinedOnAPlugin(t *testing.T) {
|
||||||
multusConfig := newMultusConfigWithDelegates(
|
multusConfig, err := newMultusConfigWithDelegates(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig,
|
kubeconfig,
|
||||||
primaryCNIConfig,
|
primaryCNIConfig,
|
||||||
withCapabilities(
|
withCapabilities(
|
||||||
documentHelper(`{"plugins": [ {"capabilities": {"portMappings": true, "tuning": true}} ] }`)))
|
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\"}"
|
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)
|
newTestCase(t, multusConfig.Generate).assertResult(expectedResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultusConfigWithCapabilitiesDefinedOnMultiplePlugins(t *testing.T) {
|
func TestMultusConfigWithCapabilitiesDefinedOnMultiplePlugins(t *testing.T) {
|
||||||
multusConfig := newMultusConfigWithDelegates(
|
multusConfig, err := newMultusConfigWithDelegates(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig,
|
kubeconfig,
|
||||||
primaryCNIConfig,
|
primaryCNIConfig,
|
||||||
withCapabilities(
|
withCapabilities(
|
||||||
documentHelper(`{"plugins": [ {"capabilities": { "portMappings": true }}, {"capabilities": { "tuning": true }} ]}`)))
|
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\"}"
|
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)
|
newTestCase(t, multusConfig.Generate).assertResult(expectedResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultusConfigWithCapabilitiesDefinedOnMultiplePluginsFilterOnlyEnabled(t *testing.T) {
|
func TestMultusConfigWithCapabilitiesDefinedOnMultiplePluginsFilterOnlyEnabled(t *testing.T) {
|
||||||
multusConfig := newMultusConfigWithDelegates(
|
multusConfig, err := newMultusConfigWithDelegates(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig,
|
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\"}"
|
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)
|
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) {
|
func TestMultusConfigWithOverriddenName(t *testing.T) {
|
||||||
newNetworkName := "mega-net-2000"
|
newNetworkName := "mega-net-2000"
|
||||||
multusConfig := newMultusConfigWithDelegates(
|
multusConfig, _ := newMultusConfigWithDelegates(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig,
|
kubeconfig,
|
||||||
|
@ -78,8 +78,9 @@ func newManager(config MultusConf, multusConfigDir string, defaultCNIPluginName
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := configManager.loadPrimaryCNIConfigFromFile(); err != nil {
|
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
|
return configManager, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,8 +89,7 @@ func (m *Manager) loadPrimaryCNIConfigFromFile() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return logging.Errorf("failed to access the primary CNI configuration from %s: %v", m.primaryCNIConfigPath, err)
|
return logging.Errorf("failed to access the primary CNI configuration from %s: %v", m.primaryCNIConfigPath, err)
|
||||||
}
|
}
|
||||||
m.loadPrimaryCNIConfigurationData(primaryCNIConfigData)
|
return m.loadPrimaryCNIConfigurationData(primaryCNIConfigData)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OverrideNetworkName overrides the name of the multus configuration with the
|
// OverrideNetworkName overrides the name of the multus configuration with the
|
||||||
@ -104,15 +104,14 @@ func (m *Manager) OverrideNetworkName() error {
|
|||||||
if networkName == "" {
|
if networkName == "" {
|
||||||
return fmt.Errorf("the primary CNI Configuration does not feature the network name: %v", m.cniConfigData)
|
return fmt.Errorf("the primary CNI Configuration does not feature the network name: %v", m.cniConfigData)
|
||||||
}
|
}
|
||||||
m.multusConfig.Mutate(WithOverriddenName(networkName))
|
return m.multusConfig.Mutate(WithOverriddenName(networkName))
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) loadPrimaryCNIConfigurationData(primaryCNIConfigData interface{}) {
|
func (m *Manager) loadPrimaryCNIConfigurationData(primaryCNIConfigData interface{}) error {
|
||||||
cniConfigData := primaryCNIConfigData.(map[string]interface{})
|
cniConfigData := primaryCNIConfigData.(map[string]interface{})
|
||||||
|
|
||||||
m.cniConfigData = cniConfigData
|
m.cniConfigData = cniConfigData
|
||||||
m.multusConfig.Mutate(
|
return m.multusConfig.Mutate(
|
||||||
withDelegates(cniConfigData),
|
withDelegates(cniConfigData),
|
||||||
withCapabilities(cniConfigData))
|
withCapabilities(cniConfigData))
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ var _ = Describe(suiteName, func() {
|
|||||||
defaultCniConfig = fmt.Sprintf("%s/%s", multusConfigDir, primaryCNIPluginName)
|
defaultCniConfig = fmt.Sprintf("%s/%s", multusConfigDir, primaryCNIPluginName)
|
||||||
Expect(ioutil.WriteFile(defaultCniConfig, []byte(primaryCNIPluginTemplate), userRWPermission)).To(Succeed())
|
Expect(ioutil.WriteFile(defaultCniConfig, []byte(primaryCNIPluginTemplate), userRWPermission)).To(Succeed())
|
||||||
|
|
||||||
multusConf := NewMultusConfig(
|
multusConf, _ := NewMultusConfig(
|
||||||
primaryCNIName,
|
primaryCNIName,
|
||||||
cniVersion,
|
cniVersion,
|
||||||
kubeconfig)
|
kubeconfig)
|
||||||
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -4,6 +4,7 @@ github.com/Microsoft/go-winio/pkg/guid
|
|||||||
# github.com/beorn7/perks v1.0.1
|
# github.com/beorn7/perks v1.0.1
|
||||||
github.com/beorn7/perks/quantile
|
github.com/beorn7/perks/quantile
|
||||||
# github.com/blang/semver v3.5.1+incompatible
|
# github.com/blang/semver v3.5.1+incompatible
|
||||||
|
## explicit
|
||||||
github.com/blang/semver
|
github.com/blang/semver
|
||||||
# github.com/cespare/xxhash/v2 v2.1.1
|
# github.com/cespare/xxhash/v2 v2.1.1
|
||||||
github.com/cespare/xxhash/v2
|
github.com/cespare/xxhash/v2
|
||||||
|
Loading…
Reference in New Issue
Block a user