Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/services/signalr/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func (r Registration) EphemeralResources() []func() ephemeral.EphemeralResource

func (r Registration) ListResources() []sdk.FrameworkListWrappedResource {
return []sdk.FrameworkListWrappedResource{
CustomCertWebPubsubListResource{},
SignalRServiceListResource{},
WebPubSubListResource{},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

package signalr

//go:generate go run ../../tools/generator-tests resourceidentity -resource-name web_pubsub_custom_certificate -service-package-name signalr -properties "name" -compare-values "subscription_id:web_pubsub_id,resource_group_name:web_pubsub_id,web_pub_sub_name:web_pubsub_id"

import (
"context"
"fmt"
Expand All @@ -12,6 +14,7 @@ import (
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-helpers/resourcemanager/keyvault"
"github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids"
"github.com/hashicorp/go-azure-sdk/resource-manager/webpubsub/2024-03-01/webpubsub"
"github.com/hashicorp/terraform-provider-azurerm/internal/locks"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
Expand All @@ -26,9 +29,18 @@ type CustomCertWebPubsubModel struct {
CertificateVersion string `tfschema:"certificate_version"`
}

const webPubsubCustomCertificateResourceType = "azurerm_web_pubsub_custom_certificate"

type CustomCertWebPubsubResource struct{}

var _ sdk.Resource = CustomCertWebPubsubResource{}
var (
_ sdk.Resource = CustomCertWebPubsubResource{}
_ sdk.ResourceWithIdentity = CustomCertWebPubsubResource{}
)

func (r CustomCertWebPubsubResource) Identity() resourceids.ResourceId {
return &webpubsub.CustomCertificateId{}
}

func (r CustomCertWebPubsubResource) Arguments() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
Expand Down Expand Up @@ -69,7 +81,7 @@ func (r CustomCertWebPubsubResource) ModelObject() interface{} {
}

func (r CustomCertWebPubsubResource) ResourceType() string {
return "azurerm_web_pubsub_custom_certificate"
return webPubsubCustomCertificateResourceType
}

func (r CustomCertWebPubsubResource) Create() sdk.ResourceFunc {
Expand Down Expand Up @@ -124,6 +136,9 @@ func (r CustomCertWebPubsubResource) Create() sdk.ResourceFunc {
}

metadata.SetID(id)
if err := pluginsdk.SetResourceIdentityData(metadata.ResourceData, &id); err != nil {
return err
}
return nil
},
}
Expand Down Expand Up @@ -153,8 +168,6 @@ func (r CustomCertWebPubsubResource) Read() sdk.ResourceFunc {
}

vaultBasedUri := resp.Model.Properties.KeyVaultBaseUri
certName := resp.Model.Properties.KeyVaultSecretName

subscriptionResourceId := commonids.NewSubscriptionID(id.SubscriptionId)
keyVaultIdRaw, err := keyVaultClient.KeyVaultIDFromBaseUrl(ctx, subscriptionResourceId, vaultBasedUri)
if err != nil {
Expand All @@ -166,25 +179,8 @@ func (r CustomCertWebPubsubResource) Read() sdk.ResourceFunc {
return fmt.Errorf("parsing key vault %s: %+v", vaultId, err)
}
}
certVersion := ""
if resp.Model.Properties.KeyVaultSecretVersion != nil {
certVersion = *resp.Model.Properties.KeyVaultSecretVersion
}
nestedItem, err := keyvault.NewNestedItemID(vaultBasedUri, keyvault.NestedItemTypeCertificate, certName, certVersion)
if err != nil {
return err
}

certId := nestedItem.ID()

state := CustomCertWebPubsubModel{
Name: id.CustomCertificateName,
CustomCertId: certId,
WebPubsubId: webpubsub.NewWebPubSubID(id.SubscriptionId, id.ResourceGroupName, id.WebPubSubName).ID(),
CertificateVersion: pointer.From(resp.Model.Properties.KeyVaultSecretVersion),
}

return metadata.Encode(&state)
return r.flatten(metadata, id, resp.Model)
},
}
}
Expand Down Expand Up @@ -248,3 +244,30 @@ func webPubsubCustomCertificateDeleteRefreshFunc(ctx context.Context, client *we
return res, "Exists", nil
}
}

func (r CustomCertWebPubsubResource) flatten(metadata sdk.ResourceMetaData, id *webpubsub.CustomCertificateId, model *webpubsub.CustomCertificate) error {
if model == nil {
return fmt.Errorf("retrieving %s: got nil model", *id)
}

vaultBasedUri := model.Properties.KeyVaultBaseUri
certName := model.Properties.KeyVaultSecretName
certVersion := pointer.From(model.Properties.KeyVaultSecretVersion)
nestedItem, err := keyvault.NewNestedItemID(vaultBasedUri, keyvault.NestedItemTypeCertificate, certName, certVersion)
if err != nil {
return err
}

state := CustomCertWebPubsubModel{
Name: id.CustomCertificateName,
CustomCertId: nestedItem.ID(),
WebPubsubId: webpubsub.NewWebPubSubID(id.SubscriptionId, id.ResourceGroupName, id.WebPubSubName).ID(),
CertificateVersion: certVersion,
}

if err := pluginsdk.SetResourceIdentityData(metadata.ResourceData, id); err != nil {
return err
}

return metadata.Encode(&state)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright IBM Corp. 2014, 2025
// SPDX-License-Identifier: MPL-2.0

package signalr_test

import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/statecheck"
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
customstatecheck "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/statecheck"
)

func TestAccWebPubsubCustomCertificate_resourceIdentity(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_web_pubsub_custom_certificate", "test")
r := WebPubsubCustomCertificateResource{}

checkedFields := map[string]struct{}{
"name": {},
"resource_group_name": {},
"subscription_id": {},
"web_pub_sub_name": {},
}

data.ResourceIdentityTest(t, []acceptance.TestStep{
{
Config: r.basic(data),
ConfigStateChecks: []statecheck.StateCheck{
customstatecheck.ExpectAllIdentityFieldsAreChecked("azurerm_web_pubsub_custom_certificate.test", checkedFields),
statecheck.ExpectIdentityValueMatchesStateAtPath("azurerm_web_pubsub_custom_certificate.test", tfjsonpath.New("name"), tfjsonpath.New("name")),
customstatecheck.ExpectStateContainsIdentityValueAtPath("azurerm_web_pubsub_custom_certificate.test", tfjsonpath.New("resource_group_name"), tfjsonpath.New("web_pubsub_id")),
customstatecheck.ExpectStateContainsIdentityValueAtPath("azurerm_web_pubsub_custom_certificate.test", tfjsonpath.New("subscription_id"), tfjsonpath.New("web_pubsub_id")),
customstatecheck.ExpectStateContainsIdentityValueAtPath("azurerm_web_pubsub_custom_certificate.test", tfjsonpath.New("web_pub_sub_name"), tfjsonpath.New("web_pubsub_id")),
},
},
data.ImportBlockWithResourceIdentityStep(false),
data.ImportBlockWithIDStep(false),
}, false)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright IBM Corp. 2014, 2025
// SPDX-License-Identifier: MPL-2.0

package signalr

import (
"context"
"fmt"

"github.com/hashicorp/go-azure-helpers/framework/typehelpers"
"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-sdk/resource-manager/webpubsub/2024-03-01/webpubsub"
"github.com/hashicorp/terraform-plugin-framework/list"
"github.com/hashicorp/terraform-plugin-framework/list/schema"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
)

type (
CustomCertWebPubsubListResource struct{}
CustomCertWebPubsubListModel struct {
WebPubsubId types.String `tfsdk:"web_pubsub_id"`
}
)

var _ sdk.FrameworkListWrappedResource = new(CustomCertWebPubsubListResource)

func (r CustomCertWebPubsubListResource) ResourceFunc() *pluginsdk.Resource {
return sdk.WrappedResource(CustomCertWebPubsubResource{})
}

func (r CustomCertWebPubsubListResource) Metadata(_ context.Context, _ resource.MetadataRequest, response *resource.MetadataResponse) {
response.TypeName = CustomCertWebPubsubResource{}.ResourceType()
}

func (r CustomCertWebPubsubListResource) ListResourceConfigSchema(_ context.Context, _ list.ListResourceSchemaRequest, response *list.ListResourceSchemaResponse) {
response.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"web_pubsub_id": schema.StringAttribute{
Required: true,
Validators: []validator.String{
typehelpers.WrappedStringValidator{Func: webpubsub.ValidateWebPubSubID},
},
},
},
}
}

func (r CustomCertWebPubsubListResource) List(ctx context.Context, request list.ListRequest, stream *list.ListResultsStream, metadata sdk.ResourceMetadata) {
client := metadata.Client.SignalR.WebPubSubClient.WebPubSub

var data CustomCertWebPubsubListModel
diags := request.Config.Get(ctx, &data)
if diags.HasError() {
stream.Results = list.ListResultsStreamDiagnostics(diags)
return
}

webPubsubId, err := webpubsub.ParseWebPubSubID(data.WebPubsubId.ValueString())
if err != nil {
sdk.SetResponseErrorDiagnostic(stream, fmt.Sprintf("parsing Web PubSub ID for `%s`", webPubsubCustomCertificateResourceType), err)
return
}

resp, err := client.CustomCertificatesListComplete(ctx, *webPubsubId)
if err != nil {
sdk.SetResponseErrorDiagnostic(stream, fmt.Sprintf("listing `%s`", webPubsubCustomCertificateResourceType), err)
return
}

stream.Results = func(push func(list.ListResult) bool) {
for _, cert := range resp.Items {
result := request.NewListResult(ctx)
result.DisplayName = pointer.From(cert.Name)

id, err := webpubsub.ParseCustomCertificateIDInsensitively(pointer.From(cert.Id))
if err != nil {
sdk.SetErrorDiagnosticAndPushListResult(result, push, "parsing Web PubSub Custom Certificate ID", err)
return
}

r := CustomCertWebPubsubResource{}
rmd := sdk.NewResourceMetaData(metadata.Client, r)
rmd.ResourceData.SetId(id.ID())

if err := r.flatten(rmd, id, &cert); err != nil {
sdk.SetErrorDiagnosticAndPushListResult(result, push, fmt.Sprintf("encoding `%s` resource data", r.ResourceType()), err)
return
}

sdk.EncodeListResult(ctx, rmd.ResourceData, &result)
if result.Diagnostics.HasError() {
push(result)
return
}
if !push(result) {
return
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package signalr_test

import (
"context"
"regexp"
"strconv"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
"github.com/hashicorp/terraform-plugin-testing/querycheck"
"github.com/hashicorp/terraform-plugin-testing/tfversion"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
"github.com/hashicorp/terraform-provider-azurerm/internal/provider/framework"
)

func TestAccCustomCertWebPubsub_listByWebPubSubID(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_web_pubsub_custom_certificate", "testlist")
r := CustomCertWebPubsubResource{}

resource.Test(t, resource.TestCase{
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
tfversion.SkipBelow(tfversion.Version1_14_0),
},
ProtoV5ProviderFactories: framework.ProtoV5ProviderFactoriesInit(context.Background(), "azurerm"),
Steps: []resource.TestStep{
{
Config: r.basic(data),
},
{
Query: true,
Config: r.basicListQuery(),
QueryResultChecks: []querycheck.QueryResultCheck{
querycheck.ExpectLengthAtLeast("azurerm_web_pubsub_custom_certificate.list", 1),
querycheck.ExpectIdentity(
"azurerm_web_pubsub_custom_certificate.list",
map[string]knownvalue.Check{
"name": knownvalue.StringRegexp(regexp.MustCompile(data.RandomString)),
"web_pub_sub_name": knownvalue.StringRegexp(regexp.MustCompile(strconv.Itoa(data.RandomInteger))),
"resource_group_name": knownvalue.StringRegexp(regexp.MustCompile(strconv.Itoa(data.RandomInteger))),
"subscription_id": knownvalue.StringExact(data.Subscriptions.Primary),
},
),
},
},
},
})
}

func (r CustomCertWebPubsubResource) basicListQuery() string {
return `
list "azurerm_web_pubsub_custom_certificate" "list" {
provider = azurerm
config {
web_pubsub_id = azurerm_web_pubsub.test.id
}
}
`
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import (

type CustomCertWebPubsubResource struct{}

// Alias retained for generated identity test naming.
type WebPubsubCustomCertificateResource = CustomCertWebPubsubResource

func TestAccCustomCertWebPubsub_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_web_pubsub_custom_certificate", "test")
r := CustomCertWebPubsubResource{}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
subcategory: "Messaging"
layout: "azurerm"
page_title: "Azure Resource Manager: azurerm_web_pubsub_custom_certificate"
description: |-
Lists Web PubSub Custom Certificate resources.
---

# List resource: azurerm_web_pubsub_custom_certificate

Lists Web PubSub Custom Certificate resources.

## Example Usage

### List Web PubSub Custom Certificates in a Web PubSub service

```hcl
list "azurerm_web_pubsub_custom_certificate" "example" {
provider = azurerm
config {
web_pubsub_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myresourcegroup/providers/Microsoft.SignalRService/webPubSub/mywps"
}
}
```

## Argument Reference

This list resource supports the following arguments:

* `web_pubsub_id` - (Required) The ID of the Web PubSub service to query.
Loading