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())
return resource.RetryableError(err)
})
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
}
@ -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) {

View File

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