diff --git a/internal/provider/provider.go b/internal/provider/provider.go index dc16a595d5..73ed20a0c1 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -437,6 +437,7 @@ func (p *MongodbtlasProvider) DataSources(context.Context) []func() datasource.D } previewDataSources := []func() datasource.DataSource{ // Data sources not yet in GA encryptionatrestprivateendpoint.DataSource, + encryptionatrestprivateendpoint.PluralDataSource, } if providerEnablePreview { dataSources = append(dataSources, previewDataSources...) diff --git a/internal/service/encryptionatrestprivateendpoint/data_source_schema.go b/internal/service/encryptionatrestprivateendpoint/data_source_schema.go index 08f0a5c66a..cf4b2c0df6 100644 --- a/internal/service/encryptionatrestprivateendpoint/data_source_schema.go +++ b/internal/service/encryptionatrestprivateendpoint/data_source_schema.go @@ -14,11 +14,6 @@ func DataSourceSchema(ctx context.Context) schema.Schema { Description: "Human-readable label that identifies the cloud provider of the private endpoint.", MarkdownDescription: "Human-readable label that identifies the cloud provider of the private endpoint.", }, - "endpoint_id": schema.StringAttribute{ - Required: true, - Description: "Unique 24-hexadecimal digit string that identifies the private endpoint.", - MarkdownDescription: "Unique 24-hexadecimal digit string that identifies the private endpoint.", - }, "error_message": schema.StringAttribute{ Computed: true, Description: "Error message for failures associated with the Encryption At Rest private endpoint.", @@ -30,7 +25,7 @@ func DataSourceSchema(ctx context.Context) schema.Schema { MarkdownDescription: "Unique 24-hexadecimal digit string that identifies your project. Use the [/groups](#tag/Projects/operation/listProjects) endpoint to retrieve all projects to which the authenticated user has access.\n\n**NOTE**: Groups and projects are synonymous terms. Your group id is the same as your project id. For existing groups, your group/project id remains the same. The resource and corresponding endpoints use the term groups.", }, "id": schema.StringAttribute{ - Computed: true, + Required: true, Description: "Unique 24-hexadecimal digit string that identifies the Private Endpoint Service.", MarkdownDescription: "Unique 24-hexadecimal digit string that identifies the Private Endpoint Service.", }, diff --git a/internal/service/encryptionatrestprivateendpoint/model.go b/internal/service/encryptionatrestprivateendpoint/model.go index b15174058f..5467b490cc 100644 --- a/internal/service/encryptionatrestprivateendpoint/model.go +++ b/internal/service/encryptionatrestprivateendpoint/model.go @@ -1,15 +1,19 @@ package encryptionatrestprivateendpoint import ( - "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion" "go.mongodb.org/atlas-sdk/v20240805001/admin" + + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion" ) -func NewTFEarPrivateEndpoint(apiResp *admin.EARPrivateEndpoint) *TFEarPrivateEndpointModel { +func NewTFEarPrivateEndpoint(apiResp *admin.EARPrivateEndpoint, projectID string) *TFEarPrivateEndpointModel { if apiResp == nil { return nil } return &TFEarPrivateEndpointModel{ + ProjectID: types.StringValue(projectID), CloudProvider: conversion.StringNullIfEmpty(apiResp.GetCloudProvider()), ErrorMessage: conversion.StringNullIfEmpty(apiResp.GetErrorMessage()), ID: conversion.StringNullIfEmpty(apiResp.GetId()), diff --git a/internal/service/encryptionatrestprivateendpoint/model_test.go b/internal/service/encryptionatrestprivateendpoint/model_test.go index 6f9fcf9755..322e3c0629 100644 --- a/internal/service/encryptionatrestprivateendpoint/model_test.go +++ b/internal/service/encryptionatrestprivateendpoint/model_test.go @@ -3,14 +3,18 @@ package encryptionatrestprivateendpoint_test import ( "testing" + "go.mongodb.org/atlas-sdk/v20240805001/admin" + "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/mongodb/terraform-provider-mongodbatlas/internal/service/encryptionatrestprivateendpoint" "github.com/stretchr/testify/assert" - "go.mongodb.org/atlas-sdk/v20240805001/admin" + + "github.com/mongodb/terraform-provider-mongodbatlas/internal/service/encryptionatrestprivateendpoint" ) const ( testCloudProvider = "AZURE" + testProjectID = "666666666067bd1e20a8bf14" + testTotalResultCount = 99 testErrMsg = "error occurred" testID = "6666666999999adsfsgdg" testRegionName = "US_EAST" @@ -41,6 +45,7 @@ func TestEncryptionAtRestPrivateEndpointSDKToTFModel(t *testing.T) { RegionName: types.StringValue(testRegionName), Status: types.StringValue(testStatus), PrivateEndpointConnectionName: types.StringValue(testPEConnectionName), + ProjectID: types.StringValue(testProjectID), }, }, "Complete SDK response with error message": { @@ -59,13 +64,14 @@ func TestEncryptionAtRestPrivateEndpointSDKToTFModel(t *testing.T) { RegionName: types.StringValue(testRegionName), Status: types.StringValue(testStatus), PrivateEndpointConnectionName: types.StringValue(testPEConnectionName), + ProjectID: types.StringValue(testProjectID), }, }, } for testName, tc := range testCases { t.Run(testName, func(t *testing.T) { - resultModel := encryptionatrestprivateendpoint.NewTFEarPrivateEndpoint(tc.SDKResp) + resultModel := encryptionatrestprivateendpoint.NewTFEarPrivateEndpoint(tc.SDKResp, testProjectID) assert.Equal(t, tc.expectedTFModel, resultModel, "created terraform model did not match expected output") }) } @@ -119,3 +125,62 @@ func TestEncryptionAtRestPrivateEndpointTFModelToSDK(t *testing.T) { }) } } + +type sdkToTFModelPluralDSTestCase struct { + expectedTFModel *encryptionatrestprivateendpoint.TFEncryptionAtRestPrivateEndpointsDSModel + SDKResp []admin.EARPrivateEndpoint +} + +func TestEncryptionAtRestPrivateEndpointPluralDSSDKToTFModel(t *testing.T) { + testCases := map[string]sdkToTFModelPluralDSTestCase{ + "Complete SDK response": { + SDKResp: []admin.EARPrivateEndpoint{ + { + CloudProvider: admin.PtrString(testCloudProvider), + ErrorMessage: admin.PtrString(""), + Id: admin.PtrString(testID), + RegionName: admin.PtrString(testRegionName), + Status: admin.PtrString(testStatus), + PrivateEndpointConnectionName: admin.PtrString(testPEConnectionName), + }, + { + CloudProvider: admin.PtrString(testCloudProvider), + ErrorMessage: admin.PtrString(testErrMsg), + Id: admin.PtrString(testID), + RegionName: admin.PtrString(testRegionName), + Status: admin.PtrString(testStatus), + PrivateEndpointConnectionName: admin.PtrString(testPEConnectionName), + }, + }, + expectedTFModel: &encryptionatrestprivateendpoint.TFEncryptionAtRestPrivateEndpointsDSModel{ + CloudProvider: types.StringValue(testCloudProvider), + ProjectID: types.StringValue(testProjectID), + Results: []encryptionatrestprivateendpoint.TFEarPrivateEndpointDSModel{ + { + CloudProvider: types.StringValue(testCloudProvider), + ErrorMessage: types.StringNull(), + ID: types.StringValue(testID), + RegionName: types.StringValue(testRegionName), + Status: types.StringValue(testStatus), + PrivateEndpointConnectionName: types.StringValue(testPEConnectionName), + }, + { + CloudProvider: types.StringValue(testCloudProvider), + ErrorMessage: types.StringValue(testErrMsg), + ID: types.StringValue(testID), + RegionName: types.StringValue(testRegionName), + Status: types.StringValue(testStatus), + PrivateEndpointConnectionName: types.StringValue(testPEConnectionName), + }, + }, + }, + }, + } + + for testName, tc := range testCases { + t.Run(testName, func(t *testing.T) { + resultModel := encryptionatrestprivateendpoint.NewTFEarPrivateEndpoints(testProjectID, testCloudProvider, tc.SDKResp) + assert.Equal(t, tc.expectedTFModel, resultModel, "created terraform model did not match expected output") + }) + } +} diff --git a/internal/service/encryptionatrestprivateendpoint/plural_data_source.go b/internal/service/encryptionatrestprivateendpoint/plural_data_source.go new file mode 100644 index 0000000000..c7c7f019e1 --- /dev/null +++ b/internal/service/encryptionatrestprivateendpoint/plural_data_source.go @@ -0,0 +1,56 @@ +//nolint:gocritic +package encryptionatrestprivateendpoint + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + + "github.com/mongodb/terraform-provider-mongodbatlas/internal/config" +) + +var _ datasource.DataSource = &encryptionAtRestPrivateEndpointsDS{} +var _ datasource.DataSourceWithConfigure = &encryptionAtRestPrivateEndpointsDS{} + +func PluralDataSource() datasource.DataSource { + return &encryptionAtRestPrivateEndpointsDS{ + DSCommon: config.DSCommon{ + DataSourceName: fmt.Sprintf("%ss", encryptionAtRestPrivateEndpointName), + }, + } +} + +type encryptionAtRestPrivateEndpointsDS struct { + config.DSCommon +} + +func (d *encryptionAtRestPrivateEndpointsDS) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = PluralDataSourceSchema(ctx) +} + +func (d *encryptionAtRestPrivateEndpointsDS) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var encryptionAtRestPrivateEndpointsConfig TFEncryptionAtRestPrivateEndpointsDSModel + resp.Diagnostics.Append(req.Config.Get(ctx, &encryptionAtRestPrivateEndpointsConfig)...) + if resp.Diagnostics.HasError() { + return + } + + // TODO: make get request to obtain list of results + + // connV2 := d.Client.AtlasV2 + // TODO: GetEncryptionAtRestPrivateEndpointsForCloudProvider returns paginated results + // v, resp, err := connV2.EncryptionAtRestUsingCustomerKeyManagementApi.GetEncryptionAtRestPrivateEndpointsForCloudProvider(ctx, "", "").Execute() + // if err != nil { + // resp.Diagnostics.AddError("error fetching results", err.Error()) + // return + //} + + // TODO: process response into new terraform state + // newEncryptionAtRestPrivateEndpointsModel := NewTFEarPrivateEndpoints("","",conversion.IntPtr(99), v.GetResults()) + // if diags.HasError() { + // resp.Diagnostics.Append(diags...) + // return + // } + // resp.Diagnostics.Append(resp.State.Set(ctx, NewTFEarPrivateEndpoints(ctx))...) +} diff --git a/internal/service/encryptionatrestprivateendpoint/pural_data_source_schema.go b/internal/service/encryptionatrestprivateendpoint/pural_data_source_schema.go new file mode 100644 index 0000000000..9f88d4979a --- /dev/null +++ b/internal/service/encryptionatrestprivateendpoint/pural_data_source_schema.go @@ -0,0 +1,107 @@ +package encryptionatrestprivateendpoint + +import ( + "context" + + "go.mongodb.org/atlas-sdk/v20240805001/admin" + + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion" +) + +func PluralDataSourceSchema(ctx context.Context) schema.Schema { + return schema.Schema{ + Attributes: map[string]schema.Attribute{ + "cloud_provider": schema.StringAttribute{ + Required: true, + Description: "Human-readable label that identifies the cloud provider for the private endpoints to return.", + MarkdownDescription: "Human-readable label that identifies the cloud provider for the private endpoints to return.", + }, + "project_id": schema.StringAttribute{ + Required: true, + Description: "Unique 24-hexadecimal digit string that identifies your project. Use the [/groups](#tag/Projects/operation/listProjects) endpoint to retrieve all projects to which the authenticated user has access.\n\n**NOTE**: Groups and projects are synonymous terms. Your group id is the same as your project id. For existing groups, your group/project id remains the same. The resource and corresponding endpoints use the term groups.", + MarkdownDescription: "Unique 24-hexadecimal digit string that identifies your project. Use the [/groups](#tag/Projects/operation/listProjects) endpoint to retrieve all projects to which the authenticated user has access.\n\n**NOTE**: Groups and projects are synonymous terms. Your group id is the same as your project id. For existing groups, your group/project id remains the same. The resource and corresponding endpoints use the term groups.", + }, + "results": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "cloud_provider": schema.StringAttribute{ + Computed: true, + Description: "Human-readable label that identifies the cloud provider for the Encryption At Rest private endpoint.", + MarkdownDescription: "Human-readable label that identifies the cloud provider for the Encryption At Rest private endpoint.", + }, + "error_message": schema.StringAttribute{ + Computed: true, + Description: "Error message for failures associated with the Encryption At Rest private endpoint.", + MarkdownDescription: "Error message for failures associated with the Encryption At Rest private endpoint.", + }, + "id": schema.StringAttribute{ + Computed: true, + Description: "Unique 24-hexadecimal digit string that identifies the Private Endpoint Service.", + MarkdownDescription: "Unique 24-hexadecimal digit string that identifies the Private Endpoint Service.", + }, + "private_endpoint_connection_name": schema.StringAttribute{ + Computed: true, + Description: "Connection name of the Azure Private Endpoint.", + MarkdownDescription: "Connection name of the Azure Private Endpoint.", + }, + "region_name": schema.StringAttribute{ + Computed: true, + Description: "Cloud provider region in which the Encryption At Rest private endpoint is located.", + MarkdownDescription: "Cloud provider region in which the Encryption At Rest private endpoint is located.", + }, + "status": schema.StringAttribute{ + Computed: true, + Description: "State of the Encryption At Rest private endpoint.", + MarkdownDescription: "State of the Encryption At Rest private endpoint.", + }, + }, + }, + Computed: true, + Description: "List of returned documents that MongoDB Cloud providers when completing this request.", + MarkdownDescription: "List of returned documents that MongoDB Cloud providers when completing this request.", + }, + }, + } +} + +type TFEncryptionAtRestPrivateEndpointsDSModel struct { + CloudProvider types.String `tfsdk:"cloud_provider"` + ProjectID types.String `tfsdk:"project_id"` + Results []TFEarPrivateEndpointDSModel `tfsdk:"results"` +} + +type TFEarPrivateEndpointDSModel struct { + CloudProvider types.String `tfsdk:"cloud_provider"` + ErrorMessage types.String `tfsdk:"error_message"` + ID types.String `tfsdk:"id"` + PrivateEndpointConnectionName types.String `tfsdk:"private_endpoint_connection_name"` + RegionName types.String `tfsdk:"region_name"` + Status types.String `tfsdk:"status"` +} + +func NewTFEarPrivateEndpoints(projectID, cloudProvider string, results []admin.EARPrivateEndpoint) *TFEncryptionAtRestPrivateEndpointsDSModel { + return &TFEncryptionAtRestPrivateEndpointsDSModel{ + ProjectID: types.StringValue(projectID), + CloudProvider: types.StringValue(cloudProvider), + Results: NewTFEarPrivateEndpointsDS(results), + } +} + +func NewTFEarPrivateEndpointsDS(endpoints []admin.EARPrivateEndpoint) []TFEarPrivateEndpointDSModel { + results := make([]TFEarPrivateEndpointDSModel, len(endpoints)) + + for i, v := range endpoints { + results[i] = TFEarPrivateEndpointDSModel{ + CloudProvider: conversion.StringNullIfEmpty(v.GetCloudProvider()), + ErrorMessage: conversion.StringNullIfEmpty(v.GetErrorMessage()), + ID: conversion.StringNullIfEmpty(v.GetId()), + RegionName: conversion.StringNullIfEmpty(v.GetRegionName()), + Status: conversion.StringNullIfEmpty(v.GetStatus()), + PrivateEndpointConnectionName: conversion.StringNullIfEmpty(v.GetPrivateEndpointConnectionName()), + } + } + return results +} diff --git a/internal/service/encryptionatrestprivateendpoint/resource_schema.go b/internal/service/encryptionatrestprivateendpoint/resource_schema.go index 076488886c..13a2ef96d3 100644 --- a/internal/service/encryptionatrestprivateendpoint/resource_schema.go +++ b/internal/service/encryptionatrestprivateendpoint/resource_schema.go @@ -15,11 +15,6 @@ func ResourceSchema(ctx context.Context) schema.Schema { Description: "Human-readable label that identifies the cloud provider for the Encryption At Rest private endpoint.", MarkdownDescription: "Human-readable label that identifies the cloud provider for the Encryption At Rest private endpoint.", }, - "endpoint_id": schema.StringAttribute{ - Computed: true, - Description: "Unique 24-hexadecimal digit string that identifies the private endpoint.", - MarkdownDescription: "Unique 24-hexadecimal digit string that identifies the private endpoint.", - }, "error_message": schema.StringAttribute{ Computed: true, Description: "Error message for failures associated with the Encryption At Rest private endpoint.", @@ -56,7 +51,6 @@ func ResourceSchema(ctx context.Context) schema.Schema { type TFEarPrivateEndpointModel struct { CloudProvider types.String `tfsdk:"cloud_provider"` - EndpointID types.String `tfsdk:"endpoint_id"` ErrorMessage types.String `tfsdk:"error_message"` ProjectID types.String `tfsdk:"project_id"` ID types.String `tfsdk:"id"`