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

r/dev_test_virtual_network: support for controlling the subnet #2041

Merged
merged 3 commits into from
Oct 11, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
101 changes: 99 additions & 2 deletions azurerm/resource_arm_dev_test_virtual_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,36 @@ func resourceArmDevTestVirtualNetwork() *schema.Resource {
Optional: true,
},

"subnet": {
Type: schema.TypeList,
Optional: true,
Computed: true,
// whilst the API accepts multiple, in practice only one is usable
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
},

"use_in_virtual_machine_creation": {
Type: schema.TypeString,
Optional: true,
Default: string(dtl.Allow),
ValidateFunc: validateDevTestVirtualNetworkUsagePermissionType(),
},

"use_public_ip_address": {
Type: schema.TypeString,
Optional: true,
Default: string(dtl.Allow),
ValidateFunc: validateDevTestVirtualNetworkUsagePermissionType(),
},
},
},
},

"tags": tagsSchema(),

"unique_identifier": {
Expand All @@ -68,10 +98,15 @@ func resourceArmDevTestVirtualNetworkCreateUpdate(d *schema.ResourceData, meta i
description := d.Get("description").(string)
tags := d.Get("tags").(map[string]interface{})

subscriptionId := meta.(*ArmClient).subscriptionId
subnetsRaw := d.Get("subnet").([]interface{})
subnets := expandDevTestVirtualNetworkSubnets(subnetsRaw, subscriptionId, resourceGroup, labName, name)

parameters := dtl.VirtualNetwork{
Tags: expandTags(tags),
VirtualNetworkProperties: &dtl.VirtualNetworkProperties{
Description: utils.String(description),
Description: utils.String(description),
SubnetOverrides: subnets,
},
}

Expand Down Expand Up @@ -111,7 +146,8 @@ func resourceArmDevTestVirtualNetworkRead(d *schema.ResourceData, meta interface
labName := id.Path["labs"]
name := id.Path["virtualnetworks"]

read, err := client.Get(ctx, resourceGroup, labName, name, "")
// TODO: is the expand still needed?
read, err := client.Get(ctx, resourceGroup, labName, name, "subnetOverrides")
if err != nil {
if utils.ResponseWasNotFound(read.Response) {
log.Printf("[DEBUG] DevTest Virtual Network %q was not found in Lab %q / Resource Group %q - removing from state!", name, labName, resourceGroup)
Expand All @@ -129,6 +165,11 @@ func resourceArmDevTestVirtualNetworkRead(d *schema.ResourceData, meta interface
if props := read.VirtualNetworkProperties; props != nil {
d.Set("description", props.Description)

flattenedSubnets := flattenDevTestVirtualNetworkSubnets(props.SubnetOverrides)
if err := d.Set("subnet", flattenedSubnets); err != nil {
return fmt.Errorf("Error setting `subnet`: %+v", err)
}

// Computed fields
d.Set("unique_identifier", props.UniqueIdentifier)
}
Expand Down Expand Up @@ -179,3 +220,59 @@ func validateDevTestVirtualNetworkName() schema.SchemaValidateFunc {
regexp.MustCompile("^[A-Za-z0-9_-]+$"),
"Virtual Network Name can only include alphanumeric characters, underscores, hyphens.")
}

func expandDevTestVirtualNetworkSubnets(input []interface{}, subscriptionId, resourceGroupName, labName, virtualNetworkName string) *[]dtl.SubnetOverride {
results := make([]dtl.SubnetOverride, 0)
if len(input) == 0 {
return &results
}

for _, val := range input {
v := val.(map[string]interface{})
// default found from the Portal
name := fmt.Sprintf("%sSubnet", virtualNetworkName)
idFmt := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.DevTestLab/labs/%s/virtualnetworks/%s/subnets/%s"
subnetId := fmt.Sprintf(idFmt, subscriptionId, resourceGroupName, labName, virtualNetworkName, name)
usePublicIPAddress := v["use_public_ip_address"].(string)
useInVirtualMachineCreation := v["use_in_virtual_machine_creation"].(string)

subnet := dtl.SubnetOverride{
ResourceID: utils.String(subnetId),
LabSubnetName: utils.String(name),
UsePublicIPAddressPermission: dtl.UsagePermissionType(usePublicIPAddress),
UseInVMCreationPermission: dtl.UsagePermissionType(useInVirtualMachineCreation),
}

results = append(results, subnet)
}

return &results
}

func flattenDevTestVirtualNetworkSubnets(input *[]dtl.SubnetOverride) []interface{} {
outputs := make([]interface{}, 0)
if input == nil {
return outputs
}

for _, v := range *input {
output := make(map[string]interface{}, 0)
if v.LabSubnetName != nil {
output["name"] = *v.LabSubnetName
}
output["use_public_ip_address"] = string(v.UsePublicIPAddressPermission)
output["use_in_virtual_machine_creation"] = string(v.UseInVMCreationPermission)

outputs = append(outputs, output)
}

return outputs
}

func validateDevTestVirtualNetworkUsagePermissionType() schema.SchemaValidateFunc {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Very minor this could go in the validate package

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will fix this in #2058 since it's built on top of this branch 👍

return validation.StringInSlice([]string{
string(dtl.Allow),
string(dtl.Default),
string(dtl.Deny),
}, false)
}
55 changes: 55 additions & 0 deletions azurerm/resource_arm_dev_test_virtual_network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,35 @@ func TestAccAzureRMDevTestVirtualNetwork_basic(t *testing.T) {
})
}

func TestAccAzureRMDevTestVirtualNetwork_subnet(t *testing.T) {
resourceName := "azurerm_dev_test_virtual_network.test"
rInt := acctest.RandInt()
location := testLocation()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMDevTestVirtualNetworkDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMDevTestVirtualNetwork_subnets(rInt, location),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMDevTestVirtualNetworkExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "subnet.#", "1"),
resource.TestCheckResourceAttr(resourceName, "subnet.0.use_public_ip_address", "Allow"),
resource.TestCheckResourceAttr(resourceName, "subnet.0.use_in_virtual_machine_creation", "Allow"),
resource.TestCheckResourceAttr(resourceName, "tags.%", "0"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testCheckAzureRMDevTestVirtualNetworkExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
// Ensure we have enough information in state to look up in API
Expand Down Expand Up @@ -141,3 +170,29 @@ resource "azurerm_dev_test_virtual_network" "test" {
}
`, rInt, location, rInt, rInt)
}

func testAccAzureRMDevTestVirtualNetwork_subnets(rInt int, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}
resource "azurerm_dev_test_lab" "test" {
name = "acctestdtl%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
}
resource "azurerm_dev_test_virtual_network" "test" {
name = "acctestdtvn%d"
lab_name = "${azurerm_dev_test_lab.test.name}"
resource_group_name = "${azurerm_resource_group.test.name}"
subnet {
use_public_ip_address = "Allow"
use_in_virtual_machine_creation = "Allow"
}
}
`, rInt, location, rInt, rInt)
}
18 changes: 18 additions & 0 deletions website/docs/r/dev_test_virtual_network.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,34 @@ The following arguments are supported:

* `description` - (Optional) A description for the Virtual Network.

* `subnet` - (Optional) A `subnet` block as defined below.

* `tags` - (Optional) A mapping of tags to assign to the resource.

---

A `subnet` block supports the following:

* `use_public_ip_address` - (Required) Can Virtual Machines in this Subnet use Public IP Addresses? Possible values are `Allow`, `Default` and `Deny`.

* `use_in_virtual_machine_creation` - (Required) Can this subnet be used for creating Virtual Machines? Possible values are `Allow`, `Default` and `Deny`.

## Attributes Reference

The following attributes are exported:

* `id` - The ID of the Dev Test Virtual Network.

* `subnet` - A `subnet` block as defined below.

* `unique_identifier` - The unique immutable identifier of the Dev Test Virtual Network.

---

A `subnet` block exports the following:

* `name` - The name of the Subnet for this Virtual Network.

## Import

Dev Test Virtual Networks can be imported using the `resource id`, e.g.
Expand Down