driftctl/pkg/scanner.go

90 lines
2.1 KiB
Go
Raw Normal View History

package pkg
import (
"context"
"fmt"
"github.com/cloudskiff/driftctl/pkg/remote"
2021-01-15 11:44:13 +00:00
"github.com/cloudskiff/driftctl/pkg/parallel"
"github.com/sirupsen/logrus"
2020-12-16 12:02:02 +00:00
"github.com/cloudskiff/driftctl/pkg/alerter"
"github.com/cloudskiff/driftctl/pkg/resource"
)
type Scanner struct {
resourceSuppliers []resource.Supplier
2021-01-15 11:44:13 +00:00
runner *parallel.ParallelRunner
2020-12-16 12:02:02 +00:00
alerter *alerter.Alerter
}
2020-12-16 12:02:02 +00:00
func NewScanner(resourceSuppliers []resource.Supplier, alerter *alerter.Alerter) *Scanner {
return &Scanner{
resourceSuppliers: resourceSuppliers,
2021-01-15 11:44:13 +00:00
runner: parallel.NewParallelRunner(context.TODO(), 10),
2020-12-16 12:02:02 +00:00
alerter: alerter,
}
}
func (s *Scanner) Resources() ([]resource.Resource, error) {
for _, resourceProvider := range s.resourceSuppliers {
supplier := resourceProvider
s.runner.Run(func() (interface{}, error) {
res, err := supplier.Resources()
if err != nil {
err := remote.HandleResourceEnumerationError(err, s.alerter)
if err == nil {
return []resource.Resource{}, nil
}
return nil, err
}
for _, resource := range res {
logrus.WithFields(logrus.Fields{
"id": resource.TerraformId(),
"type": resource.TerraformType(),
}).Debug("Found cloud resource")
}
return res, nil
})
}
results := make([]resource.Resource, 0)
loop:
for {
select {
case resources, ok := <-s.runner.Read():
if !ok || resources == nil {
break loop
}
for _, res := range resources.([]resource.Resource) {
normalisable, ok := res.(resource.NormalizedResource)
if ok {
normalizedRes, err := normalisable.NormalizeForProvider()
if err != nil {
logrus.Errorf("Could not normalize remote for res %s: %+v", res.TerraformId(), err)
results = append(results, res)
}
if err == nil {
results = append(results, normalizedRes)
}
}
if !ok {
results = append(results, res)
}
}
case <-s.runner.DoneChan():
break loop
}
}
return results, s.runner.Err()
}
func (s *Scanner) Stop() {
logrus.Debug("Stopping scanner")
s.runner.Stop(fmt.Errorf("interrupted"))
}