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 }