From a4c4291827421335f719b77b325f4e3d1f5115eb Mon Sep 17 00:00:00 2001 From: Yanjun Zhou Date: Tue, 14 Jan 2025 10:11:06 +0800 Subject: [PATCH] Add e2e test for IPBlocksInfo (#983) (#999) Signed-off-by: Yanjun Zhou --- pkg/apis/vpc/v1alpha1/ipblocksinfo_types.go | 1 + .../vpc/v1alpha1/fake/fake_ipblocksinfo.go | 24 +-- .../vpc/v1alpha1/fake/fake_vpc_client.go | 4 +- .../typed/vpc/v1alpha1/ipblocksinfo.go | 14 +- .../typed/vpc/v1alpha1/vpc_client.go | 4 +- .../vpc/v1alpha1/interface.go | 2 +- .../vpc/v1alpha1/ipblocksinfo.go | 13 +- .../vpc/v1alpha1/expansion_generated.go | 4 - .../listers/vpc/v1alpha1/ipblocksinfo.go | 43 +---- test/e2e/framework.go | 7 +- test/e2e/nsx_ipblocksinfo_test.go | 170 ++++++++++++++++++ 11 files changed, 200 insertions(+), 86 deletions(-) create mode 100644 test/e2e/nsx_ipblocksinfo_test.go diff --git a/pkg/apis/vpc/v1alpha1/ipblocksinfo_types.go b/pkg/apis/vpc/v1alpha1/ipblocksinfo_types.go index 77871d0ba..47ab96f8c 100644 --- a/pkg/apis/vpc/v1alpha1/ipblocksinfo_types.go +++ b/pkg/apis/vpc/v1alpha1/ipblocksinfo_types.go @@ -8,6 +8,7 @@ import ( ) // +genclient +// +genclient:nonNamespaced //+kubebuilder:object:root=true //+kubebuilder:resource:scope="Cluster",path=ipblocksinfos diff --git a/pkg/client/clientset/versioned/typed/vpc/v1alpha1/fake/fake_ipblocksinfo.go b/pkg/client/clientset/versioned/typed/vpc/v1alpha1/fake/fake_ipblocksinfo.go index a5261db93..3846ed0a4 100644 --- a/pkg/client/clientset/versioned/typed/vpc/v1alpha1/fake/fake_ipblocksinfo.go +++ b/pkg/client/clientset/versioned/typed/vpc/v1alpha1/fake/fake_ipblocksinfo.go @@ -19,7 +19,6 @@ import ( // FakeIPBlocksInfos implements IPBlocksInfoInterface type FakeIPBlocksInfos struct { Fake *FakeCrdV1alpha1 - ns string } var ipblocksinfosResource = v1alpha1.SchemeGroupVersion.WithResource("ipblocksinfos") @@ -29,8 +28,7 @@ var ipblocksinfosKind = v1alpha1.SchemeGroupVersion.WithKind("IPBlocksInfo") // Get takes name of the iPBlocksInfo, and returns the corresponding iPBlocksInfo object, and an error if there is any. func (c *FakeIPBlocksInfos) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IPBlocksInfo, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(ipblocksinfosResource, c.ns, name), &v1alpha1.IPBlocksInfo{}) - + Invokes(testing.NewRootGetAction(ipblocksinfosResource, name), &v1alpha1.IPBlocksInfo{}) if obj == nil { return nil, err } @@ -40,8 +38,7 @@ func (c *FakeIPBlocksInfos) Get(ctx context.Context, name string, options v1.Get // List takes label and field selectors, and returns the list of IPBlocksInfos that match those selectors. func (c *FakeIPBlocksInfos) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.IPBlocksInfoList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(ipblocksinfosResource, ipblocksinfosKind, c.ns, opts), &v1alpha1.IPBlocksInfoList{}) - + Invokes(testing.NewRootListAction(ipblocksinfosResource, ipblocksinfosKind, opts), &v1alpha1.IPBlocksInfoList{}) if obj == nil { return nil, err } @@ -62,15 +59,13 @@ func (c *FakeIPBlocksInfos) List(ctx context.Context, opts v1.ListOptions) (resu // Watch returns a watch.Interface that watches the requested iPBlocksInfos. func (c *FakeIPBlocksInfos) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { return c.Fake. - InvokesWatch(testing.NewWatchAction(ipblocksinfosResource, c.ns, opts)) - + InvokesWatch(testing.NewRootWatchAction(ipblocksinfosResource, opts)) } // Create takes the representation of a iPBlocksInfo and creates it. Returns the server's representation of the iPBlocksInfo, and an error, if there is any. func (c *FakeIPBlocksInfos) Create(ctx context.Context, iPBlocksInfo *v1alpha1.IPBlocksInfo, opts v1.CreateOptions) (result *v1alpha1.IPBlocksInfo, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(ipblocksinfosResource, c.ns, iPBlocksInfo), &v1alpha1.IPBlocksInfo{}) - + Invokes(testing.NewRootCreateAction(ipblocksinfosResource, iPBlocksInfo), &v1alpha1.IPBlocksInfo{}) if obj == nil { return nil, err } @@ -80,8 +75,7 @@ func (c *FakeIPBlocksInfos) Create(ctx context.Context, iPBlocksInfo *v1alpha1.I // Update takes the representation of a iPBlocksInfo and updates it. Returns the server's representation of the iPBlocksInfo, and an error, if there is any. func (c *FakeIPBlocksInfos) Update(ctx context.Context, iPBlocksInfo *v1alpha1.IPBlocksInfo, opts v1.UpdateOptions) (result *v1alpha1.IPBlocksInfo, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(ipblocksinfosResource, c.ns, iPBlocksInfo), &v1alpha1.IPBlocksInfo{}) - + Invokes(testing.NewRootUpdateAction(ipblocksinfosResource, iPBlocksInfo), &v1alpha1.IPBlocksInfo{}) if obj == nil { return nil, err } @@ -91,14 +85,13 @@ func (c *FakeIPBlocksInfos) Update(ctx context.Context, iPBlocksInfo *v1alpha1.I // Delete takes name of the iPBlocksInfo and deletes it. Returns an error if one occurs. func (c *FakeIPBlocksInfos) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(ipblocksinfosResource, c.ns, name, opts), &v1alpha1.IPBlocksInfo{}) - + Invokes(testing.NewRootDeleteActionWithOptions(ipblocksinfosResource, name, opts), &v1alpha1.IPBlocksInfo{}) return err } // DeleteCollection deletes a collection of objects. func (c *FakeIPBlocksInfos) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(ipblocksinfosResource, c.ns, listOpts) + action := testing.NewRootDeleteCollectionAction(ipblocksinfosResource, listOpts) _, err := c.Fake.Invokes(action, &v1alpha1.IPBlocksInfoList{}) return err @@ -107,8 +100,7 @@ func (c *FakeIPBlocksInfos) DeleteCollection(ctx context.Context, opts v1.Delete // Patch applies the patch and returns the patched iPBlocksInfo. func (c *FakeIPBlocksInfos) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.IPBlocksInfo, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(ipblocksinfosResource, c.ns, name, pt, data, subresources...), &v1alpha1.IPBlocksInfo{}) - + Invokes(testing.NewRootPatchSubresourceAction(ipblocksinfosResource, name, pt, data, subresources...), &v1alpha1.IPBlocksInfo{}) if obj == nil { return nil, err } diff --git a/pkg/client/clientset/versioned/typed/vpc/v1alpha1/fake/fake_vpc_client.go b/pkg/client/clientset/versioned/typed/vpc/v1alpha1/fake/fake_vpc_client.go index f61b00f3d..53e59be08 100644 --- a/pkg/client/clientset/versioned/typed/vpc/v1alpha1/fake/fake_vpc_client.go +++ b/pkg/client/clientset/versioned/typed/vpc/v1alpha1/fake/fake_vpc_client.go @@ -23,8 +23,8 @@ func (c *FakeCrdV1alpha1) IPAddressAllocations(namespace string) v1alpha1.IPAddr return &FakeIPAddressAllocations{c, namespace} } -func (c *FakeCrdV1alpha1) IPBlocksInfos(namespace string) v1alpha1.IPBlocksInfoInterface { - return &FakeIPBlocksInfos{c, namespace} +func (c *FakeCrdV1alpha1) IPBlocksInfos() v1alpha1.IPBlocksInfoInterface { + return &FakeIPBlocksInfos{c} } func (c *FakeCrdV1alpha1) NetworkInfos(namespace string) v1alpha1.NetworkInfoInterface { diff --git a/pkg/client/clientset/versioned/typed/vpc/v1alpha1/ipblocksinfo.go b/pkg/client/clientset/versioned/typed/vpc/v1alpha1/ipblocksinfo.go index a0eaf084a..8eb80ac7d 100644 --- a/pkg/client/clientset/versioned/typed/vpc/v1alpha1/ipblocksinfo.go +++ b/pkg/client/clientset/versioned/typed/vpc/v1alpha1/ipblocksinfo.go @@ -20,7 +20,7 @@ import ( // IPBlocksInfosGetter has a method to return a IPBlocksInfoInterface. // A group's client should implement this interface. type IPBlocksInfosGetter interface { - IPBlocksInfos(namespace string) IPBlocksInfoInterface + IPBlocksInfos() IPBlocksInfoInterface } // IPBlocksInfoInterface has methods to work with IPBlocksInfo resources. @@ -39,14 +39,12 @@ type IPBlocksInfoInterface interface { // iPBlocksInfos implements IPBlocksInfoInterface type iPBlocksInfos struct { client rest.Interface - ns string } // newIPBlocksInfos returns a IPBlocksInfos -func newIPBlocksInfos(c *CrdV1alpha1Client, namespace string) *iPBlocksInfos { +func newIPBlocksInfos(c *CrdV1alpha1Client) *iPBlocksInfos { return &iPBlocksInfos{ client: c.RESTClient(), - ns: namespace, } } @@ -54,7 +52,6 @@ func newIPBlocksInfos(c *CrdV1alpha1Client, namespace string) *iPBlocksInfos { func (c *iPBlocksInfos) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IPBlocksInfo, err error) { result = &v1alpha1.IPBlocksInfo{} err = c.client.Get(). - Namespace(c.ns). Resource("ipblocksinfos"). Name(name). VersionedParams(&options, scheme.ParameterCodec). @@ -71,7 +68,6 @@ func (c *iPBlocksInfos) List(ctx context.Context, opts v1.ListOptions) (result * } result = &v1alpha1.IPBlocksInfoList{} err = c.client.Get(). - Namespace(c.ns). Resource("ipblocksinfos"). VersionedParams(&opts, scheme.ParameterCodec). Timeout(timeout). @@ -88,7 +84,6 @@ func (c *iPBlocksInfos) Watch(ctx context.Context, opts v1.ListOptions) (watch.I } opts.Watch = true return c.client.Get(). - Namespace(c.ns). Resource("ipblocksinfos"). VersionedParams(&opts, scheme.ParameterCodec). Timeout(timeout). @@ -99,7 +94,6 @@ func (c *iPBlocksInfos) Watch(ctx context.Context, opts v1.ListOptions) (watch.I func (c *iPBlocksInfos) Create(ctx context.Context, iPBlocksInfo *v1alpha1.IPBlocksInfo, opts v1.CreateOptions) (result *v1alpha1.IPBlocksInfo, err error) { result = &v1alpha1.IPBlocksInfo{} err = c.client.Post(). - Namespace(c.ns). Resource("ipblocksinfos"). VersionedParams(&opts, scheme.ParameterCodec). Body(iPBlocksInfo). @@ -112,7 +106,6 @@ func (c *iPBlocksInfos) Create(ctx context.Context, iPBlocksInfo *v1alpha1.IPBlo func (c *iPBlocksInfos) Update(ctx context.Context, iPBlocksInfo *v1alpha1.IPBlocksInfo, opts v1.UpdateOptions) (result *v1alpha1.IPBlocksInfo, err error) { result = &v1alpha1.IPBlocksInfo{} err = c.client.Put(). - Namespace(c.ns). Resource("ipblocksinfos"). Name(iPBlocksInfo.Name). VersionedParams(&opts, scheme.ParameterCodec). @@ -125,7 +118,6 @@ func (c *iPBlocksInfos) Update(ctx context.Context, iPBlocksInfo *v1alpha1.IPBlo // Delete takes name of the iPBlocksInfo and deletes it. Returns an error if one occurs. func (c *iPBlocksInfos) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { return c.client.Delete(). - Namespace(c.ns). Resource("ipblocksinfos"). Name(name). Body(&opts). @@ -140,7 +132,6 @@ func (c *iPBlocksInfos) DeleteCollection(ctx context.Context, opts v1.DeleteOpti timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second } return c.client.Delete(). - Namespace(c.ns). Resource("ipblocksinfos"). VersionedParams(&listOpts, scheme.ParameterCodec). Timeout(timeout). @@ -153,7 +144,6 @@ func (c *iPBlocksInfos) DeleteCollection(ctx context.Context, opts v1.DeleteOpti func (c *iPBlocksInfos) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.IPBlocksInfo, err error) { result = &v1alpha1.IPBlocksInfo{} err = c.client.Patch(pt). - Namespace(c.ns). Resource("ipblocksinfos"). Name(name). SubResource(subresources...). diff --git a/pkg/client/clientset/versioned/typed/vpc/v1alpha1/vpc_client.go b/pkg/client/clientset/versioned/typed/vpc/v1alpha1/vpc_client.go index d7ba28a5f..011472244 100644 --- a/pkg/client/clientset/versioned/typed/vpc/v1alpha1/vpc_client.go +++ b/pkg/client/clientset/versioned/typed/vpc/v1alpha1/vpc_client.go @@ -40,8 +40,8 @@ func (c *CrdV1alpha1Client) IPAddressAllocations(namespace string) IPAddressAllo return newIPAddressAllocations(c, namespace) } -func (c *CrdV1alpha1Client) IPBlocksInfos(namespace string) IPBlocksInfoInterface { - return newIPBlocksInfos(c, namespace) +func (c *CrdV1alpha1Client) IPBlocksInfos() IPBlocksInfoInterface { + return newIPBlocksInfos(c) } func (c *CrdV1alpha1Client) NetworkInfos(namespace string) NetworkInfoInterface { diff --git a/pkg/client/informers/externalversions/vpc/v1alpha1/interface.go b/pkg/client/informers/externalversions/vpc/v1alpha1/interface.go index 296d61738..1cf4be4a5 100644 --- a/pkg/client/informers/externalversions/vpc/v1alpha1/interface.go +++ b/pkg/client/informers/externalversions/vpc/v1alpha1/interface.go @@ -56,7 +56,7 @@ func (v *version) IPAddressAllocations() IPAddressAllocationInformer { // IPBlocksInfos returns a IPBlocksInfoInformer. func (v *version) IPBlocksInfos() IPBlocksInfoInformer { - return &iPBlocksInfoInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} + return &iPBlocksInfoInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } // NetworkInfos returns a NetworkInfoInformer. diff --git a/pkg/client/informers/externalversions/vpc/v1alpha1/ipblocksinfo.go b/pkg/client/informers/externalversions/vpc/v1alpha1/ipblocksinfo.go index 85e31e728..887d2a42b 100644 --- a/pkg/client/informers/externalversions/vpc/v1alpha1/ipblocksinfo.go +++ b/pkg/client/informers/externalversions/vpc/v1alpha1/ipblocksinfo.go @@ -29,33 +29,32 @@ type IPBlocksInfoInformer interface { type iPBlocksInfoInformer struct { factory internalinterfaces.SharedInformerFactory tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string } // NewIPBlocksInfoInformer constructs a new informer for IPBlocksInfo type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. -func NewIPBlocksInfoInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredIPBlocksInfoInformer(client, namespace, resyncPeriod, indexers, nil) +func NewIPBlocksInfoInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredIPBlocksInfoInformer(client, resyncPeriod, indexers, nil) } // NewFilteredIPBlocksInfoInformer constructs a new informer for IPBlocksInfo type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. -func NewFilteredIPBlocksInfoInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { +func NewFilteredIPBlocksInfoInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { return cache.NewSharedIndexInformer( &cache.ListWatch{ ListFunc: func(options v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.CrdV1alpha1().IPBlocksInfos(namespace).List(context.TODO(), options) + return client.CrdV1alpha1().IPBlocksInfos().List(context.TODO(), options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.CrdV1alpha1().IPBlocksInfos(namespace).Watch(context.TODO(), options) + return client.CrdV1alpha1().IPBlocksInfos().Watch(context.TODO(), options) }, }, &vpcv1alpha1.IPBlocksInfo{}, @@ -65,7 +64,7 @@ func NewFilteredIPBlocksInfoInformer(client versioned.Interface, namespace strin } func (f *iPBlocksInfoInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredIPBlocksInfoInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewFilteredIPBlocksInfoInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) } func (f *iPBlocksInfoInformer) Informer() cache.SharedIndexInformer { diff --git a/pkg/client/listers/vpc/v1alpha1/expansion_generated.go b/pkg/client/listers/vpc/v1alpha1/expansion_generated.go index 3b5ef6f01..7d06e88a3 100644 --- a/pkg/client/listers/vpc/v1alpha1/expansion_generated.go +++ b/pkg/client/listers/vpc/v1alpha1/expansion_generated.go @@ -25,10 +25,6 @@ type IPAddressAllocationNamespaceListerExpansion interface{} // IPBlocksInfoLister. type IPBlocksInfoListerExpansion interface{} -// IPBlocksInfoNamespaceListerExpansion allows custom methods to be added to -// IPBlocksInfoNamespaceLister. -type IPBlocksInfoNamespaceListerExpansion interface{} - // NetworkInfoListerExpansion allows custom methods to be added to // NetworkInfoLister. type NetworkInfoListerExpansion interface{} diff --git a/pkg/client/listers/vpc/v1alpha1/ipblocksinfo.go b/pkg/client/listers/vpc/v1alpha1/ipblocksinfo.go index ea1e283ac..678bd83e0 100644 --- a/pkg/client/listers/vpc/v1alpha1/ipblocksinfo.go +++ b/pkg/client/listers/vpc/v1alpha1/ipblocksinfo.go @@ -18,8 +18,9 @@ type IPBlocksInfoLister interface { // List lists all IPBlocksInfos in the indexer. // Objects returned here must be treated as read-only. List(selector labels.Selector) (ret []*v1alpha1.IPBlocksInfo, err error) - // IPBlocksInfos returns an object that can list and get IPBlocksInfos. - IPBlocksInfos(namespace string) IPBlocksInfoNamespaceLister + // Get retrieves the IPBlocksInfo from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.IPBlocksInfo, error) IPBlocksInfoListerExpansion } @@ -41,41 +42,9 @@ func (s *iPBlocksInfoLister) List(selector labels.Selector) (ret []*v1alpha1.IPB return ret, err } -// IPBlocksInfos returns an object that can list and get IPBlocksInfos. -func (s *iPBlocksInfoLister) IPBlocksInfos(namespace string) IPBlocksInfoNamespaceLister { - return iPBlocksInfoNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// IPBlocksInfoNamespaceLister helps list and get IPBlocksInfos. -// All objects returned here must be treated as read-only. -type IPBlocksInfoNamespaceLister interface { - // List lists all IPBlocksInfos in the indexer for a given namespace. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.IPBlocksInfo, err error) - // Get retrieves the IPBlocksInfo from the indexer for a given namespace and name. - // Objects returned here must be treated as read-only. - Get(name string) (*v1alpha1.IPBlocksInfo, error) - IPBlocksInfoNamespaceListerExpansion -} - -// iPBlocksInfoNamespaceLister implements the IPBlocksInfoNamespaceLister -// interface. -type iPBlocksInfoNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all IPBlocksInfos in the indexer for a given namespace. -func (s iPBlocksInfoNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.IPBlocksInfo, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.IPBlocksInfo)) - }) - return ret, err -} - -// Get retrieves the IPBlocksInfo from the indexer for a given namespace and name. -func (s iPBlocksInfoNamespaceLister) Get(name string) (*v1alpha1.IPBlocksInfo, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) +// Get retrieves the IPBlocksInfo from the index for a given name. +func (s *iPBlocksInfoLister) Get(name string) (*v1alpha1.IPBlocksInfo, error) { + obj, exists, err := s.indexer.GetByKey(name) if err != nil { return nil, err } diff --git a/test/e2e/framework.go b/test/e2e/framework.go index 9534b070a..1a15ca396 100644 --- a/test/e2e/framework.go +++ b/test/e2e/framework.go @@ -643,15 +643,12 @@ func deleteYAML(filename string, ns string) error { // tags should be present in pairs, the first tag is the scope, the second tag is the value // caller should transform the response to the expected resource type func (data *TestData) queryResource(resourceType string, tags []string) (model.SearchResponse, error) { - tagScopeClusterKey := strings.Replace(common.TagScopeNamespace, "/", "\\/", -1) - tagScopeClusterValue := strings.Replace(tags[0], ":", "\\:", -1) - tagParam := fmt.Sprintf("tags.scope:%s AND tags.tag:%s", tagScopeClusterKey, tagScopeClusterValue) resourceParam := fmt.Sprintf("%s:%s", common.ResourceType, resourceType) - queryParam := resourceParam + " AND " + tagParam + queryParam := resourceParam if len(tags) >= 2 { tagscope := strings.Replace(tags[0], "/", "\\/", -1) tagtag := strings.Replace(tags[1], ":", "\\:", -1) - tagParam = fmt.Sprintf("tags.scope:%s AND tags.tag:%s", tagscope, tagtag) + tagParam := fmt.Sprintf("tags.scope:%s AND tags.tag:%s", tagscope, tagtag) queryParam = resourceParam + " AND " + tagParam } queryParam += " AND marked_for_delete:false" diff --git a/test/e2e/nsx_ipblocksinfo_test.go b/test/e2e/nsx_ipblocksinfo_test.go new file mode 100644 index 000000000..54c8b3b0f --- /dev/null +++ b/test/e2e/nsx_ipblocksinfo_test.go @@ -0,0 +1,170 @@ +package e2e + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/require" + "github.com/vmware/vsphere-automation-sdk-go/services/nsxt/model" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + + "github.com/vmware-tanzu/nsx-operator/pkg/apis/vpc/v1alpha1" + "github.com/vmware-tanzu/nsx-operator/pkg/nsx/services/common" + nsxutil "github.com/vmware-tanzu/nsx-operator/pkg/nsx/util" +) + +var ( + ipBlocksInfoCRDName = "ip-blocks-info" + defaultOrg = "default" + defaultProject = "project-quality" + defaultVPCProfile = "default" +) + +func TestIPBlocksInfo(t *testing.T) { + t.Run("case=InitialIPBlocksInfo", InitialIPBlocksInfo) + t.Run("case=CustomIPBlocksInfo", CustomIPBlocksInfo) +} + +func InitialIPBlocksInfo(t *testing.T) { + privateTGWIPCIDRs, externalIPCIDRs := getDefaultIPBlocksCidrs(t) + assertIPBlocksInfo(t, privateTGWIPCIDRs, externalIPCIDRs) +} + +func CustomIPBlocksInfo(t *testing.T) { + // Create Private IPBlocks + ipBlockName := "ipblocksinfo-test-10.0.0.0-netmask-28" + ipBlockCidr := "10.0.0.0/28" + err := testData.nsxClient.IPBlockClient.Patch(defaultOrg, defaultProject, ipBlockName, model.IpAddressBlock{ + Cidr: &ipBlockCidr, + Visibility: common.String("PRIVATE"), + }) + require.NoError(t, err) + defer func() { + testData.nsxClient.IPBlockClient.Delete(defaultOrg, defaultProject, ipBlockName) + }() + + // Create VPC Connectivity Profile + vpcProfileName := "ipblocksinfo-test" + vpcProfile, err := testData.nsxClient.VPCConnectivityProfilesClient.Get(defaultOrg, defaultProject, defaultVPCProfile) + require.NoError(t, err) + err = testData.nsxClient.VPCConnectivityProfilesClient.Patch(defaultOrg, defaultProject, vpcProfileName, model.VpcConnectivityProfile{ + TransitGatewayPath: vpcProfile.TransitGatewayPath, + ExternalIpBlocks: vpcProfile.ExternalIpBlocks, + PrivateTgwIpBlocks: []string{fmt.Sprintf("/orgs/%s/projects/%s/infra/ip-blocks/%s", defaultOrg, defaultProject, ipBlockName)}, + }) + require.NoError(t, err) + defer func() { + err := testData.nsxClient.VPCConnectivityProfilesClient.Delete(defaultOrg, defaultProject, vpcProfileName) + require.NoError(t, err) + }() + + // Create VPC with the profile above + vpcId := "ipblocks-info-test" + err = testData.nsxClient.VPCClient.Patch(defaultOrg, defaultProject, vpcId, model.Vpc{}) + require.NoError(t, err) + vpcAttachmentId := "default" + err = testData.nsxClient.VpcAttachmentClient.Patch(defaultOrg, defaultProject, vpcId, vpcAttachmentId, model.VpcAttachment{ + VpcConnectivityProfile: common.String(fmt.Sprintf("/orgs/%s/projects/%s/vpc-connectivity-profiles/%s", defaultOrg, defaultProject, vpcProfileName)), + }) + require.NoError(t, err) + defer func() { + err := testData.nsxClient.VpcAttachmentClient.Delete(defaultOrg, defaultProject, vpcId, vpcAttachmentId) + require.NoError(t, err) + }() + + // Create VPCNetworkConfigurations + vpcConfigName := "vpc-config-ipblocks-info" + _, err = testData.crdClientset.CrdV1alpha1().VPCNetworkConfigurations().Create(context.TODO(), &v1alpha1.VPCNetworkConfiguration{ + ObjectMeta: metav1.ObjectMeta{ + Name: vpcConfigName, + }, + Spec: v1alpha1.VPCNetworkConfigurationSpec{ + NSXProject: fmt.Sprintf("/orgs/%s/projects/%s", defaultOrg, defaultProject), + VPC: vpcId, + }, + }, metav1.CreateOptions{}) + require.NoError(t, err) + + privateTGWIPCIDRs, externalIPCIDRs := getDefaultIPBlocksCidrs(t) + defer func() { + // Delete VPCNetworkConfigurations and check + err = testData.crdClientset.CrdV1alpha1().VPCNetworkConfigurations().Delete(context.TODO(), vpcConfigName, metav1.DeleteOptions{}) + require.NoError(t, err) + assertIPBlocksInfo(t, privateTGWIPCIDRs, externalIPCIDRs) + }() + + // Check IPBlocksInfo + updatedPrivateTGWIPCIDRs := append(privateTGWIPCIDRs, ipBlockCidr) + assertIPBlocksInfo(t, updatedPrivateTGWIPCIDRs, externalIPCIDRs) +} + +func getDefaultIPBlocksCidrs(t *testing.T) (privateTGWIPCIDRs []string, externalIPCIDRs []string) { + vpcProfile, err := testData.nsxClient.VPCConnectivityProfilesClient.Get(defaultOrg, defaultProject, defaultVPCProfile) + require.NoError(t, err) + // Assume only one ipblock in default VPC Connectivity Profile + externalBlock := vpcProfile.ExternalIpBlocks[0] + privateTGWBlock := vpcProfile.PrivateTgwIpBlocks[0] + + results, err := testData.queryResource(common.ResourceTypeIPBlock, []string{}) + require.NoError(t, err) + res := transSearchResponsetoIPBlock(results) + count := 0 + for _, ipblock := range res { + if count >= 2 { + break + } + if *ipblock.Path == externalBlock { + externalIPCIDRs = append(externalIPCIDRs, *ipblock.Cidr) + count++ + } + if *ipblock.Path == privateTGWBlock { + privateTGWIPCIDRs = append(privateTGWIPCIDRs, *ipblock.Cidr) + count++ + } + } + return +} + +func assertIPBlocksInfo(t *testing.T, privateTGWIPCIDRs []string, externalIPCIDRs []string) { + deadlineCtx, deadlineCancel := context.WithTimeout(context.Background(), defaultTimeout) + defer deadlineCancel() + err := wait.PollUntilContextTimeout(deadlineCtx, 1*time.Second, defaultTimeout, false, func(ctx context.Context) (done bool, err error) { + res, err := testData.crdClientset.CrdV1alpha1().IPBlocksInfos().Get(context.TODO(), ipBlocksInfoCRDName, metav1.GetOptions{}) + if err != nil { + if errors.IsNotFound(err) { + return false, nil + } + log.Error(err, "Error fetching IPBlocksInfo", "IPBlocksInfo", res, "Name", ipBlocksInfoCRDName) + return false, fmt.Errorf("error when waiting for IPBlocksInfo") + } + log.V(2).Info("IPBlocksInfo cidrs", "externalIPCIDRs", res.ExternalIPCIDRs, "privateTGWIPCIDRs", res.PrivateTGWIPCIDRs) + if nsxutil.CompareArraysWithoutOrder(res.ExternalIPCIDRs, externalIPCIDRs) && nsxutil.CompareArraysWithoutOrder(res.PrivateTGWIPCIDRs, privateTGWIPCIDRs) { + return true, nil + } + return false, nil + }) + require.NoError(t, err) + return +} + +func transSearchResponsetoIPBlock(response model.SearchResponse) []model.IpAddressBlock { + var resources []model.IpAddressBlock + if response.Results == nil { + return resources + } + for _, result := range response.Results { + obj, err := common.NewConverter().ConvertToGolang(result, model.IpAddressBlockBindingType()) + if err != nil { + log.Info("Failed to convert to golang subnet", "error", err) + return resources + } + if ipblock, ok := obj.(model.IpAddressBlock); ok { + resources = append(resources, ipblock) + } + } + return resources +}