github.com/hobbeswalsh/terraform@v0.3.7-0.20150619183303-ad17cf55a0fa/builtin/providers/azure/resource_azure_local_network.go (about)

     1  package azure
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  
     7  	"github.com/Azure/azure-sdk-for-go/management/virtualnetwork"
     8  	"github.com/hashicorp/terraform/helper/schema"
     9  )
    10  
    11  // resourceAzureLocalNetworkConnetion returns the schema.Resource associated to an
    12  // Azure hosted service.
    13  func resourceAzureLocalNetworkConnection() *schema.Resource {
    14  	return &schema.Resource{
    15  		Create: resourceAzureLocalNetworkConnectionCreate,
    16  		Read:   resourceAzureLocalNetworkConnectionRead,
    17  		Update: resourceAzureLocalNetworkConnectionUpdate,
    18  		Exists: resourceAzureLocalNetworkConnectionExists,
    19  		Delete: resourceAzureLocalNetworkConnectionDelete,
    20  
    21  		Schema: map[string]*schema.Schema{
    22  			"name": &schema.Schema{
    23  				Type:        schema.TypeString,
    24  				Required:    true,
    25  				ForceNew:    true,
    26  				Description: parameterDescriptions["name"],
    27  			},
    28  			"vpn_gateway_address": &schema.Schema{
    29  				Type:        schema.TypeString,
    30  				Required:    true,
    31  				Description: parameterDescriptions["vpn_gateway_address"],
    32  			},
    33  			"address_space_prefixes": &schema.Schema{
    34  				Type:     schema.TypeList,
    35  				Required: true,
    36  				Elem: &schema.Schema{
    37  					Type: schema.TypeString,
    38  				},
    39  				Description: parameterDescriptions["address_space_prefixes"],
    40  			},
    41  		},
    42  	}
    43  }
    44  
    45  // sourceAzureLocalNetworkConnectionCreate issues all the necessary API calls
    46  // to create a virtual network on Azure.
    47  func resourceAzureLocalNetworkConnectionCreate(d *schema.ResourceData, meta interface{}) error {
    48  	azureClient := meta.(*Client)
    49  	mgmtClient := azureClient.mgmtClient
    50  	vnetClient := azureClient.vnetClient
    51  
    52  	log.Println("[INFO] Fetching current network configuration from Azure.")
    53  	azureClient.mutex.Lock()
    54  	defer azureClient.mutex.Unlock()
    55  	netConf, err := vnetClient.GetVirtualNetworkConfiguration()
    56  	if err != nil {
    57  		return fmt.Errorf("Failed to get the current network configuration from Azure: %s", err)
    58  	}
    59  
    60  	// get provided configuration:
    61  	name := d.Get("name").(string)
    62  	vpnGateway := d.Get("vpn_gateway_address").(string)
    63  	var prefixes []string
    64  	for _, prefix := range d.Get("address_space_prefixes").([]interface{}) {
    65  		prefixes = append(prefixes, prefix.(string))
    66  	}
    67  
    68  	// add configuration to network config:
    69  	netConf.Configuration.LocalNetworkSites = append(netConf.Configuration.LocalNetworkSites,
    70  		virtualnetwork.LocalNetworkSite{
    71  			Name:              name,
    72  			VPNGatewayAddress: vpnGateway,
    73  			AddressSpace: virtualnetwork.AddressSpace{
    74  				AddressPrefix: prefixes,
    75  			},
    76  		})
    77  
    78  	// send the configuration back to Azure:
    79  	log.Println("[INFO] Sending updated network configuration back to Azure.")
    80  	reqID, err := vnetClient.SetVirtualNetworkConfiguration(netConf)
    81  	if err != nil {
    82  		return fmt.Errorf("Failed setting updated network configuration: %s", err)
    83  	}
    84  	err = mgmtClient.WaitForOperation(reqID, nil)
    85  	if err != nil {
    86  		return fmt.Errorf("Failed updating the network configuration: %s", err)
    87  	}
    88  
    89  	d.SetId(name)
    90  	return nil
    91  }
    92  
    93  // resourceAzureLocalNetworkConnectionRead does all the necessary API calls to
    94  // read the state of our local natwork from Azure.
    95  func resourceAzureLocalNetworkConnectionRead(d *schema.ResourceData, meta interface{}) error {
    96  	azureClient := meta.(*Client)
    97  	vnetClient := azureClient.vnetClient
    98  
    99  	log.Println("[INFO] Fetching current network configuration from Azure.")
   100  	netConf, err := vnetClient.GetVirtualNetworkConfiguration()
   101  	if err != nil {
   102  		return fmt.Errorf("Failed to get the current network configuration from Azure: %s", err)
   103  	}
   104  
   105  	var found bool
   106  	name := d.Get("name").(string)
   107  
   108  	// browsing for our network config:
   109  	for _, lnet := range netConf.Configuration.LocalNetworkSites {
   110  		if lnet.Name == name {
   111  			found = true
   112  			d.Set("vpn_gateway_address", lnet.VPNGatewayAddress)
   113  			d.Set("address_space_prefixes", lnet.AddressSpace.AddressPrefix)
   114  			break
   115  		}
   116  	}
   117  
   118  	// remove the resource from the state of it has been deleted in the meantime:
   119  	if !found {
   120  		log.Println(fmt.Printf("[INFO] Azure local network '%s' has been deleted remotely. Removimg from Terraform.", name))
   121  		d.SetId("")
   122  	}
   123  
   124  	return nil
   125  }
   126  
   127  // resourceAzureLocalNetworkConnectionUpdate does all the necessary API calls
   128  // update the settings of our Local Network on Azure.
   129  func resourceAzureLocalNetworkConnectionUpdate(d *schema.ResourceData, meta interface{}) error {
   130  	azureClient := meta.(*Client)
   131  	mgmtClient := azureClient.mgmtClient
   132  	vnetClient := azureClient.vnetClient
   133  
   134  	log.Println("[INFO] Fetching current network configuration from Azure.")
   135  	azureClient.mutex.Lock()
   136  	defer azureClient.mutex.Unlock()
   137  	netConf, err := vnetClient.GetVirtualNetworkConfiguration()
   138  	if err != nil {
   139  		return fmt.Errorf("Failed to get the current network configuration from Azure: %s", err)
   140  	}
   141  
   142  	name := d.Get("name").(string)
   143  	cvpn := d.HasChange("vpn_gateway_address")
   144  	cprefixes := d.HasChange("address_space_prefixes")
   145  
   146  	var found bool
   147  	for i, lnet := range netConf.Configuration.LocalNetworkSites {
   148  		if lnet.Name == name {
   149  			found = true
   150  			if cvpn {
   151  				netConf.Configuration.LocalNetworkSites[i].VPNGatewayAddress = d.Get("vpn_gateway_address").(string)
   152  			}
   153  			if cprefixes {
   154  				var prefixes []string
   155  				for _, prefix := range d.Get("address_space_prefixes").([]interface{}) {
   156  					prefixes = append(prefixes, prefix.(string))
   157  				}
   158  				netConf.Configuration.LocalNetworkSites[i].AddressSpace.AddressPrefix = prefixes
   159  			}
   160  			break
   161  		}
   162  	}
   163  
   164  	// remove the resource from the state of it has been deleted in the meantime:
   165  	if !found {
   166  		log.Println(fmt.Printf("[INFO] Azure local network '%s' has been deleted remotely. Removimg from Terraform.", name))
   167  		d.SetId("")
   168  	} else if cvpn || cprefixes {
   169  		// else, send the configuration back to Azure:
   170  		log.Println("[INFO] Sending updated network configuration back to Azure.")
   171  		reqID, err := vnetClient.SetVirtualNetworkConfiguration(netConf)
   172  		if err != nil {
   173  			return fmt.Errorf("Failed setting updated network configuration: %s", err)
   174  		}
   175  		err = mgmtClient.WaitForOperation(reqID, nil)
   176  		if err != nil {
   177  			return fmt.Errorf("Failed updating the network configuration: %s", err)
   178  		}
   179  	}
   180  
   181  	return nil
   182  }
   183  
   184  // resourceAzureLocalNetworkConnectionExists does all the necessary API calls
   185  // to check if the local network already exists on Azure.
   186  func resourceAzureLocalNetworkConnectionExists(d *schema.ResourceData, meta interface{}) (bool, error) {
   187  	vnetClient := meta.(*Client).vnetClient
   188  
   189  	log.Println("[INFO] Fetching current network configuration from Azure.")
   190  	netConf, err := vnetClient.GetVirtualNetworkConfiguration()
   191  	if err != nil {
   192  		return false, fmt.Errorf("Failed to get the current network configuration from Azure: %s", err)
   193  	}
   194  
   195  	name := d.Get("name")
   196  
   197  	for _, lnet := range netConf.Configuration.LocalNetworkSites {
   198  		if lnet.Name == name {
   199  			return true, nil
   200  		}
   201  	}
   202  
   203  	return false, nil
   204  }
   205  
   206  // resourceAzureLocalNetworkConnectionDelete does all the necessary API calls
   207  // to delete a local network off Azure.
   208  func resourceAzureLocalNetworkConnectionDelete(d *schema.ResourceData, meta interface{}) error {
   209  	azureClient := meta.(*Client)
   210  	mgmtClient := azureClient.mgmtClient
   211  	vnetClient := azureClient.vnetClient
   212  
   213  	log.Println("[INFO] Fetching current network configuration from Azure.")
   214  	azureClient.mutex.Lock()
   215  	defer azureClient.mutex.Unlock()
   216  	netConf, err := vnetClient.GetVirtualNetworkConfiguration()
   217  	if err != nil {
   218  		return fmt.Errorf("Failed to get the current network configuration from Azure: %s", err)
   219  	}
   220  
   221  	name := d.Get("name").(string)
   222  
   223  	// search for our local network and remove it if found:
   224  	for i, lnet := range netConf.Configuration.LocalNetworkSites {
   225  		if lnet.Name == name {
   226  			netConf.Configuration.LocalNetworkSites = append(
   227  				netConf.Configuration.LocalNetworkSites[:i],
   228  				netConf.Configuration.LocalNetworkSites[i+1:]...,
   229  			)
   230  			break
   231  		}
   232  	}
   233  
   234  	// send the configuration back to Azure:
   235  	log.Println("[INFO] Sending updated network configuration back to Azure.")
   236  	reqID, err := vnetClient.SetVirtualNetworkConfiguration(netConf)
   237  	if err != nil {
   238  		return fmt.Errorf("Failed setting updated network configuration: %s", err)
   239  	}
   240  	err = mgmtClient.WaitForOperation(reqID, nil)
   241  	if err != nil {
   242  		return fmt.Errorf("Failed updating the network configuration: %s", err)
   243  	}
   244  
   245  	d.SetId("")
   246  	return nil
   247  }