Skip to content

Commit 895f2a9

Browse files
Sugar-packhelderjs
andauthored
CLOUDP-142596: Add serverless PE support (#779)
Co-authored-by: Helder Santana <contato@heldersantana.net>
1 parent 6e725be commit 895f2a9

File tree

24 files changed

+972
-20
lines changed

24 files changed

+972
-20
lines changed

.github/workflows/test-e2e.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ jobs:
9090
"networkpeering",
9191
"privatelink",
9292
"project-settings",
93+
"serverless-pe",
9394
"x509auth",
9495
"custom-roles",
9596
]

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

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,24 @@ spec:
553553
its name. Can only contain ASCII letters, numbers, and hyphens.
554554
pattern: ^[a-zA-Z0-9][a-zA-Z0-9-]*$
555555
type: string
556+
privateEndpoints:
557+
items:
558+
properties:
559+
cloudProviderEndpointID:
560+
description: CloudProviderEndpointID is the identifier of
561+
the cloud provider endpoint.
562+
type: string
563+
name:
564+
description: Name is the name of the Serverless PrivateLink
565+
Service. Should be unique.
566+
type: string
567+
privateEndpointIpAddress:
568+
description: PrivateEndpointIPAddress is the IPv4 address
569+
of the private endpoint in your Azure VNet that someone
570+
added to this private endpoint service.
571+
type: string
572+
type: object
573+
type: array
556574
providerSettings:
557575
description: Configuration for the provisioned hosts on which
558576
MongoDB runs. The available options are specific to the cloud
@@ -787,6 +805,50 @@ spec:
787805
reconciliation of the resource.
788806
format: int64
789807
type: integer
808+
serverlessPrivateEndpoints:
809+
items:
810+
properties:
811+
_id:
812+
description: ID is the identifier of the Serverless PrivateLink
813+
Service.
814+
type: string
815+
cloudProviderEndpointId:
816+
description: CloudProviderEndpointID is the identifier of the
817+
cloud provider endpoint.
818+
type: string
819+
endpointServiceName:
820+
description: EndpointServiceName is the name of the PrivateLink
821+
endpoint service in AWS. Returns null while the endpoint service
822+
is being created.
823+
type: string
824+
errorMessage:
825+
description: ErrorMessage is the error message if the Serverless
826+
PrivateLink Service failed to create or connect.
827+
type: string
828+
name:
829+
description: Name is the name of the Serverless PrivateLink
830+
Service. Should be unique.
831+
type: string
832+
privateEndpointIpAddress:
833+
description: PrivateEndpointIPAddress is the IPv4 address of
834+
the private endpoint in your Azure VNet that someone added
835+
to this private endpoint service.
836+
type: string
837+
privateLinkServiceResourceId:
838+
description: PrivateLinkServiceResourceID is the root-relative
839+
path that identifies the Azure Private Link Service that MongoDB
840+
Cloud manages. MongoDB Cloud returns null while it creates
841+
the endpoint service.
842+
type: string
843+
providerName:
844+
description: ProviderName is human-readable label that identifies
845+
the cloud provider. Values include AWS or AZURE.
846+
type: string
847+
status:
848+
description: Status of the AWS Serverless PrivateLink connection.
849+
type: string
850+
type: object
851+
type: array
790852
stateName:
791853
description: 'StateName is the current state of the cluster. The possible
792854
states are: IDLE, CREATING, UPDATING, DELETING, DELETED, REPAIRING'

pkg/api/v1/atlasdeployment_types.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ type ServerlessSpec struct {
179179
Name string `json:"name"`
180180
// Configuration for the provisioned hosts on which MongoDB runs. The available options are specific to the cloud service provider.
181181
ProviderSettings *ProviderSettingsSpec `json:"providerSettings"`
182+
183+
PrivateEndpoints []ServerlessPrivateEndpoint `json:"privateEndpoints,omitempty"`
182184
}
183185

184186
// BiConnector specifies BI Connector for Atlas configuration on this deployment.
@@ -706,11 +708,14 @@ func NewDefaultAWSServerlessInstance(namespace, projectName string) *AtlasDeploy
706708
}
707709

708710
func (c *AtlasDeployment) AtlasName() string {
709-
if c.Spec.DeploymentSpec.Name != "" {
711+
if c.Spec.DeploymentSpec != nil {
710712
return c.Spec.DeploymentSpec.Name
711713
}
712-
if c.Spec.AdvancedDeploymentSpec.Name != "" {
714+
if c.Spec.AdvancedDeploymentSpec != nil {
713715
return c.Spec.AdvancedDeploymentSpec.Name
714716
}
715-
return c.Spec.ServerlessSpec.Name
717+
if c.Spec.ServerlessSpec != nil {
718+
return c.Spec.ServerlessSpec.Name
719+
}
720+
return ""
716721
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package v1
2+
3+
import (
4+
"go.mongodb.org/atlas/mongodbatlas"
5+
6+
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/provider"
7+
)
8+
9+
type ServerlessPrivateEndpoint struct {
10+
// Name is the name of the Serverless PrivateLink Service. Should be unique.
11+
Name string `json:"name,omitempty"`
12+
// CloudProviderEndpointID is the identifier of the cloud provider endpoint.
13+
CloudProviderEndpointID string `json:"cloudProviderEndpointID,omitempty"`
14+
// PrivateEndpointIPAddress is the IPv4 address of the private endpoint in your Azure VNet that someone added to this private endpoint service.
15+
PrivateEndpointIPAddress string `json:"privateEndpointIpAddress,omitempty"`
16+
}
17+
18+
// IsInitialState pe initially should be empty except for comment
19+
func (in *ServerlessPrivateEndpoint) IsInitialState() bool {
20+
return in.Name != "" && in.CloudProviderEndpointID == "" && in.PrivateEndpointIPAddress == ""
21+
}
22+
23+
func (in *ServerlessPrivateEndpoint) ToAtlas(providerName provider.ProviderName) *mongodbatlas.ServerlessPrivateEndpointConnection {
24+
if in.IsInitialState() {
25+
return &mongodbatlas.ServerlessPrivateEndpointConnection{
26+
Comment: in.Name,
27+
}
28+
}
29+
30+
switch providerName {
31+
case provider.ProviderAWS:
32+
return &mongodbatlas.ServerlessPrivateEndpointConnection{
33+
Comment: in.Name,
34+
CloudProviderEndpointID: in.CloudProviderEndpointID,
35+
ProviderName: string(providerName),
36+
}
37+
case provider.ProviderAzure:
38+
return &mongodbatlas.ServerlessPrivateEndpointConnection{
39+
Comment: in.Name,
40+
CloudProviderEndpointID: in.CloudProviderEndpointID,
41+
PrivateEndpointIPAddress: in.PrivateEndpointIPAddress,
42+
ProviderName: string(providerName),
43+
}
44+
default:
45+
return nil
46+
}
47+
}

pkg/api/v1/status/atlasdeployment.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ type AtlasDeploymentStatus struct {
2020
// ConnectionStrings is a set of connection strings that your applications use to connect to this cluster.
2121
ConnectionStrings *ConnectionStrings `json:"connectionStrings,omitempty"`
2222

23+
ServerlessPrivateEndpoints []ServerlessPrivateEndpoint `json:"serverlessPrivateEndpoints,omitempty"`
24+
2325
// MongoURIUpdated is a timestamp in ISO 8601 date and time format in UTC when the connection string was last updated.
2426
// The connection string changes if you update any of the other values.
2527
MongoURIUpdated string `json:"mongoURIUpdated,omitempty"`
@@ -108,6 +110,12 @@ func AtlasDeploymentStateNameOption(stateName string) AtlasDeploymentStatusOptio
108110
}
109111
}
110112

113+
func AtlasDeploymentSPEOption(pe []ServerlessPrivateEndpoint) AtlasDeploymentStatusOption {
114+
return func(s *AtlasDeploymentStatus) {
115+
s.ServerlessPrivateEndpoints = pe
116+
}
117+
}
118+
111119
func AtlasDeploymentMongoDBVersionOption(mongoDBVersion string) AtlasDeploymentStatusOption {
112120
return func(s *AtlasDeploymentStatus) {
113121
s.MongoDBVersion = mongoDBVersion

pkg/api/v1/status/condition.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ const (
5151

5252
// AtlasDeployment condition types
5353
const (
54-
DeploymentReadyType ConditionType = "DeploymentReady"
54+
DeploymentReadyType ConditionType = "DeploymentReady"
55+
ServerlessPrivateEndpointReadyType ConditionType = "ServerlessPrivateEndpointReady"
5556
)
5657

5758
// AtlasDatabaseUser condition types
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package status
2+
3+
import (
4+
"fmt"
5+
6+
"go.mongodb.org/atlas/mongodbatlas"
7+
)
8+
9+
type ServerlessPrivateEndpoint struct {
10+
// ID is the identifier of the Serverless PrivateLink Service.
11+
ID string `json:"_id,omitempty"`
12+
// CloudProviderEndpointID is the identifier of the cloud provider endpoint.
13+
CloudProviderEndpointID string `json:"cloudProviderEndpointId,omitempty"`
14+
// Name is the name of the Serverless PrivateLink Service. Should be unique.
15+
Name string `json:"name,omitempty"`
16+
// EndpointServiceName is the name of the PrivateLink endpoint service in AWS. Returns null while the endpoint service is being created.
17+
EndpointServiceName string `json:"endpointServiceName,omitempty"`
18+
// ErrorMessage is the error message if the Serverless PrivateLink Service failed to create or connect.
19+
ErrorMessage string `json:"errorMessage,omitempty"`
20+
// Status of the AWS Serverless PrivateLink connection.
21+
Status string `json:"status,omitempty"`
22+
// ProviderName is human-readable label that identifies the cloud provider. Values include AWS or AZURE.
23+
ProviderName string `json:"providerName,omitempty"`
24+
// PrivateEndpointIPAddress is the IPv4 address of the private endpoint in your Azure VNet that someone added to this private endpoint service.
25+
PrivateEndpointIPAddress string `json:"privateEndpointIpAddress,omitempty"`
26+
// PrivateLinkServiceResourceID is the root-relative path that identifies the Azure Private Link Service that MongoDB Cloud manages. MongoDB Cloud returns null while it creates the endpoint service.
27+
PrivateLinkServiceResourceID string `json:"privateLinkServiceResourceId,omitempty"`
28+
}
29+
30+
func SPEFromAtlas(in mongodbatlas.ServerlessPrivateEndpointConnection) ServerlessPrivateEndpoint {
31+
return ServerlessPrivateEndpoint{
32+
ID: in.ID,
33+
CloudProviderEndpointID: in.CloudProviderEndpointID,
34+
Name: in.Comment,
35+
EndpointServiceName: in.EndpointServiceName,
36+
ErrorMessage: in.ErrorMessage,
37+
Status: in.Status,
38+
ProviderName: in.ProviderName,
39+
PrivateEndpointIPAddress: in.PrivateEndpointIPAddress,
40+
PrivateLinkServiceResourceID: in.PrivateLinkServiceResourceID,
41+
}
42+
}
43+
44+
func FailedToCreateSPE(comment, message string) ServerlessPrivateEndpoint {
45+
return ServerlessPrivateEndpoint{
46+
ErrorMessage: message,
47+
Name: comment,
48+
Status: StatusFailed,
49+
}
50+
}
51+
52+
func FailedDuplicationSPE(name, cloudProviderEndpointID, privateEndpointIPAddress string) ServerlessPrivateEndpoint {
53+
return ServerlessPrivateEndpoint{
54+
CloudProviderEndpointID: cloudProviderEndpointID,
55+
PrivateEndpointIPAddress: privateEndpointIPAddress,
56+
ErrorMessage: fmt.Sprintf("The SPE with same name exists: %s. Please use unique names", name),
57+
Name: name,
58+
Status: StatusFailed,
59+
}
60+
}
61+
62+
func FailedToConnectSPE(pe mongodbatlas.ServerlessPrivateEndpointConnection, message string) ServerlessPrivateEndpoint {
63+
return ServerlessPrivateEndpoint{
64+
ID: pe.ID,
65+
CloudProviderEndpointID: pe.CloudProviderEndpointID,
66+
Name: pe.Comment,
67+
EndpointServiceName: pe.EndpointServiceName,
68+
ErrorMessage: message,
69+
Status: StatusFailed,
70+
ProviderName: pe.ProviderName,
71+
PrivateEndpointIPAddress: pe.PrivateEndpointIPAddress,
72+
PrivateLinkServiceResourceID: pe.PrivateLinkServiceResourceID,
73+
}
74+
}

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/api/v1/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/atlasdeployment/deployment.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,12 @@ func (r *AtlasDeploymentReconciler) ensureConnectionSecrets(ctx *workflow.Contex
240240
}
241241

242242
data := connectionsecret.ConnectionData{
243-
DBUserName: dbUser.Spec.Username,
244-
ConnURL: connectionStrings.Standard,
245-
SrvConnURL: connectionStrings.StandardSrv,
246-
Password: password,
243+
DBUserName: dbUser.Spec.Username,
244+
ConnURL: connectionStrings.Standard,
245+
SrvConnURL: connectionStrings.StandardSrv,
246+
Password: password,
247+
PvtConnURL: connectionStrings.Private,
248+
PvtSrvConnURL: connectionStrings.PrivateSrv,
247249
}
248250
connectionsecret.FillPrivateConnStrings(connectionStrings, &data)
249251

0 commit comments

Comments
 (0)