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