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 }