github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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  	var result []*schema.ResourceData
    54  
    55  	if len(perm.UserIdGroupPairs) == 0 {
    56  		r, err := resourceAwsSecurityGroupImportStatePermPair(sg, ruleType, perm)
    57  		if err != nil {
    58  			return nil, err
    59  		}
    60  		result = append(result, r)
    61  	} else {
    62  		// If the rule contained more than one source security group, this
    63  		// will iterate over them and create one rule for each
    64  		// source security group.
    65  		for _, pair := range perm.UserIdGroupPairs {
    66  			p := &ec2.IpPermission{
    67  				FromPort:      perm.FromPort,
    68  				IpProtocol:    perm.IpProtocol,
    69  				IpRanges:      perm.IpRanges,
    70  				PrefixListIds: perm.PrefixListIds,
    71  				ToPort:        perm.ToPort,
    72  
    73  				UserIdGroupPairs: []*ec2.UserIdGroupPair{pair},
    74  			}
    75  
    76  			r, err := resourceAwsSecurityGroupImportStatePermPair(sg, ruleType, p)
    77  			if err != nil {
    78  				return nil, err
    79  			}
    80  			result = append(result, r)
    81  		}
    82  	}
    83  	return result, nil
    84  }
    85  
    86  func resourceAwsSecurityGroupImportStatePermPair(sg *ec2.SecurityGroup, ruleType string, perm *ec2.IpPermission) (*schema.ResourceData, error) {
    87  	// Construct the rule. We do this by populating the absolute
    88  	// minimum necessary for Refresh on the rule to work. This
    89  	// happens to be a lot of fields since they're almost all needed
    90  	// for de-dupping.
    91  	sgId := sg.GroupId
    92  	id := ipPermissionIDHash(*sgId, ruleType, perm)
    93  	ruleResource := resourceAwsSecurityGroupRule()
    94  	d := ruleResource.Data(nil)
    95  	d.SetId(id)
    96  	d.SetType("aws_security_group_rule")
    97  	d.Set("security_group_id", sgId)
    98  	d.Set("type", ruleType)
    99  
   100  	// 'self' is false by default. Below, we range over the group ids and set true
   101  	// if the parent sg id is found
   102  	d.Set("self", false)
   103  
   104  	if len(perm.UserIdGroupPairs) > 0 {
   105  		s := perm.UserIdGroupPairs[0]
   106  
   107  		// Check for Pair that is the same as the Security Group, to denote self.
   108  		// Otherwise, mark the group id in source_security_group_id
   109  		isVPC := sg.VpcId != nil && *sg.VpcId != ""
   110  		if isVPC {
   111  			if *s.GroupId == *sg.GroupId {
   112  				d.Set("self", true)
   113  				// prune the self reference from the UserIdGroupPairs, so we don't
   114  				// have duplicate sg ids (both self and in source_security_group_id)
   115  				perm.UserIdGroupPairs = append(perm.UserIdGroupPairs[:0], perm.UserIdGroupPairs[0+1:]...)
   116  			}
   117  		} else {
   118  			if *s.GroupName == *sg.GroupName {
   119  				d.Set("self", true)
   120  				// prune the self reference from the UserIdGroupPairs, so we don't
   121  				// have duplicate sg ids (both self and in source_security_group_id)
   122  				perm.UserIdGroupPairs = append(perm.UserIdGroupPairs[:0], perm.UserIdGroupPairs[0+1:]...)
   123  			}
   124  		}
   125  	}
   126  
   127  	if err := setFromIPPerm(d, sg, perm); err != nil {
   128  		return nil, errwrap.Wrapf("Error importing AWS Security Group: {{err}}", err)
   129  	}
   130  
   131  	return d, nil
   132  }