Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add e2e regarding ippool.spec.multusName affinity. #2420

Merged
merged 1 commit into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions test/doc/ippoolcr.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
| D00006 | Successfully create and delete IPPools in batch | p2 | | done | |
| D00007 | Add, delete, modify, and query ippools that are created manually | p1 | | done | |
| D00008 | Manually ippool inherits subnet attributes (including routes, vlanId, etc.) | p3 | | | |
| D00009 | multusName matches, IP can be assigned | p2 | | | |
| D00010 | multusName mismatch, unable to assign IP | p3 | | | |
| D00009 | multusName matches, IP can be assigned | p2 | | done | |
| D00010 | multusName mismatch, unable to assign IP | p3 | | done | |
| D00011 | The node where the pod is located matches the nodeName, and the IP can be assigned | p2 | | | |
| D00012 | The node where the pod resides does not match the nodeName, and the IP cannot be assigned | p3 | | | |
| D00013 | nodeName has higher priority than nodeAffinity | p3 | | | |
Expand Down
158 changes: 158 additions & 0 deletions test/e2e/ippoolcr/ippoolcr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (
"github.com/spidernet-io/e2eframework/tools"
"github.com/spidernet-io/spiderpool/pkg/types"
"github.com/spidernet-io/spiderpool/test/e2e/common"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ = Describe("test ippool CR", Label("ippoolCR"), func() {
Expand Down Expand Up @@ -422,4 +424,160 @@ var _ = Describe("test ippool CR", Label("ippoolCR"), func() {
GinkgoWriter.Printf("Time cost to delete %v ipv6 ippools is %v \n", ippoolNumber, endT4)
}
})

Context("Test multusName affinity", func() {
var namespace, v4PoolName, v6PoolName, dsName, spiderMultusNadName string
var iPv4PoolObj, iPv6PoolObj *spiderpoolv2beta1.SpiderIPPool
var v4SubnetName, v6SubnetName string
var v4SubnetObject, v6SubnetObject *spiderpoolv2beta1.SpiderSubnet
var spiderMultusConfig *spiderpoolv2beta1.SpiderMultusConfig

BeforeEach(func() {
dsName = "ds-" + common.GenerateString(10, true)
namespace = "ns" + tools.RandomName()
spiderMultusNadName = "test-multus-" + common.GenerateString(10, true)

err := frame.CreateNamespaceUntilDefaultServiceAccountReady(namespace, common.ServiceAccountReadyTimeout)
GinkgoWriter.Printf("create namespace %v. \n", namespace)
Expect(err).NotTo(HaveOccurred())

ctx, cancel := context.WithTimeout(context.Background(), common.PodStartTimeout)
defer cancel()
if frame.Info.IpV4Enabled {
v4PoolName, iPv4PoolObj = common.GenerateExampleIpv4poolObject(1)
// Associate ip pool with multus name
iPv4PoolObj.Spec.MultusName = []string{spiderMultusNadName}
if frame.Info.SpiderSubnetEnabled {
v4SubnetName, v4SubnetObject = common.GenerateExampleV4SubnetObject(frame, len(frame.Info.KindNodeList))
Expect(v4SubnetObject).NotTo(BeNil())
Expect(common.CreateSubnet(frame, v4SubnetObject)).NotTo(HaveOccurred())
err = common.CreateIppoolInSpiderSubnet(ctx, frame, v4SubnetName, iPv4PoolObj, len(frame.Info.KindNodeList))
} else {
err = common.CreateIppool(frame, iPv4PoolObj)
}
Expect(err).NotTo(HaveOccurred(), "Failed to create v4 Pool %v \n", v4PoolName)
}

if frame.Info.IpV6Enabled {
v6PoolName, iPv6PoolObj = common.GenerateExampleIpv6poolObject(len(frame.Info.KindNodeList))
// Associate ip pool with multus name
iPv6PoolObj.Spec.MultusName = []string{spiderMultusNadName}
if frame.Info.SpiderSubnetEnabled {
v6SubnetName, v6SubnetObject = common.GenerateExampleV6SubnetObject(frame, len(frame.Info.KindNodeList))
Expect(v6SubnetObject).NotTo(BeNil())
Expect(common.CreateSubnet(frame, v6SubnetObject)).NotTo(HaveOccurred())
err = common.CreateIppoolInSpiderSubnet(ctx, frame, v6SubnetName, iPv6PoolObj, len(frame.Info.KindNodeList))
} else {
err = common.CreateIppool(frame, iPv6PoolObj)
}
Expect(err).NotTo(HaveOccurred(), "Failed to create v6 Pool %v \n", v6PoolName)
}

spiderMultusConfig = &spiderpoolv2beta1.SpiderMultusConfig{
ObjectMeta: metav1.ObjectMeta{
Name: spiderMultusNadName,
Namespace: namespace,
},
Spec: spiderpoolv2beta1.MultusCNIConfigSpec{
CniType: "macvlan",
MacvlanConfig: &spiderpoolv2beta1.SpiderMacvlanCniConfig{
Master: []string{common.NIC1},
SpiderpoolConfigPools: &spiderpoolv2beta1.SpiderpoolPools{
IPv4IPPool: []string{v4PoolName},
IPv6IPPool: []string{v6PoolName},
},
},
CoordinatorConfig: &spiderpoolv2beta1.CoordinatorSpec{},
},
}
GinkgoWriter.Printf("Generate spiderMultusConfig %v \n", spiderMultusConfig)
Expect(frame.CreateSpiderMultusInstance(spiderMultusConfig)).NotTo(HaveOccurred())
GinkgoWriter.Printf("Create spidermultus config %v/%v \n", namespace, spiderMultusNadName)

DeferCleanup(func() {
if CurrentSpecReport().Failed() {
GinkgoWriter.Println("If the use case fails, the cleanup step will be skipped")
return
}
GinkgoWriter.Printf("delete namespace %v. \n", namespace)
Expect(frame.DeleteNamespace(namespace)).NotTo(HaveOccurred())

if frame.Info.IpV4Enabled {
Expect(common.DeleteIPPoolByName(frame, v4PoolName)).NotTo(HaveOccurred())
if frame.Info.SpiderSubnetEnabled {
Expect(common.DeleteSubnetByName(frame, v4SubnetName)).NotTo(HaveOccurred())
}
}
if frame.Info.IpV6Enabled {
Expect(common.DeleteIPPoolByName(frame, v6PoolName)).NotTo(HaveOccurred())
if frame.Info.SpiderSubnetEnabled {
Expect(common.DeleteSubnetByName(frame, v6SubnetName)).NotTo(HaveOccurred())
}
}
})
})

It("IPPool can be allocated if it is compatible with multus, but cannot be allocated if it is not compatible.", Label("D00009", "D00010"), func() {
// Generate daemonset yaml and annotation
dsObject := common.GenerateExampleDaemonSetYaml(dsName, namespace)
dsObject.Spec.Template.Annotations = map[string]string{common.MultusDefaultNetwork: fmt.Sprintf("%s/%s", namespace, spiderMultusNadName)}
GinkgoWriter.Printf("Try to create daemonset: %v/%v \n", namespace, dsName)
Expect(frame.CreateDaemonSet(dsObject)).NotTo(HaveOccurred())

GinkgoWriter.Println("multusName has affinity with IPPool and can assign IP")
Eventually(func() bool {
podList, err := frame.GetPodListByLabel(dsObject.Spec.Template.Labels)
if err != nil {
GinkgoWriter.Printf("failed to get pod list by label, error is %v", err)
return false
}
return frame.CheckPodListRunning(podList)
}, common.ResourceDeleteTimeout, common.ForcedWaitingTime).Should(BeTrue())

// Create a set of daemonset again, use the default multus cr, and specify the pool with affinity to other multus cr.
// The daemonset will fail to create and the event will be as expected.
var unAffinityDsName = "un-affinit-ds-" + common.GenerateString(10, true)
unAffinityDsObject := common.GenerateExampleDaemonSetYaml(unAffinityDsName, namespace)
ippoolAnno := types.AnnoPodIPPoolValue{}
if frame.Info.IpV4Enabled {
ippoolAnno.IPv4Pools = []string{v4PoolName}
}
if frame.Info.IpV6Enabled {
ippoolAnno.IPv6Pools = []string{v6PoolName}
}
ippoolAnnoMarshal, err := json.Marshal(ippoolAnno)
Expect(err).NotTo(HaveOccurred())
unAffinityDsObject.Spec.Template.Annotations = map[string]string{constant.AnnoPodIPPool: string(ippoolAnnoMarshal)}
GinkgoWriter.Printf("Try to create daemonset: %v/%v \n", namespace, unAffinityDsName)
Expect(frame.CreateDaemonSet(unAffinityDsObject)).NotTo(HaveOccurred())

var podList *corev1.PodList
Eventually(func() bool {
podList, err = frame.GetPodListByLabel(unAffinityDsObject.Spec.Template.Labels)
if err != nil {
GinkgoWriter.Printf("failed to get pod list by label, error is %v", err)
return false
}
if len(podList.Items) != len(frame.Info.KindNodeList) {
return false
}
return true
}, common.ResourceDeleteTimeout, common.ForcedWaitingTime).Should(BeTrue())

var unmacthedMultusCRString string
if frame.Info.IpV6Enabled && !frame.Info.IpV4Enabled {
unmacthedMultusCRString = fmt.Sprintf("interface eth0 IPPool %v specified multusName [%v] unmacthed multusCR", v6PoolName, spiderMultusNadName)
} else {
unmacthedMultusCRString = fmt.Sprintf("interface eth0 IPPool %v specified multusName [%v] unmacthed multusCR", v4PoolName, spiderMultusNadName)
}

GinkgoWriter.Println("multusName has no affinity with IPPool and cannot assign IP")
for _, pod := range podList.Items {
ctx, cancel := context.WithTimeout(context.Background(), common.EventOccurTimeout)
defer cancel()
err = frame.WaitExceptEventOccurred(ctx, common.OwnerPod, pod.Name, pod.Namespace, unmacthedMultusCRString)
Expect(err).NotTo(HaveOccurred(), "Failedto get event, error is %v", err)
}
})
})
})