diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1bdedb108..c8a86ff2b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -27,20 +27,21 @@ datadog/*cloud_configuration* @DataDog/api-clients @DataDog/k9-cloud datadog/*service_account* @DataDog/api-clients @DataDog/team-aaa # Framework resources/data-sources -datadog/**/*datadog_api_key* @DataDog/api-clients @DataDog/team-aaa -datadog/**/*datadog_apm_retention_filter* @DataDog/api-clients @DataDog/apm-trace-intake -datadog/**/*datadog_hosts* @DataDog/api-clients @DataDog/redapl-storage -datadog/**/*datadog_ip_ranges* @DataDog/api-clients @DataDog/team-aaa -datadog/**/*datadog_integration_aws* @DataDog/api-clients @DataDog/cloud-integrations -datadog/**/*datadog_integration_azure* @DataDog/api-clients @DataDog/azure-integrations -datadog/**/*datadog_integration_cloudflare* @DataDog/api-clients @DataDog/saas-integrations -datadog/**/*datadog_integration_confluent* @DataDog/api-clients @DataDog/saas-integrations -datadog/**/*datadog_integration_fastly* @DataDog/api-clients @DataDog/saas-integrations -datadog/**/*datadog_integration_gcp* @DataDog/api-clients @DataDog/gcp-integrations -datadog/**/*datadog_restriction_policy* @DataDog/api-clients @DataDog/aaa-granular-access -datadog/**/*datadog_sensitive_data_scanner* @DataDog/api-clients @DataDog/sensitive-data-scanner -datadog/**/*datadog_service_account* @DataDog/api-clients @DataDog/team-aaa -datadog/**/*datadog_spans_metric* @DataDog/api-clients @DataDog/apm-trace-intake -datadog/**/*datadog_synthetics_concurrency_cap* @DataDog/api-clients @DataDog/synthetics-app @DataDog/synthetics-ct -datadog/**/*datadog_team* @DataDog/api-clients @DataDog/core-app -datadog/**/*datadog_organization_settings* @DataDog/api-clients @DataDog/core-app @DataDog/trust-and-safety +datadog/**/*datadog_api_key* @DataDog/api-clients @DataDog/team-aaa +datadog/**/*datadog_apm_retention_filter* @DataDog/api-clients @DataDog/apm-trace-intake +datadog/**/*datadog_hosts* @DataDog/api-clients @DataDog/redapl-storage +datadog/**/*datadog_ip_ranges* @DataDog/api-clients @DataDog/team-aaa +datadog/**/*datadog_integration_aws* @DataDog/api-clients @DataDog/cloud-integrations +datadog/**/*datadog_integration_azure* @DataDog/api-clients @DataDog/azure-integrations +datadog/**/*datadog_integration_cloudflare* @DataDog/api-clients @DataDog/saas-integrations +datadog/**/*datadog_integration_confluent* @DataDog/api-clients @DataDog/saas-integrations +datadog/**/*datadog_integration_fastly* @DataDog/api-clients @DataDog/saas-integrations +datadog/**/*datadog_integration_gcp* @DataDog/api-clients @DataDog/gcp-integrations +datadog/**/*datadog_restriction_policy* @DataDog/api-clients @DataDog/aaa-granular-access +datadog/**/*datadog_sensitive_data_scanner* @DataDog/api-clients @DataDog/logs-app @DataDog/sensitive-data-scanner +datadog/**/*datadog_service_account* @DataDog/api-clients @DataDog/team-aaa +datadog/**/*datadog_spans_metric* @DataDog/api-clients @DataDog/apm-trace-intake +datadog/**/*datadog_synthetics_concurrency_cap* @DataDog/api-clients @DataDog/synthetics-app @DataDog/synthetics-ct +datadog/**/*datadog_team* @DataDog/api-clients @DataDog/core-app +datadog/**/*datadog_organization_settings* @DataDog/api-clients @DataDog/core-app @DataDog/trust-and-safety +datadog/**/*datadog_integration_microsoft_teams* @DataDog/api-clients @DataDog/chat-integrations diff --git a/datadog/fwprovider/framework_provider.go b/datadog/fwprovider/framework_provider.go index 2c2e7e5ba..5a373b798 100644 --- a/datadog/fwprovider/framework_provider.go +++ b/datadog/fwprovider/framework_provider.go @@ -67,6 +67,7 @@ var Resources = []func() resource.Resource{ NewWebhookResource, NewWebhookCustomVariableResource, NewLogsCustomDestinationResource, + NewTenantBasedHandleResource, } var Datasources = []func() datasource.DataSource{ diff --git a/datadog/fwprovider/resource_datadog_integration_microsoft_teams_handle.go b/datadog/fwprovider/resource_datadog_integration_microsoft_teams_handle.go new file mode 100644 index 000000000..837efd995 --- /dev/null +++ b/datadog/fwprovider/resource_datadog_integration_microsoft_teams_handle.go @@ -0,0 +1,267 @@ +package fwprovider + +import ( + "context" + "fmt" + "strings" + + "github.com/DataDog/datadog-api-client-go/v2/api/datadogV2" + "github.com/hashicorp/terraform-plugin-framework/diag" + frameworkPath "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/terraform-providers/terraform-provider-datadog/datadog/internal/utils" +) + +var ( + _ resource.ResourceWithConfigure = &tenantBasedHandleResource{} + _ resource.ResourceWithImportState = &tenantBasedHandleResource{} +) + +type tenantBasedHandleResource struct { + Api *datadogV2.MicrosoftTeamsIntegrationApi + Auth context.Context +} + +type tenantBasedHandleModel struct { + ID types.String `tfsdk:"id"` + ChannelName types.String `tfsdk:"channel_name"` + TeamName types.String `tfsdk:"team_name"` + TenantName types.String `tfsdk:"tenant_name"` + Name types.String `tfsdk:"name"` +} + +func NewTenantBasedHandleResource() resource.Resource { + return &tenantBasedHandleResource{} +} + +func (r *tenantBasedHandleResource) Configure(_ context.Context, request resource.ConfigureRequest, response *resource.ConfigureResponse) { + providerData := request.ProviderData.(*FrameworkProvider) + r.Api = providerData.DatadogApiInstances.GetMicrosoftTeamsIntegrationApiV2() + r.Auth = providerData.Auth +} + +func (r *tenantBasedHandleResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { + response.TypeName = "integration_ms_teams_tenant_based_handle" +} + +func (r *tenantBasedHandleResource) Schema(_ context.Context, _ resource.SchemaRequest, response *resource.SchemaResponse) { + response.Schema = schema.Schema{ + Description: "Resource for interacting with Datadog Microsoft Teams Integration tenant-based handles.", + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Required: true, + Description: "Your tenant-based handle name.", + }, + "tenant_name": schema.StringAttribute{ + Required: true, + Description: "Your tenant name.", + }, + "team_name": schema.StringAttribute{ + Description: "Your team name.", + Required: true, + }, + "channel_name": schema.StringAttribute{ + Description: "Your channel name.", + Required: true, + }, + "id": utils.ResourceIDAttribute(), + }, + } +} + +func (r *tenantBasedHandleResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, frameworkPath.Root("id"), request, response) +} + +func (r *tenantBasedHandleResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { + var state tenantBasedHandleModel + response.Diagnostics.Append(request.State.Get(ctx, &state)...) + if response.Diagnostics.HasError() { + return + } + + id := state.ID.ValueString() + // Check if handle exists + resp, httpResp, err := r.Api.GetTenantBasedHandle(r.Auth, id) + if err != nil { + if httpResp != nil && httpResp.StatusCode == 404 { + response.State.RemoveResource(ctx) + return + } + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error retrieving tenant-based handle")) + return + } + if err := utils.CheckForUnparsed(resp); err != nil { + response.Diagnostics.AddError("response contains unparsedObject", err.Error()) + return + } + + diags := r.updateState(ctx, &state, &resp) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + // Save data into Terraform state + response.Diagnostics.Append(response.State.Set(ctx, &state)...) +} + +func (r *tenantBasedHandleResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { + var state tenantBasedHandleModel + response.Diagnostics.Append(request.Plan.Get(ctx, &state)...) + if response.Diagnostics.HasError() { + return + } + + body, diags := r.buildTenantBasedHandleRequestBody(ctx, &state) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + resp, _, err := r.Api.CreateTenantBasedHandle(r.Auth, *body) + if err != nil { + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error creating tenant-based handle")) + return + } + if err := utils.CheckForUnparsed(resp); err != nil { + response.Diagnostics.AddError("response contains unparsedObject", err.Error()) + return + } + r.updateState(ctx, &state, &resp) + + // Save data into Terraform state + response.Diagnostics.Append(response.State.Set(ctx, &state)...) +} + +func (r *tenantBasedHandleResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { + var state tenantBasedHandleModel + response.Diagnostics.Append(request.Plan.Get(ctx, &state)...) + if response.Diagnostics.HasError() { + return + } + + id := state.ID.ValueString() + + body, diags := r.buildTenantBasedHandleUpdateRequestBody(ctx, &state) + + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + resp, _, err := r.Api.UpdateTenantBasedHandle(r.Auth, id, *body) + if err != nil { + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error updating tenant-based handle")) + return + } + if err := utils.CheckForUnparsed(resp); err != nil { + response.Diagnostics.AddError("response contains unparsedObject", err.Error()) + return + } + r.updateState(ctx, &state, &resp) + + // Save data into Terraform state + response.Diagnostics.Append(response.State.Set(ctx, &state)...) +} + +func (r *tenantBasedHandleResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { + var state tenantBasedHandleModel + response.Diagnostics.Append(request.State.Get(ctx, &state)...) + if response.Diagnostics.HasError() { + return + } + + id := state.ID.ValueString() + + httpResp, err := r.Api.DeleteTenantBasedHandle(r.Auth, id) + if err != nil { + if httpResp != nil && httpResp.StatusCode == 404 { + return + } + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error deleting tenant-based handle")) + return + } +} + +func (r *tenantBasedHandleResource) updateState(ctx context.Context, state *tenantBasedHandleModel, resp *datadogV2.MicrosoftTeamsTenantBasedHandleResponse) diag.Diagnostics { + diags := diag.Diagnostics{} + state.ID = types.StringValue(resp.Data.GetId()) + fullHandleDataList, _, err := r.Api.ListTenantBasedHandles(r.Auth, datadogV2.ListTenantBasedHandlesOptionalParameters{Name: resp.Data.Attributes.Name}) + if err != nil { + diags.AddError("Could not get remote state: ", err.Error()) + return diags + } + var fullHandleData datadogV2.MicrosoftTeamsTenantBasedHandleInfoResponseData + if len(fullHandleDataList.Data) == 0 { + diags.AddError("No matches for handle with name: "+*resp.Data.Attributes.Name, "") + return diags + } + + fullHandleData = fullHandleDataList.Data[0] + attributes := fullHandleData.GetAttributes() + + if name, ok := attributes.GetNameOk(); ok && name != nil { + state.Name = types.StringValue(*name) + } + + if tenantName, ok := attributes.GetTenantNameOk(); ok && tenantName != nil { + state.TenantName = types.StringValue(*tenantName) + } + + if teamName, ok := attributes.GetTeamNameOk(); ok && teamName != nil { + state.TeamName = types.StringValue(*teamName) + } + + if channelName, ok := attributes.GetChannelNameOk(); ok && channelName != nil { + state.ChannelName = types.StringValue(*channelName) + } + return diags +} + +func (r *tenantBasedHandleResource) buildTenantBasedHandleRequestBody(ctx context.Context, state *tenantBasedHandleModel) (*datadogV2.MicrosoftTeamsCreateTenantBasedHandleRequest, diag.Diagnostics) { + diags := diag.Diagnostics{} + attributes := datadogV2.NewMicrosoftTeamsTenantBasedHandleRequestAttributesWithDefaults() + channelData, _, err := r.Api.GetChannelByName(r.Auth, strings.ReplaceAll(state.TenantName.ValueString(), "\"", ""), state.TeamName.ValueString(), state.ChannelName.ValueString()) + if err != nil { + channelInfo := fmt.Sprintf("Tenant Name: %s\nTeam Name: %s\nChannel Name: %s\n", state.TenantName.ValueString(), state.TeamName.ValueString(), state.ChannelName.ValueString()) + diags.AddError("Channel data not found for: \n"+channelInfo, err.Error()) + return nil, diags + } + + attributes.SetName(state.Name.ValueString()) + attributes.SetTenantId(*channelData.Data.Attributes.TenantId) + attributes.SetTeamId(*channelData.Data.Attributes.TeamId) + attributes.SetChannelId(*channelData.Data.Id) + + req := datadogV2.NewMicrosoftTeamsCreateTenantBasedHandleRequestWithDefaults() + req.Data = *datadogV2.NewMicrosoftTeamsTenantBasedHandleRequestDataWithDefaults() + req.Data.SetAttributes(*attributes) + + return req, diags +} + +func (r *tenantBasedHandleResource) buildTenantBasedHandleUpdateRequestBody(ctx context.Context, state *tenantBasedHandleModel) (*datadogV2.MicrosoftTeamsUpdateTenantBasedHandleRequest, diag.Diagnostics) { + diags := diag.Diagnostics{} + attributes := datadogV2.NewMicrosoftTeamsTenantBasedHandleAttributesWithDefaults() + channelData, _, err := r.Api.GetChannelByName(r.Auth, strings.ReplaceAll(state.TenantName.ValueString(), "\"", ""), state.TeamName.ValueString(), state.ChannelName.ValueString()) + if err != nil { + channelInfo := fmt.Sprintf("Tenant Name: %s\nTeam Name: %s\nChannel Name: %s\n", state.TenantName.ValueString(), state.TeamName.ValueString(), state.ChannelName.ValueString()) + diags.AddError("Channel data not found for: \n"+channelInfo, err.Error()) + return nil, diags + } + + attributes.SetName(state.Name.ValueString()) + attributes.SetTenantId(*channelData.Data.Attributes.TenantId) + attributes.SetTeamId(*channelData.Data.Attributes.TeamId) + attributes.SetChannelId(*channelData.Data.Id) + + req := datadogV2.NewMicrosoftTeamsUpdateTenantBasedHandleRequestWithDefaults() + req.Data = *datadogV2.NewMicrosoftTeamsUpdateTenantBasedHandleRequestDataWithDefaults() + req.Data.SetAttributes(*attributes) + + return req, diags +} diff --git a/datadog/internal/utils/api_instances_helper.go b/datadog/internal/utils/api_instances_helper.go index fa42a1eb0..4dfd68451 100644 --- a/datadog/internal/utils/api_instances_helper.go +++ b/datadog/internal/utils/api_instances_helper.go @@ -44,45 +44,46 @@ type ApiInstances struct { webhooksIntegrationApiV1 *datadogV1.WebhooksIntegrationApi //V2 APIs - apiManagementAPIV2 *datadogV2.APIManagementApi - apmRetentionFiltersApiV2 *datadogV2.APMRetentionFiltersApi - auditApiV2 *datadogV2.AuditApi - authNMappingsApiV2 *datadogV2.AuthNMappingsApi - cloudflareIntegrationApiV2 *datadogV2.CloudflareIntegrationApi - csmThreatsApiV2 *datadogV2.CSMThreatsApi - confluentCloudApiV2 *datadogV2.ConfluentCloudApi - dashboardListsApiV2 *datadogV2.DashboardListsApi - domainAllowlistApiV2 *datadogV2.DomainAllowlistApi - downtimesApiV2 *datadogV2.DowntimesApi - eventsApiV2 *datadogV2.EventsApi - fastlyIntegrationApiV2 *datadogV2.FastlyIntegrationApi - gcpStsIntegrationApiV2 *datadogV2.GCPIntegrationApi - incidentServicesApiV2 *datadogV2.IncidentServicesApi - incidentTeamsApiV2 *datadogV2.IncidentTeamsApi - incidentsApiV2 *datadogV2.IncidentsApi - ipAllowlistApiV2 *datadogV2.IPAllowlistApi - keyManagementApiV2 *datadogV2.KeyManagementApi - logsApiV2 *datadogV2.LogsApi - logsArchivesApiV2 *datadogV2.LogsArchivesApi - logsCustomDestinationsApiV2 *datadogV2.LogsCustomDestinationsApi - logsMetricsApiV2 *datadogV2.LogsMetricsApi - metricsApiV2 *datadogV2.MetricsApi - monitorsApiV2 *datadogV2.MonitorsApi - opsgenieIntegrationApiV2 *datadogV2.OpsgenieIntegrationApi - organizationsApiV2 *datadogV2.OrganizationsApi - processesApiV2 *datadogV2.ProcessesApi - powerpackApiV2 *datadogV2.PowerpackApi - restrictionPolicyApiV2 *datadogV2.RestrictionPoliciesApi - rolesApiV2 *datadogV2.RolesApi - rumApiV2 *datadogV2.RUMApi - securityMonitoringApiV2 *datadogV2.SecurityMonitoringApi - sensitiveDataScannerApiV2 *datadogV2.SensitiveDataScannerApi - serviceAccountsApiV2 *datadogV2.ServiceAccountsApi - spansMetricsApiV2 *datadogV2.SpansMetricsApi - syntheticsApiV2 *datadogV2.SyntheticsApi - teamsApiV2 *datadogV2.TeamsApi - usageMeteringApiV2 *datadogV2.UsageMeteringApi - usersApiV2 *datadogV2.UsersApi + apiManagementAPIV2 *datadogV2.APIManagementApi + apmRetentionFiltersApiV2 *datadogV2.APMRetentionFiltersApi + auditApiV2 *datadogV2.AuditApi + authNMappingsApiV2 *datadogV2.AuthNMappingsApi + cloudflareIntegrationApiV2 *datadogV2.CloudflareIntegrationApi + csmThreatsApiV2 *datadogV2.CSMThreatsApi + confluentCloudApiV2 *datadogV2.ConfluentCloudApi + dashboardListsApiV2 *datadogV2.DashboardListsApi + domainAllowlistApiV2 *datadogV2.DomainAllowlistApi + downtimesApiV2 *datadogV2.DowntimesApi + eventsApiV2 *datadogV2.EventsApi + fastlyIntegrationApiV2 *datadogV2.FastlyIntegrationApi + gcpStsIntegrationApiV2 *datadogV2.GCPIntegrationApi + incidentServicesApiV2 *datadogV2.IncidentServicesApi + incidentTeamsApiV2 *datadogV2.IncidentTeamsApi + incidentsApiV2 *datadogV2.IncidentsApi + ipAllowlistApiV2 *datadogV2.IPAllowlistApi + keyManagementApiV2 *datadogV2.KeyManagementApi + logsApiV2 *datadogV2.LogsApi + logsArchivesApiV2 *datadogV2.LogsArchivesApi + logsCustomDestinationsApiV2 *datadogV2.LogsCustomDestinationsApi + logsMetricsApiV2 *datadogV2.LogsMetricsApi + metricsApiV2 *datadogV2.MetricsApi + microsoftTeamsIntegrationApiV2 *datadogV2.MicrosoftTeamsIntegrationApi + monitorsApiV2 *datadogV2.MonitorsApi + opsgenieIntegrationApiV2 *datadogV2.OpsgenieIntegrationApi + organizationsApiV2 *datadogV2.OrganizationsApi + processesApiV2 *datadogV2.ProcessesApi + powerpackApiV2 *datadogV2.PowerpackApi + restrictionPolicyApiV2 *datadogV2.RestrictionPoliciesApi + rolesApiV2 *datadogV2.RolesApi + rumApiV2 *datadogV2.RUMApi + securityMonitoringApiV2 *datadogV2.SecurityMonitoringApi + sensitiveDataScannerApiV2 *datadogV2.SensitiveDataScannerApi + serviceAccountsApiV2 *datadogV2.ServiceAccountsApi + spansMetricsApiV2 *datadogV2.SpansMetricsApi + syntheticsApiV2 *datadogV2.SyntheticsApi + teamsApiV2 *datadogV2.TeamsApi + usageMeteringApiV2 *datadogV2.UsageMeteringApi + usersApiV2 *datadogV2.UsersApi } // GetAuthenticationApiV1 get instance of AuthenticationApi @@ -644,3 +645,11 @@ func (i *ApiInstances) GetAPIManagementApiV2() *datadogV2.APIManagementApi { } return i.apiManagementAPIV2 } + +// GetMicrosoftTeamsIntegrationApiV2 get instance of APIMicrosoftTeamsIntegration +func (i *ApiInstances) GetMicrosoftTeamsIntegrationApiV2() *datadogV2.MicrosoftTeamsIntegrationApi { + if i.microsoftTeamsIntegrationApiV2 == nil { + i.microsoftTeamsIntegrationApiV2 = datadogV2.NewMicrosoftTeamsIntegrationApi(i.HttpClient) + } + return i.microsoftTeamsIntegrationApiV2 +} diff --git a/datadog/tests/cassettes/TestAccMSTeamsTenantBasedHandlesBasic.freeze b/datadog/tests/cassettes/TestAccMSTeamsTenantBasedHandlesBasic.freeze new file mode 100644 index 000000000..b6e9b2358 --- /dev/null +++ b/datadog/tests/cassettes/TestAccMSTeamsTenantBasedHandlesBasic.freeze @@ -0,0 +1 @@ +2024-11-13T14:27:31.888538-05:00 \ No newline at end of file diff --git a/datadog/tests/cassettes/TestAccMSTeamsTenantBasedHandlesBasic.yaml b/datadog/tests/cassettes/TestAccMSTeamsTenantBasedHandlesBasic.yaml new file mode 100644 index 000000000..05f1c4266 --- /dev/null +++ b/datadog/tests/cassettes/TestAccMSTeamsTenantBasedHandlesBasic.yaml @@ -0,0 +1,469 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/tenant-based-handles + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"data":[{"id":"5f002dba-7cd2-11ef-8717-da7ad0900002","type":"ms-teams-tenant-based-handle-info","attributes":{"channel_id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","channel_name":"General","name":"test","team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","team_name":"incident-6252-is_this_a_new_title","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97","tenant_name":"Datadog, Inc."}},{"id":"9fc79cf6-7ffd-11ef-b391-da7ad0900002","type":"ms-teams-tenant-based-handle-info","attributes":{"channel_id":"19:iD_D2xy_sAa-JV851JJYwIa6mlW9F9Nxm3SLyZq68qY1@thread.tacv2","channel_name":"General-1","name":"TwA43H2NIrilngRZ6dOvNBVNFx4fZvPgdYaroSwcvoObDbJ8RRJtSyKCjkiV2AaVziZSfxNKrL7oV4XHAC0gDv4cuZwGzkv3hJyPGqCuUEHP89CyJMOrtkCRgCM5XeNqoK28J2todRY8ibd3S3xwIwmCK83F2bnBjVB6WEDbmO92F7B9XcIglNwPpy7KMeNRjzxy8Y3c0Ji6jYQIIMRDnawdBGWqCQmGtJ7mFPCHpYlZHKBT7uyV1gIAuGtwIr","team_id":"e5f50a58-c929-4fb3-8866-e2cd836de3c2","team_name":"Chat Integrations","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97","tenant_name":"Datadog, Inc."}},{"id":"73ffbd06-8002-11ef-af80-da7ad0900002","type":"ms-teams-tenant-based-handle-info","attributes":{"channel_id":"19:iD_D2xy_sAa-JV851JJYwIa6mlW9F9Nxm3SLyZq68qY1@thread.tacv2","channel_name":"General-1","name":"TwA43H2NIrilngRZ6dOvNBVNFx4fZvPgdYaroSwcvoObDbJ8RRJtSyKCjkiV2AaVziZSfxNKrL7oV4XHAC0gDv4cuZwGzkv3hJyPGqCuUEHP89CyJMOrtkCRgCM5XeNqoK28J2todRY8ibd3S3xwIwmCK83F2bnBjVB6WEDbmO92F7B9XcIglNwPpy7KMeNRjzxy8Y3c0Ji6jYQIIMRDnawdBGWqCQmGtJ7mFPCHpYlZHKBT7uyV1gIAuGtwI","team_id":"e5f50a58-c929-4fb3-8866-e2cd836de3c2","team_name":"Chat Integrations","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97","tenant_name":"Datadog, Inc."}},{"id":"793156a6-8032-11ef-940c-da7ad0900002","type":"ms-teams-tenant-based-handle-info","attributes":{"channel_id":"19:iD_D2xy_sAa-JV851JJYwIa6mlW9F9Nxm3SLyZq68qY1@thread.tacv2","channel_name":"General-1","name":"TwA43H2NIrilngRZ6dOvNBVNFx4fZvPgdYaroSwcvoObDbJ8RRJtSyKCjkiV2AaVziZSfxNKrL7oV4XHAC0gDv4cuZwGzkv3hJyPGqCuUEHP89CyJMOrtkCRgCM5XeNqoK28J2todRY8ibd3S3xwIwmCK83F2bnBjVB6WEDbmO92F7B9XcIglNwPpy7KMeNRjzxy8Y3c0Ji6jYQIIMRDnawdBGWqCQmGtJ7mFPCHpYlZHKBT7uyV1gIAuGowI","team_id":"e5f50a58-c929-4fb3-8866-e2cd836de3c2","team_name":"Chat Integrations","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97","tenant_name":"Datadog, Inc."}},{"id":"e67bac72-a13c-11ef-83e6-da7ad0900002","type":"ms-teams-tenant-based-handle-info","attributes":{"channel_id":"19:iD_D2xy_sAa-JV851JJYwIa6mlW9F9Nxm3SLyZq68qY1@thread.tacv2","channel_name":"General-1","name":"terraform-test-first-handle-3","team_id":"e5f50a58-c929-4fb3-8866-e2cd836de3c2","team_name":"Chat Integrations","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97","tenant_name":"Datadog, Inc."}},{"id":"e67dbed6-a13c-11ef-9575-da7ad0900002","type":"ms-teams-tenant-based-handle-info","attributes":{"channel_id":"19:ef852c755a5542518c5d2c84588e38e6@thread.tacv2","channel_name":"sample","name":"terraform-test-first-handle","team_id":"e5f50a58-c929-4fb3-8866-e2cd836de3c2","team_name":"Chat Integrations","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97","tenant_name":"Datadog, Inc."}},{"id":"e67eba66-a13c-11ef-ba20-da7ad0900002","type":"ms-teams-tenant-based-handle-info","attributes":{"channel_id":"19:36dd21273b174467b89ba9d5e4809f9c@thread.tacv2","channel_name":"Ops-1","name":"terraform-test-first-handle-2","team_id":"e5f50a58-c929-4fb3-8866-e2cd836de3c2","team_name":"Chat Integrations","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97","tenant_name":"Datadog, Inc."}}]}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 126.453416ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/channel/Datadog%2C%20Inc./incident-6252-is_this_a_new_title/General + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: 242 + uncompressed: false + body: '{"data":{"id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","type":"ms-teams-channel-info","attributes":{"is_primary":true,"team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97"}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 84.880791ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 298 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: | + {"data":{"attributes":{"channel_id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","name":"tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051","team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97"},"type":"tenant-based-handle"}} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/tenant-based-handles + method: POST + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: 341 + uncompressed: false + body: '{"data":{"id":"54acc68c-a1f5-11ef-8bf7-da7ad0900002","type":"tenant-based-handle","attributes":{"channel_id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","name":"tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051","team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97"}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 201 Created + code: 201 + duration: 106.626417ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/tenant-based-handles?name=tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051 + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: 460 + uncompressed: false + body: '{"data":[{"id":"54acc68c-a1f5-11ef-8bf7-da7ad0900002","type":"ms-teams-tenant-based-handle-info","attributes":{"channel_id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","channel_name":"General","name":"tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051","team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","team_name":"incident-6252-is_this_a_new_title","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97","tenant_name":"Datadog, Inc."}}]}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 80.5415ms + - id: 4 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/tenant-based-handles/54acc68c-a1f5-11ef-8bf7-da7ad0900002 + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: 341 + uncompressed: false + body: '{"data":{"id":"54acc68c-a1f5-11ef-8bf7-da7ad0900002","type":"tenant-based-handle","attributes":{"channel_id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","name":"tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051","team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97"}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 86.192791ms + - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/tenant-based-handles?name=tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051 + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: 460 + uncompressed: false + body: '{"data":[{"id":"54acc68c-a1f5-11ef-8bf7-da7ad0900002","type":"ms-teams-tenant-based-handle-info","attributes":{"channel_id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","channel_name":"General","name":"tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051","team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","team_name":"incident-6252-is_this_a_new_title","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97","tenant_name":"Datadog, Inc."}}]}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 76.270542ms + - id: 6 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/tenant-based-handles/54acc68c-a1f5-11ef-8bf7-da7ad0900002 + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: 341 + uncompressed: false + body: '{"data":{"id":"54acc68c-a1f5-11ef-8bf7-da7ad0900002","type":"tenant-based-handle","attributes":{"channel_id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","name":"tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051","team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97"}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 90.018208ms + - id: 7 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/tenant-based-handles?name=tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051 + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: 460 + uncompressed: false + body: '{"data":[{"id":"54acc68c-a1f5-11ef-8bf7-da7ad0900002","type":"ms-teams-tenant-based-handle-info","attributes":{"channel_id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","channel_name":"General","name":"tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051","team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","team_name":"incident-6252-is_this_a_new_title","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97","tenant_name":"Datadog, Inc."}}]}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 102.64ms + - id: 8 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/channel/Datadog%2C%20Inc./incident-6252-is_this_a_new_title/General + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: 242 + uncompressed: false + body: '{"data":{"id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","type":"ms-teams-channel-info","attributes":{"is_primary":true,"team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97"}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 214.527375ms + - id: 9 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 306 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: | + {"data":{"attributes":{"channel_id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","name":"tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051-updated","team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97"},"type":"tenant-based-handle"}} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/tenant-based-handles/54acc68c-a1f5-11ef-8bf7-da7ad0900002 + method: PATCH + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: 349 + uncompressed: false + body: '{"data":{"id":"54acc68c-a1f5-11ef-8bf7-da7ad0900002","type":"tenant-based-handle","attributes":{"channel_id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","name":"tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051-updated","team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97"}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 98.305208ms + - id: 10 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/tenant-based-handles?name=tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051-updated + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: 468 + uncompressed: false + body: '{"data":[{"id":"54acc68c-a1f5-11ef-8bf7-da7ad0900002","type":"ms-teams-tenant-based-handle-info","attributes":{"channel_id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","channel_name":"General","name":"tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051-updated","team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","team_name":"incident-6252-is_this_a_new_title","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97","tenant_name":"Datadog, Inc."}}]}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 94.274917ms + - id: 11 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/tenant-based-handles/54acc68c-a1f5-11ef-8bf7-da7ad0900002 + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: 349 + uncompressed: false + body: '{"data":{"id":"54acc68c-a1f5-11ef-8bf7-da7ad0900002","type":"tenant-based-handle","attributes":{"channel_id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","name":"tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051-updated","team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97"}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 92.794333ms + - id: 12 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/tenant-based-handles?name=tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051-updated + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: 468 + uncompressed: false + body: '{"data":[{"id":"54acc68c-a1f5-11ef-8bf7-da7ad0900002","type":"ms-teams-tenant-based-handle-info","attributes":{"channel_id":"19:m2LnqTUOkhuzGCyeG_0xql4rbKc2ZSJ25JS6UZINc-01@thread.tacv2","channel_name":"General","name":"tf-testaccmsteamstenantbasedhandlesbasic-local-1731526051-updated","team_id":"008b01f1-4b68-4e81-b8a9-cfa27ba6c112","team_name":"incident-6252-is_this_a_new_title","tenant_id":"4d3bac44-0230-4732-9e70-cc00736f0a97","tenant_name":"Datadog, Inc."}}]}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 83.887667ms + - id: 13 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - '*/*' + url: https://api.datadoghq.com/api/v2/integration/ms-teams/configuration/tenant-based-handles/54acc68c-a1f5-11ef-8bf7-da7ad0900002 + method: DELETE + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: {} + status: 204 No Content + code: 204 + duration: 58.396792ms diff --git a/datadog/tests/provider_test.go b/datadog/tests/provider_test.go index 8407fb8b8..04516b881 100644 --- a/datadog/tests/provider_test.go +++ b/datadog/tests/provider_test.go @@ -193,6 +193,7 @@ var testFiles2EndpointTags = map[string]string{ "tests/resource_datadog_integration_fastly_account_test": "integration-fastly-account", "tests/resource_datadog_integration_gcp_sts_test": "integration-gcp", "tests/resource_datadog_integration_gcp_test": "integration-gcp", + "tests/resource_datadog_integration_microsoft_teams_handle_test": "integration-microsoft-teams", "tests/resource_datadog_integration_opsgenie_service_object_test": "integration-opsgenie-service", "tests/resource_datadog_integration_pagerduty_service_object_test": "integration-pagerduty", "tests/resource_datadog_integration_pagerduty_test": "integration-pagerduty", diff --git a/datadog/tests/resource_datadog_integration_microsoft_teams_handle_test.go b/datadog/tests/resource_datadog_integration_microsoft_teams_handle_test.go new file mode 100644 index 000000000..846d74038 --- /dev/null +++ b/datadog/tests/resource_datadog_integration_microsoft_teams_handle_test.go @@ -0,0 +1,151 @@ +package test + +import ( + "context" + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + + "github.com/terraform-providers/terraform-provider-datadog/datadog/fwprovider" + "github.com/terraform-providers/terraform-provider-datadog/datadog/internal/utils" +) + +func TestAccMSTeamsTenantBasedHandlesBasic(t *testing.T) { + t.Parallel() + ctx, providers, accProviders := testAccFrameworkMuxProviders(context.Background(), t) + uniq := strings.ToLower(uniqueEntityName(ctx, t)) + + apiInstances := providers.frameworkProvider.DatadogApiInstances + auth := providers.frameworkProvider.Auth + resp, _, err := apiInstances.GetMicrosoftTeamsIntegrationApiV2().ListTenantBasedHandles(auth) + // Return if there are no available channels to test + if err != nil || len(resp.Data) == 0 { + return + } + + tenantName := *resp.Data[0].Attributes.TenantName + teamName := *resp.Data[0].Attributes.TeamName + channelName := *resp.Data[0].Attributes.ChannelName + + resource.Test(t, resource.TestCase{ + ProtoV5ProviderFactories: accProviders, + CheckDestroy: testAccCheckDatadogMSTeamsTenantBasedHandlesDestroy(providers.frameworkProvider), + Steps: []resource.TestStep{ + { + Config: testAccCheckDatadogMSTeamsTenantBasedHandles(uniq, tenantName, teamName, channelName), + Check: resource.ComposeTestCheckFunc( + testAccCheckDatadogMSTeamsTenantBasedHandlesExists(providers.frameworkProvider), + resource.TestCheckResourceAttr( + "datadog_integration_ms_teams_tenant_based_handle.foo", "name", uniq), + resource.TestCheckResourceAttr( + "datadog_integration_ms_teams_tenant_based_handle.foo", "tenant_name", tenantName), + resource.TestCheckResourceAttr( + "datadog_integration_ms_teams_tenant_based_handle.foo", "team_name", teamName), + resource.TestCheckResourceAttr( + "datadog_integration_ms_teams_tenant_based_handle.foo", "channel_name", channelName), + ), + }, + { + Config: testAccCheckDatadogMSTeamsTenantBasedHandlesUpdated(uniq, tenantName, teamName, channelName), + Check: resource.ComposeTestCheckFunc( + testAccCheckDatadogMSTeamsTenantBasedHandlesExists(providers.frameworkProvider), + resource.TestCheckResourceAttr( + "datadog_integration_ms_teams_tenant_based_handle.foo", "name", fmt.Sprintf("%s-updated", uniq)), + resource.TestCheckResourceAttr( + "datadog_integration_ms_teams_tenant_based_handle.foo", "tenant_name", tenantName), + resource.TestCheckResourceAttr( + "datadog_integration_ms_teams_tenant_based_handle.foo", "team_name", teamName), + resource.TestCheckResourceAttr( + "datadog_integration_ms_teams_tenant_based_handle.foo", "channel_name", channelName), + ), + }, + }, + }) +} + +func testAccCheckDatadogMSTeamsTenantBasedHandles(uniq string, tenantName string, teamName string, channelName string) string { + return fmt.Sprintf(` +resource "datadog_integration_ms_teams_tenant_based_handle" "foo" { + name = "%s" + tenant_name = "%s" + team_name = "%s" + channel_name = "%s" +}`, uniq, tenantName, teamName, channelName) +} + +func testAccCheckDatadogMSTeamsTenantBasedHandlesUpdated(uniq string, tenantName string, teamName string, channelName string) string { + return fmt.Sprintf(` +resource "datadog_integration_ms_teams_tenant_based_handle" "foo" { + name = "%s-updated" + tenant_name = "%s" + team_name = "%s" + channel_name = "%s" +}`, uniq, tenantName, teamName, channelName) +} + +func testAccCheckDatadogMSTeamsTenantBasedHandlesDestroy(accProvider *fwprovider.FrameworkProvider) func(*terraform.State) error { + return func(s *terraform.State) error { + apiInstances := accProvider.DatadogApiInstances + auth := accProvider.Auth + + if err := MSTeamsTenantBasedHandlesDestroyHelper(auth, s, apiInstances); err != nil { + return err + } + return nil + } +} + +func MSTeamsTenantBasedHandlesDestroyHelper(auth context.Context, s *terraform.State, apiInstances *utils.ApiInstances) error { + for _, r := range s.RootModule().Resources { + if r.Type != "resource_datadog_integration_ms_teams_tenant_based_handle" { + continue + } + id := r.Primary.ID + + err := utils.Retry(2, 10, func() error { + _, httpResp, err := apiInstances.GetMicrosoftTeamsIntegrationApiV2().GetTenantBasedHandle(auth, id) + if err != nil { + if httpResp != nil && httpResp.StatusCode == 404 { + return nil + } + return &utils.RetryableError{Prob: fmt.Sprintf("received an error retrieving handle %s", err)} + } + return &utils.RetryableError{Prob: "Handle still exists"} + }) + + if err != nil { + return err + } + } + return nil +} + +func testAccCheckDatadogMSTeamsTenantBasedHandlesExists(accProvider *fwprovider.FrameworkProvider) resource.TestCheckFunc { + return func(s *terraform.State) error { + apiInstances := accProvider.DatadogApiInstances + auth := accProvider.Auth + + if err := msTeamsTenantBasedHandlesExistsHelper(auth, s, apiInstances); err != nil { + return err + } + return nil + } +} + +func msTeamsTenantBasedHandlesExistsHelper(auth context.Context, s *terraform.State, apiInstances *utils.ApiInstances) error { + for _, r := range s.RootModule().Resources { + if r.Type != "resource_datadog_integration_ms_teams_tenant_based_handle" { + continue + } + id := r.Primary.ID + + _, httpResp, err := apiInstances.GetMicrosoftTeamsIntegrationApiV2().GetTenantBasedHandle(auth, id) + if err != nil { + return utils.TranslateClientError(err, httpResp, "error retrieving handle") + } + } + return nil +} diff --git a/docs/resources/integration_aws_tag_filter.md b/docs/resources/integration_aws_tag_filter.md index 1769d2107..0dee55668 100644 --- a/docs/resources/integration_aws_tag_filter.md +++ b/docs/resources/integration_aws_tag_filter.md @@ -27,7 +27,7 @@ resource "datadog_integration_aws_tag_filter" "foo" { ### Required - `account_id` (String) Your AWS Account ID without dashes. -- `namespace` (String) The namespace associated with the tag filter entry. Valid values are `elb`, `application_elb`, `sqs`, `rds`, `custom`, `network_elb`, `lambda`, `step_functions`. +- `namespace` (String) The namespace associated with the tag filter entry. Valid values are `elb`, `application_elb`, `sqs`, `rds`, `custom`, `network_elb`, `lambda`. - `tag_filter_str` (String) The tag filter string. ### Read-Only diff --git a/docs/resources/integration_ms_teams_tenant_based_handle.md b/docs/resources/integration_ms_teams_tenant_based_handle.md new file mode 100644 index 000000000..db7b06519 --- /dev/null +++ b/docs/resources/integration_ms_teams_tenant_based_handle.md @@ -0,0 +1,27 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "datadog_integration_ms_teams_tenant_based_handle Resource - terraform-provider-datadog" +subcategory: "" +description: |- + Resource for interacting with Datadog Microsoft Teams Integration tenant-based handles. +--- + +# datadog_integration_ms_teams_tenant_based_handle (Resource) + +Resource for interacting with Datadog Microsoft Teams Integration tenant-based handles. + + + + +## Schema + +### Required + +- `channel_name` (String) Your channel name. +- `name` (String) Your tenant-based handle name. +- `team_name` (String) Your team name. +- `tenant_name` (String) Your tenant name. + +### Read-Only + +- `id` (String) The ID of this resource. diff --git a/examples/resources/datadog_integration_microsoft_teams_tenant_based_handle/import.sh b/examples/resources/datadog_integration_microsoft_teams_tenant_based_handle/import.sh new file mode 100644 index 000000000..ffb29263a --- /dev/null +++ b/examples/resources/datadog_integration_microsoft_teams_tenant_based_handle/import.sh @@ -0,0 +1,2 @@ +# Tenant Based Handles can be imported using UUID, e.g. +terraform import datadog_integration_ms_teams_tenant_based_handle.testing_tenant_based_handle "90646597-5fdb-4a17-a240-647003f8c028" diff --git a/examples/resources/datadog_integration_microsoft_teams_tenant_based_handle/resource.tf b/examples/resources/datadog_integration_microsoft_teams_tenant_based_handle/resource.tf new file mode 100644 index 000000000..9a0d8b277 --- /dev/null +++ b/examples/resources/datadog_integration_microsoft_teams_tenant_based_handle/resource.tf @@ -0,0 +1,8 @@ +# Create a new integration_ms_teams_tenant_based_handle resource + +resource "datadog_integration_ms_teams_tenant_based_handle" "testing_tenant_based_handle" { + name = "sample_handle_name" + tenant_name = "sample_tenant_name" + team_name = "sample_team_name" + channel_name = "sample_channel_name" +} diff --git a/go.mod b/go.mod index 9c84c0cf8..a9ea0e387 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,7 @@ module github.com/terraform-providers/terraform-provider-datadog require ( - github.com/DataDog/datadog-api-client-go/v2 v2.33.1-0.20241114153206-4637c31fedcf + github.com/DataDog/datadog-api-client-go/v2 v2.33.1-0.20241113153831-04f32a8539e4 github.com/DataDog/dd-sdk-go-testing v0.0.0-20211116174033-1cd082e322ad github.com/Masterminds/semver/v3 v3.1.1 github.com/google/go-cmp v0.5.9 @@ -96,4 +96,4 @@ require ( google.golang.org/protobuf v1.33.0 // indirect ) -go 1.23.0 +go 1.23 diff --git a/go.sum b/go.sum index a9aac74df..32a210520 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/DataDog/datadog-api-client-go/v2 v2.33.1-0.20241114153206-4637c31fedcf h1:ev4nydbonZI3p8JrKanDp2AfK6sScWgKgPoJ9OEDvvY= -github.com/DataDog/datadog-api-client-go/v2 v2.33.1-0.20241114153206-4637c31fedcf/go.mod h1:d3tOEgUd2kfsr9uuHQdY+nXrWp4uikgTgVCPdKNK30U= +github.com/DataDog/datadog-api-client-go/v2 v2.33.1-0.20241113153831-04f32a8539e4 h1:1QSRccPmp7/Jap3EMZ27e4qDWlr5jUyy89ToVBbGyeY= +github.com/DataDog/datadog-api-client-go/v2 v2.33.1-0.20241113153831-04f32a8539e4/go.mod h1:d3tOEgUd2kfsr9uuHQdY+nXrWp4uikgTgVCPdKNK30U= github.com/DataDog/datadog-go v4.4.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v4.8.3+incompatible h1:fNGaYSuObuQb5nzeTQqowRAd9bpDIRRV4/gUtIBjh8Q= github.com/DataDog/datadog-go v4.8.3+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=