github.com/memsql/terraform@v0.7.0-rc2.0.20160706152241-21e2173e0a32/builtin/providers/azurerm/resource_arm_virtual_network.go (about)

     1  package azurerm
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"net/http"
     7  
     8  	"github.com/Azure/azure-sdk-for-go/arm/network"
     9  	"github.com/hashicorp/terraform/helper/hashcode"
    10  	"github.com/hashicorp/terraform/helper/resource"
    11  	"github.com/hashicorp/terraform/helper/schema"
    12  )
    13  
    14  func resourceArmVirtualNetwork() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceArmVirtualNetworkCreate,
    17  		Read:   resourceArmVirtualNetworkRead,
    18  		Update: resourceArmVirtualNetworkCreate,
    19  		Delete: resourceArmVirtualNetworkDelete,
    20  
    21  		Schema: map[string]*schema.Schema{
    22  			"name": {
    23  				Type:     schema.TypeString,
    24  				Required: true,
    25  				ForceNew: true,
    26  			},
    27  
    28  			"address_space": {
    29  				Type:     schema.TypeList,
    30  				Required: true,
    31  				Elem: &schema.Schema{
    32  					Type: schema.TypeString,
    33  				},
    34  			},
    35  
    36  			"dns_servers": {
    37  				Type:     schema.TypeList,
    38  				Optional: true,
    39  				Elem: &schema.Schema{
    40  					Type: schema.TypeString,
    41  				},
    42  			},
    43  
    44  			"subnet": {
    45  				Type:     schema.TypeSet,
    46  				Optional: true,
    47  				Computed: true,
    48  				Elem: &schema.Resource{
    49  					Schema: map[string]*schema.Schema{
    50  						"name": {
    51  							Type:     schema.TypeString,
    52  							Required: true,
    53  						},
    54  						"address_prefix": {
    55  							Type:     schema.TypeString,
    56  							Required: true,
    57  						},
    58  						"security_group": {
    59  							Type:     schema.TypeString,
    60  							Optional: true,
    61  						},
    62  					},
    63  				},
    64  				Set: resourceAzureSubnetHash,
    65  			},
    66  
    67  			"location": {
    68  				Type:      schema.TypeString,
    69  				Required:  true,
    70  				ForceNew:  true,
    71  				StateFunc: azureRMNormalizeLocation,
    72  			},
    73  
    74  			"resource_group_name": {
    75  				Type:     schema.TypeString,
    76  				Required: true,
    77  				ForceNew: true,
    78  			},
    79  
    80  			"tags": tagsSchema(),
    81  		},
    82  	}
    83  }
    84  
    85  func resourceArmVirtualNetworkCreate(d *schema.ResourceData, meta interface{}) error {
    86  	client := meta.(*ArmClient)
    87  	vnetClient := client.vnetClient
    88  
    89  	log.Printf("[INFO] preparing arguments for Azure ARM virtual network creation.")
    90  
    91  	name := d.Get("name").(string)
    92  	location := d.Get("location").(string)
    93  	resGroup := d.Get("resource_group_name").(string)
    94  	tags := d.Get("tags").(map[string]interface{})
    95  
    96  	vnet := network.VirtualNetwork{
    97  		Name:       &name,
    98  		Location:   &location,
    99  		Properties: getVirtualNetworkProperties(d),
   100  		Tags:       expandTags(tags),
   101  	}
   102  
   103  	_, err := vnetClient.CreateOrUpdate(resGroup, name, vnet, make(chan struct{}))
   104  	if err != nil {
   105  		return err
   106  	}
   107  
   108  	read, err := vnetClient.Get(resGroup, name, "")
   109  	if err != nil {
   110  		return err
   111  	}
   112  	if read.ID == nil {
   113  		return fmt.Errorf("Cannot read Virtual Network %s (resource group %s) ID", name, resGroup)
   114  	}
   115  
   116  	d.SetId(*read.ID)
   117  
   118  	return resourceArmVirtualNetworkRead(d, meta)
   119  }
   120  
   121  func resourceArmVirtualNetworkRead(d *schema.ResourceData, meta interface{}) error {
   122  	vnetClient := meta.(*ArmClient).vnetClient
   123  
   124  	id, err := parseAzureResourceID(d.Id())
   125  	if err != nil {
   126  		return err
   127  	}
   128  	resGroup := id.ResourceGroup
   129  	name := id.Path["virtualNetworks"]
   130  
   131  	resp, err := vnetClient.Get(resGroup, name, "")
   132  	if resp.StatusCode == http.StatusNotFound {
   133  		d.SetId("")
   134  		return nil
   135  	}
   136  	if err != nil {
   137  		return fmt.Errorf("Error making Read request on Azure virtual network %s: %s", name, err)
   138  	}
   139  	vnet := *resp.Properties
   140  
   141  	// update appropriate values
   142  	d.Set("address_space", vnet.AddressSpace.AddressPrefixes)
   143  
   144  	subnets := &schema.Set{
   145  		F: resourceAzureSubnetHash,
   146  	}
   147  
   148  	for _, subnet := range *vnet.Subnets {
   149  		s := map[string]interface{}{}
   150  
   151  		s["name"] = *subnet.Name
   152  		s["address_prefix"] = *subnet.Properties.AddressPrefix
   153  		if subnet.Properties.NetworkSecurityGroup != nil {
   154  			s["security_group"] = *subnet.Properties.NetworkSecurityGroup.ID
   155  		}
   156  
   157  		subnets.Add(s)
   158  	}
   159  	d.Set("subnet", subnets)
   160  
   161  	dnses := []string{}
   162  	for _, dns := range *vnet.DhcpOptions.DNSServers {
   163  		dnses = append(dnses, dns)
   164  	}
   165  	d.Set("dns_servers", dnses)
   166  
   167  	flattenAndSetTags(d, resp.Tags)
   168  
   169  	return nil
   170  }
   171  
   172  func resourceArmVirtualNetworkDelete(d *schema.ResourceData, meta interface{}) error {
   173  	vnetClient := meta.(*ArmClient).vnetClient
   174  
   175  	id, err := parseAzureResourceID(d.Id())
   176  	if err != nil {
   177  		return err
   178  	}
   179  	resGroup := id.ResourceGroup
   180  	name := id.Path["virtualNetworks"]
   181  
   182  	_, err = vnetClient.Delete(resGroup, name, make(chan struct{}))
   183  
   184  	return err
   185  }
   186  
   187  func getVirtualNetworkProperties(d *schema.ResourceData) *network.VirtualNetworkPropertiesFormat {
   188  	// first; get address space prefixes:
   189  	prefixes := []string{}
   190  	for _, prefix := range d.Get("address_space").([]interface{}) {
   191  		prefixes = append(prefixes, prefix.(string))
   192  	}
   193  
   194  	// then; the dns servers:
   195  	dnses := []string{}
   196  	for _, dns := range d.Get("dns_servers").([]interface{}) {
   197  		dnses = append(dnses, dns.(string))
   198  	}
   199  
   200  	// then; the subnets:
   201  	subnets := []network.Subnet{}
   202  	if subs := d.Get("subnet").(*schema.Set); subs.Len() > 0 {
   203  		for _, subnet := range subs.List() {
   204  			subnet := subnet.(map[string]interface{})
   205  
   206  			name := subnet["name"].(string)
   207  			prefix := subnet["address_prefix"].(string)
   208  			secGroup := subnet["security_group"].(string)
   209  
   210  			var subnetObj network.Subnet
   211  			subnetObj.Name = &name
   212  			subnetObj.Properties = &network.SubnetPropertiesFormat{}
   213  			subnetObj.Properties.AddressPrefix = &prefix
   214  
   215  			if secGroup != "" {
   216  				subnetObj.Properties.NetworkSecurityGroup = &network.SecurityGroup{
   217  					ID: &secGroup,
   218  				}
   219  			}
   220  
   221  			subnets = append(subnets, subnetObj)
   222  		}
   223  	}
   224  
   225  	// finally; return the struct:
   226  	return &network.VirtualNetworkPropertiesFormat{
   227  		AddressSpace: &network.AddressSpace{
   228  			AddressPrefixes: &prefixes,
   229  		},
   230  		DhcpOptions: &network.DhcpOptions{
   231  			DNSServers: &dnses,
   232  		},
   233  		Subnets: &subnets,
   234  	}
   235  }
   236  
   237  func resourceAzureSubnetHash(v interface{}) int {
   238  	m := v.(map[string]interface{})
   239  	subnet := m["name"].(string) + m["address_prefix"].(string)
   240  	if securityGroup, present := m["security_group"]; present {
   241  		subnet = subnet + securityGroup.(string)
   242  	}
   243  	return hashcode.String(subnet)
   244  }
   245  
   246  func virtualNetworkStateRefreshFunc(client *ArmClient, resourceGroupName string, networkName string) resource.StateRefreshFunc {
   247  	return func() (interface{}, string, error) {
   248  		res, err := client.vnetClient.Get(resourceGroupName, networkName, "")
   249  		if err != nil {
   250  			return nil, "", fmt.Errorf("Error issuing read request in virtualNetworkStateRefreshFunc to Azure ARM for virtual network '%s' (RG: '%s'): %s", networkName, resourceGroupName, err)
   251  		}
   252  
   253  		return res, *res.Properties.ProvisioningState, nil
   254  	}
   255  }