Skip to content

Commit

Permalink
New Resourece: azurerm_signalr_shared_private_link_resource (#16187)
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaxyi authored Jul 29, 2022
1 parent 8c89a5a commit 15cfe83
Show file tree
Hide file tree
Showing 4 changed files with 460 additions and 0 deletions.
1 change: 1 addition & 0 deletions internal/services/signalr/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func (r Registration) SupportedResources() map[string]*pluginsdk.Resource {
return map[string]*pluginsdk.Resource{
"azurerm_signalr_service": resourceArmSignalRService(),
"azurerm_signalr_service_network_acl": resourceArmSignalRServiceNetworkACL(),
"azurerm_signalr_shared_private_link_resource": resourceSignalRSharedPrivateLinkResource(),
"azurerm_web_pubsub": resourceWebPubSub(),
"azurerm_web_pubsub_hub": resourceWebPubsubHub(),
"azurerm_web_pubsub_network_acl": resourceWebpubsubNetworkACL(),
Expand Down
177 changes: 177 additions & 0 deletions internal/services/signalr/signalr_shared_private_link_resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package signalr

import (
"fmt"
"time"

"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/resource-manager/signalr/2022-02-01/signalr"
"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/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 resourceSignalRSharedPrivateLinkResource() *pluginsdk.Resource {
return &pluginsdk.Resource{
Create: resourceSignalRSharedPrivateLinkCreateUpdate,
Read: resourceSignalRSharedPrivateLinkRead,
Update: resourceSignalRSharedPrivateLinkCreateUpdate,
Delete: resourceSignalrSharedPrivateLinkDelete,

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 := signalr.ParseSharedPrivateLinkResourceIDInsensitively(id)
return err
}),

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

"signalr_service_id": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: signalr.ValidateSignalRID,
},

"sub_resource_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 resourceSignalRSharedPrivateLinkCreateUpdate(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).SignalR.SignalRClient
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

signalrID, err := signalr.ParseSignalRID(d.Get("signalr_service_id").(string))
if err != nil {
return fmt.Errorf("parsing ID of %s: %+v", signalrID, err)
}

id := signalr.NewSharedPrivateLinkResourceID(subscriptionId, signalrID.ResourceGroupName, signalrID.ResourceName, d.Get("name").(string))
if d.IsNewResource() {
existing, err := client.SharedPrivateLinkResourcesGet(ctx, id)
if err != nil {
if !response.WasNotFound(existing.HttpResponse) {
return fmt.Errorf("checking for existing %q: %+v", id, err)
}
}
if !response.WasNotFound(existing.HttpResponse) {
return tf.ImportAsExistsError("azurerm_signalr_shared_private_link_resource", id.ID())
}
}

parameters := signalr.SharedPrivateLinkResource{
Properties: &signalr.SharedPrivateLinkResourceProperties{
GroupId: d.Get("sub_resource_name").(string),
PrivateLinkResourceId: d.Get("target_resource_id").(string),
},
}

requestMessage := d.Get("request_message").(string)
if requestMessage != "" {
parameters.Properties.RequestMessage = utils.String(requestMessage)
}

if err := client.SharedPrivateLinkResourcesCreateOrUpdateThenPoll(ctx, id, parameters); err != nil {
return fmt.Errorf("creating the shared private link for signalr %s: %+v", id, err)
}

d.SetId(id.ID())
return resourceSignalRSharedPrivateLinkRead(d, meta)
}

func resourceSignalRSharedPrivateLinkRead(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).SignalR.SignalRClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := signalr.ParseSharedPrivateLinkResourceID(d.Id())
if err != nil {
return err
}

resp, err := client.SharedPrivateLinkResourcesGet(ctx, *id)
if err != nil {
if response.WasNotFound(resp.HttpResponse) {
d.SetId("")
return fmt.Errorf("%s was not found", id)
}
return fmt.Errorf("retrieving shared private link %s: %+v", id, err)
}

if model := resp.Model; model != nil {
d.Set("name", model.Name)
d.Set("signalr_service_id", signalr.NewSignalRID(id.SubscriptionId, id.ResourceGroupName, id.ResourceName).ID())

if props := model.Properties; props != nil {
d.Set("sub_resource_name", props.GroupId)
d.Set("target_resource_id", props.PrivateLinkResourceId)

if props.RequestMessage != nil {
d.Set("request_message", props.RequestMessage)
}

status := string(*props.Status)
d.Set("status", status)
}
}
return nil
}

func resourceSignalrSharedPrivateLinkDelete(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).SignalR.SignalRClient
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := signalr.ParseSharedPrivateLinkResourceIDInsensitively(d.Id())
if err != nil {
return err
}

if err := client.SharedPrivateLinkResourcesDeleteThenPoll(ctx, *id); err != nil {
return fmt.Errorf("deleting %s: %+v", id, err)
}
return nil
}
179 changes: 179 additions & 0 deletions internal/services/signalr/signalr_shared_private_link_resource_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package signalr_test

import (
"context"
"fmt"
"testing"

"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/resource-manager/signalr/2022-02-01/signalr"
"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/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

type SignalrSharedPrivateLinkResource struct{}

func TestAccSignalrSharedPrivateLinkResource_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_signalr_shared_private_link_resource", "test")
r := SignalrSharedPrivateLinkResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r)),
},
data.ImportStep(),
})
}

func TestAccSignalrSharedPrivateLinkResource_basicSites(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_signalr_shared_private_link_resource", "test")
r := SignalrSharedPrivateLinkResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.basicSites(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r)),
},
data.ImportStep(),
})
}

func TestAccSignalrSharedPrivateLinkResource_requiresImport(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_signalr_shared_private_link_resource", "test")
r := SignalrSharedPrivateLinkResource{}

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 SignalrSharedPrivateLinkResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
id, err := signalr.ParseSharedPrivateLinkResourceIDInsensitively(state.ID)
if err != nil {
return nil, err
}
resp, err := clients.SignalR.SignalRClient.SharedPrivateLinkResourcesGet(ctx, *id)
if err != nil {
if response.WasNotFound(resp.HttpResponse) {
return utils.Bool(false), nil
}
return nil, fmt.Errorf("retrieving %s: %+v", id, err)
}
return utils.Bool(true), nil
}

func (r SignalrSharedPrivateLinkResource) 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_signalr_shared_private_link_resource" "test" {
name = "acctest-%d"
signalr_service_id = azurerm_signalr_service.test.id
sub_resource_name = "vault"
target_resource_id = azurerm_key_vault.test.id
request_message = "please approve"
}
`, template, data.RandomInteger, data.RandomInteger)
}

func (r SignalrSharedPrivateLinkResource) requiresImport(data acceptance.TestData) string {
config := r.basic(data)
return fmt.Sprintf(`
%s
resource "azurerm_signalr_shared_private_link_resource" "import" {
name = azurerm_signalr_shared_private_link_resource.test.name
signalr_service_id = azurerm_signalr_shared_private_link_resource.test.signalr_service_id
sub_resource_name = azurerm_signalr_shared_private_link_resource.test.sub_resource_name
target_resource_id = azurerm_signalr_shared_private_link_resource.test.target_resource_id
}
`, config)
}

func (r SignalrSharedPrivateLinkResource) basicSites(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_service_plan" "test" {
name = "acctestASP-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
os_type = "Windows"
sku_name = "S1"
}
resource "azurerm_windows_web_app" "test" {
name = "acctestWA-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
service_plan_id = azurerm_service_plan.test.id
site_config {}
}
resource "azurerm_signalr_shared_private_link_resource" "test" {
name = "acctest-%d"
signalr_service_id = azurerm_signalr_service.test.id
sub_resource_name = "sites"
target_resource_id = azurerm_windows_web_app.test.id
request_message = "please approve"
}
`, r.template(data), data.RandomInteger, data.RandomInteger, data.RandomInteger)
}
func (SignalrSharedPrivateLinkResource) template(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
data "azurerm_client_config" "current" {}
resource "azurerm_resource_group" "test" {
name = "acctestRG-signalr-%d"
location = "%s"
}
resource "azurerm_signalr_service" "test" {
name = "acctestSignalr-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
sku {
name = "Standard_S1"
capacity = 1
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}
Loading

0 comments on commit 15cfe83

Please sign in to comment.