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