From db627798e613689e7fc1f4f356a362bfb696907b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 7 Jul 2016 14:06:02 -0700 Subject: [PATCH] provider/aws: Handle spurious failures in resourceAwsSecurityGroupRuleRead (#7377) Previously, any old HTTP error would be treated as the security_group_rule being deleted. In reality there are only a few cases where this is the right assumption. --- .../aws/resource_aws_security_group_rule.go | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/builtin/providers/aws/resource_aws_security_group_rule.go b/builtin/providers/aws/resource_aws_security_group_rule.go index e963ca679..d170b3d20 100644 --- a/builtin/providers/aws/resource_aws_security_group_rule.go +++ b/builtin/providers/aws/resource_aws_security_group_rule.go @@ -205,11 +205,14 @@ func resourceAwsSecurityGroupRuleRead(d *schema.ResourceData, meta interface{}) conn := meta.(*AWSClient).ec2conn sg_id := d.Get("security_group_id").(string) sg, err := findResourceSecurityGroup(conn, sg_id) - if err != nil { - log.Printf("[DEBUG] Error finding Secuirty Group (%s) for Rule (%s): %s", sg_id, d.Id(), err) + if _, notFound := err.(securityGroupNotFound); notFound { + // The security group containing this rule no longer exists. d.SetId("") return nil } + if err != nil { + return fmt.Errorf("Error finding security group (%s) for rule (%s): %s", sg_id, d.Id(), err) + } isVPC := sg.VpcId != nil && *sg.VpcId != "" @@ -312,19 +315,35 @@ func findResourceSecurityGroup(conn *ec2.EC2, id string) (*ec2.SecurityGroup, er GroupIds: []*string{aws.String(id)}, } resp, err := conn.DescribeSecurityGroups(req) + if err, ok := err.(awserr.Error); ok && err.Code() == "InvalidGroup.NotFound" { + return nil, securityGroupNotFound{id, nil} + } if err != nil { return nil, err } - - if resp == nil || len(resp.SecurityGroups) != 1 || resp.SecurityGroups[0] == nil { - return nil, fmt.Errorf( - "Expected to find one security group with ID %q, got: %#v", - id, resp.SecurityGroups) + if resp == nil { + return nil, securityGroupNotFound{id, nil} + } + if len(resp.SecurityGroups) != 1 || resp.SecurityGroups[0] == nil { + return nil, securityGroupNotFound{id, resp.SecurityGroups} } return resp.SecurityGroups[0], nil } +type securityGroupNotFound struct { + id string + securityGroups []*ec2.SecurityGroup +} + +func (err securityGroupNotFound) Error() string { + if err.securityGroups == nil { + return fmt.Sprintf("No security group with ID %q", err.id) + } + return fmt.Sprintf("Expected to find one security group with ID %q, got: %#v", + err.id, err.securityGroups) +} + // ByGroupPair implements sort.Interface for []*ec2.UserIDGroupPairs based on // GroupID or GroupName field (only one should be set). type ByGroupPair []*ec2.UserIdGroupPair