2021-01-20 13:01:57 +00:00
package remote
import (
"fmt"
2021-02-11 11:21:49 +00:00
"strings"
2021-01-20 13:01:57 +00:00
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/cloudskiff/driftctl/pkg/alerter"
2021-03-02 10:39:14 +00:00
"github.com/cloudskiff/driftctl/pkg/remote/aws"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/remote/github"
2021-02-12 21:35:21 +00:00
"github.com/sirupsen/logrus"
2021-01-20 13:01:57 +00:00
)
2021-02-12 21:35:21 +00:00
type EnumerationAccessDeniedAlert struct {
2021-03-02 10:39:14 +00:00
message string
provider string
2021-02-12 21:35:21 +00:00
}
2021-03-02 10:39:14 +00:00
func NewEnumerationAccessDeniedAlert ( provider , supplierType , listedTypeError string ) * EnumerationAccessDeniedAlert {
2021-02-12 21:35:21 +00:00
message := fmt . Sprintf ( "Ignoring %s from drift calculation: Listing %s is forbidden." , supplierType , listedTypeError )
2021-03-02 10:39:14 +00:00
return & EnumerationAccessDeniedAlert { message , provider }
2021-02-12 21:35:21 +00:00
}
func ( e * EnumerationAccessDeniedAlert ) Message ( ) string {
return e . message
}
func ( e * EnumerationAccessDeniedAlert ) ShouldIgnoreResource ( ) bool {
return true
}
2021-03-02 10:39:14 +00:00
func ( e * EnumerationAccessDeniedAlert ) GetProviderMessage ( ) string {
message := "It seems that we got access denied exceptions while listing resources.\n"
switch e . provider {
case github . RemoteGithubTerraform :
2021-03-03 10:05:36 +00:00
message += "Please be sure that your Github token has the right permissions, check the last up-to-date documentation there: https://docs.driftctl.com/providers/github/authentication#least-privileged-policy"
2021-03-02 10:39:14 +00:00
case aws . RemoteAWSTerraform :
message += "The latest minimal read-only IAM policy for driftctl is always available here, please update yours: https://docs.driftctl.com/providers/aws/authentication#least-privileged-policy"
default :
return ""
}
return message
}
func HandleResourceEnumerationError ( err error , alerter * alerter . Alerter ) error {
2021-01-20 13:01:57 +00:00
listError , ok := err . ( * remoteerror . ResourceEnumerationError )
if ! ok {
return err
}
2021-03-02 10:39:14 +00:00
rootCause := listError . RootCause ( )
reqerr , ok := rootCause . ( awserr . RequestFailure )
if ok {
return handleAWSError ( alerter , listError , reqerr )
2021-01-20 13:01:57 +00:00
}
2021-03-02 10:39:14 +00:00
if strings . HasPrefix (
rootCause . Error ( ) ,
"Your token has not been granted the required scopes to execute this query." ,
) {
sendEnumerationAlert ( github . RemoteGithubTerraform , alerter , listError )
2021-01-20 13:01:57 +00:00
return nil
}
return err
}
2021-03-02 10:39:14 +00:00
func handleAWSError ( alerter alerter . AlerterInterface , listError * remoteerror . ResourceEnumerationError , reqerr awserr . RequestFailure ) error {
if reqerr . StatusCode ( ) == 403 || ( reqerr . StatusCode ( ) == 400 && strings . Contains ( reqerr . Code ( ) , "AccessDenied" ) ) {
sendEnumerationAlert ( aws . RemoteAWSTerraform , alerter , listError )
return nil
}
return reqerr
}
func sendEnumerationAlert ( provider string , alerter alerter . AlerterInterface , listError * remoteerror . ResourceEnumerationError ) {
logrus . WithFields ( logrus . Fields {
"supplier_type" : listError . SupplierType ( ) ,
"listed_type" : listError . ListedTypeError ( ) ,
} ) . Debugf ( "Got an access denied error" )
alerter . SendAlert ( listError . SupplierType ( ) , NewEnumerationAccessDeniedAlert ( provider , listError . SupplierType ( ) , listError . ListedTypeError ( ) ) )
}