terraform/builtin/providers/azure/resource_azure_virtual_netw...

224 lines
5.6 KiB
Go

package azure
import (
"fmt"
"log"
"strings"
"github.com/hashicorp/terraform/helper/schema"
"github.com/mitchellh/mapstructure"
"github.com/svanharmelen/azure-sdk-for-go/management"
"github.com/svanharmelen/azure-sdk-for-go/management/virtualnetwork"
)
const (
virtualNetworkRetrievalError = "Error retrieving Virtual Network Configuration: %s"
)
func resourceAzureVirtualNetwork() *schema.Resource {
return &schema.Resource{
Create: resourceAzureVirtualNetworkCreate,
Read: resourceAzureVirtualNetworkRead,
Update: resourceAzureVirtualNetworkUpdate,
Delete: resourceAzureVirtualNetworkDelete,
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"address_space": &schema.Schema{
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"subnet": &schema.Schema{
Type: schema.TypeMap,
Required: true,
},
"location": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
}
}
func resourceAzureVirtualNetworkCreate(d *schema.ResourceData, meta interface{}) error {
mc := meta.(*management.Client)
name := d.Get("name").(string)
nc, err := virtualnetwork.NewClient(*mc).GetVirtualNetworkConfiguration()
if err != nil {
if strings.Contains(err.Error(), "ResourceNotFound") {
nc = virtualnetwork.NetworkConfiguration{}
} else {
return fmt.Errorf(virtualNetworkRetrievalError, err)
}
}
for _, n := range nc.Configuration.VirtualNetworkSites {
if n.Name == name {
return fmt.Errorf("Virtual Network %s already exists!", name)
}
}
network, err := createVirtualNetwork(d)
if err != nil {
return err
}
nc.Configuration.VirtualNetworkSites = append(nc.Configuration.VirtualNetworkSites, network)
req, err := virtualnetwork.NewClient(*mc).SetVirtualNetworkConfiguration(nc)
if err != nil {
return fmt.Errorf("Error creating Virtual Network %s: %s", name, err)
}
// Wait until the virtual network is created
if err := mc.WaitForOperation(req, nil); err != nil {
log.Printf(
"[DEBUG] Error waiting for Virtual Network %s to be created: %s", name, err)
}
d.SetId(name)
return resourceAzureVirtualNetworkRead(d, meta)
}
func resourceAzureVirtualNetworkRead(d *schema.ResourceData, meta interface{}) error {
mc := meta.(*management.Client)
nc, err := virtualnetwork.NewClient(*mc).GetVirtualNetworkConfiguration()
if err != nil {
return fmt.Errorf(virtualNetworkRetrievalError, err)
}
for _, n := range nc.Configuration.VirtualNetworkSites {
if n.Name == d.Id() {
d.Set("address_space", n.AddressSpace.AddressPrefix)
d.Set("location", n.Location)
subnets := map[string]interface{}{}
for _, s := range n.Subnets {
subnets[s.Name] = s.AddressPrefix
}
d.Set("subnet", subnets)
return nil
}
}
log.Printf("[DEBUG] Virtual Network %s does no longer exist", d.Id())
d.SetId("")
return nil
}
func resourceAzureVirtualNetworkUpdate(d *schema.ResourceData, meta interface{}) error {
mc := meta.(*management.Client)
nc, err := virtualnetwork.NewClient(*mc).GetVirtualNetworkConfiguration()
if err != nil {
return fmt.Errorf(virtualNetworkRetrievalError, err)
}
found := false
for i, n := range nc.Configuration.VirtualNetworkSites {
if n.Name == d.Id() {
network, err := createVirtualNetwork(d)
if err != nil {
return err
}
nc.Configuration.VirtualNetworkSites[i] = network
found = true
}
}
if !found {
return fmt.Errorf("Virtual Network %s does not exists!", d.Id())
}
req, err := virtualnetwork.NewClient(*mc).SetVirtualNetworkConfiguration(nc)
if err != nil {
return fmt.Errorf("Error updating Virtual Network %s: %s", d.Id(), err)
}
// Wait until the virtual network is updated
if err := mc.WaitForOperation(req, nil); err != nil {
log.Printf(
"[DEBUG] Error waiting for Virtual Network %s to be updated: %s", d.Id(), err)
}
return resourceAzureVirtualNetworkRead(d, meta)
}
func resourceAzureVirtualNetworkDelete(d *schema.ResourceData, meta interface{}) error {
mc := meta.(*management.Client)
nc, err := virtualnetwork.NewClient(*mc).GetVirtualNetworkConfiguration()
if err != nil {
return fmt.Errorf(virtualNetworkRetrievalError, err)
}
filtered := nc.Configuration.VirtualNetworkSites[:0]
for _, n := range nc.Configuration.VirtualNetworkSites {
if n.Name != d.Id() {
filtered = append(filtered, n)
}
}
nc.Configuration.VirtualNetworkSites = filtered
req, err := virtualnetwork.NewClient(*mc).SetVirtualNetworkConfiguration(nc)
if err != nil {
return fmt.Errorf("Error deleting Virtual Network %s: %s", d.Id(), err)
}
// Wait until the virtual network is deleted
if err := mc.WaitForOperation(req, nil); err != nil {
log.Printf(
"[DEBUG] Error waiting for Virtual Network %s to be deleted: %s", d.Id(), err)
}
d.SetId("")
return nil
}
func createVirtualNetwork(d *schema.ResourceData) (virtualnetwork.VirtualNetworkSite, error) {
var addressPrefix []string
err := mapstructure.WeakDecode(d.Get("address_space"), &addressPrefix)
if err != nil {
return virtualnetwork.VirtualNetworkSite{}, fmt.Errorf("Error decoding address_space: %s", err)
}
addressSpace := virtualnetwork.AddressSpace{
AddressPrefix: addressPrefix,
}
subnets := []virtualnetwork.Subnet{}
for n, p := range d.Get("subnet").(map[string]interface{}) {
subnets = append(subnets, virtualnetwork.Subnet{
Name: n,
AddressPrefix: p.(string),
})
}
return virtualnetwork.VirtualNetworkSite{
Name: d.Get("name").(string),
Location: d.Get("location").(string),
AddressSpace: addressSpace,
Subnets: subnets,
}, nil
}