2015-10-26 15:45:48 +01:00
|
|
|
package vcd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/terraform/helper/hashcode"
|
|
|
|
"github.com/hashicorp/terraform/helper/schema"
|
2015-11-06 11:19:59 +01:00
|
|
|
"github.com/hmrc/vmware-govcd"
|
|
|
|
types "github.com/hmrc/vmware-govcd/types/v56"
|
2015-10-26 15:45:48 +01:00
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
func resourceVcdNetwork() *schema.Resource {
|
|
|
|
return &schema.Resource{
|
|
|
|
Create: resourceVcdNetworkCreate,
|
|
|
|
Read: resourceVcdNetworkRead,
|
|
|
|
Delete: resourceVcdNetworkDelete,
|
|
|
|
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"name": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
ForceNew: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"fence_mode": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
2015-11-10 19:39:58 +01:00
|
|
|
ForceNew: true,
|
2015-10-26 15:45:48 +01:00
|
|
|
Default: "natRouted",
|
|
|
|
},
|
|
|
|
|
|
|
|
"edge_gateway": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
2015-11-10 19:39:58 +01:00
|
|
|
ForceNew: true,
|
2015-10-26 15:45:48 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
"netmask": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
2015-11-10 19:39:58 +01:00
|
|
|
ForceNew: true,
|
2015-10-26 15:45:48 +01:00
|
|
|
Default: "255.255.255.0",
|
|
|
|
},
|
|
|
|
|
|
|
|
"gateway": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
2015-11-10 19:39:58 +01:00
|
|
|
ForceNew: true,
|
2015-10-26 15:45:48 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
"dns1": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
2015-11-10 19:39:58 +01:00
|
|
|
ForceNew: true,
|
2015-10-26 15:45:48 +01:00
|
|
|
Default: "8.8.8.8",
|
|
|
|
},
|
|
|
|
|
|
|
|
"dns2": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
2015-11-10 19:39:58 +01:00
|
|
|
ForceNew: true,
|
2015-10-26 15:45:48 +01:00
|
|
|
Default: "8.8.4.4",
|
|
|
|
},
|
|
|
|
|
|
|
|
"dns_suffix": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
2015-11-10 19:39:58 +01:00
|
|
|
ForceNew: true,
|
2015-10-26 15:45:48 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
"href": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
Computed: true,
|
2015-11-10 19:39:58 +01:00
|
|
|
ForceNew: true,
|
2015-10-26 15:45:48 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
"dhcp_pool": &schema.Schema{
|
|
|
|
Type: schema.TypeSet,
|
|
|
|
Optional: true,
|
2015-11-10 19:39:58 +01:00
|
|
|
ForceNew: true,
|
2015-10-26 15:45:48 +01:00
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"start_address": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"end_address": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2015-11-16 21:11:05 +01:00
|
|
|
Set: resourceVcdNetworkIPAddressHash,
|
2015-10-26 15:45:48 +01:00
|
|
|
},
|
|
|
|
"static_ip_pool": &schema.Schema{
|
|
|
|
Type: schema.TypeSet,
|
|
|
|
Optional: true,
|
2015-11-10 19:39:58 +01:00
|
|
|
ForceNew: true,
|
2015-10-26 15:45:48 +01:00
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"start_address": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"end_address": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2015-11-16 21:11:05 +01:00
|
|
|
Set: resourceVcdNetworkIPAddressHash,
|
2015-10-26 15:45:48 +01:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceVcdNetworkCreate(d *schema.ResourceData, meta interface{}) error {
|
2015-11-16 21:11:05 +01:00
|
|
|
vcdClient := meta.(*govcd.VCDClient)
|
|
|
|
log.Printf("[TRACE] CLIENT: %#v", vcdClient)
|
|
|
|
vcdClient.Mutex.Lock()
|
|
|
|
defer vcdClient.Mutex.Unlock()
|
2015-10-26 15:45:48 +01:00
|
|
|
|
2015-11-16 21:11:05 +01:00
|
|
|
edgeGateway, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
|
2015-10-26 15:45:48 +01:00
|
|
|
|
2015-11-16 21:11:05 +01:00
|
|
|
ipRanges := expandIPRange(d.Get("static_ip_pool").(*schema.Set).List())
|
2015-10-26 15:45:48 +01:00
|
|
|
|
|
|
|
newnetwork := &types.OrgVDCNetwork{
|
|
|
|
Xmlns: "http://www.vmware.com/vcloud/v1.5",
|
|
|
|
Name: d.Get("name").(string),
|
|
|
|
Configuration: &types.NetworkConfiguration{
|
|
|
|
FenceMode: d.Get("fence_mode").(string),
|
|
|
|
IPScopes: &types.IPScopes{
|
|
|
|
IPScope: types.IPScope{
|
|
|
|
IsInherited: false,
|
|
|
|
Gateway: d.Get("gateway").(string),
|
|
|
|
Netmask: d.Get("netmask").(string),
|
|
|
|
DNS1: d.Get("dns1").(string),
|
|
|
|
DNS2: d.Get("dns2").(string),
|
|
|
|
DNSSuffix: d.Get("dns_suffix").(string),
|
|
|
|
IPRanges: &ipRanges,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
BackwardCompatibilityMode: true,
|
|
|
|
},
|
|
|
|
EdgeGateway: &types.Reference{
|
|
|
|
HREF: edgeGateway.EdgeGateway.HREF,
|
|
|
|
},
|
|
|
|
IsShared: false,
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("[INFO] NETWORK: %#v", newnetwork)
|
|
|
|
|
2015-11-02 17:39:56 +01:00
|
|
|
err = retryCall(4, func() error {
|
2015-11-16 21:11:05 +01:00
|
|
|
return vcdClient.OrgVdc.CreateOrgVDCNetwork(newnetwork)
|
2015-11-02 17:39:56 +01:00
|
|
|
})
|
2015-10-26 15:45:48 +01:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error: %#v", err)
|
|
|
|
}
|
|
|
|
|
2015-11-16 21:11:05 +01:00
|
|
|
err = vcdClient.OrgVdc.Refresh()
|
2015-11-02 17:39:56 +01:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error refreshing vdc: %#v", err)
|
|
|
|
}
|
2015-10-26 15:45:48 +01:00
|
|
|
|
2015-11-16 21:11:05 +01:00
|
|
|
network, err := vcdClient.OrgVdc.FindVDCNetwork(d.Get("name").(string))
|
2015-11-02 17:39:56 +01:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error finding network: %#v", err)
|
|
|
|
}
|
2015-10-26 15:45:48 +01:00
|
|
|
|
2015-11-02 17:39:56 +01:00
|
|
|
if dhcp, ok := d.GetOk("dhcp_pool"); ok {
|
|
|
|
err = retryCall(4, func() error {
|
|
|
|
task, err := edgeGateway.AddDhcpPool(network.OrgVDCNetwork, dhcp.(*schema.Set).List())
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error adding DHCP pool: %#v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return task.WaitTaskCompletion()
|
|
|
|
})
|
2015-10-26 15:45:48 +01:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error completing tasks: %#v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
d.SetId(d.Get("name").(string))
|
|
|
|
|
|
|
|
return resourceVcdNetworkRead(d, meta)
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceVcdNetworkRead(d *schema.ResourceData, meta interface{}) error {
|
2015-11-16 21:11:05 +01:00
|
|
|
vcdClient := meta.(*govcd.VCDClient)
|
|
|
|
log.Printf("[DEBUG] VCD Client configuration: %#v", vcdClient)
|
|
|
|
log.Printf("[DEBUG] VCD Client configuration: %#v", vcdClient.OrgVdc)
|
2015-10-26 15:45:48 +01:00
|
|
|
|
2015-11-16 21:11:05 +01:00
|
|
|
err := vcdClient.OrgVdc.Refresh()
|
2015-10-26 15:45:48 +01:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error refreshing vdc: %#v", err)
|
|
|
|
}
|
|
|
|
|
2015-11-16 21:11:05 +01:00
|
|
|
network, err := vcdClient.OrgVdc.FindVDCNetwork(d.Id())
|
2015-10-26 15:45:48 +01:00
|
|
|
if err != nil {
|
2015-11-06 17:39:40 +01:00
|
|
|
log.Printf("[DEBUG] Network no longer exists. Removing from tfstate")
|
|
|
|
d.SetId("")
|
|
|
|
return nil
|
2015-10-26 15:45:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
d.Set("name", network.OrgVDCNetwork.Name)
|
|
|
|
d.Set("href", network.OrgVDCNetwork.HREF)
|
|
|
|
d.Set("fence_mode", network.OrgVDCNetwork.Configuration.FenceMode)
|
|
|
|
d.Set("gateway", network.OrgVDCNetwork.Configuration.IPScopes.IPScope.Gateway)
|
|
|
|
d.Set("netmask", network.OrgVDCNetwork.Configuration.IPScopes.IPScope.Netmask)
|
|
|
|
d.Set("dns1", network.OrgVDCNetwork.Configuration.IPScopes.IPScope.DNS1)
|
|
|
|
d.Set("dns2", network.OrgVDCNetwork.Configuration.IPScopes.IPScope.DNS2)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceVcdNetworkDelete(d *schema.ResourceData, meta interface{}) error {
|
2015-11-16 21:11:05 +01:00
|
|
|
vcdClient := meta.(*govcd.VCDClient)
|
|
|
|
vcdClient.Mutex.Lock()
|
|
|
|
defer vcdClient.Mutex.Unlock()
|
|
|
|
err := vcdClient.OrgVdc.Refresh()
|
2015-10-26 15:45:48 +01:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error refreshing vdc: %#v", err)
|
|
|
|
}
|
|
|
|
|
2015-11-16 21:11:05 +01:00
|
|
|
network, err := vcdClient.OrgVdc.FindVDCNetwork(d.Id())
|
2015-10-26 15:45:48 +01:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error finding network: %#v", err)
|
|
|
|
}
|
|
|
|
|
2015-11-02 17:39:56 +01:00
|
|
|
err = retryCall(4, func() error {
|
2015-10-26 15:45:48 +01:00
|
|
|
task, err := network.Delete()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error Deleting Network: %#v", err)
|
|
|
|
}
|
2015-11-02 17:39:56 +01:00
|
|
|
return task.WaitTaskCompletion()
|
2015-10-26 15:45:48 +01:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-11-16 21:11:05 +01:00
|
|
|
func resourceVcdNetworkIPAddressHash(v interface{}) int {
|
2015-10-26 15:45:48 +01:00
|
|
|
var buf bytes.Buffer
|
|
|
|
m := v.(map[string]interface{})
|
|
|
|
buf.WriteString(fmt.Sprintf("%s-",
|
|
|
|
strings.ToLower(m["start_address"].(string))))
|
|
|
|
buf.WriteString(fmt.Sprintf("%s-",
|
|
|
|
strings.ToLower(m["end_address"].(string))))
|
|
|
|
|
|
|
|
return hashcode.String(buf.String())
|
|
|
|
}
|