github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/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 }