provider/aws: Mark Lambda function as gone when it's gone (#6924)

* helper/error: Introduce TimeoutError & UnexpectedStateError

* provider/aws: Mark Lambda function as gone when it's gone
This commit is contained in:
Radek Simko 2016-06-02 00:50:43 +01:00 committed by Paul Stack
parent a8c091982a
commit bf8931b1ab
3 changed files with 69 additions and 11 deletions

View File

@ -189,7 +189,24 @@ func resourceAwsLambdaPermissionRead(d *schema.ResourceData, meta interface{}) e
statement, err = findLambdaPolicyStatementById(&policy, d.Id()) statement, err = findLambdaPolicyStatementById(&policy, d.Id())
return resource.RetryableError(err) return resource.RetryableError(err)
}) })
if err != nil { if err != nil {
// Missing whole policy or Lambda function (API error)
if awsErr, ok := err.(awserr.Error); ok {
if awsErr.Code() == "ResourceNotFoundException" {
log.Printf("[WARN] No Lambda Permission Policy found: %v", input)
d.SetId("")
return nil
}
}
// Missing permission inside valid policy
if nfErr, ok := err.(*resource.NotFoundError); ok {
log.Printf("[WARN] %s", nfErr)
d.SetId("")
return nil
}
return err return err
} }
@ -313,7 +330,11 @@ func findLambdaPolicyStatementById(policy *LambdaPolicy, id string) (
} }
} }
return nil, fmt.Errorf("Failed to find statement %q in Lambda policy:\n%s", id, policy.Statement) return nil, &resource.NotFoundError{
LastRequest: id,
LastResponse: policy,
Message: fmt.Sprintf("Failed to find statement %q in Lambda policy:\n%s", id, policy.Statement),
}
} }
func getQualifierFromLambdaAliasOrVersionArn(arn string) (string, error) { func getQualifierFromLambdaAliasOrVersionArn(arn string) (string, error) {

View File

@ -1,5 +1,10 @@
package resource package resource
import (
"fmt"
"strings"
)
type NotFoundError struct { type NotFoundError struct {
LastError error LastError error
LastRequest interface{} LastRequest interface{}
@ -15,3 +20,33 @@ func (e *NotFoundError) Error() string {
return "couldn't find resource" return "couldn't find resource"
} }
// UnexpectedStateError is returned when Refresh returns a state that's neither in Target nor Pending
type UnexpectedStateError struct {
LastError error
State string
ExpectedState []string
}
func (e *UnexpectedStateError) Error() string {
return fmt.Sprintf(
"unexpected state '%s', wanted target '%s'. last error: %s",
e.State,
strings.Join(e.ExpectedState, ", "),
e.LastError,
)
}
// TimeoutError is returned when WaitForState times out
type TimeoutError struct {
LastError error
ExpectedState []string
}
func (e *TimeoutError) Error() string {
return fmt.Sprintf(
"timeout while waiting for state to become '%s'. last error: %s",
strings.Join(e.ExpectedState, ", "),
e.LastError,
)
}

View File

@ -1,8 +1,6 @@
package resource package resource
import ( import (
"errors"
"fmt"
"log" "log"
"math" "math"
"time" "time"
@ -109,7 +107,9 @@ func (conf *StateChangeConf) WaitForState() (interface{}, error) {
// not finding it for awhile, and if so, report an error. // not finding it for awhile, and if so, report an error.
notfoundTick += 1 notfoundTick += 1
if notfoundTick > conf.NotFoundChecks { if notfoundTick > conf.NotFoundChecks {
resulterr = errors.New("couldn't find resource") resulterr = &NotFoundError{
LastError: resulterr,
}
return return
} }
} else { } else {
@ -138,10 +138,11 @@ func (conf *StateChangeConf) WaitForState() (interface{}, error) {
} }
if !found { if !found {
resulterr = fmt.Errorf( resulterr = &UnexpectedStateError{
"unexpected state '%s', wanted target '%s'", LastError: resulterr,
currentState, State: currentState,
conf.Target) ExpectedState: conf.Target,
}
return return
} }
} }
@ -152,8 +153,9 @@ func (conf *StateChangeConf) WaitForState() (interface{}, error) {
case <-doneCh: case <-doneCh:
return result, resulterr return result, resulterr
case <-time.After(conf.Timeout): case <-time.After(conf.Timeout):
return nil, fmt.Errorf( return nil, &TimeoutError{
"timeout while waiting for state to become '%s'", LastError: resulterr,
conf.Target) ExpectedState: conf.Target,
}
} }
} }