224 lines
5.6 KiB
Go
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
|
|
}
|