diff --git a/owner.go b/owner.go index 3e5bfaa..a300a30 100644 --- a/owner.go +++ b/owner.go @@ -6,12 +6,13 @@ import ( "github.com/aquasecurity/trivy/pkg/iac/terraform" tfcontext "github.com/aquasecurity/trivy/pkg/iac/terraform/context" "github.com/zclconf/go-cty/cty" + "golang.org/x/xerrors" ) -func workspaceOwnerHook(dfs fs.FS, input Input) (func(ctx *tfcontext.Context, blocks terraform.Blocks, inputVars map[string]cty.Value), error) { +func workspaceOwnerHook(_ fs.FS, input Input) (func(ctx *tfcontext.Context, blocks terraform.Blocks, inputVars map[string]cty.Value), error) { ownerValue, err := input.Owner.ToCtyValue() if err != nil { - return nil, err + return nil, xerrors.Errorf("failed to convert owner value", err) } return func(ctx *tfcontext.Context, blocks terraform.Blocks, inputVars map[string]cty.Value) { diff --git a/types/owner.go b/types/owner.go index 2676091..e714d5f 100644 --- a/types/owner.go +++ b/types/owner.go @@ -1,81 +1,62 @@ package types import ( - "github.com/google/uuid" "github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty/gocty" + "golang.org/x/xerrors" ) // Based on https://github.com/coder/terraform-provider-coder/blob/9a745586b23a9cb5de2f65a2dcac12e48b134ffa/provider/workspace_owner.go#L72 type WorkspaceOwner struct { - ID uuid.UUID `json:"id"` - Name string `json:"name"` - FullName string `json:"full_name"` - Email string `json:"email"` - SSHPublicKey string `json:"ssh_public_key"` + ID string `json:"id" cty:"id"` + Name string `json:"name" cty:"name"` + FullName string `json:"full_name" cty:"full_name"` + Email string `json:"email" cty:"email"` + SSHPublicKey string `json:"ssh_public_key" cty:"ssh_public_key"` // SSHPrivateKey is intentionally omitted for now, due to the security risk // that exposing it poses. - // SSHPrivateKey string `json:"ssh_private_key"` - Groups []string `json:"groups"` + // SSHPrivateKey string `json:"ssh_private_key" cty:"ssh_private_key"` + Groups []string `json:"groups" cty:"groups"` // SessionToken is intentionally omitted for now, due to the security risk // that exposing it poses. - // SessionToken string `json:"session_token"` + // SessionToken string `json:"session_token" cty:"session_token"` // OIDCAccessToken is intentionally omitted for now, due to the security risk // that exposing it poses. - // OIDCAccessToken string `json:"oidc_access_token"` - LoginType string `json:"login_type"` - RBACRoles []WorkspaceOwnerRBACRole `json:"rbac_roles"` + // OIDCAccessToken string `json:"oidc_access_token" cty:"oidc_access_token"` + LoginType string `json:"login_type" cty:"login_type"` + RBACRoles []WorkspaceOwnerRBACRole `json:"rbac_roles" cty:"rbac_roles"` +} + +type WorkspaceOwnerRBACRole struct { + Name string `json:"name" cty:"name"` + OrgID string `json:"org_id" cty:"org_id"` } func (o *WorkspaceOwner) ToCtyValue() (cty.Value, error) { if o.Groups == nil { - o.Groups = []string{} + o.Groups = make([]string, 0) } - convertedGroups, err := gocty.ToCtyValue(o.Groups, cty.List(cty.String)) - if err != nil { - return cty.Value{}, err + if o.RBACRoles == nil { + o.RBACRoles = make([]WorkspaceOwnerRBACRole, 0) } - roleValues := make([]cty.Value, 0, len(o.RBACRoles)) - for _, role := range o.RBACRoles { - roleValue, err := role.ToCtyValue() - if err != nil { - return cty.Value{}, err - } - roleValues = append(roleValues, roleValue) - } - var convertedRoles cty.Value = cty.ListValEmpty(WorkspaceOwnerRBACRole{}.CtyType()) - if len(roleValues) > 0 { - convertedRoles = cty.ListVal(roleValues) + ownerValue, err := gocty.ToCtyValue(o, cty.Object(map[string]cty.Type{ + "id": cty.String, + "name": cty.String, + "full_name": cty.String, + "email": cty.String, + "ssh_public_key": cty.String, + "groups": cty.List(cty.String), + "login_type": cty.String, + "rbac_roles": cty.List(cty.Object( + map[string]cty.Type{ + "name": cty.String, + "org_id": cty.String, + }, + )), + })) + if err != nil { + return cty.Value{}, xerrors.Errorf("failed to convert owner value", err) } - - return cty.ObjectVal(map[string]cty.Value{ - "id": cty.StringVal(o.ID.String()), - "name": cty.StringVal(o.Name), - "full_name": cty.StringVal(o.FullName), - "email": cty.StringVal(o.Email), - "ssh_public_key": cty.StringVal(o.SSHPublicKey), - "groups": convertedGroups, - "login_type": cty.StringVal(o.LoginType), - "rbac_roles": convertedRoles, - }), nil -} - -type WorkspaceOwnerRBACRole struct { - Name string `json:"name"` - OrgID uuid.UUID `json:"org_id"` -} - -func (_ WorkspaceOwnerRBACRole) CtyType() cty.Type { - return cty.Object(map[string]cty.Type{ - "name": cty.String, - "org_id": cty.String, - }) -} - -func (r *WorkspaceOwnerRBACRole) ToCtyValue() (cty.Value, error) { - return cty.ObjectVal(map[string]cty.Value{ - "name": cty.StringVal(r.Name), - "org_id": cty.StringVal(r.OrgID.String()), - }), nil + return ownerValue, nil } diff --git a/types/owner_test.go b/types/owner_test.go index a2a3585..d8fb549 100644 --- a/types/owner_test.go +++ b/types/owner_test.go @@ -3,13 +3,12 @@ package types import ( "testing" - "github.com/google/uuid" "github.com/stretchr/testify/require" ) func TestToCtyValue(t *testing.T) { owner := WorkspaceOwner{ - ID: uuid.MustParse("f6457744-3e16-45b2-b3b0-80c2df491c99"), + ID: "f6457744-3e16-45b2-b3b0-80c2df491c99", Name: "Nissa", FullName: "Nissa, Worldwaker", Email: "nissa@coder.com", @@ -18,14 +17,14 @@ func TestToCtyValue(t *testing.T) { LoginType: "password", RBACRoles: []WorkspaceOwnerRBACRole{ {Name: "User Admin"}, - {Name: "Organization User Admin", OrgID: uuid.MustParse("5af9253a-ecde-4a71-b8f5-c8d15be9e52b")}, + {Name: "Organization User Admin", OrgID: "5af9253a-ecde-4a71-b8f5-c8d15be9e52b"}, }, } ownerValue, err := owner.ToCtyValue() require.NoError(t, err) - require.Equal(t, owner.ID.String(), ownerValue.AsValueMap()["id"].AsString()) + require.Equal(t, owner.ID, ownerValue.AsValueMap()["id"].AsString()) require.Equal(t, owner.Name, ownerValue.AsValueMap()["name"].AsString()) require.Equal(t, owner.SSHPublicKey, ownerValue.AsValueMap()["ssh_public_key"].AsString()) for i, it := range owner.Groups { @@ -34,13 +33,13 @@ func TestToCtyValue(t *testing.T) { for i, it := range owner.RBACRoles { roleValueMap := ownerValue.AsValueMap()["rbac_roles"].AsValueSlice()[i].AsValueMap() require.Equal(t, it.Name, roleValueMap["name"].AsString()) - require.Equal(t, it.OrgID.String(), roleValueMap["org_id"].AsString()) + require.Equal(t, it.OrgID, roleValueMap["org_id"].AsString()) } } func TestToCtyValueWithNilLists(t *testing.T) { owner := WorkspaceOwner{ - ID: uuid.MustParse("f6457744-3e16-45b2-b3b0-80c2df491c99"), + ID: "f6457744-3e16-45b2-b3b0-80c2df491c99", Name: "Nissa", FullName: "Nissa, Worldwaker", Email: "nissa@coder.com",