2018-06-20 02:27:42 +00:00
// Copyright (c) 2017 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package k8sclient
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
testutils "github.com/intel/multus-cni/testing"
"github.com/containernetworking/cni/pkg/skel"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
func TestK8sClient ( t * testing . T ) {
RegisterFailHandler ( Fail )
RunSpecs ( t , "k8sclient" )
}
var _ = Describe ( "k8sclient operations" , func ( ) {
var tmpDir string
var err error
BeforeEach ( func ( ) {
tmpDir , err = ioutil . TempDir ( "" , "multus_tmp" )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
} )
AfterEach ( func ( ) {
err := os . RemoveAll ( tmpDir )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
} )
It ( "retrieves delegates from kubernetes using simple format annotation" , func ( ) {
fakePod := testutils . NewFakePod ( "testpod" , "net1,net2" )
net1 := ` {
"name" : "net1" ,
"type" : "mynet" ,
"cniVersion" : "0.2.0"
} `
net2 := ` {
"name" : "net2" ,
"type" : "mynet2" ,
"cniVersion" : "0.2.0"
} `
net3 := ` {
"name" : "net3" ,
"type" : "mynet3" ,
"cniVersion" : "0.2.0"
} `
args := & skel . CmdArgs {
Args : fmt . Sprintf ( "K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s" , fakePod . ObjectMeta . Name , fakePod . ObjectMeta . Namespace ) ,
}
fKubeClient := testutils . NewFakeKubeClient ( )
fKubeClient . AddPod ( fakePod )
fKubeClient . AddNetConfig ( fakePod . ObjectMeta . Namespace , "net1" , net1 )
fKubeClient . AddNetConfig ( fakePod . ObjectMeta . Namespace , "net2" , net2 )
// net3 is not used; make sure it's not accessed
fKubeClient . AddNetConfig ( fakePod . ObjectMeta . Namespace , "net3" , net3 )
delegates , err := GetK8sNetwork ( args , "" , fKubeClient , tmpDir )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
Expect ( fKubeClient . PodCount ) . To ( Equal ( 1 ) )
Expect ( fKubeClient . NetCount ) . To ( Equal ( 2 ) )
Expect ( len ( delegates ) ) . To ( Equal ( 2 ) )
Expect ( delegates [ 0 ] . Name ) . To ( Equal ( "net1" ) )
Expect ( delegates [ 0 ] . Type ) . To ( Equal ( "mynet" ) )
Expect ( delegates [ 0 ] . MasterPlugin ) . To ( BeFalse ( ) )
Expect ( delegates [ 1 ] . Name ) . To ( Equal ( "net2" ) )
Expect ( delegates [ 1 ] . Type ) . To ( Equal ( "mynet2" ) )
Expect ( delegates [ 1 ] . MasterPlugin ) . To ( BeFalse ( ) )
} )
It ( "fails when the network does not exist" , func ( ) {
fakePod := testutils . NewFakePod ( "testpod" , "net1,net2" )
net3 := ` {
"name" : "net3" ,
"type" : "mynet3" ,
"cniVersion" : "0.2.0"
} `
args := & skel . CmdArgs {
Args : fmt . Sprintf ( "K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s" , fakePod . ObjectMeta . Name , fakePod . ObjectMeta . Namespace ) ,
}
fKubeClient := testutils . NewFakeKubeClient ( )
fKubeClient . AddPod ( fakePod )
fKubeClient . AddNetConfig ( fakePod . ObjectMeta . Namespace , "net3" , net3 )
delegates , err := GetK8sNetwork ( args , "" , fKubeClient , tmpDir )
Expect ( len ( delegates ) ) . To ( Equal ( 0 ) )
Expect ( err ) . To ( MatchError ( "GetK8sNetwork: failed getting the delegate: getKubernetesDelegate: failed to get network resource, refer Multus README.md for the usage guide: resource not found" ) )
} )
It ( "retrieves delegates from kubernetes using JSON format annotation" , func ( ) {
fakePod := testutils . NewFakePod ( "testpod" , ` [
{ "name" : "net1" } ,
{
"name" : "net2" ,
"ipRequest" : "1.2.3.4" ,
"macRequest" : "aa:bb:cc:dd:ee:ff"
} ,
{
"name" : "net3" ,
"namespace" : "other-ns"
}
] ` )
args := & skel . CmdArgs {
Args : fmt . Sprintf ( "K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s" , fakePod . ObjectMeta . Name , fakePod . ObjectMeta . Namespace ) ,
}
fKubeClient := testutils . NewFakeKubeClient ( )
fKubeClient . AddPod ( fakePod )
fKubeClient . AddNetConfig ( fakePod . ObjectMeta . Namespace , "net1" , ` {
"name" : "net1" ,
"type" : "mynet" ,
"cniVersion" : "0.2.0"
} ` )
fKubeClient . AddNetConfig ( fakePod . ObjectMeta . Namespace , "net2" , ` {
"name" : "net2" ,
"type" : "mynet2" ,
"cniVersion" : "0.2.0"
} ` )
fKubeClient . AddNetConfig ( "other-ns" , "net3" , ` {
"name" : "net3" ,
"type" : "mynet3" ,
"cniVersion" : "0.2.0"
} ` )
delegates , err := GetK8sNetwork ( args , "" , fKubeClient , tmpDir )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
Expect ( fKubeClient . PodCount ) . To ( Equal ( 1 ) )
Expect ( fKubeClient . NetCount ) . To ( Equal ( 3 ) )
Expect ( len ( delegates ) ) . To ( Equal ( 3 ) )
Expect ( delegates [ 0 ] . Name ) . To ( Equal ( "net1" ) )
Expect ( delegates [ 0 ] . Type ) . To ( Equal ( "mynet" ) )
Expect ( delegates [ 1 ] . Name ) . To ( Equal ( "net2" ) )
Expect ( delegates [ 1 ] . Type ) . To ( Equal ( "mynet2" ) )
Expect ( delegates [ 2 ] . Name ) . To ( Equal ( "net3" ) )
Expect ( delegates [ 2 ] . Type ) . To ( Equal ( "mynet3" ) )
} )
It ( "fails when the JSON format annotation is invalid" , func ( ) {
fakePod := testutils . NewFakePod ( "testpod" , "[adsfasdfasdfasf]" )
args := & skel . CmdArgs {
Args : fmt . Sprintf ( "K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s" , fakePod . ObjectMeta . Name , fakePod . ObjectMeta . Namespace ) ,
}
fKubeClient := testutils . NewFakeKubeClient ( )
fKubeClient . AddPod ( fakePod )
delegates , err := GetK8sNetwork ( args , "" , fKubeClient , tmpDir )
Expect ( len ( delegates ) ) . To ( Equal ( 0 ) )
Expect ( err ) . To ( MatchError ( "parsePodNetworkAnnotation: failed to parse pod Network Attachment Selection Annotation JSON format: invalid character 'a' looking for beginning of value" ) )
} )
It ( "retrieves delegates from kubernetes using on-disk config files" , func ( ) {
fakePod := testutils . NewFakePod ( "testpod" , "net1,net2" )
args := & skel . CmdArgs {
Args : fmt . Sprintf ( "K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s" , fakePod . ObjectMeta . Name , fakePod . ObjectMeta . Namespace ) ,
}
fKubeClient := testutils . NewFakeKubeClient ( )
fKubeClient . AddPod ( fakePod )
net1Name := filepath . Join ( tmpDir , "10-net1.conf" )
fKubeClient . AddNetFile ( fakePod . ObjectMeta . Namespace , "net1" , net1Name , ` {
"name" : "net1" ,
"type" : "mynet" ,
"cniVersion" : "0.2.0"
} ` )
net2Name := filepath . Join ( tmpDir , "20-net2.conf" )
fKubeClient . AddNetFile ( fakePod . ObjectMeta . Namespace , "net2" , net2Name , ` {
"name" : "net2" ,
"type" : "mynet2" ,
"cniVersion" : "0.2.0"
} ` )
delegates , err := GetK8sNetwork ( args , "" , fKubeClient , tmpDir )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
Expect ( fKubeClient . PodCount ) . To ( Equal ( 1 ) )
Expect ( fKubeClient . NetCount ) . To ( Equal ( 2 ) )
Expect ( len ( delegates ) ) . To ( Equal ( 2 ) )
Expect ( delegates [ 0 ] . Name ) . To ( Equal ( "net1" ) )
Expect ( delegates [ 0 ] . Type ) . To ( Equal ( "mynet" ) )
Expect ( delegates [ 1 ] . Name ) . To ( Equal ( "net2" ) )
Expect ( delegates [ 1 ] . Type ) . To ( Equal ( "mynet2" ) )
} )
2018-07-19 16:21:31 +00:00
It ( "injects network name into minimal thick plugin CNI config" , func ( ) {
fakePod := testutils . NewFakePod ( "testpod" , "net1" )
args := & skel . CmdArgs {
Args : fmt . Sprintf ( "K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s" , fakePod . ObjectMeta . Name , fakePod . ObjectMeta . Namespace ) ,
}
fKubeClient := testutils . NewFakeKubeClient ( )
fKubeClient . AddPod ( fakePod )
fKubeClient . AddNetConfig ( fakePod . ObjectMeta . Namespace , "net1" , "{\"type\": \"mynet\"}" )
delegates , err := GetK8sNetwork ( args , "" , fKubeClient , tmpDir )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
Expect ( fKubeClient . PodCount ) . To ( Equal ( 1 ) )
Expect ( fKubeClient . NetCount ) . To ( Equal ( 1 ) )
Expect ( len ( delegates ) ) . To ( Equal ( 1 ) )
Expect ( delegates [ 0 ] . Name ) . To ( Equal ( "net1" ) )
Expect ( delegates [ 0 ] . Type ) . To ( Equal ( "mynet" ) )
} )
2018-06-20 02:27:42 +00:00
It ( "fails when on-disk config file is not valid" , func ( ) {
fakePod := testutils . NewFakePod ( "testpod" , "net1,net2" )
args := & skel . CmdArgs {
Args : fmt . Sprintf ( "K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s" , fakePod . ObjectMeta . Name , fakePod . ObjectMeta . Namespace ) ,
}
fKubeClient := testutils . NewFakeKubeClient ( )
fKubeClient . AddPod ( fakePod )
net1Name := filepath . Join ( tmpDir , "10-net1.conf" )
fKubeClient . AddNetFile ( fakePod . ObjectMeta . Namespace , "net1" , net1Name , ` {
"name" : "net1" ,
"type" : "mynet" ,
"cniVersion" : "0.2.0"
} ` )
net2Name := filepath . Join ( tmpDir , "20-net2.conf" )
fKubeClient . AddNetFile ( fakePod . ObjectMeta . Namespace , "net2" , net2Name , "asdfasdfasfdasfd" )
delegates , err := GetK8sNetwork ( args , "" , fKubeClient , tmpDir )
Expect ( len ( delegates ) ) . To ( Equal ( 0 ) )
2018-07-19 16:21:31 +00:00
Expect ( err ) . To ( MatchError ( fmt . Sprintf ( "GetK8sNetwork: failed getting the delegate: cniConfigFromNetworkResource: err in getCNIConfigFromFile: Error loading CNI config file %s: error parsing configuration: invalid character 'a' looking for beginning of value" , net2Name ) ) )
2018-06-20 02:27:42 +00:00
} )
} )