github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/alicloud/resource_alicloud_security_group_rule.go (about) 1 package alicloud 2 3 import ( 4 "fmt" 5 "github.com/denverdino/aliyungo/ecs" 6 "github.com/hashicorp/terraform/helper/resource" 7 "github.com/hashicorp/terraform/helper/schema" 8 "strings" 9 "time" 10 ) 11 12 func resourceAliyunSecurityGroupRule() *schema.Resource { 13 return &schema.Resource{ 14 Create: resourceAliyunSecurityGroupRuleCreate, 15 Read: resourceAliyunSecurityGroupRuleRead, 16 Delete: resourceAliyunSecurityGroupRuleDelete, 17 18 Schema: map[string]*schema.Schema{ 19 "type": &schema.Schema{ 20 Type: schema.TypeString, 21 Required: true, 22 ForceNew: true, 23 ValidateFunc: validateSecurityRuleType, 24 Description: "Type of rule, ingress (inbound) or egress (outbound).", 25 }, 26 27 "ip_protocol": &schema.Schema{ 28 Type: schema.TypeString, 29 Required: true, 30 ForceNew: true, 31 ValidateFunc: validateSecurityRuleIpProtocol, 32 }, 33 34 "nic_type": &schema.Schema{ 35 Type: schema.TypeString, 36 Optional: true, 37 ForceNew: true, 38 Computed: true, 39 ValidateFunc: validateSecurityRuleNicType, 40 }, 41 42 "policy": &schema.Schema{ 43 Type: schema.TypeString, 44 Optional: true, 45 ForceNew: true, 46 ValidateFunc: validateSecurityRulePolicy, 47 }, 48 49 "port_range": &schema.Schema{ 50 Type: schema.TypeString, 51 Required: true, 52 ForceNew: true, 53 }, 54 55 "priority": &schema.Schema{ 56 Type: schema.TypeInt, 57 Optional: true, 58 ForceNew: true, 59 ValidateFunc: validateSecurityPriority, 60 }, 61 62 "security_group_id": &schema.Schema{ 63 Type: schema.TypeString, 64 Required: true, 65 ForceNew: true, 66 }, 67 68 "cidr_ip": &schema.Schema{ 69 Type: schema.TypeString, 70 Optional: true, 71 ForceNew: true, 72 }, 73 74 "source_security_group_id": &schema.Schema{ 75 Type: schema.TypeString, 76 Optional: true, 77 ForceNew: true, 78 }, 79 80 "source_group_owner_account": &schema.Schema{ 81 Type: schema.TypeString, 82 Optional: true, 83 ForceNew: true, 84 }, 85 }, 86 } 87 } 88 89 func resourceAliyunSecurityGroupRuleCreate(d *schema.ResourceData, meta interface{}) error { 90 client := meta.(*AliyunClient) 91 conn := client.ecsconn 92 93 direction := d.Get("type").(string) 94 sgId := d.Get("security_group_id").(string) 95 ptl := d.Get("ip_protocol").(string) 96 port := d.Get("port_range").(string) 97 nicType := d.Get("nic_type").(string) 98 99 var autherr error 100 switch GroupRuleDirection(direction) { 101 case GroupRuleIngress: 102 args, err := buildAliyunSecurityIngressArgs(d, meta) 103 if err != nil { 104 return err 105 } 106 autherr = conn.AuthorizeSecurityGroup(args) 107 case GroupRuleEgress: 108 args, err := buildAliyunSecurityEgressArgs(d, meta) 109 if err != nil { 110 return err 111 } 112 autherr = conn.AuthorizeSecurityGroupEgress(args) 113 default: 114 return fmt.Errorf("Security Group Rule must be type 'ingress' or type 'egress'") 115 } 116 117 if autherr != nil { 118 return fmt.Errorf( 119 "Error authorizing security group rule type %s: %s", 120 direction, autherr) 121 } 122 123 d.SetId(sgId + ":" + direction + ":" + ptl + ":" + port + ":" + nicType) 124 125 return resourceAliyunSecurityGroupRuleRead(d, meta) 126 } 127 128 func resourceAliyunSecurityGroupRuleRead(d *schema.ResourceData, meta interface{}) error { 129 client := meta.(*AliyunClient) 130 parts := strings.Split(d.Id(), ":") 131 sgId := parts[0] 132 direction := parts[1] 133 ip_protocol := parts[2] 134 port_range := parts[3] 135 nic_type := parts[4] 136 rule, err := client.DescribeSecurityGroupRule(sgId, direction, nic_type, ip_protocol, port_range) 137 138 if err != nil { 139 if notFoundError(err) { 140 d.SetId("") 141 return nil 142 } 143 return fmt.Errorf("Error SecurityGroup rule: %#v", err) 144 } 145 146 d.Set("type", rule.Direction) 147 d.Set("ip_protocol", strings.ToLower(string(rule.IpProtocol))) 148 d.Set("nic_type", rule.NicType) 149 d.Set("policy", strings.ToLower(string(rule.Policy))) 150 d.Set("port_range", rule.PortRange) 151 d.Set("priority", rule.Priority) 152 d.Set("security_group_id", sgId) 153 //support source and desc by type 154 if GroupRuleDirection(direction) == GroupRuleIngress { 155 d.Set("cidr_ip", rule.SourceCidrIp) 156 d.Set("source_security_group_id", rule.SourceGroupId) 157 d.Set("source_group_owner_account", rule.SourceGroupOwnerAccount) 158 } else { 159 d.Set("cidr_ip", rule.DestCidrIp) 160 d.Set("source_security_group_id", rule.DestGroupId) 161 d.Set("source_group_owner_account", rule.DestGroupOwnerAccount) 162 } 163 164 return nil 165 } 166 167 func deleteSecurityGroupRule(d *schema.ResourceData, meta interface{}) error { 168 client := meta.(*AliyunClient) 169 ruleType := d.Get("type").(string) 170 171 if GroupRuleDirection(ruleType) == GroupRuleIngress { 172 args, err := buildAliyunSecurityIngressArgs(d, meta) 173 if err != nil { 174 return err 175 } 176 revokeArgs := &ecs.RevokeSecurityGroupArgs{ 177 AuthorizeSecurityGroupArgs: *args, 178 } 179 return client.RevokeSecurityGroup(revokeArgs) 180 } 181 182 args, err := buildAliyunSecurityEgressArgs(d, meta) 183 184 if err != nil { 185 return err 186 } 187 revokeArgs := &ecs.RevokeSecurityGroupEgressArgs{ 188 AuthorizeSecurityGroupEgressArgs: *args, 189 } 190 return client.RevokeSecurityGroupEgress(revokeArgs) 191 } 192 193 func resourceAliyunSecurityGroupRuleDelete(d *schema.ResourceData, meta interface{}) error { 194 client := meta.(*AliyunClient) 195 parts := strings.Split(d.Id(), ":") 196 sgId, direction, ip_protocol, port_range, nic_type := parts[0], parts[1], parts[2], parts[3], parts[4] 197 198 return resource.Retry(5*time.Minute, func() *resource.RetryError { 199 err := deleteSecurityGroupRule(d, meta) 200 201 if err != nil { 202 resource.RetryableError(fmt.Errorf("Security group rule in use - trying again while it is deleted.")) 203 } 204 205 _, err = client.DescribeSecurityGroupRule(sgId, direction, nic_type, ip_protocol, port_range) 206 if err != nil { 207 if notFoundError(err) { 208 return nil 209 } 210 return resource.NonRetryableError(err) 211 } 212 213 return resource.RetryableError(fmt.Errorf("Security group rule in use - trying again while it is deleted.")) 214 }) 215 216 } 217 218 func checkCidrAndSourceGroupId(cidrIp, sourceGroupId string) error { 219 if cidrIp == "" && sourceGroupId == "" { 220 return fmt.Errorf("Either cidr_ip or source_security_group_id is required.") 221 } 222 223 if cidrIp != "" && sourceGroupId != "" { 224 return fmt.Errorf("You should set only one value of cidr_ip or source_security_group_id.") 225 } 226 return nil 227 } 228 func buildAliyunSecurityIngressArgs(d *schema.ResourceData, meta interface{}) (*ecs.AuthorizeSecurityGroupArgs, error) { 229 conn := meta.(*AliyunClient).ecsconn 230 231 args := &ecs.AuthorizeSecurityGroupArgs{ 232 RegionId: getRegion(d, meta), 233 } 234 235 if v := d.Get("ip_protocol").(string); v != "" { 236 args.IpProtocol = ecs.IpProtocol(v) 237 } 238 239 if v := d.Get("port_range").(string); v != "" { 240 args.PortRange = v 241 } 242 243 if v := d.Get("policy").(string); v != "" { 244 args.Policy = ecs.PermissionPolicy(v) 245 } 246 247 if v := d.Get("priority").(int); v != 0 { 248 args.Priority = v 249 } 250 251 if v := d.Get("nic_type").(string); v != "" { 252 args.NicType = ecs.NicType(v) 253 } 254 255 cidrIp := d.Get("cidr_ip").(string) 256 sourceGroupId := d.Get("source_security_group_id").(string) 257 if err := checkCidrAndSourceGroupId(cidrIp, sourceGroupId); err != nil { 258 return nil, err 259 } 260 if cidrIp != "" { 261 args.SourceCidrIp = cidrIp 262 } 263 264 if sourceGroupId != "" { 265 args.SourceGroupId = sourceGroupId 266 } 267 268 if v := d.Get("source_group_owner_account").(string); v != "" { 269 args.SourceGroupOwnerAccount = v 270 } 271 272 sgId := d.Get("security_group_id").(string) 273 274 sgArgs := &ecs.DescribeSecurityGroupAttributeArgs{ 275 SecurityGroupId: sgId, 276 RegionId: getRegion(d, meta), 277 } 278 279 _, err := conn.DescribeSecurityGroupAttribute(sgArgs) 280 if err != nil { 281 return nil, fmt.Errorf("Error get security group %s error: %#v", sgId, err) 282 } 283 284 args.SecurityGroupId = sgId 285 286 return args, nil 287 } 288 289 func buildAliyunSecurityEgressArgs(d *schema.ResourceData, meta interface{}) (*ecs.AuthorizeSecurityGroupEgressArgs, error) { 290 conn := meta.(*AliyunClient).ecsconn 291 292 args := &ecs.AuthorizeSecurityGroupEgressArgs{ 293 RegionId: getRegion(d, meta), 294 } 295 296 if v := d.Get("ip_protocol").(string); v != "" { 297 args.IpProtocol = ecs.IpProtocol(v) 298 } 299 300 if v := d.Get("port_range").(string); v != "" { 301 args.PortRange = v 302 } 303 304 if v := d.Get("policy").(string); v != "" { 305 args.Policy = ecs.PermissionPolicy(v) 306 } 307 308 if v := d.Get("priority").(int); v != 0 { 309 args.Priority = v 310 } 311 312 if v := d.Get("nic_type").(string); v != "" { 313 args.NicType = ecs.NicType(v) 314 } 315 316 cidrIp := d.Get("cidr_ip").(string) 317 sourceGroupId := d.Get("source_security_group_id").(string) 318 if err := checkCidrAndSourceGroupId(cidrIp, sourceGroupId); err != nil { 319 return nil, err 320 } 321 if cidrIp != "" { 322 args.DestCidrIp = cidrIp 323 } 324 325 if sourceGroupId != "" { 326 args.DestGroupId = sourceGroupId 327 } 328 329 if v := d.Get("source_group_owner_account").(string); v != "" { 330 args.DestGroupOwnerAccount = v 331 } 332 333 sgId := d.Get("security_group_id").(string) 334 335 sgArgs := &ecs.DescribeSecurityGroupAttributeArgs{ 336 SecurityGroupId: sgId, 337 RegionId: getRegion(d, meta), 338 } 339 340 _, err := conn.DescribeSecurityGroupAttribute(sgArgs) 341 if err != nil { 342 return nil, fmt.Errorf("Error get security group %s error: %#v", sgId, err) 343 } 344 345 args.SecurityGroupId = sgId 346 347 return args, nil 348 }