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

Add Proximity Placement Group Resources + Support #4020

Merged
merged 21 commits into from
Sep 5, 2019
Merged
Show file tree
Hide file tree
Changes from 3 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/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ type ArmClient struct {
galleriesClient compute.GalleriesClient
galleryImagesClient compute.GalleryImagesClient
galleryImageVersionsClient compute.GalleryImageVersionsClient
ppgClient compute.ProximityPlacementGroupsClient
snapshotsClient compute.SnapshotsClient
usageOpsClient compute.UsageClient
vmExtensionImageClient compute.VirtualMachineExtensionImagesClient
Expand Down Expand Up @@ -456,6 +457,10 @@ func (c *ArmClient) registerComputeClients(endpoint, subscriptionId string, auth
galleryImageVersionsClient := compute.NewGalleryImageVersionsClientWithBaseURI(endpoint, subscriptionId)
c.configureClient(&galleryImageVersionsClient.Client, auth)
c.galleryImageVersionsClient = galleryImageVersionsClient

proximityPlacementGroupsClient := compute.NewProximityPlacementGroupsClientWithBaseURI(endpoint, subscriptionId)
c.configureClient(&proximityPlacementGroupsClient.Client, auth)
c.ppgClient = proximityPlacementGroupsClient
}

func (c *ArmClient) registerDatabases(endpoint, subscriptionId string, auth autorest.Authorizer, sender autorest.Sender) {
Expand Down
47 changes: 47 additions & 0 deletions azurerm/data_source_proximity_placement_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package azurerm

import (
"fmt"

"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func dataSourceArmProximityPlacementGroup() *schema.Resource {
return &schema.Resource{
Read: dataSourceArmProximityPlacementGroupRead,
Schema: map[string]*schema.Schema{
"resource_group_name": azure.SchemaResourceGroupNameForDataSource(),

"name": {
tobydoescode marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.NoZeroValues,
},
},
}
}

func dataSourceArmProximityPlacementGroupRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).ppgClient
ctx := meta.(*ArmClient).StopContext

resGroup := d.Get("resource_group_name").(string)
name := d.Get("name").(string)
tobydoescode marked this conversation as resolved.
Show resolved Hide resolved

resp, err := client.Get(ctx, resGroup, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Error: Proximity Placement Group %q (Resource Group %q) was not found", name, resGroup)
}

return fmt.Errorf("Error making Read request on Proximity Placement Group %q (Resource Group %q): %+v", name, resGroup, err)
}

d.SetId(*resp.ID)
flattenAndSetTags(d, resp.Tags)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add tags.SchemaForDataSource to the resource so this has an effect?

Test ended in panic.

------- Stdout: -------
=== RUN   TestAccDataSourceProximityPlacementGroup_basic
=== PAUSE TestAccDataSourceProximityPlacementGroup_basic
=== CONT  TestAccDataSourceProximityPlacementGroup_basic

------- Stderr: -------
panic: Invalid address to set: []string{"tags"}


return nil
}
56 changes: 56 additions & 0 deletions azurerm/data_source_proximity_placement_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package azurerm

import (
"fmt"
"testing"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"

"github.com/hashicorp/terraform/helper/resource"
)

func TestAccDataSourceProximityPlacementGroup_basic(t *testing.T) {
dataSourceName := "data.azurerm_proximity_placement_group.test"
ri := tf.AccRandTimeInt()
location := testLocation()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceProximityPlacementGroup_basic(ri, location),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(dataSourceName, "location"),
resource.TestCheckResourceAttrSet(dataSourceName, "name"),
resource.TestCheckResourceAttrSet(dataSourceName, "resource_group_name"),
resource.TestCheckResourceAttr(dataSourceName, "tags.%", "1"),
),
},
},
})
}

func testAccDataSourceProximityPlacementGroup_basic(rInt int, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%[1]d"
location = "%[2]s"
}

resource "azurerm_proximity_placement_group" "test" {
name = "acctestppg-%[1]d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"

tags = {
"foo" = "bar"
}
}

data "azurerm_proximity_placement_group" "test" {
resource_group_name = "${azurerm_resource_group.test.name}"
name = "${azurerm_proximity_placement_group.test.name}"
}
`, rInt, location)
}
2 changes: 2 additions & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_notification_hub": dataSourceNotificationHub(),
"azurerm_platform_image": dataSourceArmPlatformImage(),
"azurerm_policy_definition": dataSourceArmPolicyDefinition(),
"azurerm_proximity_placement_group": dataSourceArmProximityPlacementGroup(),
"azurerm_public_ip": dataSourceArmPublicIP(),
"azurerm_public_ips": dataSourceArmPublicIPs(),
"azurerm_recovery_services_vault": dataSourceArmRecoveryServicesVault(),
Expand Down Expand Up @@ -322,6 +323,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_postgresql_virtual_network_rule": resourceArmPostgreSQLVirtualNetworkRule(),
"azurerm_private_dns_zone": resourceArmPrivateDnsZone(),
"azurerm_private_dns_a_record": resourceArmPrivateDnsARecord(),
"azurerm_proximity_placement_group": resourceArmProximityPlacementGroup(),
"azurerm_public_ip": resourceArmPublicIp(),
"azurerm_public_ip_prefix": resourceArmPublicIpPrefix(),
"azurerm_recovery_services_protected_vm": resourceArmRecoveryServicesProtectedVm(),
Expand Down
34 changes: 30 additions & 4 deletions azurerm/resource_arm_availability_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ func resourceArmAvailabilitySet() *schema.Resource {
ForceNew: true,
},

"proximity_placement_group_id": {
tobydoescode marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeString,
Optional: true,
ForceNew: true,
StateFunc: func(id interface{}) string {
return strings.ToLower(id.(string))
},
},

"tags": tagsSchema(),
},
}
Expand Down Expand Up @@ -90,13 +99,24 @@ func resourceArmAvailabilitySetCreateUpdate(d *schema.ResourceData, meta interfa
managed := d.Get("managed").(bool)
tags := d.Get("tags").(map[string]interface{})

properties := compute.AvailabilitySetProperties{
PlatformFaultDomainCount: utils.Int32(int32(faultDomainCount)),
PlatformUpdateDomainCount: utils.Int32(int32(updateDomainCount)),
}

if v, ok := d.GetOk("proximity_placement_group_id"); ok {
tobydoescode marked this conversation as resolved.
Show resolved Hide resolved
proximityPlacementGroup := v.(string)
ppg := compute.SubResource{
ID: &proximityPlacementGroup,
}

properties.ProximityPlacementGroup = &ppg
tobydoescode marked this conversation as resolved.
Show resolved Hide resolved
}

availSet := compute.AvailabilitySet{
Name: &name,
Location: &location,
AvailabilitySetProperties: &compute.AvailabilitySetProperties{
tobydoescode marked this conversation as resolved.
Show resolved Hide resolved
PlatformFaultDomainCount: utils.Int32(int32(faultDomainCount)),
PlatformUpdateDomainCount: utils.Int32(int32(updateDomainCount)),
},
AvailabilitySetProperties: &properties,
Tags: expandTags(tags),
}

Expand Down Expand Up @@ -149,6 +169,12 @@ func resourceArmAvailabilitySetRead(d *schema.ResourceData, meta interface{}) er
if props := resp.AvailabilitySetProperties; props != nil {
d.Set("platform_update_domain_count", props.PlatformUpdateDomainCount)
d.Set("platform_fault_domain_count", props.PlatformFaultDomainCount)

if proximityPlacementGroup := props.ProximityPlacementGroup; proximityPlacementGroup != nil {
// Lowercase due to incorrect capitalisation of resource group name in
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this have potential issues if there are capitables in other places? we should be more specific with the fix.

Also, has a bug report been files/opened anywhere? if not could we open on on the azure for go sdk and link it here with an addtional comment:
this can be removed when http://link.to.issue has been fixed

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See other comment the ID, this is in-line with how availability set ID are handled.

// proximity placement group ID in response from get VM API request
d.Set("proximity_placement_group_id", strings.ToLower(*proximityPlacementGroup.ID))
}
}

flattenAndSetTags(d, resp.Tags)
Expand Down
126 changes: 126 additions & 0 deletions azurerm/resource_arm_proximity_placement_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package azurerm

import (
"fmt"
"log"

"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute"
"github.com/hashicorp/terraform/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmProximityPlacementGroup() *schema.Resource {
return &schema.Resource{
Create: resourceArmProximityPlacementGroupCreateUpdate,
Read: resourceArmProximityPlacementGroupRead,
Update: resourceArmProximityPlacementGroupCreateUpdate,
Delete: resourceArmProximityPlacementGroupDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we validate the name here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validate how? I'm not going to pretend I'm not rather new to this. Much of this is taken directly from availability sets since the requirements were very similar.


"resource_group_name": azure.SchemaResourceGroupName(),

"location": azure.SchemaLocation(),

"tags": tagsSchema(),
},
}
}

func resourceArmProximityPlacementGroupCreateUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).ppgClient
ctx := meta.(*ArmClient).StopContext

log.Printf("[INFO] preparing arguments for AzureRM Proximity Placement Group creation.")

name := d.Get("name").(string)
resGroup := d.Get("resource_group_name").(string)

if requireResourcesToBeImported && d.IsNewResource() {
existing, err := client.Get(ctx, resGroup, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("Error checking for presence of existing Proximity Placement Group %q (Resource Group %q): %s", name, resGroup, err)
}
}

if existing.ID != nil && *existing.ID != "" {
return tf.ImportAsExistsError("azurerm_proximity_placement_group", *existing.ID)
}
}

location := azure.NormalizeLocation(d.Get("location").(string))
tags := d.Get("tags").(map[string]interface{})

ppg := compute.ProximityPlacementGroup{
Name: &name,
Location: &location,
Tags: expandTags(tags),
}

resp, err := client.CreateOrUpdate(ctx, resGroup, name, ppg)
if err != nil {
return err
}

d.SetId(*resp.ID)

return resourceArmProximityPlacementGroupRead(d, meta)
}

func resourceArmProximityPlacementGroupRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).ppgClient
ctx := meta.(*ArmClient).StopContext

id, err := parseAzureResourceID(d.Id())
if err != nil {
return err
}
resGroup := id.ResourceGroup
name := id.Path["proximityPlacementGroups"]

resp, err := client.Get(ctx, resGroup, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
d.SetId("")
return nil
}
return fmt.Errorf("Error making Read request on Proximity Placement Group %q (Resource Group %q): %+v", name, resGroup, err)
}

d.Set("name", resp.Name)
d.Set("resource_group_name", resGroup)
if location := resp.Location; location != nil {
d.Set("location", azure.NormalizeLocation(*location))
}

flattenAndSetTags(d, resp.Tags)

return nil
}

func resourceArmProximityPlacementGroupDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).ppgClient
ctx := meta.(*ArmClient).StopContext

id, err := parseAzureResourceID(d.Id())
if err != nil {
return err
}
resGroup := id.ResourceGroup
name := id.Path["proximityPlacementGroup"]

_, err = client.Delete(ctx, resGroup, name)

return err
}
Loading