From 876d0269dfe3dea7535d41496d9adc674fb5ebca Mon Sep 17 00:00:00 2001 From: James Nugent Date: Wed, 1 Jun 2016 16:57:13 -0500 Subject: [PATCH] provider/azurerm: Fix azurerm_subnet ``` make testacc TEST=./builtin/providers/azurerm TESTARGS="-run TestAccAzureRMSubnet" ==> Checking that code complies with gofmt requirements... /Users/James/Code/go/bin/stringer go generate $(go list ./... | grep -v /vendor/) 2016/06/01 16:54:37 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/azurerm -v -run TestAccAzureRMSubnet -timeout 120m === RUN TestAccAzureRMSubnet_basic --- PASS: TestAccAzureRMSubnet_basic (131.83s) PASS ok github.com/hashicorp/terraform/builtin/providers/azurerm 131.844s ``` --- builtin/providers/azurerm/provider.go | 2 +- .../providers/azurerm/resource_arm_subnet.go | 368 +++++++++--------- .../azurerm/resource_arm_subnet_test.go | 212 +++++----- 3 files changed, 289 insertions(+), 293 deletions(-) diff --git a/builtin/providers/azurerm/provider.go b/builtin/providers/azurerm/provider.go index a69111aaa..c82bf3991 100644 --- a/builtin/providers/azurerm/provider.go +++ b/builtin/providers/azurerm/provider.go @@ -59,7 +59,7 @@ func Provider() terraform.ResourceProvider { "azurerm_storage_blob": resourceArmStorageBlob(), //"azurerm_storage_container": resourceArmStorageContainer(), "azurerm_storage_queue": resourceArmStorageQueue(), - //"azurerm_subnet": resourceArmSubnet(), + "azurerm_subnet": resourceArmSubnet(), //"azurerm_template_deployment": resourceArmTemplateDeployment(), //"azurerm_virtual_machine": resourceArmVirtualMachine(), "azurerm_virtual_network": resourceArmVirtualNetwork(), diff --git a/builtin/providers/azurerm/resource_arm_subnet.go b/builtin/providers/azurerm/resource_arm_subnet.go index 701fdf0fe..a09b9cab2 100644 --- a/builtin/providers/azurerm/resource_arm_subnet.go +++ b/builtin/providers/azurerm/resource_arm_subnet.go @@ -1,188 +1,184 @@ package azurerm -//import ( -// "fmt" -// "log" -// "net/http" -// "time" -// -// "github.com/Azure/azure-sdk-for-go/arm/network" -// "github.com/hashicorp/terraform/helper/resource" -// "github.com/hashicorp/terraform/helper/schema" -//) -// -//func resourceArmSubnet() *schema.Resource { -// return &schema.Resource{ -// Create: resourceArmSubnetCreate, -// Read: resourceArmSubnetRead, -// Update: resourceArmSubnetCreate, -// Delete: resourceArmSubnetDelete, -// -// Schema: map[string]*schema.Schema{ -// "name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// }, -// -// "resource_group_name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// }, -// -// "virtual_network_name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// }, -// -// "address_prefix": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// }, -// -// "network_security_group_id": &schema.Schema{ -// Type: schema.TypeString, -// Optional: true, -// Computed: true, -// }, -// -// "route_table_id": &schema.Schema{ -// Type: schema.TypeString, -// Optional: true, -// Computed: true, -// }, -// -// "ip_configurations": &schema.Schema{ -// Type: schema.TypeSet, -// Optional: true, -// Computed: true, -// Elem: &schema.Schema{Type: schema.TypeString}, -// Set: schema.HashString, -// }, -// }, -// } -//} -// -//func resourceArmSubnetCreate(d *schema.ResourceData, meta interface{}) error { -// client := meta.(*ArmClient) -// subnetClient := client.subnetClient -// -// log.Printf("[INFO] preparing arguments for Azure ARM Subnet creation.") -// -// name := d.Get("name").(string) -// vnetName := d.Get("virtual_network_name").(string) -// resGroup := d.Get("resource_group_name").(string) -// addressPrefix := d.Get("address_prefix").(string) -// -// armMutexKV.Lock(vnetName) -// defer armMutexKV.Unlock(vnetName) -// -// properties := network.SubnetPropertiesFormat{ -// AddressPrefix: &addressPrefix, -// } -// -// if v, ok := d.GetOk("network_security_group_id"); ok { -// nsgId := v.(string) -// properties.NetworkSecurityGroup = &network.SecurityGroup{ -// ID: &nsgId, -// } -// } -// -// if v, ok := d.GetOk("route_table_id"); ok { -// rtId := v.(string) -// properties.RouteTable = &network.RouteTable{ -// ID: &rtId, -// } -// } -// -// subnet := network.Subnet{ -// Name: &name, -// Properties: &properties, -// } -// -// resp, err := subnetClient.CreateOrUpdate(resGroup, vnetName, name, subnet) -// if err != nil { -// return err -// } -// -// d.SetId(*resp.ID) -// -// log.Printf("[DEBUG] Waiting for Subnet (%s) to become available", name) -// stateConf := &resource.StateChangeConf{ -// Pending: []string{"Accepted", "Updating"}, -// Target: []string{"Succeeded"}, -// Refresh: subnetRuleStateRefreshFunc(client, resGroup, vnetName, name), -// Timeout: 10 * time.Minute, -// } -// if _, err := stateConf.WaitForState(); err != nil { -// return fmt.Errorf("Error waiting for Subnet (%s) to become available: %s", name, err) -// } -// -// return resourceArmSubnetRead(d, meta) -//} -// -//func resourceArmSubnetRead(d *schema.ResourceData, meta interface{}) error { -// subnetClient := meta.(*ArmClient).subnetClient -// -// id, err := parseAzureResourceID(d.Id()) -// if err != nil { -// return err -// } -// resGroup := id.ResourceGroup -// vnetName := id.Path["virtualNetworks"] -// name := id.Path["subnets"] -// -// resp, err := subnetClient.Get(resGroup, vnetName, name, "") -// if resp.StatusCode == http.StatusNotFound { -// d.SetId("") -// return nil -// } -// if err != nil { -// return fmt.Errorf("Error making Read request on Azure Subnet %s: %s", name, err) -// } -// -// if resp.Properties.IPConfigurations != nil && len(*resp.Properties.IPConfigurations) > 0 { -// ips := make([]string, 0, len(*resp.Properties.IPConfigurations)) -// for _, ip := range *resp.Properties.IPConfigurations { -// ips = append(ips, *ip.ID) -// } -// -// if err := d.Set("ip_configurations", ips); err != nil { -// return err -// } -// } -// -// return nil -//} -// -//func resourceArmSubnetDelete(d *schema.ResourceData, meta interface{}) error { -// subnetClient := meta.(*ArmClient).subnetClient -// -// id, err := parseAzureResourceID(d.Id()) -// if err != nil { -// return err -// } -// resGroup := id.ResourceGroup -// name := id.Path["subnets"] -// vnetName := id.Path["virtualNetworks"] -// -// armMutexKV.Lock(vnetName) -// defer armMutexKV.Unlock(vnetName) -// -// _, err = subnetClient.Delete(resGroup, vnetName, name) -// -// return err -//} -// -//func subnetRuleStateRefreshFunc(client *ArmClient, resourceGroupName string, virtualNetworkName string, subnetName string) resource.StateRefreshFunc { -// return func() (interface{}, string, error) { -// res, err := client.subnetClient.Get(resourceGroupName, virtualNetworkName, subnetName, "") -// if err != nil { -// return nil, "", fmt.Errorf("Error issuing read request in subnetRuleStateRefreshFunc to Azure ARM for subnet '%s' (RG: '%s') (VNN: '%s'): %s", subnetName, resourceGroupName, virtualNetworkName, err) -// } -// -// return res, *res.Properties.ProvisioningState, nil -// } -//} +import ( + "fmt" + "log" + "net/http" + + "github.com/Azure/azure-sdk-for-go/arm/network" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceArmSubnet() *schema.Resource { + return &schema.Resource{ + Create: resourceArmSubnetCreate, + Read: resourceArmSubnetRead, + Update: resourceArmSubnetCreate, + Delete: resourceArmSubnetDelete, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "resource_group_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "virtual_network_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "address_prefix": { + Type: schema.TypeString, + Required: true, + }, + + "network_security_group_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "route_table_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "ip_configurations": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + }, + } +} + +func resourceArmSubnetCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient) + subnetClient := client.subnetClient + + log.Printf("[INFO] preparing arguments for Azure ARM Subnet creation.") + + name := d.Get("name").(string) + vnetName := d.Get("virtual_network_name").(string) + resGroup := d.Get("resource_group_name").(string) + addressPrefix := d.Get("address_prefix").(string) + + armMutexKV.Lock(vnetName) + defer armMutexKV.Unlock(vnetName) + + properties := network.SubnetPropertiesFormat{ + AddressPrefix: &addressPrefix, + } + + if v, ok := d.GetOk("network_security_group_id"); ok { + nsgId := v.(string) + properties.NetworkSecurityGroup = &network.SecurityGroup{ + ID: &nsgId, + } + } + + if v, ok := d.GetOk("route_table_id"); ok { + rtId := v.(string) + properties.RouteTable = &network.RouteTable{ + ID: &rtId, + } + } + + subnet := network.Subnet{ + Name: &name, + Properties: &properties, + } + + _, err := subnetClient.CreateOrUpdate(resGroup, vnetName, name, subnet, make(chan struct{})) + if err != nil { + return err + } + + read, err := subnetClient.Get(resGroup, vnetName, name, "") + if err != nil { + return err + } + if read.ID == nil { + return fmt.Errorf("Cannot read Subnet %s/%s (resource group %s) ID", vnetName, name, resGroup) + } + + d.SetId(*read.ID) + + return resourceArmSubnetRead(d, meta) +} + +func resourceArmSubnetRead(d *schema.ResourceData, meta interface{}) error { + subnetClient := meta.(*ArmClient).subnetClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + vnetName := id.Path["virtualNetworks"] + name := id.Path["subnets"] + + resp, err := subnetClient.Get(resGroup, vnetName, name, "") + if resp.StatusCode == http.StatusNotFound { + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("Error making Read request on Azure Subnet %s: %s", name, err) + } + + if resp.Properties.IPConfigurations != nil && len(*resp.Properties.IPConfigurations) > 0 { + ips := make([]string, 0, len(*resp.Properties.IPConfigurations)) + for _, ip := range *resp.Properties.IPConfigurations { + ips = append(ips, *ip.ID) + } + + if err := d.Set("ip_configurations", ips); err != nil { + return err + } + } + + return nil +} + +func resourceArmSubnetDelete(d *schema.ResourceData, meta interface{}) error { + subnetClient := meta.(*ArmClient).subnetClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["subnets"] + vnetName := id.Path["virtualNetworks"] + + armMutexKV.Lock(vnetName) + defer armMutexKV.Unlock(vnetName) + + _, err = subnetClient.Delete(resGroup, vnetName, name, make(chan struct{})) + + return err +} + +func subnetRuleStateRefreshFunc(client *ArmClient, resourceGroupName string, virtualNetworkName string, subnetName string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + res, err := client.subnetClient.Get(resourceGroupName, virtualNetworkName, subnetName, "") + if err != nil { + return nil, "", fmt.Errorf("Error issuing read request in subnetRuleStateRefreshFunc to Azure ARM for subnet '%s' (RG: '%s') (VNN: '%s'): %s", subnetName, resourceGroupName, virtualNetworkName, err) + } + + return res, *res.Properties.ProvisioningState, nil + } +} diff --git a/builtin/providers/azurerm/resource_arm_subnet_test.go b/builtin/providers/azurerm/resource_arm_subnet_test.go index 5f6314d26..844e04f99 100644 --- a/builtin/providers/azurerm/resource_arm_subnet_test.go +++ b/builtin/providers/azurerm/resource_arm_subnet_test.go @@ -1,108 +1,108 @@ package azurerm -//import ( -// "fmt" -// "net/http" -// "testing" -// -// "github.com/hashicorp/terraform/helper/acctest" -// "github.com/hashicorp/terraform/helper/resource" -// "github.com/hashicorp/terraform/terraform" -//) -// -//func TestAccAzureRMSubnet_basic(t *testing.T) { -// -// ri := acctest.RandInt() -// config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri) -// -// resource.Test(t, resource.TestCase{ -// PreCheck: func() { testAccPreCheck(t) }, -// Providers: testAccProviders, -// CheckDestroy: testCheckAzureRMSubnetDestroy, -// Steps: []resource.TestStep{ -// resource.TestStep{ -// Config: config, -// Check: resource.ComposeTestCheckFunc( -// testCheckAzureRMSubnetExists("azurerm_subnet.test"), -// ), -// }, -// }, -// }) -//} -// -//func testCheckAzureRMSubnetExists(name string) resource.TestCheckFunc { -// return func(s *terraform.State) error { -// // Ensure we have enough information in state to look up in API -// rs, ok := s.RootModule().Resources[name] -// if !ok { -// return fmt.Errorf("Not found: %s", name) -// } -// -// name := rs.Primary.Attributes["name"] -// vnetName := rs.Primary.Attributes["virtual_network_name"] -// resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] -// if !hasResourceGroup { -// return fmt.Errorf("Bad: no resource group found in state for subnet: %s", name) -// } -// -// conn := testAccProvider.Meta().(*ArmClient).subnetClient -// -// resp, err := conn.Get(resourceGroup, vnetName, name, "") -// if err != nil { -// return fmt.Errorf("Bad: Get on subnetClient: %s", err) -// } -// -// if resp.StatusCode == http.StatusNotFound { -// return fmt.Errorf("Bad: Subnet %q (resource group: %q) does not exist", name, resourceGroup) -// } -// -// return nil -// } -//} -// -//func testCheckAzureRMSubnetDestroy(s *terraform.State) error { -// conn := testAccProvider.Meta().(*ArmClient).subnetClient -// -// for _, rs := range s.RootModule().Resources { -// if rs.Type != "azurerm_subnet" { -// continue -// } -// -// name := rs.Primary.Attributes["name"] -// vnetName := rs.Primary.Attributes["virtual_network_name"] -// resourceGroup := rs.Primary.Attributes["resource_group_name"] -// -// resp, err := conn.Get(resourceGroup, vnetName, name, "") -// -// if err != nil { -// return nil -// } -// -// if resp.StatusCode != http.StatusNotFound { -// return fmt.Errorf("Subnet still exists:\n%#v", resp.Properties) -// } -// } -// -// return nil -//} -// -//var testAccAzureRMSubnet_basic = ` -//resource "azurerm_resource_group" "test" { -// name = "acctestrg-%d" -// location = "West US" -//} -// -//resource "azurerm_virtual_network" "test" { -// name = "acctestvirtnet%d" -// address_space = ["10.0.0.0/16"] -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -//} -// -//resource "azurerm_subnet" "test" { -// name = "acctestsubnet%d" -// resource_group_name = "${azurerm_resource_group.test.name}" -// virtual_network_name = "${azurerm_virtual_network.test.name}" -// address_prefix = "10.0.2.0/24" -//} -//` +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureRMSubnet_basic(t *testing.T) { + + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMSubnetDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSubnetExists("azurerm_subnet.test"), + ), + }, + }, + }) +} + +func testCheckAzureRMSubnetExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + vnetName := rs.Primary.Attributes["virtual_network_name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for subnet: %s", name) + } + + conn := testAccProvider.Meta().(*ArmClient).subnetClient + + resp, err := conn.Get(resourceGroup, vnetName, name, "") + if err != nil { + return fmt.Errorf("Bad: Get on subnetClient: %s", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Subnet %q (resource group: %q) does not exist", name, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMSubnetDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).subnetClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_subnet" { + continue + } + + name := rs.Primary.Attributes["name"] + vnetName := rs.Primary.Attributes["virtual_network_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(resourceGroup, vnetName, name, "") + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Subnet still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +var testAccAzureRMSubnet_basic = ` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "West US" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} +`