Skip to content

Commit 37d949a

Browse files
sivaram-mongodbsivaram-mongodbParthasarathyVoutcomes-winter-rakhulsprakash
authored
feat: Add StreamWorkspace CloudFormation resource (#1517)
Co-authored-by: sivaram-mongodb <sivaram@mongodb.com> Co-authored-by: ParthasarathyV <parthasarathy.varadhan@mongodb.com> Co-authored-by: Rakhul S Prakash <rakhul.s.prakash@peerislands.io> Co-authored-by: ParthasarathyV <114770988+ParthasarathyV@users.noreply.github.com>
1 parent 7213eb8 commit 37d949a

26 files changed

Lines changed: 1522 additions & 0 deletions

.github/workflows/contract-testing.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ jobs:
3030
search-deployment: ${{ steps.filter.outputs.search-deployment }}
3131
stream-connection: ${{ steps.filter.outputs.stream-connection }}
3232
stream-instance: ${{ steps.filter.outputs.stream-instance }}
33+
stream-workspace: ${{ steps.filter.outputs.stream-workspace }}
3334
steps:
3435
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
3536
if: ${{ github.event_name == 'push' }}
@@ -75,6 +76,8 @@ jobs:
7576
- 'cfn-resources/stream-connection/**'
7677
stream-instance:
7778
- 'cfn-resources/stream-instance/**'
79+
stream-workspace:
80+
- 'cfn-resources/stream-workspace/**'
7881
access-list-api-key:
7982
needs: change-detection
8083
if: ${{ needs.change-detection.outputs.access-list-api-key == 'true' }}
@@ -854,3 +857,44 @@ jobs:
854857
cat inputs/inputs_1_create.json
855858
make run-contract-testing
856859
make delete-test-resources
860+
stream-workspace:
861+
needs: change-detection
862+
if: ${{ needs.change-detection.outputs.stream-workspace == 'true' }}
863+
runs-on: ubuntu-latest
864+
steps:
865+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
866+
- uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c
867+
with:
868+
go-version-file: 'cfn-resources/go.mod'
869+
- name: setup Atlas CLI
870+
uses: mongodb/atlas-github-action@e3c9e0204659bafbb3b65e1eb1ee745cca0e9f3b
871+
- uses: aws-actions/setup-sam@c2a20b1822cc4a6bc594ff7f1dbb658758e383c3
872+
with:
873+
use-installer: true
874+
- uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708
875+
with:
876+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_TEST_ENV }}
877+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_TEST_ENV }}
878+
aws-region: eu-west-1
879+
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548
880+
with:
881+
python-version: '3.9'
882+
cache: 'pip' # caching pip dependencies
883+
- run: pip install cloudformation-cli cloudformation-cli-go-plugin
884+
- name: Run the Contract test
885+
shell: bash
886+
env:
887+
MONGODB_ATLAS_PUBLIC_API_KEY: ${{ secrets.CLOUD_DEV_PUBLIC_KEY }}
888+
MONGODB_ATLAS_PRIVATE_API_KEY: ${{ secrets.CLOUD_DEV_PRIVATE_KEY }}
889+
MONGODB_ATLAS_ORG_ID: ${{ secrets.CLOUD_DEV_ORG_ID }}
890+
MONGODB_ATLAS_OPS_MANAGER_URL: ${{ vars.MONGODB_ATLAS_BASE_URL }}
891+
MONGODB_ATLAS_PROFILE: cfn-cloud-dev-github-action
892+
run: |
893+
cd cfn-resources/stream-workspace
894+
make create-test-resources
895+
896+
cat inputs/inputs_1_create.json
897+
cat inputs/inputs_1_update.json
898+
899+
make run-contract-testing
900+
make delete-test-resources
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"artifact_type": "RESOURCE",
3+
"typeName": "MongoDB::Atlas::StreamWorkspace",
4+
"language": "go",
5+
"runtime": "provided.al2",
6+
"entrypoint": "bootstrap",
7+
"testEntrypoint": "bootstrap",
8+
"settings": {
9+
"version": false,
10+
"subparser_name": null,
11+
"verbose": 0,
12+
"force": false,
13+
"type_name": "MongoDB::Atlas::StreamWorkspace",
14+
"artifact_type": null,
15+
"endpoint_url": null,
16+
"region": null,
17+
"target_schemas": [],
18+
"profile": null,
19+
"import_path": "github.com/mongodb/mongodbatlas-cloudformation-resources/stream-workspace",
20+
"protocolVersion": "2.0.0"
21+
}
22+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
.PHONY: build test clean
2+
tags=logging callback metrics scheduler
3+
cgo=0
4+
goos=linux
5+
goarch=amd64
6+
CFNREP_GIT_SHA?=$(shell git rev-parse HEAD)
7+
ldXflags=-s -w -X github.com/mongodb/mongodbatlas-cloudformation-resources/util.defaultLogLevel=info -X github.com/mongodb/mongodbatlas-cloudformation-resources/version.Version=${CFNREP_GIT_SHA}
8+
ldXflagsD=-X github.com/mongodb/mongodbatlas-cloudformation-resources/util.defaultLogLevel=debug -X github.com/mongodb/mongodbatlas-cloudformation-resources/version.Version=${CFNREP_GIT_SHA}
9+
10+
build:
11+
cfn generate
12+
env GOOS=$(goos) CGO_ENABLED=$(cgo) GOARCH=$(goarch) go build -ldflags="$(ldXflags)" -tags="$(tags)" -o bin/bootstrap cmd/main.go
13+
14+
debug:
15+
cfn generate
16+
env GOOS=$(goos) CGO_ENABLED=$(cgo) GOARCH=$(goarch) go build -ldflags="$(ldXflagsD)" -tags="$(tags)" -o bin/bootstrap cmd/main.go
17+
18+
clean:
19+
rm -rf bin
20+
21+
create-test-resources:
22+
@echo "==> Creating test files for contract testing"
23+
./test/contract-testing/cfn-test-create-inputs.sh
24+
25+
delete-test-resources:
26+
@echo "==> Delete test resources used for contract testing"
27+
./test/cfn-test-delete-inputs.sh
28+
29+
run-contract-testing:
30+
@echo "==> Run contract testing"
31+
make build
32+
sam local start-lambda &
33+
cfn test --function-name TestEntrypoint --verbose
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# MongoDB::Atlas::StreamWorkspace
2+
3+
## Description
4+
5+
Resource for managing [Stream Workspaces](https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2/group/endpoint-streams).
6+
7+
## Requirements
8+
9+
Set up an AWS profile to securely give CloudFormation access to your Atlas credentials.
10+
For instructions on setting up a profile, [see here](/README.md#mongodb-atlas-api-keys-credential-management).
11+
12+
## Attributes and Parameters
13+
14+
See the [resource docs](docs/README.md). Also refer [AWS security best practices for CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/security-best-practices.html#creds) to manage credentials.
15+
16+
## CloudFormation Examples
17+
18+
See the examples [CFN Template](/examples/stream-workspace/stream-workspace.json) for example resource.

cfn-resources/stream-workspace/cmd/main.go

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

cfn-resources/stream-workspace/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.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright 2026 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 resource
16+
17+
import "go.mongodb.org/atlas-sdk/v20250312012/admin"
18+
19+
func NewStreamWorkspaceCreateReq(model *Model) *admin.StreamsTenant {
20+
if model == nil {
21+
return nil
22+
}
23+
dataProcessRegion := *model.DataProcessRegion
24+
streamTenant := &admin.StreamsTenant{
25+
Name: model.WorkspaceName,
26+
GroupId: model.ProjectId,
27+
DataProcessRegion: &admin.StreamsDataProcessRegion{
28+
CloudProvider: *dataProcessRegion.CloudProvider,
29+
Region: *dataProcessRegion.Region,
30+
},
31+
}
32+
if streamConfig := model.StreamConfig; streamConfig != nil {
33+
streamTenant.StreamConfig = &admin.StreamConfig{}
34+
if tier := streamConfig.Tier; tier != nil {
35+
streamTenant.StreamConfig.Tier = tier
36+
}
37+
if maxTierSize := streamConfig.MaxTierSize; maxTierSize != nil {
38+
streamTenant.StreamConfig.MaxTierSize = maxTierSize
39+
}
40+
}
41+
return streamTenant
42+
}
43+
44+
func NewStreamWorkspaceUpdateReq(model *Model) *admin.StreamsTenantUpdateRequest {
45+
if model == nil || model.DataProcessRegion == nil {
46+
return nil
47+
}
48+
dataProcessRegion := *model.DataProcessRegion
49+
if dataProcessRegion.Region == nil {
50+
return nil
51+
}
52+
// CloudFormation is AWS-only, so CloudProvider is always AWS
53+
cloudProvider := CloudProvider
54+
return &admin.StreamsTenantUpdateRequest{
55+
CloudProvider: &cloudProvider,
56+
Region: dataProcessRegion.Region,
57+
}
58+
}
59+
60+
func newModelDataRegion(dataProcessRegion *admin.StreamsDataProcessRegion) *StreamsDataProcessRegion {
61+
return &StreamsDataProcessRegion{
62+
CloudProvider: &dataProcessRegion.CloudProvider,
63+
Region: &dataProcessRegion.Region,
64+
}
65+
}
66+
67+
func newModelStreamConfig(streamConfig *admin.StreamConfig) *StreamConfig {
68+
if streamConfig == nil {
69+
return nil
70+
}
71+
modelConfig := &StreamConfig{}
72+
if streamConfig.Tier != nil {
73+
modelConfig.Tier = streamConfig.Tier
74+
}
75+
if streamConfig.MaxTierSize != nil {
76+
modelConfig.MaxTierSize = streamConfig.MaxTierSize
77+
}
78+
return modelConfig
79+
}
80+
81+
func GetStreamWorkspaceModel(streamTenant *admin.StreamsTenant, currentModel *Model) *Model {
82+
model := new(Model)
83+
84+
if currentModel != nil {
85+
model = currentModel
86+
}
87+
88+
if streamTenant != nil {
89+
model.WorkspaceName = streamTenant.Name
90+
model.DataProcessRegion = newModelDataRegion(streamTenant.DataProcessRegion)
91+
model.StreamConfig = newModelStreamConfig(streamTenant.StreamConfig)
92+
model.ProjectId = streamTenant.GroupId
93+
model.Id = streamTenant.Id
94+
model.Hostnames = streamTenant.GetHostnames()
95+
}
96+
97+
return model
98+
}

0 commit comments

Comments
 (0)