Skip to content

Commit

Permalink
add data source for managed hsm key
Browse files Browse the repository at this point in the history
  • Loading branch information
wuxu92 committed Nov 8, 2024
1 parent e85a546 commit 35c5888
Show file tree
Hide file tree
Showing 5 changed files with 287 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -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{}
Original file line number Diff line number Diff line change
@@ -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))
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func TestAccKeyVaultManagedHardwareSecurityModule(t *testing.T) {
"purge": testAccKeyVaultHSMKey_purge,
"softDeleteRecovery": testAccKeyVaultHSMKey_softDeleteRecovery,
"rotationPolicy": testAccMHSMKeyRotationPolicy_all,
"data_source": testAccKeyVaultMHSMKeyDataSource_basic,
},
})
}
Expand Down
1 change: 1 addition & 0 deletions internal/services/managedhsm/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func (r Registration) SupportedResources() map[string]*pluginsdk.Resource {
func (r Registration) DataSources() []sdk.DataSource {
return []sdk.DataSource{
KeyvaultMHSMRoleDefinitionDataSource{},
KeyvaultMHSMKeyDataSource{},
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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.

0 comments on commit 35c5888

Please sign in to comment.