diff --git a/azurerm/internal/services/compute/parse/availability_set.go b/azurerm/internal/services/compute/parse/availability_set.go index 07288baa3fb4..bd3a9c899827 100644 --- a/azurerm/internal/services/compute/parse/availability_set.go +++ b/azurerm/internal/services/compute/parse/availability_set.go @@ -11,10 +11,21 @@ type AvailabilitySetId struct { Name string } +func NewAvailabilitySetId(resourceGroup, name string) AvailabilitySetId { + return AvailabilitySetId{ + ResourceGroup: resourceGroup, + Name: name, + } +} + +func (id AvailabilitySetId) ID(subscriptionId string) string { + return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/availabilitySets/%s", subscriptionId, id.ResourceGroup, id.Name) +} + func AvailabilitySetID(input string) (*AvailabilitySetId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { - return nil, fmt.Errorf("[ERROR] Unable to parse Availability Set ID %q: %+v", input, err) + return nil, fmt.Errorf("unable to parse Availability Set ID %q: %+v", input, err) } set := AvailabilitySetId{ diff --git a/azurerm/internal/services/compute/parse/availability_set_test.go b/azurerm/internal/services/compute/parse/availability_set_test.go index 9c0d5447b33b..c53636f41489 100644 --- a/azurerm/internal/services/compute/parse/availability_set_test.go +++ b/azurerm/internal/services/compute/parse/availability_set_test.go @@ -2,8 +2,21 @@ package parse import ( "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" ) +var _ resourceid.Formatter = AvailabilitySetId{} + +func TestAvailabilitySetIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + actual := NewAvailabilitySetId("group1", "set1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/availabilitySets/set1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + func TestAvailabilitySetID(t *testing.T) { testData := []struct { Name string diff --git a/azurerm/internal/services/compute/parse/dedicated_host.go b/azurerm/internal/services/compute/parse/dedicated_host.go index f3054896e72d..0971ac42b4ff 100644 --- a/azurerm/internal/services/compute/parse/dedicated_host.go +++ b/azurerm/internal/services/compute/parse/dedicated_host.go @@ -12,10 +12,23 @@ type DedicatedHostId struct { Name string } +func NewDedicatedHostId(id DedicatedHostGroupId, name string) DedicatedHostId { + return DedicatedHostId{ + ResourceGroup: id.ResourceGroup, + HostGroup: id.Name, + Name: name, + } +} + +func (id DedicatedHostId) ID(subscriptionId string) string { + base := NewDedicatedHostGroupId(id.ResourceGroup, id.HostGroup).ID(subscriptionId) + return fmt.Sprintf("%s/hosts/%s", base, id.Name) +} + func DedicatedHostID(input string) (*DedicatedHostId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { - return nil, fmt.Errorf("[ERROR] Unable to parse Dedicated Host ID %q: %+v", input, err) + return nil, fmt.Errorf("unable to parse Dedicated Host ID %q: %+v", input, err) } host := DedicatedHostId{ diff --git a/azurerm/internal/services/compute/parse/dedicated_host_group.go b/azurerm/internal/services/compute/parse/dedicated_host_group.go index 62798022e662..d43811ff2ab5 100644 --- a/azurerm/internal/services/compute/parse/dedicated_host_group.go +++ b/azurerm/internal/services/compute/parse/dedicated_host_group.go @@ -11,10 +11,21 @@ type DedicatedHostGroupId struct { Name string } +func NewDedicatedHostGroupId(resourceGroup, name string) DedicatedHostGroupId { + return DedicatedHostGroupId{ + ResourceGroup: resourceGroup, + Name: name, + } +} + +func (id DedicatedHostGroupId) ID(subscriptionId string) string { + return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/hostGroups/%s", subscriptionId, id.ResourceGroup, id.Name) +} + func DedicatedHostGroupID(input string) (*DedicatedHostGroupId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { - return nil, fmt.Errorf("[ERROR] Unable to parse Dedicated Host Group ID %q: %+v", input, err) + return nil, fmt.Errorf("unable to parse Dedicated Host Group ID %q: %+v", input, err) } group := DedicatedHostGroupId{ diff --git a/azurerm/internal/services/compute/parse/dedicated_host_group_test.go b/azurerm/internal/services/compute/parse/dedicated_host_group_test.go index d02416904e8d..307e0c15bfbf 100644 --- a/azurerm/internal/services/compute/parse/dedicated_host_group_test.go +++ b/azurerm/internal/services/compute/parse/dedicated_host_group_test.go @@ -2,8 +2,21 @@ package parse import ( "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" ) +var _ resourceid.Formatter = DedicatedHostGroupId{} + +func TestDedicatedHostGroupIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + actual := NewDedicatedHostGroupId("group1", "hostGroup1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/hostGroups/hostGroup1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + func TestDedicatedHostGroupID(t *testing.T) { testData := []struct { Name string diff --git a/azurerm/internal/services/compute/parse/dedicated_host_test.go b/azurerm/internal/services/compute/parse/dedicated_host_test.go index 3747e4a498a8..aa628112836f 100644 --- a/azurerm/internal/services/compute/parse/dedicated_host_test.go +++ b/azurerm/internal/services/compute/parse/dedicated_host_test.go @@ -2,8 +2,22 @@ package parse import ( "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" ) +var _ resourceid.Formatter = DedicatedHostId{} + +func TestDedicatedHostIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + hostGroupId := NewDedicatedHostGroupId("group1", "hostGroup1") + actual := NewDedicatedHostId(hostGroupId, "host1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/hostGroups/hostGroup1/hosts/host1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + func TestDedicatedHostID(t *testing.T) { testData := []struct { Name string diff --git a/azurerm/internal/services/compute/parse/disk_encryption_set.go b/azurerm/internal/services/compute/parse/disk_encryption_set.go index e909fccbc01e..71edc8ca4321 100644 --- a/azurerm/internal/services/compute/parse/disk_encryption_set.go +++ b/azurerm/internal/services/compute/parse/disk_encryption_set.go @@ -11,10 +11,21 @@ type DiskEncryptionSetId struct { Name string } +func NewDiskEncryptionSetId(resourceGroup, name string) DiskEncryptionSetId { + return DiskEncryptionSetId{ + ResourceGroup: resourceGroup, + Name: name, + } +} + +func (id DiskEncryptionSetId) ID(subscriptionId string) string { + return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/diskEncryptionSets/%s", subscriptionId, id.ResourceGroup, id.Name) +} + func DiskEncryptionSetID(input string) (*DiskEncryptionSetId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { - return nil, fmt.Errorf("[ERROR] Unable to parse Disk Encryption Set ID %q: %+v", input, err) + return nil, fmt.Errorf("unable to parse Disk Encryption Set ID %q: %+v", input, err) } encryptionSetId := DiskEncryptionSetId{ diff --git a/azurerm/internal/services/compute/parse/disk_encryption_set_test.go b/azurerm/internal/services/compute/parse/disk_encryption_set_test.go index 77532e797076..3f4fbfe684c4 100644 --- a/azurerm/internal/services/compute/parse/disk_encryption_set_test.go +++ b/azurerm/internal/services/compute/parse/disk_encryption_set_test.go @@ -1,6 +1,21 @@ package parse -import "testing" +import ( + "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" +) + +var _ resourceid.Formatter = DiskEncryptionSetId{} + +func TestDiskEncryptionSetIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + actual := NewDiskEncryptionSetId("group1", "set1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/diskEncryptionSets/set1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} func TestDiskEncryptionSetID(t *testing.T) { testData := []struct { diff --git a/azurerm/internal/services/compute/parse/image.go b/azurerm/internal/services/compute/parse/image.go index e3c61f7d3fdb..3cf767717464 100644 --- a/azurerm/internal/services/compute/parse/image.go +++ b/azurerm/internal/services/compute/parse/image.go @@ -11,10 +11,21 @@ type ImageId struct { Name string } +func NewImageId(resourceGroup, name string) ImageId { + return ImageId{ + ResourceGroup: resourceGroup, + Name: name, + } +} + +func (id ImageId) ID(subscriptionId string) string { + return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/images/%s", subscriptionId, id.ResourceGroup, id.Name) +} + func ImageID(input string) (*ImageId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { - return nil, fmt.Errorf("[ERROR] Unable to parse Image ID %q: %+v", input, err) + return nil, fmt.Errorf("unable to parse Image ID %q: %+v", input, err) } set := ImageId{ diff --git a/azurerm/internal/services/compute/parse/image_test.go b/azurerm/internal/services/compute/parse/image_test.go index 7022e54a37ec..86f6232bbd94 100644 --- a/azurerm/internal/services/compute/parse/image_test.go +++ b/azurerm/internal/services/compute/parse/image_test.go @@ -2,8 +2,21 @@ package parse import ( "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" ) +var _ resourceid.Formatter = ImageId{} + +func TestImageIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + actual := NewImageId("group1", "image1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/images/image1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + func TestImageID(t *testing.T) { testData := []struct { Name string diff --git a/azurerm/internal/services/compute/parse/managed_disk.go b/azurerm/internal/services/compute/parse/managed_disk.go index 09aeb89164c0..ec5d64d46dd3 100644 --- a/azurerm/internal/services/compute/parse/managed_disk.go +++ b/azurerm/internal/services/compute/parse/managed_disk.go @@ -11,10 +11,21 @@ type ManagedDiskId struct { Name string } +func NewManagedDiskId(resourceGroup, name string) ManagedDiskId { + return ManagedDiskId{ + ResourceGroup: resourceGroup, + Name: name, + } +} + +func (id ManagedDiskId) ID(subscriptionId string) string { + return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/disks/%s", subscriptionId, id.ResourceGroup, id.Name) +} + func ManagedDiskID(input string) (*ManagedDiskId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { - return nil, fmt.Errorf("[ERROR] Unable to parse Managed Disk ID %q: %+v", input, err) + return nil, fmt.Errorf("unable to parse Managed Disk ID %q: %+v", input, err) } disk := ManagedDiskId{ diff --git a/azurerm/internal/services/compute/parse/managed_disk_test.go b/azurerm/internal/services/compute/parse/managed_disk_test.go index 5c48b86899b6..4ca30d53caac 100644 --- a/azurerm/internal/services/compute/parse/managed_disk_test.go +++ b/azurerm/internal/services/compute/parse/managed_disk_test.go @@ -2,8 +2,21 @@ package parse import ( "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" ) +var _ resourceid.Formatter = ManagedDiskId{} + +func TestManagedDiskIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + actual := NewManagedDiskId("group1", "disk1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/disks/disk1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + func TestManagedDiskID(t *testing.T) { testData := []struct { Name string diff --git a/azurerm/internal/services/compute/parse/proximity_placement_group.go b/azurerm/internal/services/compute/parse/proximity_placement_group.go index 3b97cd6b07d4..33bef947cc28 100644 --- a/azurerm/internal/services/compute/parse/proximity_placement_group.go +++ b/azurerm/internal/services/compute/parse/proximity_placement_group.go @@ -11,10 +11,21 @@ type ProximityPlacementGroupId struct { Name string } +func NewProximityPlacementGroupId(resourceGroup, name string) ProximityPlacementGroupId { + return ProximityPlacementGroupId{ + ResourceGroup: resourceGroup, + Name: name, + } +} + +func (id ProximityPlacementGroupId) ID(subscriptionId string) string { + return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/proximityPlacementGroups/%s", subscriptionId, id.ResourceGroup, id.Name) +} + func ProximityPlacementGroupID(input string) (*ProximityPlacementGroupId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { - return nil, fmt.Errorf("[ERROR] Unable to parse Proximity Placement Group ID %q: %+v", input, err) + return nil, fmt.Errorf("unable to parse Proximity Placement Group ID %q: %+v", input, err) } server := ProximityPlacementGroupId{ diff --git a/azurerm/internal/services/compute/parse/proximity_placement_group_test.go b/azurerm/internal/services/compute/parse/proximity_placement_group_test.go index 7d9e9d174876..51650734fd22 100644 --- a/azurerm/internal/services/compute/parse/proximity_placement_group_test.go +++ b/azurerm/internal/services/compute/parse/proximity_placement_group_test.go @@ -2,8 +2,21 @@ package parse import ( "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" ) +var _ resourceid.Formatter = ProximityPlacementGroupId{} + +func TestProximityPlacementGroupIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + actual := NewProximityPlacementGroupId("group1", "ppg1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/proximityPlacementGroups/ppg1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + func TestProximityPlacementGroupID(t *testing.T) { testData := []struct { Name string diff --git a/azurerm/internal/services/compute/parse/shared_image.go b/azurerm/internal/services/compute/parse/shared_image.go index 5158bcaf40f4..b7315c1b05a7 100644 --- a/azurerm/internal/services/compute/parse/shared_image.go +++ b/azurerm/internal/services/compute/parse/shared_image.go @@ -12,21 +12,34 @@ type SharedImageId struct { Name string } +func NewSharedImageId(id SharedImageGalleryId, name string) SharedImageId { + return SharedImageId{ + ResourceGroup: id.ResourceGroup, + Gallery: id.Name, + Name: name, + } +} + +func (id SharedImageId) ID(subscriptionId string) string { + base := NewSharedImageGalleryId(id.ResourceGroup, id.Gallery).ID(subscriptionId) + return fmt.Sprintf("%s/images/%s", base, id.Name) +} + func SharedImageID(input string) (*SharedImageId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { - return nil, fmt.Errorf("[ERROR] Unable to parse Image ID %q: %+v", input, err) + return nil, fmt.Errorf("unable to parse Shared Image ID %q: %+v", input, err) } - set := SharedImageId{ + image := SharedImageId{ ResourceGroup: id.ResourceGroup, } - if set.Gallery, err = id.PopSegment("galleries"); err != nil { + if image.Gallery, err = id.PopSegment("galleries"); err != nil { return nil, err } - if set.Name, err = id.PopSegment("images"); err != nil { + if image.Name, err = id.PopSegment("images"); err != nil { return nil, err } @@ -34,5 +47,5 @@ func SharedImageID(input string) (*SharedImageId, error) { return nil, err } - return &set, nil + return &image, nil } diff --git a/azurerm/internal/services/compute/parse/shared_image_gallery.go b/azurerm/internal/services/compute/parse/shared_image_gallery.go new file mode 100644 index 000000000000..43c2d8eda002 --- /dev/null +++ b/azurerm/internal/services/compute/parse/shared_image_gallery.go @@ -0,0 +1,44 @@ +package parse + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" +) + +type SharedImageGalleryId struct { + ResourceGroup string + Name string +} + +func NewSharedImageGalleryId(resourceGroup, name string) SharedImageGalleryId { + return SharedImageGalleryId{ + ResourceGroup: resourceGroup, + Name: name, + } +} + +func (id SharedImageGalleryId) ID(subscriptionId string) string { + return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/galleries/%s", subscriptionId, id.ResourceGroup, id.Name) +} + +func SharedImageGalleryID(input string) (*SharedImageGalleryId, error) { + id, err := azure.ParseAzureResourceID(input) + if err != nil { + return nil, fmt.Errorf("unable to parse Shared Image Gallery ID %q: %+v", input, err) + } + + gallery := SharedImageGalleryId{ + ResourceGroup: id.ResourceGroup, + } + + if gallery.Name, err = id.PopSegment("galleries"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &gallery, nil +} diff --git a/azurerm/internal/services/compute/parse/shared_image_gallery_test.go b/azurerm/internal/services/compute/parse/shared_image_gallery_test.go new file mode 100644 index 000000000000..fd2c7086e1ab --- /dev/null +++ b/azurerm/internal/services/compute/parse/shared_image_gallery_test.go @@ -0,0 +1,93 @@ +package parse + +import ( + "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" +) + +var _ resourceid.Formatter = SharedImageGalleryId{} + +func TestSharedImageGalleryIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + actual := NewSharedImageGalleryId("group1", "gallery1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/galleries/gallery1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + +func TestSharedImageGalleryID(t *testing.T) { + testData := []struct { + Name string + Input string + Error bool + Expect *SharedImageGalleryId + }{ + { + Name: "Empty", + Input: "", + Error: true, + }, + { + Name: "No Resource Groups Segment", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000", + Error: true, + }, + { + Name: "No Resource Groups Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/", + Error: true, + }, + { + Name: "Resource Group ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/", + Error: true, + }, + { + Name: "Missing galleries segment", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Compute/", + Error: true, + }, + { + Name: "Missing gallery Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Compute/galleries/", + Error: true, + }, + { + Name: "Shared Image Gallery ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Compute/galleries/gallery1", + Error: false, + Expect: &SharedImageGalleryId{ + ResourceGroup: "mygroup1", + Name: "gallery1", + }, + }, + { + Name: "Wrong Casing", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Compute/Galleries/gallery1", + Error: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Name) + + actual, err := SharedImageGalleryID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expected a value but got an error: %s", err) + } + + if actual.Name != v.Expect.Name { + t.Fatalf("Expected %q but got %q for Name", v.Expect.Name, actual.Name) + } + + if actual.ResourceGroup != v.Expect.ResourceGroup { + t.Fatalf("Expected %q but got %q for Resource Group", v.Expect.ResourceGroup, actual.ResourceGroup) + } + } +} diff --git a/azurerm/internal/services/compute/parse/shared_image_test.go b/azurerm/internal/services/compute/parse/shared_image_test.go index 5e3832642af7..186dc9251557 100644 --- a/azurerm/internal/services/compute/parse/shared_image_test.go +++ b/azurerm/internal/services/compute/parse/shared_image_test.go @@ -2,8 +2,22 @@ package parse import ( "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" ) +var _ resourceid.Formatter = SharedImageId{} + +func TestSharedImageIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + galleryId := NewSharedImageGalleryId("group1", "gallery1") + actual := NewSharedImageId(galleryId, "image1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/galleries/gallery1/images/image1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + func TestSharedImageID(t *testing.T) { testData := []struct { Name string @@ -74,6 +88,10 @@ func TestSharedImageID(t *testing.T) { t.Fatalf("Expected %q but got %q for Name", v.Expect.Name, actual.Name) } + if actual.Gallery != v.Expect.Gallery { + t.Fatalf("Expected %q but got %q for Gallery", v.Expect.Gallery, actual.Gallery) + } + if actual.ResourceGroup != v.Expect.ResourceGroup { t.Fatalf("Expected %q but got %q for Resource Group", v.Expect.ResourceGroup, actual.ResourceGroup) } diff --git a/azurerm/internal/services/compute/parse/shared_image_version.go b/azurerm/internal/services/compute/parse/shared_image_version.go index c11074e2d13d..380ae1c9f07c 100644 --- a/azurerm/internal/services/compute/parse/shared_image_version.go +++ b/azurerm/internal/services/compute/parse/shared_image_version.go @@ -8,15 +8,30 @@ import ( type SharedImageVersionId struct { ResourceGroup string - Version string Gallery string - Name string + ImageName string + Version string +} + +func NewSharedImageVersionId(id SharedImageId, name string) SharedImageVersionId { + return SharedImageVersionId{ + ResourceGroup: id.ResourceGroup, + Gallery: id.Gallery, + ImageName: id.Name, + Version: name, + } +} + +func (id SharedImageVersionId) ID(subscriptionId string) string { + galleryId := NewSharedImageGalleryId(id.ResourceGroup, id.Gallery) + base := NewSharedImageId(galleryId, id.ImageName).ID(subscriptionId) + return fmt.Sprintf("%s/versions/%s", base, id.Version) } func SharedImageVersionID(input string) (*SharedImageVersionId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { - return nil, fmt.Errorf("[ERROR] Unable to parse Image ID %q: %+v", input, err) + return nil, fmt.Errorf("unable to parse Shared Image Version ID %q: %+v", input, err) } set := SharedImageVersionId{ @@ -27,7 +42,7 @@ func SharedImageVersionID(input string) (*SharedImageVersionId, error) { return nil, err } - if set.Name, err = id.PopSegment("images"); err != nil { + if set.ImageName, err = id.PopSegment("images"); err != nil { return nil, err } diff --git a/azurerm/internal/services/compute/parse/shared_image_version_test.go b/azurerm/internal/services/compute/parse/shared_image_version_test.go index 92c487034a7c..e87b78294285 100644 --- a/azurerm/internal/services/compute/parse/shared_image_version_test.go +++ b/azurerm/internal/services/compute/parse/shared_image_version_test.go @@ -2,8 +2,23 @@ package parse import ( "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" ) +var _ resourceid.Formatter = SharedImageVersionId{} + +func TestSharedImageVersionIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + galleryId := NewSharedImageGalleryId("group1", "gallery1") + imageId := NewSharedImageId(galleryId, "image1") + actual := NewSharedImageVersionId(imageId, "version1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/galleries/gallery1/images/image1/versions/version1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + func TestSharedImageVersionID(t *testing.T) { testData := []struct { Name string @@ -48,7 +63,7 @@ func TestSharedImageVersionID(t *testing.T) { Expect: &SharedImageVersionId{ ResourceGroup: "mygroup1", Gallery: "gallery1", - Name: "image1", + ImageName: "image1", Version: "1.0.0", }, }, @@ -71,8 +86,8 @@ func TestSharedImageVersionID(t *testing.T) { t.Fatalf("Expected a value but got an error: %s", err) } - if actual.Name != v.Expect.Name { - t.Fatalf("Expected %q but got %q for Name", v.Expect.Name, actual.Name) + if actual.ImageName != v.Expect.ImageName { + t.Fatalf("Expected %q but got %q for Name", v.Expect.ImageName, actual.ImageName) } if actual.ResourceGroup != v.Expect.ResourceGroup { diff --git a/azurerm/internal/services/compute/parse/virtual_machine.go b/azurerm/internal/services/compute/parse/virtual_machine.go index 5781c72c596d..deddffc83946 100644 --- a/azurerm/internal/services/compute/parse/virtual_machine.go +++ b/azurerm/internal/services/compute/parse/virtual_machine.go @@ -11,10 +11,21 @@ type VirtualMachineId struct { Name string } +func NewVirtualMachineId(resourceGroup, name string) VirtualMachineId { + return VirtualMachineId{ + ResourceGroup: resourceGroup, + Name: name, + } +} + +func (id VirtualMachineId) ID(subscriptionId string) string { + return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/virtualMachines/%s", subscriptionId, id.ResourceGroup, id.Name) +} + func VirtualMachineID(input string) (*VirtualMachineId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { - return nil, fmt.Errorf("[ERROR] Unable to parse VM ID %q: %+v", input, err) + return nil, fmt.Errorf("unable to parse Virtual Machine ID %q: %+v", input, err) } vm := VirtualMachineId{ diff --git a/azurerm/internal/services/compute/parse/virtual_machine_extension.go b/azurerm/internal/services/compute/parse/virtual_machine_extension.go index 06cd9d21ac70..adf4697e4c8f 100644 --- a/azurerm/internal/services/compute/parse/virtual_machine_extension.go +++ b/azurerm/internal/services/compute/parse/virtual_machine_extension.go @@ -12,10 +12,23 @@ type VirtualMachineExtensionId struct { VirtualMachine string } +func NewVirtualMachineExtensionId(id VirtualMachineId, name string) VirtualMachineExtensionId { + return VirtualMachineExtensionId{ + ResourceGroup: id.ResourceGroup, + VirtualMachine: id.Name, + Name: name, + } +} + +func (id VirtualMachineExtensionId) ID(subscriptionId string) string { + base := NewVirtualMachineId(id.ResourceGroup, id.VirtualMachine).ID(subscriptionId) + return fmt.Sprintf("%s/extensions/%s", base, id.Name) +} + func VirtualMachineExtensionID(input string) (*VirtualMachineExtensionId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { - return nil, fmt.Errorf("[ERROR] Unable to parse App Service ID %q: %+v", input, err) + return nil, fmt.Errorf("unable to parse Virtual Machine Extension ID %q: %+v", input, err) } virtualMachineExtension := VirtualMachineExtensionId{ diff --git a/azurerm/internal/services/compute/parse/virtual_machine_extension_test.go b/azurerm/internal/services/compute/parse/virtual_machine_extension_test.go index 4cc15751c63e..a442a655dd78 100644 --- a/azurerm/internal/services/compute/parse/virtual_machine_extension_test.go +++ b/azurerm/internal/services/compute/parse/virtual_machine_extension_test.go @@ -1,6 +1,22 @@ package parse -import "testing" +import ( + "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" +) + +var _ resourceid.Formatter = VirtualMachineExtensionId{} + +func TestVirtualMachineExtensionIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + vmId := NewVirtualMachineId("group1", "vm1") + actual := NewVirtualMachineExtensionId(vmId, "extension1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/virtualMachines/vm1/extensions/extension1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} func TestParseVirtualMachineExtensionID(t *testing.T) { testData := []struct { diff --git a/azurerm/internal/services/compute/parse/virtual_machine_scale_set.go b/azurerm/internal/services/compute/parse/virtual_machine_scale_set.go index afc325d5a537..753b03fd2471 100644 --- a/azurerm/internal/services/compute/parse/virtual_machine_scale_set.go +++ b/azurerm/internal/services/compute/parse/virtual_machine_scale_set.go @@ -11,10 +11,21 @@ type VirtualMachineScaleSetId struct { Name string } +func NewVirtualMachineScaleSetId(resourceGroup, name string) VirtualMachineScaleSetId { + return VirtualMachineScaleSetId{ + ResourceGroup: resourceGroup, + Name: name, + } +} + +func (id VirtualMachineScaleSetId) ID(subscriptionId string) string { + return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/virtualMachineScaleSets/%s", subscriptionId, id.ResourceGroup, id.Name) +} + func VirtualMachineScaleSetID(input string) (*VirtualMachineScaleSetId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { - return nil, fmt.Errorf("[ERROR] Unable to parse Virtual Machine Scale Set ID %q: %+v", input, err) + return nil, fmt.Errorf("unable to parse Virtual Machine Scale Set ID %q: %+v", input, err) } vmScaleSet := VirtualMachineScaleSetId{ diff --git a/azurerm/internal/services/compute/parse/virtual_machine_scale_set_extension.go b/azurerm/internal/services/compute/parse/virtual_machine_scale_set_extension.go index 166c0b2ca1c1..6d18ba867192 100644 --- a/azurerm/internal/services/compute/parse/virtual_machine_scale_set_extension.go +++ b/azurerm/internal/services/compute/parse/virtual_machine_scale_set_extension.go @@ -12,10 +12,23 @@ type VirtualMachineScaleSetExtensionId struct { Name string } +func NewVirtualMachineScaleSetExtensionId(id VirtualMachineScaleSetId, name string) VirtualMachineScaleSetExtensionId { + return VirtualMachineScaleSetExtensionId{ + ResourceGroup: id.ResourceGroup, + VirtualMachineScaleSetName: id.Name, + Name: name, + } +} + +func (id VirtualMachineScaleSetExtensionId) ID(subscriptionId string) string { + base := NewVirtualMachineScaleSetId(id.ResourceGroup, id.VirtualMachineScaleSetName).ID(subscriptionId) + return fmt.Sprintf("%s/extensions/%s", base, id.Name) +} + func VirtualMachineScaleSetExtensionID(input string) (*VirtualMachineScaleSetExtensionId, error) { id, err := azure.ParseAzureResourceID(input) if err != nil { - return nil, fmt.Errorf("[ERROR] Unable to parse Virtual Machine Scale Set Extension ID %q: %+v", input, err) + return nil, fmt.Errorf("unable to parse Virtual Machine Scale Set Extension ID %q: %+v", input, err) } extension := VirtualMachineScaleSetExtensionId{ diff --git a/azurerm/internal/services/compute/parse/virtual_machine_scale_set_extension_test.go b/azurerm/internal/services/compute/parse/virtual_machine_scale_set_extension_test.go index 616a7d5e0c10..e7dde2028ad9 100644 --- a/azurerm/internal/services/compute/parse/virtual_machine_scale_set_extension_test.go +++ b/azurerm/internal/services/compute/parse/virtual_machine_scale_set_extension_test.go @@ -1,6 +1,22 @@ package parse -import "testing" +import ( + "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" +) + +var _ resourceid.Formatter = VirtualMachineScaleSetExtensionId{} + +func TestVirtualMachineScaleSetExtensionIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + vmssId := NewVirtualMachineScaleSetId("group1", "vmss1") + actual := NewVirtualMachineScaleSetExtensionId(vmssId, "extension1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss1/extensions/extension1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} func TestParseVirtualMachineScaleSetExtensionID(t *testing.T) { testData := []struct { diff --git a/azurerm/internal/services/compute/parse/virtual_machine_test.go b/azurerm/internal/services/compute/parse/virtual_machine_test.go index 806e3da3e2a3..aab444d5f0bc 100644 --- a/azurerm/internal/services/compute/parse/virtual_machine_test.go +++ b/azurerm/internal/services/compute/parse/virtual_machine_test.go @@ -1,6 +1,21 @@ package parse -import "testing" +import ( + "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" +) + +var _ resourceid.Formatter = VirtualMachineId{} + +func TestVirtualMachineIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + actual := NewVirtualMachineId("group1", "vm1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/virtualMachines/vm1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} func TestVirtualMachineID(t *testing.T) { var testData = []struct { diff --git a/azurerm/internal/services/compute/parse/vritual_machine_scale_set_test.go b/azurerm/internal/services/compute/parse/vritual_machine_scale_set_test.go index e22d1f90a3ff..4645eebaeada 100644 --- a/azurerm/internal/services/compute/parse/vritual_machine_scale_set_test.go +++ b/azurerm/internal/services/compute/parse/vritual_machine_scale_set_test.go @@ -1,6 +1,21 @@ package parse -import "testing" +import ( + "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" +) + +var _ resourceid.Formatter = VirtualMachineScaleSetId{} + +func TestVirtualMachineScaleSetIDFormatter(t *testing.T) { + subscriptionId := "12345678-1234-5678-1234-123456789012" + actual := NewVirtualMachineScaleSetId("group1", "vmss1").ID(subscriptionId) + expected := "/subscriptions/12345678-1234-5678-1234-123456789012/resourceGroups/group1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} func TestVirtualMachineScaleSetID(t *testing.T) { testData := []struct { diff --git a/azurerm/internal/services/compute/shared_image_gallery_resource.go b/azurerm/internal/services/compute/shared_image_gallery_resource.go index 021f4e5a46b5..f9f20d05229f 100644 --- a/azurerm/internal/services/compute/shared_image_gallery_resource.go +++ b/azurerm/internal/services/compute/shared_image_gallery_resource.go @@ -12,7 +12,9 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/compute/parse" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + 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" ) @@ -23,9 +25,10 @@ func resourceArmSharedImageGallery() *schema.Resource { Read: resourceArmSharedImageGalleryRead, Update: resourceArmSharedImageGalleryCreateUpdate, Delete: resourceArmSharedImageGalleryDelete, - Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, - }, + Importer: azSchema.ValidateResourceIDPriorToImport(func(id string) error { + _, err := parse.SharedImageGalleryID(id) + return err + }), Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(30 * time.Minute), @@ -68,7 +71,6 @@ func resourceArmSharedImageGalleryCreateUpdate(d *schema.ResourceData, meta inte log.Printf("[INFO] preparing arguments for Image Gallery creation.") - // TODO: support for Timeouts/Requiring Import name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) location := azure.NormalizeLocation(d.Get("location").(string)) @@ -124,27 +126,24 @@ func resourceArmSharedImageGalleryRead(d *schema.ResourceData, meta interface{}) ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := azure.ParseAzureResourceID(d.Id()) + id, err := parse.SharedImageGalleryID(d.Id()) if err != nil { return err } - resourceGroup := id.ResourceGroup - name := id.Path["galleries"] - - resp, err := client.Get(ctx, resourceGroup, name) + resp, err := client.Get(ctx, id.ResourceGroup, id.Name) if err != nil { if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[DEBUG] Shared Image Gallery %q (Resource Group %q) was not found - removing from state", name, resourceGroup) + log.Printf("[DEBUG] Shared Image Gallery %q (Resource Group %q) was not found - removing from state", id.Name, id.ResourceGroup) d.SetId("") return nil } - return fmt.Errorf("Error making Read request on Shared Image Gallery %q (Resource Group %q): %+v", name, resourceGroup, err) + return fmt.Errorf("Error making Read request on Shared Image Gallery %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err) } - d.Set("name", name) - d.Set("resource_group_name", resourceGroup) + d.Set("name", id.Name) + d.Set("resource_group_name", id.ResourceGroup) if location := resp.Location; location != nil { d.Set("location", azure.NormalizeLocation(*location)) } @@ -164,27 +163,24 @@ func resourceArmSharedImageGalleryDelete(d *schema.ResourceData, meta interface{ ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := azure.ParseAzureResourceID(d.Id()) + id, err := parse.SharedImageGalleryID(d.Id()) if err != nil { return err } - resourceGroup := id.ResourceGroup - name := id.Path["galleries"] - - future, err := client.Delete(ctx, resourceGroup, name) + future, err := client.Delete(ctx, id.ResourceGroup, id.Name) if err != nil { // deleted outside of Terraform if response.WasNotFound(future.Response()) { return nil } - return fmt.Errorf("Error deleting Shared Image Gallery %q (Resource Group %q): %+v", name, resourceGroup, err) + return fmt.Errorf("Error deleting Shared Image Gallery %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err) } if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { if !response.WasNotFound(future.Response()) { - return fmt.Errorf("Error waiting for the deletion of Shared Image Gallery %q (Resource Group %q): %+v", name, resourceGroup, err) + return fmt.Errorf("Error waiting for the deletion of Shared Image Gallery %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err) } } diff --git a/azurerm/internal/services/compute/shared_image_version_resource.go b/azurerm/internal/services/compute/shared_image_version_resource.go index a51b82fba9cf..b3ad24efda70 100644 --- a/azurerm/internal/services/compute/shared_image_version_resource.go +++ b/azurerm/internal/services/compute/shared_image_version_resource.go @@ -209,18 +209,18 @@ func resourceArmSharedImageVersionRead(d *schema.ResourceData, meta interface{}) return err } - resp, err := client.Get(ctx, id.ResourceGroup, id.Gallery, id.Name, id.Version, compute.ReplicationStatusTypesReplicationStatus) + resp, err := client.Get(ctx, id.ResourceGroup, id.Gallery, id.ImageName, id.Version, compute.ReplicationStatusTypesReplicationStatus) if err != nil { if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[DEBUG] Shared Image Version %q (Image %q / Gallery %q / Resource Group %q) was not found - removing from state", id.Version, id.Name, id.Gallery, id.ResourceGroup) + log.Printf("[DEBUG] Shared Image Version %q (Image %q / Gallery %q / Resource Group %q) was not found - removing from state", id.Version, id.ImageName, id.Gallery, id.ResourceGroup) d.SetId("") return nil } - return fmt.Errorf("Error retrieving Shared Image Version %q (Image %q / Gallery %q / Resource Group %q): %+v", id.Version, id.Name, id.Gallery, id.ResourceGroup, err) + return fmt.Errorf("Error retrieving Shared Image Version %q (Image %q / Gallery %q / Resource Group %q): %+v", id.Version, id.ImageName, id.Gallery, id.ResourceGroup, err) } d.Set("name", resp.Name) - d.Set("image_name", id.Name) + d.Set("image_name", id.ImageName) d.Set("gallery_name", id.Gallery) d.Set("resource_group_name", id.ResourceGroup) @@ -263,18 +263,18 @@ func resourceArmSharedImageVersionDelete(d *schema.ResourceData, meta interface{ return err } - future, err := client.Delete(ctx, id.ResourceGroup, id.Gallery, id.Name, id.Version) + future, err := client.Delete(ctx, id.ResourceGroup, id.Gallery, id.ImageName, id.Version) if err != nil { if response.WasNotFound(future.Response()) { return nil } - return fmt.Errorf("Error deleting Shared Image Version %q (Image %q / Gallery %q / Resource Group %q): %+v", id.Version, id.Name, id.Gallery, id.ResourceGroup, err) + return fmt.Errorf("Error deleting Shared Image Version %q (Image %q / Gallery %q / Resource Group %q): %+v", id.Version, id.ImageName, id.Gallery, id.ResourceGroup, err) } if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { if !response.WasNotFound(future.Response()) { - return fmt.Errorf("Error deleting Shared Image Version %q (Image %q / Gallery %q / Resource Group %q): %+v", id.Version, id.Name, id.Gallery, id.ResourceGroup, err) + return fmt.Errorf("Error deleting Shared Image Version %q (Image %q / Gallery %q / Resource Group %q): %+v", id.Version, id.ImageName, id.Gallery, id.ResourceGroup, err) } }