Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions pkg/driftctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type ScanOptions struct {

type DriftCTL struct {
remoteSupplier resource.Supplier
iacSupplier resource.Supplier
iacSupplier resource.IaCSupplier
alerter alerter.AlerterInterface
analyzer *analyser.Analyzer
resourceFactory resource.ResourceFactory
Expand All @@ -50,7 +50,7 @@ type DriftCTL struct {
}

func NewDriftCTL(remoteSupplier resource.Supplier,
iacSupplier resource.Supplier,
iacSupplier resource.IaCSupplier,
alerter *alerter.Alerter,
analyzer *analyser.Analyzer,
resFactory resource.ResourceFactory,
Expand Down Expand Up @@ -189,6 +189,7 @@ func (d DriftCTL) scan() (remoteResources []*resource.Resource, resourcesFromSta
if err != nil {
return nil, nil, err
}
d.store.Bucket(memstore.TelemetryBucket).Set("iac_source_count", d.iacSupplier.SourceCount())

logrus.Info("Start scanning cloud provider")
d.scanProgress.Start()
Expand Down
13 changes: 12 additions & 1 deletion pkg/driftctl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ func runTest(t *testing.T, cases TestCases) {
res.Sch = schema
}

stateSupplier := &resource.MockSupplier{}
stateSupplier := &resource.MockIaCSupplier{}
stateSupplier.On("Resources").Return(c.stateResources, nil)
stateSupplier.On("SourceCount").Return(uint(2))

if c.remoteResources == nil {
c.remoteResources = []*resource.Resource{}
Expand Down Expand Up @@ -138,6 +139,7 @@ func TestDriftctlRun_BasicBehavior(t *testing.T) {
assert.Equal(t, 0, store.Bucket(memstore.TelemetryBucket).Get("total_resources"))
assert.Equal(t, 0, store.Bucket(memstore.TelemetryBucket).Get("total_managed"))
assert.Equal(t, uint(0), store.Bucket(memstore.TelemetryBucket).Get("duration"))
assert.Equal(t, uint(2), store.Bucket(memstore.TelemetryBucket).Get("iac_source_count"))
},
},
{
Expand All @@ -155,6 +157,7 @@ func TestDriftctlRun_BasicBehavior(t *testing.T) {
assert.Equal(t, 1, store.Bucket(memstore.TelemetryBucket).Get("total_resources"))
assert.Equal(t, 1, store.Bucket(memstore.TelemetryBucket).Get("total_managed"))
assert.Equal(t, uint(0), store.Bucket(memstore.TelemetryBucket).Get("duration"))
assert.Equal(t, uint(2), store.Bucket(memstore.TelemetryBucket).Get("iac_source_count"))
},
options: func(t *testing.T) *pkg.ScanOptions {
return &pkg.ScanOptions{Deep: true}
Expand All @@ -173,6 +176,7 @@ func TestDriftctlRun_BasicBehavior(t *testing.T) {
assert.Equal(t, 1, store.Bucket(memstore.TelemetryBucket).Get("total_resources"))
assert.Equal(t, 0, store.Bucket(memstore.TelemetryBucket).Get("total_managed"))
assert.Equal(t, uint(0), store.Bucket(memstore.TelemetryBucket).Get("duration"))
assert.Equal(t, uint(2), store.Bucket(memstore.TelemetryBucket).Get("iac_source_count"))
},
},
{
Expand Down Expand Up @@ -226,6 +230,7 @@ func TestDriftctlRun_BasicBehavior(t *testing.T) {
assert.Equal(t, 1, store.Bucket(memstore.TelemetryBucket).Get("total_resources"))
assert.Equal(t, 1, store.Bucket(memstore.TelemetryBucket).Get("total_managed"))
assert.Equal(t, uint(0), store.Bucket(memstore.TelemetryBucket).Get("duration"))
assert.Equal(t, uint(2), store.Bucket(memstore.TelemetryBucket).Get("iac_source_count"))
},
},
{
Expand Down Expand Up @@ -264,6 +269,7 @@ func TestDriftctlRun_BasicBehavior(t *testing.T) {
assert.Equal(t, 1, store.Bucket(memstore.TelemetryBucket).Get("total_resources"))
assert.Equal(t, 1, store.Bucket(memstore.TelemetryBucket).Get("total_managed"))
assert.Equal(t, uint(0), store.Bucket(memstore.TelemetryBucket).Get("duration"))
assert.Equal(t, uint(2), store.Bucket(memstore.TelemetryBucket).Get("iac_source_count"))
},
},
{
Expand Down Expand Up @@ -304,6 +310,7 @@ func TestDriftctlRun_BasicBehavior(t *testing.T) {
assert.Equal(t, 1, store.Bucket(memstore.TelemetryBucket).Get("total_resources"))
assert.Equal(t, 1, store.Bucket(memstore.TelemetryBucket).Get("total_managed"))
assert.Equal(t, uint(0), store.Bucket(memstore.TelemetryBucket).Get("duration"))
assert.Equal(t, uint(2), store.Bucket(memstore.TelemetryBucket).Get("iac_source_count"))
},
},
{
Expand Down Expand Up @@ -344,6 +351,7 @@ func TestDriftctlRun_BasicBehavior(t *testing.T) {
assert.Equal(t, 1, store.Bucket(memstore.TelemetryBucket).Get("total_resources"))
assert.Equal(t, 1, store.Bucket(memstore.TelemetryBucket).Get("total_managed"))
assert.Equal(t, uint(0), store.Bucket(memstore.TelemetryBucket).Get("duration"))
assert.Equal(t, uint(2), store.Bucket(memstore.TelemetryBucket).Get("iac_source_count"))
},
},
{
Expand Down Expand Up @@ -434,6 +442,7 @@ func TestDriftctlRun_BasicBehavior(t *testing.T) {
assert.Equal(t, 4, store.Bucket(memstore.TelemetryBucket).Get("total_resources"))
assert.Equal(t, 2, store.Bucket(memstore.TelemetryBucket).Get("total_managed"))
assert.Equal(t, uint(0), store.Bucket(memstore.TelemetryBucket).Get("duration"))
assert.Equal(t, uint(2), store.Bucket(memstore.TelemetryBucket).Get("iac_source_count"))
},
options: func(t *testing.T) *pkg.ScanOptions {
return &pkg.ScanOptions{
Expand Down Expand Up @@ -530,6 +539,7 @@ func TestDriftctlRun_BasicBehavior(t *testing.T) {
assert.Equal(t, 6, store.Bucket(memstore.TelemetryBucket).Get("total_resources"))
assert.Equal(t, 2, store.Bucket(memstore.TelemetryBucket).Get("total_managed"))
assert.Equal(t, uint(0), store.Bucket(memstore.TelemetryBucket).Get("duration"))
assert.Equal(t, uint(2), store.Bucket(memstore.TelemetryBucket).Get("iac_source_count"))
},
options: func(t *testing.T) *pkg.ScanOptions {
return &pkg.ScanOptions{
Expand Down Expand Up @@ -628,6 +638,7 @@ func TestDriftctlRun_BasicBehavior(t *testing.T) {
assert.Equal(t, 1, store.Bucket(memstore.TelemetryBucket).Get("total_resources"))
assert.Equal(t, 0, store.Bucket(memstore.TelemetryBucket).Get("total_managed"))
assert.Equal(t, uint(0), store.Bucket(memstore.TelemetryBucket).Get("duration"))
assert.Equal(t, uint(2), store.Bucket(memstore.TelemetryBucket).Get("iac_source_count"))
},
options: func(t *testing.T) *pkg.ScanOptions {
filterStr := "Id=='role-test-1'"
Expand Down
12 changes: 10 additions & 2 deletions pkg/iac/supplier/IacChainSupplier.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

type IacChainSupplier struct {
suppliers []resource.Supplier
suppliers []resource.IaCSupplier
runner *parallel.ParallelRunner
}

Expand All @@ -20,7 +20,15 @@ func NewIacChainSupplier() *IacChainSupplier {
}
}

func (r *IacChainSupplier) AddSupplier(supplier resource.Supplier) {
func (r *IacChainSupplier) SourceCount() uint {
count := uint(0)
for _, supplier := range r.suppliers {
count += supplier.SourceCount()
}
return count
}

func (r *IacChainSupplier) AddSupplier(supplier resource.IaCSupplier) {
r.suppliers = append(r.suppliers, supplier)
}

Expand Down
20 changes: 10 additions & 10 deletions pkg/iac/supplier/IacChainSupplier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ import (
func TestIacChainSupplier_Resources(t *testing.T) {
tests := []struct {
name string
initSuppliers func(suppliers *[]resource.Supplier)
initSuppliers func(suppliers *[]resource.IaCSupplier)
want []*resource.Resource
wantErr bool
}{
{
name: "All failed",
initSuppliers: func(suppliers *[]resource.Supplier) {
sup := &resource.MockSupplier{}
initSuppliers: func(suppliers *[]resource.IaCSupplier) {
sup := &resource.MockIaCSupplier{}
sup.On("Resources").Return(nil, errors.New("1"))
*suppliers = append(*suppliers, sup)

sup = &resource.MockSupplier{}
sup = &resource.MockIaCSupplier{}
sup.On("Resources").Return(nil, errors.New("2"))
*suppliers = append(*suppliers, sup)

sup = &resource.MockSupplier{}
sup = &resource.MockIaCSupplier{}
sup.On("Resources").Return(nil, errors.New("3"))
*suppliers = append(*suppliers, sup)
},
Expand All @@ -35,16 +35,16 @@ func TestIacChainSupplier_Resources(t *testing.T) {
},
{
name: "Partial failed",
initSuppliers: func(suppliers *[]resource.Supplier) {
sup := &resource.MockSupplier{}
initSuppliers: func(suppliers *[]resource.IaCSupplier) {
sup := &resource.MockIaCSupplier{}
sup.On("Resources").Return(nil, errors.New("1"))
*suppliers = append(*suppliers, sup)

sup = &resource.MockSupplier{}
sup = &resource.MockIaCSupplier{}
sup.On("Resources").Return(nil, errors.New("2"))
*suppliers = append(*suppliers, sup)

sup = &resource.MockSupplier{}
sup = &resource.MockIaCSupplier{}
sup.On("Resources").Return([]*resource.Resource{
&resource.Resource{
Id: "ID",
Expand All @@ -67,7 +67,7 @@ func TestIacChainSupplier_Resources(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := NewIacChainSupplier()
suppliers := make([]resource.Supplier, 0)
suppliers := make([]resource.IaCSupplier, 0)
tt.initSuppliers(&suppliers)

for _, supplier := range suppliers {
Expand Down
4 changes: 2 additions & 2 deletions pkg/iac/supplier/supplier.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func GetIACSupplier(configs []config.SupplierConfig,
progress output.Progress,
alerter *alerter.Alerter,
factory resource.ResourceFactory,
filter filter.Filter) (resource.Supplier, error) {
filter filter.Filter) (resource.IaCSupplier, error) {

chainSupplier := NewIacChainSupplier()
for _, config := range configs {
Expand All @@ -47,7 +47,7 @@ func GetIACSupplier(configs []config.SupplierConfig,

deserializer := resource.NewDeserializer(factory)

var supplier resource.Supplier
var supplier resource.IaCSupplier
var err error
switch config.Key {
case state.TerraformStateReaderSupplier:
Expand Down
17 changes: 16 additions & 1 deletion pkg/iac/terraform/state/terraform_state_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type TerraformStateReader struct {
progress output.Progress
filter filter.Filter
alerter *alerter.Alerter
sourceCount uint
}

func (r *TerraformStateReader) initReader() error {
Expand All @@ -49,7 +50,16 @@ func (r *TerraformStateReader) initReader() error {
}

func NewReader(config config.SupplierConfig, library *terraform.ProviderLibrary, backendOpts *backend.Options, progress output.Progress, alerter *alerter.Alerter, deserializer *resource.Deserializer, filter filter.Filter) (*TerraformStateReader, error) {
reader := TerraformStateReader{library: library, config: config, deserializer: deserializer, backendOptions: backendOpts, progress: progress, alerter: alerter, filter: filter}
reader := TerraformStateReader{
library: library,
config: config,
deserializer: deserializer,
backendOptions: backendOpts,
progress: progress,
alerter: alerter,
filter: filter,
sourceCount: 0,
}
err := reader.initReader()
if err != nil {
return nil, err
Expand Down Expand Up @@ -214,8 +224,13 @@ func (r *TerraformStateReader) Resources() ([]*resource.Resource, error) {
return r.retrieveMultiplesStates()
}

func (r *TerraformStateReader) SourceCount() uint {
return r.sourceCount
}

func (r *TerraformStateReader) retrieveForState(path string) ([]*resource.Resource, error) {
r.config.Path = path
r.sourceCount += 1
logrus.WithFields(logrus.Fields{
"path": r.config.Path,
"backend": r.config.Backend,
Expand Down
47 changes: 47 additions & 0 deletions pkg/resource/mock_IaCSupplier.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion pkg/resource/supplier.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package resource

// Resource Supplier supply the list of resource.Resource, its the front to retrieve remote resources
// Supplier supply the list of resource.Resource, it's the main interface to retrieve remote resources
type Supplier interface {
Resources() ([]*Resource, error)
}

// IaCSupplier supply the list of resource.Resource, it's the main interface to retrieve state resources
type IaCSupplier interface {
Supplier
SourceCount() uint
}

type StoppableSupplier interface {
Supplier
Stop()
Expand Down
5 changes: 5 additions & 0 deletions pkg/telemetry/telemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type telemetry struct {
TotalManaged int `json:"total_managed"`
Duration uint `json:"duration"`
ProviderName string `json:"provider_name"`
IaCSourceCount uint `json:"iac_source_count"`
}

type Telemetry struct {
Expand Down Expand Up @@ -59,6 +60,10 @@ func (te Telemetry) SendTelemetry(store memstore.Bucket) {
t.ProviderName = val
}

if val, ok := store.Get("iac_source_count").(uint); ok {
t.IaCSourceCount = val
}

body, err := json.Marshal(t)
if err != nil {
logrus.Debug(err)
Expand Down
2 changes: 2 additions & 0 deletions pkg/telemetry/telemetry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ func TestSendTelemetry(t *testing.T) {
TotalManaged: 1,
Duration: 123,
ProviderName: "aws",
IaCSourceCount: 2,
},
setStoreValues: func(s memstore.Bucket, a *analyser.Analysis) {
s.Set("total_resources", a.Summary().TotalResources)
s.Set("total_managed", a.Summary().TotalManaged)
s.Set("duration", uint(a.Duration.Seconds()+0.5))
s.Set("provider_name", "aws")
s.Set("iac_source_count", uint(2))
},
},
{
Expand Down