Skip to content

Commit

Permalink
d/azurerm_recovery_services_vault: expose identity property (#26254)
Browse files Browse the repository at this point in the history
* d/`azurerm_recovery_services_vault`: expose identity

* Update internal/services/recoveryservices/recovery_services_vault_data_source.go

Co-authored-by: stephybun <steph@hashicorp.com>

* Update internal/services/recoveryservices/recovery_services_vault_data_source.go

Co-authored-by: stephybun <steph@hashicorp.com>

* Update internal/services/recoveryservices/recovery_services_vault_data_source.go

Co-authored-by: stephybun <steph@hashicorp.com>

* fix build issues

---------

Co-authored-by: stephybun <steph@hashicorp.com>
  • Loading branch information
jkroepke and stephybun authored Aug 14, 2024
1 parent 8ab553c commit 1b6e07f
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,78 +4,113 @@
package recoveryservices

import (
"context"
"fmt"
"time"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/go-azure-helpers/resourcemanager/identity"
"github.com/hashicorp/go-azure-helpers/resourcemanager/location"
"github.com/hashicorp/go-azure-helpers/resourcemanager/tags"
"github.com/hashicorp/go-azure-sdk/resource-manager/recoveryservices/2024-01-01/vaults"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/recoveryservices/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/timeouts"
)

func dataSourceRecoveryServicesVault() *pluginsdk.Resource {
return &pluginsdk.Resource{
Read: dataSourceRecoveryServicesVaultRead,
var _ sdk.DataSource = SiteRecoveryRecoveryVaultDataSource{}

Timeouts: &pluginsdk.ResourceTimeout{
Read: pluginsdk.DefaultTimeout(5 * time.Minute),
},

Schema: map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Required: true,
},

"resource_group_name": commonschema.ResourceGroupNameForDataSource(),
type SiteRecoveryRecoveryVaultDataSource struct{}
type SiteRecoveryRecoveryVaultDataSourceModel struct {
Name string `tfschema:"name"`
ResourceGroupName string `tfschema:"resource_group_name"`
Location string `tfschema:"location"`
Identity []identity.ModelSystemAssignedUserAssigned `tfschema:"identity"`
Sku string `tfschema:"sku"`
Tags map[string]string `tfschema:"tags"`
}

"location": commonschema.LocationComputed(),
func (SiteRecoveryRecoveryVaultDataSource) ModelObject() interface{} {
return &SiteRecoveryRecoveryVaultDataSourceModel{}
}

"tags": commonschema.TagsDataSource(),
func (SiteRecoveryRecoveryVaultDataSource) ResourceType() string {
return "azurerm_recovery_services_vault"
}

"sku": {
Type: pluginsdk.TypeString,
Computed: true,
},
func (SiteRecoveryRecoveryVaultDataSource) Arguments() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validate.RecoveryServicesVaultName,
},

"resource_group_name": commonschema.ResourceGroupNameForDataSource(),
}
}
func (SiteRecoveryRecoveryVaultDataSource) Attributes() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
"location": commonschema.LocationComputed(),

func dataSourceRecoveryServicesVaultRead(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).RecoveryServices.VaultsClient
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()
"tags": commonschema.TagsDataSource(),

id := vaults.NewVaultID(subscriptionId, d.Get("resource_group_name").(string), d.Get("name").(string))
resp, err := client.Get(ctx, id)
if err != nil {
if response.WasNotFound(resp.HttpResponse) {
return fmt.Errorf("%s was not found", id)
}
"identity": commonschema.SystemAssignedUserAssignedIdentityComputed(),

return fmt.Errorf("retrieving %s: %+v", id, err)
}

if resp.Model == nil {
return fmt.Errorf("retrieving %s: `model` was nil", id)
"sku": {
Type: pluginsdk.TypeString,
Computed: true,
},
}
model := resp.Model

d.SetId(id.ID())
d.Set("name", id.VaultName)
d.Set("resource_group_name", id.ResourceGroupName)
d.Set("location", location.Normalize(model.Location))
}

skuName := ""
if model.Sku != nil {
skuName = string(model.Sku.Name)
func (r SiteRecoveryRecoveryVaultDataSource) Read() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
client := metadata.Client.RecoveryServices.VaultsClient
subscriptionId := metadata.Client.Account.SubscriptionId

var recoveryServiceVault SiteRecoveryRecoveryVaultDataSourceModel
if err := metadata.Decode(&recoveryServiceVault); err != nil {
return err
}

id := vaults.NewVaultID(subscriptionId, recoveryServiceVault.ResourceGroupName, recoveryServiceVault.Name)
resp, err := client.Get(ctx, id)
if err != nil {
if response.WasNotFound(resp.HttpResponse) {
return fmt.Errorf("%s was not found", id)
}
return fmt.Errorf("retrieving %s: %+v", id, err)
}

if model := resp.Model; model != nil {
flattenedIdentity, err := identity.FlattenSystemAndUserAssignedMapToModel(model.Identity)

if err != nil {
return fmt.Errorf("flattening `identity`: %+v", err)
}

skuName := ""
if model.Sku != nil {
skuName = string(model.Sku.Name)
}

recoveryServiceVault.Sku = skuName
recoveryServiceVault.Location = location.Normalize(model.Location)
recoveryServiceVault.Tags = pointer.From(model.Tags)
recoveryServiceVault.Identity = pointer.From(flattenedIdentity)
}

metadata.SetID(id)

if err := metadata.Encode(&recoveryServiceVault); err != nil {
return fmt.Errorf("encoding: %+v", err)
}

return nil
},
}
d.Set("sku", skuName)

return tags.FlattenAndSet(d, model.Tags)
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,28 @@ func TestAccDataSourceAzureRMRecoveryServicesVault_basic(t *testing.T) {
check.That(data.ResourceName).Key("resource_group_name").Exists(),
check.That(data.ResourceName).Key("tags.%").HasValue("0"),
check.That(data.ResourceName).Key("sku").HasValue("Standard"),
check.That(data.ResourceName).Key("identity.%").HasValue("0"),
),
},
})
}

func TestAccDataSourceAzureRMRecoveryServicesVault_basicWithIdentity(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_recovery_services_vault", "test")
r := RecoveryServicesVaultDataSource{}

data.DataSourceTest(t, []acceptance.TestStep{
{
Config: r.basicWithIdentity(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("name").Exists(),
check.That(data.ResourceName).Key("location").Exists(),
check.That(data.ResourceName).Key("resource_group_name").Exists(),
check.That(data.ResourceName).Key("tags.%").HasValue("0"),
check.That(data.ResourceName).Key("sku").HasValue("Standard"),
check.That(data.ResourceName).Key("identity.0.type").HasValue("SystemAssigned"),
check.That(data.ResourceName).Key("identity.0.tenant_id").IsNotEmpty(),
check.That(data.ResourceName).Key("identity.0.principal_id").IsNotEmpty(),
),
},
})
Expand All @@ -41,3 +63,14 @@ data "azurerm_recovery_services_vault" "test" {
}
`, RecoveryServicesVaultResource{}.basic(data))
}

func (RecoveryServicesVaultDataSource) basicWithIdentity(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
data "azurerm_recovery_services_vault" "test" {
name = azurerm_recovery_services_vault.test.name
resource_group_name = azurerm_resource_group.test.name
}
`, RecoveryServicesVaultResource{}.basicWithIdentity(data))
}
2 changes: 1 addition & 1 deletion internal/services/recoveryservices/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func (r Registration) AssociatedGitHubLabel() string {

func (r Registration) DataSources() []sdk.DataSource {
return []sdk.DataSource{
SiteRecoveryRecoveryVaultDataSource{},
SiteRecoveryReplicationRecoveryPlanDataSource{},
}
}
Expand Down Expand Up @@ -55,7 +56,6 @@ func (r Registration) WebsiteCategories() []string {
// SupportedDataSources returns the supported Data Sources supported by this Service
func (r Registration) SupportedDataSources() map[string]*pluginsdk.Resource {
return map[string]*pluginsdk.Resource{
"azurerm_recovery_services_vault": dataSourceRecoveryServicesVault(),
"azurerm_site_recovery_fabric": dataSourceSiteRecoveryFabric(),
"azurerm_site_recovery_protection_container": dataSourceSiteRecoveryProtectionContainer(),
"azurerm_backup_policy_vm": dataSourceBackupPolicyVm(),
Expand Down
12 changes: 12 additions & 0 deletions website/docs/d/recovery_services_vault.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ The following attributes are exported:

* `sku` - The vault's current SKU.

* `identity` - (Optional) An `identity` block as defined below.

---

An `identity` block exports the following:

* `principal_id` - The Principal ID associated with this Managed Service Identity.

* `tenant_id` - The Tenant ID associated with this Managed Service Identity.

* `type` - The identity type of this Managed Service Identity.

## Timeouts

The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions:
Expand Down

0 comments on commit 1b6e07f

Please sign in to comment.