Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: search node management with mongodbatlas_search_deployment resource and data source #1633

Merged
merged 16 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/acceptance-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
cluster_outage_simulation: ${{ steps.filter.outputs.cluster_outage_simulation }}
advanced_cluster: ${{ steps.filter.outputs.advanced_cluster }}
cluster: ${{ steps.filter.outputs.cluster }}
search_deployment: ${{ steps.filter.outputs.search_deployment }}
generic: ${{ steps.filter.outputs.generic }}
backup_online_archive: ${{ steps.filter.outputs.backup_online_archive }}
backup_snapshots: ${{ steps.filter.outputs.backup_snapshots }}
Expand Down Expand Up @@ -49,6 +50,8 @@ jobs:
- 'mongodbatlas/**advanced_cluster**.go'
cluster:
- 'mongodbatlas/**mongodbatlas_cluster**.go'
search_deployment:
- 'mongodbatlas/**search_deployment**.go'
generic:
- 'mongodbatlas/data_source_mongodbatlas_backup_compliance_policy*.go'
- 'mongodbatlas/resource_mongodbatlas_backup_compliance_policy*.go'
Expand Down Expand Up @@ -185,6 +188,30 @@ jobs:
TEST_REGEX: "^TestAccClusterRSCluster"
run: make testacc

search_deployment:
needs: [ change-detection ]
if: ${{ needs.change-detection.outputs.search_deployment == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' || github.event.label.name == 'run-testacc' || github.event.label.name == 'run-testacc-search-deployment' || inputs.parent-event-name == 'release' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: 'go.mod'
- name: Acceptance Tests
env:
MONGODB_ATLAS_PUBLIC_KEY: ${{ secrets.MONGODB_ATLAS_PUBLIC_KEY_CLOUD_DEV }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI: true is missing ;-). cc @marcosuma

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true, however that env variable is not used in this job as no tests need to be skipped (several jobs dont define it). Can add just for consistency.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, i know it's only used when calling SkipTestForCI , it was more to advocate for a common env zone :-)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will try to answer to your PR :) but I think the global env variables would make the opposite effect here when you create a new job and you don't immediately expect there are global variables that might affect this job's behaviour

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or it could be the opposite, that you try to use SkipTestForCI and don't know why it's not skipping it.

I think it depends on the expectations set on the tests run from that GH action. for me it's clear in this case that all tests "want" to have CI:true even if they don't use/need it right now.

MONGODB_ATLAS_PRIVATE_KEY: ${{ secrets.MONGODB_ATLAS_PRIVATE_KEY_CLOUD_DEV }}
MONGODB_ATLAS_ORG_ID: ${{ vars.MONGODB_ATLAS_ORG_ID_CLOUD_DEV }}
MONGODB_ATLAS_BASE_URL: ${{ vars.MONGODB_ATLAS_BASE_URL }}
ACCTEST_TIMEOUT: ${{ vars.ACCTEST_TIMEOUT }}
TF_LOG: ${{ vars.LOG_LEVEL }}
TF_ACC: 1
PARALLEL_GO_TEST: 20
TEST_REGEX: "^TestAccSearchDeployment"
run: make testacc

generic: # Acceptance tests that do not use any time-consuming resource (example: cluster)
needs: [ change-detection ]
if: ${{ needs.change-detection.outputs.generic == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' || github.event.label.name == 'run-testacc' || github.event.label.name == 'run-testacc-generic' || inputs.parent-event-name == 'release' }}
Expand Down
11 changes: 11 additions & 0 deletions examples/atlas-search-deployment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# MongoDB Atlas Provider - Atlas Cluster with dedicated Search Nodes Deployment

This example shows how you can use Atlas Dedicated Search Nodes in Terraform. As a prerequisite, you need to create a project and cluster resource.
AgustinBettati marked this conversation as resolved.
Show resolved Hide resolved

Variables Required to be set:

- `public_key`: Atlas public key
- `private_key`: Atlas private key
- `org_id`: Organization ID where the project and cluster will be created.

For additional information you can visit the [Search Node Documentation](https://www.mongodb.com/docs/atlas/cluster-config/multi-cloud-distribution/#search-nodes-for-workload-isolation).
33 changes: 33 additions & 0 deletions examples/atlas-search-deployment/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
resource "mongodbatlas_project" "example" {
name = "project-name"
org_id = var.org_id
}

resource "mongodbatlas_advanced_cluster" "example" {
project_id = mongodbatlas_project.example.id
name = "ClusterExample"
cluster_type = "REPLICASET"

replication_specs {
region_configs {
electable_specs {
instance_size = "M10"
node_count = 3
}
provider_name = "AWS"
priority = 7
region_name = "US_EAST_1"
}
}
}

resource "mongodbatlas_search_deployment" "example" {
project_id = mongodbatlas_project.example.id
cluster_name = mongodbatlas_advanced_cluster.example.name
specs = [
{
instance_size = "S20_HIGHCPU_NVME"
node_count = 2
}
]
}
4 changes: 4 additions & 0 deletions examples/atlas-search-deployment/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
provider "mongodbatlas" {
public_key = var.public_key
private_key = var.private_key
}
12 changes: 12 additions & 0 deletions examples/atlas-search-deployment/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
variable "public_key" {
description = "Public API key to authenticate to Atlas"
type = string
}
variable "private_key" {
description = "Private API key to authenticate to Atlas"
type = string
}
variable "org_id" {
description = "Atlas Organization ID"
type = string
}
9 changes: 9 additions & 0 deletions examples/atlas-search-deployment/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_providers {
mongodbatlas = {
source = "mongodb/mongodbatlas"
version = "~> 1.13"
}
}
required_version = ">= 1.0"
}
4 changes: 4 additions & 0 deletions mongodbatlas/framework/retry/retry_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ const (
RetryStrategyPendingState = "PENDING"
RetryStrategyCompletedState = "COMPLETED"
RetryStrategyErrorState = "ERROR"
RetryStrategyPausedState = "PAUSED"
RetryStrategyUpdatingState = "UPDATING"
RetryStrategyIdleState = "IDLE"
RetryStrategyDeletedState = "DELETED"
)
99 changes: 99 additions & 0 deletions mongodbatlas/fw_data_source_mongodbatlas_search_deployment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package mongodbatlas

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)

var _ datasource.DataSource = &SearchDeploymentDS{}
var _ datasource.DataSourceWithConfigure = &SearchDeploymentDS{}

func NewSearchDeploymentDS() datasource.DataSource {
return &SearchDeploymentDS{
DSCommon: DSCommon{
dataSourceName: searchDeploymentName,
},
}
}

type tfSearchDeploymentDSModel struct {
ID types.String `tfsdk:"id"`
ClusterName types.String `tfsdk:"cluster_name"`
ProjectID types.String `tfsdk:"project_id"`
Specs types.List `tfsdk:"specs"`
StateName types.String `tfsdk:"state_name"`
}

type SearchDeploymentDS struct {
DSCommon
}

func (d *SearchDeploymentDS) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
},
"cluster_name": schema.StringAttribute{
Required: true,
},
"project_id": schema.StringAttribute{
Required: true,
},
"specs": schema.ListNestedAttribute{
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"instance_size": schema.StringAttribute{
Computed: true,
},
"node_count": schema.Int64Attribute{
Computed: true,
},
},
},
Computed: true,
},
"state_name": schema.StringAttribute{
Computed: true,
},
},
}
}

func (d *SearchDeploymentDS) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var searchDeploymentConfig tfSearchDeploymentDSModel
resp.Diagnostics.Append(req.Config.Get(ctx, &searchDeploymentConfig)...)
if resp.Diagnostics.HasError() {
return
}

connV2 := d.client.AtlasV2
projectID := searchDeploymentConfig.ProjectID.ValueString()
clusterName := searchDeploymentConfig.ClusterName.ValueString()
deploymentResp, _, err := connV2.AtlasSearchApi.GetAtlasSearchDeployment(ctx, projectID, clusterName).Execute()
if err != nil {
resp.Diagnostics.AddError("error getting search node information", err.Error())
return
}

newSearchDeploymentModel, diagnostics := newTFSearchDeployment(ctx, clusterName, deploymentResp, nil)
resp.Diagnostics.Append(diagnostics...)
if resp.Diagnostics.HasError() {
return
}
dsModel := convertToDSModel(newSearchDeploymentModel)
resp.Diagnostics.Append(resp.State.Set(ctx, dsModel)...)
}

func convertToDSModel(inputModel *tfSearchDeploymentRSModel) tfSearchDeploymentDSModel {
return tfSearchDeploymentDSModel{
ID: inputModel.ID,
ClusterName: inputModel.ClusterName,
ProjectID: inputModel.ProjectID,
Specs: inputModel.Specs,
StateName: inputModel.StateName,
}
}
2 changes: 2 additions & 0 deletions mongodbatlas/fw_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ func (p *MongodbtlasProvider) DataSources(context.Context) []func() datasource.D
NewProjectIPAccessListDS,
NewAtlasUserDS,
NewAtlasUsersDS,
NewSearchDeploymentDS,
}
}

Expand All @@ -423,6 +424,7 @@ func (p *MongodbtlasProvider) Resources(context.Context) []func() resource.Resou
NewDatabaseUserRS,
NewAlertConfigurationRS,
NewProjectIPAccessListRS,
NewSearchDeploymentRS,
}
}

Expand Down
Loading