From 971915d0c807a825066d0e7c68817c00f2da3c55 Mon Sep 17 00:00:00 2001 From: Xiaxin <92154856+xiaxyi@users.noreply.github.com> Date: Wed, 20 Jul 2022 11:32:26 +0800 Subject: [PATCH] Adding shared private link resource for the Azure web pubsub resource (#15550) --- internal/services/signalr/client/client.go | 22 +- internal/services/signalr/parse/web_pubsub.go | 4 +- .../services/signalr/parse/web_pubsub_hub.go | 4 +- .../signalr/parse/web_pubsub_hub_test.go | 10 +- ...web_pubsub_shared_private_link_resource.go | 75 +++++++ ...ubsub_shared_private_link_resource_test.go | 128 ++++++++++++ .../services/signalr/parse/web_pubsub_test.go | 6 +- internal/services/signalr/registration.go | 16 +- internal/services/signalr/resourceids.go | 5 +- .../validate/web_pubsub_hub_id_test.go | 8 +- .../signalr/validate/web_pubsub_id_test.go | 4 +- ..._pubsub_shared_private_link_resource_id.go | 23 +++ ...ub_shared_private_link_resource_id_test.go | 88 ++++++++ .../web_pubsub_network_acl_resource_test.go | 6 +- ...bsub_private_linked_service_data_source.go | 95 +++++++++ ...private_linked_service_data_source_test.go | 51 +++++ ...web_pubsub_shared_private_link_resource.go | 189 ++++++++++++++++++ ...ubsub_shared_private_link_resource_test.go | 138 +++++++++++++ ...pubsub_private_link_resource.html.markdown | 58 ++++++ ...b_pubsub_shared_private_link.html.markdown | 107 ++++++++++ 20 files changed, 1003 insertions(+), 34 deletions(-) create mode 100644 internal/services/signalr/parse/web_pubsub_shared_private_link_resource.go create mode 100644 internal/services/signalr/parse/web_pubsub_shared_private_link_resource_test.go create mode 100644 internal/services/signalr/validate/web_pubsub_shared_private_link_resource_id.go create mode 100644 internal/services/signalr/validate/web_pubsub_shared_private_link_resource_id_test.go create mode 100644 internal/services/signalr/web_pubsub_private_linked_service_data_source.go create mode 100644 internal/services/signalr/web_pubsub_private_linked_service_data_source_test.go create mode 100644 internal/services/signalr/web_pubsub_shared_private_link_resource.go create mode 100644 internal/services/signalr/web_pubsub_shared_private_link_resource_test.go create mode 100644 website/docs/d/web_pubsub_private_link_resource.html.markdown create mode 100644 website/docs/r/web_pubsub_shared_private_link.html.markdown diff --git a/internal/services/signalr/client/client.go b/internal/services/signalr/client/client.go index c5e6e9df77e8..b2bc565fce27 100644 --- a/internal/services/signalr/client/client.go +++ b/internal/services/signalr/client/client.go @@ -7,9 +7,11 @@ import ( ) type Client struct { - SignalRClient *signalr.SignalRClient - WebPubsubClient *webpubsub.Client - WebPubsubHubsClient *webpubsub.HubsClient + SignalRClient *signalr.SignalRClient + WebPubsubClient *webpubsub.Client + WebPubsubHubsClient *webpubsub.HubsClient + WebPubsubSharedPrivateLinkResourceClient *webpubsub.SharedPrivateLinkResourcesClient + WebPubsubPrivateLinkedResourceClient *webpubsub.PrivateLinkResourcesClient } func NewClient(o *common.ClientOptions) *Client { @@ -22,9 +24,17 @@ func NewClient(o *common.ClientOptions) *Client { webpubsubHubsClient := webpubsub.NewHubsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&webpubsubHubsClient.Client, o.ResourceManagerAuthorizer) + webPubsubSharedPrivateLinkResourceClient := webpubsub.NewSharedPrivateLinkResourcesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&webPubsubSharedPrivateLinkResourceClient.Client, o.ResourceManagerAuthorizer) + + webPubsubPrivateLinkResourceClient := webpubsub.NewPrivateLinkResourcesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&webPubsubPrivateLinkResourceClient.Client, o.ResourceManagerAuthorizer) + return &Client{ - SignalRClient: &signalRClient, - WebPubsubClient: &webpubsubClient, - WebPubsubHubsClient: &webpubsubHubsClient, + SignalRClient: &signalRClient, + WebPubsubClient: &webpubsubClient, + WebPubsubHubsClient: &webpubsubHubsClient, + WebPubsubSharedPrivateLinkResourceClient: &webPubsubSharedPrivateLinkResourceClient, + WebPubsubPrivateLinkedResourceClient: &webPubsubPrivateLinkResourceClient, } } diff --git a/internal/services/signalr/parse/web_pubsub.go b/internal/services/signalr/parse/web_pubsub.go index 5bfe2e5e64ef..532d5b9462ec 100644 --- a/internal/services/signalr/parse/web_pubsub.go +++ b/internal/services/signalr/parse/web_pubsub.go @@ -33,7 +33,7 @@ func (id WebPubsubId) String() string { } func (id WebPubsubId) ID() string { - fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.SignalRService/WebPubSub/%s" + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.SignalRService/webPubSub/%s" return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.WebPubSubName) } @@ -57,7 +57,7 @@ func WebPubsubID(input string) (*WebPubsubId, error) { return nil, fmt.Errorf("ID was missing the 'resourceGroups' element") } - if resourceId.WebPubSubName, err = id.PopSegment("WebPubSub"); err != nil { + if resourceId.WebPubSubName, err = id.PopSegment("webPubSub"); err != nil { return nil, err } diff --git a/internal/services/signalr/parse/web_pubsub_hub.go b/internal/services/signalr/parse/web_pubsub_hub.go index 619a9ea87809..5550771b412d 100644 --- a/internal/services/signalr/parse/web_pubsub_hub.go +++ b/internal/services/signalr/parse/web_pubsub_hub.go @@ -36,7 +36,7 @@ func (id WebPubsubHubId) String() string { } func (id WebPubsubHubId) ID() string { - fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.SignalRService/WebPubSub/%s/hubs/%s" + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.SignalRService/webPubSub/%s/hubs/%s" return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.WebPubSubName, id.HubName) } @@ -60,7 +60,7 @@ func WebPubsubHubID(input string) (*WebPubsubHubId, error) { return nil, fmt.Errorf("ID was missing the 'resourceGroups' element") } - if resourceId.WebPubSubName, err = id.PopSegment("WebPubSub"); err != nil { + if resourceId.WebPubSubName, err = id.PopSegment("webPubSub"); err != nil { return nil, err } if resourceId.HubName, err = id.PopSegment("hubs"); err != nil { diff --git a/internal/services/signalr/parse/web_pubsub_hub_test.go b/internal/services/signalr/parse/web_pubsub_hub_test.go index ca3f00a09599..0dff2dd75b38 100644 --- a/internal/services/signalr/parse/web_pubsub_hub_test.go +++ b/internal/services/signalr/parse/web_pubsub_hub_test.go @@ -12,7 +12,7 @@ var _ resourceids.Id = WebPubsubHubId{} func TestWebPubsubHubIDFormatter(t *testing.T) { actual := NewWebPubsubHubID("12345678-1234-9876-4563-123456789012", "resGroup1", "Webpubsub1", "Webpubsubhub1").ID() - expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/Webpubsub1/hubs/Webpubsubhub1" + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/hubs/Webpubsubhub1" if actual != expected { t.Fatalf("Expected %q but got %q", expected, actual) } @@ -63,25 +63,25 @@ func TestWebPubsubHubID(t *testing.T) { { // missing value for WebPubSubName - Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/", + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/", Error: true, }, { // missing HubName - Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/Webpubsub1/", + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/", Error: true, }, { // missing value for HubName - Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/Webpubsub1/hubs/", + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/hubs/", Error: true, }, { // valid - Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/Webpubsub1/hubs/Webpubsubhub1", + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/hubs/Webpubsubhub1", Expected: &WebPubsubHubId{ SubscriptionId: "12345678-1234-9876-4563-123456789012", ResourceGroup: "resGroup1", diff --git a/internal/services/signalr/parse/web_pubsub_shared_private_link_resource.go b/internal/services/signalr/parse/web_pubsub_shared_private_link_resource.go new file mode 100644 index 000000000000..f96e7c776aa6 --- /dev/null +++ b/internal/services/signalr/parse/web_pubsub_shared_private_link_resource.go @@ -0,0 +1,75 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +type WebPubsubSharedPrivateLinkResourceId struct { + SubscriptionId string + ResourceGroup string + WebPubSubName string + SharedPrivateLinkResourceName string +} + +func NewWebPubsubSharedPrivateLinkResourceID(subscriptionId, resourceGroup, webPubSubName, sharedPrivateLinkResourceName string) WebPubsubSharedPrivateLinkResourceId { + return WebPubsubSharedPrivateLinkResourceId{ + SubscriptionId: subscriptionId, + ResourceGroup: resourceGroup, + WebPubSubName: webPubSubName, + SharedPrivateLinkResourceName: sharedPrivateLinkResourceName, + } +} + +func (id WebPubsubSharedPrivateLinkResourceId) String() string { + segments := []string{ + fmt.Sprintf("Shared Private Link Resource Name %q", id.SharedPrivateLinkResourceName), + fmt.Sprintf("Web Pub Sub Name %q", id.WebPubSubName), + fmt.Sprintf("Resource Group %q", id.ResourceGroup), + } + segmentsStr := strings.Join(segments, " / ") + return fmt.Sprintf("%s: (%s)", "Web Pubsub Shared Private Link Resource", segmentsStr) +} + +func (id WebPubsubSharedPrivateLinkResourceId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.SignalRService/webPubSub/%s/sharedPrivateLinkResources/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.WebPubSubName, id.SharedPrivateLinkResourceName) +} + +// WebPubsubSharedPrivateLinkResourceID parses a WebPubsubSharedPrivateLinkResource ID into an WebPubsubSharedPrivateLinkResourceId struct +func WebPubsubSharedPrivateLinkResourceID(input string) (*WebPubsubSharedPrivateLinkResourceId, error) { + id, err := resourceids.ParseAzureResourceID(input) + if err != nil { + return nil, err + } + + resourceId := WebPubsubSharedPrivateLinkResourceId{ + SubscriptionId: id.SubscriptionID, + ResourceGroup: id.ResourceGroup, + } + + if resourceId.SubscriptionId == "" { + return nil, fmt.Errorf("ID was missing the 'subscriptions' element") + } + + if resourceId.ResourceGroup == "" { + return nil, fmt.Errorf("ID was missing the 'resourceGroups' element") + } + + if resourceId.WebPubSubName, err = id.PopSegment("webPubSub"); err != nil { + return nil, err + } + if resourceId.SharedPrivateLinkResourceName, err = id.PopSegment("sharedPrivateLinkResources"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &resourceId, nil +} diff --git a/internal/services/signalr/parse/web_pubsub_shared_private_link_resource_test.go b/internal/services/signalr/parse/web_pubsub_shared_private_link_resource_test.go new file mode 100644 index 000000000000..c4f3c6a6c188 --- /dev/null +++ b/internal/services/signalr/parse/web_pubsub_shared_private_link_resource_test.go @@ -0,0 +1,128 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "testing" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.Id = WebPubsubSharedPrivateLinkResourceId{} + +func TestWebPubsubSharedPrivateLinkResourceIDFormatter(t *testing.T) { + actual := NewWebPubsubSharedPrivateLinkResourceID("12345678-1234-9876-4563-123456789012", "resGroup1", "Webpubsub1", "resource1").ID() + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/sharedPrivateLinkResources/resource1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + +func TestWebPubsubSharedPrivateLinkResourceID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *WebPubsubSharedPrivateLinkResourceId + }{ + + { + // empty + Input: "", + Error: true, + }, + + { + // missing SubscriptionId + Input: "/", + Error: true, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Error: true, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Error: true, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Error: true, + }, + + { + // missing WebPubSubName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/", + Error: true, + }, + + { + // missing value for WebPubSubName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/", + Error: true, + }, + + { + // missing SharedPrivateLinkResourceName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/", + Error: true, + }, + + { + // missing value for SharedPrivateLinkResourceName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/sharedPrivateLinkResources/", + Error: true, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/sharedPrivateLinkResources/resource1", + Expected: &WebPubsubSharedPrivateLinkResourceId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resGroup1", + WebPubSubName: "Webpubsub1", + SharedPrivateLinkResourceName: "resource1", + }, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.SIGNALRSERVICE/WEBPUBSUB/WEBPUBSUB1/SHAREDPRIVATELINKRESOURCES/RESOURCE1", + Error: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := WebPubsubSharedPrivateLinkResourceID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %s", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + if actual.ResourceGroup != v.Expected.ResourceGroup { + t.Fatalf("Expected %q but got %q for ResourceGroup", v.Expected.ResourceGroup, actual.ResourceGroup) + } + if actual.WebPubSubName != v.Expected.WebPubSubName { + t.Fatalf("Expected %q but got %q for WebPubSubName", v.Expected.WebPubSubName, actual.WebPubSubName) + } + if actual.SharedPrivateLinkResourceName != v.Expected.SharedPrivateLinkResourceName { + t.Fatalf("Expected %q but got %q for SharedPrivateLinkResourceName", v.Expected.SharedPrivateLinkResourceName, actual.SharedPrivateLinkResourceName) + } + } +} diff --git a/internal/services/signalr/parse/web_pubsub_test.go b/internal/services/signalr/parse/web_pubsub_test.go index 9e286529d3b0..c2fcc4350570 100644 --- a/internal/services/signalr/parse/web_pubsub_test.go +++ b/internal/services/signalr/parse/web_pubsub_test.go @@ -12,7 +12,7 @@ var _ resourceids.Id = WebPubsubId{} func TestWebPubsubIDFormatter(t *testing.T) { actual := NewWebPubsubID("12345678-1234-9876-4563-123456789012", "resGroup1", "Webpubsub1").ID() - expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/Webpubsub1" + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1" if actual != expected { t.Fatalf("Expected %q but got %q", expected, actual) } @@ -63,13 +63,13 @@ func TestWebPubsubID(t *testing.T) { { // missing value for WebPubSubName - Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/", + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/", Error: true, }, { // valid - Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/Webpubsub1", + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1", Expected: &WebPubsubId{ SubscriptionId: "12345678-1234-9876-4563-123456789012", ResourceGroup: "resGroup1", diff --git a/internal/services/signalr/registration.go b/internal/services/signalr/registration.go index 66258f075dec..e4305c866c0e 100644 --- a/internal/services/signalr/registration.go +++ b/internal/services/signalr/registration.go @@ -29,18 +29,20 @@ 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_signalr_service": dataSourceArmSignalRService(), - "azurerm_web_pubsub": dataSourceWebPubsub(), + "azurerm_signalr_service": dataSourceArmSignalRService(), + "azurerm_web_pubsub": dataSourceWebPubsub(), + "azurerm_web_pubsub_private_link_resource": dataSourceWebPubsubPrivateLinkResource(), } } // SupportedResources returns the supported Resources supported by this Service func (r Registration) SupportedResources() map[string]*pluginsdk.Resource { return map[string]*pluginsdk.Resource{ - "azurerm_signalr_service": resourceArmSignalRService(), - "azurerm_signalr_service_network_acl": resourceArmSignalRServiceNetworkACL(), - "azurerm_web_pubsub": resourceWebPubSub(), - "azurerm_web_pubsub_hub": resourceWebPubsubHub(), - "azurerm_web_pubsub_network_acl": resourceWebpubsubNetworkACL(), + "azurerm_signalr_service": resourceArmSignalRService(), + "azurerm_signalr_service_network_acl": resourceArmSignalRServiceNetworkACL(), + "azurerm_web_pubsub": resourceWebPubSub(), + "azurerm_web_pubsub_hub": resourceWebPubsubHub(), + "azurerm_web_pubsub_network_acl": resourceWebpubsubNetworkACL(), + "azurerm_web_pubsub_shared_private_link_resource": resourceWebpubsubSharedPrivateLinkService(), } } diff --git a/internal/services/signalr/resourceids.go b/internal/services/signalr/resourceids.go index fde5e518291a..6e26df08a2da 100644 --- a/internal/services/signalr/resourceids.go +++ b/internal/services/signalr/resourceids.go @@ -1,4 +1,5 @@ package signalr -//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=WebPubsub -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/Webpubsub1 -//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=WebPubsubHub -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/Webpubsub1/hubs/Webpubsubhub1 +//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=WebPubsub -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1 +//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=WebPubsubHub -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/hubs/Webpubsubhub1 +//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=WebPubsubSharedPrivateLinkResource -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/sharedPrivateLinkResources/resource1 diff --git a/internal/services/signalr/validate/web_pubsub_hub_id_test.go b/internal/services/signalr/validate/web_pubsub_hub_id_test.go index 378cfd76e23c..d37a736e98f5 100644 --- a/internal/services/signalr/validate/web_pubsub_hub_id_test.go +++ b/internal/services/signalr/validate/web_pubsub_hub_id_test.go @@ -48,25 +48,25 @@ func TestWebPubsubHubID(t *testing.T) { { // missing value for WebPubSubName - Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/", + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/", Valid: false, }, { // missing HubName - Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/Webpubsub1/", + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/", Valid: false, }, { // missing value for HubName - Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/Webpubsub1/hubs/", + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/hubs/", Valid: false, }, { // valid - Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/Webpubsub1/hubs/Webpubsubhub1", + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/hubs/Webpubsubhub1", Valid: true, }, diff --git a/internal/services/signalr/validate/web_pubsub_id_test.go b/internal/services/signalr/validate/web_pubsub_id_test.go index 2138c415fe3c..722e8ef3e912 100644 --- a/internal/services/signalr/validate/web_pubsub_id_test.go +++ b/internal/services/signalr/validate/web_pubsub_id_test.go @@ -48,13 +48,13 @@ func TestWebPubsubID(t *testing.T) { { // missing value for WebPubSubName - Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/", + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/", Valid: false, }, { // valid - Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/WebPubSub/Webpubsub1", + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1", Valid: true, }, diff --git a/internal/services/signalr/validate/web_pubsub_shared_private_link_resource_id.go b/internal/services/signalr/validate/web_pubsub_shared_private_link_resource_id.go new file mode 100644 index 000000000000..c3254d22ec0a --- /dev/null +++ b/internal/services/signalr/validate/web_pubsub_shared_private_link_resource_id.go @@ -0,0 +1,23 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + + "github.com/hashicorp/terraform-provider-azurerm/internal/services/signalr/parse" +) + +func WebPubsubSharedPrivateLinkResourceID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := parse.WebPubsubSharedPrivateLinkResourceID(v); err != nil { + errors = append(errors, err) + } + + return +} diff --git a/internal/services/signalr/validate/web_pubsub_shared_private_link_resource_id_test.go b/internal/services/signalr/validate/web_pubsub_shared_private_link_resource_id_test.go new file mode 100644 index 000000000000..fa247d5d6ee8 --- /dev/null +++ b/internal/services/signalr/validate/web_pubsub_shared_private_link_resource_id_test.go @@ -0,0 +1,88 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import "testing" + +func TestWebPubsubSharedPrivateLinkResourceID(t *testing.T) { + cases := []struct { + Input string + Valid bool + }{ + + { + // empty + Input: "", + Valid: false, + }, + + { + // missing SubscriptionId + Input: "/", + Valid: false, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Valid: false, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Valid: false, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Valid: false, + }, + + { + // missing WebPubSubName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/", + Valid: false, + }, + + { + // missing value for WebPubSubName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/", + Valid: false, + }, + + { + // missing SharedPrivateLinkResourceName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/", + Valid: false, + }, + + { + // missing value for SharedPrivateLinkResourceName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/sharedPrivateLinkResources/", + Valid: false, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.SignalRService/webPubSub/Webpubsub1/sharedPrivateLinkResources/resource1", + Valid: true, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.SIGNALRSERVICE/WEBPUBSUB/WEBPUBSUB1/SHAREDPRIVATELINKRESOURCES/RESOURCE1", + Valid: false, + }, + } + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.Input) + _, errors := WebPubsubSharedPrivateLinkResourceID(tc.Input, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t", tc.Valid, valid) + } + } +} diff --git a/internal/services/signalr/web_pubsub_network_acl_resource_test.go b/internal/services/signalr/web_pubsub_network_acl_resource_test.go index 1d2fe0f173b1..ed4702183399 100644 --- a/internal/services/signalr/web_pubsub_network_acl_resource_test.go +++ b/internal/services/signalr/web_pubsub_network_acl_resource_test.go @@ -327,7 +327,11 @@ resource "azurerm_web_pubsub_network_acl" "test" { func (r WebPubsubNetworkACLResource) template(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { - features {} + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + } } resource "azurerm_resource_group" "test" { diff --git a/internal/services/signalr/web_pubsub_private_linked_service_data_source.go b/internal/services/signalr/web_pubsub_private_linked_service_data_source.go new file mode 100644 index 000000000000..76c24b41d575 --- /dev/null +++ b/internal/services/signalr/web_pubsub_private_linked_service_data_source.go @@ -0,0 +1,95 @@ +package signalr + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/signalr/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/signalr/validate" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" +) + +func dataSourceWebPubsubPrivateLinkResource() *pluginsdk.Resource { + return &pluginsdk.Resource{ + Read: dataSourceWebPubsubPrivateLinkResourceRead, + + Timeouts: &pluginsdk.ResourceTimeout{ + Read: pluginsdk.DefaultTimeout(5 * time.Minute), + }, + + Schema: map[string]*pluginsdk.Schema{ + "web_pubsub_id": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validate.WebPubsubID, + }, + + "shared_private_link_resource_types": { + Type: pluginsdk.TypeList, + Computed: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "subresource_name": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "description": { + Type: pluginsdk.TypeString, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceWebPubsubPrivateLinkResourceRead(d *pluginsdk.ResourceData, meta interface{}) error { + privateLinkResourceClient := meta.(*clients.Client).SignalR.WebPubsubPrivateLinkedResourceClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + webPubsubID, err := parse.WebPubsubID(d.Get("web_pubsub_id").(string)) + if err != nil { + return fmt.Errorf("parsing ID of %q: %+v", webPubsubID, err) + } + + resourceList, err := privateLinkResourceClient.List(ctx, webPubsubID.ResourceGroup, webPubsubID.WebPubSubName) + if err != nil { + return fmt.Errorf("retrieving Private Link Resource for Resource %s: %+v", webPubsubID, err) + } + + if resourceList.Values() == nil { + return fmt.Errorf("retrieving Private Link Resource for Resource %s: `resource value` was nil", webPubsubID) + } + + d.SetId(webPubsubID.ID()) + val := resourceList.Values() + + linkTypeList := make([]interface{}, 0) + + for _, v := range val { + if v.PrivateLinkResourceProperties != nil && v.PrivateLinkResourceProperties.ShareablePrivateLinkResourceTypes != nil { + for _, resource := range *v.PrivateLinkResourceProperties.ShareablePrivateLinkResourceTypes { + item := make(map[string]interface{}) + if props := resource.Properties; props != nil { + if props.GroupID != nil { + item["subresource_name"] = props.GroupID + } + if props.Description != nil { + item["description"] = props.Description + } + } + linkTypeList = append(linkTypeList, item) + } + } + } + + if err := d.Set("shared_private_link_resource_types", linkTypeList); err != nil { + return fmt.Errorf("setting `shared_private_link_resource_types` error: %+v", err) + } + return nil +} diff --git a/internal/services/signalr/web_pubsub_private_linked_service_data_source_test.go b/internal/services/signalr/web_pubsub_private_linked_service_data_source_test.go new file mode 100644 index 000000000000..c9a50191d816 --- /dev/null +++ b/internal/services/signalr/web_pubsub_private_linked_service_data_source_test.go @@ -0,0 +1,51 @@ +package signalr_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" +) + +type WebPubsubPrivateLinkedServiceDataSource struct{} + +func TestAccWebPubsubPrivateLinkedService_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_web_pubsub_private_link_resource", "test") + r := WebPubsubPrivateLinkedServiceDataSource{} + + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("shared_private_link_resource_types.#").Exists(), + check.That(data.ResourceName).Key("id").Exists(), + ), + }, + }) +} + +func (r WebPubsubPrivateLinkedServiceDataSource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_web_pubsub" "test" { + name = "acctestWebPubsub-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + sku = "Standard_S1" + capacity = 1 +} + +data "azurerm_web_pubsub_private_link_resource" "test" { + web_pubsub_id = azurerm_web_pubsub.test.id +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger) +} diff --git a/internal/services/signalr/web_pubsub_shared_private_link_resource.go b/internal/services/signalr/web_pubsub_shared_private_link_resource.go new file mode 100644 index 000000000000..85e78ee08f08 --- /dev/null +++ b/internal/services/signalr/web_pubsub_shared_private_link_resource.go @@ -0,0 +1,189 @@ +package signalr + +import ( + "fmt" + "time" + + "github.com/Azure/azure-sdk-for-go/services/webpubsub/mgmt/2021-10-01/webpubsub" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" + "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + networkValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/validate" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/signalr/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/signalr/validate" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" + "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +func resourceWebpubsubSharedPrivateLinkService() *pluginsdk.Resource { + return &pluginsdk.Resource{ + Create: resourceWebPubsubSharedPrivateLinkServiceCreateUpdate, + Read: resourceWebPubsubSharedPrivateLinkServiceRead, + Update: resourceWebPubsubSharedPrivateLinkServiceCreateUpdate, + Delete: resourceWebPubsubSharedPrivateLinkServiceDelete, + + Timeouts: &pluginsdk.ResourceTimeout{ + Create: pluginsdk.DefaultTimeout(30 * time.Minute), + Read: pluginsdk.DefaultTimeout(5 * time.Minute), + Update: pluginsdk.DefaultTimeout(30 * time.Minute), + Delete: pluginsdk.DefaultTimeout(30 * time.Minute), + }, + + Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { + _, err := parse.WebPubsubSharedPrivateLinkResourceID(id) + return err + }), + + Schema: map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "web_pubsub_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.WebPubsubID, + }, + + "subresource_name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: networkValidate.PrivateLinkSubResourceName, + }, + + "target_resource_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "request_message": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "status": { + Type: pluginsdk.TypeString, + Computed: true, + }, + }, + } +} + +func resourceWebPubsubSharedPrivateLinkServiceCreateUpdate(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).SignalR.WebPubsubSharedPrivateLinkResourceClient + subscriptionId := meta.(*clients.Client).Account.SubscriptionId + ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) + defer cancel() + + webPubsubID, err := parse.WebPubsubID(d.Get("web_pubsub_id").(string)) + if err != nil { + return fmt.Errorf("parsing ID of %q: %+v", webPubsubID, err) + } + + id := parse.NewWebPubsubSharedPrivateLinkResourceID(subscriptionId, webPubsubID.ResourceGroup, webPubsubID.WebPubSubName, d.Get("name").(string)) + + if d.IsNewResource() { + existing, err := client.Get(ctx, id.SharedPrivateLinkResourceName, id.ResourceGroup, id.WebPubSubName) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("checking for existing %q: %+v", id, err) + } + } + if !utils.ResponseWasNotFound(existing.Response) { + return tf.ImportAsExistsError("azurerm_web_pubsub_shared_private_link_resource", id.ID()) + } + } + + parameters := webpubsub.SharedPrivateLinkResource{ + SharedPrivateLinkResourceProperties: &webpubsub.SharedPrivateLinkResourceProperties{ + GroupID: utils.String(d.Get("subresource_name").(string)), + PrivateLinkResourceID: utils.String(d.Get("target_resource_id").(string)), + }, + } + + requestMessage := d.Get("request_message").(string) + if requestMessage != "" { + parameters.SharedPrivateLinkResourceProperties.RequestMessage = utils.String(requestMessage) + } + + if _, err := client.CreateOrUpdate(ctx, id.SharedPrivateLinkResourceName, parameters, id.ResourceGroup, id.WebPubSubName); err != nil { + return err + } + + d.SetId(id.ID()) + + return resourceWebPubsubSharedPrivateLinkServiceRead(d, meta) +} +func resourceWebPubsubSharedPrivateLinkServiceRead(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).SignalR.WebPubsubSharedPrivateLinkResourceClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.WebPubsubSharedPrivateLinkResourceID(d.Id()) + if err != nil { + return err + } + + resp, err := client.Get(ctx, id.SharedPrivateLinkResourceName, id.ResourceGroup, id.WebPubSubName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return fmt.Errorf("%q was not found", id) + } + return fmt.Errorf("making request on %q: %+v", id, err) + } + + d.Set("name", resp.Name) + d.Set("web_pubsub_id", parse.NewWebPubsubID(id.SubscriptionId, id.ResourceGroup, id.WebPubSubName).ID()) + + if props := resp.SharedPrivateLinkResourceProperties; props != nil { + if props.GroupID != nil { + d.Set("subresource_name", props.GroupID) + } + + if props.PrivateLinkResourceID != nil { + d.Set("target_resource_id", props.PrivateLinkResourceID) + } + + if props.RequestMessage != nil { + d.Set("request_message", props.RequestMessage) + } + + d.Set("status", props.Status) + } + + return nil +} +func resourceWebPubsubSharedPrivateLinkServiceDelete(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).SignalR.WebPubsubSharedPrivateLinkResourceClient + ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.WebPubsubSharedPrivateLinkResourceID(d.Id()) + if err != nil { + return err + } + + future, err := client.Delete(ctx, id.SharedPrivateLinkResourceName, id.ResourceGroup, id.WebPubSubName) + if err != nil { + return fmt.Errorf("deleting %q: %+v", id, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("waiting for deleting %q: %+v", id, err) + } + } + return nil +} diff --git a/internal/services/signalr/web_pubsub_shared_private_link_resource_test.go b/internal/services/signalr/web_pubsub_shared_private_link_resource_test.go new file mode 100644 index 000000000000..d7712163e892 --- /dev/null +++ b/internal/services/signalr/web_pubsub_shared_private_link_resource_test.go @@ -0,0 +1,138 @@ +package signalr_test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/signalr/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type WebPubsubSharedPrivateLinkResource struct{} + +func TestAccWebPubsubSharedPrivateLinkResource_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_web_pubsub_shared_private_link_resource", "test") + r := WebPubsubSharedPrivateLinkResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r)), + }, + data.ImportStep(), + }) +} + +func TestAccWebPubsubSharedPrivateLinkResource_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_web_pubsub_shared_private_link_resource", "test") + r := WebPubsubSharedPrivateLinkResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.RequiresImportErrorStep(r.requiresImport), + }) +} +func (r WebPubsubSharedPrivateLinkResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := parse.WebPubsubSharedPrivateLinkResourceID(state.ID) + if err != nil { + return nil, err + } + + resp, err := clients.SignalR.WebPubsubSharedPrivateLinkResourceClient.Get(ctx, id.SharedPrivateLinkResourceName, id.ResourceGroup, id.WebPubSubName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return utils.Bool(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", *id, err) + } + + return utils.Bool(true), nil +} + +func (r WebPubsubSharedPrivateLinkResource) basic(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_key_vault" "test" { + name = "vault%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + tenant_id = data.azurerm_client_config.current.tenant_id + sku_name = "standard" + soft_delete_retention_days = 7 + + access_policy { + tenant_id = data.azurerm_client_config.current.tenant_id + object_id = data.azurerm_client_config.current.object_id + + certificate_permissions = [ + "ManageContacts", + ] + + key_permissions = [ + "Create", + ] + + secret_permissions = [ + "Set", + ] + } +} + +resource "azurerm_web_pubsub_shared_private_link_resource" "test" { + name = "acctest-%d" + web_pubsub_id = azurerm_web_pubsub.test.id + subresource_name = "vault" + target_resource_id = azurerm_key_vault.test.id +} +`, template, data.RandomInteger, data.RandomInteger) +} + +func (r WebPubsubSharedPrivateLinkResource) requiresImport(data acceptance.TestData) string { + config := r.basic(data) + return fmt.Sprintf(` +%s + +resource "azurerm_web_pubsub_shared_private_link_resource" "import" { + name = azurerm_web_pubsub_shared_private_link_resource.test.name + web_pubsub_id = azurerm_web_pubsub_shared_private_link_resource.test.web_pubsub_id + subresource_name = azurerm_web_pubsub_shared_private_link_resource.test.subresource_name + target_resource_id = azurerm_web_pubsub_shared_private_link_resource.test.target_resource_id +} +`, config) +} + +func (r WebPubsubSharedPrivateLinkResource) template(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-wps-%d" + location = "%s" +} + +resource "azurerm_web_pubsub" "test" { + name = "acctestWebPubsub-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + sku = "Standard_S1" + capacity = 1 +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger) +} diff --git a/website/docs/d/web_pubsub_private_link_resource.html.markdown b/website/docs/d/web_pubsub_private_link_resource.html.markdown new file mode 100644 index 000000000000..0553874e3fc6 --- /dev/null +++ b/website/docs/d/web_pubsub_private_link_resource.html.markdown @@ -0,0 +1,58 @@ +--- +subcategory: "Web PubSub" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_web_pubsub_private_link_resource" +description: |- + Gets information about the Private Link Resource supported by the Web Pubsub Resource. +--- + +# Data Source: azurerm_web_pubsub_private_link_resource + +Use this data source to access information about the Private Link Resource supported by the Web Pubsub Resource. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "terraform-webpubsub" + location = "east us" +} + +resource "azurerm_web_pubsub" "test" { + name = "tfex-webpubsub" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + sku = "Standard_S1" + capacity = 1 +} + +data "azurerm_web_pubsub_private_link_resource" "test" { + web_pubsub_id = azurerm_web_pubsub.test.id +} +``` + +## Argument Reference + +* `web_pubsub_id` - The ID of an existing Web Pubsub Resource which Private Link Resource should be retrieved for. + +## Attributes Reference + +* `id` - The ID of an existing Web Pubsub Resource which supports the retrieved Private Link Resource list. + +* `shared_private_link_resource_types` - A `shared_private_link_resource_types` block as defined below. + +--- + +A `shared_private_link_resource_types` block exports the following: + +* `subresource_name` - The name for the resource that has been onboarded to private link service. + +* `description` - The description of the resource type that has been onboarded to private link service. + + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `read` - (Defaults to 5 minutes) Used when retrieving the Private Link Resource. + diff --git a/website/docs/r/web_pubsub_shared_private_link.html.markdown b/website/docs/r/web_pubsub_shared_private_link.html.markdown new file mode 100644 index 000000000000..f5b0d5862f69 --- /dev/null +++ b/website/docs/r/web_pubsub_shared_private_link.html.markdown @@ -0,0 +1,107 @@ +--- +subcategory: "Web PubSub" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_web_pubsub_shared_private_link_resource" +description: |- + Manages the Shared Private Link Resource for a Web Pubsub service. +--- + +# azurerm_web_pubsub_shared_private_link_resource + +Manages the Shared Private Link Resource for a Web Pubsub service. + +## Example Usage + +```hcl +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "example" { + name = "terraform-webpubsub" + location = "east us" +} + +resource "azurerm_key_vault" "example" { + name = "examplekeyvault" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + tenant_id = data.azurerm_client_config.current.tenant_id + sku_name = "standard" + soft_delete_retention_days = 7 + + access_policy { + tenant_id = data.azurerm_client_config.current.tenant_id + object_id = data.azurerm_client_config.current.object_id + + certificate_permissions = [ + "managecontacts", + ] + + key_permissions = [ + "create", + ] + + secret_permissions = [ + "set", + ] + } +} + +resource "azurerm_web_pubsub" "example" { + name = "tfex-webpubsub" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + sku = "Standard_S1" + capacity = 1 +} + +resource "azurerm_web_pubsub_shared_private_link_resource" "example" { + name = "tfex-webpubsub-splr" + web_pubsub_id = azurerm_web_pubsub.example.id + subresource_name = "vault" + target_resource_id = azurerm_key_vault.example.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specify the name of the Web Pubsub Shared Private Link Resource. Changing this forces a new resource to be created. + +* `web_pubsub_id` - (Required) Specify the id of the Web Pubsub. Changing this forces a new resource to be created. + +* `subresource_name` - (Required) Specify the sub resource name which the Web Pubsub Private Endpoint is able to connect to. Changing this forces a new resource to be created. + +-> **NOTE:** The available sub resource can be retrieved by using `azurerm_web_pubsub_private_link_resource` data source. + +* `target_resource_id` - (Required) Specify the ID of the Shared Private Link Enabled Remote Resource which this Web Pubsub Private Endpoint should be connected to. Changing this forces a new resource to be created. + +-> **NOTE:** The sub resource name should match with the type of the target resource id that's being specified. + +* `request_message` - (Optional) Specify the request message for requesting approval of the Shared Private Link Enabled Remote Resource. + +## Attributes Reference: + +The following attributes are exported: + +* `id` - The ID of the Web Pubsub Shared Private Link resource. + +* `status` - The status of a private endpoint connection. Possible values are Pending, Approved, Rejected or Disconnected. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `create` - (Defaults to 30 minutes) Used when creating the Web Pubsub Shared Private Link Resource. +* `update` - (Defaults to 30 minutes) Used when updating the Web Pubsub Shared Private Link Resource. +* `read` - (Defaults to 5 minutes) Used when retrieving the Web Pubsub Shared Private Link Resource. +* `delete` - (Defaults to 30 minutes) Used when deleting the Web Pubsub Shared Private Link Resource. + +## Import + +Web Pubsub Shared Private Link Resource can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_web_pubsub_shared_private_link_resource.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.SignalRService/webPubsub/webpubsub1/sharedPrivateLinkResources/resource1 +``` +