diff --git a/datadog/fwprovider/resource_datadog_application_key.go b/datadog/fwprovider/resource_datadog_application_key.go index c26fc67371..442ffa2b63 100644 --- a/datadog/fwprovider/resource_datadog_application_key.go +++ b/datadog/fwprovider/resource_datadog_application_key.go @@ -26,15 +26,17 @@ func NewApplicationKeyResource() resource.Resource { } type applicationKeyResourceModel struct { - ID types.String `tfsdk:"id"` - Name types.String `tfsdk:"name"` - Key types.String `tfsdk:"key"` - Scopes types.Set `tfsdk:"scopes"` + ID types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + Key types.String `tfsdk:"key"` + Scopes types.Set `tfsdk:"scopes"` + EnableActionsApiAccess types.Bool `tfsdk:"enable_actions_api_access"` } type applicationKeyResource struct { - Api *datadogV2.KeyManagementApi - Auth context.Context + Api *datadogV2.KeyManagementApi + ActionApi *datadogV2.ActionConnectionApi + Auth context.Context } func (r *applicationKeyResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { @@ -69,6 +71,10 @@ func (r *applicationKeyResource) Schema(_ context.Context, _ resource.SchemaRequ setvalidator.SizeAtLeast(1), }, }, + "enable_actions_api_access": schema.BoolAttribute{ + Description: "(Preview) Enable Actions API access for this application key. When true, the key will be automatically registered for use with Action Connection, App Builder, and Workflow Automation. Defaults to `false`.", + Optional: true, + }, "id": utils.ResourceIDAttribute(), }, } @@ -77,6 +83,7 @@ func (r *applicationKeyResource) Schema(_ context.Context, _ resource.SchemaRequ func (r *applicationKeyResource) Configure(_ context.Context, request resource.ConfigureRequest, response *resource.ConfigureResponse) { providerData := request.ProviderData.(*FrameworkProvider) r.Api = providerData.DatadogApiInstances.GetKeyManagementApiV2() + r.ActionApi = providerData.DatadogApiInstances.GetActionConnectionApiV2() r.Auth = providerData.Auth } @@ -100,6 +107,14 @@ func (r *applicationKeyResource) Create(ctx context.Context, request resource.Cr state.ID = types.StringValue(applicationKeyData.GetId()) r.updateState(ctx, &state, &applicationKeyData) + // Handle Actions API access registration if enabled + if !state.EnableActionsApiAccess.IsNull() && state.EnableActionsApiAccess.ValueBool() { + if err := r.registerForActionsApi(state.ID.ValueString()); err != nil { + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error registering application key for Actions API access")) + return + } + } + response.Diagnostics.Append(response.State.Set(ctx, &state)...) } @@ -124,17 +139,23 @@ func (r *applicationKeyResource) Read(ctx context.Context, request resource.Read applicationKeyData := resp.GetData() r.updateState(ctx, &state, &applicationKeyData) + // Check Actions API registration status + isRegistered := r.isRegisteredForActionsApi(state.ID.ValueString()) + state.EnableActionsApiAccess = types.BoolValue(isRegistered) + response.Diagnostics.Append(response.State.Set(ctx, &state)...) } func (r *applicationKeyResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { var state applicationKeyResourceModel - response.Diagnostics.Append(request.Plan.Get(ctx, &state)...) + var plan applicationKeyResourceModel + response.Diagnostics.Append(request.Plan.Get(ctx, &plan)...) + response.Diagnostics.Append(request.State.Get(ctx, &state)...) if response.Diagnostics.HasError() { return } - resp, _, err := r.Api.UpdateCurrentUserApplicationKey(r.Auth, state.ID.ValueString(), *r.buildDatadogApplicationKeyUpdateV2Struct(&state)) + resp, _, err := r.Api.UpdateCurrentUserApplicationKey(r.Auth, state.ID.ValueString(), *r.buildDatadogApplicationKeyUpdateV2Struct(&plan)) if err != nil { response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error updating application key")) @@ -142,10 +163,28 @@ func (r *applicationKeyResource) Update(ctx context.Context, request resource.Up } applicationKeyData := resp.GetData() - state.ID = types.StringValue(applicationKeyData.GetId()) - r.updateState(ctx, &state, &applicationKeyData) + plan.ID = types.StringValue(applicationKeyData.GetId()) + r.updateState(ctx, &plan, &applicationKeyData) + + // Handle Actions API access changes + oldEnabled := !state.EnableActionsApiAccess.IsNull() && state.EnableActionsApiAccess.ValueBool() + newEnabled := !plan.EnableActionsApiAccess.IsNull() && plan.EnableActionsApiAccess.ValueBool() + + if oldEnabled != newEnabled { + if newEnabled { + if err := r.registerForActionsApi(plan.ID.ValueString()); err != nil { + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error registering application key for Actions API access")) + return + } + } else { + if err := r.unregisterFromActionsApi(plan.ID.ValueString()); err != nil { + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error unregistering application key from Actions API access")) + return + } + } + } - response.Diagnostics.Append(response.State.Set(ctx, &state)...) + response.Diagnostics.Append(response.State.Set(ctx, &plan)...) } func (r *applicationKeyResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { @@ -155,6 +194,14 @@ func (r *applicationKeyResource) Delete(ctx context.Context, request resource.De return } + // Unregister from Actions API if registered + if !state.EnableActionsApiAccess.IsNull() && state.EnableActionsApiAccess.ValueBool() { + if err := r.unregisterFromActionsApi(state.ID.ValueString()); err != nil { + // Log warning but don't fail deletion + response.Diagnostics.AddWarning("Failed to unregister from Actions API", err.Error()) + } + } + if _, err := r.Api.DeleteCurrentUserApplicationKey(r.Auth, state.ID.ValueString()); err != nil { response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error deleting application key")) } @@ -198,3 +245,21 @@ func getScopesFromStateAttribute(scopes types.Set) []string { } return scopesList } + +// registerForActionsApi registers the application key for Actions API access +func (r *applicationKeyResource) registerForActionsApi(keyId string) error { + _, _, err := r.ActionApi.RegisterAppKey(r.Auth, keyId) + return err +} + +// unregisterFromActionsApi unregisters the application key from Actions API access +func (r *applicationKeyResource) unregisterFromActionsApi(keyId string) error { + _, err := r.ActionApi.UnregisterAppKey(r.Auth, keyId) + return err +} + +// isRegisteredForActionsApi checks if the application key is registered for Actions API access +func (r *applicationKeyResource) isRegisteredForActionsApi(keyId string) bool { + _, _, err := r.ActionApi.GetAppKeyRegistration(r.Auth, keyId) + return err == nil +} diff --git a/datadog/fwprovider/resource_datadog_service_account_application_key.go b/datadog/fwprovider/resource_datadog_service_account_application_key.go index fa78e2ada6..80558e4d6b 100644 --- a/datadog/fwprovider/resource_datadog_service_account_application_key.go +++ b/datadog/fwprovider/resource_datadog_service_account_application_key.go @@ -25,18 +25,20 @@ var ( ) type serviceAccountApplicationKeyResource struct { - Api *datadogV2.ServiceAccountsApi - Auth context.Context + Api *datadogV2.ServiceAccountsApi + ActionApi *datadogV2.ActionConnectionApi + Auth context.Context } type serviceAccountApplicationKeyModel struct { - ID types.String `tfsdk:"id"` - ServiceAccountId types.String `tfsdk:"service_account_id"` - Name types.String `tfsdk:"name"` - Key types.String `tfsdk:"key"` - CreatedAt types.String `tfsdk:"created_at"` - Last4 types.String `tfsdk:"last4"` - Scopes types.Set `tfsdk:"scopes"` + ID types.String `tfsdk:"id"` + ServiceAccountId types.String `tfsdk:"service_account_id"` + Name types.String `tfsdk:"name"` + Key types.String `tfsdk:"key"` + CreatedAt types.String `tfsdk:"created_at"` + Last4 types.String `tfsdk:"last4"` + Scopes types.Set `tfsdk:"scopes"` + EnableActionsApiAccess types.Bool `tfsdk:"enable_actions_api_access"` } func NewServiceAccountApplicationKeyResource() resource.Resource { @@ -46,6 +48,7 @@ func NewServiceAccountApplicationKeyResource() resource.Resource { func (r *serviceAccountApplicationKeyResource) Configure(_ context.Context, request resource.ConfigureRequest, response *resource.ConfigureResponse) { providerData, _ := request.ProviderData.(*FrameworkProvider) r.Api = providerData.DatadogApiInstances.GetServiceAccountsApiV2() + r.ActionApi = providerData.DatadogApiInstances.GetActionConnectionApiV2() r.Auth = providerData.Auth } @@ -76,6 +79,10 @@ func (r *serviceAccountApplicationKeyResource) Schema(_ context.Context, _ resou setvalidator.SizeAtLeast(1), }, }, + "enable_actions_api_access": schema.BoolAttribute{ + Description: "(Preview) Enable Actions API access for this service account application key. When true, the key will be automatically registered for use with Action Connection, App Builder, and Workflow Automation. Defaults to `false`.", + Optional: true, + }, "key": schema.StringAttribute{ Computed: true, Sensitive: true, @@ -136,6 +143,10 @@ func (r *serviceAccountApplicationKeyResource) Read(ctx context.Context, request r.updateStatePartialKey(ctx, &state, &resp) + // Check Actions API registration status + isRegistered := r.isRegisteredForActionsApi(state.ID.ValueString()) + state.EnableActionsApiAccess = types.BoolValue(isRegistered) + // Save data into Terraform state response.Diagnostics.Append(response.State.Set(ctx, &state)...) } @@ -166,22 +177,32 @@ func (r *serviceAccountApplicationKeyResource) Create(ctx context.Context, reque } r.updateStateFullKey(ctx, &state, &resp) + // Handle Actions API access registration if enabled + if !state.EnableActionsApiAccess.IsNull() && state.EnableActionsApiAccess.ValueBool() { + if err := r.registerForActionsApi(state.ID.ValueString()); err != nil { + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error registering service account application key for Actions API access")) + return + } + } + // Save data into Terraform state response.Diagnostics.Append(response.State.Set(ctx, &state)...) } func (r *serviceAccountApplicationKeyResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { var state serviceAccountApplicationKeyModel - response.Diagnostics.Append(request.Plan.Get(ctx, &state)...) + var plan serviceAccountApplicationKeyModel + response.Diagnostics.Append(request.Plan.Get(ctx, &plan)...) + response.Diagnostics.Append(request.State.Get(ctx, &state)...) if response.Diagnostics.HasError() { return } - serviceAccountId := state.ServiceAccountId.ValueString() + serviceAccountId := plan.ServiceAccountId.ValueString() - id := state.ID.ValueString() + id := plan.ID.ValueString() - body, diags := r.buildServiceAccountApplicationKeyUpdateRequestBody(ctx, &state) + body, diags := r.buildServiceAccountApplicationKeyUpdateRequestBody(ctx, &plan) response.Diagnostics.Append(diags...) if response.Diagnostics.HasError() { return @@ -196,10 +217,28 @@ func (r *serviceAccountApplicationKeyResource) Update(ctx context.Context, reque response.Diagnostics.AddError("response contains unparsedObject", err.Error()) return } - r.updateStatePartialKey(ctx, &state, &resp) + r.updateStatePartialKey(ctx, &plan, &resp) + + // Handle Actions API access changes + oldEnabled := !state.EnableActionsApiAccess.IsNull() && state.EnableActionsApiAccess.ValueBool() + newEnabled := !plan.EnableActionsApiAccess.IsNull() && plan.EnableActionsApiAccess.ValueBool() + + if oldEnabled != newEnabled { + if newEnabled { + if err := r.registerForActionsApi(plan.ID.ValueString()); err != nil { + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error registering service account application key for Actions API access")) + return + } + } else { + if err := r.unregisterFromActionsApi(plan.ID.ValueString()); err != nil { + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error unregistering service account application key from Actions API access")) + return + } + } + } // Save data into Terraform state - response.Diagnostics.Append(response.State.Set(ctx, &state)...) + response.Diagnostics.Append(response.State.Set(ctx, &plan)...) } func (r *serviceAccountApplicationKeyResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { @@ -212,6 +251,14 @@ func (r *serviceAccountApplicationKeyResource) Delete(ctx context.Context, reque id := state.ID.ValueString() + // Unregister from Actions API if registered + if !state.EnableActionsApiAccess.IsNull() && state.EnableActionsApiAccess.ValueBool() { + if err := r.unregisterFromActionsApi(state.ID.ValueString()); err != nil { + // Log warning but don't fail deletion + response.Diagnostics.AddWarning("Failed to unregister from Actions API", err.Error()) + } + } + httpResp, err := r.Api.DeleteServiceAccountApplicationKey(r.Auth, serviceAccountId, id) if err != nil { if httpResp != nil && httpResp.StatusCode == 404 { @@ -307,3 +354,21 @@ func (r *serviceAccountApplicationKeyResource) buildServiceAccountApplicationKey return req, diags } + +// registerForActionsApi registers the service account application key for Actions API access +func (r *serviceAccountApplicationKeyResource) registerForActionsApi(keyId string) error { + _, _, err := r.ActionApi.RegisterAppKey(r.Auth, keyId) + return err +} + +// unregisterFromActionsApi unregisters the service account application key from Actions API access +func (r *serviceAccountApplicationKeyResource) unregisterFromActionsApi(keyId string) error { + _, err := r.ActionApi.UnregisterAppKey(r.Auth, keyId) + return err +} + +// isRegisteredForActionsApi checks if the service account application key is registered for Actions API access +func (r *serviceAccountApplicationKeyResource) isRegisteredForActionsApi(keyId string) bool { + _, _, err := r.ActionApi.GetAppKeyRegistration(r.Auth, keyId) + return err == nil +} diff --git a/datadog/tests/resource_datadog_application_key_test.go b/datadog/tests/resource_datadog_application_key_test.go index 08c7193c28..40459f07b5 100644 --- a/datadog/tests/resource_datadog_application_key_test.go +++ b/datadog/tests/resource_datadog_application_key_test.go @@ -246,3 +246,72 @@ func datadogApplicationKeyDestroyHelper(ctx context.Context, s *terraform.State, return nil } + +// TestAccDatadogApplicationKey_ActionsApiAccess tests the preview Actions API access feature +func TestAccDatadogApplicationKey_ActionsApiAccess(t *testing.T) { + if isRecording() || isReplaying() { + t.Skip("This test doesn't support recording or replaying") + } + t.Parallel() + ctx, providers, accProviders := testAccFrameworkMuxProviders(context.Background(), t) + applicationKeyName := uniqueEntityName(ctx, t) + resourceName := "datadog_application_key.foo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV5ProviderFactories: accProviders, + CheckDestroy: testAccCheckDatadogApplicationKeyDestroy(providers.frameworkProvider), + Steps: []resource.TestStep{ + { + Config: testAccCheckDatadogApplicationKeyWithActionsApiAccess(applicationKeyName, true), + Check: resource.ComposeTestCheckFunc( + testAccCheckDatadogApplicationKeyExists(providers.frameworkProvider, resourceName), + resource.TestCheckResourceAttr(resourceName, "name", applicationKeyName), + resource.TestCheckResourceAttr(resourceName, "enable_actions_api_access", "true"), + resource.TestCheckResourceAttrSet(resourceName, "key"), + testAccCheckDatadogApplicationKeyActionsApiRegistered(providers.frameworkProvider, resourceName, true), + ), + }, + { + Config: testAccCheckDatadogApplicationKeyWithActionsApiAccess(applicationKeyName, false), + Check: resource.ComposeTestCheckFunc( + testAccCheckDatadogApplicationKeyExists(providers.frameworkProvider, resourceName), + resource.TestCheckResourceAttr(resourceName, "name", applicationKeyName), + resource.TestCheckResourceAttr(resourceName, "enable_actions_api_access", "false"), + resource.TestCheckResourceAttrSet(resourceName, "key"), + testAccCheckDatadogApplicationKeyActionsApiRegistered(providers.frameworkProvider, resourceName, false), + ), + }, + }, + }) +} + +func testAccCheckDatadogApplicationKeyWithActionsApiAccess(uniq string, enableActionsApi bool) string { + return fmt.Sprintf(` +resource "datadog_application_key" "foo" { + name = "%s" + enable_actions_api_access = %t +}`, uniq, enableActionsApi) +} + +func testAccCheckDatadogApplicationKeyActionsApiRegistered(accProvider *fwprovider.FrameworkProvider, n string, expectedRegistered bool) resource.TestCheckFunc { + return func(s *terraform.State) error { + apiInstances := accProvider.DatadogApiInstances + auth := accProvider.Auth + if err := datadogApplicationKeyActionsApiRegisteredHelper(auth, s, apiInstances, n, expectedRegistered); err != nil { + return err + } + return nil + } +} + +func datadogApplicationKeyActionsApiRegisteredHelper(ctx context.Context, s *terraform.State, apiInstances *utils.ApiInstances, name string, expectedRegistered bool) error { + id := s.RootModule().Resources[name].Primary.ID + _, _, err := apiInstances.GetActionConnectionApiV2().GetAppKeyRegistration(ctx, id) + isRegistered := err == nil + + if isRegistered != expectedRegistered { + return fmt.Errorf("application key Actions API registration status %t does not match expected %t", isRegistered, expectedRegistered) + } + return nil +} diff --git a/datadog/tests/resource_datadog_service_account_application_key_test.go b/datadog/tests/resource_datadog_service_account_application_key_test.go index 3d19ee4b89..a6585bbe41 100644 --- a/datadog/tests/resource_datadog_service_account_application_key_test.go +++ b/datadog/tests/resource_datadog_service_account_application_key_test.go @@ -239,3 +239,81 @@ func serviceAccountApplicationKeyExistsHelper(auth context.Context, s *terraform } return nil } + +// TestAccServiceAccountApplicationKey_ActionsApiAccess tests the preview Actions API access feature +func TestAccServiceAccountApplicationKey_ActionsApiAccess(t *testing.T) { + t.Parallel() + if isRecording() || isReplaying() { + t.Skip("This test doesn't support recording or replaying") + } + ctx, providers, accProviders := testAccFrameworkMuxProviders(context.Background(), t) + uniq := uniqueEntityName(ctx, t) + resourceName := "datadog_service_account_application_key.foo" + + resource.Test(t, resource.TestCase{ + ProtoV5ProviderFactories: accProviders, + CheckDestroy: testAccCheckDatadogServiceAccountApplicationKeyDestroy(providers.frameworkProvider), + Steps: []resource.TestStep{ + { + Config: testAccCheckDatadogServiceAccountApplicationKeyWithActionsApiAccess(uniq, true), + Check: resource.ComposeTestCheckFunc( + testAccCheckDatadogServiceAccountApplicationKeyExists(providers.frameworkProvider), + resource.TestCheckResourceAttr(resourceName, "name", uniq), + resource.TestCheckResourceAttr(resourceName, "enable_actions_api_access", "true"), + resource.TestCheckResourceAttrSet(resourceName, "key"), + resource.TestCheckResourceAttrPair( + resourceName, "service_account_id", "datadog_service_account.bar", "id"), + testAccCheckDatadogServiceAccountApplicationKeyActionsApiRegistered(providers.frameworkProvider, resourceName, true), + ), + }, + { + Config: testAccCheckDatadogServiceAccountApplicationKeyWithActionsApiAccess(uniq, false), + Check: resource.ComposeTestCheckFunc( + testAccCheckDatadogServiceAccountApplicationKeyExists(providers.frameworkProvider), + resource.TestCheckResourceAttr(resourceName, "name", uniq), + resource.TestCheckResourceAttr(resourceName, "enable_actions_api_access", "false"), + resource.TestCheckResourceAttrSet(resourceName, "key"), + resource.TestCheckResourceAttrPair( + resourceName, "service_account_id", "datadog_service_account.bar", "id"), + testAccCheckDatadogServiceAccountApplicationKeyActionsApiRegistered(providers.frameworkProvider, resourceName, false), + ), + }, + }, + }) +} + +func testAccCheckDatadogServiceAccountApplicationKeyWithActionsApiAccess(uniq string, enableActionsApi bool) string { + return fmt.Sprintf(` +resource "datadog_service_account" "bar" { + email = "new@example.com" + name = "testTerraformServiceAccountApplicationKeys" +} + +resource "datadog_service_account_application_key" "foo" { + service_account_id = datadog_service_account.bar.id + name = "%s" + enable_actions_api_access = %t +}`, uniq, enableActionsApi) +} + +func testAccCheckDatadogServiceAccountApplicationKeyActionsApiRegistered(accProvider *fwprovider.FrameworkProvider, n string, expectedRegistered bool) resource.TestCheckFunc { + return func(s *terraform.State) error { + apiInstances := accProvider.DatadogApiInstances + auth := accProvider.Auth + if err := serviceAccountApplicationKeyActionsApiRegisteredHelper(auth, s, apiInstances, n, expectedRegistered); err != nil { + return err + } + return nil + } +} + +func serviceAccountApplicationKeyActionsApiRegisteredHelper(ctx context.Context, s *terraform.State, apiInstances *utils.ApiInstances, name string, expectedRegistered bool) error { + id := s.RootModule().Resources[name].Primary.ID + _, _, err := apiInstances.GetActionConnectionApiV2().GetAppKeyRegistration(ctx, id) + isRegistered := err == nil + + if isRegistered != expectedRegistered { + return fmt.Errorf("service account application key Actions API registration status %t does not match expected %t", isRegistered, expectedRegistered) + } + return nil +} diff --git a/docs/resources/application_key.md b/docs/resources/application_key.md index 6081947ffd..b3071e7bac 100644 --- a/docs/resources/application_key.md +++ b/docs/resources/application_key.md @@ -17,6 +17,12 @@ Provides a Datadog Application Key resource. This can be used to create and mana resource "datadog_application_key" "foo" { name = "foo-application" } + +# Create a new Datadog Application Key with Actions API access (Preview) +resource "datadog_application_key" "actions_enabled" { + name = "foo-application-with-actions" + enable_actions_api_access = true +} ``` @@ -28,6 +34,7 @@ resource "datadog_application_key" "foo" { ### Optional +- `enable_actions_api_access` (Boolean) (Preview) Enable Actions API access for this application key. When true, the key will be automatically registered for use with Action Connection, App Builder, and Workflow Automation. - `scopes` (Set of String) Authorization scopes for the Application Key. Application Keys configured with no scopes have full access. ### Read-Only diff --git a/docs/resources/service_account_application_key.md b/docs/resources/service_account_application_key.md index 38e253e8f4..f29729dc6c 100644 --- a/docs/resources/service_account_application_key.md +++ b/docs/resources/service_account_application_key.md @@ -18,6 +18,13 @@ resource "datadog_service_account_application_key" "foo" { service_account_id = "00000000-0000-1234-0000-000000000000" name = "Application key for managing dashboards" } + +# Create new service_account_application_key resource with Actions API access (Preview) +resource "datadog_service_account_application_key" "actions_enabled" { + service_account_id = "00000000-0000-1234-0000-000000000000" + name = "Application key for managing dashboards with Actions API" + enable_actions_api_access = true +} ``` @@ -30,6 +37,7 @@ resource "datadog_service_account_application_key" "foo" { ### Optional +- `enable_actions_api_access` (Boolean) (Preview) Enable Actions API access for this service account application key. When true, the key will be automatically registered for use with Action Connection, App Builder, and Workflow Automation. - `scopes` (Set of String) Authorization scopes for the Application Key. Application Keys configured with no scopes have full access. ### Read-Only diff --git a/examples/resources/datadog_application_key/resource.tf b/examples/resources/datadog_application_key/resource.tf index 13a971474b..12679b664d 100644 --- a/examples/resources/datadog_application_key/resource.tf +++ b/examples/resources/datadog_application_key/resource.tf @@ -2,3 +2,9 @@ resource "datadog_application_key" "foo" { name = "foo-application" } + +# Create a new Datadog Application Key with Actions API access (Preview) +resource "datadog_application_key" "actions_enabled" { + name = "foo-application-with-actions" + enable_actions_api_access = true +} diff --git a/examples/resources/datadog_service_account_application_key/resource.tf b/examples/resources/datadog_service_account_application_key/resource.tf index 8f35702bb1..dc6e639da3 100644 --- a/examples/resources/datadog_service_account_application_key/resource.tf +++ b/examples/resources/datadog_service_account_application_key/resource.tf @@ -2,4 +2,11 @@ resource "datadog_service_account_application_key" "foo" { service_account_id = "00000000-0000-1234-0000-000000000000" name = "Application key for managing dashboards" +} + +# Create new service_account_application_key resource with Actions API access (Preview) +resource "datadog_service_account_application_key" "actions_enabled" { + service_account_id = "00000000-0000-1234-0000-000000000000" + name = "Application key for managing dashboards with Actions API" + enable_actions_api_access = true } \ No newline at end of file diff --git a/go.mod b/go.mod index aae638079f..125f0e15b4 100644 --- a/go.mod +++ b/go.mod @@ -85,16 +85,16 @@ require ( github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/zclconf/go-cty v1.16.3 // indirect - golang.org/x/crypto v0.38.0 // indirect + golang.org/x/crypto v0.42.0 // indirect golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect - golang.org/x/mod v0.24.0 // indirect - golang.org/x/net v0.40.0 // indirect + golang.org/x/mod v0.28.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.14.0 // indirect - golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.25.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/text v0.29.0 // indirect golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect - golang.org/x/tools v0.33.0 // indirect + golang.org/x/tools v0.37.0 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect @@ -102,4 +102,6 @@ require ( google.golang.org/protobuf v1.36.6 // indirect ) -go 1.23.0 +go 1.24.0 + +toolchain go1.24.1 diff --git a/go.sum b/go.sum index 01892eb9cf..34ef6785c9 100644 --- a/go.sum +++ b/go.sum @@ -305,8 +305,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= @@ -315,8 +315,8 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -327,8 +327,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= @@ -337,8 +337,8 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -357,8 +357,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -367,8 +367,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 h1:GZokNIeuVkl3aZHJchRrr13WCsols02MLUcz1U9is6M= golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -380,8 +380,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= -golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=