github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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  				Computed: true,
    47  				ForceNew: true,
    48  			},
    49  
    50  			"project": &schema.Schema{
    51  				Type:     schema.TypeString,
    52  				Optional: true,
    53  				Computed: true,
    54  				ForceNew: true,
    55  			},
    56  
    57  			"source_nat_ip": &schema.Schema{
    58  				Type:     schema.TypeString,
    59  				Computed: true,
    60  			},
    61  
    62  			"zone": &schema.Schema{
    63  				Type:     schema.TypeString,
    64  				Required: true,
    65  				ForceNew: true,
    66  			},
    67  		},
    68  	}
    69  }
    70  
    71  func resourceCloudStackVPCCreate(d *schema.ResourceData, meta interface{}) error {
    72  	cs := meta.(*cloudstack.CloudStackClient)
    73  
    74  	name := d.Get("name").(string)
    75  
    76  	// Retrieve the vpc_offering ID
    77  	vpcofferingid, e := retrieveID(cs, "vpc_offering", d.Get("vpc_offering").(string))
    78  	if e != nil {
    79  		return e.Error()
    80  	}
    81  
    82  	// Retrieve the zone ID
    83  	zoneid, e := retrieveID(cs, "zone", d.Get("zone").(string))
    84  	if e != nil {
    85  		return e.Error()
    86  	}
    87  
    88  	// Set the display text
    89  	displaytext, ok := d.GetOk("display_text")
    90  	if !ok {
    91  		displaytext = name
    92  	}
    93  
    94  	// Create a new parameter struct
    95  	p := cs.VPC.NewCreateVPCParams(
    96  		d.Get("cidr").(string),
    97  		displaytext.(string),
    98  		name,
    99  		vpcofferingid,
   100  		zoneid,
   101  	)
   102  
   103  	// If there is a network domain supplied, make sure to add it to the request
   104  	if networkDomain, ok := d.GetOk("network_domain"); ok {
   105  		// Set the network domain
   106  		p.SetNetworkdomain(networkDomain.(string))
   107  	}
   108  
   109  	// If there is a project supplied, we retrieve and set the project id
   110  	if err := setProjectid(p, cs, d); err != nil {
   111  		return err
   112  	}
   113  
   114  	// Create the new VPC
   115  	r, err := cs.VPC.CreateVPC(p)
   116  	if err != nil {
   117  		return fmt.Errorf("Error creating VPC %s: %s", name, err)
   118  	}
   119  
   120  	d.SetId(r.Id)
   121  
   122  	return resourceCloudStackVPCRead(d, meta)
   123  }
   124  
   125  func resourceCloudStackVPCRead(d *schema.ResourceData, meta interface{}) error {
   126  	cs := meta.(*cloudstack.CloudStackClient)
   127  
   128  	// Get the VPC details
   129  	v, count, err := cs.VPC.GetVPCByID(
   130  		d.Id(),
   131  		cloudstack.WithProject(d.Get("project").(string)),
   132  	)
   133  	if err != nil {
   134  		if count == 0 {
   135  			log.Printf(
   136  				"[DEBUG] VPC %s does no longer exist", d.Get("name").(string))
   137  			d.SetId("")
   138  			return nil
   139  		}
   140  
   141  		return err
   142  	}
   143  
   144  	d.Set("name", v.Name)
   145  	d.Set("display_text", v.Displaytext)
   146  	d.Set("cidr", v.Cidr)
   147  	d.Set("network_domain", v.Networkdomain)
   148  
   149  	// Get the VPC offering details
   150  	o, _, err := cs.VPC.GetVPCOfferingByID(v.Vpcofferingid)
   151  	if err != nil {
   152  		return err
   153  	}
   154  
   155  	setValueOrID(d, "vpc_offering", o.Name, v.Vpcofferingid)
   156  	setValueOrID(d, "project", v.Project, v.Projectid)
   157  	setValueOrID(d, "zone", v.Zonename, v.Zoneid)
   158  
   159  	// Create a new parameter struct
   160  	p := cs.Address.NewListPublicIpAddressesParams()
   161  	p.SetVpcid(d.Id())
   162  	p.SetIssourcenat(true)
   163  
   164  	// If there is a project supplied, we retrieve and set the project id
   165  	if err := setProjectid(p, cs, d); err != nil {
   166  		return err
   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  		d.Set("source_nat_ip", l.PublicIpAddresses[0].Ipaddress)
   177  	}
   178  
   179  	return nil
   180  }
   181  
   182  func resourceCloudStackVPCUpdate(d *schema.ResourceData, meta interface{}) error {
   183  	cs := meta.(*cloudstack.CloudStackClient)
   184  
   185  	name := d.Get("name").(string)
   186  
   187  	// Check if the name is changed
   188  	if d.HasChange("name") {
   189  		// Create a new parameter struct
   190  		p := cs.VPC.NewUpdateVPCParams(d.Id())
   191  
   192  		// Set the new name
   193  		p.SetName(name)
   194  
   195  		// Update the VPC
   196  		_, err := cs.VPC.UpdateVPC(p)
   197  		if err != nil {
   198  			return fmt.Errorf(
   199  				"Error updating name of VPC %s: %s", name, err)
   200  		}
   201  	}
   202  
   203  	// Check if the display text is changed
   204  	if d.HasChange("display_text") {
   205  		// Create a new parameter struct
   206  		p := cs.VPC.NewUpdateVPCParams(d.Id())
   207  
   208  		// Set the display text
   209  		displaytext, ok := d.GetOk("display_text")
   210  		if !ok {
   211  			displaytext = d.Get("name")
   212  		}
   213  
   214  		// Set the new display text
   215  		p.SetDisplaytext(displaytext.(string))
   216  
   217  		// Update the VPC
   218  		_, err := cs.VPC.UpdateVPC(p)
   219  		if err != nil {
   220  			return fmt.Errorf(
   221  				"Error updating display test of VPC %s: %s", name, err)
   222  		}
   223  	}
   224  
   225  	return resourceCloudStackVPCRead(d, meta)
   226  }
   227  
   228  func resourceCloudStackVPCDelete(d *schema.ResourceData, meta interface{}) error {
   229  	cs := meta.(*cloudstack.CloudStackClient)
   230  
   231  	// Create a new parameter struct
   232  	p := cs.VPC.NewDeleteVPCParams(d.Id())
   233  
   234  	// Delete the VPC
   235  	_, err := cs.VPC.DeleteVPC(p)
   236  	if err != nil {
   237  		// This is a very poor way to be told the ID does no longer exist :(
   238  		if strings.Contains(err.Error(), fmt.Sprintf(
   239  			"Invalid parameter id value=%s due to incorrect long value format, "+
   240  				"or entity does not exist", d.Id())) {
   241  			return nil
   242  		}
   243  
   244  		return fmt.Errorf("Error deleting VPC %s: %s", d.Get("name").(string), err)
   245  	}
   246  
   247  	return nil
   248  }