github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/import_aws_security_group.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/aws/aws-sdk-go/service/ec2"
     7  	"github.com/hashicorp/errwrap"
     8  	"github.com/hashicorp/terraform/helper/schema"
     9  )
    10  
    11  // Security group import fans out to multiple resources due to the
    12  // security group rules. Instead of creating one resource with nested
    13  // rules, we use the best practices approach of one resource per rule.
    14  func resourceAwsSecurityGroupImportState(
    15  	d *schema.ResourceData,
    16  	meta interface{}) ([]*schema.ResourceData, error) {
    17  	conn := meta.(*AWSClient).ec2conn
    18  
    19  	// First query the security group
    20  	sgRaw, _, err := SGStateRefreshFunc(conn, d.Id())()
    21  	if err != nil {
    22  		return nil, err
    23  	}
    24  	if sgRaw == nil {
    25  		return nil, fmt.Errorf("security group not found")
    26  	}
    27  	sg := sgRaw.(*ec2.SecurityGroup)
    28  
    29  	// Start building our results
    30  	results := make([]*schema.ResourceData, 1,
    31  		1+len(sg.IpPermissions)+len(sg.IpPermissionsEgress))
    32  	results[0] = d
    33  
    34  	// Construct the rules
    35  	permMap := map[string][]*ec2.IpPermission{
    36  		"ingress": sg.IpPermissions,
    37  		"egress":  sg.IpPermissionsEgress,
    38  	}
    39  	for ruleType, perms := range permMap {
    40  		for _, perm := range perms {
    41  			ds, err := resourceAwsSecurityGroupImportStatePerm(sg, ruleType, perm)
    42  			if err != nil {
    43  				return nil, err
    44  			}
    45  			results = append(results, ds...)
    46  		}
    47  	}
    48  
    49  	return results, nil
    50  }
    51  
    52  func resourceAwsSecurityGroupImportStatePerm(sg *ec2.SecurityGroup, ruleType string, perm *ec2.IpPermission) ([]*schema.ResourceData, error) {
    53  	/*
    54  	   Create a seperate Security Group Rule for:
    55  	   * The collection of IpRanges (cidr_blocks)
    56  	   * The collection of Ipv6Ranges (ipv6_cidr_blocks)
    57  	   * Each individual UserIdGroupPair (source_security_group_id)
    58  
    59  	   If, for example, a security group has rules for:
    60  	   * 2 IpRanges
    61  	   * 2 Ipv6Ranges
    62  	   * 2 UserIdGroupPairs
    63  
    64  	   This would generate 4 security group rules:
    65  	   * 1 for the collection of IpRanges
    66  	   * 1 for the collection of Ipv6Ranges
    67  	   * 1 for the first UserIdGroupPair
    68  	   * 1 for the second UserIdGroupPair
    69  	*/
    70  	var result []*schema.ResourceData
    71  
    72  	if perm.IpRanges != nil {
    73  		p := &ec2.IpPermission{
    74  			FromPort:      perm.FromPort,
    75  			IpProtocol:    perm.IpProtocol,
    76  			PrefixListIds: perm.PrefixListIds,
    77  			ToPort:        perm.ToPort,
    78  			IpRanges:      perm.IpRanges,
    79  		}
    80  
    81  		r, err := resourceAwsSecurityGroupImportStatePermPair(sg, ruleType, p)
    82  		if err != nil {
    83  			return nil, err
    84  		}
    85  		result = append(result, r)
    86  	}
    87  
    88  	if perm.Ipv6Ranges != nil {
    89  		p := &ec2.IpPermission{
    90  			FromPort:      perm.FromPort,
    91  			IpProtocol:    perm.IpProtocol,
    92  			PrefixListIds: perm.PrefixListIds,
    93  			ToPort:        perm.ToPort,
    94  			Ipv6Ranges:    perm.Ipv6Ranges,
    95  		}
    96  
    97  		r, err := resourceAwsSecurityGroupImportStatePermPair(sg, ruleType, p)
    98  		if err != nil {
    99  			return nil, err
   100  		}
   101  		result = append(result, r)
   102  	}
   103  
   104  	if len(perm.UserIdGroupPairs) > 0 {
   105  		for _, pair := range perm.UserIdGroupPairs {
   106  			p := &ec2.IpPermission{
   107  				FromPort:         perm.FromPort,
   108  				IpProtocol:       perm.IpProtocol,
   109  				PrefixListIds:    perm.PrefixListIds,
   110  				ToPort:           perm.ToPort,
   111  				UserIdGroupPairs: []*ec2.UserIdGroupPair{pair},
   112  			}
   113  
   114  			r, err := resourceAwsSecurityGroupImportStatePermPair(sg, ruleType, p)
   115  			if err != nil {
   116  				return nil, err
   117  			}
   118  			result = append(result, r)
   119  		}
   120  	}
   121  	return result, nil
   122  }
   123  
   124  func resourceAwsSecurityGroupImportStatePermPair(sg *ec2.SecurityGroup, ruleType string, perm *ec2.IpPermission) (*schema.ResourceData, error) {
   125  	// Construct the rule. We do this by populating the absolute
   126  	// minimum necessary for Refresh on the rule to work. This
   127  	// happens to be a lot of fields since they're almost all needed
   128  	// for de-dupping.
   129  	sgId := sg.GroupId
   130  	id := ipPermissionIDHash(*sgId, ruleType, perm)
   131  	ruleResource := resourceAwsSecurityGroupRule()
   132  	d := ruleResource.Data(nil)
   133  	d.SetId(id)
   134  	d.SetType("aws_security_group_rule")
   135  	d.Set("security_group_id", sgId)
   136  	d.Set("type", ruleType)
   137  
   138  	// 'self' is false by default. Below, we range over the group ids and set true
   139  	// if the parent sg id is found
   140  	d.Set("self", false)
   141  
   142  	if len(perm.UserIdGroupPairs) > 0 {
   143  		s := perm.UserIdGroupPairs[0]
   144  
   145  		// Check for Pair that is the same as the Security Group, to denote self.
   146  		// Otherwise, mark the group id in source_security_group_id
   147  		isVPC := sg.VpcId != nil && *sg.VpcId != ""
   148  		if isVPC {
   149  			if *s.GroupId == *sg.GroupId {
   150  				d.Set("self", true)
   151  				// prune the self reference from the UserIdGroupPairs, so we don't
   152  				// have duplicate sg ids (both self and in source_security_group_id)
   153  				perm.UserIdGroupPairs = append(perm.UserIdGroupPairs[:0], perm.UserIdGroupPairs[0+1:]...)
   154  			}
   155  		} else {
   156  			if *s.GroupName == *sg.GroupName {
   157  				d.Set("self", true)
   158  				// prune the self reference from the UserIdGroupPairs, so we don't
   159  				// have duplicate sg ids (both self and in source_security_group_id)
   160  				perm.UserIdGroupPairs = append(perm.UserIdGroupPairs[:0], perm.UserIdGroupPairs[0+1:]...)
   161  			}
   162  		}
   163  	}
   164  
   165  	if err := setFromIPPerm(d, sg, perm); err != nil {
   166  		return nil, errwrap.Wrapf("Error importing AWS Security Group: {{err}}", err)
   167  	}
   168  
   169  	return d, nil
   170  }