github.com/anfernee/terraform@v0.6.16-0.20160430000239-06e5085a92f2/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_id": &schema.Schema{
    20  				Type:     schema.TypeString,
    21  				Optional: true,
    22  				Computed: true,
    23  				ForceNew: true,
    24  			},
    25  
    26  			"network": &schema.Schema{
    27  				Type:       schema.TypeString,
    28  				Optional:   true,
    29  				ForceNew:   true,
    30  				Deprecated: "Please use the `network_id` field instead",
    31  			},
    32  
    33  			"vpc_id": &schema.Schema{
    34  				Type:     schema.TypeString,
    35  				Optional: true,
    36  				Computed: true,
    37  				ForceNew: true,
    38  			},
    39  
    40  			"vpc": &schema.Schema{
    41  				Type:       schema.TypeString,
    42  				Optional:   true,
    43  				ForceNew:   true,
    44  				Deprecated: "Please use the `vpc_id` field instead",
    45  			},
    46  
    47  			"project": &schema.Schema{
    48  				Type:     schema.TypeString,
    49  				Optional: true,
    50  				ForceNew: true,
    51  			},
    52  
    53  			"ip_address": &schema.Schema{
    54  				Type:     schema.TypeString,
    55  				Computed: true,
    56  			},
    57  		},
    58  	}
    59  }
    60  
    61  func resourceCloudStackIPAddressCreate(d *schema.ResourceData, meta interface{}) error {
    62  	cs := meta.(*cloudstack.CloudStackClient)
    63  
    64  	if err := verifyIPAddressParams(d); err != nil {
    65  		return err
    66  	}
    67  
    68  	// Create a new parameter struct
    69  	p := cs.Address.NewAssociateIpAddressParams()
    70  
    71  	network, ok := d.GetOk("network_id")
    72  	if !ok {
    73  		network, ok = d.GetOk("network")
    74  	}
    75  	if ok {
    76  		// Retrieve the network ID
    77  		networkid, e := retrieveID(
    78  			cs,
    79  			"network",
    80  			network.(string),
    81  			cloudstack.WithProject(d.Get("project").(string)),
    82  		)
    83  		if e != nil {
    84  			return e.Error()
    85  		}
    86  
    87  		// Set the networkid
    88  		p.SetNetworkid(networkid)
    89  	}
    90  
    91  	vpc, ok := d.GetOk("vpc_id")
    92  	if !ok {
    93  		vpc, ok = d.GetOk("vpc")
    94  	}
    95  	if ok {
    96  		// Retrieve the vpc ID
    97  		vpcid, e := retrieveID(
    98  			cs,
    99  			"vpc",
   100  			vpc.(string),
   101  			cloudstack.WithProject(d.Get("project").(string)),
   102  		)
   103  		if e != nil {
   104  			return e.Error()
   105  		}
   106  
   107  		// Set the vpcid
   108  		p.SetVpcid(vpcid)
   109  	}
   110  
   111  	// If there is a project supplied, we retrieve and set the project id
   112  	if err := setProjectid(p, cs, d); err != nil {
   113  		return err
   114  	}
   115  
   116  	// Associate a new IP address
   117  	r, err := cs.Address.AssociateIpAddress(p)
   118  	if err != nil {
   119  		return fmt.Errorf("Error associating a new IP address: %s", err)
   120  	}
   121  
   122  	d.SetId(r.Id)
   123  
   124  	return resourceCloudStackIPAddressRead(d, meta)
   125  }
   126  
   127  func resourceCloudStackIPAddressRead(d *schema.ResourceData, meta interface{}) error {
   128  	cs := meta.(*cloudstack.CloudStackClient)
   129  
   130  	// Get the IP address details
   131  	ip, count, err := cs.Address.GetPublicIpAddressByID(
   132  		d.Id(),
   133  		cloudstack.WithProject(d.Get("project").(string)),
   134  	)
   135  	if err != nil {
   136  		if count == 0 {
   137  			log.Printf(
   138  				"[DEBUG] IP address with ID %s is no longer associated", d.Id())
   139  			d.SetId("")
   140  			return nil
   141  		}
   142  
   143  		return err
   144  	}
   145  
   146  	// Updated the IP address
   147  	d.Set("ip_address", ip.Ipaddress)
   148  
   149  	_, networkID := d.GetOk("network_id")
   150  	_, network := d.GetOk("network")
   151  	if networkID || network {
   152  		d.Set("network_id", ip.Associatednetworkid)
   153  	}
   154  
   155  	_, vpcID := d.GetOk("vpc_id")
   156  	_, vpc := d.GetOk("vpc")
   157  	if vpcID || vpc {
   158  		d.Set("vpc_id", ip.Vpcid)
   159  	}
   160  
   161  	setValueOrID(d, "project", ip.Project, ip.Projectid)
   162  
   163  	return nil
   164  }
   165  
   166  func resourceCloudStackIPAddressDelete(d *schema.ResourceData, meta interface{}) error {
   167  	cs := meta.(*cloudstack.CloudStackClient)
   168  
   169  	// Create a new parameter struct
   170  	p := cs.Address.NewDisassociateIpAddressParams(d.Id())
   171  
   172  	// Disassociate the IP address
   173  	if _, err := cs.Address.DisassociateIpAddress(p); err != nil {
   174  		// This is a very poor way to be told the ID does no longer exist :(
   175  		if strings.Contains(err.Error(), fmt.Sprintf(
   176  			"Invalid parameter id value=%s due to incorrect long value format, "+
   177  				"or entity does not exist", d.Id())) {
   178  			return nil
   179  		}
   180  
   181  		return fmt.Errorf("Error disassociating IP address %s: %s", d.Get("name").(string), err)
   182  	}
   183  
   184  	return nil
   185  }
   186  
   187  func verifyIPAddressParams(d *schema.ResourceData) error {
   188  	_, networkID := d.GetOk("network_id")
   189  	_, network := d.GetOk("network")
   190  	_, vpcID := d.GetOk("vpc_id")
   191  	_, vpc := d.GetOk("vpc")
   192  
   193  	if (networkID || network) && (vpcID || vpc) || (!networkID && !network) && (!vpcID && !vpc) {
   194  		return fmt.Errorf(
   195  			"You must supply a value for either (so not both) the 'network_id' or 'vpc_id' parameter")
   196  	}
   197  
   198  	return nil
   199  }