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

Commit

Permalink
Add table turbot_active_grant closes #23
Browse files Browse the repository at this point in the history
  • Loading branch information
ParthaI committed Dec 15, 2021
1 parent 807d167 commit af0d839
Show file tree
Hide file tree
Showing 4 changed files with 256 additions and 0 deletions.
20 changes: 20 additions & 0 deletions docs/tables/turbot_active_grant.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# 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

### List all turbot active grants

```sql
select
grant_id,
identity_status,
identity_email,
identity_profile_id,
identity_trunk_title,
level_title,
resource_trunk_title
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
184 changes: 184 additions & 0 deletions turbot/table_turbot_active_grant.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
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: "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: "type_uri", Type: proto.ColumnType_STRING, Transform: transform.FromField("Resource.Type.URI"), Description: "URI 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("Resource.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("Resource.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("Resource.Turbot.UpdateTimestamp"), Description: "When the grant was last updated in Turbot."},
{Name: "version_id", Type: proto.ColumnType_INT, Transform: transform.FromField("Resource.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
createTimestamp
deleteTimestamp
timestamp
versionId
updateTimestamp
}
}
}
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
}
51 changes: 51 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,55 @@ 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
}
}

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

0 comments on commit af0d839

Please sign in to comment.