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