From 35c5888351cac44ce73ef02b9bff7a89de791f03 Mon Sep 17 00:00:00 2001 From: wuxu92 Date: Thu, 31 Oct 2024 11:41:12 +0800 Subject: [PATCH] add data source for managed hsm key --- ...dware_security_module_key_data_resource.go | 180 ++++++++++++++++++ ..._security_module_key_data_resource_test.go | 41 ++++ ..._hardware_security_module_resource_test.go | 1 + internal/services/managedhsm/registration.go | 1 + ...hardware_security_module_key.html.markdown | 64 +++++++ 5 files changed, 287 insertions(+) create mode 100644 internal/services/managedhsm/key_vault_managed_hardware_security_module_key_data_resource.go create mode 100644 internal/services/managedhsm/key_vault_managed_hardware_security_module_key_data_resource_test.go create mode 100644 website/docs/d/key_vault_managed_hardware_security_module_key.html.markdown diff --git a/internal/services/managedhsm/key_vault_managed_hardware_security_module_key_data_resource.go b/internal/services/managedhsm/key_vault_managed_hardware_security_module_key_data_resource.go new file mode 100644 index 000000000000..ad7b4beada45 --- /dev/null +++ b/internal/services/managedhsm/key_vault_managed_hardware_security_module_key_data_resource.go @@ -0,0 +1,180 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package managedhsm + +import ( + "context" + "encoding/base64" + "fmt" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-sdk/resource-manager/keyvault/2023-07-01/managedhsms" + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/managedhsm/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/tags" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" +) + +type KeyVaultMHSMKeyDataSourceModel struct { + ManagedHSMID string `tfschema:"managed_hsm_id"` + Name string `tfschema:"name"` + KeyType string `tfschema:"key_type"` + KeyOpts []string `tfschema:"key_opts"` + KeySize int64 `tfschema:"key_size"` + Curve string `tfschema:"curve"` + NotBeforeDate string `tfschema:"not_before_date"` + ExpirationDate string `tfschema:"expiration_date"` + Tags map[string]interface{} `tfschema:"tags"` + VersionedId string `tfschema:"versioned_id"` + Version string `tfschema:"version"` +} + +type KeyvaultMHSMKeyDataSource struct{} + +// Arguments implements sdk.DataSource. +func (k KeyvaultMHSMKeyDataSource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "name": { + ForceNew: true, + Required: true, + Type: pluginsdk.TypeString, + }, + "managed_hsm_id": { + Type: pluginsdk.TypeString, + ForceNew: true, + Required: true, + ValidateFunc: managedhsms.ValidateManagedHSMID, + }, + } +} + +// Attributes implements sdk.DataSource. +func (k KeyvaultMHSMKeyDataSource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "key_type": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "key_size": { + Type: pluginsdk.TypeInt, + Computed: true, + }, + + "curve": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "version": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "key_opts": { + Type: pluginsdk.TypeList, + Computed: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "not_before_date": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "expiration_date": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "versioned_id": { + Computed: true, + Type: pluginsdk.TypeString, + }, + + "tags": tags.SchemaDataSource(), + } +} + +func (k KeyvaultMHSMKeyDataSource) ModelObject() interface{} { + return &KeyVaultMHSMKeyDataSourceModel{} +} + +func (k KeyvaultMHSMKeyDataSource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: time.Minute * 5, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.ManagedHSMs.DataPlaneRoleDefinitionsClient + domainSuffix, ok := metadata.Client.Account.Environment.ManagedHSM.DomainSuffix() + if !ok { + return fmt.Errorf("could not determine Managed HSM domain suffix for environment %q", metadata.Client.Account.Environment.Name) + } + + var config KeyVaultMHSMKeyDataSourceModel + if err := metadata.Decode(&config); err != nil { + return err + } + + managedHsmId, err := managedhsms.ParseManagedHSMID(config.ManagedHSMID) + if err != nil { + return err + } + id := parse.NewManagedHSMDataPlaneVersionlessKeyID(managedHsmId.ManagedHSMName, *domainSuffix, config.Name) + + resp, err := client.GetKey(ctx, id.BaseUri(), id.KeyName, "") + if err != nil { + if response.WasNotFound(resp.Response.Response) { + return fmt.Errorf("key %q not found", config.Name) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + + if key := resp.Key; key != nil { + config.Name = id.KeyName + config.ManagedHSMID = managedHsmId.ID() + config.KeyType = string(key.Kty) + config.KeyOpts = flattenKeyVaultKeyOptions(key.KeyOps) + config.Curve = string(key.Crv) + config.Tags = tags.Flatten(resp.Tags) + + versionedID, err := parse.ManagedHSMDataPlaneVersionedKeyID(*key.Kid, domainSuffix) + if err != nil { + return fmt.Errorf("parsing versioned ID: %+v", err) + } + config.VersionedId = versionedID.ID() + config.Version = versionedID.KeyVersion + + if key.N != nil { + nBytes, err := base64.RawURLEncoding.DecodeString(*key.N) + if err != nil { + return fmt.Errorf("could not decode N: %+v", err) + } + config.KeySize = int64(len(nBytes) * 8) + } + + if attributes := resp.Attributes; attributes != nil { + if v := attributes.NotBefore; v != nil { + config.NotBeforeDate = time.Time(*v).Format(time.RFC3339) + } + + if v := attributes.Expires; v != nil { + config.ExpirationDate = time.Time(*v).Format(time.RFC3339) + } + } + } + + metadata.SetID(id) + return metadata.Encode(&config) + }, + } +} + +func (k KeyvaultMHSMKeyDataSource) ResourceType() string { + return "azurerm_key_vault_managed_hardware_security_module_key" +} + +var _ sdk.DataSource = KeyvaultMHSMKeyDataSource{} diff --git a/internal/services/managedhsm/key_vault_managed_hardware_security_module_key_data_resource_test.go b/internal/services/managedhsm/key_vault_managed_hardware_security_module_key_data_resource_test.go new file mode 100644 index 000000000000..b8fc5c2c2683 --- /dev/null +++ b/internal/services/managedhsm/key_vault_managed_hardware_security_module_key_data_resource_test.go @@ -0,0 +1,41 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package managedhsm_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" +) + +type KeyVaultMHSMKeyTestDataSource struct{} + +func testAccKeyVaultMHSMKeyDataSource_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_key_vault_managed_hardware_security_module_key", "test") + dataSourceName := "data." + data.ResourceName + r := KeyVaultMHSMKeyTestDataSource{} + + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(dataSourceName).Key("version").Exists(), + check.That(dataSourceName).Key("key_type").Exists(), + ), + }, + }) +} + +func (KeyVaultMHSMKeyTestDataSource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_key_vault_managed_hardware_security_module_key" "test" { + managed_hsm_id = azurerm_key_vault_managed_hardware_security_module.test.id + name = azurerm_key_vault_managed_hardware_security_module_key.test.name +} +`, KeyVaultMHSMKeyTestResource{}.basic(data)) +} diff --git a/internal/services/managedhsm/key_vault_managed_hardware_security_module_resource_test.go b/internal/services/managedhsm/key_vault_managed_hardware_security_module_resource_test.go index 98ff5646acf9..3166dbdf6ead 100644 --- a/internal/services/managedhsm/key_vault_managed_hardware_security_module_resource_test.go +++ b/internal/services/managedhsm/key_vault_managed_hardware_security_module_resource_test.go @@ -48,6 +48,7 @@ func TestAccKeyVaultManagedHardwareSecurityModule(t *testing.T) { "purge": testAccKeyVaultHSMKey_purge, "softDeleteRecovery": testAccKeyVaultHSMKey_softDeleteRecovery, "rotationPolicy": testAccMHSMKeyRotationPolicy_all, + "data_source": testAccKeyVaultMHSMKeyDataSource_basic, }, }) } diff --git a/internal/services/managedhsm/registration.go b/internal/services/managedhsm/registration.go index bb7f2fb5e62b..931d5e1d9f61 100644 --- a/internal/services/managedhsm/registration.go +++ b/internal/services/managedhsm/registration.go @@ -49,6 +49,7 @@ func (r Registration) SupportedResources() map[string]*pluginsdk.Resource { func (r Registration) DataSources() []sdk.DataSource { return []sdk.DataSource{ KeyvaultMHSMRoleDefinitionDataSource{}, + KeyvaultMHSMKeyDataSource{}, } } diff --git a/website/docs/d/key_vault_managed_hardware_security_module_key.html.markdown b/website/docs/d/key_vault_managed_hardware_security_module_key.html.markdown new file mode 100644 index 000000000000..4be6edb21467 --- /dev/null +++ b/website/docs/d/key_vault_managed_hardware_security_module_key.html.markdown @@ -0,0 +1,64 @@ +--- +subcategory: "Key Vault" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_key_vault_managed_hardware_security_module_key" +description: |- + Gets information about an existing Managed Hardware Security Module Key. + +--- + +# Data Source: azurerm_key_vault_managed_hardware_security_module_key + +Use this data source to access information about an existing Managed Hardware Security Module Key. + +~> **Note:** All arguments including the secret value will be stored in the raw state as plain-text. +[Read more about sensitive data in state](/docs/state/sensitive-data.html). + +## Example Usage + +```hcl +data "azurerm_key_vault_managed_hardware_security_module_key" "example" { + managed_hsm_id = azurerm_key_vault_managed_hardware_security_module.example.id + name = azurerm_key_vault_managed_hardware_security_module_key.example.name +} + +output "hsm-key-vesrion" { + value = data.azurerm_key_vault_managed_hardware_security_module_key.example.version +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - Specifies the name of the Managed Hardware Security Module Key. + +* `managed_hsm_id` - Specifies the ID of the Managed Hardware Security Module instance where the Secret resides, available on the `azurerm_key_vault_managed_hardware_security_module_key` Data Source / Resource. + +**NOTE:** The Managed Hardware Security Module must be in the same subscription as the provider. If the Managed Hardware Security Module is in another subscription, you must create an aliased provider for that subscription. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The versionless ID of the Managed Hardware Security Module Key. + +* `curve` - The EC Curve name of this Managed Hardware Security Module Key. + +* `key_type` - Specifies the Key Type of this Managed Hardware Security Module Key + +* `key_size` - Specifies the Size of this Managed Hardware Security Module Key. + +* `key_opts` - A list of JSON web key operations assigned to this Managed Hardware Security Module Key + +* `tags` - A mapping of tags assigned to this Managed Hardware Security Module Key. + +* `version` - The current version of the Managed Hardware Security Module Key. + +* `versioned_id` - The versioned ID of the Managed Hardware Security Module Key. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: + +* `read` - (Defaults to 5 minutes) Used when retrieving the Managed Hardware Security Module Key.