// Security group import fans out to multiple resources due to the // security group rules. Instead of creating one resource with nested // rules, we use the best practices approach of one resource per rule. func resourceAwsSecurityGroupImportState( d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { conn := meta.(*AWSClient).ec2conn // First query the security group sgRaw, _, err := SGStateRefreshFunc(conn, d.Id())() if err != nil { return nil, err } if sgRaw == nil { return nil, fmt.Errorf("security group not found") } sg := sgRaw.(*ec2.SecurityGroup) sgId := d.Id() // Start building our results results := make([]*schema.ResourceData, 1, 1+len(sg.IpPermissions)+len(sg.IpPermissionsEgress)) results[0] = d // Construct the rules ruleResource := resourceAwsSecurityGroupRule() permMap := map[string][]*ec2.IpPermission{ "ingress": sg.IpPermissions, "egress": sg.IpPermissionsEgress, } for ruleType, perms := range permMap { for _, perm := range perms { // Construct the rule. We do this by populating the absolute // minimum necessary for Refresh on the rule to work. This // happens to be a lot of fields since they're almost all needed // for de-dupping. id := ipPermissionIDHash(sgId, ruleType, perm) d := ruleResource.Data(nil) d.SetId(id) d.SetType("aws_security_group_rule") d.Set("security_group_id", sgId) d.Set("type", ruleType) // XXX If the rule contained more than one source security group, this // will choose one of them. We actually need to create one rule for each // source security group. setFromIPPerm(d, sg, perm) results = append(results, d) } } return results, nil }
// Route table import also imports all the rules func resourceAwsRouteTableImportState( d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { conn := meta.(*AWSClient).ec2conn // First query the resource itself id := d.Id() resp, err := conn.DescribeRouteTables(&ec2.DescribeRouteTablesInput{ RouteTableIds: []*string{&id}, }) if err != nil { return nil, err } if len(resp.RouteTables) < 1 || resp.RouteTables[0] == nil { return nil, fmt.Errorf("route table %s is not found", id) } table := resp.RouteTables[0] // Start building our results results := make([]*schema.ResourceData, 1, 2+len(table.Associations)+len(table.Routes)) results[0] = d { // Construct the routes subResource := resourceAwsRoute() for _, route := range table.Routes { // Ignore the local/default route if route.GatewayId != nil && *route.GatewayId == "local" { continue } // Minimal data for route d := subResource.Data(nil) d.SetType("aws_route") d.Set("route_table_id", id) d.Set("destination_cidr_block", route.DestinationCidrBlock) d.SetId(routeIDHash(d, route)) results = append(results, d) } } { // Construct the associations subResource := resourceAwsRouteTableAssociation() for _, assoc := range table.Associations { if *assoc.Main { // Ignore continue } // Minimal data for route d := subResource.Data(nil) d.SetType("aws_route_table_association") d.Set("route_table_id", assoc.RouteTableId) d.SetId(*assoc.RouteTableAssociationId) results = append(results, d) } } { // Construct the main associations. We could do this above but // I keep this as a separate section since it is a separate resource. subResource := resourceAwsMainRouteTableAssociation() for _, assoc := range table.Associations { if !*assoc.Main { // Ignore continue } // Minimal data for route d := subResource.Data(nil) d.SetType("aws_main_route_table_association") d.Set("route_table_id", id) d.Set("vpc_id", table.VpcId) d.SetId(*assoc.RouteTableAssociationId) results = append(results, d) } } return results, nil }
// Security group import fans out to multiple resources due to the // security group rules. Instead of creating one resource with nested // rules, we use the best practices approach of one resource per rule. func resourceAwsSecurityGroupImportState( d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { conn := meta.(*AWSClient).ec2conn // First query the security group sgRaw, _, err := SGStateRefreshFunc(conn, d.Id())() if err != nil { return nil, err } if sgRaw == nil { return nil, fmt.Errorf("security group not found") } sg := sgRaw.(*ec2.SecurityGroup) sgId := d.Id() // Start building our results results := make([]*schema.ResourceData, 1, 1+len(sg.IpPermissions)+len(sg.IpPermissionsEgress)) results[0] = d // Construct the rules ruleResource := resourceAwsSecurityGroupRule() permMap := map[string][]*ec2.IpPermission{ "ingress": sg.IpPermissions, "egress": sg.IpPermissionsEgress, } for ruleType, perms := range permMap { for _, perm := range perms { // Construct the rule. We do this by populating the absolute // minimum necessary for Refresh on the rule to work. This // happens to be a lot of fields since they're almost all needed // for de-dupping. id := ipPermissionIDHash(sgId, ruleType, perm) d := ruleResource.Data(nil) d.SetId(id) d.SetType("aws_security_group_rule") d.Set("security_group_id", sgId) d.Set("type", ruleType) // 'self' is false by default. Below, we range over the group ids and set true // if the parent sg id is found d.Set("self", false) if len(perm.UserIdGroupPairs) > 0 { s := perm.UserIdGroupPairs[0] // Check for Pair that is the same as the Security Group, to denote self. // Otherwise, mark the group id in source_security_group_id isVPC := sg.VpcId != nil && *sg.VpcId != "" if isVPC { if *s.GroupId == *sg.GroupId { d.Set("self", true) // prune the self reference from the UserIdGroupPairs, so we don't // have duplicate sg ids (both self and in source_security_group_id) perm.UserIdGroupPairs = append(perm.UserIdGroupPairs[:0], perm.UserIdGroupPairs[0+1:]...) } } else { if *s.GroupName == *sg.GroupName { d.Set("self", true) // prune the self reference from the UserIdGroupPairs, so we don't // have duplicate sg ids (both self and in source_security_group_id) perm.UserIdGroupPairs = append(perm.UserIdGroupPairs[:0], perm.UserIdGroupPairs[0+1:]...) } } } // XXX If the rule contained more than one source security group, this // will choose one of them. We actually need to create one rule for each // source security group. if err := setFromIPPerm(d, sg, perm); err != nil { return nil, errwrap.Wrapf("Error importing AWS Security Group: {{err}}", err) } results = append(results, d) } } return results, nil }