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