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 }