github.com/richardbowden/terraform@v0.6.12-0.20160901200758-30ea22c25211/builtin/providers/vcd/resource_vcd_network.go (about)

     1  package vcd
     2  
     3  import (
     4  	"log"
     5  
     6  	"bytes"
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/hashicorp/terraform/helper/hashcode"
    11  	"github.com/hashicorp/terraform/helper/resource"
    12  	"github.com/hashicorp/terraform/helper/schema"
    13  	types "github.com/hmrc/vmware-govcd/types/v56"
    14  )
    15  
    16  func resourceVcdNetwork() *schema.Resource {
    17  	return &schema.Resource{
    18  		Create: resourceVcdNetworkCreate,
    19  		Read:   resourceVcdNetworkRead,
    20  		Delete: resourceVcdNetworkDelete,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"name": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  				ForceNew: true,
    27  			},
    28  
    29  			"fence_mode": &schema.Schema{
    30  				Type:     schema.TypeString,
    31  				Optional: true,
    32  				ForceNew: true,
    33  				Default:  "natRouted",
    34  			},
    35  
    36  			"edge_gateway": &schema.Schema{
    37  				Type:     schema.TypeString,
    38  				Required: true,
    39  				ForceNew: true,
    40  			},
    41  
    42  			"netmask": &schema.Schema{
    43  				Type:     schema.TypeString,
    44  				Optional: true,
    45  				ForceNew: true,
    46  				Default:  "255.255.255.0",
    47  			},
    48  
    49  			"gateway": &schema.Schema{
    50  				Type:     schema.TypeString,
    51  				Required: true,
    52  				ForceNew: true,
    53  			},
    54  
    55  			"dns1": &schema.Schema{
    56  				Type:     schema.TypeString,
    57  				Optional: true,
    58  				ForceNew: true,
    59  				Default:  "8.8.8.8",
    60  			},
    61  
    62  			"dns2": &schema.Schema{
    63  				Type:     schema.TypeString,
    64  				Optional: true,
    65  				ForceNew: true,
    66  				Default:  "8.8.4.4",
    67  			},
    68  
    69  			"dns_suffix": &schema.Schema{
    70  				Type:     schema.TypeString,
    71  				Optional: true,
    72  				ForceNew: true,
    73  			},
    74  
    75  			"href": &schema.Schema{
    76  				Type:     schema.TypeString,
    77  				Optional: true,
    78  				Computed: true,
    79  				ForceNew: true,
    80  			},
    81  
    82  			"dhcp_pool": &schema.Schema{
    83  				Type:     schema.TypeSet,
    84  				Optional: true,
    85  				ForceNew: true,
    86  				Elem: &schema.Resource{
    87  					Schema: map[string]*schema.Schema{
    88  						"start_address": &schema.Schema{
    89  							Type:     schema.TypeString,
    90  							Required: true,
    91  						},
    92  
    93  						"end_address": &schema.Schema{
    94  							Type:     schema.TypeString,
    95  							Required: true,
    96  						},
    97  					},
    98  				},
    99  				Set: resourceVcdNetworkIPAddressHash,
   100  			},
   101  			"static_ip_pool": &schema.Schema{
   102  				Type:     schema.TypeSet,
   103  				Optional: true,
   104  				ForceNew: true,
   105  				Elem: &schema.Resource{
   106  					Schema: map[string]*schema.Schema{
   107  						"start_address": &schema.Schema{
   108  							Type:     schema.TypeString,
   109  							Required: true,
   110  						},
   111  
   112  						"end_address": &schema.Schema{
   113  							Type:     schema.TypeString,
   114  							Required: true,
   115  						},
   116  					},
   117  				},
   118  				Set: resourceVcdNetworkIPAddressHash,
   119  			},
   120  		},
   121  	}
   122  }
   123  
   124  func resourceVcdNetworkCreate(d *schema.ResourceData, meta interface{}) error {
   125  	vcdClient := meta.(*VCDClient)
   126  	log.Printf("[TRACE] CLIENT: %#v", vcdClient)
   127  	vcdClient.Mutex.Lock()
   128  	defer vcdClient.Mutex.Unlock()
   129  
   130  	edgeGateway, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
   131  
   132  	ipRanges := expandIPRange(d.Get("static_ip_pool").(*schema.Set).List())
   133  
   134  	newnetwork := &types.OrgVDCNetwork{
   135  		Xmlns: "http://www.vmware.com/vcloud/v1.5",
   136  		Name:  d.Get("name").(string),
   137  		Configuration: &types.NetworkConfiguration{
   138  			FenceMode: d.Get("fence_mode").(string),
   139  			IPScopes: &types.IPScopes{
   140  				IPScope: types.IPScope{
   141  					IsInherited: false,
   142  					Gateway:     d.Get("gateway").(string),
   143  					Netmask:     d.Get("netmask").(string),
   144  					DNS1:        d.Get("dns1").(string),
   145  					DNS2:        d.Get("dns2").(string),
   146  					DNSSuffix:   d.Get("dns_suffix").(string),
   147  					IPRanges:    &ipRanges,
   148  				},
   149  			},
   150  			BackwardCompatibilityMode: true,
   151  		},
   152  		EdgeGateway: &types.Reference{
   153  			HREF: edgeGateway.EdgeGateway.HREF,
   154  		},
   155  		IsShared: false,
   156  	}
   157  
   158  	log.Printf("[INFO] NETWORK: %#v", newnetwork)
   159  
   160  	err = retryCall(vcdClient.MaxRetryTimeout, func() *resource.RetryError {
   161  		return resource.RetryableError(vcdClient.OrgVdc.CreateOrgVDCNetwork(newnetwork))
   162  	})
   163  	if err != nil {
   164  		return fmt.Errorf("Error: %#v", err)
   165  	}
   166  
   167  	err = vcdClient.OrgVdc.Refresh()
   168  	if err != nil {
   169  		return fmt.Errorf("Error refreshing vdc: %#v", err)
   170  	}
   171  
   172  	network, err := vcdClient.OrgVdc.FindVDCNetwork(d.Get("name").(string))
   173  	if err != nil {
   174  		return fmt.Errorf("Error finding network: %#v", err)
   175  	}
   176  
   177  	if dhcp, ok := d.GetOk("dhcp_pool"); ok {
   178  		err = retryCall(vcdClient.MaxRetryTimeout, func() *resource.RetryError {
   179  			task, err := edgeGateway.AddDhcpPool(network.OrgVDCNetwork, dhcp.(*schema.Set).List())
   180  			if err != nil {
   181  				return resource.RetryableError(fmt.Errorf("Error adding DHCP pool: %#v", err))
   182  			}
   183  
   184  			return resource.RetryableError(task.WaitTaskCompletion())
   185  		})
   186  		if err != nil {
   187  			return fmt.Errorf("Error completing tasks: %#v", err)
   188  		}
   189  
   190  	}
   191  
   192  	d.SetId(d.Get("name").(string))
   193  
   194  	return resourceVcdNetworkRead(d, meta)
   195  }
   196  
   197  func resourceVcdNetworkRead(d *schema.ResourceData, meta interface{}) error {
   198  	vcdClient := meta.(*VCDClient)
   199  	log.Printf("[DEBUG] VCD Client configuration: %#v", vcdClient)
   200  	log.Printf("[DEBUG] VCD Client configuration: %#v", vcdClient.OrgVdc)
   201  
   202  	err := vcdClient.OrgVdc.Refresh()
   203  	if err != nil {
   204  		return fmt.Errorf("Error refreshing vdc: %#v", err)
   205  	}
   206  
   207  	network, err := vcdClient.OrgVdc.FindVDCNetwork(d.Id())
   208  	if err != nil {
   209  		log.Printf("[DEBUG] Network no longer exists. Removing from tfstate")
   210  		d.SetId("")
   211  		return nil
   212  	}
   213  
   214  	d.Set("name", network.OrgVDCNetwork.Name)
   215  	d.Set("href", network.OrgVDCNetwork.HREF)
   216  	if c := network.OrgVDCNetwork.Configuration; c != nil {
   217  		d.Set("fence_mode", c.FenceMode)
   218  		if c.IPScopes != nil {
   219  			d.Set("gateway", c.IPScopes.IPScope.Gateway)
   220  			d.Set("netmask", c.IPScopes.IPScope.Netmask)
   221  			d.Set("dns1", c.IPScopes.IPScope.DNS1)
   222  			d.Set("dns2", c.IPScopes.IPScope.DNS2)
   223  		}
   224  	}
   225  
   226  	return nil
   227  }
   228  
   229  func resourceVcdNetworkDelete(d *schema.ResourceData, meta interface{}) error {
   230  	vcdClient := meta.(*VCDClient)
   231  	vcdClient.Mutex.Lock()
   232  	defer vcdClient.Mutex.Unlock()
   233  	err := vcdClient.OrgVdc.Refresh()
   234  	if err != nil {
   235  		return fmt.Errorf("Error refreshing vdc: %#v", err)
   236  	}
   237  
   238  	network, err := vcdClient.OrgVdc.FindVDCNetwork(d.Id())
   239  	if err != nil {
   240  		return fmt.Errorf("Error finding network: %#v", err)
   241  	}
   242  
   243  	err = retryCall(vcdClient.MaxRetryTimeout, func() *resource.RetryError {
   244  		task, err := network.Delete()
   245  		if err != nil {
   246  			return resource.RetryableError(
   247  				fmt.Errorf("Error Deleting Network: %#v", err))
   248  		}
   249  		return resource.RetryableError(task.WaitTaskCompletion())
   250  	})
   251  	if err != nil {
   252  		return err
   253  	}
   254  
   255  	return nil
   256  }
   257  
   258  func resourceVcdNetworkIPAddressHash(v interface{}) int {
   259  	var buf bytes.Buffer
   260  	m := v.(map[string]interface{})
   261  	buf.WriteString(fmt.Sprintf("%s-",
   262  		strings.ToLower(m["start_address"].(string))))
   263  	buf.WriteString(fmt.Sprintf("%s-",
   264  		strings.ToLower(m["end_address"].(string))))
   265  
   266  	return hashcode.String(buf.String())
   267  }