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)
if err != nil {
WriteAlert(alerter)
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)
if err != nil {
WriteAlert(alerter)
return err
}
@ -252,7 +250,6 @@ func scanRun(opts *pkg.ScanOptions) error {
analysis, err := ctl.Run()
if err != nil {
WriteAlert(alerter)
return err
}
@ -292,10 +289,6 @@ func scanRun(opts *pkg.ScanOptions) error {
return nil
}
func WriteAlert(alerter *alerter.Alerter) {
_ = output.NewConsole().WriteAlerts(alerter.Retrieve())
}
func parseFromFlag(from []string) ([]config.SupplierConfig, error) {
configs := make([]config.SupplierConfig, 0, len(from))

View File

@ -9,8 +9,7 @@ import (
"strings"
"github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/cloudskiff/driftctl/pkg/alerter"
remotealerts "github.com/cloudskiff/driftctl/pkg/remote/alerts"
"github.com/cloudskiff/driftctl/pkg/remote/alerts"
"github.com/fatih/color"
"github.com/mattn/go-isatty"
"github.com/r3labs/diff/v2"
@ -161,15 +160,12 @@ func (c *Console) Write(analysis *analyser.Analysis) error {
}
c.writeSummary(analysis)
return c.WriteAlerts(analysis.Alerts())
}
func (c *Console) WriteAlerts(alerts alerter.Alerts) error {
enumerationErrorMessage := ""
for _, alerts := range alerts {
for _, alert := range alerts {
for _, a := range analysis.Alerts() {
for _, alert := range a {
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()
}
}
@ -178,6 +174,7 @@ func (c *Console) WriteAlerts(alerts alerter.Alerts) error {
if enumerationErrorMessage != "" {
_, _ = fmt.Fprintf(os.Stderr, "\n%s\n", color.YellowString(enumerationErrorMessage))
}
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"
"runtime"
"github.com/cloudskiff/driftctl/pkg/iac"
"github.com/cloudskiff/driftctl/pkg/parallel"
"github.com/cloudskiff/driftctl/pkg/resource"
"github.com/pkg/errors"
)
type IacChainSupplier struct {
@ -16,7 +16,6 @@ type IacChainSupplier struct {
func NewIacChainSupplier() *IacChainSupplier {
return &IacChainSupplier{
suppliers: []resource.Supplier{},
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)
}
func (r *IacChainSupplier) CountSuppliers() int {
return len(r.suppliers)
}
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 {
sup := supplier
r.runner.Run(func() (interface{}, error) {
@ -44,7 +35,8 @@ func (r *IacChainSupplier) Resources() ([]*resource.Resource, error) {
}
results := make([]*resource.Resource, 0)
nbErrors := 0
isSuccess := false
retrieveError := iac.NewStateReadingError()
ReadLoop:
for {
select {
@ -57,10 +49,10 @@ ReadLoop:
result, _ := supplierResult.(*result)
if result.err != nil {
nbErrors++
retrieveError.Add(result.err)
continue
}
isSuccess = true
results = append(results, result.res...)
case <-r.runner.DoneChan():
break ReadLoop
@ -71,9 +63,9 @@ ReadLoop:
return nil, r.runner.Err()
}
if nbErrors == len(r.suppliers) {
if !isSuccess {
// 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

View File

@ -12,7 +12,7 @@ func NewStateReadingAlert(key string, err error) *StateReadingAlert {
}
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 {

View File

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

View File

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

View File

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

View File

@ -6,6 +6,7 @@ import (
"github.com/cloudskiff/driftctl/pkg/alerter"
"github.com/cloudskiff/driftctl/pkg/filter"
"github.com/cloudskiff/driftctl/pkg/iac"
"github.com/cloudskiff/driftctl/pkg/output"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/states"
@ -222,16 +223,17 @@ func (r *TerraformStateReader) retrieveForState(path string) ([]*resource.Resour
r.progress.Inc()
values, err := r.retrieve()
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) {
keys, err := r.enumerator.Enumerate()
if err != nil {
r.alerter.SendAlert("", NewStateReadingAlert(r.enumerator.Path(), err))
return nil, err
r.alerter.SendAlert("", NewStateReadingAlert(r.enumerator.Origin(), err))
return nil, errors.Wrap(err, r.config.String())
}
logrus.WithFields(logrus.Fields{
@ -239,21 +241,23 @@ func (r *TerraformStateReader) retrieveMultiplesStates() ([]*resource.Resource,
}).Debug("Enumerated keys")
results := make([]*resource.Resource, 0)
nbAlert := 0
isSuccess := false
readingError := iac.NewStateReadingError()
for _, key := range keys {
resources, err := r.retrieveForState(key)
if err != nil {
readingError.Add(err)
r.alerter.SendAlert("", NewStateReadingAlert(key, err))
nbAlert++
continue
}
isSuccess = true
results = append(results, resources...)
}
if nbAlert == len(keys) {
if !isSuccess {
// 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