minor fixes, remove writealert. save reading alert in batch

main
Martin Guibert 2021-09-15 21:39:11 +02:00
parent 6fd9986cbc
commit a8918f7df1
9 changed files with 58 additions and 45 deletions

View File

@ -209,7 +209,6 @@ func scanRun(opts *pkg.ScanOptions) error {
err := remote.Activate(opts.To, opts.ProviderVersion, alerter, providerLibrary, remoteLibrary, scanProgress, resourceSchemaRepository, resFactory, opts.ConfigDir) err := remote.Activate(opts.To, opts.ProviderVersion, alerter, providerLibrary, remoteLibrary, scanProgress, resourceSchemaRepository, resFactory, opts.ConfigDir)
if err != nil { if err != nil {
WriteAlert(alerter)
return err return err
} }
@ -227,7 +226,6 @@ func scanRun(opts *pkg.ScanOptions) error {
iacSupplier, err := supplier.GetIACSupplier(opts.From, providerLibrary, opts.BackendOptions, iacProgress, alerter, resFactory, driftIgnore) iacSupplier, err := supplier.GetIACSupplier(opts.From, providerLibrary, opts.BackendOptions, iacProgress, alerter, resFactory, driftIgnore)
if err != nil { if err != nil {
WriteAlert(alerter)
return err return err
} }
@ -252,7 +250,6 @@ func scanRun(opts *pkg.ScanOptions) error {
analysis, err := ctl.Run() analysis, err := ctl.Run()
if err != nil { if err != nil {
WriteAlert(alerter)
return err return err
} }
@ -292,10 +289,6 @@ func scanRun(opts *pkg.ScanOptions) error {
return nil return nil
} }
func WriteAlert(alerter *alerter.Alerter) {
_ = output.NewConsole().WriteAlerts(alerter.Retrieve())
}
func parseFromFlag(from []string) ([]config.SupplierConfig, error) { func parseFromFlag(from []string) ([]config.SupplierConfig, error) {
configs := make([]config.SupplierConfig, 0, len(from)) configs := make([]config.SupplierConfig, 0, len(from))

View File

@ -9,8 +9,7 @@ import (
"strings" "strings"
"github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/cloudskiff/driftctl/pkg/alerter" "github.com/cloudskiff/driftctl/pkg/remote/alerts"
remotealerts "github.com/cloudskiff/driftctl/pkg/remote/alerts"
"github.com/fatih/color" "github.com/fatih/color"
"github.com/mattn/go-isatty" "github.com/mattn/go-isatty"
"github.com/r3labs/diff/v2" "github.com/r3labs/diff/v2"
@ -161,15 +160,12 @@ func (c *Console) Write(analysis *analyser.Analysis) error {
} }
c.writeSummary(analysis) c.writeSummary(analysis)
return c.WriteAlerts(analysis.Alerts())
}
func (c *Console) WriteAlerts(alerts alerter.Alerts) error {
enumerationErrorMessage := "" enumerationErrorMessage := ""
for _, alerts := range alerts { for _, a := range analysis.Alerts() {
for _, alert := range alerts { for _, alert := range a {
fmt.Println(color.YellowString(alert.Message())) fmt.Println(color.YellowString(alert.Message()))
if alert, ok := alert.(*remotealerts.RemoteAccessDeniedAlert); ok && enumerationErrorMessage == "" { if alert, ok := alert.(*alerts.RemoteAccessDeniedAlert); ok && enumerationErrorMessage == "" {
enumerationErrorMessage = alert.GetProviderMessage() enumerationErrorMessage = alert.GetProviderMessage()
} }
} }
@ -178,6 +174,7 @@ func (c *Console) WriteAlerts(alerts alerter.Alerts) error {
if enumerationErrorMessage != "" { if enumerationErrorMessage != "" {
_, _ = fmt.Fprintf(os.Stderr, "\n%s\n", color.YellowString(enumerationErrorMessage)) _, _ = fmt.Fprintf(os.Stderr, "\n%s\n", color.YellowString(enumerationErrorMessage))
} }
return nil return nil
} }

27
pkg/iac/errors.go Normal file
View File

@ -0,0 +1,27 @@
package iac
import (
"fmt"
"strings"
)
type StateReadingError struct {
errors []error
}
func NewStateReadingError() *StateReadingError {
return &StateReadingError{}
}
func (s *StateReadingError) Add(err error) {
s.errors = append(s.errors, err)
}
func (s *StateReadingError) Error() string {
var err strings.Builder
_, _ = fmt.Fprint(&err, "There were errors reading your states files : \n")
for _, e := range s.errors {
_, _ = fmt.Fprintf(&err, " - %s\n", e.Error())
}
return err.String()
}

View File

@ -4,9 +4,9 @@ import (
"context" "context"
"runtime" "runtime"
"github.com/cloudskiff/driftctl/pkg/iac"
"github.com/cloudskiff/driftctl/pkg/parallel" "github.com/cloudskiff/driftctl/pkg/parallel"
"github.com/cloudskiff/driftctl/pkg/resource" "github.com/cloudskiff/driftctl/pkg/resource"
"github.com/pkg/errors"
) )
type IacChainSupplier struct { type IacChainSupplier struct {
@ -16,8 +16,7 @@ type IacChainSupplier struct {
func NewIacChainSupplier() *IacChainSupplier { func NewIacChainSupplier() *IacChainSupplier {
return &IacChainSupplier{ return &IacChainSupplier{
suppliers: []resource.Supplier{}, runner: parallel.NewParallelRunner(context.TODO(), int64(runtime.NumCPU())),
runner: parallel.NewParallelRunner(context.TODO(), int64(runtime.NumCPU())),
} }
} }
@ -25,16 +24,8 @@ func (r *IacChainSupplier) AddSupplier(supplier resource.Supplier) {
r.suppliers = append(r.suppliers, supplier) r.suppliers = append(r.suppliers, supplier)
} }
func (r *IacChainSupplier) CountSuppliers() int {
return len(r.suppliers)
}
func (r *IacChainSupplier) Resources() ([]*resource.Resource, error) { func (r *IacChainSupplier) Resources() ([]*resource.Resource, error) {
if len(r.suppliers) <= 0 {
return nil, errors.New("There was an error retrieving your states check alerts for details.")
}
for _, supplier := range r.suppliers { for _, supplier := range r.suppliers {
sup := supplier sup := supplier
r.runner.Run(func() (interface{}, error) { r.runner.Run(func() (interface{}, error) {
@ -44,7 +35,8 @@ func (r *IacChainSupplier) Resources() ([]*resource.Resource, error) {
} }
results := make([]*resource.Resource, 0) results := make([]*resource.Resource, 0)
nbErrors := 0 isSuccess := false
retrieveError := iac.NewStateReadingError()
ReadLoop: ReadLoop:
for { for {
select { select {
@ -57,10 +49,10 @@ ReadLoop:
result, _ := supplierResult.(*result) result, _ := supplierResult.(*result)
if result.err != nil { if result.err != nil {
nbErrors++ retrieveError.Add(result.err)
continue continue
} }
isSuccess = true
results = append(results, result.res...) results = append(results, result.res...)
case <-r.runner.DoneChan(): case <-r.runner.DoneChan():
break ReadLoop break ReadLoop
@ -71,9 +63,9 @@ ReadLoop:
return nil, r.runner.Err() return nil, r.runner.Err()
} }
if nbErrors == len(r.suppliers) { if !isSuccess {
// only fail if all suppliers failed // only fail if all suppliers failed
return nil, errors.New("There was an error retrieving your states check alerts for details.") return nil, retrieveError
} }
return results, nil return results, nil

View File

@ -12,7 +12,7 @@ func NewStateReadingAlert(key string, err error) *StateReadingAlert {
} }
func (s *StateReadingAlert) Message() string { func (s *StateReadingAlert) Message() string {
return fmt.Sprintf("Your analysis will be incomplete. There was an error reading state file '%s': %s", s.key, s.err) return fmt.Sprintf("Your analysis may be incomplete. There was an error reading state file '%s': %s", s.key, s.err)
} }
func (s *StateReadingAlert) ShouldIgnoreResource() bool { func (s *StateReadingAlert) ShouldIgnoreResource() bool {

View File

@ -23,8 +23,8 @@ func NewFileEnumerator(config config.SupplierConfig) *FileEnumerator {
} }
} }
func (s *FileEnumerator) Path() string { func (s *FileEnumerator) Origin() string {
return s.config.Path return s.config.String()
} }
func (s *FileEnumerator) Enumerate() ([]string, error) { func (s *FileEnumerator) Enumerate() ([]string, error) {

View File

@ -33,8 +33,8 @@ func NewS3Enumerator(config config.SupplierConfig) *S3Enumerator {
} }
} }
func (s *S3Enumerator) Path() string { func (s *S3Enumerator) Origin() string {
return s.config.Path return s.config.String()
} }
func (s *S3Enumerator) Enumerate() ([]string, error) { func (s *S3Enumerator) Enumerate() ([]string, error) {

View File

@ -7,7 +7,7 @@ import (
) )
type StateEnumerator interface { type StateEnumerator interface {
Path() string Origin() string
Enumerate() ([]string, error) Enumerate() ([]string, error)
} }

View File

@ -6,6 +6,7 @@ import (
"github.com/cloudskiff/driftctl/pkg/alerter" "github.com/cloudskiff/driftctl/pkg/alerter"
"github.com/cloudskiff/driftctl/pkg/filter" "github.com/cloudskiff/driftctl/pkg/filter"
"github.com/cloudskiff/driftctl/pkg/iac"
"github.com/cloudskiff/driftctl/pkg/output" "github.com/cloudskiff/driftctl/pkg/output"
"github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states"
@ -222,16 +223,17 @@ func (r *TerraformStateReader) retrieveForState(path string) ([]*resource.Resour
r.progress.Inc() r.progress.Inc()
values, err := r.retrieve() values, err := r.retrieve()
if err != nil { if err != nil {
return nil, err return nil, errors.Wrap(err, r.config.String())
} }
return r.decode(values) decode, err := r.decode(values)
return decode, errors.Wrap(err, r.config.String())
} }
func (r *TerraformStateReader) retrieveMultiplesStates() ([]*resource.Resource, error) { func (r *TerraformStateReader) retrieveMultiplesStates() ([]*resource.Resource, error) {
keys, err := r.enumerator.Enumerate() keys, err := r.enumerator.Enumerate()
if err != nil { if err != nil {
r.alerter.SendAlert("", NewStateReadingAlert(r.enumerator.Path(), err)) r.alerter.SendAlert("", NewStateReadingAlert(r.enumerator.Origin(), err))
return nil, err return nil, errors.Wrap(err, r.config.String())
} }
logrus.WithFields(logrus.Fields{ logrus.WithFields(logrus.Fields{
@ -239,21 +241,23 @@ func (r *TerraformStateReader) retrieveMultiplesStates() ([]*resource.Resource,
}).Debug("Enumerated keys") }).Debug("Enumerated keys")
results := make([]*resource.Resource, 0) results := make([]*resource.Resource, 0)
nbAlert := 0 isSuccess := false
readingError := iac.NewStateReadingError()
for _, key := range keys { for _, key := range keys {
resources, err := r.retrieveForState(key) resources, err := r.retrieveForState(key)
if err != nil { if err != nil {
readingError.Add(err)
r.alerter.SendAlert("", NewStateReadingAlert(key, err)) r.alerter.SendAlert("", NewStateReadingAlert(key, err))
nbAlert++
continue continue
} }
isSuccess = true
results = append(results, resources...) results = append(results, resources...)
} }
if nbAlert == len(keys) { if !isSuccess {
// all key failed, throw an error // all key failed, throw an error
return results, errors.Errorf("Files were found but none of them could be read as a Terraform state.") return results, readingError
} }
return results, nil return results, nil