Skip to content
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.

Add table turbot_active_grant closes #23 #24

Merged
merged 4 commits into from
Jan 24, 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
67 changes: 67 additions & 0 deletions docs/tables/turbot_active_grant.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Table: turbot_active_grant

A active grant is the assignment of a permission to a Turbot user or group on a resource or resource group which is active.

## Examples
cbruno10 marked this conversation as resolved.
Show resolved Hide resolved

### Basic info

```sql
select
grant_id,
identity_status,
identity_email,
identity_profile_id,
identity_trunk_title,
level_title,
resource_trunk_title
from
turbot_active_grant;
```

### List active grants for an identity

```sql
select
grant_id,
identity_status,
identity_email,
identity_trunk_title,
level_title,
resource_trunk_title
from
turbot_active_grant
where
identity_email = '[email protected]'
```

### List active grants for inactive identities

```sql
select
grant_id,
identity_status,
identity_email,
level_title,
resource_trunk_title
from
turbot_active_grant
where
identity_status = 'Inactive'
```

### List inactive grants

```sql
select
grant_id,
identity_email,
level_title,
level_trunk_title,
level_uri,
resource_trunk_title,
resource_type_trunk_title
from
turbot_grant
where grant_id not in (select grant_id from turbot_active_grant);
```
1 change: 1 addition & 0 deletions turbot/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func Plugin(ctx context.Context) *plugin.Plugin {
},
DefaultTransform: transform.FromGo(),
TableMap: map[string]*plugin.Table{
"turbot_active_grant": tableTurbotActiveGrant(ctx),
"turbot_control": tableTurbotControl(ctx),
"turbot_control_type": tableTurbotControlType(ctx),
"turbot_notification": tableTurbotNotification(ctx),
Expand Down
186 changes: 186 additions & 0 deletions turbot/table_turbot_active_grant.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
package turbot

import (
"context"
"fmt"
"regexp"
"strconv"

"github.com/turbot/steampipe-plugin-sdk/grpc/proto"
"github.com/turbot/steampipe-plugin-sdk/plugin"
"github.com/turbot/steampipe-plugin-sdk/plugin/transform"
)

func tableTurbotActiveGrant(ctx context.Context) *plugin.Table {
return &plugin.Table{
Name: "turbot_active_grant",
Description: "All active grants of resources by Turbot.",
List: &plugin.ListConfig{
KeyColumns: []*plugin.KeyColumn{
{Name: "grant_id", Require: plugin.Optional},
},
Hydrate: listActiveGrants,
},
Columns: []*plugin.Column{
// Top columns
{Name: "grant_id", Type: proto.ColumnType_INT, Transform: transform.FromField("Grant.Turbot.ID"), Description: "Unique identifier of the grant."},
{Name: "resource_id", Type: proto.ColumnType_INT, Transform: transform.FromField("Resource.Turbot.ID"), Description: "Unique identifier of the resource."},
{Name: "identity_status", Type: proto.ColumnType_STRING, Transform: transform.FromField("Grant.Identity.Status"), Description: "Status of the identity."},
{Name: "identity_display_name", Type: proto.ColumnType_STRING, Transform: transform.FromField("Grant.Identity.DisplayName"), Description: "Display name of the identity."},
{Name: "identity_email", Type: proto.ColumnType_STRING, Transform: transform.FromField("Grant.Identity.Email"), Description: "Email identity for the identity."},
{Name: "ientity_family_name", Type: proto.ColumnType_STRING, Transform: transform.FromField("Grant.Identity.FamilyName"), Description: "Family name of the identity."},
{Name: "identity_given_name", Type: proto.ColumnType_STRING, Transform: transform.FromField("Grant.Identity.GivenName"), Description: "Given name of the identity."},
{Name: "identity_last_login_timestamp", Type: proto.ColumnType_TIMESTAMP, Transform: transform.FromField("Identity.LastLoginTimestamp"), Description: "Last login timestamp."},
{Name: "identity_profile_id", Type: proto.ColumnType_STRING, Transform: transform.FromField("Grant.Identity.ProfileID"), Description: "Profile id of the identity."},
{Name: "identity_trunk_title", Type: proto.ColumnType_STRING, Transform: transform.FromField("Grant.Identity.Trunk.Title"), Description: "Full title (including ancestor trunk) of the grant identity."},
{Name: "level_title", Type: proto.ColumnType_STRING, Transform: transform.FromField("Grant.Level.Title"), Description: "The title of the level."},
{Name: "level_trunk_title", Type: proto.ColumnType_STRING, Transform: transform.FromField("Grant.Level.Trunk.Title"), Description: "Full title (including ancestor trunk) of the level."},
{Name: "level_uri", Type: proto.ColumnType_STRING, Transform: transform.FromField("Grant.Level.URI"), Description: "The URI of the level."},
{Name: "resource_type_trunk_title", Type: proto.ColumnType_STRING, Transform: transform.FromField("Resource.Type.Trunk.Title"), Description: "Full title (including ancestor trunk) of the grant type."},
{Name: "resource_trunk_title", Type: proto.ColumnType_STRING, Transform: transform.FromField("Resource.Trunk.Title"), Description: "Full title (including ancestor trunk) of the resource."},
{Name: "resource_type_uri", Type: proto.ColumnType_STRING, Transform: transform.FromField("Resource.Type.URI"), Description: "URI of the resource type."},
{Name: "identity_akas", Type: proto.ColumnType_JSON, Transform: transform.FromField("Grant.Identity.Akas"), Description: "AKA (also known as) identifiers for the identity"},
// Other columns
{Name: "create_timestamp", Type: proto.ColumnType_TIMESTAMP, Transform: transform.FromField("Turbot.CreateTimestamp").NullIfEqual(""), Description: "The create time of the grant."},
{Name: "filter", Type: proto.ColumnType_STRING, Transform: transform.FromQual("filter"), Description: "Filter used for this grant list."},
{Name: "timestamp", Type: proto.ColumnType_TIMESTAMP, Transform: transform.FromField("Turbot.Timestamp").NullIfEqual(""), Description: "Timestamp when the grant was last modified (created, updated or deleted)."},
{Name: "update_timestamp", Type: proto.ColumnType_TIMESTAMP, Transform: transform.FromField("Turbot.UpdateTimestamp"), Description: "When the grant was last updated in Turbot."},
{Name: "version_id", Type: proto.ColumnType_INT, Transform: transform.FromField("Turbot.VersionID").NullIfEqual(""), Description: "Unique identifier for this version of the identity."},
{Name: "workspace", Type: proto.ColumnType_STRING, Hydrate: plugin.HydrateFunc(getTurbotWorkspace).WithCache(), Transform: transform.FromValue(), Description: "Specifies the workspace URL."},
},
}
}

const (
activeGrants = `
query MyQuery($filter: [String!], $paging: String) {
activeGrants(filter: $filter, paging: $paging) {
items {
resource {
akas
title
trunk {
title
}
type {
uri
trunk {
title
}
}
turbot {
id
createTimestamp
deleteTimestamp
timestamp
versionId
updateTimestamp
}
}
grant {
identity {
akas
email: get(path: "email")
status: get(path: "status")
givenName: get(path: "givenName")
profileId: get(path: "profileId")
familyName: get(path: "familyName")
displayName: get(path: "displayName")
lastLoginTimestamp: get(path: "lastLoginTimestamp")
trunk {
title
}
}
level {
title
uri
trunk {
title
}
}
turbot {
id
}
}
turbot {
createTimestamp
deleteTimestamp
updateTimestamp
title
timestamp
versionId
}
}
paging {
next
}
}
}
`
)

func listActiveGrants(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
conn, err := connect(ctx, d)
if err != nil {
plugin.Logger(ctx).Error("turbot_active_grants.listActiveGrants", "connection_error", err)
return nil, err
}

filters := []string{}
quals := d.KeyColumnQuals

filter := ""
if quals["filter"] != nil {
filter = quals["filter"].GetStringValue()
filters = append(filters, filter)
}

// Additional filters
if quals["grant_id"] != nil {
filters = append(filters, fmt.Sprintf("id:%s", getQualListValues(ctx, quals, "grant_id", "int64")))
}

// Default to a very large page size. Page sizes earlier in the filter string
// win, so this is only used as a fallback.
pageResults := false
// Add a limit if they haven't given one in the filter field
re := regexp.MustCompile(`(^|\s)limit:[0-9]+($|\s)`)
if !re.MatchString(filter) {
// The caller did not specify a limit, so set a high limit and page all
// results.
pageResults = true
var pageLimit int64 = 5000

// Adjust page limit, if less than default value
limit := d.QueryContext.Limit
if d.QueryContext.Limit != nil {
if *limit < pageLimit {
pageLimit = *limit
}
}
filters = append(filters, fmt.Sprintf("limit:%s", strconv.Itoa(int(pageLimit))))
}

nextToken := ""
for {
result := &ActiveGrantInfo{}
err = conn.DoRequest(activeGrants, map[string]interface{}{"filter": filters, "next_token": nextToken}, result)
if err != nil {
plugin.Logger(ctx).Error("turbot_active_grants.listActiveGrants", "query_error", err)
}
for _, ActiveGrantDetails := range result.ActiveGrants.Items {

d.StreamListItem(ctx, ActiveGrantDetails)
// Context can be cancelled due to manual cancellation or the limit has been hit
if d.QueryStatus.RowsRemaining(ctx) == 0 {
return nil, nil
}
}
if !pageResults || result.ActiveGrants.Paging.Next== "" {
break
}
nextToken = result.ActiveGrants.Paging.Next
}

return nil, err
}
52 changes: 52 additions & 0 deletions turbot/types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package turbot

import "time"

type ResourcesResponse struct {
Resources struct {
Items []Resource
Expand Down Expand Up @@ -419,6 +421,56 @@ type TurbotTagMetadata struct {
UpdateTimestamp *string
}

type ActiveGrantInfo struct {
ActiveGrants struct {
Items []ActiveGrant
Paging struct {
Next string
}
}
}

type ActiveGrant struct {
Resource struct {
Akas []string
Title string
Trunk struct {
Title string
}
Type struct {
URI string
Trunk struct {
Title string
}
}
Turbot TurbotControlMetadata
}
Grant struct {
Identity struct {
Akas []string
Email string
Status string
GivenName string
ProfileID string
FamilyName string
DisplayName string
LastLoginTimestamp *time.Time
Trunk struct {
Title string
}
}
Level struct {
Title string
URI string
Trunk struct {
Title string
}
}
Turbot TurbotControlMetadata
}
Turbot TurbotResourceMetadata
}

type GrantNotification struct {
RoleName *string
PermissionTypeID *string
Expand Down