Skip to content

Commit c18c7fa

Browse files
sivaram-mongodbsivaram-mongodbParthasarathyV
authored
feat: CLOUDP-372605 Update encryption-at-rest resource (#1558)
Co-authored-by: sivaram-mongodb <sivaram@mongodb.com> Co-authored-by: ParthasarathyV <114770988+ParthasarathyV@users.noreply.github.com> Co-authored-by: ParthasarathyV <parthasarathy.varadhan@mongodb.com>
1 parent 8543dfa commit c18c7fa

14 files changed

Lines changed: 297 additions & 79 deletions

File tree

.github/workflows/contract-testing.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ jobs:
1919
cloud-backup-restore-jobs: ${{ steps.filter.outputs.cloud-backup-restore-jobs }}
2020
cluster-outage-simulation: ${{ steps.filter.outputs.cluster-outage-simulation }}
2121
database-user: ${{ steps.filter.outputs.database-user }}
22+
encryption-at-rest: ${{ steps.filter.outputs.encryption-at-rest }}
2223
federated-database-instance: ${{ steps.filter.outputs.federated-database-instance }}
2324
federated-query-limit: ${{ steps.filter.outputs.federated-query-limit }}
2425
federated-settings-identity-provider: ${{ steps.filter.outputs.federated-settings-identity-provider }}
@@ -65,6 +66,8 @@ jobs:
6566
- 'cfn-resources/cluster-outage-simulation/**'
6667
database-user:
6768
- 'cfn-resources/database-user/**'
69+
encryption-at-rest:
70+
- 'cfn-resources/encryption-at-rest/**'
6871
federated-database-instance:
6972
- 'cfn-resources/federated-database-instance/**'
7073
federated-query-limit:
@@ -434,6 +437,47 @@ jobs:
434437
435438
cat inputs/*
436439
440+
make run-contract-testing
441+
make delete-test-resources
442+
encryption-at-rest:
443+
needs: change-detection
444+
if: ${{ needs.change-detection.outputs.encryption-at-rest == 'true' }}
445+
runs-on: ubuntu-latest
446+
steps:
447+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
448+
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5
449+
with:
450+
go-version-file: 'cfn-resources/go.mod'
451+
- name: setup Atlas CLI
452+
uses: mongodb/atlas-github-action@e3c9e0204659bafbb3b65e1eb1ee745cca0e9f3b
453+
- uses: aws-actions/setup-sam@d78e1a4a9656d3b223e59b80676a797f20093133
454+
with:
455+
use-installer: true
456+
- uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7
457+
with:
458+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_TEST_ENV }}
459+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_TEST_ENV }}
460+
aws-region: eu-west-1
461+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
462+
with:
463+
python-version: '3.9'
464+
cache: 'pip' # caching pip dependencies
465+
- run: pip install cloudformation-cli cloudformation-cli-go-plugin
466+
- name: Run the Contract test
467+
shell: bash
468+
env:
469+
MONGODB_ATLAS_PUBLIC_API_KEY: ${{ secrets.CLOUD_DEV_PUBLIC_KEY }}
470+
MONGODB_ATLAS_PRIVATE_API_KEY: ${{ secrets.CLOUD_DEV_PRIVATE_KEY }}
471+
MONGODB_ATLAS_ORG_ID: ${{ secrets.CLOUD_DEV_ORG_ID }}
472+
MONGODB_ATLAS_OPS_MANAGER_URL: ${{ vars.MONGODB_ATLAS_BASE_URL }}
473+
MONGODB_ATLAS_PROFILE: cfn-cloud-dev-github-action
474+
run: |
475+
pushd cfn-resources/encryption-at-rest
476+
make create-test-resources
477+
478+
cat inputs/inputs_1_create.json
479+
cat inputs/inputs_1_update.json
480+
437481
make run-contract-testing
438482
make delete-test-resources
439483
federated-database-instance:

cfn-resources/encryption-at-rest/Makefile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,21 @@ debug:
1717

1818
clean:
1919
rm -rf bin
20+
21+
submit: clean build
22+
@echo "==> Submitting to private registry for testing"
23+
cfn submit --set-default --region us-east-1
24+
25+
create-test-resources:
26+
@echo "==> Creating test files and resources for contract testing"
27+
./test/contract-testing/cfn-test-create.sh
28+
29+
delete-test-resources:
30+
@echo "==> Delete test resources used for contract testing"
31+
./test/contract-testing/cfn-test-delete.sh
32+
33+
run-contract-testing:
34+
@echo "==> Run contract testing"
35+
make build
36+
sam local start-lambda &
37+
cfn test --function-name TestEntrypoint --verbose

cfn-resources/encryption-at-rest/cmd/resource/model.go

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

cfn-resources/encryption-at-rest/cmd/resource/resource.go

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222
"math/big"
2323
"strconv"
2424

25-
admin20231115002 "go.mongodb.org/atlas-sdk/v20231115002/admin"
25+
"go.mongodb.org/atlas-sdk/v20250312013/admin"
2626

2727
"github.com/aws-cloudformation/cloudformation-cli-go-plugin/cfn/handler"
2828
"github.com/aws/aws-sdk-go-v2/aws"
@@ -57,7 +57,7 @@ func Create(req handler.Request, prevModel *Model, currentModel *Model) (handler
5757
return *pe, nil
5858
}
5959

60-
_, resp, err := client.Atlas20231115002.EncryptionAtRestUsingCustomerKeyManagementApi.UpdateEncryptionAtRest(context.Background(), *currentModel.ProjectId, currentModel.getParams()).Execute()
60+
_, resp, err := client.AtlasSDK.EncryptionAtRestUsingCustomerKeyManagementApi.UpdateEncryptionAtRest(context.Background(), *currentModel.ProjectId, currentModel.getParams()).Execute()
6161
if err != nil {
6262
return progressevent.GetFailedEventByResponse(err.Error(), resp), nil
6363
}
@@ -82,7 +82,7 @@ func Read(req handler.Request, prevModel *Model, currentModel *Model) (handler.P
8282
return *pe, nil
8383
}
8484

85-
info, resp, err := client.Atlas20231115002.EncryptionAtRestUsingCustomerKeyManagementApi.GetEncryptionAtRest(context.Background(), *currentModel.ProjectId).Execute()
85+
info, resp, err := client.AtlasSDK.EncryptionAtRestUsingCustomerKeyManagementApi.GetEncryptionAtRest(context.Background(), *currentModel.ProjectId).Execute()
8686
if err != nil {
8787
return progressevent.GetFailedEventByResponse(err.Error(), resp), nil
8888
}
@@ -91,10 +91,17 @@ func Read(req handler.Request, prevModel *Model, currentModel *Model) (handler.P
9191
return *pe, nil
9292
}
9393

94+
if currentModel.AwsKmsConfig == nil {
95+
currentModel.AwsKmsConfig = &AwsKmsConfig{}
96+
}
9497
currentModel.AwsKmsConfig.CustomerMasterKeyID = info.AwsKms.CustomerMasterKeyID
9598
currentModel.AwsKmsConfig.Enabled = info.AwsKms.Enabled
9699
currentModel.AwsKmsConfig.RoleID = info.AwsKms.RoleId
97100
currentModel.AwsKmsConfig.Region = info.AwsKms.Region
101+
currentModel.AwsKmsConfig.Valid = info.AwsKms.Valid
102+
currentModel.AwsKmsConfig.RequirePrivateNetworking = info.AwsKms.RequirePrivateNetworking
103+
104+
currentModel.EnabledForSearchNodes = info.EnabledForSearchNodes
98105

99106
return handler.ProgressEvent{
100107
OperationStatus: handler.Success,
@@ -115,7 +122,7 @@ func Update(req handler.Request, prevModel *Model, currentModel *Model) (handler
115122
return *pe, nil
116123
}
117124

118-
info, resp, err := client.Atlas20231115002.EncryptionAtRestUsingCustomerKeyManagementApi.GetEncryptionAtRest(context.Background(), *currentModel.ProjectId).Execute()
125+
info, resp, err := client.AtlasSDK.EncryptionAtRestUsingCustomerKeyManagementApi.GetEncryptionAtRest(context.Background(), *currentModel.ProjectId).Execute()
119126
if err != nil {
120127
return progressevent.GetFailedEventByResponse(err.Error(), resp), nil
121128
}
@@ -124,7 +131,7 @@ func Update(req handler.Request, prevModel *Model, currentModel *Model) (handler
124131
return *pe, nil
125132
}
126133

127-
_, resp, err = client.Atlas20231115002.EncryptionAtRestUsingCustomerKeyManagementApi.UpdateEncryptionAtRest(context.Background(), *currentModel.ProjectId, currentModel.getParams()).Execute()
134+
_, resp, err = client.AtlasSDK.EncryptionAtRestUsingCustomerKeyManagementApi.UpdateEncryptionAtRest(context.Background(), *currentModel.ProjectId, currentModel.getParams()).Execute()
128135
if err != nil {
129136
return progressevent.GetFailedEventByResponse(err.Error(), resp), nil
130137
}
@@ -148,7 +155,7 @@ func Delete(req handler.Request, prevModel *Model, currentModel *Model) (handler
148155
return *pe, nil
149156
}
150157

151-
info, resp, err := client.Atlas20231115002.EncryptionAtRestUsingCustomerKeyManagementApi.GetEncryptionAtRest(context.Background(), *currentModel.ProjectId).Execute()
158+
info, resp, err := client.AtlasSDK.EncryptionAtRestUsingCustomerKeyManagementApi.GetEncryptionAtRest(context.Background(), *currentModel.ProjectId).Execute()
152159
if err != nil {
153160
return progressevent.GetFailedEventByResponse(err.Error(), resp), nil
154161
}
@@ -157,10 +164,10 @@ func Delete(req handler.Request, prevModel *Model, currentModel *Model) (handler
157164
return *pe, nil
158165
}
159166

160-
params := &admin20231115002.EncryptionAtRest{
161-
AwsKms: &admin20231115002.AWSKMSConfiguration{Enabled: aws.Bool(false)},
167+
params := &admin.EncryptionAtRest{
168+
AwsKms: &admin.AWSKMSConfiguration{Enabled: aws.Bool(false)},
162169
}
163-
_, resp, err = client.Atlas20231115002.EncryptionAtRestUsingCustomerKeyManagementApi.UpdateEncryptionAtRest(context.Background(), *currentModel.ProjectId, params).Execute()
170+
_, resp, err = client.AtlasSDK.EncryptionAtRestUsingCustomerKeyManagementApi.UpdateEncryptionAtRest(context.Background(), *currentModel.ProjectId, params).Execute()
164171
if err != nil {
165172
return progressevent.GetFailedEventByResponse(err.Error(), resp), nil
166173
}
@@ -175,7 +182,7 @@ func List(req handler.Request, prevModel *Model, currentModel *Model) (handler.P
175182
return handler.ProgressEvent{}, errors.New("not implemented: List")
176183
}
177184

178-
func validateExist(info *admin20231115002.EncryptionAtRest) *handler.ProgressEvent {
185+
func validateExist(info *admin.EncryptionAtRest) *handler.ProgressEvent {
179186
if info != nil && info.AwsKms != nil && aws.ToBool(info.AwsKms.Enabled) {
180187
return nil
181188
}
@@ -193,13 +200,22 @@ func randInt64() int64 {
193200
return val.Int64()
194201
}
195202

196-
func (m *Model) getParams() *admin20231115002.EncryptionAtRest {
197-
return &admin20231115002.EncryptionAtRest{
198-
AwsKms: &admin20231115002.AWSKMSConfiguration{
199-
Enabled: m.AwsKmsConfig.Enabled,
200-
CustomerMasterKeyID: m.AwsKmsConfig.CustomerMasterKeyID,
201-
RoleId: m.AwsKmsConfig.RoleID,
202-
Region: m.AwsKmsConfig.Region,
203-
},
203+
func (m *Model) getParams() *admin.EncryptionAtRest {
204+
params := &admin.EncryptionAtRest{}
205+
206+
if m.EnabledForSearchNodes != nil {
207+
params.EnabledForSearchNodes = m.EnabledForSearchNodes
204208
}
209+
210+
if m.AwsKmsConfig != nil {
211+
params.AwsKms = &admin.AWSKMSConfiguration{
212+
Enabled: m.AwsKmsConfig.Enabled,
213+
CustomerMasterKeyID: m.AwsKmsConfig.CustomerMasterKeyID,
214+
Region: m.AwsKmsConfig.Region,
215+
RoleId: m.AwsKmsConfig.RoleID,
216+
RequirePrivateNetworking: m.AwsKmsConfig.RequirePrivateNetworking,
217+
}
218+
}
219+
220+
return params
205221
}

cfn-resources/encryption-at-rest/docs/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ To declare this entity in your AWS CloudFormation template, use the following sy
1313
"Type" : "MongoDB::Atlas::EncryptionAtRest",
1414
"Properties" : {
1515
"<a href="#awskmsconfig" title="AwsKmsConfig">AwsKmsConfig</a>" : <i><a href="awskmsconfig.md">AwsKmsConfig</a></i>,
16+
"<a href="#enabledforsearchnodes" title="EnabledForSearchNodes">EnabledForSearchNodes</a>" : <i>Boolean</i>,
1617
"<a href="#profile" title="Profile">Profile</a>" : <i>String</i>,
1718
"<a href="#projectid" title="ProjectId">ProjectId</a>" : <i>String</i>,
1819
}
@@ -25,6 +26,7 @@ To declare this entity in your AWS CloudFormation template, use the following sy
2526
Type: MongoDB::Atlas::EncryptionAtRest
2627
Properties:
2728
<a href="#awskmsconfig" title="AwsKmsConfig">AwsKmsConfig</a>: <i><a href="awskmsconfig.md">AwsKmsConfig</a></i>
29+
<a href="#enabledforsearchnodes" title="EnabledForSearchNodes">EnabledForSearchNodes</a>: <i>Boolean</i>
2830
<a href="#profile" title="Profile">Profile</a>: <i>String</i>
2931
<a href="#projectid" title="ProjectId">ProjectId</a>: <i>String</i>
3032
</pre>
@@ -41,6 +43,16 @@ _Type_: <a href="awskmsconfig.md">AwsKmsConfig</a>
4143

4244
_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
4345

46+
#### EnabledForSearchNodes
47+
48+
Flag that indicates whether Encryption at Rest for Dedicated Search Nodes is enabled in the specified project.
49+
50+
_Required_: No
51+
52+
_Type_: Boolean
53+
54+
_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
55+
4456
#### Profile
4557

4658
The profile is defined in AWS Secret manager. See [Secret Manager Profile setup](../../../examples/profile-secret.yaml).
@@ -73,3 +85,7 @@ For more information about using the `Fn::GetAtt` intrinsic function, see [Fn::G
7385

7486
Unique identifier.
7587

88+
#### Valid
89+
90+
Returns the <code>Valid</code> value.
91+

cfn-resources/encryption-at-rest/docs/awskmsconfig.md

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,61 +10,73 @@ To declare this entity in your AWS CloudFormation template, use the following sy
1010

1111
<pre>
1212
{
13-
"<a href="#roleid" title="RoleID">RoleID</a>" : <i>String</i>,
14-
"<a href="#customermasterkeyid" title="CustomerMasterKeyID">CustomerMasterKeyID</a>" : <i>String</i>,
1513
"<a href="#enabled" title="Enabled">Enabled</a>" : <i>Boolean</i>,
16-
"<a href="#region" title="Region">Region</a>" : <i>String</i>
14+
"<a href="#customermasterkeyid" title="CustomerMasterKeyID">CustomerMasterKeyID</a>" : <i>String</i>,
15+
"<a href="#region" title="Region">Region</a>" : <i>String</i>,
16+
"<a href="#roleid" title="RoleID">RoleID</a>" : <i>String</i>,
17+
"<a href="#requireprivatenetworking" title="RequirePrivateNetworking">RequirePrivateNetworking</a>" : <i>Boolean</i>
1718
}
1819
</pre>
1920

2021
### YAML
2122

2223
<pre>
23-
<a href="#roleid" title="RoleID">RoleID</a>: <i>String</i>
24-
<a href="#customermasterkeyid" title="CustomerMasterKeyID">CustomerMasterKeyID</a>: <i>String</i>
2524
<a href="#enabled" title="Enabled">Enabled</a>: <i>Boolean</i>
25+
<a href="#customermasterkeyid" title="CustomerMasterKeyID">CustomerMasterKeyID</a>: <i>String</i>
2626
<a href="#region" title="Region">Region</a>: <i>String</i>
27+
<a href="#roleid" title="RoleID">RoleID</a>: <i>String</i>
28+
<a href="#requireprivatenetworking" title="RequirePrivateNetworking">RequirePrivateNetworking</a>: <i>Boolean</i>
2729
</pre>
2830

2931
## Properties
3032

31-
#### RoleID
33+
#### Enabled
3234

33-
ID of an AWS IAM role authorized to manage an AWS customer master key.
35+
Specifies whether Encryption at Rest is enabled for an Atlas project. To disable Encryption at Rest, pass only this parameter with a value of false. When you disable Encryption at Rest, Atlas also removes the configuration details.
3436

3537
_Required_: No
3638

37-
_Type_: String
39+
_Type_: Boolean
3840

3941
_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
4042

4143
#### CustomerMasterKeyID
4244

43-
The AWS customer master key used to encrypt and decrypt the MongoDB master keys.
45+
Unique alphanumeric string that identifies the Amazon Web Services (AWS) Customer Master Key (CMK) you used to encrypt and decrypt the MongoDB master keys.
4446

4547
_Required_: No
4648

4749
_Type_: String
4850

4951
_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
5052

51-
#### Enabled
53+
#### Region
5254

53-
Specifies whether Encryption at Rest is enabled for an Atlas project. To disable Encryption at Rest, pass only this parameter with a value of false. When you disable Encryption at Rest, Atlas also removes the configuration details.
55+
Physical location where MongoDB Atlas deploys your AWS-hosted MongoDB cluster nodes. The region you choose can affect network latency for clients accessing your databases.
5456

5557
_Required_: No
5658

57-
_Type_: Boolean
59+
_Type_: String
5860

5961
_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
6062

61-
#### Region
63+
#### RoleID
6264

63-
The AWS region in which the AWS customer master key exists.
65+
Unique 24-hexadecimal digit string that identifies an Amazon Web Services (AWS) Identity and Access Management (IAM) role. This IAM role has the permissions required to manage your AWS customer master key.
6466

6567
_Required_: No
6668

6769
_Type_: String
6870

6971
_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
7072

73+
#### RequirePrivateNetworking
74+
75+
Enable connection to your Amazon Web Services (AWS) Key Management Service (KMS) over private networking.
76+
77+
_Required_: No
78+
79+
_Type_: Boolean
80+
81+
_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
82+

0 commit comments

Comments
 (0)