Skip to content

Commit

Permalink
add vip to webhook e2e (#2525)
Browse files Browse the repository at this point in the history
* add vip e2e

* Change variable name

* Update test/e2e/framework/vip.go

Co-authored-by: 张祖建 <zhangzujian.7@gmail.com>

---------

Co-authored-by: yl4811 <yl4811@yealink.com>
Co-authored-by: 张祖建 <zhangzujian.7@gmail.com>
  • Loading branch information
3 people committed Mar 22, 2023
1 parent 30d30bf commit e971095
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 0 deletions.
87 changes: 87 additions & 0 deletions test/e2e/framework/vip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package framework

import (
"context"
apiv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1"
v1 "github.com/kubeovn/kube-ovn/pkg/client/clientset/versioned/typed/kubeovn/v1"
"github.com/kubeovn/kube-ovn/pkg/util"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"time"
)

// VipClient is a struct for vip client.
type VipClient struct {
f *Framework
v1.VipInterface
}

func (f *Framework) VipClient() *VipClient {
return &VipClient{
f: f,
VipInterface: f.KubeOVNClientSet.KubeovnV1().Vips(),
}
}

func (c *VipClient) Get(name string) *apiv1.Vip {
vip, err := c.VipInterface.Get(context.TODO(), name, metav1.GetOptions{})
ExpectNoError(err)
return vip.DeepCopy()
}

// Create creates a new vip according to the framework specifications
func (c *VipClient) Create(pn *apiv1.Vip) *apiv1.Vip {
vip, err := c.VipInterface.Create(context.TODO(), pn, metav1.CreateOptions{})
ExpectNoError(err, "Error creating vip")
return vip.DeepCopy()
}

// Patch patches the vip
func (c *VipClient) Patch(original, modified *apiv1.Vip, timeout time.Duration) *apiv1.Vip {
patch, err := util.GenerateMergePatchPayload(original, modified)
ExpectNoError(err)

var patchedVip *apiv1.Vip
err = wait.PollImmediate(2*time.Second, timeout, func() (bool, error) {
p, err := c.VipInterface.Patch(context.TODO(), original.Name, types.MergePatchType, patch, metav1.PatchOptions{}, "")
if err != nil {
return handleWaitingAPIError(err, false, "patch vip %q", original.Name)
}
patchedVip = p
return true, nil
})
if err == nil {
return patchedVip.DeepCopy()
}

if IsTimeout(err) {
Failf("timed out while retrying to patch vip %s", original.Name)
}
ExpectNoError(maybeTimeoutError(err, "patching vip %s", original.Name))

return nil
}

// Delete deletes a vip if the vip exists
func (c *VipClient) Delete(name string, options metav1.DeleteOptions) {
err := c.VipInterface.Delete(context.TODO(), name, options)
if err != nil && !apierrors.IsNotFound(err) {
Failf("Failed to delete vip %q: %v", name, err)
}
}

func MakeVip(name, subnet, v4ip, v6ip string) *apiv1.Vip {
vip := &apiv1.Vip{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: apiv1.VipSpec{
Subnet: subnet,
V4ip: v4ip,
V6ip: v6ip,
},
}
return vip
}
1 change: 1 addition & 0 deletions test/e2e/webhook/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
// Import tests.
_ "github.com/kubeovn/kube-ovn/test/e2e/webhook/pod"
_ "github.com/kubeovn/kube-ovn/test/e2e/webhook/subnet"
_ "github.com/kubeovn/kube-ovn/test/e2e/webhook/vip"
)

func init() {
Expand Down
86 changes: 86 additions & 0 deletions test/e2e/webhook/vip/vip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package vip

import (
"context"
"fmt"
"github.com/kubeovn/kube-ovn/pkg/util"
"github.com/onsi/ginkgo/v2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"math/big"

apiv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1"
"github.com/kubeovn/kube-ovn/test/e2e/framework"
)

var _ = framework.Describe("[group:webhook-vip]", func() {
f := framework.NewDefaultFramework("webhook-vip")

var vip *apiv1.Vip
var subnet *apiv1.Subnet
var vipClient *framework.VipClient
var subnetClient *framework.SubnetClient
var vipName, subnetName, namespaceName string
var cidr, lastIPv4 string

ginkgo.BeforeEach(func() {
subnetClient = f.SubnetClient()
subnetName = "subnet-" + framework.RandomSuffix()
cidr = framework.RandomCIDR(f.ClusterIpFamily)
cidrV4, _ := util.SplitStringIP(cidr)
if cidrV4 == "" {
lastIPv4 = ""
} else {
lastIPv4, _ = util.LastIP(cidrV4)
}

vipClient = f.VipClient()
subnetClient = f.SubnetClient()
vipName = "vip-" + framework.RandomSuffix()
namespaceName = f.Namespace.Name

ginkgo.By("Creating subnet " + subnetName)
subnet = framework.MakeSubnet(subnetName, "", cidr, "", nil, nil, []string{namespaceName})
subnet = subnetClient.CreateSync(subnet)
})

ginkgo.AfterEach(func() {
ginkgo.By("Deleting vip " + vipName)
vipClient.Delete(vipName, metav1.DeleteOptions{})

ginkgo.By("Deleting subnet " + subnetName)
subnetClient.DeleteSync(subnetName)
})

framework.ConformanceIt("check create vip with different errors", func() {
ginkgo.By("Creating vip " + vipName)
vip = framework.MakeVip(vipName, "", "", "")

ginkgo.By("validating subnet")
vip.Spec.Subnet = ""
_, err := vipClient.VipInterface.Create(context.TODO(), vip, metav1.CreateOptions{})
framework.ExpectError(err, fmt.Errorf("subnet parameter cannot be empty"))

ginkgo.By("validating wrong subnet")
vip.Spec.Subnet = "abc"
_, err = vipClient.VipInterface.Create(context.TODO(), vip, metav1.CreateOptions{})
framework.ExpectError(err, fmt.Errorf("Subnet.kubeovn.io \"%s\" not found", vip.Spec.Subnet))

ginkgo.By("Validating vip usage with wrong v4ip")
vip.Spec.Subnet = subnetName
vip.Spec.V4ip = "10.10.10.10.10"
_, err = vipClient.VipInterface.Create(context.TODO(), vip, metav1.CreateOptions{})
framework.ExpectError(err, fmt.Errorf("%s is not a valid ip", vip.Spec.V4ip))

ginkgo.By("Validating vip usage with wrong v6ip")
vip.Spec.V4ip = ""
vip.Spec.V6ip = "2001:250:207::eff2::2"
_, err = vipClient.VipInterface.Create(context.TODO(), vip, metav1.CreateOptions{})
framework.ExpectError(err, fmt.Errorf("%s is not a valid ip", vip.Spec.V6ip))

ginkgo.By("validate ip not in subnet cidr")
vip.Spec.V6ip = ""
vip.Spec.V4ip = util.BigInt2Ip(big.NewInt(0).Add(util.Ip2BigInt(lastIPv4), big.NewInt(10)))
_, err = vipClient.VipInterface.Create(context.TODO(), vip, metav1.CreateOptions{})
framework.ExpectError(err, fmt.Errorf("%s is not in the range of subnet %s", vip.Spec.V4ip, vip.Spec.Subnet))
})
})

0 comments on commit e971095

Please sign in to comment.