Skip to content

Commit

Permalink
Fix panic: missing check if state is a cty null value
Browse files Browse the repository at this point in the history
  • Loading branch information
jckuester committed Jun 9, 2020
1 parent 1501a9a commit e4cf0da
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 4 deletions.
8 changes: 4 additions & 4 deletions pkg/resource/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ func (f Filter) Apply(res []awsls.Resource) []awsls.Resource {

func GetTags(r *awsls.Resource) (map[string]string, error) {
if r == nil || r.UpdatableResource == nil {
return nil, fmt.Errorf("resource is nil")
return nil, fmt.Errorf("resource is nil: %+v", r)
}

state := r.State()

if state == nil {
return nil, fmt.Errorf("state is nil")
if state == nil || state.IsNull() {
return nil, fmt.Errorf("state is nil: %+v", state)
}

if !state.CanIterateElements() {
return nil, fmt.Errorf("cannot iterate: %s", *state)
return nil, fmt.Errorf("cannot iterate: %s", state.GoString())
}

attrValue, ok := state.AsValueMap()["tags"]
Expand Down
111 changes: 111 additions & 0 deletions pkg/resource/select_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package resource_test

import (
"reflect"
"testing"
"time"

"github.com/zclconf/go-cty/cty"

"github.com/aws/aws-sdk-go/aws"
awsls "github.com/jckuester/awsls/aws"
"github.com/jckuester/awsweeper/pkg/resource"
terradozerRes "github.com/jckuester/terradozer/pkg/resource"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -409,3 +413,110 @@ func TestYamlFilter_Apply_NegatedStringFilter(t *testing.T) {
require.Len(t, result, 1)
assert.Equal(t, "select-this", result[0].ID)
}

func TestGetTags(t *testing.T) {
tests := []struct {
name string
arg *awsls.Resource
want map[string]string
wantErr string
}{
{
name: "resource is nil",
wantErr: "resource is nil: <nil>",
},
{
name: "embedded updatable resource is nil",
arg: &awsls.Resource{},
wantErr: "resource is nil: &{Type: ID: Region: Tags:map[] CreatedAt:<nil> UpdatableResource:<nil>}",
},
{
name: "state is nil",
arg: &awsls.Resource{
UpdatableResource: &terradozerRes.Resource{},
},
wantErr: "state is nil: <nil>",
},
{
name: "state is nil value",
arg: &awsls.Resource{
UpdatableResource: terradozerRes.NewWithState("aws_foo", "1234", nil, &cty.NilVal),
},
wantErr: "state is nil: &{ty:{typeImpl:<nil>} v:<nil>}",
},
{
name: "null map",
arg: &awsls.Resource{
UpdatableResource: terradozerRes.NewWithState("aws_foo", "1234",
nil, ctyValuePtr(cty.NullVal(cty.Map(cty.String)))),
},
wantErr: "state is nil: &{ty:{typeImpl:{typeImplSigil:{} ElementTypeT:{typeImpl:{typeImplSigil:{} Kind:83}}}} v:<nil>}",
},
{
name: "unhandled type",
arg: &awsls.Resource{
UpdatableResource: terradozerRes.NewWithState("aws_foo", "1234",
nil, ctyValuePtr(cty.ObjectVal(map[string]cty.Value{
"tags": cty.StringVal("foo"),
}))),
},
wantErr: "currently unhandled type: string",
},
{
name: "tags attribute not found",
arg: &awsls.Resource{
UpdatableResource: terradozerRes.NewWithState("aws_foo", "1234",
nil, ctyValuePtr(cty.ObjectVal(map[string]cty.Value{
"tag": cty.StringVal("foo"),
}))),
},
wantErr: "attribute not found: tags",
},
{
name: "cannot iterate element",
arg: &awsls.Resource{
UpdatableResource: terradozerRes.NewWithState("aws_foo", "1234",
nil, ctyValuePtr(cty.StringVal("foo"))),
},
wantErr: "cannot iterate: cty.StringVal(\"foo\")",
},
{
name: "empty map of tags",
arg: &awsls.Resource{
UpdatableResource: terradozerRes.NewWithState("aws_foo", "1234",
nil, ctyValuePtr(cty.ObjectVal(map[string]cty.Value{
"tags": cty.MapValEmpty(cty.String),
}))),
},
want: map[string]string{},
},
{
name: "some tags",
arg: &awsls.Resource{
UpdatableResource: terradozerRes.NewWithState("aws_foo", "1234",
nil, ctyValuePtr(cty.ObjectVal(map[string]cty.Value{
"tags": cty.MapVal(map[string]cty.Value{"foo": cty.StringVal("bar")}),
}))),
},
want: map[string]string{"foo": "bar"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := resource.GetTags(tt.arg)

if tt.wantErr != "" {
assert.EqualError(t, err, tt.wantErr)
} else {
require.NoError(t, err)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetTags() got = %v, want %v", got, tt.want)
}
}
})
}
}

func ctyValuePtr(v cty.Value) *cty.Value {
return &v
}

0 comments on commit e4cf0da

Please sign in to comment.