github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/alicloud/resource_alicloud_eip_association.go (about)

     1  package alicloud
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/denverdino/aliyungo/common"
     8  	"github.com/denverdino/aliyungo/ecs"
     9  	"github.com/hashicorp/terraform/helper/resource"
    10  	"github.com/hashicorp/terraform/helper/schema"
    11  	"time"
    12  )
    13  
    14  func resourceAliyunEipAssociation() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceAliyunEipAssociationCreate,
    17  		Read:   resourceAliyunEipAssociationRead,
    18  		Delete: resourceAliyunEipAssociationDelete,
    19  
    20  		Schema: map[string]*schema.Schema{
    21  			"allocation_id": &schema.Schema{
    22  				Type:     schema.TypeString,
    23  				Optional: true,
    24  				Computed: true,
    25  				ForceNew: true,
    26  			},
    27  
    28  			"instance_id": &schema.Schema{
    29  				Type:     schema.TypeString,
    30  				Optional: true,
    31  				Computed: true,
    32  				ForceNew: true,
    33  			},
    34  		},
    35  	}
    36  }
    37  
    38  func resourceAliyunEipAssociationCreate(d *schema.ResourceData, meta interface{}) error {
    39  
    40  	conn := meta.(*AliyunClient).ecsconn
    41  
    42  	allocationId := d.Get("allocation_id").(string)
    43  	instanceId := d.Get("instance_id").(string)
    44  
    45  	if err := conn.AssociateEipAddress(allocationId, instanceId); err != nil {
    46  		return err
    47  	}
    48  
    49  	d.SetId(allocationId + ":" + instanceId)
    50  
    51  	return resourceAliyunEipAssociationRead(d, meta)
    52  }
    53  
    54  func resourceAliyunEipAssociationRead(d *schema.ResourceData, meta interface{}) error {
    55  	client := meta.(*AliyunClient)
    56  
    57  	allocationId, instanceId, err := getAllocationIdAndInstanceId(d, meta)
    58  	if err != nil {
    59  		return err
    60  	}
    61  
    62  	eip, err := client.DescribeEipAddress(allocationId)
    63  
    64  	if err != nil {
    65  		if notFoundError(err) {
    66  			d.SetId("")
    67  			return nil
    68  		}
    69  		return fmt.Errorf("Error Describe Eip Attribute: %#v", err)
    70  	}
    71  
    72  	if eip.InstanceId != instanceId {
    73  		d.SetId("")
    74  		return nil
    75  	}
    76  
    77  	d.Set("instance_id", eip.InstanceId)
    78  	d.Set("allocation_id", allocationId)
    79  	return nil
    80  }
    81  
    82  func resourceAliyunEipAssociationDelete(d *schema.ResourceData, meta interface{}) error {
    83  
    84  	conn := meta.(*AliyunClient).ecsconn
    85  
    86  	allocationId, instanceId, err := getAllocationIdAndInstanceId(d, meta)
    87  	if err != nil {
    88  		return err
    89  	}
    90  
    91  	return resource.Retry(5*time.Minute, func() *resource.RetryError {
    92  		err := conn.UnassociateEipAddress(allocationId, instanceId)
    93  
    94  		if err != nil {
    95  			e, _ := err.(*common.Error)
    96  			errCode := e.ErrorResponse.Code
    97  			if errCode == InstanceIncorrectStatus || errCode == HaVipIncorrectStatus {
    98  				return resource.RetryableError(fmt.Errorf("Eip in use - trying again while make it unassociated."))
    99  			}
   100  		}
   101  
   102  		args := &ecs.DescribeEipAddressesArgs{
   103  			RegionId:     getRegion(d, meta),
   104  			AllocationId: allocationId,
   105  		}
   106  
   107  		eips, _, descErr := conn.DescribeEipAddresses(args)
   108  
   109  		if descErr != nil {
   110  			return resource.NonRetryableError(descErr)
   111  		} else if eips == nil || len(eips) < 1 {
   112  			return nil
   113  		}
   114  		for _, eip := range eips {
   115  			if eip.Status != ecs.EipStatusAvailable {
   116  				return resource.RetryableError(fmt.Errorf("Eip in use - trying again while make it unassociated."))
   117  			}
   118  		}
   119  
   120  		return nil
   121  	})
   122  }
   123  
   124  func getAllocationIdAndInstanceId(d *schema.ResourceData, meta interface{}) (string, string, error) {
   125  	parts := strings.Split(d.Id(), ":")
   126  
   127  	if len(parts) != 2 {
   128  		return "", "", fmt.Errorf("invalid resource id")
   129  	}
   130  	return parts[0], parts[1], nil
   131  }