github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/cloudstack/resource_cloudstack_ipaddress.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 resourceCloudStackIPAddress() *schema.Resource {
    13  	return &schema.Resource{
    14  		Create: resourceCloudStackIPAddressCreate,
    15  		Read:   resourceCloudStackIPAddressRead,
    16  		Delete: resourceCloudStackIPAddressDelete,
    17  
    18  		Schema: map[string]*schema.Schema{
    19  			"network": &schema.Schema{
    20  				Type:     schema.TypeString,
    21  				Optional: true,
    22  				ForceNew: true,
    23  			},
    24  
    25  			"vpc": &schema.Schema{
    26  				Type:     schema.TypeString,
    27  				Optional: true,
    28  				ForceNew: true,
    29  			},
    30  
    31  			"project": &schema.Schema{
    32  				Type:     schema.TypeString,
    33  				Optional: true,
    34  				ForceNew: true,
    35  			},
    36  
    37  			"ipaddress": &schema.Schema{
    38  				Type:     schema.TypeString,
    39  				Computed: true,
    40  			},
    41  		},
    42  	}
    43  }
    44  
    45  func resourceCloudStackIPAddressCreate(d *schema.ResourceData, meta interface{}) error {
    46  	cs := meta.(*cloudstack.CloudStackClient)
    47  
    48  	if err := verifyIPAddressParams(d); err != nil {
    49  		return err
    50  	}
    51  
    52  	// Create a new parameter struct
    53  	p := cs.Address.NewAssociateIpAddressParams()
    54  
    55  	if network, ok := d.GetOk("network"); ok {
    56  		// Retrieve the network ID
    57  		networkid, e := retrieveID(cs, "network", network.(string))
    58  		if e != nil {
    59  			return e.Error()
    60  		}
    61  
    62  		// Set the networkid
    63  		p.SetNetworkid(networkid)
    64  	}
    65  
    66  	if vpc, ok := d.GetOk("vpc"); ok {
    67  		// Retrieve the vpc ID
    68  		vpcid, e := retrieveID(cs, "vpc", vpc.(string))
    69  		if e != nil {
    70  			return e.Error()
    71  		}
    72  
    73  		// Set the vpcid
    74  		p.SetVpcid(vpcid)
    75  	}
    76  
    77  	// If there is a project supplied, we retrieve and set the project id
    78  	if project, ok := d.GetOk("project"); ok {
    79  		// Retrieve the project ID
    80  		projectid, e := retrieveID(cs, "project", project.(string))
    81  		if e != nil {
    82  			return e.Error()
    83  		}
    84  		// Set the default project ID
    85  		p.SetProjectid(projectid)
    86  	}
    87  
    88  	// Associate a new IP address
    89  	r, err := cs.Address.AssociateIpAddress(p)
    90  	if err != nil {
    91  		return fmt.Errorf("Error associating a new IP address: %s", err)
    92  	}
    93  
    94  	d.SetId(r.Id)
    95  
    96  	return resourceCloudStackIPAddressRead(d, meta)
    97  }
    98  
    99  func resourceCloudStackIPAddressRead(d *schema.ResourceData, meta interface{}) error {
   100  	cs := meta.(*cloudstack.CloudStackClient)
   101  
   102  	// Get the network ACL list details
   103  	f, count, err := cs.Address.GetPublicIpAddressByID(d.Id())
   104  	if err != nil {
   105  		if count == 0 {
   106  			log.Printf(
   107  				"[DEBUG] IP address with ID %s is no longer associated", d.Id())
   108  			d.SetId("")
   109  			return nil
   110  		}
   111  
   112  		return err
   113  	}
   114  
   115  	// Updated the IP address
   116  	d.Set("ipaddress", f.Ipaddress)
   117  
   118  	if _, ok := d.GetOk("network"); ok {
   119  		// Get the network details
   120  		n, _, err := cs.Network.GetNetworkByID(f.Associatednetworkid)
   121  		if err != nil {
   122  			return err
   123  		}
   124  
   125  		setValueOrID(d, "network", n.Name, f.Associatednetworkid)
   126  	}
   127  
   128  	if _, ok := d.GetOk("vpc"); ok {
   129  		// Get the VPC details
   130  		v, _, err := cs.VPC.GetVPCByID(f.Vpcid)
   131  		if err != nil {
   132  			return err
   133  		}
   134  
   135  		setValueOrID(d, "vpc", v.Name, f.Vpcid)
   136  	}
   137  
   138  	setValueOrID(d, "project", f.Project, f.Projectid)
   139  
   140  	return nil
   141  }
   142  
   143  func resourceCloudStackIPAddressDelete(d *schema.ResourceData, meta interface{}) error {
   144  	cs := meta.(*cloudstack.CloudStackClient)
   145  
   146  	// Create a new parameter struct
   147  	p := cs.Address.NewDisassociateIpAddressParams(d.Id())
   148  
   149  	// Disassociate the IP address
   150  	if _, err := cs.Address.DisassociateIpAddress(p); err != nil {
   151  		// This is a very poor way to be told the ID does no longer exist :(
   152  		if strings.Contains(err.Error(), fmt.Sprintf(
   153  			"Invalid parameter id value=%s due to incorrect long value format, "+
   154  				"or entity does not exist", d.Id())) {
   155  			return nil
   156  		}
   157  
   158  		return fmt.Errorf("Error disassociating IP address %s: %s", d.Get("name").(string), err)
   159  	}
   160  
   161  	return nil
   162  }
   163  
   164  func verifyIPAddressParams(d *schema.ResourceData) error {
   165  	_, network := d.GetOk("network")
   166  	_, vpc := d.GetOk("vpc")
   167  
   168  	if network && vpc || !network && !vpc {
   169  		return fmt.Errorf(
   170  			"You must supply a value for either (so not both) the 'network' or 'vpc' parameter")
   171  	}
   172  
   173  	return nil
   174  }