github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/alicloud/resource_alicloud_vswitch.go (about)

     1  package alicloud
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/denverdino/aliyungo/common"
     7  	"github.com/denverdino/aliyungo/ecs"
     8  	"github.com/hashicorp/terraform/helper/resource"
     9  	"github.com/hashicorp/terraform/helper/schema"
    10  	"log"
    11  	"time"
    12  )
    13  
    14  func resourceAliyunSubnet() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceAliyunSwitchCreate,
    17  		Read:   resourceAliyunSwitchRead,
    18  		Update: resourceAliyunSwitchUpdate,
    19  		Delete: resourceAliyunSwitchDelete,
    20  
    21  		Schema: map[string]*schema.Schema{
    22  			"availability_zone": &schema.Schema{
    23  				Type:     schema.TypeString,
    24  				Required: true,
    25  				ForceNew: true,
    26  			},
    27  			"vpc_id": &schema.Schema{
    28  				Type:     schema.TypeString,
    29  				Required: true,
    30  				ForceNew: true,
    31  			},
    32  			"cidr_block": &schema.Schema{
    33  				Type:         schema.TypeString,
    34  				Required:     true,
    35  				ForceNew:     true,
    36  				ValidateFunc: validateSwitchCIDRNetworkAddress,
    37  			},
    38  			"name": &schema.Schema{
    39  				Type:     schema.TypeString,
    40  				Optional: true,
    41  			},
    42  			"description": &schema.Schema{
    43  				Type:     schema.TypeString,
    44  				Optional: true,
    45  			},
    46  		},
    47  	}
    48  }
    49  
    50  func resourceAliyunSwitchCreate(d *schema.ResourceData, meta interface{}) error {
    51  
    52  	conn := meta.(*AliyunClient).ecsconn
    53  
    54  	args, err := buildAliyunSwitchArgs(d, meta)
    55  	if err != nil {
    56  		return err
    57  	}
    58  
    59  	var vswitchID string
    60  	err = resource.Retry(3*time.Minute, func() *resource.RetryError {
    61  		vswId, err := conn.CreateVSwitch(args)
    62  		if err != nil {
    63  			if e, ok := err.(*common.Error); ok && (e.StatusCode == 400 || e.Code == UnknownError) {
    64  				return resource.RetryableError(fmt.Errorf("Vswitch is still creating result from some unknown error -- try again"))
    65  			}
    66  			return resource.NonRetryableError(err)
    67  		}
    68  		vswitchID = vswId
    69  		return nil
    70  	})
    71  
    72  	if err != nil {
    73  		return fmt.Errorf("Create subnet got an error :%s", err)
    74  	}
    75  
    76  	d.SetId(vswitchID)
    77  
    78  	err = conn.WaitForVSwitchAvailable(args.VpcId, vswitchID, 60)
    79  	if err != nil {
    80  		return fmt.Errorf("WaitForVSwitchAvailable got a error: %s", err)
    81  	}
    82  
    83  	return resourceAliyunSwitchUpdate(d, meta)
    84  }
    85  
    86  func resourceAliyunSwitchRead(d *schema.ResourceData, meta interface{}) error {
    87  
    88  	conn := meta.(*AliyunClient).ecsconn
    89  
    90  	args := &ecs.DescribeVSwitchesArgs{
    91  		VpcId:     d.Get("vpc_id").(string),
    92  		VSwitchId: d.Id(),
    93  	}
    94  
    95  	vswitches, _, err := conn.DescribeVSwitches(args)
    96  
    97  	if err != nil {
    98  		if notFoundError(err) {
    99  			d.SetId("")
   100  			return nil
   101  		}
   102  		return err
   103  	}
   104  
   105  	if len(vswitches) == 0 {
   106  		d.SetId("")
   107  		return nil
   108  	}
   109  
   110  	vswitch := vswitches[0]
   111  
   112  	d.Set("availability_zone", vswitch.ZoneId)
   113  	d.Set("vpc_id", vswitch.VpcId)
   114  	d.Set("cidr_block", vswitch.CidrBlock)
   115  	d.Set("name", vswitch.VSwitchName)
   116  	d.Set("description", vswitch.Description)
   117  
   118  	return nil
   119  }
   120  
   121  func resourceAliyunSwitchUpdate(d *schema.ResourceData, meta interface{}) error {
   122  
   123  	conn := meta.(*AliyunClient).ecsconn
   124  
   125  	d.Partial(true)
   126  
   127  	attributeUpdate := false
   128  	args := &ecs.ModifyVSwitchAttributeArgs{
   129  		VSwitchId: d.Id(),
   130  	}
   131  
   132  	if d.HasChange("name") {
   133  		d.SetPartial("name")
   134  		args.VSwitchName = d.Get("name").(string)
   135  
   136  		attributeUpdate = true
   137  	}
   138  
   139  	if d.HasChange("description") {
   140  		d.SetPartial("description")
   141  		args.Description = d.Get("description").(string)
   142  
   143  		attributeUpdate = true
   144  	}
   145  	if attributeUpdate {
   146  		if err := conn.ModifyVSwitchAttribute(args); err != nil {
   147  			return err
   148  		}
   149  
   150  	}
   151  
   152  	d.Partial(false)
   153  
   154  	return resourceAliyunSwitchRead(d, meta)
   155  }
   156  
   157  func resourceAliyunSwitchDelete(d *schema.ResourceData, meta interface{}) error {
   158  	conn := meta.(*AliyunClient).ecsconn
   159  
   160  	return resource.Retry(5*time.Minute, func() *resource.RetryError {
   161  		err := conn.DeleteVSwitch(d.Id())
   162  
   163  		if err != nil {
   164  			e, _ := err.(*common.Error)
   165  			if e.ErrorResponse.Code == VswitcInvalidRegionId {
   166  				log.Printf("[ERROR] Delete Switch is failed.")
   167  				return resource.NonRetryableError(err)
   168  			}
   169  
   170  			return resource.RetryableError(fmt.Errorf("Switch in use. -- trying again while it is deleted."))
   171  		}
   172  
   173  		vsw, _, vswErr := conn.DescribeVSwitches(&ecs.DescribeVSwitchesArgs{
   174  			VpcId:     d.Get("vpc_id").(string),
   175  			VSwitchId: d.Id(),
   176  		})
   177  
   178  		if vswErr != nil {
   179  			return resource.NonRetryableError(vswErr)
   180  		} else if vsw == nil || len(vsw) < 1 {
   181  			return nil
   182  		}
   183  
   184  		return resource.RetryableError(fmt.Errorf("Switch in use. -- trying again while it is deleted."))
   185  	})
   186  }
   187  
   188  func buildAliyunSwitchArgs(d *schema.ResourceData, meta interface{}) (*ecs.CreateVSwitchArgs, error) {
   189  
   190  	client := meta.(*AliyunClient)
   191  
   192  	vpcID := d.Get("vpc_id").(string)
   193  
   194  	vpc, err := client.DescribeVpc(vpcID)
   195  	if err != nil {
   196  		return nil, err
   197  	}
   198  
   199  	if vpc == nil {
   200  		return nil, fmt.Errorf("vpc_id not found")
   201  	}
   202  
   203  	zoneID := d.Get("availability_zone").(string)
   204  
   205  	zone, err := client.DescribeZone(zoneID)
   206  	if err != nil {
   207  		return nil, err
   208  	}
   209  
   210  	err = client.ResourceAvailable(zone, ecs.ResourceTypeVSwitch)
   211  	if err != nil {
   212  		return nil, err
   213  	}
   214  
   215  	cidrBlock := d.Get("cidr_block").(string)
   216  
   217  	args := &ecs.CreateVSwitchArgs{
   218  		VpcId:     vpcID,
   219  		ZoneId:    zoneID,
   220  		CidrBlock: cidrBlock,
   221  	}
   222  
   223  	if v, ok := d.GetOk("name"); ok && v != "" {
   224  		args.VSwitchName = v.(string)
   225  	}
   226  
   227  	if v, ok := d.GetOk("description"); ok && v != "" {
   228  		args.Description = v.(string)
   229  	}
   230  
   231  	return args, nil
   232  }