Skip to content

Commit 3dec6e1

Browse files
rakhul-mongooutcomes-winter-rakhulsprakashsivaram-mongodbParthasarathyV
authored
feat: CLOUDP-369802 Add log-integration resource (#1555)
Co-authored-by: Rakhul S Prakash <rakhul.s.prakash@peerislands.io> Co-authored-by: sivaram-mongodb <sivaram@mongodb.com> Co-authored-by: ParthasarathyV <114770988+ParthasarathyV@users.noreply.github.com>
1 parent be11fc6 commit 3dec6e1

28 files changed

Lines changed: 1389 additions & 0 deletions

.github/workflows/contract-testing.yaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ jobs:
2525
federated-settings-identity-provider: ${{ steps.filter.outputs.federated-settings-identity-provider }}
2626
federated-settings-org-role-mapping: ${{ steps.filter.outputs.federated-settings-org-role-mapping }}
2727
flex-cluster: ${{ steps.filter.outputs.flex-cluster }}
28+
log-integration: ${{ steps.filter.outputs.log-integration }}
2829
online-archive: ${{ steps.filter.outputs.online-archive }}
2930
organization: ${{ steps.filter.outputs.organization }}
3031
service-account: ${{ steps.filter.outputs.service-account }}
@@ -78,6 +79,8 @@ jobs:
7879
- 'cfn-resources/federated-settings-org-role-mapping/**'
7980
flex-cluster:
8081
- 'cfn-resources/flex-cluster/**'
82+
log-integration:
83+
- 'cfn-resources/log-integration/**'
8184
online-archive:
8285
- 'cfn-resources/online-archive/**'
8386
organization:
@@ -689,6 +692,46 @@ jobs:
689692
690693
make run-contract-testing
691694
make delete-test-resources
695+
log-integration:
696+
needs: change-detection
697+
if: ${{ needs.change-detection.outputs.log-integration == 'true' }}
698+
runs-on: ubuntu-latest
699+
steps:
700+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
701+
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5
702+
with:
703+
go-version-file: 'cfn-resources/go.mod'
704+
- name: setup Atlas CLI
705+
uses: mongodb/atlas-github-action@e3c9e0204659bafbb3b65e1eb1ee745cca0e9f3b
706+
- uses: aws-actions/setup-sam@c2a20b1822cc4a6bc594ff7f1dbb658758e383c3
707+
with:
708+
use-installer: true
709+
- uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708
710+
with:
711+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_TEST_ENV }}
712+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_TEST_ENV }}
713+
aws-region: eu-west-1
714+
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548
715+
with:
716+
python-version: '3.9'
717+
cache: 'pip' # caching pip dependencies
718+
- run: pip install cloudformation-cli cloudformation-cli-go-plugin
719+
- name: Run the Contract test
720+
shell: bash
721+
env:
722+
MONGODB_ATLAS_PUBLIC_API_KEY: ${{ secrets.CLOUD_DEV_PUBLIC_KEY }}
723+
MONGODB_ATLAS_PRIVATE_API_KEY: ${{ secrets.CLOUD_DEV_PRIVATE_KEY }}
724+
MONGODB_ATLAS_ORG_ID: ${{ secrets.CLOUD_DEV_ORG_ID }}
725+
MONGODB_ATLAS_OPS_MANAGER_URL: ${{ vars.MONGODB_ATLAS_BASE_URL }}
726+
MONGODB_ATLAS_PROFILE: cfn-cloud-dev-github-action
727+
run: |
728+
pushd cfn-resources/log-integration
729+
make create-test-resources
730+
731+
cat inputs/*
732+
733+
make run-contract-testing
734+
make delete-test-resources
692735
online-archive:
693736
needs: change-detection
694737
if: ${{ needs.change-detection.outputs.online-archive == 'true' }}

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,8 @@ CLAUDE.md
4848

4949
# generated markdown file with resource versions, will not be commited until we have mechanism to keep updated
5050
cfn-resources/resource-versions.md
51+
52+
# dynamically generated test policy files (not templates)
53+
**/test/trust-policy.json
54+
**/test/s3-policy.json
55+
**/test/add-policy.json
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"typeName": "MongoDB::Atlas::LogIntegration",
3+
"language": "go",
4+
"runtime": "provided.al2",
5+
"entrypoint": "bootstrap",
6+
"testEntrypoint": "bootstrap",
7+
"settings": {
8+
"import_path": "github.com/mongodb/mongodbatlas-cloudformation-resources/log-integration",
9+
"protocolVersion": "2.0.0",
10+
"pluginVersion": "2.0.4"
11+
}
12+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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/debug cmd/main.go
17+
18+
clean:
19+
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
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# MongoDB::Atlas::LogIntegration
2+
3+
## Description
4+
5+
The log integration resource provides access to push-based log export configurations for MongoDB Atlas. The resource allows you to create, edit and delete log export integrations to AWS S3 buckets. Push-based log export enables you to automatically export MongoDB Atlas logs to your AWS S3 bucket with 1-minute frequency.
6+
7+
For more information, see [Push Logs to AWS S3 bucket](https://www.mongodb.com/docs/atlas/push-logs/) and the [Push-Based Log Export API](https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2/group/endpoint-push-based-log-export).
8+
9+
## Requirements
10+
11+
To securely give CloudFormation access to your Atlas credentials, you must
12+
set up an [AWS Profile](/README.md#mongodb-atlas-api-keys-credential-management).
13+
14+
## Attributes and Parameters
15+
16+
See the [resource docs](docs/README.md).
17+
18+
## CloudFormation Examples
19+
20+
See the example [CFN Template](/examples/log-integration/README.md) for example resource.

cfn-resources/log-integration/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/log-integration/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: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
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 (
18+
"context"
19+
"fmt"
20+
"net/http"
21+
22+
"github.com/aws-cloudformation/cloudformation-cli-go-plugin/cfn/handler"
23+
"github.com/mongodb/mongodbatlas-cloudformation-resources/util"
24+
"github.com/mongodb/mongodbatlas-cloudformation-resources/util/constants"
25+
"github.com/mongodb/mongodbatlas-cloudformation-resources/util/progressevent"
26+
)
27+
28+
func HandleCreate(req *handler.Request, client *util.MongoDBClient, model *Model) handler.ProgressEvent {
29+
s3LogIntegrationReq := NewLogIntegrationCreateRequest(model)
30+
logIntegrationResp, resp, err := client.AtlasSDK.PushBasedLogExportApi.CreateGroupLogIntegration(context.Background(), *model.ProjectId, s3LogIntegrationReq).Execute()
31+
if err != nil {
32+
return handleError(resp, err, "Error creating log integration")
33+
}
34+
35+
UpdateLogIntegrationModel(model, logIntegrationResp)
36+
return handler.ProgressEvent{
37+
OperationStatus: handler.Success,
38+
Message: "Create complete",
39+
ResourceModel: model,
40+
}
41+
}
42+
43+
func HandleRead(req *handler.Request, client *util.MongoDBClient, model *Model) handler.ProgressEvent {
44+
logIntegrationResp, resp, err := client.AtlasSDK.PushBasedLogExportApi.GetGroupLogIntegration(context.Background(), *model.ProjectId, *model.IntegrationId).Execute()
45+
if err != nil {
46+
return handleError(resp, err, "Error reading log integration")
47+
}
48+
49+
UpdateLogIntegrationModel(model, logIntegrationResp)
50+
return handler.ProgressEvent{
51+
OperationStatus: handler.Success,
52+
Message: constants.ReadComplete,
53+
ResourceModel: model,
54+
}
55+
}
56+
57+
func HandleUpdate(req *handler.Request, client *util.MongoDBClient, model *Model) handler.ProgressEvent {
58+
logIntegrationReq := NewLogIntegrationUpdateRequest(model)
59+
logIntegrationResp, resp, err := client.AtlasSDK.PushBasedLogExportApi.UpdateGroupLogIntegration(context.Background(), *model.ProjectId, *model.IntegrationId, logIntegrationReq).Execute()
60+
if err != nil {
61+
return handleError(resp, err, "Error updating log integration")
62+
}
63+
64+
UpdateLogIntegrationModel(model, logIntegrationResp)
65+
return handler.ProgressEvent{
66+
OperationStatus: handler.Success,
67+
Message: "Update complete",
68+
ResourceModel: model,
69+
}
70+
}
71+
72+
func HandleDelete(req *handler.Request, client *util.MongoDBClient, model *Model) handler.ProgressEvent {
73+
resp, err := client.AtlasSDK.PushBasedLogExportApi.DeleteGroupLogIntegration(context.Background(), *model.ProjectId, *model.IntegrationId).Execute()
74+
if err != nil {
75+
return handleError(resp, err, "Error deleting log integration")
76+
}
77+
78+
return handler.ProgressEvent{
79+
OperationStatus: handler.Success,
80+
Message: "Delete complete",
81+
}
82+
}
83+
84+
func HandleList(req *handler.Request, client *util.MongoDBClient, model *Model) handler.ProgressEvent {
85+
paginatedResp, resp, err := client.AtlasSDK.PushBasedLogExportApi.ListGroupLogIntegrations(context.Background(), *model.ProjectId).Execute()
86+
if err != nil {
87+
return handleError(resp, err, "Error listing log integrations")
88+
}
89+
90+
var allModels []*Model
91+
results := paginatedResp.GetResults()
92+
for i := range results {
93+
modelItem := &Model{
94+
ProjectId: model.ProjectId,
95+
Profile: model.Profile,
96+
}
97+
UpdateLogIntegrationModel(modelItem, &results[i])
98+
allModels = append(allModels, modelItem)
99+
}
100+
101+
return handler.ProgressEvent{
102+
OperationStatus: handler.Success,
103+
Message: constants.Complete,
104+
ResourceModel: allModels,
105+
}
106+
}
107+
108+
func handleError(resp *http.Response, err error, message string) handler.ProgressEvent {
109+
errMsg := fmt.Sprintf("%s: %v", message, err)
110+
return progressevent.GetFailedEventByResponse(errMsg, resp)
111+
}

0 commit comments

Comments
 (0)