Skip to content

Commit

Permalink
New Resource/Datasource azurerm_storage_sync_group (#8462)
Browse files Browse the repository at this point in the history
  • Loading branch information
yupwei68 authored Sep 17, 2020
1 parent 35d1689 commit 2ad8be4
Show file tree
Hide file tree
Showing 12 changed files with 639 additions and 0 deletions.
5 changes: 5 additions & 0 deletions azurerm/internal/services/storage/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Client struct {
CachesClient *storagecache.CachesClient
StorageTargetsClient *storagecache.StorageTargetsClient
SyncServiceClient *storagesync.ServicesClient
StoragesyncGroupClient storagesync.SyncGroupsClient
SubscriptionId string

environment az.Environment
Expand Down Expand Up @@ -57,6 +58,9 @@ func NewClient(options *common.ClientOptions) *Client {
syncServiceClient := storagesync.NewServicesClientWithBaseURI(options.ResourceManagerEndpoint, options.SubscriptionId)
options.ConfigureClient(&syncServiceClient.Client, options.ResourceManagerAuthorizer)

storagesyncgroupClient := storagesync.NewSyncGroupsClientWithBaseURI(options.ResourceManagerEndpoint, options.SubscriptionId)
options.ConfigureClient(&storagesyncgroupClient.Client, options.ResourceManagerAuthorizer)

// TODO: switch Storage Containers to using the storage.BlobContainersClient
// (which should fix #2977) when the storage clients have been moved in here
client := Client{
Expand All @@ -68,6 +72,7 @@ func NewClient(options *common.ClientOptions) *Client {
SubscriptionId: options.SubscriptionId,
StorageTargetsClient: &storageTargetsClient,
SyncServiceClient: &syncServiceClient,
StoragesyncGroupClient: storagesyncgroupClient,
environment: options.Environment,
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package storage

import (
"fmt"
"log"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/storage/parsers"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/storage/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func dataSourceArmStorageSyncGroup() *schema.Resource {
return &schema.Resource{
Read: dataSourceArmStorageSyncGroupRead,

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

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

"storage_sync_id": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validate.StorageSyncId,
},
},
}
}

func dataSourceArmStorageSyncGroupRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Storage.StoragesyncGroupClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

name := d.Get("name").(string)
ssID := d.Get("storage_sync_id").(string)
ssId, _ := parsers.ParseStorageSyncID(ssID)

resp, err := client.Get(ctx, ssId.ResourceGroup, ssId.Name, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[INFO] Storage Sync Group %q does not exist - removing from state", name)
d.SetId("")
return nil
}
return fmt.Errorf("reading Storage Sync Group %q (Storage Sync Name %q / Resource Group %q): %+v", name, ssId.Name, ssId.ResourceGroup, err)
}

if resp.ID == nil || *resp.ID == "" {
return fmt.Errorf("reading Storage Sync Group %q (Storage Sync Name %q /Resource Group %q) ID is empty or nil", name, ssId.Name, ssId.ResourceGroup)
}

d.SetId(*resp.ID)

d.Set("name", name)
d.Set("storage_sync_id", ssID)
return nil
}
31 changes: 31 additions & 0 deletions azurerm/internal/services/storage/parsers/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ type StorageSyncId struct {
ResourceGroup string
}

type StorageSyncGroupId struct {
Name string
StorageSyncName string
ResourceGroup string
}

func ParseAccountID(input string) (*AccountID, error) {
id, err := azure.ParseAzureResourceID(input)
if err != nil {
Expand Down Expand Up @@ -57,3 +63,28 @@ func ParseStorageSyncID(input string) (*StorageSyncId, error) {

return &storageSync, nil
}

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

storageSyncGroup := StorageSyncGroupId{
ResourceGroup: id.ResourceGroup,
}

if storageSyncGroup.StorageSyncName, err = id.PopSegment("storageSyncServices"); err != nil {
return nil, err
}

if storageSyncGroup.Name, err = id.PopSegment("syncGroups"); err != nil {
return nil, err
}

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

return &storageSyncGroup, nil
}
78 changes: 78 additions & 0 deletions azurerm/internal/services/storage/parsers/id_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,81 @@ func TestParseStorageSyncID(t *testing.T) {
}
}
}

func TestParseStorageSyncGroupID(t *testing.T) {
testData := []struct {
Name string
Input string
Expected *StorageSyncGroupId
}{
{
Name: "Empty",
Input: "",
Expected: nil,
},
{
Name: "No Resource Groups Segment",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000",
Expected: nil,
},
{
Name: "No Resource Groups Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/",
Expected: nil,
},
{
Name: "Resource Group ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/",
Expected: nil,
},
{
Name: "Missing Sync Group",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.StorageSync/storageSyncServices/sync1",
Expected: nil,
},
{
Name: "Missing Sync Group Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.StorageSync/storageSyncServices/sync1/syncGroups/",
Expected: nil,
},
{
Name: "Sync Group Id",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.StorageSync/storageSyncServices/sync1/syncGroups/group1",
Expected: &StorageSyncGroupId{
Name: "group1",
StorageSyncName: "sync1",
ResourceGroup: "resGroup1",
},
},
{
Name: "Wrong Casing",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.StorageSync/storageSyncServices/sync1/SyncGroups/group1",
Expected: nil,
},
}

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

actual, err := StorageSyncGroupID(v.Input)
if err != nil {
if v.Expected == nil {
continue
}

t.Fatalf("Expected a value but got an error: %s", err)
}

if actual.Name != v.Expected.Name {
t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name)
}

if actual.StorageSyncName != v.Expected.StorageSyncName {
t.Fatalf("Expected %q but got %q for Storage Sync Name", v.Expected.Name, actual.Name)
}

if actual.ResourceGroup != v.Expected.ResourceGroup {
t.Fatalf("Expected %q but got %q for Resource Group", v.Expected.ResourceGroup, actual.ResourceGroup)
}
}
}
2 changes: 2 additions & 0 deletions azurerm/internal/services/storage/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource {
"azurerm_storage_container": dataSourceArmStorageContainer(),
"azurerm_storage_management_policy": dataSourceArmStorageManagementPolicy(),
"azurerm_storage_sync": dataSourceArmStorageSync(),
"azurerm_storage_sync_group": dataSourceArmStorageSyncGroup(),
}
}

Expand All @@ -49,5 +50,6 @@ func (r Registration) SupportedResources() map[string]*schema.Resource {
"azurerm_storage_table": resourceArmStorageTable(),
"azurerm_storage_table_entity": resourceArmStorageTableEntity(),
"azurerm_storage_sync": resourceArmStorageSync(),
"azurerm_storage_sync_group": resourceArmStorageSyncGroup(),
}
}
142 changes: 142 additions & 0 deletions azurerm/internal/services/storage/resource_arm_storage_sync_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package storage

import (
"fmt"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/storagesync/mgmt/2020-03-01/storagesync"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"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/storage/parsers"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/storage/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 resourceArmStorageSyncGroup() *schema.Resource {
return &schema.Resource{
Create: resourceArmStorageSyncGroupCreate,
Read: resourceArmStorageSyncGroupRead,
Delete: resourceArmStorageSyncGroupDelete,

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

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

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

"storage_sync_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.StorageSyncId,
},
},
}
}

func resourceArmStorageSyncGroupCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Storage.StoragesyncGroupClient
ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d)
defer cancel()

name := d.Get("name").(string)
ssId, _ := parsers.ParseStorageSyncID(d.Get("storage_sync_id").(string))

existing, err := client.Get(ctx, ssId.ResourceGroup, ssId.Name, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("checking for presence of existing Storage Sync Group (Storage Sync Group Name %q / Storage Sync Name %q /Resource Group %q): %+v", name, ssId.Name, ssId.ResourceGroup, err)
}
}
if existing.ID != nil && *existing.ID != "" {
return tf.ImportAsExistsError("azurerm_storage_sync_group", *existing.ID)
}

if _, err := client.Create(ctx, ssId.ResourceGroup, ssId.Name, name, storagesync.SyncGroupCreateParameters{}); err != nil {
return fmt.Errorf("creating Storage Sync Group (Storage Sync Group Name %q / Storage Sync Name %q /Resource Group %q): %+v", name, ssId.Name, ssId.ResourceGroup, err)
}

resp, err := client.Get(ctx, ssId.ResourceGroup, ssId.Name, name)
if err != nil {
return fmt.Errorf("retrieving Storage Sync Group (Storage Sync Group Name %q / Storage Sync Name %q /Resource Group %q): %+v", name, ssId.Name, ssId.ResourceGroup, err)
}

if resp.ID == nil || *resp.ID == "" {
return fmt.Errorf("reading Storage Sync Group (Storage Sync Group Name %q / Storage Sync Name %q /Resource Group %q) ID is empty or nil", name, ssId.Name, ssId.ResourceGroup)
}

d.SetId(*resp.ID)

return resourceArmStorageSyncGroupRead(d, meta)
}

func resourceArmStorageSyncGroupRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Storage.StoragesyncGroupClient
ssClient := meta.(*clients.Client).Storage.SyncServiceClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

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

resp, err := client.Get(ctx, id.ResourceGroup, id.StorageSyncName, id.Name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[INFO] Storage Sync Group %q does not exist - removing from state", d.Id())
d.SetId("")
return nil
}
return fmt.Errorf("reading Storage Sync Group (Storage Sync Group Name %q / Storage Sync Name %q /Resource Group %q): %+v", id.Name, id.StorageSyncName, id.ResourceGroup, err)
}

d.Set("name", resp.Name)

ssResp, err := ssClient.Get(ctx, id.ResourceGroup, id.StorageSyncName)
if err != nil {
return fmt.Errorf("reading Storage Sync %q (Resource Group %q): %+v", id.StorageSyncName, id.ResourceGroup, err)
}

if ssResp.ID == nil || *ssResp.ID == "" {
return fmt.Errorf("reading Storage Sync %q (Resource Group %q) ID is empty or nil", id.StorageSyncName, id.ResourceGroup)
}

d.Set("storage_sync_id", ssResp.ID)

return nil
}

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

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

if _, err := client.Delete(ctx, id.ResourceGroup, id.StorageSyncName, id.Name); err != nil {
return fmt.Errorf("deleting Storage Sync Group (Storage Sync Group Name %q / Storage Sync Name %q /Resource Group %q): %+v", id.Name, id.StorageSyncName, id.ResourceGroup, err)
}

return nil
}
Loading

0 comments on commit 2ad8be4

Please sign in to comment.