Skip to content

Commit 84cda07

Browse files
feat: CLOUDP-369811 - Federated SettingsOrgRoleMapping Enable contract_testing workflow (#1568)
Co-authored-by: Rakhul S Prakash <rakhul.s.prakash@peerislands.io>
1 parent 5cdcc11 commit 84cda07

11 files changed

Lines changed: 173 additions & 62 deletions

File tree

.github/workflows/contract-testing.yaml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ jobs:
2222
federated-database-instance: ${{ steps.filter.outputs.federated-database-instance }}
2323
federated-query-limit: ${{ steps.filter.outputs.federated-query-limit }}
2424
federated-settings-identity-provider: ${{ steps.filter.outputs.federated-settings-identity-provider }}
25+
federated-settings-org-role-mapping: ${{ steps.filter.outputs.federated-settings-org-role-mapping }}
2526
flex-cluster: ${{ steps.filter.outputs.flex-cluster }}
2627
online-archive: ${{ steps.filter.outputs.online-archive }}
2728
organization: ${{ steps.filter.outputs.organization }}
@@ -68,6 +69,8 @@ jobs:
6869
- 'cfn-resources/federated-query-limit/**'
6970
federated-settings-identity-provider:
7071
- 'cfn-resources/federated-settings-identity-provider/**'
72+
federated-settings-org-role-mapping:
73+
- 'cfn-resources/federated-settings-org-role-mapping/**'
7174
flex-cluster:
7275
- 'cfn-resources/flex-cluster/**'
7376
online-archive:
@@ -553,6 +556,48 @@ jobs:
553556
make run-contract-testing
554557
make delete-test-resources
555558
559+
federated-settings-org-role-mapping:
560+
needs: change-detection
561+
if: ${{ needs.change-detection.outputs.federated-settings-org-role-mapping == 'true' }}
562+
runs-on: ubuntu-latest
563+
steps:
564+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
565+
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5
566+
with:
567+
go-version-file: 'cfn-resources/go.mod'
568+
- name: setup Atlas CLI
569+
uses: mongodb/atlas-github-action@e3c9e0204659bafbb3b65e1eb1ee745cca0e9f3b
570+
- uses: aws-actions/setup-sam@d78e1a4a9656d3b223e59b80676a797f20093133
571+
with:
572+
use-installer: true
573+
- uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7
574+
with:
575+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_TEST_ENV }}
576+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_TEST_ENV }}
577+
aws-region: eu-west-1
578+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
579+
with:
580+
python-version: '3.9'
581+
cache: 'pip' # caching pip dependencies
582+
- run: pip install cloudformation-cli cloudformation-cli-go-plugin
583+
- name: Run the Contract test
584+
shell: bash
585+
env:
586+
MONGODB_ATLAS_PUBLIC_API_KEY: ${{ secrets.CLOUD_DEV_PUBLIC_KEY }}
587+
MONGODB_ATLAS_PRIVATE_API_KEY: ${{ secrets.CLOUD_DEV_PRIVATE_KEY }}
588+
MONGODB_ATLAS_ORG_ID: ${{ secrets.CLOUD_DEV_ORG_ID }}
589+
MONGODB_ATLAS_OPS_MANAGER_URL: ${{ vars.MONGODB_ATLAS_BASE_URL }}
590+
MONGODB_ATLAS_PROFILE: cfn-cloud-dev-github-action
591+
MONGODB_ATLAS_FEDERATION_SETTINGS_ID: ${{ vars.MONGODB_ATLAS_FEDERATION_SETTINGS_ID }}
592+
run: |
593+
cd cfn-resources/federated-settings-org-role-mapping
594+
make create-test-resources
595+
596+
cat inputs/*
597+
598+
make run-contract-testing
599+
make delete-test-resources
600+
556601
flex-cluster:
557602
needs: change-detection
558603
if: ${{ needs.change-detection.outputs.flex-cluster == 'true' }}

cfn-resources/federated-settings-org-role-mapping/Makefile

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,25 @@ build:
1313

1414
debug:
1515
cfn generate
16-
env GOOS=$(goos) CGO_ENABLED=$(cgo) GOARCH=$(goarch) go build -ldflags="$(ldXflagsD)" -tags="$(tags)" -o bin/bootstrap cmd/main.go
16+
env GOOS=$(goos) CGO_ENABLED=$(cgo) GOARCH=$(goarch) go build -ldflags="$(ldXflagsD)" -tags="$(tags)" -o bin/debug cmd/main.go
1717

1818
clean:
1919
rm -rf bin
20+
21+
submit: clean build # submit to private registry must use release build not debug 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/federated-settings-org-role-mapping/cmd/resource/config.go

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

cfn-resources/federated-settings-org-role-mapping/cmd/resource/resource.go

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,14 @@ import (
2121
"net/http"
2222
"strings"
2323

24-
admin20231115002 "go.mongodb.org/atlas-sdk/v20231115002/admin"
25-
2624
"github.com/aws-cloudformation/cloudformation-cli-go-plugin/cfn/handler"
2725
"github.com/aws/aws-sdk-go-v2/service/cloudformation/types"
2826

2927
"github.com/mongodb/mongodbatlas-cloudformation-resources/util"
3028
"github.com/mongodb/mongodbatlas-cloudformation-resources/util/constants"
3129
"github.com/mongodb/mongodbatlas-cloudformation-resources/util/progressevent"
3230
"github.com/mongodb/mongodbatlas-cloudformation-resources/util/validator"
31+
"go.mongodb.org/atlas-sdk/v20250312013/admin"
3332
)
3433

3534
var CreateRequiredFields = []string{constants.FederationSettingsID, constants.OrgID, constants.ExternalGroupName, constants.RoleAssignments}
@@ -68,9 +67,9 @@ func Create(req handler.Request, prevModel *Model, currentModel *Model) (handler
6867
orgID := currentModel.OrgId
6968

7069
requestBody, _, _ := modelToRoleMappingRequest(currentModel)
71-
federatedSettingsOrganizationRoleMapping, resp, err := client.Atlas20231115002.FederatedAuthenticationApi.CreateRoleMapping(context.Background(), *federationSettingsID, *orgID, requestBody).Execute()
70+
federatedSettingsOrganizationRoleMapping, resp, err := client.AtlasSDK.FederatedAuthenticationApi.CreateRoleMapping(context.Background(), *federationSettingsID, *orgID, requestBody).Execute()
7271
if err != nil {
73-
if resp.StatusCode == http.StatusBadRequest && strings.Contains(err.Error(), "DUPLICATE_ROLE_MAPPING") {
72+
if resp != nil && resp.StatusCode == http.StatusBadRequest && strings.Contains(err.Error(), "DUPLICATE_ROLE_MAPPING") {
7473
return progressevent.GetFailedEventByCode("Resource already exists",
7574
string(types.HandlerErrorCodeAlreadyExists)), nil
7675
}
@@ -101,7 +100,7 @@ func Read(req handler.Request, prevModel *Model, currentModel *Model) (handler.P
101100
orgID := currentModel.OrgId
102101
roleMappingID := currentModel.Id
103102

104-
federatedSettingsOrganizationRoleMapping, resp, err := client.Atlas20231115002.FederatedAuthenticationApi.
103+
federatedSettingsOrganizationRoleMapping, resp, err := client.AtlasSDK.FederatedAuthenticationApi.
105104
GetRoleMapping(context.Background(), *federationSettingsID, *roleMappingID, *orgID).
106105
Execute()
107106
if err != nil {
@@ -137,7 +136,7 @@ func Update(req handler.Request, prevModel *Model, currentModel *Model) (handler
137136
return progressevent.GetFailedEventByCode("Not Found", string(types.HandlerErrorCodeNotFound)), nil
138137
}
139138

140-
if (currentModel.RoleAssignments) == nil || len(currentModel.RoleAssignments) == 0 {
139+
if len(currentModel.RoleAssignments) == 0 {
141140
err := errors.New(RoleAssignementShouldBeSet)
142141
return handler.ProgressEvent{
143142
OperationStatus: handler.Failed,
@@ -146,7 +145,7 @@ func Update(req handler.Request, prevModel *Model, currentModel *Model) (handler
146145
}
147146
// preparing model request
148147
requestBody, _, _ := modelToRoleMappingRequest(currentModel)
149-
federatedSettingsOrganizationRoleMapping, resp, err := client.Atlas20231115002.FederatedAuthenticationApi.
148+
federatedSettingsOrganizationRoleMapping, resp, err := client.AtlasSDK.FederatedAuthenticationApi.
150149
UpdateRoleMapping(context.Background(), *federationSettingsID, *roleMappingID, *orgID, requestBody).
151150
Execute()
152151
if err != nil {
@@ -183,7 +182,7 @@ func Delete(req handler.Request, prevModel *Model, currentModel *Model) (handler
183182
federationSettingsID := currentModel.FederationSettingsId
184183
orgID := currentModel.OrgId
185184
roleMappingID := currentModel.Id
186-
resp, err := client.Atlas20231115002.FederatedAuthenticationApi.
185+
resp, err := client.AtlasSDK.FederatedAuthenticationApi.
187186
DeleteRoleMapping(context.Background(), *federationSettingsID, *roleMappingID, *orgID).
188187
Execute()
189188
if err != nil {
@@ -214,7 +213,7 @@ func List(req handler.Request, prevModel *Model, currentModel *Model) (handler.P
214213
federationSettingsID := currentModel.FederationSettingsId
215214
orgID := currentModel.OrgId
216215

217-
federatedSettingsOrganizationRoleMappings, resp, err := client.Atlas20231115002.
216+
federatedSettingsOrganizationRoleMappings, resp, err := client.AtlasSDK.
218217
FederatedAuthenticationApi.
219218
ListRoleMappings(context.Background(), *federationSettingsID, *orgID).
220219
Execute()
@@ -224,15 +223,18 @@ func List(req handler.Request, prevModel *Model, currentModel *Model) (handler.P
224223
}
225224

226225
models := make([]interface{}, 0)
227-
for i := range federatedSettingsOrganizationRoleMappings.Results {
228-
model := Model{}
229-
model.Profile = currentModel.Profile
230-
model.OrgId = currentModel.OrgId
231-
model.FederationSettingsId = currentModel.FederationSettingsId
232-
model.Id = federatedSettingsOrganizationRoleMappings.Results[i].Id
233-
model.ExternalGroupName = &federatedSettingsOrganizationRoleMappings.Results[i].ExternalGroupName
234-
model.RoleAssignments = flattenRoleAssignments(federatedSettingsOrganizationRoleMappings.Results[i].RoleAssignments)
235-
models = append(models, model)
226+
if federatedSettingsOrganizationRoleMappings.Results != nil {
227+
for i := range *federatedSettingsOrganizationRoleMappings.Results {
228+
roleMappings := *federatedSettingsOrganizationRoleMappings.Results
229+
model := Model{}
230+
model.Profile = currentModel.Profile
231+
model.OrgId = currentModel.OrgId
232+
model.FederationSettingsId = currentModel.FederationSettingsId
233+
model.Id = roleMappings[i].Id
234+
model.ExternalGroupName = &roleMappings[i].ExternalGroupName
235+
model.RoleAssignments = flattenRoleAssignments(roleMappings[i].RoleAssignments)
236+
models = append(models, model)
237+
}
236238
}
237239
return handler.ProgressEvent{
238240
OperationStatus: handler.Success,
@@ -241,8 +243,8 @@ func List(req handler.Request, prevModel *Model, currentModel *Model) (handler.P
241243
}, nil
242244
}
243245

244-
func modelToRoleMappingRequest(currentModel *Model) (*admin20231115002.AuthFederationRoleMapping, handler.ProgressEvent, error) {
245-
roleMappingRequest := &admin20231115002.AuthFederationRoleMapping{}
246+
func modelToRoleMappingRequest(currentModel *Model) (*admin.AuthFederationRoleMapping, handler.ProgressEvent, error) {
247+
roleMappingRequest := &admin.AuthFederationRoleMapping{}
246248
if currentModel.Id != nil {
247249
roleMappingRequest.Id = currentModel.Id
248250
}
@@ -255,10 +257,10 @@ func modelToRoleMappingRequest(currentModel *Model) (*admin20231115002.AuthFeder
255257
return roleMappingRequest, handler.ProgressEvent{}, nil
256258
}
257259

258-
func expandRoleAssignments(assignments []RoleAssignment) []admin20231115002.RoleAssignment {
259-
roles := make([]admin20231115002.RoleAssignment, len(assignments))
260+
func expandRoleAssignments(assignments []RoleAssignment) *[]admin.ConnectedOrgConfigRoleAssignment {
261+
roles := make([]admin.ConnectedOrgConfigRoleAssignment, len(assignments))
260262
for i := range assignments {
261-
role := admin20231115002.RoleAssignment{}
263+
role := admin.ConnectedOrgConfigRoleAssignment{}
262264
if util.IsStringPresent(assignments[i].Role) {
263265
role.Role = assignments[i].Role
264266
}
@@ -273,10 +275,10 @@ func expandRoleAssignments(assignments []RoleAssignment) []admin20231115002.Role
273275
roles[i] = role
274276
}
275277

276-
return roles
278+
return &roles
277279
}
278280

279-
func roleMappingToModel(currentModel Model, roleMapping *admin20231115002.AuthFederationRoleMapping) *Model {
281+
func roleMappingToModel(currentModel Model, roleMapping *admin.AuthFederationRoleMapping) *Model {
280282
out := &Model{
281283
Profile: currentModel.Profile,
282284
FederationSettingsId: currentModel.FederationSettingsId,
@@ -288,9 +290,12 @@ func roleMappingToModel(currentModel Model, roleMapping *admin20231115002.AuthFe
288290
return out
289291
}
290292

291-
func flattenRoleAssignments(assignments []admin20231115002.RoleAssignment) []RoleAssignment {
293+
func flattenRoleAssignments(assignments *[]admin.ConnectedOrgConfigRoleAssignment) []RoleAssignment {
292294
roleAssignments := make([]RoleAssignment, 0)
293-
for _, role := range assignments {
295+
if assignments == nil {
296+
return roleAssignments
297+
}
298+
for _, role := range *assignments {
294299
roleAssignments = append(roleAssignments, RoleAssignment{
295300
Role: role.Role,
296301
OrgId: role.OrgId,
@@ -302,7 +307,7 @@ func flattenRoleAssignments(assignments []admin20231115002.RoleAssignment) []Rol
302307

303308
func isRoleMappingExists(currentModel *Model, client *util.MongoDBClient) bool {
304309
var isExists bool
305-
fedSettingsConnectedOrg, _, err := client.Atlas20231115002.FederatedAuthenticationApi.
310+
fedSettingsConnectedOrg, _, err := client.AtlasSDK.FederatedAuthenticationApi.
306311
GetRoleMapping(context.Background(), *currentModel.FederationSettingsId, *currentModel.Id, *currentModel.OrgId).
307312
Execute()
308313
if err != nil {

cfn-resources/federated-settings-org-role-mapping/docs/README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@ _Update requires_: [Replacement](https://docs.aws.amazon.com/AWSCloudFormation/l
5050

5151
Unique human-readable label that identifies the identity provider group to whichthis role mapping applies.
5252

53-
_Required_: No
53+
_Required_: Yes
5454

5555
_Type_: String
5656

57-
_Minimum_: <code>1</code>
57+
_Minimum Length_: <code>1</code>
5858

59-
_Maximum_: <code>200</code>
59+
_Maximum Length_: <code>200</code>
6060

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

@@ -68,9 +68,9 @@ _Required_: Yes
6868

6969
_Type_: String
7070

71-
_Minimum_: <code>24</code>
71+
_Minimum Length_: <code>24</code>
7272

73-
_Maximum_: <code>24</code>
73+
_Maximum Length_: <code>24</code>
7474

7575
_Pattern_: <code>^([a-f0-9]{24})$</code>
7676

@@ -84,9 +84,9 @@ _Required_: Yes
8484

8585
_Type_: String
8686

87-
_Minimum_: <code>24</code>
87+
_Minimum Length_: <code>24</code>
8888

89-
_Maximum_: <code>24</code>
89+
_Maximum Length_: <code>24</code>
9090

9191
_Pattern_: <code>^([a-f0-9]{24})$</code>
9292

cfn-resources/federated-settings-org-role-mapping/test/cfn-test-create-inputs.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function usage {
1515
}
1616

1717
#set profile
18-
profile="federation"
18+
profile="default"
1919
if [ ${MONGODB_ATLAS_PROFILE+x} ]; then
2020
echo "profile set to ${MONGODB_ATLAS_PROFILE}"
2121
profile=${MONGODB_ATLAS_PROFILE}
@@ -41,10 +41,10 @@ cd "$(dirname "$0")" || exit
4141
for inputFile in inputs_*; do
4242
outputFile=${inputFile//$WORDTOREMOVE/}
4343
jq --arg org "$MONGODB_ATLAS_ORG_ID" \
44-
--arg FederationSettingsId "$ATLAS_FEDERATED_SETTINGS_ID" \
44+
--arg FederationSettingsId "$MONGODB_ATLAS_FEDERATION_SETTINGS_ID" \
4545
--arg projectId "$projectId" \
4646
--arg profile "$profile" \
47-
'.Profile?|=$profile | .FederationSettingsId?|=$FederationSettingsId | .OrgId?|=$org | .RoleAssignments[0].ProjectId?|=$projectId' \
47+
'.Profile?|=$profile | .FederationSettingsId?|=$FederationSettingsId | .OrgId?|=$org | .RoleAssignments[0].OrgId?|=$org | .RoleAssignments[1].ProjectId?|=$projectId' \
4848
"$inputFile" >"../inputs/$outputFile"
4949
done
5050
cd ..
Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,4 @@
11
#!/usr/bin/env bash
22
# cfn-test-delete-inputs.sh
33
#
4-
# This tool deletes the mongodb resources used for `cfn test` as inputs.
5-
#
6-
7-
set -o errexit
8-
set -o nounset
9-
set -o pipefail
10-
11-
function usage {
12-
echo "usage:$0 "
13-
}
14-
15-
projectId=$(jq -r '.ProjectId' ./inputs/inputs_1_create.json)
16-
17-
#delete project
18-
if atlas projects delete "$projectId" --force; then
19-
echo "$projectId project deletion OK"
20-
else
21-
(echo "Failed cleaning project:$projectId" && exit 1)
22-
fi
4+
# Needs to exist to be called in Publish, but no cleanup is needed.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env bash
2+
3+
# This tool generates the resources and json files in the inputs/ for `cfn test`.
4+
set -o errexit
5+
set -o nounset
6+
set -o pipefail
7+
8+
projectName="cfn-test-bot-$(date +%s)-$RANDOM"
9+
10+
# create project
11+
projectId=$(atlas projects create "${projectName}" --output=json | jq -r '.id')
12+
13+
echo "projectId: $projectId"
14+
echo "projectName: $projectName"
15+
16+
./test/cfn-test-create-inputs.sh "$projectName"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env bash
2+
3+
# This tool deletes the mongodb resources used for `cfn test` as inputs.
4+
set -o errexit
5+
set -o nounset
6+
set -o pipefail
7+
8+
projectId=$(jq -r '.RoleAssignments[] | select(.ProjectId != null) | .ProjectId' ./inputs/inputs_1_create.json | head -n 1)
9+
10+
if [ -n "$projectId" ] && [ "$projectId" != "null" ]; then
11+
if atlas projects delete "$projectId" --force; then
12+
echo "$projectId project deletion OK"
13+
else
14+
(echo "Failed cleaning project: $projectId" && exit 1)
15+
fi
16+
else
17+
echo "No project to delete (no ProjectId found in test inputs)"
18+
fi

0 commit comments

Comments
 (0)