From 0809b2925f66c34387cee42579f132f5cd54299b Mon Sep 17 00:00:00 2001 From: Erik F <16261515+erikfuller@users.noreply.github.com> Date: Fri, 8 Sep 2023 13:51:35 -0700 Subject: [PATCH 1/2] Removal of service cache. Err on items not found by name. Use sdk auto-paging methods. --- cmd/aws-application-networking-k8s/main.go | 2 +- controllers/gateway_controller.go | 9 +- controllers/route_controller.go | 41 ++- pkg/aws/services/vpclattice.go | 212 ++++++----- pkg/aws/services/vpclattice_mocks.go | 15 + pkg/aws/services/vpclattice_test.go | 282 ++++++++++++--- pkg/deploy/lattice/error.go | 6 +- pkg/deploy/lattice/listener_manager.go | 70 ++-- pkg/deploy/lattice/listener_manager_mock.go | 15 + pkg/deploy/lattice/listener_manager_test.go | 48 +-- pkg/deploy/lattice/listener_synthesizer.go | 24 +- .../lattice/listener_synthesizer_test.go | 18 +- pkg/deploy/lattice/rule_manager.go | 34 +- pkg/deploy/lattice/rule_manager_mock.go | 15 + pkg/deploy/lattice/rule_manager_test.go | 51 ++- pkg/deploy/lattice/rule_synthesizer.go | 10 +- pkg/deploy/lattice/rule_synthesizer_test.go | 20 +- pkg/deploy/lattice/service_manager.go | 34 +- pkg/deploy/lattice/service_manager_test.go | 17 +- pkg/deploy/lattice/service_network_manager.go | 37 +- .../lattice/service_network_manager_test.go | 14 +- .../lattice/service_network_synthesizer.go | 3 +- pkg/deploy/lattice/service_synthesizer.go | 4 - .../lattice/service_synthesizer_test.go | 6 - pkg/deploy/stack_deployer.go | 6 +- pkg/deploy/stack_deployer_test.go | 85 +++-- pkg/latticestore/latticestore.go | 135 +------ pkg/latticestore/latticestore_test.go | 66 ---- pkg/model/lattice/service.go | 4 +- pkg/utils/common.go | 5 + test/pkg/test/framework.go | 331 ++---------------- test/pkg/test/gateway.go | 4 +- test/pkg/test/grpc_helloworld.go | 3 - test/pkg/test/grpcbin.go | 4 - test/pkg/test/grpcroute.go | 4 - test/pkg/test/header_match_httproute.go | 4 - test/pkg/test/httpapp.go | 3 - test/pkg/test/method_match_httproute.go | 6 +- test/pkg/test/nginxapp.go | 5 - test/pkg/test/path_match_httproute.go | 4 - test/pkg/test/service_export_import.go | 3 - test/pkg/test/weighted_routing_httproute.go | 4 - .../integration/defined_target_ports_test.go | 5 +- 43 files changed, 738 insertions(+), 930 deletions(-) diff --git a/cmd/aws-application-networking-k8s/main.go b/cmd/aws-application-networking-k8s/main.go index 3e5a26d8..d654fa97 100644 --- a/cmd/aws-application-networking-k8s/main.go +++ b/cmd/aws-application-networking-k8s/main.go @@ -155,7 +155,7 @@ func main() { setupLog.Fatalf("gateway-class controller setup failed: %s", err) } - err = controllers.RegisterGatewayController(ctrlLog.Named("gateway"), cloud, latticeDataStore, finalizerManager, mgr) + err = controllers.RegisterGatewayController(ctrlLog.Named("gateway"), cloud, finalizerManager, mgr) if err != nil { setupLog.Fatalf("gateway controller setup failed: %s", err) } diff --git a/controllers/gateway_controller.go b/controllers/gateway_controller.go index 47b681fb..369a27e0 100644 --- a/controllers/gateway_controller.go +++ b/controllers/gateway_controller.go @@ -24,7 +24,6 @@ import ( "github.com/aws/aws-application-networking-k8s/pkg/deploy" "github.com/aws/aws-application-networking-k8s/pkg/gateway" "github.com/aws/aws-application-networking-k8s/pkg/k8s" - "github.com/aws/aws-application-networking-k8s/pkg/latticestore" "github.com/aws/aws-application-networking-k8s/pkg/model/core" latticemodel "github.com/aws/aws-application-networking-k8s/pkg/model/lattice" lattice_runtime "github.com/aws/aws-application-networking-k8s/pkg/runtime" @@ -60,14 +59,12 @@ type GatewayReconciler struct { modelBuilder gateway.ServiceNetworkModelBuilder stackDeployer deploy.StackDeployer cloud aws.Cloud - datastore *latticestore.LatticeDataStore stackMarshaller deploy.StackMarshaller } func RegisterGatewayController( log gwlog.Logger, cloud aws.Cloud, - datastore *latticestore.LatticeDataStore, finalizerManager k8s.FinalizerManager, mgr ctrl.Manager, ) error { @@ -76,7 +73,7 @@ func RegisterGatewayController( evtRec := mgr.GetEventRecorderFor("gateway") modelBuilder := gateway.NewServiceNetworkModelBuilder() - stackDeployer := deploy.NewServiceNetworkStackDeployer(cloud, mgrClient, datastore) + stackDeployer := deploy.NewServiceNetworkStackDeployer(cloud, mgrClient) stackMarshaller := deploy.NewDefaultStackMarshaller() r := &GatewayReconciler{ @@ -88,7 +85,6 @@ func RegisterGatewayController( modelBuilder: modelBuilder, stackDeployer: stackDeployer, cloud: cloud, - datastore: datastore, stackMarshaller: stackMarshaller, } @@ -254,9 +250,6 @@ func (r *GatewayReconciler) reconcileGatewayResources(ctx context.Context, gw *g if err != nil { return err } - if snInfo == nil { - return fmt.Errorf("Service network %s for account %s not found", gw.Name, config.AccountID) - } if err = r.updateGatewayStatus(ctx, *snInfo.SvcNetwork.Arn, gw); err != nil { return err diff --git a/controllers/route_controller.go b/controllers/route_controller.go index d4dae6ab..24da02a3 100644 --- a/controllers/route_controller.go +++ b/controllers/route_controller.go @@ -19,6 +19,8 @@ package controllers import ( "context" "fmt" + "github.com/aws/aws-application-networking-k8s/pkg/aws/services" + "github.com/aws/aws-application-networking-k8s/pkg/utils" "github.com/aws/aws-application-networking-k8s/pkg/utils/gwlog" @@ -70,12 +72,21 @@ type RouteReconciler struct { stackDeployer deploy.StackDeployer latticeDataStore *latticestore.LatticeDataStore stackMarshaller deploy.StackMarshaller + cloud aws.Cloud } const ( LatticeAssignedDomainName = "application-networking.k8s.aws/lattice-assigned-domain-name" ) +type RouteNameProvider struct { + Route core.Route +} + +func (r *RouteNameProvider) LatticeName() string { + return utils.LatticeServiceName(r.Route.Name(), r.Route.Namespace()) +} + func RegisterAllRouteControllers( log gwlog.Logger, cloud aws.Cloud, @@ -107,6 +118,7 @@ func RegisterAllRouteControllers( modelBuilder: gateway.NewLatticeServiceBuilder(log, mgrClient, datastore, cloud), stackDeployer: deploy.NewLatticeServiceStackDeploy(log, cloud, mgrClient, datastore), stackMarshaller: deploy.NewDefaultStackMarshaller(), + cloud: cloud, } svcImportEventHandler := eventhandlers.NewServiceImportEventHandler(log, mgrClient) @@ -311,9 +323,7 @@ func (r *RouteReconciler) buildAndDeployModel( if err := r.stackDeployer.Deploy(ctx, stack); err != nil { r.log.Infof("RouteReconciler: Failed deploy %s due to err %s", route.Name(), err) - var retryErr = errors.New(lattice.LATTICE_RETRY) - - if errors.As(err, &retryErr) { + if errors.As(err, &lattice.RetryErr) { r.eventRecorder.Event(route.K8sObject(), corev1.EventTypeNormal, k8s.RouteEventReasonRetryReconcile, "retry reconcile...") @@ -358,22 +368,27 @@ func (r *RouteReconciler) reconcileRouteResource(ctx context.Context, route core return backendRefIPFamiliesErr } - _, _, err := r.buildAndDeployModel(ctx, route) + if _, _, err := r.buildAndDeployModel(ctx, route); err != nil { + return err + } - //TODO add metric + r.eventRecorder.Event(route.K8sObject(), corev1.EventTypeNormal, + k8s.RouteEventReasonDeploySucceed, "Adding/Updating reconcile Done!") - if err == nil { - r.eventRecorder.Event(route.K8sObject(), corev1.EventTypeNormal, - k8s.RouteEventReasonDeploySucceed, "Adding/Updating reconcile Done!") + svc, err := r.cloud.Lattice().FindService(ctx, &RouteNameProvider{route}) + if err != nil && !services.IsNotFoundError(err) { + return err + } - serviceStatus, err1 := r.latticeDataStore.GetLatticeService(route.Name(), route.Namespace()) + if svc == nil || svc.DnsEntry == nil || svc.DnsEntry.DomainName == nil { + return errors.New(lattice.LATTICE_RETRY) + } - if err1 == nil { - r.updateRouteStatus(ctx, serviceStatus.DNS, route) - } + if err := r.updateRouteStatus(ctx, *svc.DnsEntry.DomainName, route); err != nil { + return err } - return err + return nil } func (r *RouteReconciler) updateRouteStatus(ctx context.Context, dns string, route core.Route) error { diff --git a/pkg/aws/services/vpclattice.go b/pkg/aws/services/vpclattice.go index 2598ce42..fb65c488 100644 --- a/pkg/aws/services/vpclattice.go +++ b/pkg/aws/services/vpclattice.go @@ -2,6 +2,8 @@ package services import ( "context" + "errors" + "fmt" "os" "github.com/aws/aws-sdk-go/aws" @@ -20,6 +22,29 @@ type ServiceNetworkInfo struct { SvcNetwork vpclattice.ServiceNetworkSummary Tags Tags } + +type LatticeNameProvider interface { + LatticeName() string +} + +type NotFoundError struct { + ResourceType string + Name string +} + +func (e *NotFoundError) Error() string { + return fmt.Sprintf("%s %s not found", e.ResourceType, e.Name) +} + +func NewNotFoundError(resourceType string, name string) error { + return &NotFoundError{resourceType, name} +} + +func IsNotFoundError(err error) bool { + nfErr := &NotFoundError{} + return errors.As(err, &nfErr) +} + type Lattice interface { vpclatticeiface.VPCLatticeAPI ListServiceNetworksAsList(ctx context.Context, input *vpclattice.ListServiceNetworksInput) ([]*vpclattice.ServiceNetworkSummary, error) @@ -29,6 +54,7 @@ type Lattice interface { ListServiceNetworkVpcAssociationsAsList(ctx context.Context, input *vpclattice.ListServiceNetworkVpcAssociationsInput) ([]*vpclattice.ServiceNetworkVpcAssociationSummary, error) ListServiceNetworkServiceAssociationsAsList(ctx context.Context, input *vpclattice.ListServiceNetworkServiceAssociationsInput) ([]*vpclattice.ServiceNetworkServiceAssociationSummary, error) FindServiceNetwork(ctx context.Context, name string, accountId string) (*ServiceNetworkInfo, error) + FindService(ctx context.Context, nameProvider LatticeNameProvider) (*vpclattice.ServiceSummary, error) } type defaultLattice struct { @@ -54,41 +80,33 @@ func NewDefaultLattice(sess *session.Session, region string) *defaultLattice { func (d *defaultLattice) ListServiceNetworksAsList(ctx context.Context, input *vpclattice.ListServiceNetworksInput) ([]*vpclattice.ServiceNetworkSummary, error) { result := []*vpclattice.ServiceNetworkSummary{} - resp, err := d.ListServiceNetworksWithContext(ctx, input) - for { - if err != nil { - return nil, err - } - for _, mesh := range resp.Items { - result = append(result, mesh) - } - if resp.NextToken == nil { - break + err := d.ListServiceNetworksPagesWithContext(ctx, input, func(page *vpclattice.ListServiceNetworksOutput, lastPage bool) bool { + for _, sn := range page.Items { + result = append(result, sn) } - input.NextToken = resp.NextToken - resp, err = d.ListServiceNetworksWithContext(ctx, input) + return true + }) + if err != nil { + return nil, err } + return result, nil } func (d *defaultLattice) ListServicesAsList(ctx context.Context, input *vpclattice.ListServicesInput) ([]*vpclattice.ServiceSummary, error) { result := []*vpclattice.ServiceSummary{} - resp, err := d.ListServicesWithContext(ctx, input) - for { - if err != nil { - return nil, err - } - for _, mesh := range resp.Items { - result = append(result, mesh) + err := d.ListServicesPagesWithContext(ctx, input, func(page *vpclattice.ListServicesOutput, lastPage bool) bool { + for _, svc := range page.Items { + result = append(result, svc) } - if resp.NextToken == nil { - break - } - input.NextToken = resp.NextToken - resp, err = d.ListServicesWithContext(ctx, input) + return true + }) + + if err != nil { + return nil, err } return result, nil @@ -96,20 +114,16 @@ func (d *defaultLattice) ListServicesAsList(ctx context.Context, input *vpclatti func (d *defaultLattice) ListTargetGroupsAsList(ctx context.Context, input *vpclattice.ListTargetGroupsInput) ([]*vpclattice.TargetGroupSummary, error) { result := []*vpclattice.TargetGroupSummary{} - resp, err := d.ListTargetGroupsWithContext(ctx, input) - for { - if err != nil { - return nil, err + err := d.ListTargetGroupsPagesWithContext(ctx, input, func(page *vpclattice.ListTargetGroupsOutput, lastPage bool) bool { + for _, tg := range page.Items { + result = append(result, tg) } - for _, mesh := range resp.Items { - result = append(result, mesh) - } - if resp.NextToken == nil { - break - } - input.NextToken = resp.NextToken - resp, err = d.ListTargetGroupsWithContext(ctx, input) + return true + }) + + if err != nil { + return nil, err } return result, nil @@ -117,20 +131,16 @@ func (d *defaultLattice) ListTargetGroupsAsList(ctx context.Context, input *vpcl func (d *defaultLattice) ListTargetsAsList(ctx context.Context, input *vpclattice.ListTargetsInput) ([]*vpclattice.TargetSummary, error) { result := []*vpclattice.TargetSummary{} - resp, err := d.ListTargetsWithContext(ctx, input) - for { - if err != nil { - return nil, err - } - for _, target := range resp.Items { + err := d.ListTargetsPagesWithContext(ctx, input, func(page *vpclattice.ListTargetsOutput, lastPage bool) bool { + for _, target := range page.Items { result = append(result, target) } - if resp.NextToken == nil { - break - } - input.NextToken = resp.NextToken - resp, err = d.ListTargetsWithContext(ctx, input) + return true + }) + + if err != nil { + return nil, err } return result, nil @@ -138,20 +148,16 @@ func (d *defaultLattice) ListTargetsAsList(ctx context.Context, input *vpclattic func (d *defaultLattice) ListServiceNetworkVpcAssociationsAsList(ctx context.Context, input *vpclattice.ListServiceNetworkVpcAssociationsInput) ([]*vpclattice.ServiceNetworkVpcAssociationSummary, error) { result := []*vpclattice.ServiceNetworkVpcAssociationSummary{} - resp, err := d.ListServiceNetworkVpcAssociationsWithContext(ctx, input) - for { - if err != nil { - return nil, err - } - for _, mesh := range resp.Items { - result = append(result, mesh) - } - if resp.NextToken == nil { - break + err := d.ListServiceNetworkVpcAssociationsPagesWithContext(ctx, input, func(page *vpclattice.ListServiceNetworkVpcAssociationsOutput, lastPage bool) bool { + for _, assoc := range page.Items { + result = append(result, assoc) } - input.NextToken = resp.NextToken - resp, err = d.ListServiceNetworkVpcAssociationsWithContext(ctx, input) + return true + }) + + if err != nil { + return nil, err } return result, nil @@ -159,20 +165,16 @@ func (d *defaultLattice) ListServiceNetworkVpcAssociationsAsList(ctx context.Con func (d *defaultLattice) ListServiceNetworkServiceAssociationsAsList(ctx context.Context, input *vpclattice.ListServiceNetworkServiceAssociationsInput) ([]*vpclattice.ServiceNetworkServiceAssociationSummary, error) { result := []*vpclattice.ServiceNetworkServiceAssociationSummary{} - resp, err := d.ListServiceNetworkServiceAssociationsWithContext(ctx, input) - for { - if err != nil { - return nil, err - } - for _, mesh := range resp.Items { - result = append(result, mesh) + err := d.ListServiceNetworkServiceAssociationsPagesWithContext(ctx, input, func(page *vpclattice.ListServiceNetworkServiceAssociationsOutput, lastPage bool) bool { + for _, assoc := range page.Items { + result = append(result, assoc) } - if resp.NextToken == nil { - break - } - input.NextToken = resp.NextToken - resp, err = d.ListServiceNetworkServiceAssociationsWithContext(ctx, input) + return true + }) + + if err != nil { + return nil, err } return result, nil @@ -181,51 +183,81 @@ func (d *defaultLattice) ListServiceNetworkServiceAssociationsAsList(ctx context func (d *defaultLattice) FindServiceNetwork(ctx context.Context, name string, optionalAccountId string) (*ServiceNetworkInfo, error) { input := vpclattice.ListServiceNetworksInput{} - for { - - resp, err := d.ListServiceNetworksWithContext(ctx, &input) - if err != nil { - return nil, err - } - - for _, r := range resp.Items { + var innerErr error + var snMatch *ServiceNetworkInfo + err := d.ListServiceNetworksPagesWithContext(ctx, &input, func(page *vpclattice.ListServiceNetworksOutput, lastPage bool) bool { + for _, r := range page.Items { if aws.StringValue(r.Name) != name { continue } acctIdMatches, err1 := accountIdMatches(optionalAccountId, *r.Arn) if err1 != nil { - return nil, err1 + innerErr = err1 + return false } if !acctIdMatches { - glog.V(6).Infoln("ServiceNetwork found but does not match account id ", name, r.Arn, optionalAccountId) + glog.V(6).Infoln("ServiceNetwork found but does not match account id", name, r.Arn, optionalAccountId) continue } - glog.V(6).Infoln("Found ServiceNetwork ", name, r.Arn, optionalAccountId) - + glog.V(6).Infoln("Found ServiceNetwork", name, r.Arn, optionalAccountId) tagsInput := vpclattice.ListTagsForResourceInput{ ResourceArn: r.Arn, } tagsOutput, err2 := d.ListTagsForResourceWithContext(ctx, &tagsInput) if err2 != nil { - return nil, err2 + innerErr = err2 + return false } - return &ServiceNetworkInfo{ + snMatch = &ServiceNetworkInfo{ SvcNetwork: *r, Tags: tagsOutput.Tags, - }, nil + } + return false } - if resp.NextToken == nil { - break + return true + }) + + if innerErr != nil { + return nil, innerErr + } + if err != nil { + return nil, err + } + if snMatch == nil { + glog.V(6).Infoln("Service network for account not found ", name, optionalAccountId) + return nil, NewNotFoundError("Service network", name) + } + + return snMatch, nil +} +func (d *defaultLattice) FindService(ctx context.Context, nameProvider LatticeNameProvider) (*vpclattice.ServiceSummary, error) { + serviceName := nameProvider.LatticeName() + input := vpclattice.ListServicesInput{} + + var svcMatch *vpclattice.ServiceSummary + err := d.ListServicesPagesWithContext(ctx, &input, func(page *vpclattice.ListServicesOutput, lastPage bool) bool { + for _, svc := range page.Items { + if *svc.Name == serviceName { + svcMatch = svc + return false + } } + return true + }) - input.NextToken = resp.NextToken + if err != nil { + return nil, err + } + if svcMatch == nil { + glog.V(6).Infoln("Service not found", serviceName) + return nil, NewNotFoundError("Service", serviceName) } - return nil, nil + return svcMatch, nil } func accountIdMatches(accountId string, itemArn string) (bool, error) { diff --git a/pkg/aws/services/vpclattice_mocks.go b/pkg/aws/services/vpclattice_mocks.go index a75e39c7..468c944d 100644 --- a/pkg/aws/services/vpclattice_mocks.go +++ b/pkg/aws/services/vpclattice_mocks.go @@ -1036,6 +1036,21 @@ func (mr *MockLatticeMockRecorder) DeregisterTargetsWithContext(arg0, arg1 inter return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeregisterTargetsWithContext", reflect.TypeOf((*MockLattice)(nil).DeregisterTargetsWithContext), varargs...) } +// FindService mocks base method. +func (m *MockLattice) FindService(arg0 context.Context, arg1 LatticeNameProvider) (*vpclattice.ServiceSummary, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindService", arg0, arg1) + ret0, _ := ret[0].(*vpclattice.ServiceSummary) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FindService indicates an expected call of FindService. +func (mr *MockLatticeMockRecorder) FindService(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindService", reflect.TypeOf((*MockLattice)(nil).FindService), arg0, arg1) +} + // FindServiceNetwork mocks base method. func (m *MockLattice) FindServiceNetwork(arg0 context.Context, arg1, arg2 string) (*ServiceNetworkInfo, error) { m.ctrl.T.Helper() diff --git a/pkg/aws/services/vpclattice_test.go b/pkg/aws/services/vpclattice_test.go index 253e7501..0d421672 100644 --- a/pkg/aws/services/vpclattice_test.go +++ b/pkg/aws/services/vpclattice_test.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go/aws/request" "testing" "github.com/aws/aws-sdk-go/service/vpclattice" @@ -13,6 +14,17 @@ import ( "github.com/stretchr/testify/assert" ) +func Test_IsNotFoundError(t *testing.T) { + err := errors.New("ERROR") + nfErr := NewNotFoundError("type", "name") + blankNfEff := &NotFoundError{} + + assert.False(t, IsNotFoundError(err)) + assert.False(t, IsNotFoundError(nil)) + assert.True(t, IsNotFoundError(nfErr)) + assert.True(t, IsNotFoundError(blankNfEff)) +} + func Test_defaultLattice_ListServiceNetworksAsList(t *testing.T) { tests := []struct { ctx context.Context @@ -46,29 +58,38 @@ func Test_defaultLattice_ListServiceNetworksAsList(t *testing.T) { MaxResults: &tt.maxResults, NextToken: nil, } - sampleMesh := &vpclattice.ServiceNetworkSummary{ + sn := &vpclattice.ServiceNetworkSummary{ Arn: &tt.testArn, Id: &tt.testId, Name: &tt.testName, } - listMeshOutput1 := &vpclattice.ListServiceNetworksOutput{ - Items: []*vpclattice.ServiceNetworkSummary{sampleMesh, sampleMesh}, + listOutput1 := &vpclattice.ListServiceNetworksOutput{ + Items: []*vpclattice.ServiceNetworkSummary{sn, sn}, NextToken: &tt.nextToken, } - listMeshOutput2 := &vpclattice.ListServiceNetworksOutput{ - Items: []*vpclattice.ServiceNetworkSummary{sampleMesh, sampleMesh}, + listOutput2 := &vpclattice.ListServiceNetworksOutput{ + Items: []*vpclattice.ServiceNetworkSummary{sn, sn}, NextToken: &tt.nextToken, } - listMeshOutput3 := &vpclattice.ListServiceNetworksOutput{ - Items: []*vpclattice.ServiceNetworkSummary{sampleMesh}, + listOutput3 := &vpclattice.ListServiceNetworksOutput{ + Items: []*vpclattice.ServiceNetworkSummary{sn}, NextToken: nil, } - mockLattice.EXPECT().ListServiceNetworksWithContext(tt.ctx, input).Return(listMeshOutput1, nil) - mockLattice.EXPECT().ListServiceNetworksWithContext(tt.ctx, input).Return(listMeshOutput2, nil) - mockLattice.EXPECT().ListServiceNetworksWithContext(tt.ctx, input).Return(listMeshOutput3, nil) + mockLattice.EXPECT().ListServiceNetworksPagesWithContext(tt.ctx, input, gomock.Any()).DoAndReturn( + func(ctx aws.Context, input *vpclattice.ListServiceNetworksInput, f func(*vpclattice.ListServiceNetworksOutput, bool) bool, opts ...request.Option) error { + cont := f(listOutput1, false) + if cont { + cont = f(listOutput2, false) + } + if cont { + f(listOutput3, true) + } + return nil + }).Times(1) + got, err := d.ListServiceNetworksAsList(tt.ctx, input) assert.Nil(t, err) - assert.Equal(t, got, []*vpclattice.ServiceNetworkSummary{sampleMesh, sampleMesh, sampleMesh, sampleMesh, sampleMesh}) + assert.Equal(t, got, []*vpclattice.ServiceNetworkSummary{sn, sn, sn, sn, sn}) } } @@ -110,8 +131,16 @@ func Test_defaultLattice_ListServicesAsList(t *testing.T) { Items: []*vpclattice.ServiceSummary{sampleService}, NextToken: nil, } - mockLattice.EXPECT().ListServicesWithContext(tt.ctx, input).Return(listOutput1, nil) - mockLattice.EXPECT().ListServicesWithContext(tt.ctx, input).Return(listOutput2, nil) + + mockLattice.EXPECT().ListServicesPagesWithContext(tt.ctx, input, gomock.Any()).DoAndReturn( + func(ctx aws.Context, input *vpclattice.ListServicesInput, f func(*vpclattice.ListServicesOutput, bool) bool, opts ...request.Option) error { + cont := f(listOutput1, false) + if cont { + f(listOutput2, true) + } + return nil + }).Times(1) + got, err := d.ListServicesAsList(tt.ctx, input) assert.Nil(t, err) assert.Equal(t, got, []*vpclattice.ServiceSummary{sampleService, sampleService}) @@ -148,11 +177,17 @@ func Test_defaultLattice_ListTGsAsList(t *testing.T) { sample := &vpclattice.TargetGroupSummary{ Name: &tt.testName, } + listOutput1 := &vpclattice.ListTargetGroupsOutput{ Items: []*vpclattice.TargetGroupSummary{sample}, NextToken: nil, } - mockLattice.EXPECT().ListTargetGroupsWithContext(tt.ctx, input).Return(listOutput1, nil) + + mockLattice.EXPECT().ListTargetGroupsPagesWithContext(tt.ctx, input, gomock.Any()).DoAndReturn( + func(ctx aws.Context, input *vpclattice.ListTargetGroupsInput, f func(*vpclattice.ListTargetGroupsOutput, bool) bool, opts ...request.Option) error { + f(listOutput1, true) + return nil + }).Times(1) got, err := d.ListTargetGroupsAsList(tt.ctx, input) assert.Nil(t, err) @@ -194,7 +229,11 @@ func Test_defaultLattice_ListTargetsAsList(t *testing.T) { Items: []*vpclattice.TargetSummary{sample, sample}, NextToken: nil, } - mockLattice.EXPECT().ListTargetsWithContext(tt.ctx, input).Return(listOutput1, nil) + mockLattice.EXPECT().ListTargetsPagesWithContext(tt.ctx, input, gomock.Any()).DoAndReturn( + func(ctx aws.Context, input *vpclattice.ListTargetsInput, f func(*vpclattice.ListTargetsOutput, bool) bool, opts ...request.Option) error { + f(listOutput1, true) + return nil + }).Times(1) got, err := d.ListTargetsAsList(tt.ctx, input) assert.Nil(t, err) @@ -236,7 +275,11 @@ func Test_defaultLattice_ListServiceNetworkVpcAssociationsAsList(t *testing.T) { Items: []*vpclattice.ServiceNetworkVpcAssociationSummary{sample}, NextToken: nil, } - mockLattice.EXPECT().ListServiceNetworkVpcAssociationsWithContext(tt.ctx, input).Return(listOutput1, nil) + mockLattice.EXPECT().ListServiceNetworkVpcAssociationsPagesWithContext(tt.ctx, input, gomock.Any()).DoAndReturn( + func(ctx aws.Context, input *vpclattice.ListServiceNetworkVpcAssociationsInput, f func(*vpclattice.ListServiceNetworkVpcAssociationsOutput, bool) bool, opts ...request.Option) error { + f(listOutput1, true) + return nil + }).Times(1) got, err := d.ListServiceNetworkVpcAssociationsAsList(tt.ctx, input) assert.Nil(t, err) @@ -276,7 +319,11 @@ func Test_defaultLattice_ListServiceNetworkServiceAssociationsAsList(t *testing. Items: []*vpclattice.ServiceNetworkServiceAssociationSummary{}, NextToken: nil, } - mockLattice.EXPECT().ListServiceNetworkServiceAssociationsWithContext(tt.ctx, input).Return(listOutput1, nil) + mockLattice.EXPECT().ListServiceNetworkServiceAssociationsPagesWithContext(tt.ctx, input, gomock.Any()).DoAndReturn( + func(ctx aws.Context, input *vpclattice.ListServiceNetworkServiceAssociationsInput, f func(*vpclattice.ListServiceNetworkServiceAssociationsOutput, bool) bool, opts ...request.Option) error { + f(listOutput1, true) + return nil + }).Times(1) got, err := d.ListServiceNetworkServiceAssociationsAsList(tt.ctx, input) assert.Nil(t, err) @@ -297,20 +344,24 @@ func Test_defaultLattice_FindServiceNetwork_happyPath(t *testing.T) { snName := "sn-name" acctId := "123456" - arn := getTestArn(acctId) + testArn := getTestArn(acctId) item := &vpclattice.ServiceNetworkSummary{ Name: &snName, - Arn: &arn, + Arn: &testArn, Id: aws.String("id"), } - listOutput := &vpclattice.ListServiceNetworksOutput{ + listOutput1 := &vpclattice.ListServiceNetworksOutput{ Items: []*vpclattice.ServiceNetworkSummary{item}, NextToken: nil, } - mockLattice.EXPECT().ListServiceNetworksWithContext(gomock.Any(), gomock.Any()).Return(listOutput, nil).AnyTimes() + mockLattice.EXPECT().ListServiceNetworksPagesWithContext(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( + func(ctx aws.Context, input *vpclattice.ListServiceNetworksInput, f func(*vpclattice.ListServiceNetworksOutput, bool) bool, opts ...request.Option) error { + f(listOutput1, true) + return nil + }).AnyTimes() mockLattice.EXPECT().ListTagsForResourceWithContext(ctx, gomock.Any()).Return( &vpclattice.ListTagsForResourceOutput{}, nil).AnyTimes() @@ -326,7 +377,7 @@ func Test_defaultLattice_FindServiceNetwork_happyPath(t *testing.T) { mismatchedAccountId := "555555" itemNotFound, err3 := d.FindServiceNetwork(ctx, snName, mismatchedAccountId) - assert.Nil(t, err3) + assert.True(t, IsNotFoundError(err3)) assert.Nil(t, itemNotFound) } @@ -339,7 +390,7 @@ func Test_defaultLattice_FindServiceNetwork_disambiguateByAccount(t *testing.T) acct1 := "12345" acct2 := "88888" - listOutput := &vpclattice.ListServiceNetworksOutput{ + listOutput1 := &vpclattice.ListServiceNetworksOutput{ Items: []*vpclattice.ServiceNetworkSummary{ { Arn: aws.String(getTestArn(acct1)), @@ -355,8 +406,12 @@ func Test_defaultLattice_FindServiceNetwork_disambiguateByAccount(t *testing.T) NextToken: nil, } - mockLattice.EXPECT().ListServiceNetworksWithContext(gomock.Any(), gomock.Any()).Return( - listOutput, nil).AnyTimes() + mockLattice.EXPECT().ListServiceNetworksPagesWithContext(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( + func(ctx aws.Context, input *vpclattice.ListServiceNetworksInput, f func(*vpclattice.ListServiceNetworksOutput, bool) bool, opts ...request.Option) error { + f(listOutput1, true) + return nil + }).AnyTimes() + mockLattice.EXPECT().ListTagsForResourceWithContext(ctx, gomock.Any()).Return( &vpclattice.ListTagsForResourceOutput{ Tags: map[string]*string{ @@ -390,17 +445,21 @@ func Test_defaultLattice_FindServiceNetwork_noResults(t *testing.T) { mockLattice := NewMockLattice(c) d := &defaultLattice{VPCLatticeAPI: mockLattice} - mockLattice.EXPECT().ListServiceNetworksWithContext(gomock.Any(), gomock.Any()).Return( - &vpclattice.ListServiceNetworksOutput{}, nil).AnyTimes() + mockLattice.EXPECT().ListServiceNetworksPagesWithContext(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( + func(ctx aws.Context, input *vpclattice.ListServiceNetworksInput, f func(*vpclattice.ListServiceNetworksOutput, bool) bool, opts ...request.Option) error { + f(&vpclattice.ListServiceNetworksOutput{}, true) + return nil + }).AnyTimes() + mockLattice.EXPECT().ListTagsForResourceWithContext(ctx, gomock.Any()).Return( &vpclattice.ListTagsForResourceOutput{}, nil).AnyTimes() item, err := d.FindServiceNetwork(ctx, "foo", "1234") - assert.Nil(t, err) + assert.True(t, IsNotFoundError(err)) assert.Nil(t, item) } -func Test_defaultLattice_FindServiceNetwork_manyResults(t *testing.T) { +func Test_defaultLattice_FindServiceNetwork_pagedResults(t *testing.T) { ctx := context.TODO() c := gomock.NewController(t) mockLattice := NewMockLattice(c) @@ -424,18 +483,21 @@ func Test_defaultLattice_FindServiceNetwork_manyResults(t *testing.T) { } } - rIdx := 0 - - mockLattice.EXPECT().ListServiceNetworksWithContext(gomock.Any(), gomock.Any()).DoAndReturn( - func(_ context.Context, req *vpclattice.ListServiceNetworksInput, _ ...interface{}) (*vpclattice.ListServiceNetworksOutput, error) { - result := - &vpclattice.ListServiceNetworksOutput{ - Items: results[rIdx], - NextToken: tokens[rIdx], + mockLattice.EXPECT().ListServiceNetworksPagesWithContext(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( + func(ctx aws.Context, input *vpclattice.ListServiceNetworksInput, f func(*vpclattice.ListServiceNetworksOutput, bool) bool, opts ...request.Option) error { + for i, result := range results { + responsePage := &vpclattice.ListServiceNetworksOutput{ + Items: result, + NextToken: tokens[i], + } + cont := f(responsePage, i+1 == len(results)) + if !cont { + break } - rIdx = (rIdx + 1) % len(results) - return result, nil + } + return nil }).AnyTimes() + mockLattice.EXPECT().ListTagsForResourceWithContext(ctx, gomock.Any()).Return( &vpclattice.ListTagsForResourceOutput{}, nil).AnyTimes() @@ -453,6 +515,10 @@ func Test_defaultLattice_FindServiceNetwork_manyResults(t *testing.T) { assert.Nil(t, err2) assert.NotNil(t, page2item) assert.Equal(t, "name-21", *page2item.SvcNetwork.Name) + + notPresentItem, err4 := d.FindServiceNetwork(ctx, "no-name", "") + assert.True(t, IsNotFoundError(err4)) + assert.Nil(t, notPresentItem) } func Test_defaultLattice_FindServiceNetwork_errorsRaised(t *testing.T) { @@ -461,26 +527,140 @@ func Test_defaultLattice_FindServiceNetwork_errorsRaised(t *testing.T) { mockLattice := NewMockLattice(c) d := &defaultLattice{VPCLatticeAPI: mockLattice} - mockLattice.EXPECT().ListServiceNetworksWithContext(gomock.Any(), gomock.Any()).Return( - nil, errors.Errorf("LIST_ERR")).Times(1) + mockLattice.EXPECT().ListServiceNetworksPagesWithContext(gomock.Any(), gomock.Any(), gomock.Any()). + Return(errors.New("LIST_ERR")).Times(1) _, listErr := d.FindServiceNetwork(ctx, "foo", "1234") assert.NotNil(t, listErr) + assert.False(t, IsNotFoundError(listErr)) - mockLattice.EXPECT().ListServiceNetworksWithContext(gomock.Any(), gomock.Any()).Return( - &vpclattice.ListServiceNetworksOutput{ - Items: []*vpclattice.ServiceNetworkSummary{ - { - Arn: aws.String(getTestArn("1234")), - Name: aws.String("foo"), - Id: aws.String("id"), - }, + listOutput := vpclattice.ListServiceNetworksOutput{ + Items: []*vpclattice.ServiceNetworkSummary{ + { + Arn: aws.String(getTestArn("1234")), + Name: aws.String("foo"), + Id: aws.String("id"), }, - NextToken: nil, - }, nil).Times(1) + }, + NextToken: nil, + } + mockLattice.EXPECT().ListServiceNetworksPagesWithContext(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( + func(ctx aws.Context, input *vpclattice.ListServiceNetworksInput, f func(*vpclattice.ListServiceNetworksOutput, bool) bool, opts ...request.Option) error { + f(&listOutput, true) + return nil + }).Times(1) + mockLattice.EXPECT().ListTagsForResourceWithContext(ctx, gomock.Any()).Return( nil, errors.Errorf("TAG_ERR")).Times(1) _, tagErr := d.FindServiceNetwork(ctx, "foo", "1234") assert.NotNil(t, tagErr) + assert.False(t, IsNotFoundError(tagErr)) +} + +type StringNameProvider struct { + name string +} + +func (p *StringNameProvider) LatticeName() string { + return p.name +} + +func Test_defaultLattice_FindService_happyPath(t *testing.T) { + ctx := context.TODO() + c := gomock.NewController(t) + mockLattice := NewMockLattice(c) + d := &defaultLattice{VPCLatticeAPI: mockLattice} + + name := "s-name" + + item := &vpclattice.ServiceSummary{ + Name: &name, + Arn: aws.String("arn"), + Id: aws.String("id"), + } + + listOutput1 := &vpclattice.ListServicesOutput{ + Items: []*vpclattice.ServiceSummary{item}, + NextToken: nil, + } + + mockLattice.EXPECT().ListServicesPagesWithContext(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( + func(ctx aws.Context, input *vpclattice.ListServicesInput, f func(*vpclattice.ListServicesOutput, bool) bool, opts ...request.Option) error { + f(listOutput1, true) + return nil + }).AnyTimes() + + itemFound, err1 := d.FindService(ctx, &StringNameProvider{name}) + assert.Nil(t, err1) + assert.NotNil(t, itemFound) + assert.Equal(t, name, *itemFound.Name) + + itemNotFound, err2 := d.FindService(ctx, &StringNameProvider{"no-name"}) + assert.True(t, IsNotFoundError(err2)) + assert.Nil(t, itemNotFound) +} + +func Test_defaultLattice_FindService_pagedResults(t *testing.T) { + ctx := context.TODO() + c := gomock.NewController(t) + mockLattice := NewMockLattice(c) + d := &defaultLattice{VPCLatticeAPI: mockLattice} + + item1 := &vpclattice.ServiceSummary{ + Name: aws.String("name1"), + Arn: aws.String("arn1"), + Id: aws.String("id1"), + } + item2 := &vpclattice.ServiceSummary{ + Name: aws.String("name2"), + Arn: aws.String("arn2"), + Id: aws.String("id2"), + } + + listOutput1 := &vpclattice.ListServicesOutput{ + Items: []*vpclattice.ServiceSummary{item1}, + NextToken: aws.String("next"), + } + listOutput2 := &vpclattice.ListServicesOutput{ + Items: []*vpclattice.ServiceSummary{item2}, + NextToken: nil, + } + + mockLattice.EXPECT().ListServicesPagesWithContext(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( + func(ctx aws.Context, input *vpclattice.ListServicesInput, f func(*vpclattice.ListServicesOutput, bool) bool, opts ...request.Option) error { + cont := f(listOutput1, false) + if cont { + f(listOutput2, true) + } + return nil + }).AnyTimes() + + itemFound1, err1 := d.FindService(ctx, &StringNameProvider{"name1"}) + assert.Nil(t, err1) + assert.NotNil(t, itemFound1) + assert.Equal(t, "name1", *itemFound1.Name) + + itemFound2, err2 := d.FindService(ctx, &StringNameProvider{"name2"}) + assert.Nil(t, err2) + assert.NotNil(t, itemFound2) + assert.Equal(t, "name2", *itemFound2.Name) + + itemNotFound, err3 := d.FindService(ctx, &StringNameProvider{"no-name"}) + assert.True(t, IsNotFoundError(err3)) + assert.Nil(t, itemNotFound) +} + +func Test_defaultLattice_FindService_errorsRaised(t *testing.T) { + ctx := context.TODO() + c := gomock.NewController(t) + mockLattice := NewMockLattice(c) + d := &defaultLattice{VPCLatticeAPI: mockLattice} + + mockLattice.EXPECT().ListServicesPagesWithContext(gomock.Any(), gomock.Any(), gomock.Any()). + Return(errors.New("LIST_ERR")).Times(1) + + _, listErr := d.FindService(ctx, &StringNameProvider{"foo"}) + assert.NotNil(t, listErr) + assert.False(t, IsNotFoundError(listErr)) } diff --git a/pkg/deploy/lattice/error.go b/pkg/deploy/lattice/error.go index 1cd4626c..ea32872b 100644 --- a/pkg/deploy/lattice/error.go +++ b/pkg/deploy/lattice/error.go @@ -3,11 +3,7 @@ package lattice import "errors" const ( - LATTICE_CREATE_IN_PROGRESS = "LATTICE_CREATE_IN_PROGRESS" - LATTICE_DELETE_IN_PROGRESS = "LATTICE_DELETE_IN_PROGRESS" - LATTICE_NOT_FOUND = "LATTICE_NOT_FOUND" - LATTICE_ALREADY_EXIST = "LATTICE_ALREADY_EXIST" - LATTICE_RETRY = "LATTICE_RETRY" + LATTICE_RETRY = "LATTICE_RETRY" ) var RetryErr = errors.New(LATTICE_RETRY) diff --git a/pkg/deploy/lattice/listener_manager.go b/pkg/deploy/lattice/listener_manager.go index ce57a2a2..16937a77 100644 --- a/pkg/deploy/lattice/listener_manager.go +++ b/pkg/deploy/lattice/listener_manager.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "github.com/aws/aws-application-networking-k8s/pkg/aws/services" "strings" "github.com/golang/glog" @@ -18,6 +19,7 @@ import ( ) type ListenerManager interface { + Cloud() lattice_aws.Cloud Create(ctx context.Context, service *latticemodel.Listener) (latticemodel.ListenerStatus, error) Delete(ctx context.Context, listenerID string, serviceID string) error List(ctx context.Context, serviceID string) ([]*vpclattice.ListenerSummary, error) @@ -35,24 +37,37 @@ func NewListenerManager(cloud lattice_aws.Cloud, latticeDataStore *latticestore. } } -func (s *defaultListenerManager) Create(ctx context.Context, listener *latticemodel.Listener) (latticemodel.ListenerStatus, error) { - glog.V(6).Infof("Creating listener >>>> %v \n", listener) +func (d *defaultListenerManager) Cloud() lattice_aws.Cloud { + return d.cloud +} - serviceStatus, err := s.latticeDataStore.GetLatticeService(listener.Spec.Name, listener.Spec.Namespace) +type ListenerNameProvider struct { + l *latticemodel.Listener +} - if err != nil { - errmsg := fmt.Sprintf("Service %v not found during listener creation", listener.Spec) - glog.V(6).Infof("Error during create listner %s \n", errmsg) - return latticemodel.ListenerStatus{}, errors.New(errmsg) - } +func (r *ListenerNameProvider) LatticeName() string { + return utils.LatticeServiceName(r.l.Spec.Name, r.l.Spec.Namespace) +} - lis, err := s.findListenerByNamePort(ctx, serviceStatus.ID, listener.Spec.Port) +func (d *defaultListenerManager) Create(ctx context.Context, listener *latticemodel.Listener) (latticemodel.ListenerStatus, error) { + glog.V(6).Infof("Creating listener >>>> %v \n", listener) - glog.V(6).Infof("findListenerByNamePort %v , lisenter %v error %v\n", listener, lis, err) + svc, err1 := d.cloud.Lattice().FindService(ctx, &ListenerNameProvider{listener}) + if err1 != nil { + if services.IsNotFoundError(err1) { + errMsg := fmt.Sprintf("Service %v not found during listener creation", listener.Spec.Name) + glog.V(6).Infof("Error during create listner %s \n", errMsg) + return latticemodel.ListenerStatus{}, errors.New(errMsg) + } else { + return latticemodel.ListenerStatus{}, err1 + } + } - if err == nil { + lis, err2 := d.findListenerByNamePort(ctx, *svc.Id, listener.Spec.Port) + glog.V(6).Infof("findListenerByNamePort %v , listener %v error %v\n", listener, lis, err2) + + if err2 == nil { // update Listener - // TODO k8sname, k8snamespace := latticeName2k8s(aws.StringValue(lis.Name)) return latticemodel.ListenerStatus{ Name: k8sname, @@ -61,7 +76,7 @@ func (s *defaultListenerManager) Create(ctx context.Context, listener *latticemo Protocol: aws.StringValue(lis.Protocol), ListenerARN: aws.StringValue(lis.Arn), ListenerID: aws.StringValue(lis.Id), - ServiceID: serviceStatus.ID, + ServiceID: aws.StringValue(svc.Id), }, nil } @@ -79,13 +94,11 @@ func (s *defaultListenerManager) Create(ctx context.Context, listener *latticemo Name: aws.String(k8sLatticeListenerName(listener.Spec.Name, listener.Spec.Namespace, int(listener.Spec.Port), listener.Spec.Protocol)), Port: aws.Int64(listener.Spec.Port), Protocol: aws.String(listener.Spec.Protocol), - ServiceIdentifier: aws.String(serviceStatus.ID), + ServiceIdentifier: aws.String(*svc.Id), Tags: nil, } - latticeSess := s.cloud.Lattice() - - resp, err := latticeSess.CreateListener(&listenerInput) + resp, err := d.cloud.Lattice().CreateListener(&listenerInput) glog.V(2).Infoln("############req creating listner ###########") glog.V(2).Infoln(listenerInput) @@ -97,39 +110,31 @@ func (s *defaultListenerManager) Create(ctx context.Context, listener *latticemo Namespace: listener.Spec.Namespace, ListenerARN: aws.StringValue(resp.Arn), ListenerID: aws.StringValue(resp.Id), - ServiceID: serviceStatus.ID, + ServiceID: aws.StringValue(svc.Id), Port: listener.Spec.Port, Protocol: listener.Spec.Protocol}, nil } -func k8s2LatticeName(name string, namespace string) string { - // TODO handle namespace - return name - -} - func k8sLatticeListenerName(name string, namespace string, port int, protocol string) string { listenerName := fmt.Sprintf("%s-%s-%d-%s", utils.Truncate(name, 20), utils.Truncate(namespace, 18), port, strings.ToLower(protocol)) return listenerName } func latticeName2k8s(name string) (string, string) { - // TODO handle namespace return name, "default" } -func (s *defaultListenerManager) List(ctx context.Context, serviceID string) ([]*vpclattice.ListenerSummary, error) { +func (d *defaultListenerManager) List(ctx context.Context, serviceID string) ([]*vpclattice.ListenerSummary, error) { var sdkListeners []*vpclattice.ListenerSummary glog.V(6).Infof("List - defaultListenerManager serviceID %v \n", serviceID) - latticeSess := s.cloud.Lattice() listenerListInput := vpclattice.ListListenersInput{ ServiceIdentifier: aws.String(serviceID), } - resp, err := latticeSess.ListListeners(&listenerListInput) + resp, err := d.cloud.Lattice().ListListeners(&listenerListInput) if err != nil { glog.V(6).Infof("defaultListenerManager: Failed to list service err %v \n", err) @@ -156,14 +161,13 @@ func (s *defaultListenerManager) List(ctx context.Context, serviceID string) ([] } -func (s *defaultListenerManager) findListenerByNamePort(ctx context.Context, serviceID string, port int64) (*vpclattice.ListenerSummary, error) { +func (d *defaultListenerManager) findListenerByNamePort(ctx context.Context, serviceID string, port int64) (*vpclattice.ListenerSummary, error) { glog.V(6).Infof("calling findListenerByNamePort serviceID %v port %d \n", serviceID, port) - latticeSess := s.cloud.Lattice() listenerListInput := vpclattice.ListListenersInput{ ServiceIdentifier: aws.String(serviceID), } - resp, err := latticeSess.ListListeners(&listenerListInput) + resp, err := d.cloud.Lattice().ListListenersWithContext(ctx, &listenerListInput) if err == nil { for _, r := range resp.Items { @@ -182,7 +186,7 @@ func (s *defaultListenerManager) findListenerByNamePort(ctx context.Context, ser return nil, errors.New("Listener does not exist") } -func (s *defaultListenerManager) Delete(ctx context.Context, listenerID string, serviceID string) error { +func (d *defaultListenerManager) Delete(ctx context.Context, listenerID string, serviceID string) error { // TODO glog.V(6).Infof("listern--Delete >>> listener %v in service %v\n", listenerID, serviceID) @@ -191,7 +195,7 @@ func (s *defaultListenerManager) Delete(ctx context.Context, listenerID string, ListenerIdentifier: aws.String(listenerID), } - resp, err := s.cloud.Lattice().DeleteListener(&listenerDeleteInput) + resp, err := d.cloud.Lattice().DeleteListener(&listenerDeleteInput) glog.V(2).Infoln("############ req delete listner ###########") glog.V(2).Infoln(listenerDeleteInput) diff --git a/pkg/deploy/lattice/listener_manager_mock.go b/pkg/deploy/lattice/listener_manager_mock.go index d1d5b8ec..1fb8664e 100644 --- a/pkg/deploy/lattice/listener_manager_mock.go +++ b/pkg/deploy/lattice/listener_manager_mock.go @@ -8,6 +8,7 @@ import ( context "context" reflect "reflect" + aws "github.com/aws/aws-application-networking-k8s/pkg/aws" lattice "github.com/aws/aws-application-networking-k8s/pkg/model/lattice" vpclattice "github.com/aws/aws-sdk-go/service/vpclattice" gomock "github.com/golang/mock/gomock" @@ -36,6 +37,20 @@ func (m *MockListenerManager) EXPECT() *MockListenerManagerMockRecorder { return m.recorder } +// Cloud mocks base method. +func (m *MockListenerManager) Cloud() aws.Cloud { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Cloud") + ret0, _ := ret[0].(aws.Cloud) + return ret0 +} + +// Cloud indicates an expected call of Cloud. +func (mr *MockListenerManagerMockRecorder) Cloud() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Cloud", reflect.TypeOf((*MockListenerManager)(nil).Cloud)) +} + // Create mocks base method. func (m *MockListenerManager) Create(ctx context.Context, service *lattice.Listener) (lattice.ListenerStatus, error) { m.ctrl.T.Helper() diff --git a/pkg/deploy/lattice/listener_manager_test.go b/pkg/deploy/lattice/listener_manager_test.go index b6b217a0..15dc5e52 100644 --- a/pkg/deploy/lattice/listener_manager_test.go +++ b/pkg/deploy/lattice/listener_manager_test.go @@ -80,19 +80,19 @@ func Test_AddListener(t *testing.T) { noServiceID bool }{ { - name: "add listner", + name: "add listener", isUpdate: false, noServiceID: false, }, { - name: "update listner", + name: "update listener", isUpdate: true, noServiceID: false, }, { - name: "add listner, no service ID", + name: "add listener, no service ID", isUpdate: false, noServiceID: true, }, @@ -104,11 +104,9 @@ func Test_AddListener(t *testing.T) { defer c.Finish() ctx := context.TODO() - mockVpcLatticeSess := mocks.NewMockLattice(c) - + mockLattice := mocks.NewMockLattice(c) mockCloud := mocks_aws.NewMockCloud(c) - - mockCloud.EXPECT().Lattice().Return(mockVpcLatticeSess).AnyTimes() + mockCloud.EXPECT().Lattice().Return(mockLattice).AnyTimes() latticeDataStore := latticestore.NewLatticeDataStore() listenerManager := NewListenerManager(mockCloud, latticeDataStore) @@ -117,12 +115,6 @@ func Test_AddListener(t *testing.T) { var serviceARN = "serviceARN" var serviceDNS = "DNS-test" - if !tt.noServiceID { - // Add service to ds - latticeDataStore.AddLatticeService(namespaceName.Name, namespaceName.Namespace, serviceARN, serviceID, serviceDNS) - - } - stack := core.NewDefaultStack(core.StackID(namespaceName)) action := latticemodel.DefaultAction{ @@ -137,6 +129,21 @@ func Test_AddListener(t *testing.T) { listener := latticemodel.NewListener(stack, listenerResourceName, int64(listenersummarys[0].Port), "HTTP", namespaceName.Name, namespaceName.Namespace, action) + if !tt.noServiceID { + mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( + &vpclattice.ServiceSummary{ + Name: aws.String((&ListenerNameProvider{listener}).LatticeName()), + Arn: aws.String(serviceARN), + Id: aws.String(serviceID), + DnsEntry: &vpclattice.DnsEntry{ + DomainName: aws.String(serviceDNS), + HostedZoneId: aws.String("my-favourite-zone"), + }, + }, nil).Times(1) + } else { + mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return(nil, &mocks.NotFoundError{}).Times(1) + } + listenerOutput := vpclattice.CreateListenerOutput{} listenerInput := vpclattice.CreateListenerInput{} @@ -148,15 +155,13 @@ func Test_AddListener(t *testing.T) { defaultAction := vpclattice.RuleAction{ FixedResponse: &defaultResp, } - //listenerARN := "listener-ARN" - //listenerID := "listener-ID" - if !tt.noServiceID && !tt.isUpdate { - listername := k8sLatticeListenerName(namespaceName.Name, namespaceName.Namespace, + if !tt.noServiceID && !tt.isUpdate { + listenerName := k8sLatticeListenerName(namespaceName.Name, namespaceName.Namespace, int(listenersummarys[0].Port), listenersummarys[0].Protocol) listenerInput = vpclattice.CreateListenerInput{ DefaultAction: &defaultAction, - Name: &listername, + Name: &listenerName, ServiceIdentifier: &serviceID, Protocol: aws.String("HTTP"), Port: aws.Int64(listenersummarys[0].Port), @@ -166,11 +171,10 @@ func Test_AddListener(t *testing.T) { DefaultAction: &defaultAction, Id: &listenersummarys[0].Id, } - mockVpcLatticeSess.EXPECT().CreateListener(&listenerInput).Return(&listenerOutput, nil) + mockLattice.EXPECT().CreateListener(&listenerInput).Return(&listenerOutput, nil) } if !tt.noServiceID { - listenerListInput := vpclattice.ListListenersInput{ ServiceIdentifier: aws.String(serviceID), } @@ -178,12 +182,10 @@ func Test_AddListener(t *testing.T) { listenerOutput := vpclattice.ListListenersOutput{} if tt.isUpdate { - listenerOutput = listenerList - } - mockVpcLatticeSess.EXPECT().ListListeners(&listenerListInput).Return(&listenerOutput, nil) + mockLattice.EXPECT().ListListenersWithContext(ctx, &listenerListInput).Return(&listenerOutput, nil) } resp, err := listenerManager.Create(ctx, listener) diff --git a/pkg/deploy/lattice/listener_synthesizer.go b/pkg/deploy/lattice/listener_synthesizer.go index 67663e6b..eaa01dd8 100644 --- a/pkg/deploy/lattice/listener_synthesizer.go +++ b/pkg/deploy/lattice/listener_synthesizer.go @@ -15,7 +15,7 @@ import ( ) type listenerSynthesizer struct { - listener ListenerManager + listenerMgr ListenerManager stack core.Stack latticestore *latticestore.LatticeDataStore } @@ -23,7 +23,7 @@ type listenerSynthesizer struct { func NewListenerSynthesizer(ListenerManager ListenerManager, stack core.Stack, store *latticestore.LatticeDataStore) *listenerSynthesizer { return &listenerSynthesizer{ - listener: ListenerManager, + listenerMgr: ListenerManager, stack: stack, latticestore: store, } @@ -37,7 +37,7 @@ func (l *listenerSynthesizer) Synthesize(ctx context.Context) error { glog.V(6).Infof("Synthesize Listener: %v\n", resListener) for _, listener := range resListener { - status, err := l.listener.Create(ctx, listener) + status, err := l.listenerMgr.Create(ctx, listener) if err != nil { errmsg := fmt.Sprintf("ListenerSynthesie: failed to create listener %v, err %v", listener, err) @@ -53,8 +53,7 @@ func (l *listenerSynthesizer) Synthesize(ctx context.Context) error { // handle delete sdkListeners, err := l.getSDKListeners(ctx) - - glog.V(6).Infof("getSDKlistener: %v, err: %v\n", sdkListeners, err) + glog.V(6).Infof("getSDKlistener result: %v, err: %v\n", sdkListeners, err) for _, sdkListener := range sdkListeners { _, err := l.findMatchListener(ctx, sdkListener, resListener) @@ -64,7 +63,7 @@ func (l *listenerSynthesizer) Synthesize(ctx context.Context) error { } glog.V(6).Infof("ListenerSynthesize >>>> delete staled sdk listener %v\n", *sdkListener) - l.listener.Delete(ctx, sdkListener.ListenerID, sdkListener.ServiceID) + l.listenerMgr.Delete(ctx, sdkListener.ListenerID, sdkListener.ServiceID) k8sname, k8snamespace := latticeName2k8s(sdkListener.Name) l.latticestore.DelListener(k8sname, k8snamespace, sdkListener.Port, sdkListener.Protocol) @@ -96,17 +95,16 @@ func (l *listenerSynthesizer) getSDKListeners(ctx context.Context) ([]*latticemo var resService []*latticemodel.Service err := l.stack.ListResources(&resService) - - glog.V(6).Infof("getSDKListeners service: %v err: %v \n", resService, err) + glog.V(6).Infof("service: %v ignore err: %v \n", resService, err) for _, service := range resService { - latticeService, err := l.latticestore.GetLatticeService(service.Spec.Name, service.Spec.Namespace) + latticeService, err := l.listenerMgr.Cloud().Lattice().FindService(ctx, service) if err != nil { - glog.V(6).Infof("getSDKRules: failed to find in store, service: %v, err: %v \n", service, err) - return sdkListeners, errors.New("getSDKRules: failed to find service in store") + glog.V(6).Infof("failed to find in store, service: %v, err: %v \n", service, err) + return sdkListeners, errors.New("failed to find service in store") } - listenerSummaries, err := l.listener.List(ctx, latticeService.ID) + listenerSummaries, err := l.listenerMgr.List(ctx, aws.StringValue(latticeService.Id)) for _, listenerSummary := range listenerSummaries { @@ -114,7 +112,7 @@ func (l *listenerSynthesizer) getSDKListeners(ctx context.Context) ([]*latticemo Name: aws.StringValue(listenerSummary.Name), ListenerARN: aws.StringValue(listenerSummary.Arn), ListenerID: aws.StringValue(listenerSummary.Id), - ServiceID: aws.StringValue(&latticeService.ID), + ServiceID: aws.StringValue(latticeService.Id), Port: aws.Int64Value(listenerSummary.Port), Protocol: aws.StringValue(listenerSummary.Protocol), }) diff --git a/pkg/deploy/lattice/listener_synthesizer_test.go b/pkg/deploy/lattice/listener_synthesizer_test.go index a4cae409..a567da71 100644 --- a/pkg/deploy/lattice/listener_synthesizer_test.go +++ b/pkg/deploy/lattice/listener_synthesizer_test.go @@ -2,6 +2,10 @@ package lattice import ( "context" + "github.com/aws/aws-application-networking-k8s/pkg/aws" + "github.com/aws/aws-application-networking-k8s/pkg/aws/services" + sdk "github.com/aws/aws-sdk-go/aws" + //"errors" "fmt" "testing" @@ -104,6 +108,11 @@ func Test_SynthesizeListener(t *testing.T) { stack := core.NewDefaultStack(core.StackID(k8s.NamespacedName(tt.httpRoute))) mockListenerManager := NewMockListenerManager(c) + mockCloud := aws.NewMockCloud(c) + mockLattice := services.NewMockLattice(c) + + mockListenerManager.EXPECT().Cloud().Return(mockCloud).AnyTimes() + mockCloud.EXPECT().Lattice().Return(mockLattice).AnyTimes() pro := "HTTP" protocols := []*string{&pro} @@ -125,7 +134,13 @@ func Test_SynthesizeListener(t *testing.T) { BackendServiceNamespace: "default", } - latticemodel.NewLatticeService(stack, "", spec) + stackService := latticemodel.NewLatticeService(stack, "", spec) + mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( + &vpclattice.ServiceSummary{ + Name: sdk.String(stackService.LatticeName()), + Arn: sdk.String("svc-arn"), + Id: sdk.String(tt.serviceID), + }, nil) port := int64(tt.gwListenerPort) @@ -140,7 +155,6 @@ func Test_SynthesizeListener(t *testing.T) { }, }, tt.mgrErr) - ds.AddLatticeService(tt.httpRoute.Name, tt.httpRoute.Namespace, tt.serviceARN, tt.serviceID, "dns") if !tt.wantIsDeleted { listenerResourceName := fmt.Sprintf("%s-%s-%d-%s", tt.httpRoute.Name, tt.httpRoute.Namespace, tt.gwListenerPort, protocol) diff --git a/pkg/deploy/lattice/rule_manager.go b/pkg/deploy/lattice/rule_manager.go index 08c16d2c..d5d123fc 100644 --- a/pkg/deploy/lattice/rule_manager.go +++ b/pkg/deploy/lattice/rule_manager.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "github.com/aws/aws-application-networking-k8s/pkg/utils" "github.com/golang/glog" "strings" @@ -17,6 +18,7 @@ import ( ) type RuleManager interface { + Cloud() lattice_aws.Cloud Create(ctx context.Context, rule *latticemodel.Rule) (latticemodel.RuleStatus, error) Delete(ctx context.Context, ruleID string, listenerID string, serviceID string) error Update(ctx context.Context, rules []*latticemodel.Rule) error @@ -36,6 +38,18 @@ func NewRuleManager(cloud lattice_aws.Cloud, store *latticestore.LatticeDataStor } } +func (r *defaultRuleManager) Cloud() lattice_aws.Cloud { + return r.cloud +} + +type RuleNameProvider struct { + rule *latticemodel.Rule +} + +func (r *RuleNameProvider) LatticeName() string { + return utils.LatticeServiceName(r.rule.Spec.ServiceName, r.rule.Spec.ServiceNamespace) +} + func (r *defaultRuleManager) Get(ctx context.Context, serviceID string, listernID string, ruleID string) (*vpclattice.GetRuleOutput, error) { getruleInput := vpclattice.GetRuleInput{ ListenerIdentifier: aws.String(listernID), @@ -92,8 +106,7 @@ func (r *defaultRuleManager) Update(ctx context.Context, rules []*latticemodel.R glog.V(6).Infof("Rule --- update >>>>>>>>.%v\n", rules) - latticeService, err := r.latticeDataStore.GetLatticeService(rules[0].Spec.ServiceName, rules[0].Spec.ServiceNamespace) - + latticeService, err := r.cloud.Lattice().FindService(ctx, &RuleNameProvider{rules[0]}) if err != nil { errmsg := fmt.Sprintf("Service %v not found during rule creation", rules[0].Spec) glog.V(2).Infof("Error during update rule %s \n", errmsg) @@ -122,7 +135,7 @@ func (r *defaultRuleManager) Update(ctx context.Context, rules []*latticemodel.R // batchupdate rules using right priority batchRuleInput := vpclattice.BatchUpdateRuleInput{ ListenerIdentifier: aws.String(listener.ID), - ServiceIdentifier: aws.String(latticeService.ID), + ServiceIdentifier: aws.String(*latticeService.Id), Rules: ruleUpdateList, } @@ -139,10 +152,9 @@ func (r *defaultRuleManager) Update(ctx context.Context, rules []*latticemodel.R func (r *defaultRuleManager) Create(ctx context.Context, rule *latticemodel.Rule) (latticemodel.RuleStatus, error) { glog.V(6).Infof("Rule --- Create >>>>>>>>.%v\n", *rule) - latticeService, err := r.latticeDataStore.GetLatticeService(rule.Spec.ServiceName, rule.Spec.ServiceNamespace) - + latticeService, err := r.cloud.Lattice().FindService(ctx, &RuleNameProvider{rule}) if err != nil { - errmsg := fmt.Sprintf("Service %v not found during rule creation", rule.Spec) + errmsg := fmt.Sprintf("Service %v not found during rule creation, err: %v", rule.Spec, err) glog.V(2).Infof("Error during create rule %s \n", errmsg) return latticemodel.RuleStatus{}, errors.New(errmsg) } @@ -164,7 +176,7 @@ func (r *defaultRuleManager) Create(ctx context.Context, rule *latticemodel.Rule return latticemodel.RuleStatus{}, errors.New("failed to create rule, due to invalid ruleID") } - ruleStatus, err := r.findMatchingRule(ctx, rule, latticeService.ID, listener.ID) + ruleStatus, err := r.findMatchingRule(ctx, rule, *latticeService.Id, listener.ID) if err == nil && !ruleStatus.UpdateTGsNeeded { @@ -217,7 +229,7 @@ func (r *defaultRuleManager) Create(ctx context.Context, rule *latticemodel.Rule HttpMatch: &httpMatch, }, Priority: aws.Int64(ruleStatus.Priority), - ServiceIdentifier: aws.String(latticeService.ID), + ServiceIdentifier: aws.String(*latticeService.Id), RuleIdentifier: aws.String(ruleStatus.RuleID), } @@ -230,7 +242,7 @@ func (r *defaultRuleManager) Create(ctx context.Context, rule *latticemodel.Rule return latticemodel.RuleStatus{ RuleID: aws.StringValue(resp.Id), UpdatePriorityNeeded: ruleStatus.UpdatePriorityNeeded, - ServiceID: latticeService.ID, + ServiceID: aws.StringValue(latticeService.Id), ListenerID: listener.ID, }, nil @@ -253,7 +265,7 @@ func (r *defaultRuleManager) Create(ctx context.Context, rule *latticemodel.Rule }, Name: aws.String(ruleName), Priority: aws.Int64(ruleStatus.Priority), - ServiceIdentifier: aws.String(latticeService.ID), + ServiceIdentifier: aws.String(*latticeService.Id), } resp, err := r.cloud.Lattice().CreateRule(&ruleInput) @@ -268,7 +280,7 @@ func (r *defaultRuleManager) Create(ctx context.Context, rule *latticemodel.Rule return latticemodel.RuleStatus{ RuleID: *resp.Id, ListenerID: listener.ID, - ServiceID: latticeService.ID, + ServiceID: aws.StringValue(latticeService.Id), UpdatePriorityNeeded: ruleStatus.UpdatePriorityNeeded, UpdateTGsNeeded: ruleStatus.UpdatePriorityNeeded, }, nil diff --git a/pkg/deploy/lattice/rule_manager_mock.go b/pkg/deploy/lattice/rule_manager_mock.go index 351199f3..70a0a3eb 100644 --- a/pkg/deploy/lattice/rule_manager_mock.go +++ b/pkg/deploy/lattice/rule_manager_mock.go @@ -8,6 +8,7 @@ import ( context "context" reflect "reflect" + aws "github.com/aws/aws-application-networking-k8s/pkg/aws" lattice "github.com/aws/aws-application-networking-k8s/pkg/model/lattice" vpclattice "github.com/aws/aws-sdk-go/service/vpclattice" gomock "github.com/golang/mock/gomock" @@ -36,6 +37,20 @@ func (m *MockRuleManager) EXPECT() *MockRuleManagerMockRecorder { return m.recorder } +// Cloud mocks base method. +func (m *MockRuleManager) Cloud() aws.Cloud { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Cloud") + ret0, _ := ret[0].(aws.Cloud) + return ret0 +} + +// Cloud indicates an expected call of Cloud. +func (mr *MockRuleManagerMockRecorder) Cloud() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Cloud", reflect.TypeOf((*MockRuleManager)(nil).Cloud)) +} + // Create mocks base method. func (m *MockRuleManager) Create(ctx context.Context, rule *lattice.Rule) (lattice.RuleStatus, error) { m.ctrl.T.Helper() diff --git a/pkg/deploy/lattice/rule_manager_test.go b/pkg/deploy/lattice/rule_manager_test.go index 5fe25a8a..d25bb097 100644 --- a/pkg/deploy/lattice/rule_manager_test.go +++ b/pkg/deploy/lattice/rule_manager_test.go @@ -524,19 +524,27 @@ func Test_CreateRule(t *testing.T) { defer c.Finish() ctx := context.TODO() - mockVpcLatticeSess := mocks.NewMockLattice(c) - + mockLattice := mocks.NewMockLattice(c) mockCloud := mocks_aws.NewMockCloud(c) - - mockCloud.EXPECT().Lattice().Return(mockVpcLatticeSess).AnyTimes() + mockCloud.EXPECT().Lattice().Return(mockLattice).AnyTimes() latticeDataStore := latticestore.NewLatticeDataStore() ruleManager := NewRuleManager(mockCloud, latticeDataStore) if !tt.noServiceID { - latticeDataStore.AddLatticeService(tt.newRule.Spec.ServiceName, tt.newRule.Spec.ServiceNamespace, "serviceARN", - tt.newRule.Status.ServiceID, "test-dns") + mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( + &vpclattice.ServiceSummary{ + Name: aws.String((&RuleNameProvider{tt.newRule}).LatticeName()), + Arn: aws.String("serviceARN"), + Id: aws.String(tt.newRule.Status.ServiceID), + DnsEntry: &vpclattice.DnsEntry{ + DomainName: aws.String("test-dns"), + HostedZoneId: aws.String("my-favourite-zone"), + }, + }, nil).Times(1) + } else { + mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return(nil, &mocks.NotFoundError{}).Times(1) } if !tt.noListenerID { @@ -571,7 +579,7 @@ func Test_CreateRule(t *testing.T) { Items: items, } } - mockVpcLatticeSess.EXPECT().ListRules(&ruleInput).Return(&ruleOutput, nil) + mockLattice.EXPECT().ListRules(&ruleInput).Return(&ruleOutput, nil) if tt.oldRule != nil { ruleGetInput := vpclattice.GetRuleInput{ @@ -608,7 +616,7 @@ func Test_CreateRule(t *testing.T) { }, } - mockVpcLatticeSess.EXPECT().GetRule(&ruleGetInput).Return(&ruleGetOutput, nil) + mockLattice.EXPECT().GetRule(&ruleGetInput).Return(&ruleGetOutput, nil) } } @@ -653,7 +661,7 @@ func Test_CreateRule(t *testing.T) { ruleOutput := vpclattice.CreateRuleOutput{ Id: aws.String(ruleID), } - mockVpcLatticeSess.EXPECT().CreateRule(&ruleInput).Return(&ruleOutput, nil) + mockLattice.EXPECT().CreateRule(&ruleInput).Return(&ruleOutput, nil) } if tt.updateRule { @@ -693,7 +701,7 @@ func Test_CreateRule(t *testing.T) { ruleOutput := vpclattice.UpdateRuleOutput{ Id: aws.String(ruleID), } - mockVpcLatticeSess.EXPECT().UpdateRule(&ruleInput).Return(&ruleOutput, nil) + mockLattice.EXPECT().UpdateRule(&ruleInput).Return(&ruleOutput, nil) } } @@ -741,11 +749,9 @@ func Test_UpdateRule(t *testing.T) { defer c.Finish() ctx := context.TODO() - mockVpcLatticeSess := mocks.NewMockLattice(c) - + mockLattice := mocks.NewMockLattice(c) mockCloud := mocks_aws.NewMockCloud(c) - - mockCloud.EXPECT().Lattice().Return(mockVpcLatticeSess).AnyTimes() + mockCloud.EXPECT().Lattice().Return(mockLattice).AnyTimes() latticeDataStore := latticestore.NewLatticeDataStore() @@ -753,9 +759,18 @@ func Test_UpdateRule(t *testing.T) { var i = 0 if !tt.noServiceID { - - latticeDataStore.AddLatticeService(rules[i].Spec.ServiceName, rules[i].Spec.ServiceNamespace, "serviceARN", - rules[i].Status.ServiceID, "test-dns") + mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( + &vpclattice.ServiceSummary{ + Name: aws.String((&RuleNameProvider{rules[i]}).LatticeName()), + Arn: aws.String("serviceARN"), + Id: aws.String(rules[i].Status.ServiceID), + DnsEntry: &vpclattice.DnsEntry{ + DomainName: aws.String("test-dns"), + HostedZoneId: aws.String("my-favourite-zone"), + }, + }, nil).Times(1) + } else { + mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return(nil, &mocks.NotFoundError{}).Times(1) } if !tt.noListenerID { @@ -785,7 +800,7 @@ func Test_UpdateRule(t *testing.T) { if !tt.noListenerID && !tt.noServiceID { var batchRuleOutput vpclattice.BatchUpdateRuleOutput - mockVpcLatticeSess.EXPECT().BatchUpdateRule(&batchRuleInput).Return(&batchRuleOutput, nil) + mockLattice.EXPECT().BatchUpdateRule(&batchRuleInput).Return(&batchRuleOutput, nil) } err := ruleManager.Update(ctx, rules) diff --git a/pkg/deploy/lattice/rule_synthesizer.go b/pkg/deploy/lattice/rule_synthesizer.go index 30083cdc..f9ee6ecd 100644 --- a/pkg/deploy/lattice/rule_synthesizer.go +++ b/pkg/deploy/lattice/rule_synthesizer.go @@ -3,6 +3,7 @@ package lattice import ( "context" "errors" + "github.com/aws/aws-sdk-go/aws" "github.com/golang/glog" "github.com/aws/aws-application-networking-k8s/pkg/latticestore" @@ -123,11 +124,10 @@ func (r *ruleSynthesizer) getSDKRules(ctx context.Context) ([]*latticemodel.Rule glog.V(6).Infof("getSDKRules, rule %v err %v \n", resRule, err) for _, service := range resService { - latticeService, err := r.latticestore.GetLatticeService(service.Spec.Name, service.Spec.Namespace) - + latticeService, err := r.rule.Cloud().Lattice().FindService(ctx, service) if err != nil { - glog.V(6).Infof("getSDKRules: failed to find service in store service %v, err %v \n", service, err) - return sdkRules, errors.New("getSDKRules: failed to find service in store") + glog.V(6).Infof("getSDKRules: failed to find service %v, err %v \n", service, err) + return sdkRules, errors.New("getSDKRules: failed to find service") } listeners, err := r.latticestore.GetAllListeners(service.Spec.Name, service.Spec.Namespace) @@ -139,7 +139,7 @@ func (r *ruleSynthesizer) getSDKRules(ctx context.Context) ([]*latticemodel.Rule } for _, listener := range listeners { - rules, _ := r.rule.List(ctx, latticeService.ID, listener.ID) + rules, _ := r.rule.List(ctx, aws.StringValue(latticeService.Id), listener.ID) sdkRules = append(sdkRules, rules...) diff --git a/pkg/deploy/lattice/rule_synthesizer_test.go b/pkg/deploy/lattice/rule_synthesizer_test.go index 2d32277a..aacd1bc7 100644 --- a/pkg/deploy/lattice/rule_synthesizer_test.go +++ b/pkg/deploy/lattice/rule_synthesizer_test.go @@ -2,6 +2,9 @@ package lattice import ( "context" + "github.com/aws/aws-application-networking-k8s/pkg/aws" + "github.com/aws/aws-application-networking-k8s/pkg/aws/services" + //"errors" "fmt" "testing" @@ -9,6 +12,7 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" + sdk "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/vpclattice" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" gateway_api "sigs.k8s.io/gateway-api/apis/v1beta1" @@ -294,6 +298,11 @@ func Test_SynthesizeDeleteRule(t *testing.T) { ds := latticestore.NewLatticeDataStore() mockRuleManager := NewMockRuleManager(c) + mockCloud := aws.NewMockCloud(c) + mockLattice := services.NewMockLattice(c) + + mockRuleManager.EXPECT().Cloud().Return(mockCloud).AnyTimes() + mockCloud.EXPECT().Lattice().Return(mockLattice).AnyTimes() var serviceName = "service1" var serviceNamespace = "test" @@ -313,9 +322,14 @@ func Test_SynthesizeDeleteRule(t *testing.T) { Namespace: serviceNamespace, Protocols: protocols, } - latticemodel.NewLatticeService(stack, "", spec) - - ds.AddLatticeService(serviceName, serviceNamespace, "servicearn", serviceID, "test-dns") + stackService := latticemodel.NewLatticeService(stack, "", spec) + + mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( + &vpclattice.ServiceSummary{ + Name: sdk.String(stackService.LatticeName()), + Arn: sdk.String("svc-arn"), + Id: sdk.String(serviceID), + }, nil) rule1 := latticemodel.RuleStatus{ RuleARN: "rule1-arn", diff --git a/pkg/deploy/lattice/service_manager.go b/pkg/deploy/lattice/service_manager.go index 86e67504..007c26ad 100644 --- a/pkg/deploy/lattice/service_manager.go +++ b/pkg/deploy/lattice/service_manager.go @@ -3,6 +3,7 @@ package lattice import ( "context" "fmt" + "github.com/aws/aws-application-networking-k8s/pkg/aws/services" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/vpclattice" @@ -46,21 +47,6 @@ func NewServiceManager(cloud lattice_aws.Cloud, latticeDataStore *latticestore.L } } -// find service by name, if not found returns nil without error -func (m *defaultServiceManager) getService(ctx context.Context, svcName string) (*vpclattice.ServiceSummary, error) { - svcsReq := vpclattice.ListServicesInput{} - svcsResp, err := m.cloud.Lattice().ListServicesAsList(ctx, &svcsReq) - if err != nil { - return nil, err - } - for _, r := range svcsResp { - if aws.StringValue(r.Name) == svcName { - return r, nil - } - } - return nil, nil -} - func (m *defaultServiceManager) createServiceAndAssociate(ctx context.Context, svc *Service) (ServiceInfo, error) { createSvcReq := m.newCreateSvcReq(svc) createSvcResp, err := m.cloud.Lattice().CreateServiceWithContext(ctx, createSvcReq) @@ -83,9 +69,6 @@ func (m *defaultServiceManager) createAssociation(ctx context.Context, svcId *st if err != nil { return err } - if snInfo == nil { - return fmt.Errorf("Service network %s for account %s not found", snName, m.cloud.Config().AccountId) - } assocReq := &CreateSnSvcAssocReq{ ServiceIdentifier: svcId, @@ -292,8 +275,8 @@ func (m *defaultServiceManager) deleteService(ctx context.Context, svc *SvcSumma // Create or update Service and ServiceNetwork-Service associations func (m *defaultServiceManager) Create(ctx context.Context, svc *Service) (ServiceInfo, error) { - svcSum, err := m.getService(ctx, svc.LatticeName()) - if err != nil { + svcSum, err := m.cloud.Lattice().FindService(ctx, svc) + if err != nil && !services.IsNotFoundError(err) { return ServiceInfo{}, err } @@ -310,12 +293,13 @@ func (m *defaultServiceManager) Create(ctx context.Context, svc *Service) (Servi } func (m *defaultServiceManager) Delete(ctx context.Context, svc *Service) error { - svcSum, err := m.getService(ctx, svc.LatticeName()) + svcSum, err := m.cloud.Lattice().FindService(ctx, svc) if err != nil { - return err - } - if svcSum == nil { - return nil // already deleted + if services.IsNotFoundError(err) { + return nil // already deleted + } else { + return err + } } err = m.deleteAllAssociations(ctx, svcSum) diff --git a/pkg/deploy/lattice/service_manager_test.go b/pkg/deploy/lattice/service_manager_test.go index 457c3419..bd1c6d4f 100644 --- a/pkg/deploy/lattice/service_manager_test.go +++ b/pkg/deploy/lattice/service_manager_test.go @@ -42,8 +42,9 @@ func TestServiceManagerInteg(t *testing.T) { // service does not exist in lattice lat.EXPECT(). - ListServicesAsList(gomock.Any(), gomock.Any()). - Return([]*SvcSummary{}, nil) + FindService(gomock.Any(), gomock.Any()). + Return(nil, &services.NotFoundError{}). + Times(1) // assert that we call create service lat.EXPECT(). @@ -115,12 +116,12 @@ func TestServiceManagerInteg(t *testing.T) { // service exists in lattice lat.EXPECT(). - ListServicesAsList(gomock.Any(), gomock.Any()). - Return([]*SvcSummary{{ + FindService(gomock.Any(), gomock.Any()). + Return(&vpclattice.ServiceSummary{ Arn: aws.String("svc-arn"), Id: aws.String("svc-id"), Name: aws.String(svc.LatticeName()), - }}, nil). + }, nil). Times(1) // 3 associations exist in lattice: keep, delete, and foreign @@ -205,12 +206,12 @@ func TestServiceManagerInteg(t *testing.T) { // service exists lat.EXPECT(). - ListServicesAsList(gomock.Any(), gomock.Any()). - Return([]*SvcSummary{{ + FindService(gomock.Any(), gomock.Any()). + Return(&vpclattice.ServiceSummary{ Arn: aws.String("svc-arn"), Id: aws.String("svc-id"), Name: aws.String(svc.LatticeName()), - }}, nil) + }, nil) lat.EXPECT(). ListServiceNetworkServiceAssociationsAsList(gomock.Any(), gomock.Any()). Return([]*SnSvcAssocSummary{ diff --git a/pkg/deploy/lattice/service_network_manager.go b/pkg/deploy/lattice/service_network_manager.go index 3fe9667d..6740cb43 100644 --- a/pkg/deploy/lattice/service_network_manager.go +++ b/pkg/deploy/lattice/service_network_manager.go @@ -3,6 +3,7 @@ package lattice import ( "context" "errors" + "github.com/aws/aws-application-networking-k8s/pkg/aws/services" "github.com/golang/glog" "github.com/aws/aws-sdk-go/aws" @@ -53,7 +54,7 @@ type defaultServiceNetworkManager struct { func (m *defaultServiceNetworkManager) Create(ctx context.Context, service_network *latticemodel.ServiceNetwork) (latticemodel.ServiceNetworkStatus, error) { // check if exists service_networkSummary, err := m.cloud.Lattice().FindServiceNetwork(ctx, service_network.Spec.Name, "") - if err != nil { + if err != nil && !services.IsNotFoundError(err) { return latticemodel.ServiceNetworkStatus{ServiceNetworkARN: "", ServiceNetworkID: ""}, err } @@ -170,15 +171,15 @@ func (m *defaultServiceNetworkManager) List(ctx context.Context) ([]string, erro return service_networkList, nil } -func (m *defaultServiceNetworkManager) Delete(ctx context.Context, service_network string) error { - service_networkSummary, err := m.cloud.Lattice().FindServiceNetwork(ctx, service_network, "") +func (m *defaultServiceNetworkManager) Delete(ctx context.Context, snName string) error { + service_networkSummary, err := m.cloud.Lattice().FindServiceNetwork(ctx, snName, "") if err != nil { - return err - } - - if service_networkSummary == nil { - glog.V(2).Infof("Successfully deleted unknown service_network %v\n", service_network) - return nil + if services.IsNotFoundError(err) { + glog.V(2).Infoln("Service network not found, assume already deleted", snName) + return nil + } else { + return err + } } vpcLatticeSess := m.cloud.Lattice() @@ -197,9 +198,9 @@ func (m *defaultServiceNetworkManager) Delete(ctx context.Context, service_netwo } glog.V(2).Infof("DeleteServiceNetworkVpcAssociationInput >>>> %v\n", deleteServiceNetworkVpcAssociationInput) resp, err := vpcLatticeSess.DeleteServiceNetworkVpcAssociationWithContext(ctx, &deleteServiceNetworkVpcAssociationInput) - glog.V(2).Infof("DeleteServiceNetworkVPCAssociationResp: service_network %v , resp %v, err %v \n", service_network, resp, err) + glog.V(2).Infof("DeleteServiceNetworkVPCAssociationResp: service_network %v , resp %v, err %v \n", snName, resp, err) if err != nil { - glog.V(2).Infof("Failed to delete association for %v, err: %v \n", service_network, err) + glog.V(2).Infof("Failed to delete association for %v, err: %v \n", snName, err) } // retry later to check if VPC disassociation workflow finishes return errors.New(LATTICE_RETRY) @@ -214,9 +215,9 @@ func (m *defaultServiceNetworkManager) Delete(ctx context.Context, service_netwo needToDelete = true } else { if ok { - glog.V(2).Infof("Skip deleting, the service network[%v] is created by VPC %v", service_network, *vpcOwner) + glog.V(2).Infof("Skip deleting, the service network[%v] is created by VPC %v", snName, *vpcOwner) } else { - glog.V(2).Infof("Skip deleting, the service network[%v] is not created by K8S, since there is no tag", service_network) + glog.V(2).Infof("Skip deleting, the service network[%v] is not created by K8S, since there is no tag", snName) } } } @@ -224,25 +225,25 @@ func (m *defaultServiceNetworkManager) Delete(ctx context.Context, service_netwo if needToDelete { if len(assocResp) != 0 { - glog.V(2).Infof("Retry deleting %v later, due to service network still has VPCs associated", service_network) + glog.V(2).Infof("Retry deleting %v later, due to service network still has VPCs associated", snName) return errors.New(LATTICE_RETRY) } deleteInput := vpclattice.DeleteServiceNetworkInput{ ServiceNetworkIdentifier: &service_networkID, } - glog.V(2).Infof("DeleteServiceNetworkWithContext: service_network %v", service_network) + glog.V(2).Infof("DeleteServiceNetworkWithContext: service_network %v", snName) resp, err := vpcLatticeSess.DeleteServiceNetworkWithContext(ctx, &deleteInput) - glog.V(2).Infof("DeleteServiceNetworkWithContext: service_network %v , resp %v, err %v \n", service_network, resp, err) + glog.V(2).Infof("DeleteServiceNetworkWithContext: service_network %v , resp %v, err %v \n", snName, resp, err) if err != nil { return errors.New(LATTICE_RETRY) } - glog.V(2).Infof("Successfully delete service_network %v\n", service_network) + glog.V(2).Infof("Successfully delete service_network %v\n", snName) return err } else { - glog.V(2).Infof("Deleting service_network (%v) Skipped, since it is owned by different VPC ", service_network) + glog.V(2).Infof("Deleting service_network (%v) Skipped, since it is owned by different VPC ", snName) return nil } } diff --git a/pkg/deploy/lattice/service_network_manager_test.go b/pkg/deploy/lattice/service_network_manager_test.go index 643e0555..b343b1b7 100644 --- a/pkg/deploy/lattice/service_network_manager_test.go +++ b/pkg/deploy/lattice/service_network_manager_test.go @@ -3,12 +3,12 @@ package lattice import ( "context" "errors" + mocks_aws "github.com/aws/aws-application-networking-k8s/pkg/aws" + mocks "github.com/aws/aws-application-networking-k8s/pkg/aws/services" "github.com/aws/aws-application-networking-k8s/pkg/config" "github.com/aws/aws-sdk-go/service/vpclattice" "testing" - mocks_aws "github.com/aws/aws-application-networking-k8s/pkg/aws" - mocks "github.com/aws/aws-application-networking-k8s/pkg/aws/services" latticemodel "github.com/aws/aws-application-networking-k8s/pkg/model/lattice" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" @@ -46,8 +46,7 @@ func Test_CreateServiceNetwork_MeshNotExist_NoNeedToAssociate(t *testing.T) { mockLattice.EXPECT().CreateServiceNetworkWithContext(ctx, createServiceNetworkInput).Return(meshCreateOutput, nil) mockCloud.EXPECT().Lattice().Return(mockLattice).AnyTimes() - mockLattice.EXPECT(). - FindServiceNetwork(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + mockLattice.EXPECT().FindServiceNetwork(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, &mocks.NotFoundError{}).Times(1) meshManager := NewDefaultServiceNetworkManager(mockCloud) resp, err := meshManager.Create(ctx, &meshCreateInput) @@ -131,13 +130,12 @@ func Test_CreateServiceNetwork_ListFailed(t *testing.T) { mockCloud := mocks_aws.NewMockCloud(c) mockLattice.EXPECT().FindServiceNetwork(ctx, gomock.Any(), gomock.Any()).Return(nil, errors.New("ERROR")) - mockCloud.EXPECT().Lattice().Return(mockLattice) + mockCloud.EXPECT().Lattice().Return(mockLattice).AnyTimes() meshManager := NewDefaultServiceNetworkManager(mockCloud) resp, err := meshManager.Create(ctx, &meshCreateInput) assert.NotNil(t, err) - assert.Equal(t, err, errors.New("ERROR")) assert.Equal(t, resp.ServiceNetworkARN, "") assert.Equal(t, resp.ServiceNetworkID, "") } @@ -733,8 +731,8 @@ func Test_DeleteMesh_MeshNotExist(t *testing.T) { ctx := context.TODO() mockLattice := mocks.NewMockLattice(c) mockCloud := mocks_aws.NewMockCloud(c) - mockLattice.EXPECT().FindServiceNetwork(ctx, gomock.Any(), gomock.Any()).Return(nil, nil) - mockCloud.EXPECT().Lattice().Return(mockLattice) + mockLattice.EXPECT().FindServiceNetwork(ctx, gomock.Any(), gomock.Any()).Return(nil, &mocks.NotFoundError{}) + mockCloud.EXPECT().Lattice().Return(mockLattice).AnyTimes() meshManager := NewDefaultServiceNetworkManager(mockCloud) err := meshManager.Delete(ctx, "test") diff --git a/pkg/deploy/lattice/service_network_synthesizer.go b/pkg/deploy/lattice/service_network_synthesizer.go index d58a49f5..e69d0ad5 100644 --- a/pkg/deploy/lattice/service_network_synthesizer.go +++ b/pkg/deploy/lattice/service_network_synthesizer.go @@ -88,7 +88,7 @@ func (s *serviceNetworkSynthesizer) deleteServiceNetwork(ctx context.Context, re // TODO need to check if service network is referenced by gateway in other namespace gwList := &gateway_api.GatewayList{} - s.Client.List(context.TODO(), gwList) + s.Client.List(ctx, gwList) snUsedByGateway := false for _, gw := range gwList.Items { if gw.Name == resServiceNetwork.Spec.Name && @@ -108,6 +108,7 @@ func (s *serviceNetworkSynthesizer) deleteServiceNetwork(ctx context.Context, re err := s.serviceNetworkManager.Delete(ctx, resServiceNetwork.Spec.Name) if err != nil { + glog.V(6).Infof("Synthesizing Gateway delete failed for gateway %v error =%v\n ", resServiceNetwork.Spec.Name, err) return LATTICE_RETRY } else { glog.V(6).Infof("Synthesizing Gateway: successfully deleted gateway %v\n", resServiceNetwork.Spec.Name) diff --git a/pkg/deploy/lattice/service_synthesizer.go b/pkg/deploy/lattice/service_synthesizer.go index 02014892..f9073481 100644 --- a/pkg/deploy/lattice/service_synthesizer.go +++ b/pkg/deploy/lattice/service_synthesizer.go @@ -44,7 +44,6 @@ func (s *serviceSynthesizer) Synthesize(ctx context.Context) error { if err == nil { glog.V(6).Infof("service - Synthesizer: finish deleting service %v\n", *resService) - s.latticeDataStore.DelLatticeService(resService.Spec.Name, resService.Spec.Namespace) // also delete all listeners of this service listeners, err := s.latticeDataStore.GetAllListeners(resService.Spec.Name, resService.Spec.Namespace) @@ -68,9 +67,6 @@ func (s *serviceSynthesizer) Synthesize(ctx context.Context) error { return err } - s.latticeDataStore.AddLatticeService(resService.Spec.Name, resService.Spec.Namespace, - serviceStatus.Arn, serviceStatus.Id, serviceStatus.Dns) - glog.V(6).Infof("Creating Service DNS") resService.Status = &serviceStatus err = s.dnsEndpointManager.Create(ctx, resService) diff --git a/pkg/deploy/lattice/service_synthesizer_test.go b/pkg/deploy/lattice/service_synthesizer_test.go index 4d4052d4..0bfc719e 100644 --- a/pkg/deploy/lattice/service_synthesizer_test.go +++ b/pkg/deploy/lattice/service_synthesizer_test.go @@ -197,12 +197,6 @@ func Test_SynthesizeService(t *testing.T) { if tt.wantErrIsNil { assert.Nil(t, err) - if tt.httpRoute.DeletionTimestamp.IsZero() { - svc, err := ds.GetLatticeService(spec.Name, spec.Namespace) - assert.Nil(t, err) - assert.Equal(t, tt.serviceARN, svc.ARN) - assert.Equal(t, tt.serviceID, svc.ID) - } } else { assert.NotNil(t, err) } diff --git a/pkg/deploy/stack_deployer.go b/pkg/deploy/stack_deployer.go index 070df412..836b8294 100644 --- a/pkg/deploy/stack_deployer.go +++ b/pkg/deploy/stack_deployer.go @@ -26,11 +26,8 @@ type StackDeployer interface { type serviceNetworkStackDeployer struct { cloud aws.Cloud k8sclient client.Client - // TODO vpcID string - //TODO others latticeServiceNetworkManager lattice.ServiceNetworkManager - latticeDataStore *latticestore.LatticeDataStore } type ResourceSynthesizer interface { @@ -38,12 +35,11 @@ type ResourceSynthesizer interface { PostSynthesize(ctx context.Context) error } -func NewServiceNetworkStackDeployer(cloud aws.Cloud, k8sClient client.Client, latticeDataStore *latticestore.LatticeDataStore) *serviceNetworkStackDeployer { +func NewServiceNetworkStackDeployer(cloud aws.Cloud, k8sClient client.Client) *serviceNetworkStackDeployer { return &serviceNetworkStackDeployer{ cloud: cloud, k8sclient: k8sClient, latticeServiceNetworkManager: lattice.NewDefaultServiceNetworkManager(cloud), - latticeDataStore: latticeDataStore, } } diff --git a/pkg/deploy/stack_deployer_test.go b/pkg/deploy/stack_deployer_test.go index 9133608f..e60e681d 100644 --- a/pkg/deploy/stack_deployer_test.go +++ b/pkg/deploy/stack_deployer_test.go @@ -2,7 +2,10 @@ package deploy import ( "context" + "github.com/aws/aws-application-networking-k8s/pkg/aws/services" "github.com/aws/aws-application-networking-k8s/pkg/utils/gwlog" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/vpclattice" "testing" mock_client "github.com/aws/aws-application-networking-k8s/mocks/controller-runtime/client" @@ -23,33 +26,36 @@ func Test_latticeServiceStackDeployer_createAllResources(t *testing.T) { defer c.Finish() mockClient := mock_client.NewMockClient(c) - mockCloud := mocks_aws.NewMockCloud(c) - + mockLattice := services.NewMockLattice(c) mockServiceManager := lattice.NewMockServiceManager(c) - mockTargetGroupManager := lattice.NewMockTargetGroupManager(c) - mockListenerManager := lattice.NewMockListenerManager(c) - mockRuleManager := lattice.NewMockRuleManager(c) - mockDnsManager := externaldns.NewMockDnsEndpointManager(c) - mockTargetsManager := lattice.NewMockTargetsManager(c) - mockLatticeDataStore := latticestore.NewLatticeDataStore() ctx := context.TODO() s := core.NewDefaultStack(core.StackID(types.NamespacedName{Namespace: "tt", Name: "name"})) - latticemodel.NewLatticeService(s, "fake-service", latticemodel.ServiceSpec{}) + stackService := latticemodel.NewLatticeService(s, "fake-service", latticemodel.ServiceSpec{}) latticemodel.NewTargetGroup(s, "fake-targetGroup", latticemodel.TargetGroupSpec{}) latticemodel.NewTargets(s, "fake-target", latticemodel.TargetsSpec{}) latticemodel.NewListener(s, "fake-listener", 8080, "HTTP", "service1", "default", latticemodel.DefaultAction{}) latticemodel.NewRule(s, "fake-rule", "fake-rule", "default", 80, "HTTP", latticemodel.RuleAction{}, latticemodel.RuleSpec{}) + mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( + &vpclattice.ServiceSummary{ + Name: aws.String(stackService.LatticeName()), + Id: aws.String("fake-service"), + }, nil).AnyTimes() + + mockListenerManager.EXPECT().Cloud().Return(mockCloud).AnyTimes() + mockRuleManager.EXPECT().Cloud().Return(mockCloud).AnyTimes() + mockCloud.EXPECT().Lattice().Return(mockLattice).AnyTimes() + mockTargetGroupManager.EXPECT().List(gomock.Any()).AnyTimes() mockListenerManager.EXPECT().List(gomock.Any(), gomock.Any()).AnyTimes() @@ -83,21 +89,14 @@ func Test_latticeServiceStackDeployer_CreateJustService(t *testing.T) { defer c.Finish() mockClient := mock_client.NewMockClient(c) - mockCloud := mocks_aws.NewMockCloud(c) - + mockLattice := services.NewMockLattice(c) mockServiceManager := lattice.NewMockServiceManager(c) - mockTargetGroupManager := lattice.NewMockTargetGroupManager(c) - mockTargetsManager := lattice.NewMockTargetsManager(c) - mockListenerManager := lattice.NewMockListenerManager(c) - mockRuleManager := lattice.NewMockRuleManager(c) - mockDnsManager := externaldns.NewMockDnsEndpointManager(c) - mockLatticeDataStore := latticestore.NewLatticeDataStore() ctx := context.TODO() @@ -110,7 +109,17 @@ func Test_latticeServiceStackDeployer_CreateJustService(t *testing.T) { s := core.NewDefaultStack(core.StackID(types.NamespacedName{Namespace: "tt", Name: "name"})) - latticemodel.NewLatticeService(s, "fake-service", latticemodel.ServiceSpec{}) + stackService := latticemodel.NewLatticeService(s, "fake-service", latticemodel.ServiceSpec{}) + + mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( + &vpclattice.ServiceSummary{ + Name: aws.String(stackService.LatticeName()), + Id: aws.String("fake-service"), + }, nil).AnyTimes() + + mockListenerManager.EXPECT().Cloud().Return(mockCloud).AnyTimes() + mockRuleManager.EXPECT().Cloud().Return(mockCloud).AnyTimes() + mockCloud.EXPECT().Lattice().Return(mockLattice).AnyTimes() deployer := &LatticeServiceStackDeployer{ log: gwlog.FallbackLogger, @@ -135,29 +144,33 @@ func Test_latticeServiceStackDeployer_DeleteService(t *testing.T) { defer c.Finish() mockClient := mock_client.NewMockClient(c) - mockCloud := mocks_aws.NewMockCloud(c) - + mockLattice := services.NewMockLattice(c) mockServiceManager := lattice.NewMockServiceManager(c) - mockTargetGroupManager := lattice.NewMockTargetGroupManager(c) - mockListenerManager := lattice.NewMockListenerManager(c) - mockRuleManager := lattice.NewMockRuleManager(c) - mockTargetsManager := lattice.NewMockTargetsManager(c) - mockLatticeDataStore := latticestore.NewLatticeDataStore() ctx := context.TODO() s := core.NewDefaultStack(core.StackID(types.NamespacedName{Namespace: "tt", Name: "name"})) - latticemodel.NewLatticeService(s, "fake-service", latticemodel.ServiceSpec{ + stackService := latticemodel.NewLatticeService(s, "fake-service", latticemodel.ServiceSpec{ IsDeleted: true, }) + mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( + &vpclattice.ServiceSummary{ + Name: aws.String(stackService.LatticeName()), + Id: aws.String("fake-service"), + }, nil).AnyTimes() + + mockListenerManager.EXPECT().Cloud().Return(mockCloud).AnyTimes() + mockRuleManager.EXPECT().Cloud().Return(mockCloud).AnyTimes() + mockCloud.EXPECT().Lattice().Return(mockLattice).AnyTimes() + mockTargetGroupManager.EXPECT().List(gomock.Any()).AnyTimes() mockListenerManager.EXPECT().List(gomock.Any(), gomock.Any()).AnyTimes() @@ -185,32 +198,36 @@ func Test_latticeServiceStackDeployer_DeleteAllResources(t *testing.T) { defer c.Finish() mockClient := mock_client.NewMockClient(c) - mockCloud := mocks_aws.NewMockCloud(c) - + mockLattice := services.NewMockLattice(c) mockServiceManager := lattice.NewMockServiceManager(c) - mockTargetGroupManager := lattice.NewMockTargetGroupManager(c) - mockListenerManager := lattice.NewMockListenerManager(c) - mockRuleManager := lattice.NewMockRuleManager(c) - mockTargetsManager := lattice.NewMockTargetsManager(c) - mockLatticeDataStore := latticestore.NewLatticeDataStore() ctx := context.TODO() s := core.NewDefaultStack(core.StackID(types.NamespacedName{Namespace: "tt", Name: "name"})) - latticemodel.NewLatticeService(s, "fake-service", latticemodel.ServiceSpec{ + stackService := latticemodel.NewLatticeService(s, "fake-service", latticemodel.ServiceSpec{ IsDeleted: true, }) latticemodel.NewTargetGroup(s, "fake-targetGroup", latticemodel.TargetGroupSpec{ IsDeleted: true, }) + mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( + &vpclattice.ServiceSummary{ + Name: aws.String(stackService.LatticeName()), + Id: aws.String("fake-service"), + }, nil).AnyTimes() + + mockListenerManager.EXPECT().Cloud().Return(mockCloud).AnyTimes() + mockRuleManager.EXPECT().Cloud().Return(mockCloud).AnyTimes() + mockCloud.EXPECT().Lattice().Return(mockLattice).AnyTimes() + mockTargetGroupManager.EXPECT().List(gomock.Any()).AnyTimes() mockListenerManager.EXPECT().List(gomock.Any(), gomock.Any()).AnyTimes() diff --git a/pkg/latticestore/latticestore.go b/pkg/latticestore/latticestore.go index 0d9283be..000b9e2b 100644 --- a/pkg/latticestore/latticestore.go +++ b/pkg/latticestore/latticestore.go @@ -11,35 +11,13 @@ import ( // ERROR CODE const ( - DATASTORE_SERVICE_NETWORK_NOT_EXIST = "service network does not exist in Data Store" - DATASTORE_SERVICE_NOT_EXIST = "service does not exist in Data Store" - DATASTORE_TG_NOT_EXIST = "target Group does not exist in Data Store" - DATASTORE_LISTENER_NOT_EXIST = "listener does not exist in Data Store" -) - -// Status -const ( - DATASTORE_SERVICE_NETWORK_CREATE_IN_PROGRESS = "service network is create-in-progress" - DATASTORE_SERVICE_NETWORK_CREATED = "service network is created and associated" + DATASTORE_TG_NOT_EXIST = "target Group does not exist in Data Store" + DATASTORE_LISTENER_NOT_EXIST = "listener does not exist in Data Store" ) // this package is used to cache lattice info that relates to K8S object. // e.g. the AWSARN for the matching K8S object -type LatticeServiceKey struct { - Name string - Namespace string -} - -type LatticeService struct { - LatticeServiceKey LatticeServiceKey - ARN string - ID string - DNS string -} - -type LatticeServicePool map[LatticeServiceKey]*LatticeService - type ListenerKey struct { Name string Namespace string @@ -80,27 +58,24 @@ type Target struct { type TargetGroupPool map[TargetGroupKey]*TargetGroup type LatticeDataStore struct { - log gwlog.Logger - lock sync.Mutex - latticeServices LatticeServicePool - targetGroups TargetGroupPool - listeners ListenerPool + log gwlog.Logger + lock sync.Mutex + targetGroups TargetGroupPool + listeners ListenerPool } type LatticeDataStoreInfo struct { - LatticeServices map[string]LatticeService - TargetGroups map[string]TargetGroup - Listeners map[string]Listener + TargetGroups map[string]TargetGroup + Listeners map[string]Listener } var defaultLatticeDataStore *LatticeDataStore func NewLatticeDataStoreWithLog(log gwlog.Logger) *LatticeDataStore { defaultLatticeDataStore = &LatticeDataStore{ - log: log, - latticeServices: make(LatticeServicePool), - targetGroups: make(TargetGroupPool), - listeners: make(ListenerPool), + log: log, + targetGroups: make(TargetGroupPool), + listeners: make(ListenerPool), } return defaultLatticeDataStore } @@ -114,14 +89,8 @@ func dumpCurrentLatticeDataStore(ds *LatticeDataStore) *LatticeDataStoreInfo { defer ds.lock.Unlock() var store = LatticeDataStoreInfo{ - LatticeServices: make(map[string]LatticeService), - TargetGroups: make(map[string]TargetGroup), - Listeners: make(map[string]Listener), - } - - for _, svc := range ds.latticeServices { - key := fmt.Sprintf("%s-%s", svc.LatticeServiceKey.Name, svc.LatticeServiceKey.Namespace) - store.LatticeServices[key] = *svc + TargetGroups: make(map[string]TargetGroup), + Listeners: make(map[string]Listener), } for tgkey, targetgroup := range ds.targetGroups { @@ -142,80 +111,6 @@ func GetDefaultLatticeDataStore() *LatticeDataStore { return defaultLatticeDataStore } -func (ds *LatticeDataStore) AddLatticeService(name string, namespace string, arn string, id string, dns string) error { - ds.lock.Lock() - defer ds.lock.Unlock() - - serviceKey := LatticeServiceKey{ - Name: name, - Namespace: namespace, - } - - _, ok := ds.latticeServices[serviceKey] - if ok { - ds.log.Debugf("UpdateLatticeService: name: %s namespace: %s, arn: %s", name, namespace, arn) - } else { - ds.log.Debugf("AddLatticeService API, name: %s, namespace: %s, arn: %s", name, namespace, arn) - } - - ds.latticeServices[serviceKey] = &LatticeService{ - LatticeServiceKey: serviceKey, - ARN: arn, - ID: id, - DNS: dns, - } - - return nil -} - -func (ds *LatticeDataStore) DelLatticeService(name string, namespace string) error { - ds.lock.Lock() - defer ds.lock.Unlock() - - ds.log.Debugf("DelLatticeService API, name: %s namespace: %s", name, namespace) - - serviceKey := LatticeServiceKey{ - Name: name, - Namespace: namespace, - } - - _, ok := ds.latticeServices[serviceKey] - - if !ok { - ds.log.Debugf("Deleting unknown service: name: %s, namespace: %s", name, namespace) - return errors.New(DATASTORE_SERVICE_NOT_EXIST) - } - delete(ds.latticeServices, serviceKey) - return nil - -} - -func (ds *LatticeDataStore) GetLatticeService(name string, namespace string) (LatticeService, error) { - ds.lock.Lock() - defer ds.lock.Unlock() - - ds.log.Debugf("GetLatticeService API, name: %s, namespace: %s", name, namespace) - var svc = LatticeService{} - - serviceKey := LatticeServiceKey{ - Name: name, - Namespace: namespace, - } - - _, ok := ds.latticeServices[serviceKey] - - if ok { - svc.LatticeServiceKey = serviceKey - svc.ARN = ds.latticeServices[serviceKey].ARN - svc.ID = ds.latticeServices[serviceKey].ID - svc.DNS = ds.latticeServices[serviceKey].DNS - return svc, nil - } else { - return svc, errors.New(DATASTORE_SERVICE_NOT_EXIST) - } - -} - // the max tg name length is 127 // worst case - k8s-(50)-(50)-https-http2 (117 chars) func TargetGroupName(name, namespace string) string { @@ -234,10 +129,6 @@ func TargetGroupLongName(defaultName, routeName, vpcId string) string { ) } -func LatticeServiceName(name string, namespace string) string { - return fmt.Sprintf("%s-%s", utils.Truncate(name, 20), utils.Truncate(namespace, 18)) -} - func (ds *LatticeDataStore) AddTargetGroup(name string, vpc string, arn string, tgID string, isServiceImport bool, routeName string) error { ds.lock.Lock() diff --git a/pkg/latticestore/latticestore_test.go b/pkg/latticestore/latticestore_test.go index f7828c44..60130dd0 100644 --- a/pkg/latticestore/latticestore_test.go +++ b/pkg/latticestore/latticestore_test.go @@ -26,72 +26,6 @@ func Test_GetDefaultLatticeDataStore(t *testing.T) { assert.Equal(t, inputDataStore, defaultDataStore, "") } -func Test_LatticeService(t *testing.T) { - inputDataStore := NewLatticeDataStore() - - name := "service" - namespace := "default" - name1 := "service1" - namespace1 := "ns1" - arn := "arn" - id := "id" - dns := "dns-name" - - // GetLatticeService on an unknown service - service, err := inputDataStore.GetLatticeService(name, namespace) - fmt.Printf("error :%v\n", err) - assert.NotNil(t, err) - assert.Equal(t, errors.New(DATASTORE_SERVICE_NOT_EXIST), err) - - // AddLatticeService Happy path - err = inputDataStore.AddLatticeService(name, namespace, arn, id, dns) - assert.Nil(t, err) - - store := dumpCurrentLatticeDataStore(inputDataStore) - fmt.Printf("store:%v \n", store) - - assert.Equal(t, len(store.LatticeServices), 1, "") - - // verify GetLatticeService ok - service, err = inputDataStore.GetLatticeService(name, namespace) - assert.Nil(t, err) - assert.Equal(t, name, service.LatticeServiceKey.Name) - assert.Equal(t, namespace, service.LatticeServiceKey.Namespace) - assert.Equal(t, arn, service.ARN) - assert.Equal(t, id, service.ID) - - // add same service again, no impact - err = inputDataStore.AddLatticeService(name, namespace, arn, id, dns) - assert.Nil(t, err) - - store = dumpCurrentLatticeDataStore(inputDataStore) - fmt.Printf("store:%v \n", store) - assert.Equal(t, 1, len(store.LatticeServices), "") - - // add another service - err = inputDataStore.AddLatticeService(name1, namespace1, arn, id, dns) - assert.Nil(t, err) - - // verify 2 service added - store = dumpCurrentLatticeDataStore(inputDataStore) - fmt.Printf("store:%v \n", store) - - assert.Equal(t, 2, len(store.LatticeServices), "") - - // delete 2nd service - err = inputDataStore.DelLatticeService(name1, namespace1) - assert.Nil(t, err) - - // delete unknown service, 2nd delete should failed - err = inputDataStore.DelLatticeService(name1, namespace1) - assert.Equal(t, errors.New(DATASTORE_SERVICE_NOT_EXIST), err) - - store = dumpCurrentLatticeDataStore(inputDataStore) - fmt.Printf("store:%v \n", store) - assert.Equal(t, 1, len(store.LatticeServices), "") - -} - func Test_TargetGroup(t *testing.T) { inputDataStore := NewLatticeDataStore() diff --git a/pkg/model/lattice/service.go b/pkg/model/lattice/service.go index 6b2fca47..192b1602 100644 --- a/pkg/model/lattice/service.go +++ b/pkg/model/lattice/service.go @@ -1,8 +1,8 @@ package lattice import ( - "github.com/aws/aws-application-networking-k8s/pkg/latticestore" "github.com/aws/aws-application-networking-k8s/pkg/model/core" + "github.com/aws/aws-application-networking-k8s/pkg/utils" ) type Service struct { @@ -43,5 +43,5 @@ func NewLatticeService(stack core.Stack, id string, spec ServiceSpec) *Service { } func (s *Service) LatticeName() string { - return latticestore.LatticeServiceName(s.Spec.Name, s.Spec.Namespace) + return utils.LatticeServiceName(s.Spec.Name, s.Spec.Namespace) } diff --git a/pkg/utils/common.go b/pkg/utils/common.go index 1a31204e..1f1f7111 100644 --- a/pkg/utils/common.go +++ b/pkg/utils/common.go @@ -1,6 +1,7 @@ package utils import ( + "fmt" "strings" ) @@ -31,3 +32,7 @@ func SliceFilter[T any](in []T, f FilterFunc[T]) []T { } return out } + +func LatticeServiceName(name string, namespace string) string { + return fmt.Sprintf("%s-%s", Truncate(name, 20), Truncate(namespace, 18)) +} diff --git a/test/pkg/test/framework.go b/test/pkg/test/framework.go index 4c9ae595..848f9ec2 100644 --- a/test/pkg/test/framework.go +++ b/test/pkg/test/framework.go @@ -94,19 +94,13 @@ func addOptionalCRDs(scheme *runtime.Scheme) { type Framework struct { client.Client - ctx context.Context - log gwlog.Logger - k8sScheme *runtime.Scheme - namespace string - controllerRuntimeConfig *rest.Config - LatticeClient services.Lattice - GrpcurlRunner *v1.Pod - TestCasesCreatedServiceNetworkNames map[string]bool //key: ServiceNetworkName; value: not in use, meaningless - TestCasesCreatedServiceNames map[string]bool //key: ServiceName; value not in use, meaningless - TestCasesCreatedTargetGroupNames map[string]bool //key: TargetGroupName; value: not in use, meaningless - // TODO: instead of using one big list TestCasesCreatedK8sResource to track all created k8s resource, - // we should create different lists for different kind of k8s resource i.e., httproute have 1 list, service have another list etc. - TestCasesCreatedK8sResource []client.Object + ctx context.Context + log gwlog.Logger + k8sScheme *runtime.Scheme + namespace string + controllerRuntimeConfig *rest.Config + LatticeClient services.Lattice + GrpcurlRunner *v1.Pod } func NewFramework(ctx context.Context, log gwlog.Logger, testNamespace string) *Framework { @@ -115,17 +109,14 @@ func NewFramework(ctx context.Context, log gwlog.Logger, testNamespace string) * config.ConfigInit() controllerRuntimeConfig := controllerruntime.GetConfigOrDie() framework := &Framework{ - Client: lo.Must(client.New(controllerRuntimeConfig, client.Options{Scheme: testScheme})), - LatticeClient: services.NewDefaultLattice(session.Must(session.NewSession()), config.Region), // region is currently hardcoded - GrpcurlRunner: &v1.Pod{}, - ctx: ctx, - log: log, - k8sScheme: testScheme, - namespace: testNamespace, - controllerRuntimeConfig: controllerRuntimeConfig, - TestCasesCreatedServiceNetworkNames: make(map[string]bool), - TestCasesCreatedServiceNames: make(map[string]bool), - TestCasesCreatedTargetGroupNames: make(map[string]bool), + Client: lo.Must(client.New(controllerRuntimeConfig, client.Options{Scheme: testScheme})), + LatticeClient: services.NewDefaultLattice(session.Must(session.NewSession()), config.Region), // region is currently hardcoded + GrpcurlRunner: &v1.Pod{}, + ctx: ctx, + log: log, + k8sScheme: testScheme, + namespace: testNamespace, + controllerRuntimeConfig: controllerRuntimeConfig, } SetDefaultEventuallyTimeout(3 * time.Minute) SetDefaultEventuallyPollingInterval(10 * time.Second) @@ -149,7 +140,6 @@ func (env *Framework) ExpectToBeClean(ctx context.Context) { retrievedServiceNetworks, _ := env.LatticeClient.ListServiceNetworksAsList(ctx, &vpclattice.ListServiceNetworksInput{}) for _, sn := range retrievedServiceNetworks { env.log.Infof("Found service network, checking if created by current EKS Cluster: %v", sn) - g.Expect(*sn.Name).Should(Not(BeKeyOf(env.TestCasesCreatedServiceNetworkNames))) retrievedTags, err := env.LatticeClient.ListTagsForResourceWithContext(ctx, &vpclattice.ListTagsForResourceInput{ ResourceArn: sn.Arn, }) @@ -166,7 +156,6 @@ func (env *Framework) ExpectToBeClean(ctx context.Context) { retrievedServices, _ := env.LatticeClient.ListServicesAsList(ctx, &vpclattice.ListServicesInput{}) for _, service := range retrievedServices { env.log.Infof("Found service, checking if created by current EKS Cluster: %v", service) - g.Expect(*service.Name).Should(Not(BeKeyOf(env.TestCasesCreatedServiceNames))) retrievedTags, err := env.LatticeClient.ListTagsForResourceWithContext(ctx, &vpclattice.ListTagsForResourceInput{ ResourceArn: service.Arn, }) @@ -200,37 +189,11 @@ func (env *Framework) ExpectToBeClean(ctx context.Context) { //so we temporarily skip to verify whether ServiceExport created TargetGroup is deleted or not continue } - g.Expect(env.TestCasesCreatedServiceNames).To(Not(ContainElements(BeKeyOf(*tg.Name)))) } } }).Should(Succeed()) } -// if we still want this method, we should tag the things we create with the test suite -func (env *Framework) CleanTestEnvironment(ctx context.Context) { - defer GinkgoRecover() - env.log.Info("Cleaning the test environment") - // Kubernetes API Objects - namespaces := &v1.NamespaceList{} - Expect(env.List(ctx, namespaces)).WithOffset(1).To(Succeed()) - // TODO: instead of using one big list TestCasesCreatedK8sResource to track all created k8s resource, - // we should create different lists for different kind of k8s resource i.e., httproute have 1 list, service have another list etc. - for _, object := range env.TestCasesCreatedK8sResource { - env.log.Infof("Deleting k8s resource %s %s/%s", reflect.TypeOf(object), object.GetNamespace(), object.GetName()) - env.Delete(ctx, object) - //Ignore resource-not-found error here, as the test case logic itself could already clear the resources - } - - //Theoretically, Deleting all k8s resource by above `env.Delete(ctx, object)`, will make controller delete all related VPC Lattice resource, - //but the controller is still developing in the progress and may leaking some VPCLattice resource, need to invoke vpcLattice api to double confirm and delete leaking resource. - env.DeleteAllFrameworkTracedServiceNetworks(ctx) - env.DeleteAllFrameworkTracedVpcLatticeServices(ctx) - env.DeleteAllFrameworkTracedTargetGroups(ctx) - env.EventuallyExpectNotFound(ctx, env.TestCasesCreatedK8sResource...) - env.TestCasesCreatedK8sResource = nil - -} - func (env *Framework) ExpectCreated(ctx context.Context, objects ...client.Object) { for _, object := range objects { env.log.Infof("Creating %s %s/%s", reflect.TypeOf(object), object.GetNamespace(), object.GetName()) @@ -305,19 +268,15 @@ func (env *Framework) GetServiceNetwork(ctx context.Context, gateway *gateway_ap func (env *Framework) GetVpcLatticeService(ctx context.Context, route core.Route) *vpclattice.ServiceSummary { var found *vpclattice.ServiceSummary - serviceName := latticestore.LatticeServiceName(route.Name(), route.Namespace()) + rnProvider := controllers.RouteNameProvider{route} + Eventually(func(g Gomega) { - listServicesOutput, err := env.LatticeClient.ListServicesWithContext(ctx, &vpclattice.ListServicesInput{}) + svc, err := env.LatticeClient.FindService(ctx, &rnProvider) g.Expect(err).ToNot(HaveOccurred()) - g.Expect(listServicesOutput.Items).ToNot(BeEmpty()) - for _, service := range listServicesOutput.Items { - if *service.Name == serviceName { - found = service - } - } + found = svc g.Expect(found).ToNot(BeNil()) g.Expect(found.Status).To(Equal(lo.ToPtr(vpclattice.ServiceStatusActive))) - g.Expect(found.DnsEntry).To(ContainSubstring(serviceName)) + g.Expect(found.DnsEntry).To(ContainSubstring(rnProvider.LatticeName())) }).WithOffset(1).Should(Succeed()) return found @@ -437,256 +396,6 @@ func (env *Framework) AreAllLatticeTargetsHealthy(ctx context.Context, tg *vpcla return true, nil } -func (env *Framework) DeleteAllFrameworkTracedServiceNetworks(ctx aws.Context) { - env.log.Infof("DeleteAllFrameworkTracedServiceNetworks %v", env.TestCasesCreatedServiceNetworkNames) - sns, err := env.LatticeClient.ListServiceNetworksAsList(ctx, &vpclattice.ListServiceNetworksInput{}) - Expect(err).ToNot(HaveOccurred()) - filteredSns := lo.Filter(sns, func(sn *vpclattice.ServiceNetworkSummary, _ int) bool { - _, ok := env.TestCasesCreatedServiceNames[*sn.Name] - return ok - }) - snIds := lo.Map(filteredSns, func(svc *vpclattice.ServiceNetworkSummary, _ int) *string { - return svc.Id - }) - var serviceNetworkIdsWithRemainingAssociations []*string - for _, snId := range snIds { - _, err := env.LatticeClient.DeleteServiceNetworkWithContext(ctx, &vpclattice.DeleteServiceNetworkInput{ - ServiceNetworkIdentifier: snId, - }) - if err != nil { - if aerr, ok := err.(awserr.Error); ok { - switch aerr.Code() { - case vpclattice.ErrCodeResourceNotFoundException: - continue - case vpclattice.ErrCodeConflictException: - serviceNetworkIdsWithRemainingAssociations = append(serviceNetworkIdsWithRemainingAssociations, snId) - } - } - } - } - - var allServiceNetworkVpcAssociationIdsToBeDeleted []*string - for _, snIdWithRemainingAssociations := range serviceNetworkIdsWithRemainingAssociations { - associations, err := env.LatticeClient.ListServiceNetworkVpcAssociationsAsList(ctx, &vpclattice.ListServiceNetworkVpcAssociationsInput{ - ServiceNetworkIdentifier: snIdWithRemainingAssociations, - }) - Expect(err).ToNot(HaveOccurred()) - - snvaIds := lo.Map(associations, func(association *vpclattice.ServiceNetworkVpcAssociationSummary, _ int) *string { - return association.Id - }) - allServiceNetworkVpcAssociationIdsToBeDeleted = append(allServiceNetworkVpcAssociationIdsToBeDeleted, snvaIds...) - } - - for _, snvaId := range allServiceNetworkVpcAssociationIdsToBeDeleted { - _, err := env.LatticeClient.DeleteServiceNetworkVpcAssociationWithContext(ctx, &vpclattice.DeleteServiceNetworkVpcAssociationInput{ - ServiceNetworkVpcAssociationIdentifier: snvaId, - }) - Expect(err).ToNot(HaveOccurred()) - } - - var allServiceNetworkServiceAssociationIdsToBeDeleted []*string - - for _, snIdWithRemainingAssociations := range serviceNetworkIdsWithRemainingAssociations { - associations, err := env.LatticeClient.ListServiceNetworkServiceAssociationsAsList(ctx, &vpclattice.ListServiceNetworkServiceAssociationsInput{ - ServiceNetworkIdentifier: snIdWithRemainingAssociations, - }) - Expect(err).ToNot(HaveOccurred()) - - snsaIds := lo.Map(associations, func(association *vpclattice.ServiceNetworkServiceAssociationSummary, _ int) *string { - return association.Id - }) - allServiceNetworkServiceAssociationIdsToBeDeleted = append(allServiceNetworkServiceAssociationIdsToBeDeleted, snsaIds...) - } - - for _, snsaId := range allServiceNetworkServiceAssociationIdsToBeDeleted { - _, err := env.LatticeClient.DeleteServiceNetworkServiceAssociationWithContext(ctx, &vpclattice.DeleteServiceNetworkServiceAssociationInput{ - ServiceNetworkServiceAssociationIdentifier: snsaId, - }) - Expect(err).ToNot(HaveOccurred()) - } - - Eventually(func(g Gomega) { - for _, snvaId := range allServiceNetworkVpcAssociationIdsToBeDeleted { - _, err := env.LatticeClient.GetServiceNetworkVpcAssociationWithContext(ctx, &vpclattice.GetServiceNetworkVpcAssociationInput{ - ServiceNetworkVpcAssociationIdentifier: snvaId, - }) - if err != nil { - g.Expect(err.(awserr.Error).Code()).To(Equal(vpclattice.ErrCodeResourceNotFoundException)) - } - } - for _, snsaId := range allServiceNetworkServiceAssociationIdsToBeDeleted { - _, err := env.LatticeClient.GetServiceNetworkServiceAssociationWithContext(ctx, &vpclattice.GetServiceNetworkServiceAssociationInput{ - ServiceNetworkServiceAssociationIdentifier: snsaId, - }) - if err != nil { - g.Expect(err.(awserr.Error).Code()).To(Equal(vpclattice.ErrCodeResourceNotFoundException)) - } - } - }).Should(Succeed()) - - for _, snId := range serviceNetworkIdsWithRemainingAssociations { - env.LatticeClient.DeleteServiceNetworkWithContext(ctx, &vpclattice.DeleteServiceNetworkInput{ - ServiceNetworkIdentifier: snId, - }) - } - - env.TestCasesCreatedServiceNetworkNames = make(map[string]bool) -} - -// In the VPC Lattice backend code, delete VPC Lattice services will also make all its listeners and rules to be deleted asynchronously -func (env *Framework) DeleteAllFrameworkTracedVpcLatticeServices(ctx aws.Context) { - env.log.Infoln("DeleteAllFrameworkTracedVpcLatticeServices", env.TestCasesCreatedServiceNames) - services, err := env.LatticeClient.ListServicesAsList(ctx, &vpclattice.ListServicesInput{}) - Expect(err).ToNot(HaveOccurred()) - filteredServices := lo.Filter(services, func(service *vpclattice.ServiceSummary, _ int) bool { - _, ok := env.TestCasesCreatedServiceNames[*service.Name] - return ok - }) - serviceIds := lo.Map(filteredServices, func(svc *vpclattice.ServiceSummary, _ int) *string { - return svc.Id - }) - var serviceWithRemainingAssociations []*string - for _, serviceId := range serviceIds { - _, err := env.LatticeClient.DeleteServiceWithContext(ctx, &vpclattice.DeleteServiceInput{ - ServiceIdentifier: serviceId, - }) - if err != nil { - if aerr, ok := err.(awserr.Error); ok { - switch aerr.Code() { - case vpclattice.ErrCodeResourceNotFoundException: - delete(env.TestCasesCreatedServiceNames, *serviceId) - continue - case vpclattice.ErrCodeConflictException: - serviceWithRemainingAssociations = append(serviceWithRemainingAssociations, serviceId) - } - } - - } - } - var allServiceNetworkServiceAssociationIdsToBeDeleted []*string - - for _, serviceIdWithRemainingAssociations := range serviceWithRemainingAssociations { - - associations, err := env.LatticeClient.ListServiceNetworkServiceAssociationsAsList(ctx, &vpclattice.ListServiceNetworkServiceAssociationsInput{ - ServiceIdentifier: serviceIdWithRemainingAssociations, - }) - Expect(err).ToNot(HaveOccurred()) - - snsaIds := lo.Map(associations, func(association *vpclattice.ServiceNetworkServiceAssociationSummary, _ int) *string { - return association.Id - }) - allServiceNetworkServiceAssociationIdsToBeDeleted = append(allServiceNetworkServiceAssociationIdsToBeDeleted, snsaIds...) - } - - for _, snsaId := range allServiceNetworkServiceAssociationIdsToBeDeleted { - _, err := env.LatticeClient.DeleteServiceNetworkServiceAssociationWithContext(ctx, &vpclattice.DeleteServiceNetworkServiceAssociationInput{ - ServiceNetworkServiceAssociationIdentifier: snsaId, - }) - if err != nil { - Expect(err.(awserr.Error).Code()).To(Equal(vpclattice.ErrCodeResourceNotFoundException)) - } - } - - Eventually(func(g Gomega) { - for _, snsaId := range allServiceNetworkServiceAssociationIdsToBeDeleted { - _, err := env.LatticeClient.GetServiceNetworkServiceAssociationWithContext(ctx, &vpclattice.GetServiceNetworkServiceAssociationInput{ - ServiceNetworkServiceAssociationIdentifier: snsaId, - }) - if err != nil { - g.Expect(err.(awserr.Error).Code()).To(Equal(vpclattice.ErrCodeResourceNotFoundException)) - } - } - }).Should(Succeed()) - - for _, serviceId := range serviceWithRemainingAssociations { - env.LatticeClient.DeleteServiceWithContext(ctx, &vpclattice.DeleteServiceInput{ - ServiceIdentifier: serviceId, - }) - } - env.TestCasesCreatedServiceNames = make(map[string]bool) -} - -func (env *Framework) DeleteAllFrameworkTracedTargetGroups(ctx aws.Context) { - targetGroups, err := env.LatticeClient.ListTargetGroupsAsList(ctx, &vpclattice.ListTargetGroupsInput{}) - Expect(err).ToNot(HaveOccurred()) - filteredTgs := lo.Filter(targetGroups, func(targetGroup *vpclattice.TargetGroupSummary, _ int) bool { - for key, _ := range env.TestCasesCreatedTargetGroupNames { - if strings.HasPrefix(*targetGroup.Name, key) { - return true - } - } - return false - }) - tgIds := lo.Map(filteredTgs, func(targetGroup *vpclattice.TargetGroupSummary, _ int) *string { - return targetGroup.Id - }) - - env.log.Infoln("Number of traced target groups to delete is:", len(tgIds)) - - var tgsToDeregister []string - for _, tgId := range tgIds { - env.log.Infoln("Attempting to delete target group: ", tgId) - - _, err := env.LatticeClient.DeleteTargetGroup(&vpclattice.DeleteTargetGroupInput{ - TargetGroupIdentifier: tgId, - }) - if err != nil { - tgsToDeregister = append(tgsToDeregister, *tgId) - } else { - env.log.Infoln("Deleted target group: ", tgId) - } - } - - // next try to deregister targets - var tgsToDelete []string - for _, tgId := range tgsToDeregister { - targetSummaries, err := env.LatticeClient.ListTargetsAsList(ctx, &vpclattice.ListTargetsInput{ - TargetGroupIdentifier: &tgId, - }) - - if err.(awserr.Error).Code() == vpclattice.ErrCodeResourceNotFoundException { - env.log.Infoln("Target group already deleted: ", tgId) - continue - } - - Expect(err).ToNot(HaveOccurred()) - tgsToDelete = append(tgsToDelete, tgId) - if len(targetSummaries) > 0 { - var targets []*vpclattice.Target = lo.Map(targetSummaries, func(targetSummary *vpclattice.TargetSummary, _ int) *vpclattice.Target { - return &vpclattice.Target{ - Id: targetSummary.Id, - Port: targetSummary.Port, - } - }) - env.LatticeClient.DeregisterTargetsWithContext(ctx, &vpclattice.DeregisterTargetsInput{ - TargetGroupIdentifier: &tgId, - Targets: targets, - }) - } - } - - if len(tgsToDelete) > 0 { - env.log.Infoln("Need to wait for draining targets to be deregistered", tgsToDelete) - // After initiating the DeregisterTargets call, the Targets will be in `draining` status for the next 5 minutes, - // And VPC lattice backend will run a background job to completely delete the targets within 6 minutes at maximum in total. - Eventually(func(g Gomega) { - env.log.Infoln("Trying to clear Target group", tgsToDelete, "need to wait for draining targets to be deregistered") - - for _, tgId := range tgsToDelete { - _, err := env.LatticeClient.DeleteTargetGroupWithContext(ctx, &vpclattice.DeleteTargetGroupInput{ - TargetGroupIdentifier: &tgId, - }) - if err != nil { - g.Expect(err.(awserr.Error).Code()).To(Equal(vpclattice.ErrCodeResourceNotFoundException)) - } - } - }).WithPolling(15 * time.Second).WithTimeout(7 * time.Minute).Should(Succeed()) - - } - env.TestCasesCreatedServiceNames = make(map[string]bool) -} - func (env *Framework) GetLatticeServiceHttpsListenerNonDefaultRules(ctx context.Context, vpcLatticeService *vpclattice.ServiceSummary) ([]*vpclattice.GetRuleOutput, error) { listListenerResp, err := env.LatticeClient.ListListenersWithContext(ctx, &vpclattice.ListListenersInput{ diff --git a/test/pkg/test/gateway.go b/test/pkg/test/gateway.go index cd3df00a..0af6a02e 100644 --- a/test/pkg/test/gateway.go +++ b/test/pkg/test/gateway.go @@ -9,7 +9,7 @@ func (env *Framework) NewGateway(name string, namespace string) *v1beta1.Gateway gateway := New( &v1beta1.Gateway{ ObjectMeta: metav1.ObjectMeta{ - Name: name, + Name: name, Namespace: namespace, Annotations: map[string]string{ "application-networking.k8s.aws/lattice-vpc-association": "true", @@ -33,7 +33,5 @@ func (env *Framework) NewGateway(name string, namespace string) *v1beta1.Gateway Status: v1beta1.GatewayStatus{}, }, ) - env.TestCasesCreatedServiceNetworkNames[gateway.Name] = true - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, gateway) return gateway } diff --git a/test/pkg/test/grpc_helloworld.go b/test/pkg/test/grpc_helloworld.go index cd300006..d9f779c3 100644 --- a/test/pkg/test/grpc_helloworld.go +++ b/test/pkg/test/grpc_helloworld.go @@ -1,7 +1,6 @@ package test import ( - "github.com/aws/aws-application-networking-k8s/pkg/latticestore" "github.com/samber/lo" appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" @@ -62,8 +61,6 @@ func (env *Framework) NewGrpcHelloWorld(options GrpcAppOptions) (*appsv1.Deploym }, }, }) - env.TestCasesCreatedTargetGroupNames[latticestore.TargetGroupName(service.Name, service.Namespace)] = true - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, service, deployment) return deployment, service } diff --git a/test/pkg/test/grpcbin.go b/test/pkg/test/grpcbin.go index cc952913..1a0f0e60 100644 --- a/test/pkg/test/grpcbin.go +++ b/test/pkg/test/grpcbin.go @@ -6,8 +6,6 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - - "github.com/aws/aws-application-networking-k8s/pkg/latticestore" ) type GrpcAppOptions struct { @@ -74,7 +72,5 @@ func (env *Framework) NewGrpcBin(options GrpcAppOptions) (*appsv1.Deployment, *v }, }, }) - env.TestCasesCreatedTargetGroupNames[latticestore.TargetGroupName(service.Name, service.Namespace)] = true - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, service, deployment) return deployment, service } diff --git a/test/pkg/test/grpcroute.go b/test/pkg/test/grpcroute.go index b6508f2d..e1d08a34 100644 --- a/test/pkg/test/grpcroute.go +++ b/test/pkg/test/grpcroute.go @@ -5,8 +5,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/gateway-api/apis/v1alpha2" "sigs.k8s.io/gateway-api/apis/v1beta1" - - "github.com/aws/aws-application-networking-k8s/pkg/latticestore" ) func (env *Framework) NewGRPCRoute(namespace string, parentRefsGateway *v1beta1.Gateway, rules []v1alpha2.GRPCRouteRule) *v1alpha2.GRPCRoute { @@ -27,7 +25,5 @@ func (env *Framework) NewGRPCRoute(namespace string, parentRefsGateway *v1beta1. }, }) - env.TestCasesCreatedServiceNames[latticestore.LatticeServiceName(grpcRoute.Name, grpcRoute.Namespace)] = true - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, grpcRoute) return grpcRoute } diff --git a/test/pkg/test/header_match_httproute.go b/test/pkg/test/header_match_httproute.go index 0a5c1165..fe3f842a 100644 --- a/test/pkg/test/header_match_httproute.go +++ b/test/pkg/test/header_match_httproute.go @@ -5,8 +5,6 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/gateway-api/apis/v1beta1" - - "github.com/aws/aws-application-networking-k8s/pkg/latticestore" ) func (env *Framework) NewHeaderMatchHttpRoute(parentRefsGateway *v1beta1.Gateway, services []*v1.Service) *v1beta1.HTTPRoute { @@ -55,7 +53,5 @@ func (env *Framework) NewHeaderMatchHttpRoute(parentRefsGateway *v1beta1.Gateway }, }) - env.TestCasesCreatedServiceNames[latticestore.LatticeServiceName(httpRoute.Name, parentRefsGateway.Namespace)] = true - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, httpRoute) return httpRoute } diff --git a/test/pkg/test/httpapp.go b/test/pkg/test/httpapp.go index 958e3044..032a18be 100644 --- a/test/pkg/test/httpapp.go +++ b/test/pkg/test/httpapp.go @@ -1,7 +1,6 @@ package test import ( - "github.com/aws/aws-application-networking-k8s/pkg/latticestore" "github.com/samber/lo" appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" @@ -76,8 +75,6 @@ func (env *Framework) NewHttpApp(options HTTPAppOptions) (*appsv1.Deployment, *v }}, }, }, options.MergeFromService...) - env.TestCasesCreatedTargetGroupNames[latticestore.TargetGroupName(service.Name, service.Namespace)] = true - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, service, deployment) return deployment, service } diff --git a/test/pkg/test/method_match_httproute.go b/test/pkg/test/method_match_httproute.go index 075ea3ea..e50863ca 100644 --- a/test/pkg/test/method_match_httproute.go +++ b/test/pkg/test/method_match_httproute.go @@ -5,8 +5,6 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/gateway-api/apis/v1beta1" - - "github.com/aws/aws-application-networking-k8s/pkg/latticestore" ) // creates a route sending GET to getService and POST to postService @@ -56,11 +54,9 @@ func (env *Framework) NewMethodMatchHttpRoute(parentRefsGateway *v1beta1.Gateway SectionName: lo.ToPtr(v1beta1.SectionName("http")), }}, }, - Rules: []v1beta1.HTTPRouteRule {getRule, postRule}, + Rules: []v1beta1.HTTPRouteRule{getRule, postRule}, }, }) - env.TestCasesCreatedServiceNames[latticestore.LatticeServiceName(httpRoute.Name, httpRoute.Namespace)] = true - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, httpRoute) return httpRoute } diff --git a/test/pkg/test/nginxapp.go b/test/pkg/test/nginxapp.go index 25e598bb..8c272bd1 100644 --- a/test/pkg/test/nginxapp.go +++ b/test/pkg/test/nginxapp.go @@ -1,7 +1,6 @@ package test import ( - "github.com/aws/aws-application-networking-k8s/pkg/latticestore" "github.com/samber/lo" appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" @@ -117,8 +116,6 @@ func (env *Framework) NewNginxApp(options ElasticSearchOptions) (*appsv1.Deploym }}, }, }, options.MergeFromService...) - env.TestCasesCreatedTargetGroupNames[latticestore.TargetGroupName(service.Name, service.Namespace)] = true - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, service, deployment) return deployment, service } @@ -152,7 +149,5 @@ func (env *Framework) NewHttpRoute(parentRefsGateway *v1beta1.Gateway, service * Rules: rules, }, }) - env.TestCasesCreatedServiceNames[latticestore.LatticeServiceName(httpRoute.Name, httpRoute.Namespace)] = true - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, httpRoute) return httpRoute } diff --git a/test/pkg/test/path_match_httproute.go b/test/pkg/test/path_match_httproute.go index 6b0cc531..3b2e4465 100644 --- a/test/pkg/test/path_match_httproute.go +++ b/test/pkg/test/path_match_httproute.go @@ -7,8 +7,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/gateway-api/apis/v1beta1" - - "github.com/aws/aws-application-networking-k8s/pkg/latticestore" ) func (env *Framework) NewPathMatchHttpRoute(parentRefsGateway *v1beta1.Gateway, backendRefObjects []client.Object, @@ -60,7 +58,5 @@ func (env *Framework) NewPathMatchHttpRoute(parentRefsGateway *v1beta1.Gateway, Rules: rules, }, }) - env.TestCasesCreatedServiceNames[latticestore.LatticeServiceName(httpRoute.Name, httpRoute.Namespace)] = true - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, httpRoute) return httpRoute } diff --git a/test/pkg/test/service_export_import.go b/test/pkg/test/service_export_import.go index 105102ce..ae62a36b 100644 --- a/test/pkg/test/service_export_import.go +++ b/test/pkg/test/service_export_import.go @@ -41,7 +41,6 @@ func (env *Framework) CreateServiceExportAndServiceImportByService(service *v1.S }, }, }) - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, serviceExport, serviceImport) return serviceExport, serviceImport } @@ -60,7 +59,6 @@ func (env *Framework) CreateServiceExport(service *v1.Service) *v1alpha1.Service }, }, }) - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, serviceExport) return serviceExport } @@ -84,6 +82,5 @@ func (env *Framework) CreateServiceImport(service *v1.Service) *v1alpha1.Service }, }, }) - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, serviceImport) return serviceImport } diff --git a/test/pkg/test/weighted_routing_httproute.go b/test/pkg/test/weighted_routing_httproute.go index 1f65d95b..3f8a6d2d 100644 --- a/test/pkg/test/weighted_routing_httproute.go +++ b/test/pkg/test/weighted_routing_httproute.go @@ -5,8 +5,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/gateway-api/apis/v1beta1" - - "github.com/aws/aws-application-networking-k8s/pkg/latticestore" ) type ObjectAndWeight struct { @@ -51,7 +49,5 @@ func (env *Framework) NewWeightedRoutingHttpRoute(parentRefsGateway *v1beta1.Gat }, }, }) - env.TestCasesCreatedServiceNames[latticestore.LatticeServiceName(httpRoute.Name, httpRoute.Namespace)] = true - env.TestCasesCreatedK8sResource = append(env.TestCasesCreatedK8sResource, httpRoute) return httpRoute } diff --git a/test/suites/integration/defined_target_ports_test.go b/test/suites/integration/defined_target_ports_test.go index af10ba70..b22c112a 100644 --- a/test/suites/integration/defined_target_ports_test.go +++ b/test/suites/integration/defined_target_ports_test.go @@ -1,6 +1,7 @@ package integration import ( + "github.com/aws/aws-application-networking-k8s/controllers" "os" "github.com/aws/aws-sdk-go/service/vpclattice" @@ -11,7 +12,6 @@ import ( "sigs.k8s.io/gateway-api/apis/v1beta1" "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1" - "github.com/aws/aws-application-networking-k8s/pkg/latticestore" "github.com/aws/aws-application-networking-k8s/pkg/model/core" "github.com/aws/aws-application-networking-k8s/test/pkg/test" ) @@ -70,7 +70,8 @@ var _ = Describe("Defined Target Ports", func() { // Verify VPC Lattice Service exists route, _ := core.NewRoute(httpRoute) vpcLatticeService = testFramework.GetVpcLatticeService(ctx, route) - Expect(*vpcLatticeService.DnsEntry).To(ContainSubstring(latticestore.LatticeServiceName(httpRoute.Name, httpRoute.Namespace))) + rnp := controllers.RouteNameProvider{route} + Expect(*vpcLatticeService.DnsEntry).To(ContainSubstring(rnp.LatticeName())) performVerification(service, deployment, definedPorts) }) From ec424d07cddef762c6aeb010045a7d326b4511f5 Mon Sep 17 00:00:00 2001 From: Erik F <16261515+erikfuller@users.noreply.github.com> Date: Thu, 14 Sep 2023 13:34:44 -0700 Subject: [PATCH 2/2] Updated LatticeName() -> LatticeServiceName() based on PR feedback --- controllers/route_controller.go | 6 +++--- pkg/aws/services/vpclattice.go | 10 +++++----- pkg/aws/services/vpclattice_mocks.go | 2 +- pkg/aws/services/vpclattice_test.go | 16 ++++++++-------- pkg/deploy/lattice/listener_manager.go | 6 +++--- pkg/deploy/lattice/listener_manager_test.go | 2 +- pkg/deploy/lattice/listener_synthesizer_test.go | 2 +- pkg/deploy/lattice/rule_manager.go | 8 ++++---- pkg/deploy/lattice/rule_manager_test.go | 4 ++-- pkg/deploy/lattice/rule_synthesizer_test.go | 2 +- pkg/deploy/lattice/service_manager.go | 4 ++-- pkg/deploy/lattice/service_manager_test.go | 8 ++++---- pkg/deploy/stack_deployer_test.go | 8 ++++---- pkg/model/lattice/service.go | 2 +- test/pkg/test/framework.go | 4 ++-- .../integration/defined_target_ports_test.go | 4 ++-- 16 files changed, 44 insertions(+), 44 deletions(-) diff --git a/controllers/route_controller.go b/controllers/route_controller.go index 24da02a3..67888fcc 100644 --- a/controllers/route_controller.go +++ b/controllers/route_controller.go @@ -79,11 +79,11 @@ const ( LatticeAssignedDomainName = "application-networking.k8s.aws/lattice-assigned-domain-name" ) -type RouteNameProvider struct { +type RouteLSNProvider struct { Route core.Route } -func (r *RouteNameProvider) LatticeName() string { +func (r *RouteLSNProvider) LatticeServiceName() string { return utils.LatticeServiceName(r.Route.Name(), r.Route.Namespace()) } @@ -375,7 +375,7 @@ func (r *RouteReconciler) reconcileRouteResource(ctx context.Context, route core r.eventRecorder.Event(route.K8sObject(), corev1.EventTypeNormal, k8s.RouteEventReasonDeploySucceed, "Adding/Updating reconcile Done!") - svc, err := r.cloud.Lattice().FindService(ctx, &RouteNameProvider{route}) + svc, err := r.cloud.Lattice().FindService(ctx, &RouteLSNProvider{route}) if err != nil && !services.IsNotFoundError(err) { return err } diff --git a/pkg/aws/services/vpclattice.go b/pkg/aws/services/vpclattice.go index fb65c488..6e2e2b8a 100644 --- a/pkg/aws/services/vpclattice.go +++ b/pkg/aws/services/vpclattice.go @@ -23,8 +23,8 @@ type ServiceNetworkInfo struct { Tags Tags } -type LatticeNameProvider interface { - LatticeName() string +type LatticeServiceNameProvider interface { + LatticeServiceName() string } type NotFoundError struct { @@ -54,7 +54,7 @@ type Lattice interface { ListServiceNetworkVpcAssociationsAsList(ctx context.Context, input *vpclattice.ListServiceNetworkVpcAssociationsInput) ([]*vpclattice.ServiceNetworkVpcAssociationSummary, error) ListServiceNetworkServiceAssociationsAsList(ctx context.Context, input *vpclattice.ListServiceNetworkServiceAssociationsInput) ([]*vpclattice.ServiceNetworkServiceAssociationSummary, error) FindServiceNetwork(ctx context.Context, name string, accountId string) (*ServiceNetworkInfo, error) - FindService(ctx context.Context, nameProvider LatticeNameProvider) (*vpclattice.ServiceSummary, error) + FindService(ctx context.Context, nameProvider LatticeServiceNameProvider) (*vpclattice.ServiceSummary, error) } type defaultLattice struct { @@ -234,8 +234,8 @@ func (d *defaultLattice) FindServiceNetwork(ctx context.Context, name string, op return snMatch, nil } -func (d *defaultLattice) FindService(ctx context.Context, nameProvider LatticeNameProvider) (*vpclattice.ServiceSummary, error) { - serviceName := nameProvider.LatticeName() +func (d *defaultLattice) FindService(ctx context.Context, nameProvider LatticeServiceNameProvider) (*vpclattice.ServiceSummary, error) { + serviceName := nameProvider.LatticeServiceName() input := vpclattice.ListServicesInput{} var svcMatch *vpclattice.ServiceSummary diff --git a/pkg/aws/services/vpclattice_mocks.go b/pkg/aws/services/vpclattice_mocks.go index 468c944d..573771e4 100644 --- a/pkg/aws/services/vpclattice_mocks.go +++ b/pkg/aws/services/vpclattice_mocks.go @@ -1037,7 +1037,7 @@ func (mr *MockLatticeMockRecorder) DeregisterTargetsWithContext(arg0, arg1 inter } // FindService mocks base method. -func (m *MockLattice) FindService(arg0 context.Context, arg1 LatticeNameProvider) (*vpclattice.ServiceSummary, error) { +func (m *MockLattice) FindService(arg0 context.Context, arg1 LatticeServiceNameProvider) (*vpclattice.ServiceSummary, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FindService", arg0, arg1) ret0, _ := ret[0].(*vpclattice.ServiceSummary) diff --git a/pkg/aws/services/vpclattice_test.go b/pkg/aws/services/vpclattice_test.go index 0d421672..72538919 100644 --- a/pkg/aws/services/vpclattice_test.go +++ b/pkg/aws/services/vpclattice_test.go @@ -558,11 +558,11 @@ func Test_defaultLattice_FindServiceNetwork_errorsRaised(t *testing.T) { assert.False(t, IsNotFoundError(tagErr)) } -type StringNameProvider struct { +type StringLSNProvider struct { name string } -func (p *StringNameProvider) LatticeName() string { +func (p *StringLSNProvider) LatticeServiceName() string { return p.name } @@ -591,12 +591,12 @@ func Test_defaultLattice_FindService_happyPath(t *testing.T) { return nil }).AnyTimes() - itemFound, err1 := d.FindService(ctx, &StringNameProvider{name}) + itemFound, err1 := d.FindService(ctx, &StringLSNProvider{name}) assert.Nil(t, err1) assert.NotNil(t, itemFound) assert.Equal(t, name, *itemFound.Name) - itemNotFound, err2 := d.FindService(ctx, &StringNameProvider{"no-name"}) + itemNotFound, err2 := d.FindService(ctx, &StringLSNProvider{"no-name"}) assert.True(t, IsNotFoundError(err2)) assert.Nil(t, itemNotFound) } @@ -636,17 +636,17 @@ func Test_defaultLattice_FindService_pagedResults(t *testing.T) { return nil }).AnyTimes() - itemFound1, err1 := d.FindService(ctx, &StringNameProvider{"name1"}) + itemFound1, err1 := d.FindService(ctx, &StringLSNProvider{"name1"}) assert.Nil(t, err1) assert.NotNil(t, itemFound1) assert.Equal(t, "name1", *itemFound1.Name) - itemFound2, err2 := d.FindService(ctx, &StringNameProvider{"name2"}) + itemFound2, err2 := d.FindService(ctx, &StringLSNProvider{"name2"}) assert.Nil(t, err2) assert.NotNil(t, itemFound2) assert.Equal(t, "name2", *itemFound2.Name) - itemNotFound, err3 := d.FindService(ctx, &StringNameProvider{"no-name"}) + itemNotFound, err3 := d.FindService(ctx, &StringLSNProvider{"no-name"}) assert.True(t, IsNotFoundError(err3)) assert.Nil(t, itemNotFound) } @@ -660,7 +660,7 @@ func Test_defaultLattice_FindService_errorsRaised(t *testing.T) { mockLattice.EXPECT().ListServicesPagesWithContext(gomock.Any(), gomock.Any(), gomock.Any()). Return(errors.New("LIST_ERR")).Times(1) - _, listErr := d.FindService(ctx, &StringNameProvider{"foo"}) + _, listErr := d.FindService(ctx, &StringLSNProvider{"foo"}) assert.NotNil(t, listErr) assert.False(t, IsNotFoundError(listErr)) } diff --git a/pkg/deploy/lattice/listener_manager.go b/pkg/deploy/lattice/listener_manager.go index 16937a77..a729333f 100644 --- a/pkg/deploy/lattice/listener_manager.go +++ b/pkg/deploy/lattice/listener_manager.go @@ -41,18 +41,18 @@ func (d *defaultListenerManager) Cloud() lattice_aws.Cloud { return d.cloud } -type ListenerNameProvider struct { +type ListenerLSNProvider struct { l *latticemodel.Listener } -func (r *ListenerNameProvider) LatticeName() string { +func (r *ListenerLSNProvider) LatticeServiceName() string { return utils.LatticeServiceName(r.l.Spec.Name, r.l.Spec.Namespace) } func (d *defaultListenerManager) Create(ctx context.Context, listener *latticemodel.Listener) (latticemodel.ListenerStatus, error) { glog.V(6).Infof("Creating listener >>>> %v \n", listener) - svc, err1 := d.cloud.Lattice().FindService(ctx, &ListenerNameProvider{listener}) + svc, err1 := d.cloud.Lattice().FindService(ctx, &ListenerLSNProvider{listener}) if err1 != nil { if services.IsNotFoundError(err1) { errMsg := fmt.Sprintf("Service %v not found during listener creation", listener.Spec.Name) diff --git a/pkg/deploy/lattice/listener_manager_test.go b/pkg/deploy/lattice/listener_manager_test.go index 15dc5e52..0df89814 100644 --- a/pkg/deploy/lattice/listener_manager_test.go +++ b/pkg/deploy/lattice/listener_manager_test.go @@ -132,7 +132,7 @@ func Test_AddListener(t *testing.T) { if !tt.noServiceID { mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( &vpclattice.ServiceSummary{ - Name: aws.String((&ListenerNameProvider{listener}).LatticeName()), + Name: aws.String((&ListenerLSNProvider{listener}).LatticeServiceName()), Arn: aws.String(serviceARN), Id: aws.String(serviceID), DnsEntry: &vpclattice.DnsEntry{ diff --git a/pkg/deploy/lattice/listener_synthesizer_test.go b/pkg/deploy/lattice/listener_synthesizer_test.go index a567da71..45d7dd97 100644 --- a/pkg/deploy/lattice/listener_synthesizer_test.go +++ b/pkg/deploy/lattice/listener_synthesizer_test.go @@ -137,7 +137,7 @@ func Test_SynthesizeListener(t *testing.T) { stackService := latticemodel.NewLatticeService(stack, "", spec) mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( &vpclattice.ServiceSummary{ - Name: sdk.String(stackService.LatticeName()), + Name: sdk.String(stackService.LatticeServiceName()), Arn: sdk.String("svc-arn"), Id: sdk.String(tt.serviceID), }, nil) diff --git a/pkg/deploy/lattice/rule_manager.go b/pkg/deploy/lattice/rule_manager.go index d5d123fc..e758a876 100644 --- a/pkg/deploy/lattice/rule_manager.go +++ b/pkg/deploy/lattice/rule_manager.go @@ -42,11 +42,11 @@ func (r *defaultRuleManager) Cloud() lattice_aws.Cloud { return r.cloud } -type RuleNameProvider struct { +type RuleLSNPRovider struct { rule *latticemodel.Rule } -func (r *RuleNameProvider) LatticeName() string { +func (r *RuleLSNPRovider) LatticeServiceName() string { return utils.LatticeServiceName(r.rule.Spec.ServiceName, r.rule.Spec.ServiceNamespace) } @@ -106,7 +106,7 @@ func (r *defaultRuleManager) Update(ctx context.Context, rules []*latticemodel.R glog.V(6).Infof("Rule --- update >>>>>>>>.%v\n", rules) - latticeService, err := r.cloud.Lattice().FindService(ctx, &RuleNameProvider{rules[0]}) + latticeService, err := r.cloud.Lattice().FindService(ctx, &RuleLSNPRovider{rules[0]}) if err != nil { errmsg := fmt.Sprintf("Service %v not found during rule creation", rules[0].Spec) glog.V(2).Infof("Error during update rule %s \n", errmsg) @@ -152,7 +152,7 @@ func (r *defaultRuleManager) Update(ctx context.Context, rules []*latticemodel.R func (r *defaultRuleManager) Create(ctx context.Context, rule *latticemodel.Rule) (latticemodel.RuleStatus, error) { glog.V(6).Infof("Rule --- Create >>>>>>>>.%v\n", *rule) - latticeService, err := r.cloud.Lattice().FindService(ctx, &RuleNameProvider{rule}) + latticeService, err := r.cloud.Lattice().FindService(ctx, &RuleLSNPRovider{rule}) if err != nil { errmsg := fmt.Sprintf("Service %v not found during rule creation, err: %v", rule.Spec, err) glog.V(2).Infof("Error during create rule %s \n", errmsg) diff --git a/pkg/deploy/lattice/rule_manager_test.go b/pkg/deploy/lattice/rule_manager_test.go index d25bb097..c579298e 100644 --- a/pkg/deploy/lattice/rule_manager_test.go +++ b/pkg/deploy/lattice/rule_manager_test.go @@ -535,7 +535,7 @@ func Test_CreateRule(t *testing.T) { if !tt.noServiceID { mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( &vpclattice.ServiceSummary{ - Name: aws.String((&RuleNameProvider{tt.newRule}).LatticeName()), + Name: aws.String((&RuleLSNPRovider{tt.newRule}).LatticeServiceName()), Arn: aws.String("serviceARN"), Id: aws.String(tt.newRule.Status.ServiceID), DnsEntry: &vpclattice.DnsEntry{ @@ -761,7 +761,7 @@ func Test_UpdateRule(t *testing.T) { if !tt.noServiceID { mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( &vpclattice.ServiceSummary{ - Name: aws.String((&RuleNameProvider{rules[i]}).LatticeName()), + Name: aws.String((&RuleLSNPRovider{rules[i]}).LatticeServiceName()), Arn: aws.String("serviceARN"), Id: aws.String(rules[i].Status.ServiceID), DnsEntry: &vpclattice.DnsEntry{ diff --git a/pkg/deploy/lattice/rule_synthesizer_test.go b/pkg/deploy/lattice/rule_synthesizer_test.go index aacd1bc7..84116acf 100644 --- a/pkg/deploy/lattice/rule_synthesizer_test.go +++ b/pkg/deploy/lattice/rule_synthesizer_test.go @@ -326,7 +326,7 @@ func Test_SynthesizeDeleteRule(t *testing.T) { mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( &vpclattice.ServiceSummary{ - Name: sdk.String(stackService.LatticeName()), + Name: sdk.String(stackService.LatticeServiceName()), Arn: sdk.String("svc-arn"), Id: sdk.String(serviceID), }, nil) diff --git a/pkg/deploy/lattice/service_manager.go b/pkg/deploy/lattice/service_manager.go index 007c26ad..202305ba 100644 --- a/pkg/deploy/lattice/service_manager.go +++ b/pkg/deploy/lattice/service_manager.go @@ -87,7 +87,7 @@ func (m *defaultServiceManager) createAssociation(ctx context.Context, svcId *st } func (m *defaultServiceManager) newCreateSvcReq(svc *Service) *CreateSvcReq { - svcName := svc.LatticeName() + svcName := svc.LatticeServiceName() req := &vpclattice.CreateServiceInput{ Name: &svcName, } @@ -227,7 +227,7 @@ func associationsDiff(svc *Service, curAssocs []*SnSvcAssocSummary) ([]string, [ // TODO: we should have something more lightweight, retrying full reconciliation looks to heavy if aws.StringValue(oldSn.Status) == vpclattice.ServiceNetworkServiceAssociationStatusDeleteInProgress { return nil, nil, fmt.Errorf("%w: want to associate sn: %s to svc: %s, but status is: %s", - RetryErr, newSn, svc.LatticeName(), *oldSn.Status) + RetryErr, newSn, svc.LatticeServiceName(), *oldSn.Status) } // TODO: if assoc in failed state, may be we should try to re-create? } diff --git a/pkg/deploy/lattice/service_manager_test.go b/pkg/deploy/lattice/service_manager_test.go index bd1c6d4f..f0950f2b 100644 --- a/pkg/deploy/lattice/service_manager_test.go +++ b/pkg/deploy/lattice/service_manager_test.go @@ -51,7 +51,7 @@ func TestServiceManagerInteg(t *testing.T) { CreateServiceWithContext(gomock.Any(), gomock.Any()). DoAndReturn( func(_ context.Context, req *CreateSvcReq, _ ...interface{}) (*CreateSvcResp, error) { - assert.Equal(t, svc.LatticeName(), *req.Name) + assert.Equal(t, svc.LatticeServiceName(), *req.Name) return &CreateSvcResp{ Arn: aws.String("arn"), DnsEntry: &vpclattice.DnsEntry{DomainName: aws.String("dns")}, @@ -120,7 +120,7 @@ func TestServiceManagerInteg(t *testing.T) { Return(&vpclattice.ServiceSummary{ Arn: aws.String("svc-arn"), Id: aws.String("svc-id"), - Name: aws.String(svc.LatticeName()), + Name: aws.String(svc.LatticeServiceName()), }, nil). Times(1) @@ -210,7 +210,7 @@ func TestServiceManagerInteg(t *testing.T) { Return(&vpclattice.ServiceSummary{ Arn: aws.String("svc-arn"), Id: aws.String("svc-id"), - Name: aws.String(svc.LatticeName()), + Name: aws.String(svc.LatticeServiceName()), }, nil) lat.EXPECT(). ListServiceNetworkServiceAssociationsAsList(gomock.Any(), gomock.Any()). @@ -258,7 +258,7 @@ func TestCreateSvcReq(t *testing.T) { req := m.newCreateSvcReq(svcModel) - assert.Equal(t, *req.Name, svcModel.LatticeName()) + assert.Equal(t, *req.Name, svcModel.LatticeServiceName()) assert.Equal(t, *req.CustomDomainName, spec.CustomerDomainName) assert.Equal(t, *req.CertificateArn, spec.CustomerCertARN) diff --git a/pkg/deploy/stack_deployer_test.go b/pkg/deploy/stack_deployer_test.go index e60e681d..b5097ec2 100644 --- a/pkg/deploy/stack_deployer_test.go +++ b/pkg/deploy/stack_deployer_test.go @@ -48,7 +48,7 @@ func Test_latticeServiceStackDeployer_createAllResources(t *testing.T) { mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( &vpclattice.ServiceSummary{ - Name: aws.String(stackService.LatticeName()), + Name: aws.String(stackService.LatticeServiceName()), Id: aws.String("fake-service"), }, nil).AnyTimes() @@ -113,7 +113,7 @@ func Test_latticeServiceStackDeployer_CreateJustService(t *testing.T) { mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( &vpclattice.ServiceSummary{ - Name: aws.String(stackService.LatticeName()), + Name: aws.String(stackService.LatticeServiceName()), Id: aws.String("fake-service"), }, nil).AnyTimes() @@ -163,7 +163,7 @@ func Test_latticeServiceStackDeployer_DeleteService(t *testing.T) { mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( &vpclattice.ServiceSummary{ - Name: aws.String(stackService.LatticeName()), + Name: aws.String(stackService.LatticeServiceName()), Id: aws.String("fake-service"), }, nil).AnyTimes() @@ -220,7 +220,7 @@ func Test_latticeServiceStackDeployer_DeleteAllResources(t *testing.T) { mockLattice.EXPECT().FindService(gomock.Any(), gomock.Any()).Return( &vpclattice.ServiceSummary{ - Name: aws.String(stackService.LatticeName()), + Name: aws.String(stackService.LatticeServiceName()), Id: aws.String("fake-service"), }, nil).AnyTimes() diff --git a/pkg/model/lattice/service.go b/pkg/model/lattice/service.go index 192b1602..2c143e87 100644 --- a/pkg/model/lattice/service.go +++ b/pkg/model/lattice/service.go @@ -42,6 +42,6 @@ func NewLatticeService(stack core.Stack, id string, spec ServiceSpec) *Service { return service } -func (s *Service) LatticeName() string { +func (s *Service) LatticeServiceName() string { return utils.LatticeServiceName(s.Spec.Name, s.Spec.Namespace) } diff --git a/test/pkg/test/framework.go b/test/pkg/test/framework.go index 848f9ec2..acc524e4 100644 --- a/test/pkg/test/framework.go +++ b/test/pkg/test/framework.go @@ -268,7 +268,7 @@ func (env *Framework) GetServiceNetwork(ctx context.Context, gateway *gateway_ap func (env *Framework) GetVpcLatticeService(ctx context.Context, route core.Route) *vpclattice.ServiceSummary { var found *vpclattice.ServiceSummary - rnProvider := controllers.RouteNameProvider{route} + rnProvider := controllers.RouteLSNProvider{route} Eventually(func(g Gomega) { svc, err := env.LatticeClient.FindService(ctx, &rnProvider) @@ -276,7 +276,7 @@ func (env *Framework) GetVpcLatticeService(ctx context.Context, route core.Route found = svc g.Expect(found).ToNot(BeNil()) g.Expect(found.Status).To(Equal(lo.ToPtr(vpclattice.ServiceStatusActive))) - g.Expect(found.DnsEntry).To(ContainSubstring(rnProvider.LatticeName())) + g.Expect(found.DnsEntry).To(ContainSubstring(rnProvider.LatticeServiceName())) }).WithOffset(1).Should(Succeed()) return found diff --git a/test/suites/integration/defined_target_ports_test.go b/test/suites/integration/defined_target_ports_test.go index b22c112a..77eb130a 100644 --- a/test/suites/integration/defined_target_ports_test.go +++ b/test/suites/integration/defined_target_ports_test.go @@ -70,8 +70,8 @@ var _ = Describe("Defined Target Ports", func() { // Verify VPC Lattice Service exists route, _ := core.NewRoute(httpRoute) vpcLatticeService = testFramework.GetVpcLatticeService(ctx, route) - rnp := controllers.RouteNameProvider{route} - Expect(*vpcLatticeService.DnsEntry).To(ContainSubstring(rnp.LatticeName())) + rnp := controllers.RouteLSNProvider{route} + Expect(*vpcLatticeService.DnsEntry).To(ContainSubstring(rnp.LatticeServiceName())) performVerification(service, deployment, definedPorts) })