Skip to content

Commit ee4f973

Browse files
committed
private endpoint: add support for regional mode
1 parent 604283d commit ee4f973

File tree

10 files changed

+280
-43
lines changed

10 files changed

+280
-43
lines changed

api/condition.go

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,23 +48,24 @@ const (
4848

4949
// AtlasProject condition types
5050
const (
51-
ProjectReadyType ConditionType = "ProjectReady"
52-
IPAccessListReadyType ConditionType = "IPAccessListReady"
53-
MaintenanceWindowReadyType ConditionType = "MaintenanceWindowReady"
54-
PrivateEndpointServiceReadyType ConditionType = "PrivateEndpointServiceReady"
55-
PrivateEndpointReadyType ConditionType = "PrivateEndpointReady"
56-
NetworkPeerReadyType ConditionType = "NetworkPeerReady"
57-
CloudProviderIntegrationReadyType ConditionType = "CloudProviderIntegrationReady"
58-
IntegrationReadyType ConditionType = "ThirdPartyIntegrationReady"
59-
AlertConfigurationReadyType ConditionType = "AlertConfigurationReady"
60-
EncryptionAtRestReadyType ConditionType = "EncryptionAtRestReady"
61-
AuditingReadyType ConditionType = "AuditingReady"
62-
ProjectSettingsReadyType ConditionType = "ProjectSettingsReady"
63-
ProjectCustomRolesReadyType ConditionType = "ProjectCustomRolesReady"
64-
ProjectTeamsReadyType ConditionType = "ProjectTeamsReady"
65-
SearchIndexesReadyType ConditionType = "AtlasSearchIndexesReady"
66-
BackupComplianceReadyType ConditionType = "BackupCompliancePolicyReady"
67-
X509AuthReadyType ConditionType = "X509AuthReady"
51+
ProjectReadyType ConditionType = "ProjectReady"
52+
IPAccessListReadyType ConditionType = "IPAccessListReady"
53+
MaintenanceWindowReadyType ConditionType = "MaintenanceWindowReady"
54+
PrivateEndpointServiceReadyType ConditionType = "PrivateEndpointServiceReady"
55+
RegionalizedPrivateEndpointReadyType ConditionType = "RegionalizedPrivateEndpointReady"
56+
PrivateEndpointReadyType ConditionType = "PrivateEndpointReady"
57+
NetworkPeerReadyType ConditionType = "NetworkPeerReady"
58+
CloudProviderIntegrationReadyType ConditionType = "CloudProviderIntegrationReady"
59+
IntegrationReadyType ConditionType = "ThirdPartyIntegrationReady"
60+
AlertConfigurationReadyType ConditionType = "AlertConfigurationReady"
61+
EncryptionAtRestReadyType ConditionType = "EncryptionAtRestReady"
62+
AuditingReadyType ConditionType = "AuditingReady"
63+
ProjectSettingsReadyType ConditionType = "ProjectSettingsReady"
64+
ProjectCustomRolesReadyType ConditionType = "ProjectCustomRolesReady"
65+
ProjectTeamsReadyType ConditionType = "ProjectTeamsReady"
66+
SearchIndexesReadyType ConditionType = "AtlasSearchIndexesReady"
67+
BackupComplianceReadyType ConditionType = "BackupCompliancePolicyReady"
68+
X509AuthReadyType ConditionType = "X509AuthReady"
6869
)
6970

7071
// AtlasDeployment condition types

api/v1/atlasproject_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ type AtlasProjectSpec struct {
7272
// PrivateEndpoints is a list of Private Endpoints configured for the current Project.
7373
PrivateEndpoints []PrivateEndpoint `json:"privateEndpoints,omitempty"`
7474

75+
// RegionalizedPrivateEndpoint allows to enable regionalized private endpoints. See more at
76+
// https://www.mongodb.com/docs/atlas/security-private-endpoint/
77+
// +optional
78+
RegionalizedPrivateEndpoint *project.RegionalizedPrivateEndpoint `json:"regionalizedPrivateEndpoint,omitempty"`
79+
7580
// CloudProviderAccessRoles is a list of Cloud Provider Access Roles configured for the current Project.
7681
// Deprecated: This configuration was deprecated in favor of CloudProviderIntegrations
7782
CloudProviderAccessRoles []CloudProviderAccessRole `json:"cloudProviderAccessRoles,omitempty"`
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2025 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package project
16+
17+
type RegionalizedPrivateEndpoint struct {
18+
// Flag indicating whether regionalized private endpoint mode should be enabled.
19+
// +optional
20+
Enabled bool `json:"enabled,omitempty"`
21+
}

api/v1/zz_generated.deepcopy.go

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

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,16 @@ spec:
902902
- GOV_REGIONS_ONLY
903903
- COMMERCIAL_FEDRAMP_REGIONS_ONLY
904904
type: string
905+
regionalizedPrivateEndpoint:
906+
description: |-
907+
RegionalizedPrivateEndpoint allows to enable regionalized private endpoints. See more at
908+
https://www.mongodb.com/docs/atlas/security-private-endpoint/
909+
properties:
910+
enabled:
911+
description: Flag indicating whether regionalized private endpoint
912+
mode should be enabled.
913+
type: boolean
914+
type: object
905915
settings:
906916
description: Settings allow to set Project Settings for the project
907917
properties:

internal/controller/atlasproject/atlasproject_controller.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,11 @@ func (r *AtlasProjectReconciler) ensureProjectResources(workflowCtx *workflow.Co
190190
}
191191
results = append(results, result)
192192

193+
if result = r.ensureRegionalizedPrivateEndpointMode(workflowCtx, project); result.IsOk() {
194+
r.EventRecorder.Event(project, "Normal", string(api.RegionalizedPrivateEndpointReadyType), "")
195+
}
196+
results = append(results, result)
197+
193198
if result = ensureCloudProviderIntegration(workflowCtx, project); result.IsOk() {
194199
r.EventRecorder.Event(project, "Normal", string(api.CloudProviderIntegrationReadyType), "")
195200
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2025 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package atlasproject
16+
17+
import (
18+
"github.com/mongodb/mongodb-atlas-kubernetes/v2/api"
19+
akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/api/v1"
20+
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/controller/workflow"
21+
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/translation/privateendpoint"
22+
)
23+
24+
// ensureRegionalizedPrivateEndpointMode ensures that if the AtlasProject spec
25+
// defines a regionalized private endpoint setting, it is reflected in Atlas.
26+
func (r *AtlasProjectReconciler) ensureRegionalizedPrivateEndpointMode(workflowCtx *workflow.Context, atlasProject *akov2.AtlasProject) workflow.DeprecatedResult {
27+
if atlasProject.Spec.RegionalizedPrivateEndpoint == nil {
28+
workflowCtx.UnsetCondition(api.RegionalizedPrivateEndpointReadyType)
29+
return workflow.OK()
30+
}
31+
32+
expectedMode := atlasProject.Spec.RegionalizedPrivateEndpoint.Enabled
33+
34+
peApi := privateendpoint.NewPrivateEndpointAPI(workflowCtx.SdkClientSet.SdkClient20250312002.PrivateEndpointServicesApi)
35+
currentMode, err := peApi.GetRegionalizedPrivateEndpointSetting(workflowCtx.Context, atlasProject.ID())
36+
if err != nil {
37+
result := workflow.Terminate(workflow.ProjectRegionalizedEndpointModeIsNotReadyInAtlas, err)
38+
workflowCtx.SetConditionFromResult(api.RegionalizedPrivateEndpointReadyType, result)
39+
return result
40+
}
41+
42+
if currentMode != expectedMode {
43+
if _, err := peApi.ToggleRegionalizedPrivateEndpointSetting(workflowCtx.Context, atlasProject.ID(), expectedMode); err != nil {
44+
result := workflow.Terminate(workflow.ProjectRegionalizedEndpointModeIsNotReadyInAtlas, err)
45+
workflowCtx.SetConditionFromResult(api.RegionalizedPrivateEndpointReadyType, result)
46+
return result
47+
}
48+
}
49+
50+
workflowCtx.SetConditionTrue(api.RegionalizedPrivateEndpointReadyType)
51+
return workflow.OK()
52+
}

internal/controller/workflow/reason.go

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,32 +33,33 @@ const (
3333

3434
// Atlas Project reasons
3535
const (
36-
ProjectNotCreatedInAtlas ConditionReason = "ProjectNotCreatedInAtlas"
37-
ProjectBeingConfiguredInAtlas ConditionReason = "ProjectBeingConfiguredInAtlas"
38-
ProjectIPAccessInvalid ConditionReason = "ProjectIPAccessListInvalid"
39-
ProjectIPNotCreatedInAtlas ConditionReason = "ProjectIPAccessListNotCreatedInAtlas"
40-
ProjectWindowInvalid ConditionReason = "ProjectWindowInvalid"
41-
ProjectWindowNotObtainedFromAtlas ConditionReason = "ProjectWindowNotObtainedFromAtlas"
42-
ProjectWindowNotCreatedInAtlas ConditionReason = "ProjectWindowNotCreatedInAtlas"
43-
ProjectWindowNotDeletedInAtlas ConditionReason = "projectWindowNotDeletedInAtlas"
44-
ProjectWindowNotDeferredInAtlas ConditionReason = "ProjectWindowNotDeferredInAtlas"
45-
ProjectWindowNotAutoDeferredInAtlas ConditionReason = "ProjectWindowNotAutoDeferredInAtlas"
46-
ProjectPEServiceIsNotReadyInAtlas ConditionReason = "ProjectPrivateEndpointServiceIsNotReadyInAtlas"
47-
ProjectPEInterfaceIsNotReadyInAtlas ConditionReason = "ProjectPrivateEndpointIsNotReadyInAtlas"
48-
ProjectIPAccessListNotActive ConditionReason = "ProjectIPAccessListNotActive"
49-
ProjectIntegrationInternal ConditionReason = "ProjectIntegrationInternalError"
50-
ProjectIntegrationRequest ConditionReason = "ProjectIntegrationRequestError"
51-
ProjectIntegrationReady ConditionReason = "ProjectIntegrationReady"
52-
ProjectPrivateEndpointIsNotReadyInAtlas ConditionReason = "ProjectPrivateEndpointIsNotReadyInAtlas"
53-
ProjectNetworkPeerIsNotReadyInAtlas ConditionReason = "ProjectNetworkPeerIsNotReadyInAtlas"
54-
ProjectEncryptionAtRestReady ConditionReason = "ProjectEncryptionAtRestReady"
55-
ProjectCloudIntegrationsIsNotReadyInAtlas ConditionReason = "ProjectCloudIntegrationsIsNotReadyInAtlas"
56-
ProjectAuditingReady ConditionReason = "ProjectAuditingReady"
57-
ProjectSettingsReady ConditionReason = "ProjectSettingsReady"
58-
ProjectAlertConfigurationIsNotReadyInAtlas ConditionReason = "ProjectAlertConfigurationIsNotReadyInAtlas"
59-
ProjectCustomRolesReady ConditionReason = "ProjectCustomRolesReady"
60-
ProjectTeamUnavailable ConditionReason = "ProjectTeamUnavailable"
61-
ProjectX509NotConfigured ConditionReason = "ProjectX509NotConfigured"
36+
ProjectNotCreatedInAtlas ConditionReason = "ProjectNotCreatedInAtlas"
37+
ProjectBeingConfiguredInAtlas ConditionReason = "ProjectBeingConfiguredInAtlas"
38+
ProjectIPAccessInvalid ConditionReason = "ProjectIPAccessListInvalid"
39+
ProjectIPNotCreatedInAtlas ConditionReason = "ProjectIPAccessListNotCreatedInAtlas"
40+
ProjectWindowInvalid ConditionReason = "ProjectWindowInvalid"
41+
ProjectWindowNotObtainedFromAtlas ConditionReason = "ProjectWindowNotObtainedFromAtlas"
42+
ProjectWindowNotCreatedInAtlas ConditionReason = "ProjectWindowNotCreatedInAtlas"
43+
ProjectWindowNotDeletedInAtlas ConditionReason = "projectWindowNotDeletedInAtlas"
44+
ProjectWindowNotDeferredInAtlas ConditionReason = "ProjectWindowNotDeferredInAtlas"
45+
ProjectWindowNotAutoDeferredInAtlas ConditionReason = "ProjectWindowNotAutoDeferredInAtlas"
46+
ProjectPEServiceIsNotReadyInAtlas ConditionReason = "ProjectPrivateEndpointServiceIsNotReadyInAtlas"
47+
ProjectPEInterfaceIsNotReadyInAtlas ConditionReason = "ProjectPrivateEndpointIsNotReadyInAtlas"
48+
ProjectIPAccessListNotActive ConditionReason = "ProjectIPAccessListNotActive"
49+
ProjectIntegrationInternal ConditionReason = "ProjectIntegrationInternalError"
50+
ProjectIntegrationRequest ConditionReason = "ProjectIntegrationRequestError"
51+
ProjectIntegrationReady ConditionReason = "ProjectIntegrationReady"
52+
ProjectPrivateEndpointIsNotReadyInAtlas ConditionReason = "ProjectPrivateEndpointIsNotReadyInAtlas"
53+
ProjectRegionalizedEndpointModeIsNotReadyInAtlas ConditionReason = "ProjectRegionalizedEndpointModeIsNotReadyInAtlas"
54+
ProjectNetworkPeerIsNotReadyInAtlas ConditionReason = "ProjectNetworkPeerIsNotReadyInAtlas"
55+
ProjectEncryptionAtRestReady ConditionReason = "ProjectEncryptionAtRestReady"
56+
ProjectCloudIntegrationsIsNotReadyInAtlas ConditionReason = "ProjectCloudIntegrationsIsNotReadyInAtlas"
57+
ProjectAuditingReady ConditionReason = "ProjectAuditingReady"
58+
ProjectSettingsReady ConditionReason = "ProjectSettingsReady"
59+
ProjectAlertConfigurationIsNotReadyInAtlas ConditionReason = "ProjectAlertConfigurationIsNotReadyInAtlas"
60+
ProjectCustomRolesReady ConditionReason = "ProjectCustomRolesReady"
61+
ProjectTeamUnavailable ConditionReason = "ProjectTeamUnavailable"
62+
ProjectX509NotConfigured ConditionReason = "ProjectX509NotConfigured"
6263
)
6364

6465
// Atlas Backup Compliance Policy reasons

internal/mocks/translation/private_endpoint_service.go

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

0 commit comments

Comments
 (0)