Skip to content

Instantly share code, notes, and snippets.

@jayco
Last active June 30, 2020 12:07
Show Gist options
  • Save jayco/b5fd78a0241a151cf816f5e5d75daf8f to your computer and use it in GitHub Desktop.
Save jayco/b5fd78a0241a151cf816f5e5d75daf8f to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"context"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
"golang.org/x/oauth2"
)
// general config values - org pipeline and generated api token with full access
var (
apiToken = flag.String("token", "", "GRAPHQL API token")
orgSlug = flag.String("org", "", "Orginization slug")
teamSlug = flag.String("team", "", "Team slug")
graphAPI = "https://graphql.buildkite.com/v1"
)
type teamResponse struct {
ID *string `json:"id"`
Name *string `json:"name"`
}
type user struct {
Node struct {
User struct {
ID *string `json:"id"`
Name *string `json:"name"`
} `json:"user"`
Teams struct {
Edges []struct {
Node struct {
Team struct {
ID *string `json:"id"`
} `json:"team"`
} `json:"node"`
} `json:"edges"`
} `json:"teams"`
} `json:"node"`
}
type orgResponse struct {
Members struct {
Edges []*user `json:"edges"`
} `json:"members"`
}
type teamMemberCreate struct {
TeamMemberEdge struct {
Node struct {
ID *string `json:"id"`
} `json:"node"`
} `json:"teamMemberEdge"`
}
type data struct {
Team *teamResponse `json:"team"`
Organization *orgResponse `json:"organization"`
TeamMemberCreate *teamMemberCreate `json:"teamMemberCreate"`
}
type payload struct {
Data *data `json:"data"`
}
func jsonPost(c *http.Client, jsonData *map[string]string) (*payload, error) {
jsonValue, _ := json.Marshal(jsonData)
data := bytes.NewBuffer(jsonValue)
res, err := c.Post(graphAPI, "application/json", data)
if err != nil {
return nil, err
}
defer res.Body.Close()
var p payload
b, _ := ioutil.ReadAll(res.Body)
json.Unmarshal(b, &p)
return &p, nil
}
func getTeamID(c *http.Client, orgSlug string, teamSlug string) *teamResponse {
template := `query {
team(slug: "%s/%s") {
id
name
}
}`
res, _ := jsonPost(c, &map[string]string{"query": fmt.Sprintf(template, orgSlug, teamSlug)})
return res.Data.Team
}
func getUsersInOrg(c *http.Client, orgSlug string) *orgResponse {
template := `query {
organization(slug: "%s") {
members(first: 500) {
edges {
node {
user {
id
name
}
teams(first: 500) {
edges {
node {
team {
id
}
}
}
}
}
}
}
}
}`
res, _ := jsonPost(c, &map[string]string{"query": fmt.Sprintf(template, orgSlug)})
return res.Data.Organization
}
func addUsersToTeam(c *http.Client, team *teamResponse, users *orgResponse) {
template := `mutation {
teamMemberCreate(
input: {
teamID: "%s"
userID: "%s"
}
) {
teamMemberEdge {
node {
id
}
}
}
}`
buffer := len(users.Members.Edges)
results := make(chan string, buffer)
for _, m := range users.Members.Edges {
go func(u *user) {
isMember := false
for _, t := range u.Node.Teams.Edges {
if *t.Node.Team.ID == *team.ID {
isMember = true
break
}
}
if isMember {
results <- fmt.Sprintf("SKIP: user %v is already a member of %v team \n", *u.Node.User.Name, *team.Name)
} else {
_, err := jsonPost(c, &map[string]string{"query": fmt.Sprintf(template, *team.ID, *u.Node.User.ID)})
if err != nil {
results <- fmt.Sprintf("FAILED: for user %s with %v \n", *u.Node.User.Name, err)
return
}
results <- fmt.Sprintf("SUCCESS: adding user %s to %s team \n", *u.Node.User.Name, *team.Name)
}
}(m)
}
total := 0
for {
select {
case r := <-results:
total++
fmt.Println(r)
if total == buffer {
return
}
case <-time.After(50 * time.Millisecond):
fmt.Printf(".")
}
}
}
func main() {
flag.Parse()
src := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: *apiToken})
httpClient := oauth2.NewClient(context.Background(), src)
// grab the team ID
team := getTeamID(httpClient, *orgSlug, *teamSlug)
// grab the users and generate queries for those who are not members
log.Println("Fetching the org user ids")
org := getUsersInOrg(httpClient, *orgSlug)
// add users to a teamn
log.Println("Adding users to team")
addUsersToTeam(httpClient, team, org)
}
@jayco
Copy link
Author

jayco commented Jun 30, 2020

go run main.go --org your-org --token your-token --team everyone

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment