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