diff --git a/builtin/providers/azurerm/provider.go b/builtin/providers/azurerm/provider.go index 08788eef5f..9d2fd1754c 100644 --- a/builtin/providers/azurerm/provider.go +++ b/builtin/providers/azurerm/provider.go @@ -52,8 +52,8 @@ func Provider() terraform.ResourceProvider { //"azurerm_network_interface": resourceArmNetworkInterface(), //"azurerm_network_security_group": resourceArmNetworkSecurityGroup(), //"azurerm_network_security_rule": resourceArmNetworkSecurityRule(), - "azurerm_public_ip": resourceArmPublicIp(), - //"azurerm_route": resourceArmRoute(), + "azurerm_public_ip": resourceArmPublicIp(), + "azurerm_route": resourceArmRoute(), "azurerm_route_table": resourceArmRouteTable(), "azurerm_storage_account": resourceArmStorageAccount(), "azurerm_storage_blob": resourceArmStorageBlob(), diff --git a/builtin/providers/azurerm/resource_arm_route.go b/builtin/providers/azurerm/resource_arm_route.go index 965d7e3a35..ae7b382795 100644 --- a/builtin/providers/azurerm/resource_arm_route.go +++ b/builtin/providers/azurerm/resource_arm_route.go @@ -1,161 +1,144 @@ 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 resourceArmRoute() *schema.Resource { -// return &schema.Resource{ -// Create: resourceArmRouteCreate, -// Read: resourceArmRouteRead, -// Update: resourceArmRouteCreate, -// Delete: resourceArmRouteDelete, -// -// 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, -// }, -// -// "route_table_name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// }, -// -// "address_prefix": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// }, -// -// "next_hop_type": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ValidateFunc: validateRouteTableNextHopType, -// }, -// -// "next_hop_in_ip_address": &schema.Schema{ -// Type: schema.TypeString, -// Optional: true, -// Computed: true, -// }, -// }, -// } -//} -// -//func resourceArmRouteCreate(d *schema.ResourceData, meta interface{}) error { -// client := meta.(*ArmClient) -// routesClient := client.routesClient -// -// name := d.Get("name").(string) -// rtName := d.Get("route_table_name").(string) -// resGroup := d.Get("resource_group_name").(string) -// -// addressPrefix := d.Get("address_prefix").(string) -// nextHopType := d.Get("next_hop_type").(string) -// -// armMutexKV.Lock(rtName) -// defer armMutexKV.Unlock(rtName) -// -// properties := network.RoutePropertiesFormat{ -// AddressPrefix: &addressPrefix, -// NextHopType: network.RouteNextHopType(nextHopType), -// } -// -// if v, ok := d.GetOk("next_hop_in_ip_address"); ok { -// nextHopInIpAddress := v.(string) -// properties.NextHopIPAddress = &nextHopInIpAddress -// } -// -// route := network.Route{ -// Name: &name, -// Properties: &properties, -// } -// -// resp, err := routesClient.CreateOrUpdate(resGroup, rtName, name, route) -// if err != nil { -// return err -// } -// d.SetId(*resp.ID) -// -// log.Printf("[DEBUG] Waiting for Route (%s) to become available", name) -// stateConf := &resource.StateChangeConf{ -// Pending: []string{"Accepted", "Updating"}, -// Target: []string{"Succeeded"}, -// Refresh: routeStateRefreshFunc(client, resGroup, rtName, name), -// Timeout: 10 * time.Minute, -// } -// if _, err := stateConf.WaitForState(); err != nil { -// return fmt.Errorf("Error waiting for Route (%s) to become available: %s", name, err) -// } -// -// return resourceArmRouteRead(d, meta) -//} -// -//func resourceArmRouteRead(d *schema.ResourceData, meta interface{}) error { -// routesClient := meta.(*ArmClient).routesClient -// -// id, err := parseAzureResourceID(d.Id()) -// if err != nil { -// return err -// } -// resGroup := id.ResourceGroup -// rtName := id.Path["routeTables"] -// routeName := id.Path["routes"] -// -// resp, err := routesClient.Get(resGroup, rtName, routeName) -// if resp.StatusCode == http.StatusNotFound { -// d.SetId("") -// return nil -// } -// if err != nil { -// return fmt.Errorf("Error making Read request on Azure Route %s: %s", routeName, err) -// } -// -// return nil -//} -// -//func resourceArmRouteDelete(d *schema.ResourceData, meta interface{}) error { -// client := meta.(*ArmClient) -// routesClient := client.routesClient -// -// id, err := parseAzureResourceID(d.Id()) -// if err != nil { -// return err -// } -// resGroup := id.ResourceGroup -// rtName := id.Path["routeTables"] -// routeName := id.Path["routes"] -// -// armMutexKV.Lock(rtName) -// defer armMutexKV.Unlock(rtName) -// -// _, err = routesClient.Delete(resGroup, rtName, routeName) -// -// return err -//} -// -//func routeStateRefreshFunc(client *ArmClient, resourceGroupName string, routeTableName string, routeName string) resource.StateRefreshFunc { -// return func() (interface{}, string, error) { -// res, err := client.routesClient.Get(resourceGroupName, routeTableName, routeName) -// if err != nil { -// return nil, "", fmt.Errorf("Error issuing read request in routeStateRefreshFunc to Azure ARM for route '%s' (RG: '%s') (NSG: '%s'): %s", routeName, resourceGroupName, routeTableName, err) -// } -// -// return res, *res.Properties.ProvisioningState, nil -// } -//} +import ( + "fmt" + "net/http" + + "github.com/Azure/azure-sdk-for-go/arm/network" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceArmRoute() *schema.Resource { + return &schema.Resource{ + Create: resourceArmRouteCreate, + Read: resourceArmRouteRead, + Update: resourceArmRouteCreate, + Delete: resourceArmRouteDelete, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "resource_group_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "route_table_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "address_prefix": { + Type: schema.TypeString, + Required: true, + }, + + "next_hop_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateRouteTableNextHopType, + }, + + "next_hop_in_ip_address": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + } +} + +func resourceArmRouteCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient) + routesClient := client.routesClient + + name := d.Get("name").(string) + rtName := d.Get("route_table_name").(string) + resGroup := d.Get("resource_group_name").(string) + + addressPrefix := d.Get("address_prefix").(string) + nextHopType := d.Get("next_hop_type").(string) + + armMutexKV.Lock(rtName) + defer armMutexKV.Unlock(rtName) + + properties := network.RoutePropertiesFormat{ + AddressPrefix: &addressPrefix, + NextHopType: network.RouteNextHopType(nextHopType), + } + + if v, ok := d.GetOk("next_hop_in_ip_address"); ok { + nextHopInIpAddress := v.(string) + properties.NextHopIPAddress = &nextHopInIpAddress + } + + route := network.Route{ + Name: &name, + Properties: &properties, + } + + _, err := routesClient.CreateOrUpdate(resGroup, rtName, name, route, make(chan struct{})) + if err != nil { + return err + } + + read, err := routesClient.Get(resGroup, rtName, name) + if err != nil { + return err + } + if read.ID == nil { + return fmt.Errorf("Cannot read Route %s/%s (resource group %s) ID", rtName, name, resGroup) + } + d.SetId(*read.ID) + + return resourceArmRouteRead(d, meta) +} + +func resourceArmRouteRead(d *schema.ResourceData, meta interface{}) error { + routesClient := meta.(*ArmClient).routesClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + rtName := id.Path["routeTables"] + routeName := id.Path["routes"] + + resp, err := routesClient.Get(resGroup, rtName, routeName) + if resp.StatusCode == http.StatusNotFound { + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("Error making Read request on Azure Route %s: %s", routeName, err) + } + + return nil +} + +func resourceArmRouteDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient) + routesClient := client.routesClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + rtName := id.Path["routeTables"] + routeName := id.Path["routes"] + + armMutexKV.Lock(rtName) + defer armMutexKV.Unlock(rtName) + + _, err = routesClient.Delete(resGroup, rtName, routeName, make(chan struct{})) + + return err +} diff --git a/builtin/providers/azurerm/resource_arm_route_test.go b/builtin/providers/azurerm/resource_arm_route_test.go index b98a6302b7..6a664e9bfb 100644 --- a/builtin/providers/azurerm/resource_arm_route_test.go +++ b/builtin/providers/azurerm/resource_arm_route_test.go @@ -1,159 +1,159 @@ 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 TestAccAzureRMRoute_basic(t *testing.T) { -// -// ri := acctest.RandInt() -// config := fmt.Sprintf(testAccAzureRMRoute_basic, ri, ri, ri) -// -// resource.Test(t, resource.TestCase{ -// PreCheck: func() { testAccPreCheck(t) }, -// Providers: testAccProviders, -// CheckDestroy: testCheckAzureRMRouteDestroy, -// Steps: []resource.TestStep{ -// resource.TestStep{ -// Config: config, -// Check: resource.ComposeTestCheckFunc( -// testCheckAzureRMRouteExists("azurerm_route.test"), -// ), -// }, -// }, -// }) -//} -// -//func TestAccAzureRMRoute_multipleRoutes(t *testing.T) { -// -// ri := acctest.RandInt() -// preConfig := fmt.Sprintf(testAccAzureRMRoute_basic, ri, ri, ri) -// postConfig := fmt.Sprintf(testAccAzureRMRoute_multipleRoutes, ri, ri, ri) -// -// resource.Test(t, resource.TestCase{ -// PreCheck: func() { testAccPreCheck(t) }, -// Providers: testAccProviders, -// CheckDestroy: testCheckAzureRMRouteDestroy, -// Steps: []resource.TestStep{ -// resource.TestStep{ -// Config: preConfig, -// Check: resource.ComposeTestCheckFunc( -// testCheckAzureRMRouteExists("azurerm_route.test"), -// ), -// }, -// -// resource.TestStep{ -// Config: postConfig, -// Check: resource.ComposeTestCheckFunc( -// testCheckAzureRMRouteExists("azurerm_route.test1"), -// ), -// }, -// }, -// }) -//} -// -//func testCheckAzureRMRouteExists(name string) resource.TestCheckFunc { -// return func(s *terraform.State) error { -// -// rs, ok := s.RootModule().Resources[name] -// if !ok { -// return fmt.Errorf("Not found: %s", name) -// } -// -// name := rs.Primary.Attributes["name"] -// rtName := rs.Primary.Attributes["route_table_name"] -// resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] -// if !hasResourceGroup { -// return fmt.Errorf("Bad: no resource group found in state for route: %s", name) -// } -// -// conn := testAccProvider.Meta().(*ArmClient).routesClient -// -// resp, err := conn.Get(resourceGroup, rtName, name) -// if err != nil { -// return fmt.Errorf("Bad: Get on routesClient: %s", err) -// } -// -// if resp.StatusCode == http.StatusNotFound { -// return fmt.Errorf("Bad: Route %q (resource group: %q) does not exist", name, resourceGroup) -// } -// -// return nil -// } -//} -// -//func testCheckAzureRMRouteDestroy(s *terraform.State) error { -// conn := testAccProvider.Meta().(*ArmClient).routesClient -// -// for _, rs := range s.RootModule().Resources { -// if rs.Type != "azurerm_route" { -// continue -// } -// -// name := rs.Primary.Attributes["name"] -// rtName := rs.Primary.Attributes["route_table_name"] -// resourceGroup := rs.Primary.Attributes["resource_group_name"] -// -// resp, err := conn.Get(resourceGroup, rtName, name) -// -// if err != nil { -// return nil -// } -// -// if resp.StatusCode != http.StatusNotFound { -// return fmt.Errorf("Route still exists:\n%#v", resp.Properties) -// } -// } -// -// return nil -//} -// -//var testAccAzureRMRoute_basic = ` -//resource "azurerm_resource_group" "test" { -// name = "acctestrg-%d" -// location = "West US" -//} -// -//resource "azurerm_route_table" "test" { -// name = "acctestrt%d" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -//} -// -//resource "azurerm_route" "test" { -// name = "acctestroute%d" -// resource_group_name = "${azurerm_resource_group.test.name}" -// route_table_name = "${azurerm_route_table.test.name}" -// -// address_prefix = "10.1.0.0/16" -// next_hop_type = "vnetlocal" -//} -//` -// -//var testAccAzureRMRoute_multipleRoutes = ` -//resource "azurerm_resource_group" "test" { -// name = "acctestrg-%d" -// location = "West US" -//} -// -//resource "azurerm_route_table" "test" { -// name = "acctestrt%d" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -//} -// -//resource "azurerm_route" "test1" { -// name = "acctestroute%d" -// resource_group_name = "${azurerm_resource_group.test.name}" -// route_table_name = "${azurerm_route_table.test.name}" -// -// address_prefix = "10.2.0.0/16" -// next_hop_type = "none" -//} -//` +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureRMRoute_basic(t *testing.T) { + + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMRoute_basic, ri, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMRouteDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRouteExists("azurerm_route.test"), + ), + }, + }, + }) +} + +func TestAccAzureRMRoute_multipleRoutes(t *testing.T) { + + ri := acctest.RandInt() + preConfig := fmt.Sprintf(testAccAzureRMRoute_basic, ri, ri, ri) + postConfig := fmt.Sprintf(testAccAzureRMRoute_multipleRoutes, ri, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMRouteDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRouteExists("azurerm_route.test"), + ), + }, + + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRouteExists("azurerm_route.test1"), + ), + }, + }, + }) +} + +func testCheckAzureRMRouteExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + rtName := rs.Primary.Attributes["route_table_name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for route: %s", name) + } + + conn := testAccProvider.Meta().(*ArmClient).routesClient + + resp, err := conn.Get(resourceGroup, rtName, name) + if err != nil { + return fmt.Errorf("Bad: Get on routesClient: %s", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Route %q (resource group: %q) does not exist", name, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMRouteDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).routesClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_route" { + continue + } + + name := rs.Primary.Attributes["name"] + rtName := rs.Primary.Attributes["route_table_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(resourceGroup, rtName, name) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Route still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +var testAccAzureRMRoute_basic = ` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "West US" +} + +resource "azurerm_route_table" "test" { + name = "acctestrt%d" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_route" "test" { + name = "acctestroute%d" + resource_group_name = "${azurerm_resource_group.test.name}" + route_table_name = "${azurerm_route_table.test.name}" + + address_prefix = "10.1.0.0/16" + next_hop_type = "vnetlocal" +} +` + +var testAccAzureRMRoute_multipleRoutes = ` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "West US" +} + +resource "azurerm_route_table" "test" { + name = "acctestrt%d" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_route" "test1" { + name = "acctestroute%d" + resource_group_name = "${azurerm_resource_group.test.name}" + route_table_name = "${azurerm_route_table.test.name}" + + address_prefix = "10.2.0.0/16" + next_hop_type = "none" +} +`