Skip to content

Commit 8a36b59

Browse files
author
Anton
authored
CLOUDP-78181: ip access list (part 3) (#92)
1 parent 7505f50 commit 8a36b59

File tree

6 files changed

+248
-56
lines changed

6 files changed

+248
-56
lines changed

config/crd/bases/atlas.mongodb.com_atlasprojects.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,35 @@ spec:
118118
- type
119119
type: object
120120
type: array
121+
expiredIpAccessList:
122+
description: The list of IP Access List entries that are expired due
123+
to 'deleteAfterDate' being less than the current date. Note, that
124+
this field is updated by the Atlas Operator only after specification
125+
changes
126+
items:
127+
description: TODO solve circular dependency (move ProjectIPAccessList
128+
to subpackage?) Copy of mdbv1.ProjectIPAccessList
129+
properties:
130+
awsSecurityGroup:
131+
description: Unique identifier of AWS security group in this
132+
access list entry.
133+
type: string
134+
cidrBlock:
135+
description: Range of IP addresses in CIDR notation in this
136+
access list entry.
137+
type: string
138+
comment:
139+
description: Comment associated with this access list entry.
140+
type: string
141+
deleteAfterDate:
142+
description: Timestamp in ISO 8601 date and time format in UTC
143+
after which Atlas deletes the temporary access list entry.
144+
type: string
145+
ipAddress:
146+
description: Entry using an IP address in this access list entry.
147+
type: string
148+
type: object
149+
type: array
121150
id:
122151
description: The ID of the Atlas Project
123152
type: string

pkg/api/v1/status/atlasproject.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ func AtlasProjectIDOption(id string) AtlasProjectStatusOption {
1010
s.ID = id
1111
}
1212
}
13+
func AtlasProjectExpiredIPAccessOption(lists []ProjectIPAccessList) AtlasProjectStatusOption {
14+
return func(s *AtlasProjectStatus) {
15+
s.ExpiredIPAccessList = lists
16+
}
17+
}
1318

1419
// AtlasProjectStatus defines the observed state of AtlasProject
1520
type AtlasProjectStatus struct {
@@ -18,4 +23,29 @@ type AtlasProjectStatus struct {
1823
// The ID of the Atlas Project
1924
// +optional
2025
ID string `json:"id,omitempty"`
26+
27+
// The list of IP Access List entries that are expired due to 'deleteAfterDate' being less than the current date.
28+
// Note, that this field is updated by the Atlas Operator only after specification changes
29+
ExpiredIPAccessList []ProjectIPAccessList `json:"expiredIpAccessList,omitempty"`
30+
}
31+
32+
// TODO solve circular dependency (move ProjectIPAccessList to subpackage?)
33+
34+
// ProjectIPAccessList is a copy of mdbv1.ProjectIPAccessList
35+
type ProjectIPAccessList struct {
36+
// Unique identifier of AWS security group in this access list entry.
37+
// +optional
38+
AwsSecurityGroup string `json:"awsSecurityGroup,omitempty"`
39+
// Range of IP addresses in CIDR notation in this access list entry.
40+
// +optional
41+
CIDRBlock string `json:"cidrBlock,omitempty"`
42+
// Comment associated with this access list entry.
43+
// +optional
44+
Comment string `json:"comment,omitempty"`
45+
// Timestamp in ISO 8601 date and time format in UTC after which Atlas deletes the temporary access list entry.
46+
// +optional
47+
DeleteAfterDate string `json:"deleteAfterDate,omitempty"`
48+
// Entry using an IP address in this access list entry.
49+
// +optional
50+
IPAddress string `json:"ipAddress,omitempty"`
2151
}

pkg/api/v1/status/zz_generated.deepcopy.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/controller/atlasproject/ipaccess_list.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"go.uber.org/zap"
1010

1111
mdbv1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1"
12+
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status"
1213
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/atlas"
1314
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/workflow"
1415
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/set"
@@ -20,14 +21,23 @@ import (
2021
type atlasProjectIPAccessList mongodbatlas.ProjectIPAccessList
2122

2223
func (i atlasProjectIPAccessList) Identifier() interface{} {
24+
// hack: Atlas adds the CIDRBlock in case IPAddress is specified in the response.
25+
// This doesn't conform to the "update" contract (one field per List) and doesn't allow to "merge" lists.
26+
// So we ignore the CIDRblock in this case.
27+
// Note, this used to have "&& strings.HasPrefix(i.CIDRBlock, i.IPAddress" check as well but according to the example:
28+
// https://docs.atlas.mongodb.com/reference/api/ip-access-list/add-entries-to-access-list/#example-body the IP may
29+
// be not a prefix of CIDR!
30+
if i.CIDRBlock != "" && i.IPAddress != "" {
31+
return i.AwsSecurityGroup + i.IPAddress
32+
}
2333
return i.CIDRBlock + i.AwsSecurityGroup + i.IPAddress
2434
}
2535

2636
func (r *AtlasProjectReconciler) ensureIPAccessList(ctx *workflow.Context, connection atlas.Connection, projectID string, project *mdbv1.AtlasProject) workflow.Result {
2737
if err := validateIPAccessLists(project.Spec.ProjectIPAccessList); err != nil {
2838
return workflow.Terminate(workflow.ProjectIPAccessInvalid, err.Error())
2939
}
30-
active, _ := filterActiveIPAccessLists(project.Spec.ProjectIPAccessList)
40+
active, expired := filterActiveIPAccessLists(project.Spec.ProjectIPAccessList)
3141

3242
client, err := atlas.Client(r.AtlasDomain, connection, ctx.Log)
3343
if err != nil {
@@ -36,7 +46,12 @@ func (r *AtlasProjectReconciler) ensureIPAccessList(ctx *workflow.Context, conne
3646
if result := createOrDeleteInAtlas(client, projectID, active, ctx.Log); !result.IsOk() {
3747
return result
3848
}
39-
// TODO update status - add the expired project IP access list there
49+
// TODO remove after the circular dependency is solved
50+
expiredCopy := make([]status.ProjectIPAccessList, len(expired))
51+
for i, list := range expired {
52+
expiredCopy[i] = status.ProjectIPAccessList(list)
53+
}
54+
ctx.EnsureStatusOption(status.AtlasProjectExpiredIPAccessOption(expiredCopy))
4055
return workflow.OK()
4156
}
4257

test/int/integration_suite_test.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"k8s.io/client-go/kubernetes/scheme"
3535
"k8s.io/client-go/rest"
3636
ctrl "sigs.k8s.io/controller-runtime"
37+
"sigs.k8s.io/controller-runtime/pkg/client/config"
3738
ctrzap "sigs.k8s.io/controller-runtime/pkg/log/zap"
3839

3940
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -92,14 +93,23 @@ var _ = SynchronizedBeforeSuite(func() []byte {
9293
fmt.Printf("Api Server is listening on %s\n", cfg.Host)
9394
return []byte(cfg.Host)
9495
}, func(data []byte) {
95-
// This is the host that was serialized on the 1st node by the function above.
96-
host := string(data)
97-
// copied from Environment.Start()
98-
cfg = &rest.Config{
99-
Host: host,
100-
// gotta go fast during tests -- we don't really care about overwhelming our test API server
101-
QPS: 1000.0,
102-
Burst: 2000.0,
96+
if os.Getenv("USE_EXISTING_CLUSTER") != "" {
97+
var err error
98+
// For the existing cluster we read the kubeconfig
99+
cfg, err = config.GetConfig()
100+
if err != nil {
101+
panic("Failed to read the config for existing cluster")
102+
}
103+
} else {
104+
// This is the host that was serialized on the 1st node by the function above.
105+
host := string(data)
106+
// copied from Environment.Start()
107+
cfg = &rest.Config{
108+
Host: host,
109+
// gotta go fast during tests -- we don't really care about overwhelming our test API server
110+
QPS: 1000.0,
111+
Burst: 2000.0,
112+
}
103113
}
104114

105115
err := mdbv1.AddToScheme(scheme.Scheme)

0 commit comments

Comments
 (0)