driftctl/pkg/driftctl.go

191 lines
5.8 KiB
Go
Raw Normal View History

package pkg
import (
"fmt"
2021-04-28 10:42:06 +00:00
"time"
2021-06-25 15:14:50 +00:00
"github.com/cloudskiff/driftctl/pkg/memstore"
2021-05-03 16:41:52 +00:00
globaloutput "github.com/cloudskiff/driftctl/pkg/output"
2021-03-29 16:10:50 +00:00
"github.com/jmespath/go-jmespath"
"github.com/sirupsen/logrus"
2020-12-16 12:02:02 +00:00
"github.com/cloudskiff/driftctl/pkg/alerter"
"github.com/cloudskiff/driftctl/pkg/analyser"
2021-04-09 11:15:16 +00:00
"github.com/cloudskiff/driftctl/pkg/cmd/scan/output"
"github.com/cloudskiff/driftctl/pkg/filter"
2021-04-09 11:15:16 +00:00
"github.com/cloudskiff/driftctl/pkg/iac/config"
"github.com/cloudskiff/driftctl/pkg/iac/terraform/state/backend"
"github.com/cloudskiff/driftctl/pkg/middlewares"
"github.com/cloudskiff/driftctl/pkg/resource"
)
2021-04-09 11:15:16 +00:00
type ScanOptions struct {
2021-04-27 16:32:03 +00:00
Coverage bool
Detect bool
From []config.SupplierConfig
To string
2021-07-21 15:57:05 +00:00
Output []output.OutputConfig
2021-04-27 16:32:03 +00:00
Filter *jmespath.JMESPath
Quiet bool
BackendOptions *backend.Options
StrictMode bool
DisableTelemetry bool
ProviderVersion string
ConfigDir string
2021-06-17 13:39:31 +00:00
DriftignorePath string
2021-06-11 15:10:06 +00:00
Deep bool
2021-04-09 11:15:16 +00:00
}
type DriftCTL struct {
2021-04-29 10:32:02 +00:00
remoteSupplier resource.Supplier
iacSupplier resource.Supplier
alerter alerter.AlerterInterface
2021-07-26 09:17:32 +00:00
analyzer *analyser.Analyzer
2021-04-29 10:32:02 +00:00
resourceFactory resource.ResourceFactory
2021-05-03 16:41:52 +00:00
scanProgress globaloutput.Progress
iacProgress globaloutput.Progress
2021-04-29 10:32:02 +00:00
resourceSchemaRepository resource.SchemaRepositoryInterface
2021-06-17 13:39:31 +00:00
opts *ScanOptions
2021-06-28 12:39:14 +00:00
store memstore.Store
}
func NewDriftCTL(remoteSupplier resource.Supplier,
iacSupplier resource.Supplier,
alerter *alerter.Alerter,
2021-07-26 09:17:32 +00:00
analyzer *analyser.Analyzer,
resFactory resource.ResourceFactory,
opts *ScanOptions,
scanProgress globaloutput.Progress,
iacProgress globaloutput.Progress,
2021-06-25 15:14:50 +00:00
resourceSchemaRepository resource.SchemaRepositoryInterface,
store memstore.Store) *DriftCTL {
2021-04-09 11:15:16 +00:00
return &DriftCTL{
remoteSupplier,
iacSupplier,
alerter,
2021-07-26 09:17:32 +00:00
analyzer,
2021-04-09 11:15:16 +00:00
resFactory,
2021-05-03 16:41:52 +00:00
scanProgress,
iacProgress,
2021-04-29 10:32:02 +00:00
resourceSchemaRepository,
2021-06-17 13:39:31 +00:00
opts,
2021-06-25 15:14:50 +00:00
store,
2021-04-09 11:15:16 +00:00
}
}
func (d DriftCTL) Run() (*analyser.Analysis, error) {
2021-04-28 10:42:06 +00:00
start := time.Now()
remoteResources, resourcesFromState, err := d.scan()
if err != nil {
2021-04-19 11:06:33 +00:00
return nil, err
}
middleware := middlewares.NewChain(
2021-05-17 15:03:10 +00:00
middlewares.NewRoute53RecordIDReconcilier(),
middlewares.NewRoute53DefaultZoneRecordSanitizer(),
middlewares.NewS3BucketAcl(),
2021-04-29 15:17:55 +00:00
middlewares.NewAwsInstanceBlockDeviceResourceMapper(d.resourceFactory),
middlewares.NewAwsDefaultSecurityGroupRule(),
middlewares.NewVPCDefaultSecurityGroupSanitizer(),
2021-03-29 16:10:50 +00:00
middlewares.NewVPCSecurityGroupRuleSanitizer(d.resourceFactory),
2021-05-21 14:09:45 +00:00
middlewares.NewIamPolicyAttachmentTransformer(d.resourceFactory),
middlewares.NewIamPolicyAttachmentExpander(d.resourceFactory),
middlewares.AwsInstanceEIP{},
2021-01-22 10:32:56 +00:00
middlewares.NewAwsDefaultInternetGatewayRoute(),
2021-01-20 21:54:41 +00:00
middlewares.NewAwsDefaultInternetGateway(),
2020-12-15 10:07:03 +00:00
middlewares.NewAwsDefaultVPC(),
middlewares.NewAwsDefaultSubnet(),
2021-03-29 16:10:50 +00:00
middlewares.NewAwsRouteTableExpander(d.alerter, d.resourceFactory),
middlewares.NewAwsDefaultRouteTable(),
middlewares.NewAwsDefaultRoute(),
middlewares.NewAwsDefaultNetworkACL(),
middlewares.NewAwsDefaultNetworkACLRule(),
middlewares.NewAwsNetworkACLExpander(d.resourceFactory),
2021-01-20 16:28:56 +00:00
middlewares.NewAwsNatGatewayEipAssoc(),
2021-03-29 16:10:50 +00:00
middlewares.NewAwsBucketPolicyExpander(d.resourceFactory),
middlewares.NewAwsSQSQueuePolicyExpander(d.resourceFactory, d.resourceSchemaRepository),
middlewares.NewAwsDefaultSQSQueuePolicy(),
2021-05-03 17:15:14 +00:00
middlewares.NewAwsSNSTopicPolicyExpander(d.resourceFactory, d.resourceSchemaRepository),
middlewares.NewAwsRoleManagedPolicyExpander(d.resourceFactory),
middlewares.NewTagsAllManager(),
2021-06-29 09:59:16 +00:00
middlewares.NewEipAssociationExpander(d.resourceFactory),
middlewares.NewRDSClusterInstanceExpander(d.resourceFactory),
2021-09-15 18:36:04 +00:00
middlewares.NewGoogleLegacyBucketIAMBindings(),
2021-10-01 08:28:16 +00:00
middlewares.NewAzurermSubnetExpander(d.resourceFactory),
2021-10-04 15:37:20 +00:00
middlewares.NewAwsApiGatewayDeploymentExpander(d.resourceFactory),
)
2021-06-17 13:39:31 +00:00
if !d.opts.StrictMode {
2021-03-29 17:01:35 +00:00
middleware = append(middleware,
middlewares.NewAwsDefaults(),
2021-03-29 17:01:35 +00:00
)
}
logrus.Debug("Ready to run middlewares")
err = middleware.Execute(&remoteResources, &resourcesFromState)
if err != nil {
2021-04-19 11:06:33 +00:00
return nil, err
}
2021-06-17 13:39:31 +00:00
if d.opts.Filter != nil {
engine := filter.NewFilterEngine(d.opts.Filter)
remoteResources, err = engine.Run(remoteResources)
if err != nil {
2021-04-19 11:06:33 +00:00
return nil, err
}
resourcesFromState, err = engine.Run(resourcesFromState)
if err != nil {
2021-04-19 11:06:33 +00:00
return nil, err
}
}
2021-07-26 09:17:32 +00:00
analysis, err := d.analyzer.Analyze(remoteResources, resourcesFromState)
if err != nil {
2021-04-19 11:06:33 +00:00
return nil, err
}
2021-06-10 13:25:54 +00:00
analysis.Duration = time.Since(start)
analysis.Date = time.Now()
2021-06-28 12:39:14 +00:00
d.store.Bucket(memstore.TelemetryBucket).Set("total_resources", analysis.Summary().TotalResources)
d.store.Bucket(memstore.TelemetryBucket).Set("total_managed", analysis.Summary().TotalManaged)
d.store.Bucket(memstore.TelemetryBucket).Set("duration", uint(analysis.Duration.Seconds()+0.5))
2021-06-25 15:14:50 +00:00
return &analysis, nil
}
func (d DriftCTL) Stop() {
stoppableSupplier, ok := d.remoteSupplier.(resource.StoppableSupplier)
if ok {
logrus.WithFields(logrus.Fields{
"supplier": fmt.Sprintf("%T", d.remoteSupplier),
}).Debug("Stopping remote supplier")
stoppableSupplier.Stop()
}
stoppableSupplier, ok = d.iacSupplier.(resource.StoppableSupplier)
if ok {
stoppableSupplier.Stop()
}
}
2021-08-09 14:03:04 +00:00
func (d DriftCTL) scan() (remoteResources []*resource.Resource, resourcesFromState []*resource.Resource, err error) {
2021-01-15 11:44:13 +00:00
logrus.Info("Start reading IaC")
2021-05-03 16:41:52 +00:00
d.iacProgress.Start()
resourcesFromState, err = d.iacSupplier.Resources()
d.iacProgress.Stop()
if err != nil {
return nil, nil, err
}
logrus.Info("Start scanning cloud provider")
2021-05-03 16:41:52 +00:00
d.scanProgress.Start()
defer d.scanProgress.Stop()
remoteResources, err = d.remoteSupplier.Resources()
if err != nil {
return nil, nil, err
}
return remoteResources, resourcesFromState, err
}