@@ -3,16 +3,19 @@ package atlasproject
3
3
import (
4
4
"context"
5
5
"errors"
6
+ "fmt"
6
7
"net/http"
7
8
"testing"
8
9
9
10
"github.com/google/go-cmp/cmp"
10
11
"github.com/google/go-cmp/cmp/cmpopts"
11
12
"github.com/stretchr/testify/assert"
12
13
"github.com/stretchr/testify/mock"
14
+ "github.com/stretchr/testify/require"
13
15
"go.mongodb.org/atlas-sdk/v20231115008/admin"
14
16
"go.mongodb.org/atlas-sdk/v20231115008/mockadmin"
15
17
"go.uber.org/zap/zaptest"
18
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16
19
17
20
"github.com/mongodb/mongodb-atlas-kubernetes/v2/api"
18
21
akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/api/v1"
@@ -570,3 +573,132 @@ func TestHasSkippedIPAccessListConfiguration(t *testing.T) {
570
573
})
571
574
}
572
575
}
576
+
577
+ func TestIPAccessListNonGreedyBehaviour (t * testing.T ) {
578
+ for _ , tc := range []struct {
579
+ title string
580
+ lastAppliedIPAccessList []string
581
+ specIPAccessList []string
582
+ atlasIPAccessList []string
583
+ wantRemoved []string
584
+ }{
585
+ {
586
+ title : "no last applied no removal in Atlas" ,
587
+ lastAppliedIPAccessList : []string {},
588
+ specIPAccessList : []string {},
589
+ atlasIPAccessList : []string {"100.90.0.0/24" , "101.99.0.0/24" },
590
+ wantRemoved : []string {},
591
+ },
592
+ {
593
+ title : "removed from last applied removes from Atlas" ,
594
+ lastAppliedIPAccessList : []string {"100.90.0.0/24" , "101.99.0.0/24" },
595
+ specIPAccessList : []string {"100.90.0.0/24" },
596
+ atlasIPAccessList : []string {"100.90.0.0/24" , "101.99.0.0/24" },
597
+ wantRemoved : []string {"101.99.0.0/24" },
598
+ },
599
+ {
600
+ title : "removed all from last applied removes all from Atlas" ,
601
+ lastAppliedIPAccessList : []string {"100.90.0.0/24" , "101.99.0.0/24" },
602
+ specIPAccessList : []string {},
603
+ atlasIPAccessList : []string {"100.90.0.0/24" , "101.99.0.0/24" },
604
+ wantRemoved : []string {"100.90.0.0/24" , "101.99.0.0/24" },
605
+ },
606
+ {
607
+ title : "not in last applied still removed from Atlas" ,
608
+ lastAppliedIPAccessList : []string {"100.90.0.0/24" },
609
+ specIPAccessList : []string {"100.90.0.0/24" },
610
+ atlasIPAccessList : []string {"100.90.0.0/24" , "101.99.0.0/24" },
611
+ wantRemoved : []string {"101.99.0.0/24" },
612
+ },
613
+ } {
614
+ t .Run (tc .title , func (t * testing.T ) {
615
+ prj := newIPAccessListTestProject (tc .specIPAccessList )
616
+ lastPrj := newIPAccessListTestProject (tc .lastAppliedIPAccessList )
617
+ prj .Annotations [customresource .AnnotationLastAppliedConfiguration ] = jsonize (t , lastPrj .Spec )
618
+
619
+ ipAccessAPI := mockadmin .NewProjectIPAccessListApi (t )
620
+ ipAccessAPI .EXPECT ().ListProjectIpAccessLists (mock .Anything , mock .Anything ).
621
+ Return (admin.ListProjectIpAccessListsApiRequest {ApiService : ipAccessAPI }).Once ()
622
+ ipAccessAPI .EXPECT ().ListProjectIpAccessListsExecute (
623
+ mock .AnythingOfType ("admin.ListProjectIpAccessListsApiRequest" )).Return (
624
+ synthesizeAtlasIPAccessList (tc .atlasIPAccessList ), nil , nil ,
625
+ ).Once ()
626
+ // CreateProjectIpAccessList is a non destrutive operation, it does not remove entries
627
+ ipAccessAPI .EXPECT ().CreateProjectIpAccessList (mock .Anything , mock .Anything , mock .Anything ).
628
+ Return (admin.CreateProjectIpAccessListApiRequest {ApiService : ipAccessAPI }).Once ()
629
+ ipAccessAPI .EXPECT ().CreateProjectIpAccessListExecute (
630
+ mock .AnythingOfType ("admin.CreateProjectIpAccessListApiRequest" )).Return (
631
+ nil , nil , nil ,
632
+ ).Once ()
633
+
634
+ removals := len (tc .wantRemoved )
635
+ if removals > 0 {
636
+ ipAccessAPI .EXPECT ().DeleteProjectIpAccessList (
637
+ mock .Anything , mock .Anything , mock .Anything ,
638
+ ).Return (admin.DeleteProjectIpAccessListApiRequest {ApiService : ipAccessAPI }).Times (removals )
639
+ ipAccessAPI .EXPECT ().DeleteProjectIpAccessListExecute (
640
+ mock .AnythingOfType ("admin.DeleteProjectIpAccessListApiRequest" )).Return (
641
+ nil , nil , nil ,
642
+ ).Times (removals )
643
+ }
644
+
645
+ unset := len (tc .specIPAccessList ) == 0
646
+ if ! unset {
647
+ ipAccessAPI .EXPECT ().GetProjectIpAccessListStatus (
648
+ mock .Anything , mock .Anything , mock .Anything ,
649
+ ).Return (admin.GetProjectIpAccessListStatusApiRequest {ApiService : ipAccessAPI }).Times (removals )
650
+ ipAccessAPI .EXPECT ().GetProjectIpAccessListStatusExecute (
651
+ mock .AnythingOfType ("admin.GetProjectIpAccessListStatusApiRequest" )).Return (
652
+ nil , nil , nil ,
653
+ ).Times (removals )
654
+ }
655
+
656
+ workflowCtx := workflow.Context {
657
+ Log : zaptest .NewLogger (t ).Sugar (),
658
+ Context : context .Background (),
659
+ SdkClient : & admin.APIClient {
660
+ ProjectIPAccessListApi : ipAccessAPI ,
661
+ },
662
+ }
663
+
664
+ result := handleIPAccessList (& workflowCtx , prj )
665
+ require .Equal (t , workflow .OK (), result )
666
+ })
667
+ }
668
+ }
669
+
670
+ func newIPAccessListTestProject (ipAccessList []string ) * akov2.AtlasProject {
671
+ return & akov2.AtlasProject {
672
+ ObjectMeta : metav1.ObjectMeta {
673
+ Annotations : map [string ]string {},
674
+ },
675
+ Spec : akov2.AtlasProjectSpec {
676
+ Name : "test-project" ,
677
+ ProjectIPAccessList : synthesizeIPAccessList (ipAccessList ),
678
+ },
679
+ }
680
+ }
681
+
682
+ func synthesizeIPAccessList (ipAccessList []string ) []project.IPAccessList {
683
+ peers := make ([]project.IPAccessList , 0 , len (ipAccessList ))
684
+ for _ , cidr := range ipAccessList {
685
+ peers = append (peers , project.IPAccessList {
686
+ CIDRBlock : cidr ,
687
+ Comment : fmt .Sprintf ("fake CIDR block %s" , cidr ),
688
+ })
689
+ }
690
+ return peers
691
+ }
692
+
693
+ func synthesizeAtlasIPAccessList (peeringIDs []string ) * admin.PaginatedNetworkAccess {
694
+ atlasIPAccessList := make ([]admin.NetworkPermissionEntry , 0 , len (peeringIDs ))
695
+ for _ , cidr := range peeringIDs {
696
+ atlasIPAccessList = append (atlasIPAccessList , admin.NetworkPermissionEntry {
697
+ CidrBlock : pointer .MakePtr (cidr ),
698
+ Comment : pointer .MakePtr (fmt .Sprintf ("fake CIDR block %s" , cidr )),
699
+ })
700
+ }
701
+ return & admin.PaginatedNetworkAccess {
702
+ Results : & atlasIPAccessList ,
703
+ }
704
+ }
0 commit comments