github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/builtin/providers/azurerm/resource_arm_route_table.go (about)

     1  package azurerm
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"net/http"
     8  	"strings"
     9  
    10  	"github.com/Azure/azure-sdk-for-go/arm/network"
    11  	"github.com/hashicorp/terraform/helper/hashcode"
    12  	"github.com/hashicorp/terraform/helper/schema"
    13  )
    14  
    15  func resourceArmRouteTable() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceArmRouteTableCreate,
    18  		Read:   resourceArmRouteTableRead,
    19  		Update: resourceArmRouteTableCreate,
    20  		Delete: resourceArmRouteTableDelete,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"name": {
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  				ForceNew: true,
    27  			},
    28  
    29  			"location": {
    30  				Type:      schema.TypeString,
    31  				Required:  true,
    32  				ForceNew:  true,
    33  				StateFunc: azureRMNormalizeLocation,
    34  			},
    35  
    36  			"resource_group_name": {
    37  				Type:     schema.TypeString,
    38  				Required: true,
    39  				ForceNew: true,
    40  			},
    41  
    42  			"route": {
    43  				Type:     schema.TypeSet,
    44  				Optional: true,
    45  				Computed: true,
    46  				Elem: &schema.Resource{
    47  					Schema: map[string]*schema.Schema{
    48  						"name": {
    49  							Type:     schema.TypeString,
    50  							Required: true,
    51  						},
    52  
    53  						"address_prefix": {
    54  							Type:     schema.TypeString,
    55  							Required: true,
    56  						},
    57  
    58  						"next_hop_type": {
    59  							Type:         schema.TypeString,
    60  							Required:     true,
    61  							ValidateFunc: validateRouteTableNextHopType,
    62  						},
    63  
    64  						"next_hop_in_ip_address": {
    65  							Type:     schema.TypeString,
    66  							Optional: true,
    67  							Computed: true,
    68  						},
    69  					},
    70  				},
    71  				Set: resourceArmRouteTableRouteHash,
    72  			},
    73  
    74  			"subnets": {
    75  				Type:     schema.TypeSet,
    76  				Optional: true,
    77  				Computed: true,
    78  				Elem:     &schema.Schema{Type: schema.TypeString},
    79  				Set:      schema.HashString,
    80  			},
    81  
    82  			"tags": tagsSchema(),
    83  		},
    84  	}
    85  }
    86  
    87  func resourceArmRouteTableCreate(d *schema.ResourceData, meta interface{}) error {
    88  	client := meta.(*ArmClient)
    89  	routeTablesClient := client.routeTablesClient
    90  
    91  	log.Printf("[INFO] preparing arguments for Azure ARM Route Table creation.")
    92  
    93  	name := d.Get("name").(string)
    94  	location := d.Get("location").(string)
    95  	resGroup := d.Get("resource_group_name").(string)
    96  	tags := d.Get("tags").(map[string]interface{})
    97  
    98  	routeSet := network.RouteTable{
    99  		Name:     &name,
   100  		Location: &location,
   101  		Tags:     expandTags(tags),
   102  	}
   103  
   104  	if _, ok := d.GetOk("route"); ok {
   105  		properties := network.RouteTablePropertiesFormat{}
   106  		routes, routeErr := expandAzureRmRouteTableRoutes(d)
   107  		if routeErr != nil {
   108  			return fmt.Errorf("Error Building list of Route Table Routes: %s", routeErr)
   109  		}
   110  		if len(routes) > 0 {
   111  			routeSet.Properties = &properties
   112  		}
   113  
   114  	}
   115  
   116  	_, err := routeTablesClient.CreateOrUpdate(resGroup, name, routeSet, make(chan struct{}))
   117  	if err != nil {
   118  		return err
   119  	}
   120  
   121  	read, err := routeTablesClient.Get(resGroup, name, "")
   122  	if err != nil {
   123  		return err
   124  	}
   125  	if read.ID == nil {
   126  		return fmt.Errorf("Cannot read Route Table %s (resource group %s) ID", name, resGroup)
   127  	}
   128  
   129  	d.SetId(*read.ID)
   130  
   131  	return resourceArmRouteTableRead(d, meta)
   132  }
   133  
   134  func resourceArmRouteTableRead(d *schema.ResourceData, meta interface{}) error {
   135  	routeTablesClient := meta.(*ArmClient).routeTablesClient
   136  
   137  	id, err := parseAzureResourceID(d.Id())
   138  	if err != nil {
   139  		return err
   140  	}
   141  	resGroup := id.ResourceGroup
   142  	name := id.Path["routeTables"]
   143  
   144  	resp, err := routeTablesClient.Get(resGroup, name, "")
   145  	if err != nil {
   146  		if resp.StatusCode == http.StatusNotFound {
   147  			d.SetId("")
   148  			return nil
   149  		}
   150  		return fmt.Errorf("Error making Read request on Azure Route Table %s: %s", name, err)
   151  	}
   152  
   153  	if resp.Properties.Subnets != nil {
   154  		if len(*resp.Properties.Subnets) > 0 {
   155  			subnets := make([]string, 0, len(*resp.Properties.Subnets))
   156  			for _, subnet := range *resp.Properties.Subnets {
   157  				id := subnet.ID
   158  				subnets = append(subnets, *id)
   159  			}
   160  
   161  			if err := d.Set("subnets", subnets); err != nil {
   162  				return err
   163  			}
   164  		}
   165  	}
   166  
   167  	flattenAndSetTags(d, resp.Tags)
   168  
   169  	return nil
   170  }
   171  
   172  func resourceArmRouteTableDelete(d *schema.ResourceData, meta interface{}) error {
   173  	routeTablesClient := meta.(*ArmClient).routeTablesClient
   174  
   175  	id, err := parseAzureResourceID(d.Id())
   176  	if err != nil {
   177  		return err
   178  	}
   179  	resGroup := id.ResourceGroup
   180  	name := id.Path["routeTables"]
   181  
   182  	_, err = routeTablesClient.Delete(resGroup, name, make(chan struct{}))
   183  
   184  	return err
   185  }
   186  
   187  func expandAzureRmRouteTableRoutes(d *schema.ResourceData) ([]network.Route, error) {
   188  	configs := d.Get("route").(*schema.Set).List()
   189  	routes := make([]network.Route, 0, len(configs))
   190  
   191  	for _, configRaw := range configs {
   192  		data := configRaw.(map[string]interface{})
   193  
   194  		address_prefix := data["address_prefix"].(string)
   195  		next_hop_type := data["next_hop_type"].(string)
   196  
   197  		properties := network.RoutePropertiesFormat{
   198  			AddressPrefix: &address_prefix,
   199  			NextHopType:   network.RouteNextHopType(next_hop_type),
   200  		}
   201  
   202  		if v := data["next_hop_in_ip_address"].(string); v != "" {
   203  			properties.NextHopIPAddress = &v
   204  		}
   205  
   206  		name := data["name"].(string)
   207  		route := network.Route{
   208  			Name:       &name,
   209  			Properties: &properties,
   210  		}
   211  
   212  		routes = append(routes, route)
   213  	}
   214  
   215  	return routes, nil
   216  }
   217  
   218  func resourceArmRouteTableRouteHash(v interface{}) int {
   219  	var buf bytes.Buffer
   220  	m := v.(map[string]interface{})
   221  	buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
   222  	buf.WriteString(fmt.Sprintf("%s-", m["address_prefix"].(string)))
   223  	buf.WriteString(fmt.Sprintf("%s-", m["next_hop_type"].(string)))
   224  
   225  	return hashcode.String(buf.String())
   226  }
   227  
   228  func validateRouteTableNextHopType(v interface{}, k string) (ws []string, errors []error) {
   229  	value := strings.ToLower(v.(string))
   230  	hopTypes := map[string]bool{
   231  		"virtualnetworkgateway": true,
   232  		"vnetlocal":             true,
   233  		"internet":              true,
   234  		"virtualappliance":      true,
   235  		"none":                  true,
   236  	}
   237  
   238  	if !hopTypes[value] {
   239  		errors = append(errors, fmt.Errorf("Route Table NextHopType Protocol can only be VirtualNetworkGateway, VnetLocal, Internet or VirtualAppliance"))
   240  	}
   241  	return
   242  }