Skip to content
This repository has been archived by the owner on Aug 16, 2022. It is now read-only.

Commit

Permalink
feat: Partial lambda Function Fetch (#1194)
Browse files Browse the repository at this point in the history

#### Summary

Here is an experimental change, where we can populate some data for Lambda Functions as long as the user has access to `lambda:List*` 

Pros:
- As long as user has access to List they can get some data in the table, they will miss information `types.FunctionCodeLocation`, `types.Concurrency` and `Tags`

Cons:
- Includes information about function that could have been deleted
- Continues to try to get details as we cannot be sure if a user doesn't have access to get a specific function or all functions

---
  • Loading branch information
bbernays authored Jul 11, 2022
1 parent e0a3b4a commit f757824
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
30 changes: 27 additions & 3 deletions client/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ var notFoundErrorSubstrings = []string{
"WAFNonexistentItemException",
}

var accessDeniedErrorStrings = map[string]struct{}{
"AuthorizationError": {},
"AccessDenied": {},
"AccessDeniedException": {},
"InsufficientPrivilegesException": {},
"UnauthorizedOperation": {},
}

func readSupportedServiceRegions() *SupportedServiceRegionsData {
f, err := supportedServiceRegionFile.Open(PartitionServiceRegionFile)
if err != nil {
Expand Down Expand Up @@ -176,13 +184,11 @@ func IgnoreAccessDeniedServiceDisabled(err error) bool {
return strings.Contains(ae.Error(), "The security token included in the request is invalid")
case "AWSOrganizationsNotInUseException":
return true
case "AuthorizationError", "AccessDenied", "AccessDeniedException", "InsufficientPrivilegesException", "UnauthorizedOperation":
return true
case "OptInRequired", "SubscriptionRequiredException", "InvalidClientTokenId":
return true
}
}
return false
return isAccessDeniedError(err)
}

func IgnoreCommonErrors(err error) bool {
Expand Down Expand Up @@ -301,6 +307,24 @@ func isNotFoundError(err error) bool {
return false
}

// IsAccessDeniedError checks if api error should be classified as a permissions issue
func (c *Client) IsAccessDeniedError(err error) bool {
if isAccessDeniedError(err) {
c.logger.Warn("API returned an Access Denied error, ignoring it and continuing...", "error", err)
return true
}
return false
}

func isAccessDeniedError(err error) bool {
var ae smithy.APIError
if !errors.As(err, &ae) {
return false
}
_, ok := accessDeniedErrorStrings[ae.ErrorCode()]
return ok
}

func IsInvalidParameterValueError(err error) bool {
var apiErr smithy.APIError
return errors.As(err, &apiErr) && apiErr.ErrorCode() == "InvalidParameterValue"
Expand Down
12 changes: 9 additions & 3 deletions resources/services/lambda/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,7 @@ func Functions() *schema.Table {
// ====================================================================================================================

func fetchLambdaFunctions(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- interface{}) error {
var diags diag.Diagnostics
var input lambda.ListFunctionsInput
c := meta.(*client.Client)
svc := c.Services().Lambda
Expand All @@ -1107,11 +1108,16 @@ func fetchLambdaFunctions(ctx context.Context, meta schema.ClientMeta, parent *s
funcResponse, err := svc.GetFunction(ctx, &getFunctionInput, func(options *lambda.Options) {
options.Region = c.Region
})

if err != nil {
if c.IsNotFoundError(err) {
if c.IsNotFoundError(err) || c.IsAccessDeniedError(err) {
diags = diags.Add(diag.FromError(err, diag.RESOLVING, diag.WithSeverity(diag.WARNING)))
res <- &lambda.GetFunctionOutput{
Configuration: &f,
}
continue
}
return diag.WrapError(err)
return diags.Add(diag.FromError(diag.WrapError(err), diag.RESOLVING, diag.WithSeverity(diag.ERROR)))
}
res <- funcResponse
}
Expand All @@ -1121,7 +1127,7 @@ func fetchLambdaFunctions(ctx context.Context, meta schema.ClientMeta, parent *s
}
input.Marker = response.NextMarker
}
return nil
return diags
}
func resolvePolicyCodeSigningConfig(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource) error {
r := resource.Item.(*lambda.GetFunctionOutput)
Expand Down

0 comments on commit f757824

Please sign in to comment.