blob: 76ef966a0d5b6ba323c2fde241bc8270d546716c [file] [log] [blame]
package proxy
import (
"context"
"fmt"
"log"
"github.com/machinebox/graphql"
)
const defaultEndpoint = "https://graphql.buildkite.com/v1"
// TODO(fwe): support paging once we have more than 500 pipelines
const pipelineQuery = `
query ($org: ID!){
organization(slug: $org) {
pipelines(first: 500) {
edges {
node {
name
public
teams(first: 500) {
edges {
node {
team {
slug
}
accessLevel
}
}
}
schedules {
edges {
node {
env
enabled
id
label
cronline
branch
commit
message
}
}
}
}
}
}
}
}
`
type response struct {
Organization struct {
Pipelines struct {
Edges []struct {
Node struct {
Name string `json:"name"`
Public bool `json:"public"`
Teams struct {
Edges []struct {
Node struct {
Team struct {
Slug string `json:"slug"`
} `json:"team"`
AccessLevel string `json:"accessLevel"`
} `json:"node"`
} `json:"edges"`
} `json:"teams"`
Schedules struct {
Edges []struct {
Node struct {
Id string `json:"id"`
Label string `json:"label"`
Cronline string `json:"cronline"`
Branch string `json:"branch"`
Commit string `json:"commit"`
Env []string `json:"env"`
Enabled bool `json:"enabled"`
Message string `json:"message"`
} `json:"node"`
} `json:"edges"`
} `json:"schedules"`
} `json:"node"`
} `json:"edges"`
} `json:"pipelines"`
} `json:"organization"`
}
type Access struct {
TeamSlug string
AccessLevel string
}
type Schedule struct {
Id string
Label string
Cronline string
Branch string
Commit string
Env []string
Enabled bool
Message string
}
type PipelineAccessAndSchedules struct {
Name string
Public bool
Access []Access
Schedules []Schedule
}
type GraphQlClient struct {
org string
graphqlClient *graphql.Client
request *graphql.Request
}
func CreateGraphQlClient(org string, apiToken string, debug bool) *GraphQlClient {
graphqlClient := graphql.NewClient(defaultEndpoint)
if debug {
graphqlClient.Log = func(s string) { log.Println(s) }
}
request := graphql.NewRequest(pipelineQuery)
request.Var("org", org)
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiToken))
return &GraphQlClient{org: org, graphqlClient: graphqlClient, request: request}
}
func (client *GraphQlClient) GetAccessAndSchedules() ([]*PipelineAccessAndSchedules, error) {
ctx := context.Background()
var resp response
if err := client.graphqlClient.Run(ctx, client.request, &resp); err != nil {
return nil, err
}
return extractAccessAndSchedulesFromResponse(resp), nil
}
func extractAccessAndSchedulesFromResponse(resp response) []*PipelineAccessAndSchedules {
edges := resp.Organization.Pipelines.Edges
result := make([]*PipelineAccessAndSchedules, len(edges))
for i, e := range edges {
access := make([]Access, len(e.Node.Teams.Edges))
for ia, a := range e.Node.Teams.Edges {
access[ia] = Access{
TeamSlug: a.Node.Team.Slug,
AccessLevel: a.Node.AccessLevel}
}
schedules := make([]Schedule, len(e.Node.Schedules.Edges))
for is, s := range e.Node.Schedules.Edges {
schedules[is] = Schedule{
Id: s.Node.Id,
Label: s.Node.Label,
Cronline: s.Node.Cronline,
Branch: s.Node.Branch,
Commit: s.Node.Commit,
Env: s.Node.Env,
Enabled: s.Node.Enabled,
Message: s.Node.Message}
}
result[i] = &PipelineAccessAndSchedules{
Name: e.Node.Name,
Public: e.Node.Public,
Access: access,
Schedules: schedules}
}
return result
}