From 3d82d94691a029e19bdec358ee13d5b80057beaf Mon Sep 17 00:00:00 2001 From: Estelle Soulard Date: Mon, 15 Dec 2025 17:32:56 +0100 Subject: [PATCH] feat(keymanager): add encrypt ephemeral resource --- docs/actions/key_manager_key_rotate_action.md | 2 +- .../keymanager/action_rotate_key_action.go | 7 +- .../keymanager/encrypt_ephemeral_resource.go | 181 +++++ .../encrypt_ephemeral_resource_test.go | 55 ++ ...ypt-ephemeral-resource-basic.cassette.yaml | 757 ++++++++++++++++++ provider/framework.go | 7 +- 6 files changed, 1006 insertions(+), 3 deletions(-) create mode 100644 internal/services/keymanager/encrypt_ephemeral_resource.go create mode 100644 internal/services/keymanager/encrypt_ephemeral_resource_test.go create mode 100644 internal/services/keymanager/testdata/encrypt-ephemeral-resource-basic.cassette.yaml diff --git a/docs/actions/key_manager_key_rotate_action.md b/docs/actions/key_manager_key_rotate_action.md index 0ab6586e37..3c1a562e7e 100644 --- a/docs/actions/key_manager_key_rotate_action.md +++ b/docs/actions/key_manager_key_rotate_action.md @@ -10,7 +10,7 @@ page_title: "Scaleway: scaleway_key_manager_key_rotate_action" ### Required -- `key_id` (String) ID of the key to rotate (UUID format) +- `key_id` (String) ID of the key to rotate. Can be a plain UUID or a regional ID. ### Optional diff --git a/internal/services/keymanager/action_rotate_key_action.go b/internal/services/keymanager/action_rotate_key_action.go index b6535cf184..b034e4eeaa 100644 --- a/internal/services/keymanager/action_rotate_key_action.go +++ b/internal/services/keymanager/action_rotate_key_action.go @@ -6,12 +6,14 @@ import ( "github.com/hashicorp/terraform-plugin-framework/action" "github.com/hashicorp/terraform-plugin-framework/action/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" key_manager "github.com/scaleway/scaleway-sdk-go/api/key_manager/v1alpha1" "github.com/scaleway/scaleway-sdk-go/scw" "github.com/scaleway/terraform-provider-scaleway/v2/internal/locality" "github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional" "github.com/scaleway/terraform-provider-scaleway/v2/internal/meta" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/verify" ) var ( @@ -66,7 +68,10 @@ func (a *RotateKeyAction) Schema(ctx context.Context, req action.SchemaRequest, }, "key_id": schema.StringAttribute{ Required: true, - Description: "ID of the key to rotate (UUID format)", + Description: "ID of the key to rotate. Can be a plain UUID or a regional ID.", + Validators: []validator.String{ + verify.IsStringUUIDOrUUIDWithLocality(), + }, }, }, } diff --git a/internal/services/keymanager/encrypt_ephemeral_resource.go b/internal/services/keymanager/encrypt_ephemeral_resource.go new file mode 100644 index 0000000000..e84fda9687 --- /dev/null +++ b/internal/services/keymanager/encrypt_ephemeral_resource.go @@ -0,0 +1,181 @@ +package keymanager + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/ephemeral" + "github.com/hashicorp/terraform-plugin-framework/ephemeral/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + key_manager "github.com/scaleway/scaleway-sdk-go/api/key_manager/v1alpha1" + "github.com/scaleway/scaleway-sdk-go/scw" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/locality" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/meta" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/verify" +) + +var ( + _ ephemeral.EphemeralResource = (*EncryptEphemeralResource)(nil) + _ ephemeral.EphemeralResourceWithConfigure = (*EncryptEphemeralResource)(nil) +) + +type EncryptEphemeralResource struct { + keyManagerAPI *key_manager.API + meta *meta.Meta +} + +func NewEncryptEphemeralResource() ephemeral.EphemeralResource { + return &EncryptEphemeralResource{} +} + +func (r *EncryptEphemeralResource) Configure(ctx context.Context, req ephemeral.ConfigureRequest, resp *ephemeral.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + m, ok := req.ProviderData.(*meta.Meta) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Ephemeral Resource Configure Type", + fmt.Sprintf("Expected *meta.Meta, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + client := m.ScwClient() + r.keyManagerAPI = key_manager.NewAPI(client) + r.meta = m +} + +func (r *EncryptEphemeralResource) Metadata(ctx context.Context, req ephemeral.MetadataRequest, resp *ephemeral.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_key_manager_encrypt" +} + +type EncryptEphemeralResourceModel struct { + Region types.String `tfsdk:"region"` + KeyID types.String `tfsdk:"key_id"` + Plaintext types.String `tfsdk:"plaintext"` + AssociatedData types.Object `tfsdk:"associated_data"` + // Output + Ciphertext types.String `tfsdk:"ciphertext"` +} + +type AssociatedDataModel struct { + Value types.String `tfsdk:"value"` +} + +func (r *EncryptEphemeralResource) Schema(ctx context.Context, req ephemeral.SchemaRequest, resp *ephemeral.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "region": regional.SchemaAttribute("Region of the key. If not set, the region is derived from the key_id when possible or from the provider configuration."), + "key_id": schema.StringAttribute{ + Required: true, + Description: "ID of the key to use for encryption. Can be a plain UUID or a regional ID.", + Validators: []validator.String{ + verify.IsStringUUIDOrUUIDWithLocality(), + }, + }, + "plaintext": schema.StringAttribute{ + Required: true, + Description: "Plaintext data to encrypt. Data size must be between 1 and 65535 bytes.", + Sensitive: true, + }, + "associated_data": schema.ObjectAttribute{ + Optional: true, + Description: "Additional authenticated data. Additional data which will not be encrypted, but authenticated and appended to the encrypted payload. Only supported by keys with a usage set to `symmetric_encryption`.", + AttributeTypes: map[string]attr.Type{ + "value": types.StringType, + }, + }, + "ciphertext": schema.StringAttribute{ + Computed: true, + Description: "Key's encrypted data.", + }, + }, + } +} + +func (r *EncryptEphemeralResource) Open(ctx context.Context, req ephemeral.OpenRequest, resp *ephemeral.OpenResponse) { + var data EncryptEphemeralResourceModel + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + if r.keyManagerAPI == nil { + resp.Diagnostics.AddError( + "Unconfigured keymanagerAPI", + "The ephemeral resource was not properly configured. The Scaleway client is missing. "+ + "This is usually a bug in the provider. Please report it to the maintainers.", + ) + return + } + + keyID := locality.ExpandID(data.KeyID.ValueString()) + plaintext := data.Plaintext.ValueString() + + var region scw.Region + var err error + + if !data.Region.IsNull() && data.Region.ValueString() != "" { + region = scw.Region(data.Region.ValueString()) + } else { + // Try to derive region from the key_id if it is a regional ID + if derivedRegion, id, parseErr := regional.ParseID(keyID); parseErr == nil { + region = derivedRegion + keyID = id + } else { + // Use default region from provider configuration + defaultRegion, exists := r.meta.ScwClient().GetDefaultRegion() + if !exists { + resp.Diagnostics.AddError( + "Missing region", + "The region attribute is required to encrypt with a key. Please provide it explicitly or configure a default region in the provider.", + ) + return + } + region = defaultRegion + } + } + + var associatedData []byte + + if !data.AssociatedData.IsNull() && !data.AssociatedData.IsUnknown() { + var assocDataModel AssociatedDataModel + diags := data.AssociatedData.As(ctx, &assocDataModel, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + }) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + associatedData = []byte(assocDataModel.Value.ValueString()) + } + + encryptReq := &key_manager.EncryptRequest{ + Region: region, + KeyID: keyID, + Plaintext: []byte(plaintext), + AssociatedData: &associatedData, + } + + encryptResp, err := r.keyManagerAPI.Encrypt(encryptReq) + if err != nil { + resp.Diagnostics.AddError( + "Error executing Key Manager Encrypt action", + fmt.Sprintf("%s", err), + ) + return + } + + data.Ciphertext = types.StringValue(string(encryptResp.Ciphertext)) + + resp.Result.Set(ctx, &data) +} diff --git a/internal/services/keymanager/encrypt_ephemeral_resource_test.go b/internal/services/keymanager/encrypt_ephemeral_resource_test.go new file mode 100644 index 0000000000..6c61fa0e16 --- /dev/null +++ b/internal/services/keymanager/encrypt_ephemeral_resource_test.go @@ -0,0 +1,55 @@ +package keymanager_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest" +) + +func TestAccEncryptEphemeralResource_Basic(t *testing.T) { + tt := acctest.NewTestTools(t) + defer tt.Cleanup() + + resource.ParallelTest(t, resource.TestCase{ + ProtoV6ProviderFactories: tt.ProviderFactories, + Steps: []resource.TestStep{ + { + Config: ` + resource "scaleway_key_manager_key" "test_key" { + name = "tf-test-encrypt-key" + region = "fr-par" + usage = "symmetric_encryption" + algorithm = "aes_256_gcm" + unprotected = true + } + + ephemeral "scaleway_key_manager_encrypt" "test_encrypt" { + key_id = scaleway_key_manager_key.test_key.id + plaintext = "test plaintext data" + region = "fr-par" + } + + resource "scaleway_secret" "main" { + name = "test-encrypted-secret" + } + + resource "scaleway_secret_version" "v1" { + description = "version1" + secret_id = scaleway_secret.main.id + data_wo = ephemeral.scaleway_key_manager_encrypt.test_encrypt.ciphertext + } + + data "scaleway_secret_version" "data_v1" { + secret_id = scaleway_secret.main.id + revision = "1" + depends_on = [scaleway_secret_version.v1] + } + `, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.scaleway_secret_version.data_v1", "data"), + ), + }, + }, + }) +} diff --git a/internal/services/keymanager/testdata/encrypt-ephemeral-resource-basic.cassette.yaml b/internal/services/keymanager/testdata/encrypt-ephemeral-resource-basic.cassette.yaml new file mode 100644 index 0000000000..fa56268a6c --- /dev/null +++ b/internal/services/keymanager/testdata/encrypt-ephemeral-resource-basic.cassette.yaml @@ -0,0 +1,757 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 141 + host: api.scaleway.com + body: '{"project_id":"57a1e028-d7d3-4a4e-80cf-52cef8fd0d3e","name":"test-encrypted-secret","tags":null,"type":"opaque","path":"/","protected":false}' + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 452 + body: '{"id":"cf7d3ab3-b033-4e6e-8239-e24cf3c9b270", "project_id":"57a1e028-d7d3-4a4e-80cf-52cef8fd0d3e", "name":"test-encrypted-secret", "status":"ready", "created_at":"2025-12-15T14:29:47.882504Z", "updated_at":"2025-12-15T14:29:47.882504Z", "tags":[], "version_count":0, "description":"", "managed":false, "type":"opaque", "protected":false, "path":"/", "ephemeral_policy":null, "used_by":[], "deletion_requested_at":null, "key_id":null, "region":"fr-par"}' + headers: + Content-Length: + - "452" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:47 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - a0fce4f0-7312-409c-99ea-91f90cac23ef + status: 200 OK + code: 200 + duration: 331.588211ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 186 + host: api.scaleway.com + body: '{"project_id":"57a1e028-d7d3-4a4e-80cf-52cef8fd0d3e","name":"tf-test-encrypt-key","usage":{"symmetric_encryption":"aes_256_gcm"},"tags":null,"unprotected":true,"origin":"unknown_origin"}' + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/key-manager/v1alpha1/regions/fr-par/keys + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 511 + body: '{"id":"f6f804cd-4722-4bd2-b8b7-64e7166cbf80", "project_id":"57a1e028-d7d3-4a4e-80cf-52cef8fd0d3e", "name":"tf-test-encrypt-key", "usage":{"symmetric_encryption":"aes_256_gcm"}, "state":"enabled", "rotation_count":1, "created_at":"2025-12-15T14:29:47.933710Z", "updated_at":"2025-12-15T14:29:47.937926Z", "protected":false, "locked":false, "description":null, "tags":[], "rotated_at":"2025-12-15T14:29:47.937926Z", "rotation_policy":null, "origin":"scaleway_kms", "deletion_requested_at":null, "region":"fr-par"}' + headers: + Content-Length: + - "511" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:47 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - 53fe311a-3027-40c3-88da-c28d6a727863 + status: 200 OK + code: 200 + duration: 383.565018ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 452 + body: '{"id":"cf7d3ab3-b033-4e6e-8239-e24cf3c9b270", "project_id":"57a1e028-d7d3-4a4e-80cf-52cef8fd0d3e", "name":"test-encrypted-secret", "status":"ready", "created_at":"2025-12-15T14:29:47.882504Z", "updated_at":"2025-12-15T14:29:47.882504Z", "tags":[], "version_count":0, "description":"", "managed":false, "type":"opaque", "protected":false, "path":"/", "ephemeral_policy":null, "used_by":[], "deletion_requested_at":null, "key_id":null, "region":"fr-par"}' + headers: + Content-Length: + - "452" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:48 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - 7de12ca5-0971-4690-a280-308fc374c01e + status: 200 OK + code: 200 + duration: 60.357163ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/key-manager/v1alpha1/regions/fr-par/keys/f6f804cd-4722-4bd2-b8b7-64e7166cbf80 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 511 + body: '{"id":"f6f804cd-4722-4bd2-b8b7-64e7166cbf80", "project_id":"57a1e028-d7d3-4a4e-80cf-52cef8fd0d3e", "name":"tf-test-encrypt-key", "usage":{"symmetric_encryption":"aes_256_gcm"}, "state":"enabled", "rotation_count":1, "created_at":"2025-12-15T14:29:47.933710Z", "updated_at":"2025-12-15T14:29:47.937926Z", "protected":false, "locked":false, "description":null, "tags":[], "rotated_at":"2025-12-15T14:29:47.937926Z", "rotation_policy":null, "origin":"scaleway_kms", "deletion_requested_at":null, "region":"fr-par"}' + headers: + Content-Length: + - "511" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:48 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - 4aa4fdaa-1cdc-4d5a-ab69-a830d14202ff + status: 200 OK + code: 200 + duration: 59.016989ms + - id: 4 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + form: + page: + - "1" + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270/versions?page=1 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 32 + body: '{"versions":[], "total_count":0}' + headers: + Content-Length: + - "32" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:48 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - e3d27709-9262-416d-afbb-8aa59922945e + status: 200 OK + code: 200 + duration: 34.266427ms + - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 67 + host: api.scaleway.com + body: '{"plaintext":"dGVzdCBwbGFpbnRleHQgZGF0YQ==","associated_data":null}' + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/key-manager/v1alpha1/regions/fr-par/keys/f6f804cd-4722-4bd2-b8b7-64e7166cbf80/encrypt + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 138 + body: '{"key_id":"f6f804cd-4722-4bd2-b8b7-64e7166cbf80", "ciphertext":"AQAAAAF4rQLGkdpQUMB95oQPOeoB+HOTHhp+m890ajVhGAw8YfIlUp0ma+I+rp6ZrvImgQ=="}' + headers: + Content-Length: + - "138" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:48 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - 2d358a2a-9654-481c-915d-4a9ec64eb729 + status: 200 OK + code: 200 + duration: 89.147218ms + - id: 6 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 156 + host: api.scaleway.com + body: '{"data":"AQAAAAF477+9AsaR77+9UFDvv71977+977+9Dznvv70B77+9c++/vR4afu+/ve+/vXRqNWEYDDxh77+9JVLvv70ma++/vT7vv73vv73vv73vv73vv70m77+9","description":"version1"}' + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270/versions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 312 + body: '{"revision":1, "secret_id":"cf7d3ab3-b033-4e6e-8239-e24cf3c9b270", "status":"enabled", "created_at":"2025-12-15T14:29:48.412399Z", "updated_at":"2025-12-15T14:29:48.412399Z", "deleted_at":null, "description":"version1", "latest":true, "ephemeral_properties":null, "deletion_requested_at":null, "region":"fr-par"}' + headers: + Content-Length: + - "312" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:48 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - 3e56353f-0795-424a-a099-ab9c7e6df458 + status: 200 OK + code: 200 + duration: 327.207676ms + - id: 7 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270/versions/1 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 312 + body: '{"revision":1, "secret_id":"cf7d3ab3-b033-4e6e-8239-e24cf3c9b270", "status":"enabled", "created_at":"2025-12-15T14:29:48.412399Z", "updated_at":"2025-12-15T14:29:48.412399Z", "deleted_at":null, "description":"version1", "latest":true, "ephemeral_properties":null, "deletion_requested_at":null, "region":"fr-par"}' + headers: + Content-Length: + - "312" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:48 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - a74a8447-f8fe-49ed-8d8a-f653a038f94d + status: 200 OK + code: 200 + duration: 81.802663ms + - id: 8 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270/versions/1/access + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 233 + body: '{"secret_id":"cf7d3ab3-b033-4e6e-8239-e24cf3c9b270", "revision":1, "data":"AQAAAAF477+9AsaR77+9UFDvv71977+977+9Dznvv70B77+9c++/vR4afu+/ve+/vXRqNWEYDDxh77+9JVLvv70ma++/vT7vv73vv73vv73vv73vv70m77+9", "data_crc32":null, "type":"opaque"}' + headers: + Content-Length: + - "233" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:48 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - f9892f34-4d72-4807-9397-68840169f409 + status: 200 OK + code: 200 + duration: 191.335545ms + - id: 9 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270/versions/1 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 312 + body: '{"revision":1, "secret_id":"cf7d3ab3-b033-4e6e-8239-e24cf3c9b270", "status":"enabled", "created_at":"2025-12-15T14:29:48.412399Z", "updated_at":"2025-12-15T14:29:48.412399Z", "deleted_at":null, "description":"version1", "latest":true, "ephemeral_properties":null, "deletion_requested_at":null, "region":"fr-par"}' + headers: + Content-Length: + - "312" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:48 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - 84eefdd9-926c-46f7-8ee4-c1950041e9a2 + status: 200 OK + code: 200 + duration: 76.614739ms + - id: 10 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 67 + host: api.scaleway.com + body: '{"plaintext":"dGVzdCBwbGFpbnRleHQgZGF0YQ==","associated_data":null}' + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/key-manager/v1alpha1/regions/fr-par/keys/f6f804cd-4722-4bd2-b8b7-64e7166cbf80/encrypt + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 138 + body: '{"key_id":"f6f804cd-4722-4bd2-b8b7-64e7166cbf80", "ciphertext":"AQAAAAG7rT5izVGOH3+ADh42C9BRhU8s8LxkztbKspcopJ1EBTglqD3tH9/NNJJIVRFknQ=="}' + headers: + Content-Length: + - "138" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:48 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - 4d95cd67-6547-4152-bbde-4dc94a62b32d + status: 200 OK + code: 200 + duration: 341.510191ms + - id: 11 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270/versions/1/access + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 233 + body: '{"secret_id":"cf7d3ab3-b033-4e6e-8239-e24cf3c9b270", "revision":1, "data":"AQAAAAF477+9AsaR77+9UFDvv71977+977+9Dznvv70B77+9c++/vR4afu+/ve+/vXRqNWEYDDxh77+9JVLvv70ma++/vT7vv73vv73vv73vv73vv70m77+9", "data_crc32":null, "type":"opaque"}' + headers: + Content-Length: + - "233" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:49 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - 79404e4a-7d31-483f-bde6-21babdcda3e6 + status: 200 OK + code: 200 + duration: 164.287782ms + - id: 12 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270/versions/1 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 312 + body: '{"revision":1, "secret_id":"cf7d3ab3-b033-4e6e-8239-e24cf3c9b270", "status":"enabled", "created_at":"2025-12-15T14:29:48.412399Z", "updated_at":"2025-12-15T14:29:48.412399Z", "deleted_at":null, "description":"version1", "latest":true, "ephemeral_properties":null, "deletion_requested_at":null, "region":"fr-par"}' + headers: + Content-Length: + - "312" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:49 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - e65b01fc-a2d3-49f2-b6b8-e6abc9b406b7 + status: 200 OK + code: 200 + duration: 80.241376ms + - id: 13 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/key-manager/v1alpha1/regions/fr-par/keys/f6f804cd-4722-4bd2-b8b7-64e7166cbf80 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 511 + body: '{"id":"f6f804cd-4722-4bd2-b8b7-64e7166cbf80", "project_id":"57a1e028-d7d3-4a4e-80cf-52cef8fd0d3e", "name":"tf-test-encrypt-key", "usage":{"symmetric_encryption":"aes_256_gcm"}, "state":"enabled", "rotation_count":1, "created_at":"2025-12-15T14:29:47.933710Z", "updated_at":"2025-12-15T14:29:47.937926Z", "protected":false, "locked":false, "description":null, "tags":[], "rotated_at":"2025-12-15T14:29:47.937926Z", "rotation_policy":null, "origin":"scaleway_kms", "deletion_requested_at":null, "region":"fr-par"}' + headers: + Content-Length: + - "511" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:49 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - bd1bf47e-d14f-4673-8fe7-3eac7a6b9970 + status: 200 OK + code: 200 + duration: 191.682725ms + - id: 14 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 452 + body: '{"id":"cf7d3ab3-b033-4e6e-8239-e24cf3c9b270", "project_id":"57a1e028-d7d3-4a4e-80cf-52cef8fd0d3e", "name":"test-encrypted-secret", "status":"ready", "created_at":"2025-12-15T14:29:47.882504Z", "updated_at":"2025-12-15T14:29:47.882504Z", "tags":[], "version_count":1, "description":"", "managed":false, "type":"opaque", "protected":false, "path":"/", "ephemeral_policy":null, "used_by":[], "deletion_requested_at":null, "key_id":null, "region":"fr-par"}' + headers: + Content-Length: + - "452" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:49 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - c960a1fc-c667-4a65-99fe-814c42cbc083 + status: 200 OK + code: 200 + duration: 284.618392ms + - id: 15 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 67 + host: api.scaleway.com + body: '{"plaintext":"dGVzdCBwbGFpbnRleHQgZGF0YQ==","associated_data":null}' + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/key-manager/v1alpha1/regions/fr-par/keys/f6f804cd-4722-4bd2-b8b7-64e7166cbf80/encrypt + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 138 + body: '{"key_id":"f6f804cd-4722-4bd2-b8b7-64e7166cbf80", "ciphertext":"AQAAAAEslpmwmWYdKV39709pfuncx20QKlj/FrQ8ouL/PbbxCVLhW8MUJbawb37m075qyQ=="}' + headers: + Content-Length: + - "138" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:50 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - b13fafec-7046-4ff0-b223-505ad9654460 + status: 200 OK + code: 200 + duration: 179.410625ms + - id: 16 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + form: + page: + - "1" + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270/versions?page=1 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 344 + body: '{"versions":[{"revision":1, "secret_id":"cf7d3ab3-b033-4e6e-8239-e24cf3c9b270", "status":"enabled", "created_at":"2025-12-15T14:29:48.412399Z", "updated_at":"2025-12-15T14:29:48.412399Z", "deleted_at":null, "description":"version1", "latest":true, "ephemeral_properties":null, "deletion_requested_at":null, "region":"fr-par"}], "total_count":1}' + headers: + Content-Length: + - "344" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:50 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - dc5343e2-0c5a-4b1d-942e-02dbd816f881 + status: 200 OK + code: 200 + duration: 474.794851ms + - id: 17 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270/versions/1 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 312 + body: '{"revision":1, "secret_id":"cf7d3ab3-b033-4e6e-8239-e24cf3c9b270", "status":"enabled", "created_at":"2025-12-15T14:29:48.412399Z", "updated_at":"2025-12-15T14:29:48.412399Z", "deleted_at":null, "description":"version1", "latest":true, "ephemeral_properties":null, "deletion_requested_at":null, "region":"fr-par"}' + headers: + Content-Length: + - "312" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:50 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - 51b072d6-4fcf-47e0-9e83-d4e9155ab4d3 + status: 200 OK + code: 200 + duration: 66.374712ms + - id: 18 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270/versions/1/access + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 233 + body: '{"secret_id":"cf7d3ab3-b033-4e6e-8239-e24cf3c9b270", "revision":1, "data":"AQAAAAF477+9AsaR77+9UFDvv71977+977+9Dznvv70B77+9c++/vR4afu+/ve+/vXRqNWEYDDxh77+9JVLvv70ma++/vT7vv73vv73vv73vv73vv70m77+9", "data_crc32":null, "type":"opaque"}' + headers: + Content-Length: + - "233" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:50 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - 1648c673-64de-4162-b292-a77f9e7027fd + status: 200 OK + code: 200 + duration: 136.26768ms + - id: 19 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270/versions/1 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 312 + body: '{"revision":1, "secret_id":"cf7d3ab3-b033-4e6e-8239-e24cf3c9b270", "status":"enabled", "created_at":"2025-12-15T14:29:48.412399Z", "updated_at":"2025-12-15T14:29:48.412399Z", "deleted_at":null, "description":"version1", "latest":true, "ephemeral_properties":null, "deletion_requested_at":null, "region":"fr-par"}' + headers: + Content-Length: + - "312" + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:50 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - 4bbb3309-1b6a-4456-a2eb-699e950d55eb + status: 200 OK + code: 200 + duration: 368.781243ms + - id: 20 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270/versions/1 + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 0 + body: "" + headers: + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:51 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - fbc7c247-bba7-4fb7-90c1-ba4009c9c1e7 + status: 204 No Content + code: 204 + duration: 126.161773ms + - id: 21 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/secret-manager/v1beta1/regions/fr-par/secrets/cf7d3ab3-b033-4e6e-8239-e24cf3c9b270 + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 0 + body: "" + headers: + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:51 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - 267b091e-8e7b-473b-90ff-53a585141d7d + status: 204 No Content + code: 204 + duration: 390.524988ms + - id: 22 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + host: api.scaleway.com + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.5; linux; amd64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/key-manager/v1alpha1/regions/fr-par/keys/f6f804cd-4722-4bd2-b8b7-64e7166cbf80 + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: 0 + body: "" + headers: + Content-Type: + - application/json + Date: + - Mon, 15 Dec 2025 14:29:51 GMT + Server: + - Scaleway API Gateway (fr-par-1;edge03) + X-Request-Id: + - 87ff3d03-11fe-42b1-990d-273dee216cdd + status: 204 No Content + code: 204 + duration: 909.994562ms diff --git a/provider/framework.go b/provider/framework.go index 486a2f5747..1c19045568 100644 --- a/provider/framework.go +++ b/provider/framework.go @@ -124,6 +124,7 @@ func (p *ScalewayProvider) Configure(ctx context.Context, req provider.Configure resp.ResourceData = m resp.DataSourceData = m resp.ActionData = m + resp.EphemeralResourceData = m } func (p *ScalewayProvider) Resources(ctx context.Context) []func() resource.Resource { @@ -131,7 +132,11 @@ func (p *ScalewayProvider) Resources(ctx context.Context) []func() resource.Reso } func (p *ScalewayProvider) EphemeralResources(_ context.Context) []func() ephemeral.EphemeralResource { - return []func() ephemeral.EphemeralResource{} + var res []func() ephemeral.EphemeralResource + + res = append(res, keymanager.NewEncryptEphemeralResource) + + return res } func (p *ScalewayProvider) DataSources(_ context.Context) []func() datasource.DataSource {