Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New resource azurerm_digital_twins_endpoint_eventgrid #9489

Merged
merged 26 commits into from
Dec 3, 2020
Merged
Show file tree
Hide file tree
Changes from 20 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
5 changes: 5 additions & 0 deletions azurerm/internal/services/digitaltwins/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ import (
)

type Client struct {
EndpointClient *digitaltwins.EndpointClient
InstanceClient *digitaltwins.Client
}

func NewClient(o *common.ClientOptions) *Client {
endpointClient := digitaltwins.NewEndpointClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&endpointClient.Client, o.ResourceManagerAuthorizer)

InstanceClient := digitaltwins.NewClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&InstanceClient.Client, o.ResourceManagerAuthorizer)

return &Client{
EndpointClient: &endpointClient,
InstanceClient: &InstanceClient,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
package digitaltwins

import (
"fmt"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/digitaltwins/mgmt/2020-10-31/digitaltwins"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/digitaltwins/parse"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/digitaltwins/validate"
azSchema "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmDigitalTwinsEndpointEventGrid() *schema.Resource {
return &schema.Resource{
Create: resourceArmDigitalTwinsEndpointEventGridCreateUpdate,
Read: resourceArmDigitalTwinsEndpointEventGridRead,
Update: resourceArmDigitalTwinsEndpointEventGridCreateUpdate,
Delete: resourceArmDigitalTwinsEndpointEventGridDelete,

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(30 * time.Minute),
Read: schema.DefaultTimeout(5 * time.Minute),
Update: schema.DefaultTimeout(30 * time.Minute),
Delete: schema.DefaultTimeout(30 * time.Minute),
},

Importer: azSchema.ValidateResourceIDPriorToImport(func(id string) error {
_, err := parse.DigitalTwinsEndpointID(id)
return err
}),

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.DigitaltwinsInstanceName,
},

"digital_twins_instance_id": {
yupwei68 marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.DigitaltwinsInstanceID,
},

"eventgrid_topic_endpoint": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.IsURLWithHTTPS,
},

"eventgrid_topic_primary_access_key": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"eventgrid_topic_secondary_access_key": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"dead_letter_storage_secret": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringIsNotEmpty,
},
},
}
}
func resourceArmDigitalTwinsEndpointEventGridCreateUpdate(d *schema.ResourceData, meta interface{}) error {
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
client := meta.(*clients.Client).DigitalTwins.EndpointClient
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

name := d.Get("name").(string)
digitalTwinsInstanceId, _ := parse.DigitalTwinsInstanceID(d.Get("digital_twins_instance_id").(string))
yupwei68 marked this conversation as resolved.
Show resolved Hide resolved

id := parse.NewDigitalTwinsEndpointID(subscriptionId, digitalTwinsInstanceId.ResourceGroup, digitalTwinsInstanceId.Name, name).ID("")

if d.IsNewResource() {
existing, err := client.Get(ctx, digitalTwinsInstanceId.ResourceGroup, digitalTwinsInstanceId.Name, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("checking for present of existing Digital Twins Endpoint %q (Resource Group %q / Digital Twins Instance Name %q): %+v", name, digitalTwinsInstanceId.ResourceGroup, digitalTwinsInstanceId.Name, err)
}
}
if !utils.ResponseWasNotFound(existing.Response) {
return tf.ImportAsExistsError("azurerm_digital_twins_endpoint_eventgrid", id)
}
}

properties := digitaltwins.EndpointResource{
Properties: &digitaltwins.EventGrid{
EndpointType: digitaltwins.EndpointTypeEventGrid,
TopicEndpoint: utils.String(d.Get("eventgrid_topic_endpoint").(string)),
AccessKey1: utils.String(d.Get("eventgrid_topic_primary_access_key").(string)),
AccessKey2: utils.String(d.Get("eventgrid_topic_secondary_access_key").(string)),
DeadLetterSecret: utils.String(d.Get("dead_letter_storage_secret").(string)),
},
}

future, err := client.CreateOrUpdate(ctx, digitalTwinsInstanceId.ResourceGroup, digitalTwinsInstanceId.Name, name, properties)
if err != nil {
return fmt.Errorf("creating/updating Digital Twins EventGrid Endpoint %q (Resource Group %q / Digital Twins Instance Name %q): %+v", name, digitalTwinsInstanceId.ResourceGroup, digitalTwinsInstanceId.Name, err)
yupwei68 marked this conversation as resolved.
Show resolved Hide resolved
}

if err := future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("waiting for creation/update of the Digital Twins EventGrid Endpoint %q (Resource Group %q / Digital Twins Instance Name %q): %+v", name, digitalTwinsInstanceId.ResourceGroup, digitalTwinsInstanceId.Name, err)
yupwei68 marked this conversation as resolved.
Show resolved Hide resolved
}

if _, err := client.Get(ctx, digitalTwinsInstanceId.ResourceGroup, digitalTwinsInstanceId.Name, name); err != nil {
return fmt.Errorf("retrieving Digital Twins EventGrid Endpoint %q (Resource Group %q / Digital Twins Instance Name %q): %+v", name, digitalTwinsInstanceId.ResourceGroup, digitalTwinsInstanceId.Name, err)
yupwei68 marked this conversation as resolved.
Show resolved Hide resolved
}

d.SetId(id)

return resourceArmDigitalTwinsEndpointEventGridRead(d, meta)
}

func resourceArmDigitalTwinsEndpointEventGridRead(d *schema.ResourceData, meta interface{}) error {
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
client := meta.(*clients.Client).DigitalTwins.EndpointClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

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

resp, err := client.Get(ctx, id.ResourceGroup, id.DigitalTwinsInstanceName, id.EndpointName)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[INFO] Digital Twins EventGrid Endpoint %q does not exist - removing from state", d.Id())
d.SetId("")
return nil
}
return fmt.Errorf("retrieving Digital Twins EventGrid Endpoint %q (Resource Group %q / Digital Twins Instance Name %q): %+v", id.EndpointName, id.ResourceGroup, id.DigitalTwinsInstanceName, err)
yupwei68 marked this conversation as resolved.
Show resolved Hide resolved
}
d.Set("name", id.EndpointName)
d.Set("digital_twins_instance_id", parse.NewDigitalTwinsInstanceID(subscriptionId, id.ResourceGroup, id.DigitalTwinsInstanceName).ID(""))
if resp.Properties != nil {
if _, ok := resp.Properties.AsEventGrid(); !ok {
return fmt.Errorf("retrieving Digital Twins Endpoint %q (Resource Group %q / Digital Twins Instance Name %q) is not type Event Grid", id.EndpointName, id.ResourceGroup, id.DigitalTwinsInstanceName)
yupwei68 marked this conversation as resolved.
Show resolved Hide resolved
}
}

return nil
}

func resourceArmDigitalTwinsEndpointEventGridDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).DigitalTwins.EndpointClient
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
defer cancel()

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

future, err := client.Delete(ctx, id.ResourceGroup, id.DigitalTwinsInstanceName, id.EndpointName)
if err != nil {
return fmt.Errorf("deleting Digital Twins EventGrid Endpoint %q (Resource Group %q / Digital Twins Instance Name %q): %+v", id.EndpointName, id.ResourceGroup, id.DigitalTwinsInstanceName, err)
yupwei68 marked this conversation as resolved.
Show resolved Hide resolved
}

if err := future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("waiting for deletion of the Digital Twins EventGrid Endpoint %q (Resource Group %q / Digital Twins Instance Name %q): %+v", id.EndpointName, id.ResourceGroup, id.DigitalTwinsInstanceName, err)
yupwei68 marked this conversation as resolved.
Show resolved Hide resolved
}
return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"fmt"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
)

type DigitalTwinsEndpointId struct {
SubscriptionId string
ResourceGroup string
DigitalTwinsInstanceName string
WodansSon marked this conversation as resolved.
Show resolved Hide resolved
EndpointName string
WodansSon marked this conversation as resolved.
Show resolved Hide resolved
}

func NewDigitalTwinsEndpointID(subscriptionId, resourceGroup, digitalTwinsInstanceName, endpointName string) DigitalTwinsEndpointId {
WodansSon marked this conversation as resolved.
Show resolved Hide resolved
return DigitalTwinsEndpointId{
SubscriptionId: subscriptionId,
ResourceGroup: resourceGroup,
DigitalTwinsInstanceName: digitalTwinsInstanceName,
WodansSon marked this conversation as resolved.
Show resolved Hide resolved
EndpointName: endpointName,
WodansSon marked this conversation as resolved.
Show resolved Hide resolved
}
}

func (id DigitalTwinsEndpointId) ID(_ string) string {
fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.DigitalTwins/digitalTwinsInstances/%s/endpoints/%s"
return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.DigitalTwinsInstanceName, id.EndpointName)
WodansSon marked this conversation as resolved.
Show resolved Hide resolved
}

func DigitalTwinsEndpointID(input string) (*DigitalTwinsEndpointId, error) {
id, err := azure.ParseAzureResourceID(input)
if err != nil {
return nil, err
}

resourceId := DigitalTwinsEndpointId{
WodansSon marked this conversation as resolved.
Show resolved Hide resolved
SubscriptionId: id.SubscriptionID,
ResourceGroup: id.ResourceGroup,
}

if resourceId.DigitalTwinsInstanceName, err = id.PopSegment("digitalTwinsInstances"); err != nil {
WodansSon marked this conversation as resolved.
Show resolved Hide resolved
return nil, err
}
if resourceId.EndpointName, err = id.PopSegment("endpoints"); err != nil {
WodansSon marked this conversation as resolved.
Show resolved Hide resolved
return nil, err
}

if err := id.ValidateNoEmptySegments(input); err != nil {
return nil, err
}

return &resourceId, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package parse
WodansSon marked this conversation as resolved.
Show resolved Hide resolved

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"testing"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid"
)

var _ resourceid.Formatter = DigitalTwinsEndpointId{}

func TestDigitalTwinsEndpointIDFormatter(t *testing.T) {
actual := NewDigitalTwinsEndpointID("12345678-1234-9876-4563-123456789012", "group1", "instance1", "endpoint1").ID("")
expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/Microsoft.DigitalTwins/digitalTwinsInstances/instance1/endpoints/endpoint1"
if actual != expected {
t.Fatalf("Expected %q but got %q", expected, actual)
}
}

func TestDigitalTwinsEndpointID(t *testing.T) {
testData := []struct {
Input string
Error bool
Expected *DigitalTwinsEndpointId
}{

{
// 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 DigitalTwinsInstanceName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/Microsoft.DigitalTwins/",
Error: true,
},

{
// missing value for DigitalTwinsInstanceName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/Microsoft.DigitalTwins/digitalTwinsInstances/",
Error: true,
},

{
// missing EndpointName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/Microsoft.DigitalTwins/digitalTwinsInstances/instance1/",
Error: true,
},

{
// missing value for EndpointName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/Microsoft.DigitalTwins/digitalTwinsInstances/instance1/endpoints/",
Error: true,
},

{
// valid
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/Microsoft.DigitalTwins/digitalTwinsInstances/instance1/endpoints/endpoint1",
Expected: &DigitalTwinsEndpointId{
SubscriptionId: "12345678-1234-9876-4563-123456789012",
ResourceGroup: "group1",
DigitalTwinsInstanceName: "instance1",
EndpointName: "endpoint1",
},
},

{
// upper-cased
Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/GROUP1/PROVIDERS/MICROSOFT.DIGITALTWINS/DIGITALTWINSINSTANCES/INSTANCE1/ENDPOINTS/ENDPOINT1",
Error: true,
},
}

for _, v := range testData {
t.Logf("[DEBUG] Testing %q", v.Input)

actual, err := DigitalTwinsEndpointID(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.DigitalTwinsInstanceName != v.Expected.DigitalTwinsInstanceName {
t.Fatalf("Expected %q but got %q for DigitalTwinsInstanceName", v.Expected.DigitalTwinsInstanceName, actual.DigitalTwinsInstanceName)
}
if actual.EndpointName != v.Expected.EndpointName {
t.Fatalf("Expected %q but got %q for EndpointName", v.Expected.EndpointName, actual.EndpointName)
}
}
}
3 changes: 2 additions & 1 deletion azurerm/internal/services/digitaltwins/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource {
// SupportedResources returns the supported Resources supported by this Service
func (r Registration) SupportedResources() map[string]*schema.Resource {
return map[string]*schema.Resource{
"azurerm_digital_twins_instance": resourceArmDigitalTwinsInstance(),
"azurerm_digital_twins_instance": resourceArmDigitalTwinsInstance(),
"azurerm_digital_twins_endpoint_eventgrid": resourceArmDigitalTwinsEndpointEventGrid(),
}
}
Loading