diff --git a/github/models/deployment.go b/github/models/deployment.go index 54816d5..3473b35 100644 --- a/github/models/deployment.go +++ b/github/models/deployment.go @@ -3,7 +3,9 @@ package models import "github.com/shurcooL/githubv4" type Environment struct { - basicIdentifiers + Id int `graphql:"id: databaseId @include(if:$includeEnvironmentId)" json:"id,omitempty"` + NodeId string `graphql:"nodeId: id @include(if:$includeEnvironmentNodeId)" json:"node_id,omitempty"` + Name string `graphql:"name @include(if:$includeEnvironmentName)" json:"name,omitempty"` // protectionRules [pageable] } @@ -11,18 +13,18 @@ type Deployment struct { Id int `graphql:"id: databaseId @include(if:$includeDeploymentId)" json:"id,omitempty"` NodeId string `graphql:"nodeId: id @include(if:$includeDeploymentNodeId)" json:"node_id,omitempty"` CommitSha string `graphql:"sha: commitOid @include(if:$includeDeploymentCommitSha)" json:"sha"` - CreatedAt NullableTime `graphql:"createdAt: createdAt @include(if:$includeDeploymentCreatedAt)" json:"created_at,omitempty"` - Creator Actor `graphql:"creator: creator @include(if:$includeDeploymentCreator)" json:"creator,omitempty"` - Description string `graphql:"description: description @include(if:$includeDeploymentDescription)" json:"description,omitempty"` - Environment string `graphql:"environment: environment @include(if:$includeDeploymentEnvironment)" json:"environment,omitempty"` - LatestEnvironment string `graphql:"latestEnvironment: latestEnvironment @include(if:$includeDeploymentLatestEnvironment)" json:"latest_environment,omitempty"` - LatestStatus DeploymentStatus `graphql:"latestStatus: latestStatus @include(if:$includeDeploymentLatestStatus)" json:"latest_status,omitempty"` - OriginalEnvironment string `graphql:"originalEnvironment: originalEnvironment @include(if:$includeDeploymentOriginalEnvironment)" json:"original_environment,omitempty"` - Payload string `graphql:"payload: payload @include(if:$includeDeploymentPayload)" json:"payload,omitempty"` - Ref BasicRef `graphql:"ref: ref @include(if:$includeDeploymentRef)" json:"ref,omitempty"` - State githubv4.DeploymentState `graphql:"state: state @include(if:$includeDeploymentState)" json:"state,omitempty"` - Task string `graphql:"task: task @include(if:$includeDeploymentTask)" json:"task,omitempty"` - UpdatedAt NullableTime `graphql:"updatedAt: updatedAt @include(if:$includeDeploymentUpdatedAt)" json:"updated_at,omitempty"` + CreatedAt NullableTime `graphql:"createdAt @include(if:$includeDeploymentCreatedAt)" json:"created_at,omitempty"` + Creator Actor `graphql:"creator @include(if:$includeDeploymentCreator)" json:"creator,omitempty"` + Description string `graphql:"description @include(if:$includeDeploymentDescription)" json:"description,omitempty"` + Environment string `graphql:"environment @include(if:$includeDeploymentEnvironment)" json:"environment,omitempty"` + LatestEnvironment string `graphql:"latestEnvironment @include(if:$includeDeploymentLatestEnvironment)" json:"latest_environment,omitempty"` + LatestStatus DeploymentStatus `graphql:"latestStatus @include(if:$includeDeploymentLatestStatus)" json:"latest_status,omitempty"` + OriginalEnvironment string `graphql:"originalEnvironment @include(if:$includeDeploymentOriginalEnvironment)" json:"original_environment,omitempty"` + Payload string `graphql:"payload @include(if:$includeDeploymentPayload)" json:"payload,omitempty"` + Ref BasicRef `graphql:"ref @include(if:$includeDeploymentRef)" json:"ref,omitempty"` + State githubv4.DeploymentState `graphql:"state @include(if:$includeDeploymentState)" json:"state,omitempty"` + Task string `graphql:"task @include(if:$includeDeploymentTask)" json:"task,omitempty"` + UpdatedAt NullableTime `graphql:"updatedAt @include(if:$includeDeploymentUpdatedAt)" json:"updated_at,omitempty"` } type DeploymentStatus struct { diff --git a/github/repo_utils.go b/github/repo_utils.go index 19c4776..a6ce82d 100644 --- a/github/repo_utils.go +++ b/github/repo_utils.go @@ -10,6 +10,73 @@ import ( "github.com/turbot/steampipe-plugin-sdk/v5/plugin" ) +func extractRepoEnvironmentFromHydrateItem(h *plugin.HydrateData) (models.Environment, error) { + if env, ok := h.Item.(models.Environment); ok { + return env, nil + } else { + return models.Environment{}, fmt.Errorf("unable to parse hydrate item %v as a Environment", h.Item) + } +} + +func appendRepoEnvironmentColumnIncludes(m *map[string]interface{}, cols []string) { + (*m)["includeEnvironmentName"] = githubv4.Boolean(slices.Contains(cols, "name")) + (*m)["includeEnvironmentNodeId"] = githubv4.Boolean(slices.Contains(cols, "node_id")) + (*m)["includeEnvironmentId"] = githubv4.Boolean(slices.Contains(cols, "id")) +} + +func envHydrateName(_ context.Context, _ *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + env, err := extractRepoEnvironmentFromHydrateItem(h) + if err != nil { + return nil, err + } + return env.Name, nil +} + +func envHydrateId(_ context.Context, _ *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + env, err := extractRepoEnvironmentFromHydrateItem(h) + if err != nil { + return nil, err + } + return env.Id, nil +} + +func envHydrateNodeId(_ context.Context, _ *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + env, err := extractRepoEnvironmentFromHydrateItem(h) + if err != nil { + return nil, err + } + return env.NodeId, nil +} + +func extractRepoCollaboratorFromHydrateItem(h *plugin.HydrateData) (RepositoryCollaborator, error) { + if rc, ok := h.Item.(RepositoryCollaborator); ok { + return rc, nil + } else { + return RepositoryCollaborator{}, fmt.Errorf("unable to parse hydrate item %v as a RepositoryCollaborator", h.Item) + } +} + +func appendRepoCollaboratorColumnIncludes(m *map[string]interface{}, cols []string) { + (*m)["includeRCPermission"] = githubv4.Boolean(slices.Contains(cols, "permission")) + (*m)["includeRCNode"] = githubv4.Boolean(slices.Contains(cols, "user_login")) +} + +func rcHydratePermission(_ context.Context, _ *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + rc, err := extractRepoCollaboratorFromHydrateItem(h) + if err != nil { + return nil, err + } + return rc.Permission, nil +} + +func rcHydrateUserLogin(_ context.Context, _ *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + rc, err := extractRepoCollaboratorFromHydrateItem(h) + if err != nil { + return nil, err + } + return rc.Node.Login, nil +} + func extractRepoVulnerabilityAlertFromHydrateItem(h *plugin.HydrateData) (models.RepositoryVulnerabilityAlert, error) { if vAlert, ok := h.Item.(models.RepositoryVulnerabilityAlert); ok { return vAlert, nil diff --git a/github/table_github_repository_collaborator.go b/github/table_github_repository_collaborator.go index 38aa372..6d5393e 100644 --- a/github/table_github_repository_collaborator.go +++ b/github/table_github_repository_collaborator.go @@ -3,20 +3,21 @@ package github import ( "context" "fmt" + "strings" + "github.com/shurcooL/githubv4" "github.com/turbot/steampipe-plugin-github/github/models" "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" "github.com/turbot/steampipe-plugin-sdk/v5/plugin" "github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform" - "strings" ) func gitHubRepositoryCollaboratorColumns() []*plugin.Column { return []*plugin.Column{ {Name: "repository_full_name", Type: proto.ColumnType_STRING, Description: "The full name of the repository, including the owner and repo name.", Transform: transform.FromQual("repository_full_name")}, {Name: "affiliation", Type: proto.ColumnType_STRING, Description: "Affiliation filter - valid values 'ALL' (default), 'OUTSIDE', 'DIRECT'.", Transform: transform.FromQual("affiliation"), Default: "ALL"}, - {Name: "permission", Type: proto.ColumnType_STRING, Description: "The permission the collaborator has on the repository."}, - {Name: "user_login", Type: proto.ColumnType_STRING, Description: "The login of the collaborator", Transform: transform.FromField("Node.Login")}, + {Name: "permission", Type: proto.ColumnType_STRING, Description: "The permission the collaborator has on the repository.", Transform: transform.FromValue(), Hydrate: rcHydratePermission}, + {Name: "user_login", Type: proto.ColumnType_STRING, Description: "The login of the collaborator", Transform: transform.FromValue(), Hydrate: rcHydrateUserLogin}, } } @@ -43,7 +44,12 @@ func tableGitHubRepositoryCollaborator() *plugin.Table { } } -func tableGitHubRepositoryCollaboratorList(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { +type RepositoryCollaborator struct { + Permission githubv4.RepositoryPermission + Node models.BasicUser +} + +func tableGitHubRepositoryCollaboratorList(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { quals := d.EqualsQuals fullName := quals["repository_full_name"].GetStringValue() owner, repoName := parseRepoFullName(fullName) @@ -70,8 +76,8 @@ func tableGitHubRepositoryCollaboratorList(ctx context.Context, d *plugin.QueryD TotalCount int PageInfo models.PageInfo Edges []struct { - Permission githubv4.RepositoryPermission - Node models.BasicUser + Permission githubv4.RepositoryPermission `graphql:"permission @include(if:$includeRCPermission)" json:"permission"` + Node models.BasicUser `graphql:"node @include(if:$includeRCNode)" json:"node"` } } `graphql:"collaborators(first: $pageSize, after: $cursor, affiliation: $affiliation)"` } `graphql:"repository(owner: $owner, name: $repo)"` @@ -85,6 +91,7 @@ func tableGitHubRepositoryCollaboratorList(ctx context.Context, d *plugin.QueryD "cursor": (*githubv4.String)(nil), "affiliation": affiliation, } + appendRepoCollaboratorColumnIncludes(&variables, d.QueryContext.Columns) client := connectV4(ctx, d) for { @@ -96,7 +103,7 @@ func tableGitHubRepositoryCollaboratorList(ctx context.Context, d *plugin.QueryD } for _, c := range query.Repository.Collaborators.Edges { - d.StreamListItem(ctx, c) + d.StreamListItem(ctx, RepositoryCollaborator{c.Permission, c.Node}) // Context can be cancelled due to manual cancellation or the limit has been hit if d.RowsRemaining(ctx) == 0 { diff --git a/github/table_github_repository_environment.go b/github/table_github_repository_environment.go index 8f4c938..e3adb05 100644 --- a/github/table_github_repository_environment.go +++ b/github/table_github_repository_environment.go @@ -2,6 +2,7 @@ package github import ( "context" + "github.com/shurcooL/githubv4" "github.com/turbot/steampipe-plugin-github/github/models" "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" @@ -12,9 +13,9 @@ import ( func gitHubRepositoryEnvironmentColumns() []*plugin.Column { return []*plugin.Column{ {Name: "repository_full_name", Type: proto.ColumnType_STRING, Transform: transform.FromQual("repository_full_name"), Description: "The full name of the repository (login/repo-name)."}, - {Name: "id", Type: proto.ColumnType_INT, Transform: transform.FromField("Id", "Node.Id"), Description: "The ID of the environment."}, - {Name: "node_id", Type: proto.ColumnType_STRING, Transform: transform.FromField("NodeId", "Node.NodeId"), Description: "The node ID of the environment."}, - {Name: "name", Type: proto.ColumnType_STRING, Transform: transform.FromField("Name", "Node.Name"), Description: "The name of the environment."}, + {Name: "id", Type: proto.ColumnType_INT, Transform: transform.FromValue(), Hydrate: envHydrateId, Description: "The ID of the environment."}, + {Name: "node_id", Type: proto.ColumnType_STRING, Transform: transform.FromValue(), Hydrate: envHydrateNodeId, Description: "The node ID of the environment."}, + {Name: "name", Type: proto.ColumnType_STRING, Transform: transform.FromValue(), Hydrate: envHydrateName, Description: "The name of the environment."}, } } @@ -36,7 +37,7 @@ func tableGitHubRepositoryEnvironment() *plugin.Table { } } -func tableGitHubRepositoryEnvironmentList(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { +func tableGitHubRepositoryEnvironmentList(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { quals := d.EqualsQuals fullName := quals["repository_full_name"].GetStringValue() owner, repoName := parseRepoFullName(fullName) @@ -60,6 +61,7 @@ func tableGitHubRepositoryEnvironmentList(ctx context.Context, d *plugin.QueryDa "pageSize": githubv4.Int(pageSize), "cursor": (*githubv4.String)(nil), } + appendRepoEnvironmentColumnIncludes(&variables, d.QueryContext.Columns) client := connectV4(ctx, d) for {