github.com/cbroglie/terraform@v0.7.0-rc3.0.20170410193827-735dfc416d46/builtin/providers/alicloud/resource_alicloud_nat_gateway.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  	"strings"
    12  	"time"
    13  )
    14  
    15  func resourceAliyunNatGateway() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceAliyunNatGatewayCreate,
    18  		Read:   resourceAliyunNatGatewayRead,
    19  		Update: resourceAliyunNatGatewayUpdate,
    20  		Delete: resourceAliyunNatGatewayDelete,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"vpc_id": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  				ForceNew: true,
    27  			},
    28  			"spec": &schema.Schema{
    29  				Type:     schema.TypeString,
    30  				Required: true,
    31  			},
    32  			"name": &schema.Schema{
    33  				Type:     schema.TypeString,
    34  				Optional: true,
    35  				Computed: true,
    36  			},
    37  			"description": &schema.Schema{
    38  				Type:     schema.TypeString,
    39  				Optional: true,
    40  			},
    41  
    42  			"bandwidth_package_ids": &schema.Schema{
    43  				Type:     schema.TypeString,
    44  				Computed: true,
    45  			},
    46  
    47  			"bandwidth_packages": &schema.Schema{
    48  				Type: schema.TypeList,
    49  				Elem: &schema.Resource{
    50  					Schema: map[string]*schema.Schema{
    51  						"ip_count": &schema.Schema{
    52  							Type:     schema.TypeInt,
    53  							Required: true,
    54  						},
    55  						"bandwidth": &schema.Schema{
    56  							Type:     schema.TypeInt,
    57  							Required: true,
    58  						},
    59  						"zone": &schema.Schema{
    60  							Type:     schema.TypeString,
    61  							Optional: true,
    62  						},
    63  					},
    64  				},
    65  				Required: true,
    66  				MaxItems: 4,
    67  			},
    68  		},
    69  	}
    70  }
    71  
    72  func resourceAliyunNatGatewayCreate(d *schema.ResourceData, meta interface{}) error {
    73  	conn := meta.(*AliyunClient).vpcconn
    74  
    75  	args := &ecs.CreateNatGatewayArgs{
    76  		RegionId: getRegion(d, meta),
    77  		VpcId:    d.Get("vpc_id").(string),
    78  		Spec:     d.Get("spec").(string),
    79  	}
    80  
    81  	bandwidthPackages := d.Get("bandwidth_packages").([]interface{})
    82  
    83  	bandwidthPackageTypes := []ecs.BandwidthPackageType{}
    84  
    85  	for _, e := range bandwidthPackages {
    86  		pack := e.(map[string]interface{})
    87  		bandwidthPackage := ecs.BandwidthPackageType{
    88  			IpCount:   pack["ip_count"].(int),
    89  			Bandwidth: pack["bandwidth"].(int),
    90  		}
    91  		if pack["zone"].(string) != "" {
    92  			bandwidthPackage.Zone = pack["zone"].(string)
    93  		}
    94  
    95  		bandwidthPackageTypes = append(bandwidthPackageTypes, bandwidthPackage)
    96  	}
    97  
    98  	args.BandwidthPackage = bandwidthPackageTypes
    99  
   100  	var name string
   101  	if v, ok := d.GetOk("name"); ok {
   102  		name = v.(string)
   103  	}
   104  
   105  	args.Name = name
   106  
   107  	if v, ok := d.GetOk("description"); ok {
   108  		args.Description = v.(string)
   109  	}
   110  	resp, err := conn.CreateNatGateway(args)
   111  	if err != nil {
   112  		return fmt.Errorf("CreateNatGateway got error: %#v", err)
   113  	}
   114  
   115  	d.SetId(resp.NatGatewayId)
   116  
   117  	return resourceAliyunNatGatewayRead(d, meta)
   118  }
   119  
   120  func resourceAliyunNatGatewayRead(d *schema.ResourceData, meta interface{}) error {
   121  
   122  	client := meta.(*AliyunClient)
   123  
   124  	natGateway, err := client.DescribeNatGateway(d.Id())
   125  	if err != nil {
   126  		if notFoundError(err) {
   127  			d.SetId("")
   128  			return nil
   129  		}
   130  		return err
   131  	}
   132  
   133  	d.Set("name", natGateway.Name)
   134  	d.Set("spec", natGateway.Spec)
   135  	d.Set("bandwidth_package_ids", strings.Join(natGateway.BandwidthPackageIds.BandwidthPackageId, ","))
   136  	d.Set("description", natGateway.Description)
   137  	d.Set("vpc_id", natGateway.VpcId)
   138  
   139  	return nil
   140  }
   141  
   142  func resourceAliyunNatGatewayUpdate(d *schema.ResourceData, meta interface{}) error {
   143  
   144  	client := meta.(*AliyunClient)
   145  	conn := client.vpcconn
   146  
   147  	natGateway, err := client.DescribeNatGateway(d.Id())
   148  	if err != nil {
   149  		return err
   150  	}
   151  
   152  	d.Partial(true)
   153  	attributeUpdate := false
   154  	args := &ecs.ModifyNatGatewayAttributeArgs{
   155  		RegionId:     natGateway.RegionId,
   156  		NatGatewayId: natGateway.NatGatewayId,
   157  	}
   158  
   159  	if d.HasChange("name") {
   160  		d.SetPartial("name")
   161  		var name string
   162  		if v, ok := d.GetOk("name"); ok {
   163  			name = v.(string)
   164  		} else {
   165  			return fmt.Errorf("cann't change name to empty string")
   166  		}
   167  		args.Name = name
   168  
   169  		attributeUpdate = true
   170  	}
   171  
   172  	if d.HasChange("description") {
   173  		d.SetPartial("description")
   174  		var description string
   175  		if v, ok := d.GetOk("description"); ok {
   176  			description = v.(string)
   177  		} else {
   178  			return fmt.Errorf("can to change description to empty string")
   179  		}
   180  
   181  		args.Description = description
   182  
   183  		attributeUpdate = true
   184  	}
   185  
   186  	if attributeUpdate {
   187  		if err := conn.ModifyNatGatewayAttribute(args); err != nil {
   188  			return err
   189  		}
   190  	}
   191  
   192  	if d.HasChange("spec") {
   193  		d.SetPartial("spec")
   194  		var spec ecs.NatGatewaySpec
   195  		if v, ok := d.GetOk("spec"); ok {
   196  			spec = ecs.NatGatewaySpec(v.(string))
   197  		} else {
   198  			// set default to small spec
   199  			spec = ecs.NatGatewaySmallSpec
   200  		}
   201  
   202  		args := &ecs.ModifyNatGatewaySpecArgs{
   203  			RegionId:     natGateway.RegionId,
   204  			NatGatewayId: natGateway.NatGatewayId,
   205  			Spec:         spec,
   206  		}
   207  
   208  		err := conn.ModifyNatGatewaySpec(args)
   209  		if err != nil {
   210  			return fmt.Errorf("%#v %#v", err, *args)
   211  		}
   212  
   213  	}
   214  	d.Partial(false)
   215  
   216  	return resourceAliyunNatGatewayRead(d, meta)
   217  }
   218  
   219  func resourceAliyunNatGatewayDelete(d *schema.ResourceData, meta interface{}) error {
   220  
   221  	client := meta.(*AliyunClient)
   222  	conn := client.vpcconn
   223  
   224  	return resource.Retry(5*time.Minute, func() *resource.RetryError {
   225  
   226  		packages, err := conn.DescribeBandwidthPackages(&ecs.DescribeBandwidthPackagesArgs{
   227  			RegionId:     getRegion(d, meta),
   228  			NatGatewayId: d.Id(),
   229  		})
   230  		if err != nil {
   231  			log.Printf("[ERROR] Describe bandwidth package is failed, natGateway Id: %s", d.Id())
   232  			return resource.NonRetryableError(err)
   233  		}
   234  
   235  		retry := false
   236  		for _, pack := range packages {
   237  			err = conn.DeleteBandwidthPackage(&ecs.DeleteBandwidthPackageArgs{
   238  				RegionId:           getRegion(d, meta),
   239  				BandwidthPackageId: pack.BandwidthPackageId,
   240  			})
   241  
   242  			if err != nil {
   243  				er, _ := err.(*common.Error)
   244  				if er.ErrorResponse.Code == NatGatewayInvalidRegionId {
   245  					log.Printf("[ERROR] Delete bandwidth package is failed, bandwidthPackageId: %#v", pack.BandwidthPackageId)
   246  					return resource.NonRetryableError(err)
   247  				}
   248  				retry = true
   249  			}
   250  		}
   251  
   252  		if retry {
   253  			return resource.RetryableError(fmt.Errorf("Bandwidth package in use - trying again while it is deleted."))
   254  		}
   255  
   256  		args := &ecs.DeleteNatGatewayArgs{
   257  			RegionId:     client.Region,
   258  			NatGatewayId: d.Id(),
   259  		}
   260  
   261  		err = conn.DeleteNatGateway(args)
   262  		if err != nil {
   263  			er, _ := err.(*common.Error)
   264  			if er.ErrorResponse.Code == DependencyViolationBandwidthPackages {
   265  				return resource.RetryableError(fmt.Errorf("NatGateway in use - trying again while it is deleted."))
   266  			}
   267  		}
   268  
   269  		describeArgs := &ecs.DescribeNatGatewaysArgs{
   270  			RegionId:     client.Region,
   271  			NatGatewayId: d.Id(),
   272  		}
   273  		gw, _, gwErr := conn.DescribeNatGateways(describeArgs)
   274  
   275  		if gwErr != nil {
   276  			log.Printf("[ERROR] Describe NatGateways failed.")
   277  			return resource.NonRetryableError(gwErr)
   278  		} else if gw == nil || len(gw) < 1 {
   279  			return nil
   280  		}
   281  
   282  		return resource.RetryableError(fmt.Errorf("NatGateway in use - trying again while it is deleted."))
   283  	})
   284  }