github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/alicloud/resource_alicloud_vpc.go (about) 1 package alicloud 2 3 import ( 4 "fmt" 5 "github.com/denverdino/aliyungo/common" 6 "github.com/denverdino/aliyungo/ecs" 7 "github.com/hashicorp/terraform/helper/resource" 8 "github.com/hashicorp/terraform/helper/schema" 9 "strings" 10 "time" 11 ) 12 13 func resourceAliyunVpc() *schema.Resource { 14 return &schema.Resource{ 15 Create: resourceAliyunVpcCreate, 16 Read: resourceAliyunVpcRead, 17 Update: resourceAliyunVpcUpdate, 18 Delete: resourceAliyunVpcDelete, 19 20 Schema: map[string]*schema.Schema{ 21 "cidr_block": &schema.Schema{ 22 Type: schema.TypeString, 23 Required: true, 24 ForceNew: true, 25 ValidateFunc: validateCIDRNetworkAddress, 26 }, 27 "name": &schema.Schema{ 28 Type: schema.TypeString, 29 Optional: true, 30 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 31 value := v.(string) 32 if len(value) < 2 || len(value) > 128 { 33 errors = append(errors, fmt.Errorf("%s cannot be longer than 128 characters", k)) 34 } 35 36 if strings.HasPrefix(value, "http://") || strings.HasPrefix(value, "https://") { 37 errors = append(errors, fmt.Errorf("%s cannot starts with http:// or https://", k)) 38 } 39 40 return 41 }, 42 }, 43 "description": &schema.Schema{ 44 Type: schema.TypeString, 45 Optional: true, 46 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 47 value := v.(string) 48 if len(value) < 2 || len(value) > 256 { 49 errors = append(errors, fmt.Errorf("%s cannot be longer than 256 characters", k)) 50 51 } 52 return 53 }, 54 }, 55 "router_id": &schema.Schema{ 56 Type: schema.TypeString, 57 Computed: true, 58 }, 59 "router_table_id": &schema.Schema{ 60 Type: schema.TypeString, 61 Computed: true, 62 }, 63 }, 64 } 65 } 66 67 func resourceAliyunVpcCreate(d *schema.ResourceData, meta interface{}) error { 68 69 args, err := buildAliyunVpcArgs(d, meta) 70 if err != nil { 71 return err 72 } 73 74 ecsconn := meta.(*AliyunClient).ecsconn 75 76 var vpc *ecs.CreateVpcResponse 77 err = resource.Retry(3*time.Minute, func() *resource.RetryError { 78 resp, err := ecsconn.CreateVpc(args) 79 if err != nil { 80 if e, ok := err.(*common.Error); ok && (e.StatusCode == 400 || e.Code == UnknownError) { 81 return resource.RetryableError(fmt.Errorf("Vpc is still creating result from some unknown error -- try again")) 82 } 83 return resource.NonRetryableError(err) 84 } 85 vpc = resp 86 return nil 87 }) 88 if err != nil { 89 return fmt.Errorf("Create vpc got an error :%#v", err) 90 } 91 92 d.SetId(vpc.VpcId) 93 d.Set("router_table_id", vpc.RouteTableId) 94 95 err = ecsconn.WaitForVpcAvailable(args.RegionId, vpc.VpcId, 60) 96 if err != nil { 97 return fmt.Errorf("Timeout when WaitForVpcAvailable") 98 } 99 100 return resourceAliyunVpcUpdate(d, meta) 101 } 102 103 func resourceAliyunVpcRead(d *schema.ResourceData, meta interface{}) error { 104 105 client := meta.(*AliyunClient) 106 107 vpc, err := client.DescribeVpc(d.Id()) 108 if err != nil { 109 return err 110 } 111 112 if vpc == nil { 113 d.SetId("") 114 return nil 115 } 116 117 d.Set("cidr_block", vpc.CidrBlock) 118 d.Set("name", vpc.VpcName) 119 d.Set("description", vpc.Description) 120 d.Set("router_id", vpc.VRouterId) 121 122 return nil 123 } 124 125 func resourceAliyunVpcUpdate(d *schema.ResourceData, meta interface{}) error { 126 127 conn := meta.(*AliyunClient).ecsconn 128 129 d.Partial(true) 130 131 attributeUpdate := false 132 args := &ecs.ModifyVpcAttributeArgs{ 133 VpcId: d.Id(), 134 } 135 136 if d.HasChange("name") { 137 d.SetPartial("name") 138 args.VpcName = d.Get("name").(string) 139 140 attributeUpdate = true 141 } 142 143 if d.HasChange("description") { 144 d.SetPartial("description") 145 args.Description = d.Get("description").(string) 146 147 attributeUpdate = true 148 } 149 150 if attributeUpdate { 151 if err := conn.ModifyVpcAttribute(args); err != nil { 152 return err 153 } 154 } 155 156 d.Partial(false) 157 158 return resourceAliyunVpcRead(d, meta) 159 } 160 161 func resourceAliyunVpcDelete(d *schema.ResourceData, meta interface{}) error { 162 conn := meta.(*AliyunClient).ecsconn 163 164 return resource.Retry(5*time.Minute, func() *resource.RetryError { 165 err := conn.DeleteVpc(d.Id()) 166 167 if err != nil { 168 return resource.RetryableError(fmt.Errorf("Vpc in use - trying again while it is deleted.")) 169 } 170 171 args := &ecs.DescribeVpcsArgs{ 172 RegionId: getRegion(d, meta), 173 VpcId: d.Id(), 174 } 175 vpc, _, descErr := conn.DescribeVpcs(args) 176 if descErr != nil { 177 return resource.NonRetryableError(err) 178 } else if vpc == nil || len(vpc) < 1 { 179 return nil 180 } 181 182 return resource.RetryableError(fmt.Errorf("Vpc in use - trying again while it is deleted.")) 183 }) 184 } 185 186 func buildAliyunVpcArgs(d *schema.ResourceData, meta interface{}) (*ecs.CreateVpcArgs, error) { 187 args := &ecs.CreateVpcArgs{ 188 RegionId: getRegion(d, meta), 189 CidrBlock: d.Get("cidr_block").(string), 190 } 191 192 if v := d.Get("name").(string); v != "" { 193 args.VpcName = v 194 } 195 196 if v := d.Get("description").(string); v != "" { 197 args.Description = v 198 } 199 200 return args, nil 201 }