Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support teams, team repositories, and team members #165

Merged
merged 18 commits into from
Jun 16, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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
14 changes: 8 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## v0.16.0 [2022-06-05]

_What's new?_

- Added `github_team` table
- Added `github_team_member` table
- Added `github_team_repository` table

## v0.15.0 [2022-05-25]

_What's new?_
Expand Down Expand Up @@ -105,7 +113,6 @@ _Bug fixes_

- `github_repository` table will now return an empty row instead of `not found` error when the repository collaborator details are not available ([#89](https://github.com/turbot/steampipe-plugin-github/pull/89))


## v0.8.1 [2021-10-26]

_Bug fixes_
Expand Down Expand Up @@ -190,7 +197,6 @@ _What's new?_
- [github_traffic_view_daily](https://hub.steampipe.io/plugins/turbot/github/tables/github_traffic_view_daily) ([#32](https://github.com/turbot/steampipe-plugin-github/pull/32))
- [github_traffic_view_weekly](https://hub.steampipe.io/plugins/turbot/github/tables/github_traffic_view_weekly) ([#33](https://github.com/turbot/steampipe-plugin-github/pull/33))


## v0.3.0 [2021-04-30]

_What's new?_
Expand All @@ -210,7 +216,6 @@ _Bug fixes_
- Cleanup unnecessary logging in github_license ([#24](https://github.com/turbot/steampipe-plugin-github/pull/24))
- Github (lower h) references should be GitHub (capital H) throughout the docs etc ([#26](https://github.com/turbot/steampipe-plugin-github/pull/26))


## v0.2.0 [2021-03-18]

_What's new?_
Expand All @@ -231,7 +236,6 @@ _Bug fixes_
- Fixed: Renamed table `github_repository_issue` to `github_issue` ([#16](https://github.com/turbot/steampipe-plugin-github/pull/16))
- Fixed: Renamed table `github_team` to `github_my_team` ([#16](https://github.com/turbot/steampipe-plugin-github/pull/16))


## v0.1.1 [2021-02-25]

_Bug fixes_
Expand All @@ -240,14 +244,12 @@ _Bug fixes_
- Fix error for missing required quals [#40](https://github.com/turbot/steampipe-plugin-sdk/issues/42).
- Queries fail with error socket: too many open files [#190](https://github.com/turbot/steampipe/issues/190)


## v0.1.0 [2021-02-18]

_What's new?_

- Added support for [connection configuration](https://github.com/turbot/steampipe-plugin-github/blob/main/docs/index.md#connection-configuration). You may specify github `token` for each connection in a configuration file.


## v0.0.5 [2021-01-28]

_What's new?_
Expand Down
30 changes: 30 additions & 0 deletions docs/tables/github_team.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Table: github_team

The `github_team` table can be used to fetch team information for a given organization. **You must specify the organization** in the where or join clause (`where organization=`, `join github_repository on organization=`).

## Examples

## Get all teams in an organization

```sql
select
t.id
t.name
japborst marked this conversation as resolved.
Show resolved Hide resolved
t.privacy
t.description
from
github.github_team
where organization = 'my_org'
```

## Get all teams in your organizations

```sql
select
o.login,
t.name,
t.slug
from github.github_my_organization as o
inner join github.github_team as t
on t.organization = o.login
```
36 changes: 36 additions & 0 deletions docs/tables/github_team_member.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Table: github_team_member

The `github_team_member` table can be used to query information about members of a team. **You must specify the organization and team slug** in the where or join clause (`where organization= AND slug=`, `join github_repository on organization= AND slug=`).

## Examples

### Get information about a specific organization's team members

```sql
select
login,
role
from
github_team_member
where
organization = 'my_org'
AND slug = 'my-team';
```

### To get members for all teams

```sql
select
t.name as team_name,
t.privacy as team_privacy,
t.description as team_description,
tm.login as user_login,
tm.role as user_role
from
github.github_team as t
inner join
github.github_team_member as tm
on t.organization = tm.organization
and t.slug = tm.slug
where t.organization = 'my_org'
```
50 changes: 50 additions & 0 deletions docs/tables/github_team_repository.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Table: github_team_repository

A repository contains all of your project's files and each file's revision history.

The `github_team_repository` table can be used to query information about repositories that a team have access to. **You must specify the organization and team slug** in the where or join clause (`where organization= AND slug=`, `join github_repository on organization= AND slug=`).

To list all **your** repositories use the `github_my_repository` table instead. To get information about **any** repository, use the `github_repository` table instead.

## Examples

### Get information about a specific organization's team

```sql
select
name,
owner_login,
language,
forks_count,
stargazers_count,
subscribers_count,
watchers_count,
description
from
github_team_repository
where
organization = 'my_org'
AND slug = 'my-team';
```

### To get repositories for all teams

```sql
select
t.id as team_id,
t.name as team_name,
t.privacy as team_privacy,
t.description as team_description,
tr.name as repo_name,
tr.fork as repo_is_fork,
tr.private as repo_is_private,
tr.archived as repo_is_archived,
tr.language as repo_primary_language
from
github.github_team as t
inner join
github.github_team_repository as tr
on t.organization = tr.organization
and t.slug = tr.slug
where t.organization = 'my_org'
```
5 changes: 4 additions & 1 deletion github/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ func Plugin(ctx context.Context) *plugin.Plugin {
"github_actions_repository_runner": tableGitHubActionsRepositoryRunner(ctx),
"github_actions_repository_secret": tableGitHubActionsRepositorySecret(ctx),
"github_actions_repository_workflow_run": tableGitHubActionsRepositoryWorkflowRun(ctx),
"github_branch": tableGitHubBranch(ctx),
"github_branch_protection": tableGitHubBranchProtection(ctx),
"github_branch": tableGitHubBranch(ctx),
"github_commit": tableGitHubCommit(ctx),
"github_community_profile": tableGitHubCommunityProfile(ctx),
"github_gist": tableGitHubGist(),
Expand Down Expand Up @@ -50,6 +50,9 @@ func Plugin(ctx context.Context) *plugin.Plugin {
"github_search_user": tableGitHubSearchUser(ctx),
"github_stargazer": tableGitHubStargazer(ctx),
"github_tag": tableGitHubTag(ctx),
"github_team_member": tableGitHubTeamMember(),
"github_team_repository": tableGitHubTeamRepository(),
"github_team": tableGitHubTeam(),
"github_traffic_view_daily": tableGitHubTrafficViewDaily(ctx),
"github_traffic_view_weekly": tableGitHubTrafficViewWeekly(ctx),
"github_user": tableGitHubUser(),
Expand Down
81 changes: 11 additions & 70 deletions github/table_github_my_team.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,52 +10,30 @@ import (
"github.com/turbot/steampipe-plugin-sdk/v3/plugin/transform"
)

func gitHubTeamColumns() []*plugin.Column {
return []*plugin.Column{

// Top columns
{Name: "organization", Type: pb.ColumnType_STRING, Description: "The organization the team is associated with.", Transform: transform.FromField("Organization.Login"), Hydrate: tableGitHubTeamGet},
{Name: "slug", Type: pb.ColumnType_STRING, Description: "The team slug name."},
{Name: "name", Type: pb.ColumnType_STRING, Description: "The name of the team."},
{Name: "members_count", Type: pb.ColumnType_INT, Description: "The number of members.", Hydrate: tableGitHubTeamGet},

// Not yet supported by go-github
//{Name: "created_at", Type: pb.ColumnType_TIMESTAMP, Hydrate: tableGitHubTeamGet, Transform: transform.Transform(convertTimestamp)},
{Name: "description", Type: pb.ColumnType_STRING, Description: "The description of the team."},
// Not yet supported by go-github
//{Name: "html_url", Type: pb.ColumnType_STRING, Description: "The URL of the team page in GitHub."},
{Name: "id", Type: pb.ColumnType_INT, Description: "The ID of the team."},
{Name: "members_url", Type: pb.ColumnType_STRING, Description: "The API Members URL."},
{Name: "node_id", Type: pb.ColumnType_STRING, Description: "The node id of the team."},
// Only load relevant fields from the organization
{Name: "organization_id", Type: pb.ColumnType_INT, Description: "The user id (number) of the organization.", Transform: transform.FromField("Organization.ID"), Hydrate: tableGitHubTeamGet},
{Name: "organization_login", Type: pb.ColumnType_STRING, Description: "The login name of the organization.", Transform: transform.FromField("Organization.Login"), Hydrate: tableGitHubTeamGet},
{Name: "organization_type", Type: pb.ColumnType_STRING, Description: "The type of the organization).", Transform: transform.FromField("Organization.Type"), Hydrate: tableGitHubTeamGet},
{Name: "permission", Type: pb.ColumnType_STRING, Description: "The default repository permissions of the team."},
{Name: "privacy", Type: pb.ColumnType_STRING, Description: "The privacy setting of the team (closed or secret)."},
{Name: "repos_count", Type: pb.ColumnType_INT, Description: "The number of repositories for the team.", Hydrate: tableGitHubTeamGet},
{Name: "repositories_url", Type: pb.ColumnType_STRING, Description: "The API Repositories URL."},
// Not yet supported by go-github
// {Name: "updated_at", Type: pb.ColumnType_TIMESTAMP, Hydrate: tableGitHubTeamGet},
{Name: "url", Type: pb.ColumnType_STRING, Description: "The API URL of the team."},
//// TABLE DEFINITION

func gitHubMyTeamColumns() []*plugin.Column {
teamColumns := gitHubTeamColumns()
myTeamColumns := []*plugin.Column{
{Name: "organization", Type: pb.ColumnType_STRING, Description: "The organization the team is associated with.", Transform: transform.FromField("Organization.Login")},
}
}

//// TABLE DEFINITION
return append(teamColumns, myTeamColumns...)
}

func tableGitHubMyTeam() *plugin.Table {
return &plugin.Table{
Name: "github_my_team",
Description: "GitHub Teams in your organizations. GitHub Teams are groups of organization members that reflect your company or group's structure with cascading access permissions and mentions.",
Description: "GitHub Teams that you belong to in your organization. GitHub Teams are groups of organization members that reflect your company or group's structure with cascading access permissions and mentions.",
List: &plugin.ListConfig{
Hydrate: tableGitHubMyTeamList,
},
Get: &plugin.GetConfig{
KeyColumns: plugin.AllColumns([]string{"organization_id", "id"}),
KeyColumns: plugin.AllColumns([]string{"organization", "slug"}),
ShouldIgnoreError: isNotFoundError([]string{"404"}),
Hydrate: tableGitHubTeamGet,
},
Columns: gitHubTeamColumns(),
Columns: gitHubMyTeamColumns(),
}
}

Expand Down Expand Up @@ -119,40 +97,3 @@ func tableGitHubMyTeamList(ctx context.Context, d *plugin.QueryData, h *plugin.H
}

//// HYDRATE FUNCTIONS

func tableGitHubTeamGet(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
var orgID, teamID int64
if h.Item != nil {
team := h.Item.(*github.Team)
orgID = *team.Organization.ID
teamID = *team.ID
} else {
orgID = d.KeyColumnQuals["organization_id"].GetInt64Value()
teamID = d.KeyColumnQuals["id"].GetInt64Value()
}

client := connect(ctx, d)

type GetResponse struct {
team *github.Team
resp *github.Response
}

getDetails := func(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
detail, resp, err := client.Teams.GetTeamByID(ctx, orgID, teamID)
return GetResponse{
team: detail,
resp: resp,
}, err
}

getResponse, err := plugin.RetryHydrate(ctx, d, h, getDetails, &plugin.RetryConfig{ShouldRetryError: shouldRetryError})

if err != nil {
return nil, err
}
getResp := getResponse.(GetResponse)
team := getResp.team

return team, nil
}
Loading