Skip to content

Commit

Permalink
New DataSource: azurerm_shared_image_versions (#6700)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbfrahry committed Apr 30, 2020
1 parent 5cd6c9d commit bdb1321
Show file tree
Hide file tree
Showing 6 changed files with 413 additions and 0 deletions.
183 changes: 183 additions & 0 deletions azurerm/internal/services/compute/data_source_shared_image_versions.go
@@ -0,0 +1,183 @@
package compute

import (
"fmt"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"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/tags"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func dataSourceArmSharedImageVersions() *schema.Resource {
return &schema.Resource{
Read: dataSourceArmSharedImageVersionsRead,

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

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

"image_name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validate.SharedImageName,
},

"resource_group_name": azure.SchemaResourceGroupNameForDataSource(),

"tags_filter": tags.Schema(),

"images": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
},

"location": azure.SchemaLocationForDataSource(),

"managed_image_id": {
Type: schema.TypeString,
Computed: true,
},

"target_region": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
},

"regional_replica_count": {
Type: schema.TypeInt,
Computed: true,
},

"storage_account_type": {
Type: schema.TypeString,
Computed: true,
},
},
},
},

"exclude_from_latest": {
Type: schema.TypeBool,
Computed: true,
},

"tags": tags.SchemaDataSource(),
},
},
},
},
}
}

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

imageName := d.Get("image_name").(string)
galleryName := d.Get("gallery_name").(string)
resourceGroup := d.Get("resource_group_name").(string)
filterTags := tags.Expand(d.Get("tags_filter").(map[string]interface{}))

resp, err := client.ListByGalleryImage(ctx, resourceGroup, galleryName, imageName)
if err != nil {
if utils.ResponseWasNotFound(resp.Response().Response) {
log.Printf("[DEBUG] Shared Image Versions (Image %q / Gallery %q / Resource Group %q) was not found - removing from state", imageName, galleryName, resourceGroup)
d.SetId("")
return nil
}
return fmt.Errorf("retrieving Shared Image Versions (Image %q / Gallery %q / Resource Group %q): %+v", imageName, galleryName, resourceGroup, err)
}

images := flattenSharedImageVersions(resp.Values(), filterTags)
if len(images) == 0 {
return fmt.Errorf("unable to find any images")
}

d.SetId(time.Now().UTC().String())

d.Set("image_name", imageName)
d.Set("gallery_name", galleryName)
d.Set("resource_group_name", resourceGroup)

if err := d.Set("images", images); err != nil {
return fmt.Errorf("setting `images`: %+v", err)
}

return nil
}

func flattenSharedImageVersions(input []compute.GalleryImageVersion, filterTags map[string]*string) []interface{} {
results := make([]interface{}, 0)

for _, imageVersion := range input {
flattenedIPAddress := flattenSharedImageVersion(imageVersion)
found := true
// Loop through our filter tags and see if they match
for k, v := range filterTags {
if v != nil {
// If the tags don't match, return false
if imageVersion.Tags[k] == nil || *v != *imageVersion.Tags[k] {
found = false
}
}
}

if found {
results = append(results, flattenedIPAddress)
}
}

return results
}

func flattenSharedImageVersion(input compute.GalleryImageVersion) map[string]interface{} {
output := make(map[string]interface{})

output["name"] = input.Name

if location := input.Location; location != nil {
output["location"] = azure.NormalizeLocation(*location)
}

if props := input.GalleryImageVersionProperties; props != nil {
if profile := props.PublishingProfile; profile != nil {
output["exclude_from_latest"] = profile.ExcludeFromLatest
output["target_region"] = flattenSharedImageVersionDataSourceTargetRegions(profile.TargetRegions)
}

if profile := props.StorageProfile; profile != nil {
if source := profile.Source; source != nil {
output["managed_image_id"] = source.ID
}
}
}

output["tags"] = tags.Flatten(input.Tags)

return output
}
1 change: 1 addition & 0 deletions azurerm/internal/services/compute/registration.go
Expand Up @@ -31,6 +31,7 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource {
"azurerm_proximity_placement_group": dataSourceArmProximityPlacementGroup(),
"azurerm_shared_image_gallery": dataSourceArmSharedImageGallery(),
"azurerm_shared_image_version": dataSourceArmSharedImageVersion(),
"azurerm_shared_image_versions": dataSourceArmSharedImageVersions(),
"azurerm_shared_image": dataSourceArmSharedImage(),
"azurerm_snapshot": dataSourceArmSnapshot(),
"azurerm_virtual_machine": dataSourceArmVirtualMachine(),
Expand Down
@@ -0,0 +1,151 @@
package tests

import (
"fmt"
"regexp"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance"
)

func TestAccDataSourceAzureRMSharedImageVersions_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_shared_image_versions", "test")
username := "testadmin"
password := "Password1234!"
hostname := fmt.Sprintf("tftestcustomimagesrc%d", data.RandomInteger)
resourceGroup := fmt.Sprintf("acctestRG-%d", data.RandomInteger)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMSharedImageVersionDestroy,
Steps: []resource.TestStep{
{
// need to create a vm and then reference it in the image creation
Config: testAccAzureRMSharedImageVersion_setup(data, username, password, hostname),
Destroy: false,
Check: resource.ComposeTestCheckFunc(
testCheckAzureVMExists("azurerm_virtual_machine.testsource", true),
testGeneralizeVMImage(resourceGroup, "testsource", username, password, hostname, "22", data.Locations.Primary),
),
},
{
Config: testAccDataSourceSharedImageVersions_basic(data, username, password, hostname),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(data.ResourceName, "images.0.tags.%", "0"),
resource.TestCheckResourceAttrSet(data.ResourceName, "images.0.managed_image_id"),
resource.TestCheckResourceAttr(data.ResourceName, "images.0.target_region.#", "1"),
resource.TestCheckResourceAttr(data.ResourceName, "images.0.target_region.0.storage_account_type", "Standard_LRS"),
),
},
},
})
}

func TestAccDataSourceAzureRMSharedImageVersions_tagsFilterError(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_shared_image_versions", "test")
username := "testadmin"
password := "Password1234!"
hostname := fmt.Sprintf("tftestcustomimagesrc%d", data.RandomInteger)
resourceGroup := fmt.Sprintf("acctestRG-%d", data.RandomInteger)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMSharedImageVersionDestroy,
Steps: []resource.TestStep{
{
// need to create a vm and then reference it in the image creation
Config: testAccAzureRMSharedImageVersion_setup(data, username, password, hostname),
Destroy: false,
Check: resource.ComposeTestCheckFunc(
testCheckAzureVMExists("azurerm_virtual_machine.testsource", true),
testGeneralizeVMImage(resourceGroup, "testsource", username, password, hostname, "22", data.Locations.Primary),
),
},
{
Config: testAccDataSourceSharedImageVersions_tagsFilterError(data, username, password, hostname),
ExpectError: regexp.MustCompile("unable to find any images"),
},
},
})
}

func TestAccDataSourceAzureRMSharedImageVersions_tagsFilter(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_shared_image_versions", "test")
username := "testadmin"
password := "Password1234!"
hostname := fmt.Sprintf("tftestcustomimagesrc%d", data.RandomInteger)
resourceGroup := fmt.Sprintf("acctestRG-%d", data.RandomInteger)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMSharedImageVersionDestroy,
Steps: []resource.TestStep{
{
// need to create a vm and then reference it in the image creation
Config: testAccAzureRMSharedImageVersion_setup(data, username, password, hostname),
Destroy: false,
Check: resource.ComposeTestCheckFunc(
testCheckAzureVMExists("azurerm_virtual_machine.testsource", true),
testGeneralizeVMImage(resourceGroup, "testsource", username, password, hostname, "22", data.Locations.Primary),
),
},
{
Config: testAccDataSourceSharedImageVersions_tagsFilter(data, username, password, hostname),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(data.ResourceName, "images.#", "1"),
),
},
},
})
}

func testAccDataSourceSharedImageVersions_basic(data acceptance.TestData, username, password, hostname string) string {
template := testAccAzureRMSharedImageVersion_imageVersion(data, username, password, hostname)
return fmt.Sprintf(`
%s
data "azurerm_shared_image_versions" "test" {
gallery_name = azurerm_shared_image_version.test.gallery_name
image_name = azurerm_shared_image_version.test.image_name
resource_group_name = azurerm_shared_image_version.test.resource_group_name
}
`, template)
}

func testAccDataSourceSharedImageVersions_tagsFilterError(data acceptance.TestData, username, password, hostname string) string {
template := testAccAzureRMSharedImageVersion_imageVersion(data, username, password, hostname)
return fmt.Sprintf(`
%s
data "azurerm_shared_image_versions" "test" {
gallery_name = azurerm_shared_image_version.test.gallery_name
image_name = azurerm_shared_image_version.test.image_name
resource_group_name = azurerm_shared_image_version.test.resource_group_name
tags_filter = {
"foo" = "error"
}
}
`, template)
}

func testAccDataSourceSharedImageVersions_tagsFilter(data acceptance.TestData, username, password, hostname string) string {
template := testAccAzureRMSharedImageVersion_imageVersion(data, username, password, hostname)
return fmt.Sprintf(`
%s
data "azurerm_shared_image_versions" "test" {
gallery_name = azurerm_shared_image_version.test.gallery_name
image_name = azurerm_shared_image_version.test.image_name
resource_group_name = azurerm_shared_image_version.test.resource_group_name
tags_filter = {
"foo" = "bar"
}
}
`, template)
}
Expand Up @@ -278,6 +278,10 @@ resource "azurerm_shared_image_version" "test" {
name = azurerm_resource_group.test.location
regional_replica_count = 1
}
tags = {
"foo" = "bar"
}
}
`, template)
}
Expand Down
4 changes: 4 additions & 0 deletions website/azurerm.erb
Expand Up @@ -510,6 +510,10 @@
<a href="/docs/providers/azurerm/d/shared_image_version.html">azurerm_shared_image_version</a>
</li>

<li>
<a href="/docs/providers/azurerm/d/shared_image_versions.html">azurerm_shared_image_versions</a>
</li>

<li>
<a href="/docs/providers/azurerm/d/signalr_service.html">azurerm_signalr_service</a>
</li>
Expand Down

0 comments on commit bdb1321

Please sign in to comment.