github.com/icebourg/terraform@v0.6.5-0.20151015205227-263cc1b85535/builtin/providers/cloudstack/resource_cloudstack_vpc.go (about)

     1  package cloudstack
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strings"
     7  
     8  	"github.com/hashicorp/terraform/helper/schema"
     9  	"github.com/xanzy/go-cloudstack/cloudstack"
    10  )
    11  
    12  func resourceCloudStackVPC() *schema.Resource {
    13  	return &schema.Resource{
    14  		Create: resourceCloudStackVPCCreate,
    15  		Read:   resourceCloudStackVPCRead,
    16  		Update: resourceCloudStackVPCUpdate,
    17  		Delete: resourceCloudStackVPCDelete,
    18  
    19  		Schema: map[string]*schema.Schema{
    20  			"name": &schema.Schema{
    21  				Type:     schema.TypeString,
    22  				Required: true,
    23  			},
    24  
    25  			"display_text": &schema.Schema{
    26  				Type:     schema.TypeString,
    27  				Optional: true,
    28  				Computed: true,
    29  			},
    30  
    31  			"cidr": &schema.Schema{
    32  				Type:     schema.TypeString,
    33  				Required: true,
    34  				ForceNew: true,
    35  			},
    36  
    37  			"vpc_offering": &schema.Schema{
    38  				Type:     schema.TypeString,
    39  				Required: true,
    40  				ForceNew: true,
    41  			},
    42  
    43  			"network_domain": &schema.Schema{
    44  				Type:     schema.TypeString,
    45  				Optional: true,
    46  				ForceNew: true,
    47  			},
    48  
    49  			"project": &schema.Schema{
    50  				Type:     schema.TypeString,
    51  				Optional: true,
    52  				ForceNew: true,
    53  			},
    54  
    55  			"source_nat_ip": &schema.Schema{
    56  				Type:     schema.TypeString,
    57  				Computed: true,
    58  			},
    59  
    60  			"zone": &schema.Schema{
    61  				Type:     schema.TypeString,
    62  				Required: true,
    63  				ForceNew: true,
    64  			},
    65  		},
    66  	}
    67  }
    68  
    69  func resourceCloudStackVPCCreate(d *schema.ResourceData, meta interface{}) error {
    70  	cs := meta.(*cloudstack.CloudStackClient)
    71  
    72  	name := d.Get("name").(string)
    73  
    74  	// Retrieve the vpc_offering ID
    75  	vpcofferingid, e := retrieveID(cs, "vpc_offering", d.Get("vpc_offering").(string))
    76  	if e != nil {
    77  		return e.Error()
    78  	}
    79  
    80  	// Retrieve the zone ID
    81  	zoneid, e := retrieveID(cs, "zone", d.Get("zone").(string))
    82  	if e != nil {
    83  		return e.Error()
    84  	}
    85  
    86  	// Set the display text
    87  	displaytext, ok := d.GetOk("display_text")
    88  	if !ok {
    89  		displaytext = name
    90  	}
    91  
    92  	// Create a new parameter struct
    93  	p := cs.VPC.NewCreateVPCParams(
    94  		d.Get("cidr").(string),
    95  		displaytext.(string),
    96  		name,
    97  		vpcofferingid,
    98  		zoneid,
    99  	)
   100  
   101  	// If there is a network domain supplied, make sure to add it to the request
   102  	if networkDomain, ok := d.GetOk("network_domain"); ok {
   103  		// Set the network domain
   104  		p.SetNetworkdomain(networkDomain.(string))
   105  	}
   106  
   107  	// If there is a project supplied, we retrieve and set the project id
   108  	if project, ok := d.GetOk("project"); ok {
   109  		// Retrieve the project ID
   110  		projectid, e := retrieveID(cs, "project", project.(string))
   111  		if e != nil {
   112  			return e.Error()
   113  		}
   114  		// Set the default project ID
   115  		p.SetProjectid(projectid)
   116  	}
   117  
   118  	// Create the new VPC
   119  	r, err := cs.VPC.CreateVPC(p)
   120  	if err != nil {
   121  		return fmt.Errorf("Error creating VPC %s: %s", name, err)
   122  	}
   123  
   124  	d.SetId(r.Id)
   125  
   126  	return resourceCloudStackVPCRead(d, meta)
   127  }
   128  
   129  func resourceCloudStackVPCRead(d *schema.ResourceData, meta interface{}) error {
   130  	cs := meta.(*cloudstack.CloudStackClient)
   131  
   132  	// Get the VPC details
   133  	v, count, err := cs.VPC.GetVPCByID(d.Id())
   134  	if err != nil {
   135  		if count == 0 {
   136  			log.Printf(
   137  				"[DEBUG] VPC %s does no longer exist", d.Get("name").(string))
   138  			d.SetId("")
   139  			return nil
   140  		}
   141  
   142  		return err
   143  	}
   144  
   145  	d.Set("name", v.Name)
   146  	d.Set("display_text", v.Displaytext)
   147  	d.Set("cidr", v.Cidr)
   148  	d.Set("network_domain", v.Networkdomain)
   149  
   150  	// Get the VPC offering details
   151  	o, _, err := cs.VPC.GetVPCOfferingByID(v.Vpcofferingid)
   152  	if err != nil {
   153  		return err
   154  	}
   155  
   156  	setValueOrID(d, "vpc_offering", o.Name, v.Vpcofferingid)
   157  	setValueOrID(d, "project", v.Project, v.Projectid)
   158  	setValueOrID(d, "zone", v.Zonename, v.Zoneid)
   159  
   160  	// Create a new parameter struct
   161  	p := cs.Address.NewListPublicIpAddressesParams()
   162  	p.SetVpcid(d.Id())
   163  	p.SetIssourcenat(true)
   164  
   165  	if _, ok := d.GetOk("project"); ok {
   166  		p.SetProjectid(v.Projectid)
   167  	}
   168  
   169  	// Get the source NAT IP assigned to the VPC
   170  	l, err := cs.Address.ListPublicIpAddresses(p)
   171  	if err != nil {
   172  		return err
   173  	}
   174  
   175  	if l.Count != 1 {
   176  		return fmt.Errorf("Unexpected number (%d) of source NAT IPs returned", l.Count)
   177  	}
   178  
   179  	d.Set("source_nat_ip", l.PublicIpAddresses[0].Ipaddress)
   180  
   181  	return nil
   182  }
   183  
   184  func resourceCloudStackVPCUpdate(d *schema.ResourceData, meta interface{}) error {
   185  	cs := meta.(*cloudstack.CloudStackClient)
   186  
   187  	// Check if the name or display text is changed
   188  	if d.HasChange("name") || d.HasChange("display_text") {
   189  		// Create a new parameter struct
   190  		p := cs.VPC.NewUpdateVPCParams(d.Id())
   191  
   192  		// Set the display text
   193  		displaytext, ok := d.GetOk("display_text")
   194  		if !ok {
   195  			displaytext = d.Get("name")
   196  		}
   197  		// Set the (new) display text
   198  		p.SetDisplaytext(displaytext.(string))
   199  
   200  		// Update the VPC
   201  		_, err := cs.VPC.UpdateVPC(p)
   202  		if err != nil {
   203  			return fmt.Errorf(
   204  				"Error updating VPC %s: %s", d.Get("name").(string), err)
   205  		}
   206  	}
   207  
   208  	return resourceCloudStackVPCRead(d, meta)
   209  }
   210  
   211  func resourceCloudStackVPCDelete(d *schema.ResourceData, meta interface{}) error {
   212  	cs := meta.(*cloudstack.CloudStackClient)
   213  
   214  	// Create a new parameter struct
   215  	p := cs.VPC.NewDeleteVPCParams(d.Id())
   216  
   217  	// Delete the VPC
   218  	_, err := cs.VPC.DeleteVPC(p)
   219  	if err != nil {
   220  		// This is a very poor way to be told the ID does no longer exist :(
   221  		if strings.Contains(err.Error(), fmt.Sprintf(
   222  			"Invalid parameter id value=%s due to incorrect long value format, "+
   223  				"or entity does not exist", d.Id())) {
   224  			return nil
   225  		}
   226  
   227  		return fmt.Errorf("Error deleting VPC %s: %s", d.Get("name").(string), err)
   228  	}
   229  
   230  	return nil
   231  }