oncall-engine/grafana-plugin/pkg/plugin/teams.go

188 lines
4.7 KiB
Go
Raw Permalink Normal View History

package plugin
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"sync/atomic"
)
type Teams struct {
Teams []Team `json:"teams"`
}
type Team struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
AvatarURL string `json:"avatarUrl"`
}
type OnCallTeam struct {
ID int `json:"team_id"`
Name string `json:"name"`
Email string `json:"email"`
AvatarURL string `json:"avatar_url"`
}
func (a *OnCallTeam) Equal(b *OnCallTeam) bool {
if a.ID != b.ID {
return false
}
if a.Name != b.Name {
return false
}
if a.Email != b.Email {
return false
}
if a.AvatarURL != b.AvatarURL {
return false
}
return true
}
func (a *App) GetTeamsForUser(settings *OnCallPluginSettings, onCallUser *OnCallUser) ([]int, error) {
atomic.AddInt32(&a.TeamForUserCallCount, 1)
reqURL, err := url.JoinPath(settings.GrafanaURL, fmt.Sprintf("api/users/%d/teams", onCallUser.ID))
if err != nil {
return nil, fmt.Errorf("error creating URL: %v", err)
}
req, err := http.NewRequest("GET", reqURL, nil)
if err != nil {
return nil, fmt.Errorf("error creating creating new request: %v", err)
}
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", settings.GrafanaToken))
res, err := a.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, fmt.Errorf("error reading response: %v", err)
}
var result []Team
err = json.Unmarshal(body, &result)
if err != nil {
return nil, fmt.Errorf("failed to parse JSON response: %v body=%v", err, string(body))
}
if res.StatusCode == 200 {
var teams []int
for _, team := range result {
teams = append(teams, team.ID)
}
return teams, nil
}
return nil, fmt.Errorf("no teams for %s, http status %s", onCallUser.Login, res.Status)
}
func (a *App) GetAllTeams(settings *OnCallPluginSettings) ([]OnCallTeam, error) {
atomic.AddInt32(&a.AllTeamsCallCount, 1)
reqURL, err := url.Parse(settings.GrafanaURL)
if err != nil {
return nil, fmt.Errorf("error parsing URL: %v", err)
}
reqURL.Path += "api/teams/search"
q := reqURL.Query()
q.Set("perpage", "100000")
reqURL.RawQuery = q.Encode()
req, err := http.NewRequest("GET", reqURL.String(), nil)
if err != nil {
return nil, fmt.Errorf("error creating new request: %v", err)
}
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", settings.GrafanaToken))
res, err := a.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %+v", err)
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, fmt.Errorf("error reading response: %+v", err)
}
var result Teams
err = json.Unmarshal(body, &result)
if err != nil {
return nil, fmt.Errorf("failed to parse JSON response: %v body=%v", err, string(body))
}
if res.StatusCode == 200 {
var teams []OnCallTeam
for _, team := range result.Teams {
onCallTeam := OnCallTeam{
ID: team.ID,
Name: team.Name,
Email: team.Email,
AvatarURL: team.AvatarURL,
}
teams = append(teams, onCallTeam)
}
return teams, nil
}
return nil, fmt.Errorf("http status %s", res.Status)
}
func (a *App) GetTeamsMembersForTeam(settings *OnCallPluginSettings, onCallTeam *OnCallTeam) ([]int, error) {
atomic.AddInt32(&a.TeamMembersForTeamCallCount, 1)
reqURL, err := url.JoinPath(settings.GrafanaURL, fmt.Sprintf("api/teams/%d/members", onCallTeam.ID))
if err != nil {
return nil, fmt.Errorf("error creating URL: %+v", err)
}
req, err := http.NewRequest("GET", reqURL, nil)
if err != nil {
return nil, fmt.Errorf("error creating creating new request: %+v", err)
}
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", settings.GrafanaToken))
res, err := a.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %+v", err)
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, fmt.Errorf("error reading response: %+v", err)
}
var result []OrgUser
err = json.Unmarshal(body, &result)
if err != nil {
return nil, fmt.Errorf("failed to parse JSON response: %v body=%v", err, string(body))
}
if res.StatusCode == 200 {
var members []int
for _, user := range result {
members = append(members, user.ID)
}
return members, nil
}
return nil, fmt.Errorf("http status %s", res.Status)
}
func (a *App) GetAllTeamMembers(settings *OnCallPluginSettings, onCallTeams []OnCallTeam) (map[int][]int, error) {
teamMapping := map[int][]int{}
for _, team := range onCallTeams {
teamMembers, err := a.GetTeamsMembersForTeam(settings, &team)
if err != nil {
return nil, err
}
teamMapping[team.ID] = teamMembers
}
return teamMapping, nil
}