Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fea: transform alert from enum lib into diagnostic #1579

Merged
merged 2 commits into from
Aug 18, 2022
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
15 changes: 14 additions & 1 deletion enumeration/alerter/alert.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package alerter

import "encoding/json"
import (
"encoding/json"

"github.com/snyk/driftctl/enumeration/resource"
)

type Alerts map[string][]Alert

type Alert interface {
Message() string
ShouldIgnoreResource() bool
Resource() *resource.Resource
}

type FakeAlert struct {
Expand All @@ -22,6 +27,10 @@ func (f *FakeAlert) ShouldIgnoreResource() bool {
return f.IgnoreResource
}

func (f *FakeAlert) Resource() *resource.Resource {
eliecharra marked this conversation as resolved.
Show resolved Hide resolved
return nil
}

type SerializableAlert struct {
Alert
}
Expand All @@ -38,6 +47,10 @@ func (u *SerializedAlert) ShouldIgnoreResource() bool {
return false
}

func (s *SerializedAlert) Resource() *resource.Resource {
return nil
}

func (s *SerializableAlert) UnmarshalJSON(bytes []byte) error {
var res SerializedAlert

Expand Down
12 changes: 0 additions & 12 deletions enumeration/diagnostic.go

This file was deleted.

54 changes: 54 additions & 0 deletions enumeration/diagnostic/diagnostic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package diagnostic

import (
"github.com/snyk/driftctl/enumeration/alerter"
"github.com/snyk/driftctl/enumeration/remote/alerts"
"github.com/snyk/driftctl/enumeration/resource"
)

type Diagnostic interface {
Code() string
Message() string
ResourceType() string
Resource() *resource.Resource
}

type diagnosticImpl struct {
alert alerter.Alert
}

func (d *diagnosticImpl) Code() string {
if _, ok := d.alert.(*alerts.RemoteAccessDeniedAlert); ok {
return "ACCESS_DENIED"
}
return "UNKNOWN_ERROR"
}

func (d *diagnosticImpl) Message() string {
return d.alert.Message()
}

func (d *diagnosticImpl) ResourceType() string {
ty := ""
if d.Resource() != nil {
ty = d.Resource().ResourceType()
}
return ty
}

func (d *diagnosticImpl) Resource() *resource.Resource {
return d.alert.Resource()
}

type Diagnostics []Diagnostic

func FromAlerts(alertMap alerter.Alerts) Diagnostics {
var results Diagnostics
for _, v := range alertMap {
for _, alert := range v {
diag := &diagnosticImpl{alert}
results = append(results, diag)
}
}
return results
}
3 changes: 2 additions & 1 deletion enumeration/enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package enumeration
import (
"time"

"github.com/snyk/driftctl/enumeration/diagnostic"
"github.com/snyk/driftctl/enumeration/resource"
)

Expand All @@ -24,7 +25,7 @@ type EnumerateOutput struct {
// If the diagnostic is associated with a resource type, the ResourceType()
// call will indicate which type. If associated with a resource, the Resource()
// call will indicate which resource.
Diagnostics Diagnostics
Diagnostics diagnostic.Diagnostics
}

type Enumerator interface {
Expand Down
43 changes: 36 additions & 7 deletions enumeration/enumerator/cloud_enumerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import (
"os"
"sync"

"github.com/snyk/driftctl/enumeration"

"github.com/sirupsen/logrus"
"github.com/snyk/driftctl/enumeration"
"github.com/snyk/driftctl/enumeration/alerter"
"github.com/snyk/driftctl/enumeration/diagnostic"
"github.com/snyk/driftctl/enumeration/parallel"
"github.com/snyk/driftctl/enumeration/remote"
"github.com/snyk/driftctl/enumeration/remote/common"
Expand All @@ -27,6 +27,11 @@ type CloudEnumerator struct {
to string
}

type ListOutput struct {
Resources []*resource.Resource
Diagnostics diagnostic.Diagnostics
}

type cloudEnumeratorBuilder struct {
cloud string
providerVersion string
Expand Down Expand Up @@ -58,7 +63,7 @@ func (b *cloudEnumeratorBuilder) Build() (*CloudEnumerator, error) {
detailsFetcherRunner: parallel.NewParallelRunner(context.TODO(), 10),
providerLibrary: terraform.NewProviderLibrary(),
remoteLibrary: common.NewRemoteLibrary(),
alerter: &sliceAlerter{},
alerter: newSliceAlerter(),
progress: &dummyCounter{},
}

Expand Down Expand Up @@ -92,6 +97,9 @@ func (e *CloudEnumerator) init(to, providerVersion, configDirectory string) erro
}

func (e *CloudEnumerator) Enumerate(input *enumeration.EnumerateInput) (*enumeration.EnumerateOutput, error) {

e.alerter.alerts = alerter.Alerts{}

types := map[string]struct{}{}
for _, resourceType := range input.ResourceTypes {
types[resourceType] = struct{}{}
Expand Down Expand Up @@ -135,14 +143,19 @@ func (e *CloudEnumerator) Enumerate(input *enumeration.EnumerateInput) (*enumera

mapRes := mapByType(results)

diagnostics := diagnostic.FromAlerts(e.alerter.Alerts())

return &enumeration.EnumerateOutput{
Resources: mapRes,
Timings: nil,
Diagnostics: nil,
Diagnostics: diagnostics,
}, nil
}

func (e *CloudEnumerator) Refresh(input *enumeration.RefreshInput) (*enumeration.RefreshOutput, error) {

e.alerter.alerts = alerter.Alerts{}

for _, resByType := range input.Resources {
for _, res := range resByType {
res := res
Expand Down Expand Up @@ -170,10 +183,11 @@ func (e *CloudEnumerator) Refresh(input *enumeration.RefreshInput) (*enumeration
}

mapRes := mapByType(results)
diagnostics := diagnostic.FromAlerts(e.alerter.Alerts())

return &enumeration.RefreshOutput{
Resources: mapRes,
Diagnostics: nil,
Diagnostics: diagnostics,
}, nil
}

Expand Down Expand Up @@ -203,26 +217,41 @@ loop:
return results, runner.Err()
}

func (e *CloudEnumerator) List(typ string) ([]*resource.Resource, error) {
func (e *CloudEnumerator) List(typ string) (*ListOutput, error) {

diagnostics := diagnostic.Diagnostics{}

enumInput := &enumeration.EnumerateInput{ResourceTypes: []string{typ}}
enumerate, err := e.Enumerate(enumInput)
if err != nil {
return nil, err
}
diagnostics = append(diagnostics, enumerate.Diagnostics...)

refreshInput := &enumeration.RefreshInput{Resources: enumerate.Resources}
refresh, err := e.Refresh(refreshInput)
if err != nil {
return nil, err
}
return refresh.Resources[typ], nil
diagnostics = append(diagnostics, refresh.Diagnostics...)

return &ListOutput{
Resources: refresh.Resources[typ],
Diagnostics: diagnostics,
}, nil
}

type sliceAlerter struct {
lock sync.Mutex
alerts alerter.Alerts
}

func newSliceAlerter() *sliceAlerter {
return &sliceAlerter{
alerts: alerter.Alerts{},
}
}

func (d *sliceAlerter) Alerts() alerter.Alerts {
return d.alerts
}
Expand Down
3 changes: 2 additions & 1 deletion enumeration/refresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package enumeration

import (
"github.com/hashicorp/terraform/terraform"
"github.com/snyk/driftctl/enumeration/diagnostic"
"github.com/snyk/driftctl/enumeration/resource"
)

Expand All @@ -12,7 +13,7 @@ type RefreshInput struct {

type RefreshOutput struct {
Resources map[string][]*resource.Resource
Diagnostics Diagnostics
Diagnostics diagnostic.Diagnostics
}

type GetSchemasOutput struct {
Expand Down
25 changes: 21 additions & 4 deletions enumeration/remote/alerts/alerts.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package alerts

import (
"fmt"
"strings"

"github.com/snyk/driftctl/enumeration/alerter"
"github.com/snyk/driftctl/enumeration/remote/common"
remoteerror "github.com/snyk/driftctl/enumeration/remote/error"
"github.com/snyk/driftctl/enumeration/resource"

"github.com/sirupsen/logrus"
)
Expand All @@ -21,33 +23,44 @@ type RemoteAccessDeniedAlert struct {
message string
provider string
scanningPhase ScanningPhase
resource *resource.Resource
}

func NewRemoteAccessDeniedAlert(provider string, scanErr *remoteerror.ResourceScanningError, scanningPhase ScanningPhase) *RemoteAccessDeniedAlert {
var message string
switch scanningPhase {
case EnumerationPhase:
message = fmt.Sprintf(
"Ignoring %s from drift calculation: Listing %s is forbidden: %s",
"An error occured listing %s: listing %s is forbidden: %s",
scanErr.Resource(),
scanErr.ListedTypeError(),
scanErr.RootCause().Error(),
)
case DetailsFetchingPhase:
message = fmt.Sprintf(
"Ignoring %s from drift calculation: Reading details of %s is forbidden: %s",
"An error occured listing %s: reading details of %s is forbidden: %s",
scanErr.Resource(),
scanErr.ListedTypeError(),
scanErr.RootCause().Error(),
)
default:
message = fmt.Sprintf(
"Ignoring %s from drift calculation: %s",
"An error occured listing %s: %s",
scanErr.Resource(),
scanErr.RootCause().Error(),
)
}
return &RemoteAccessDeniedAlert{message, provider, scanningPhase}

var relatedResource *resource.Resource
resourceFQDNSSplit := strings.SplitN(scanErr.Resource(), ".", 2)
if len(resourceFQDNSSplit) == 2 {
relatedResource = &resource.Resource{
Id: resourceFQDNSSplit[1],
Type: resourceFQDNSSplit[0],
}
}

return &RemoteAccessDeniedAlert{message, provider, scanningPhase, relatedResource}
}

func (e *RemoteAccessDeniedAlert) Message() string {
Expand All @@ -58,6 +71,10 @@ func (e *RemoteAccessDeniedAlert) ShouldIgnoreResource() bool {
return true
}

func (e *RemoteAccessDeniedAlert) Resource() *resource.Resource {
return e.resource
}

func (e *RemoteAccessDeniedAlert) GetProviderMessage() string {
var message string
if e.scanningPhase == DetailsFetchingPhase {
Expand Down
4 changes: 4 additions & 0 deletions enumeration/remote/aws/sns_topic_subscription_enumerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ func (p *wrongArnTopicAlert) ShouldIgnoreResource() bool {
return false
}

func (p *wrongArnTopicAlert) Resource() *resource.Resource {
return nil
}

type SNSTopicSubscriptionEnumerator struct {
repository repository.SNSRepository
factory resource.ResourceFactory
Expand Down
8 changes: 8 additions & 0 deletions pkg/analyser/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ func (u *UnmanagedSecurityGroupRulesAlert) ShouldIgnoreResource() bool {
return false
}

func (u *UnmanagedSecurityGroupRulesAlert) Resource() *resource.Resource {
return nil
}

type ComputedDiffAlert struct{}

func NewComputedDiffAlert() *ComputedDiffAlert {
Expand All @@ -37,6 +41,10 @@ func (c *ComputedDiffAlert) ShouldIgnoreResource() bool {
return false
}

func (c *ComputedDiffAlert) Resource() *resource.Resource {
return nil
}

type AnalyzerOptions struct {
Deep bool `json:"deep"`
OnlyManaged bool `json:"only_managed"`
Expand Down
6 changes: 3 additions & 3 deletions pkg/cmd/scan/output/testdata/output.html
Original file line number Diff line number Diff line change
Expand Up @@ -681,17 +681,17 @@ <h2>Jun 10, 2021</h2>

<li data-kind="resource-alerts" class="resource-item">

<span>Ignoring aws_vpc from drift calculation: Listing aws_vpc is forbidden: dummy error</span>
<span>An error occured listing aws_vpc: listing aws_vpc is forbidden: dummy error</span>
</li>

<li data-kind="resource-alerts" class="resource-item">

<span>Ignoring aws_sqs from drift calculation: Listing aws_sqs is forbidden: dummy error</span>
<span>An error occured listing aws_sqs: listing aws_sqs is forbidden: dummy error</span>
</li>

<li data-kind="resource-alerts" class="resource-item">

<span>Ignoring aws_sns from drift calculation: Listing aws_sns is forbidden: dummy error</span>
<span>An error occured listing aws_sns: listing aws_sns is forbidden: dummy error</span>
</li>


Expand Down
Loading