Commit 9b079032 authored by John Jarvis's avatar John Jarvis

Refactoring and lint fixes.

parent 61e096bb
Pipeline #15944975 passed with stage
in 3 minutes and 33 seconds
......@@ -35,25 +35,10 @@ func main() {
if err != nil {
log.Fatalln(err)
}
fmt.Println("Downloading graphs from performance ...")
start := time.Now()
graphs := oncall.DownloadGraphs(config)
secs := time.Since(start).Seconds()
fmt.Printf(" %d graphs took %.2f seconds to download\n", len(graphs), secs)
fmt.Println("Uploading graphs to Gitlab project ...")
start = time.Now()
weekly_ops_graphs := oncall.UploadGraphs(config, graphs)
secs = time.Since(start).Seconds()
fmt.Printf(" Completed upload in %.2f seconds\n", secs)
desc := oncall.GenerateTemplate(config, weekly_ops_graphs)
opts := oncall.OnCallReportOptions{}
report := oncall.NewOnCallReport(config, opts)
title := "OnCall report for period: " +
time.Now().UTC().AddDate(0, 0, -7).Format("2006-01-02") +
" - " + time.Now().UTC().Format("2006-01-02")
fmt.Println("Creating issue ...")
issue := oncall.CreateReportIssue(config, title, desc.String())
fmt.Println("Created issue ", issue.WebURL)
report.CreateReportIssue(title)
}
......@@ -2,9 +2,10 @@ package oncall
import (
"fmt"
"time"
gitlab "github.com/xanzy/go-gitlab"
config "gitlab.com/gl-infra/oncall-robot-assistant/config"
"time"
)
func getIssuesClosedDuringMilestone(config *config.Config) []*gitlab.Issue {
......@@ -15,8 +16,8 @@ func getIssuesClosedDuringMilestone(config *config.Config) []*gitlab.Issue {
state := "closed"
opts.State = &state
opts.Milestone = &config.Milestone
day_interval := time.Now().UTC().AddDate(0, 0, -config.DayOffset)
opts.CreatedAfter = &day_interval
dayInterval := time.Now().UTC().AddDate(0, 0, -config.DayOffset)
opts.CreatedAfter = &dayInterval
if issues, _, err := git.Issues.ListProjectIssues(config.GitLab.Id, &opts); err != nil {
panic(err)
} else {
......@@ -28,8 +29,8 @@ func getIssuesOpenedDuringShift(config *config.Config) []*gitlab.Issue {
labels := []string{config.OncallLabel}
var opts gitlab.ListProjectIssuesOptions
opts.Labels = labels
day_interval := time.Now().UTC().AddDate(0, 0, -config.DayOffset)
opts.CreatedAfter = &day_interval
dayInterval := time.Now().UTC().AddDate(0, 0, -config.DayOffset)
opts.CreatedAfter = &dayInterval
if issues, _, err := git.Issues.ListProjectIssues(config.GitLab.Id, &opts); err != nil {
panic(err)
} else {
......@@ -51,20 +52,20 @@ func getIssuesOpenAll(config *config.Config) []*gitlab.Issue {
}
}
func filterIssuesByLabel(label string, issues []*gitlab.Issue) (filtered_issues []*gitlab.Issue) {
func filterIssuesByLabel(label string, issues []*gitlab.Issue) (filteredIssues []*gitlab.Issue) {
for _, p := range issues {
if stringInSlice(label, p.Labels) {
filtered_issues = append(filtered_issues, p)
filteredIssues = append(filteredIssues, p)
}
}
return
}
func filterIssuesByState(state string, issues []*gitlab.Issue) (filtered_issues []*gitlab.Issue) {
func filterIssuesByState(state string, issues []*gitlab.Issue) (filteredIssues []*gitlab.Issue) {
for _, p := range issues {
fmt.Println(state, p.Labels)
if p.State == state {
filtered_issues = append(filtered_issues, p)
filteredIssues = append(filteredIssues, p)
}
}
return
......
......@@ -22,91 +22,94 @@ type GraphData struct {
Info string
}
func UploadGraphs(config *config.Config, graphs <-chan GraphData) (ops_graphs []WeeklyOpsGraph) {
git := gitlab.NewClient(nil, config.GitLab.Token)
type OnCallReportClients struct {
GitLab *gitlab.Client
}
type OnCallReport struct {
Config *config.Config
Clients *OnCallReportClients
}
type OnCallReportOptions struct {
}
// Initializes the oncall report
func NewOnCallReport(config *config.Config, opts OnCallReportOptions) *OnCallReport {
r := OnCallReport{
Config: config,
Clients: newReportClients(opts, config),
}
return &r
}
// Creates a new report and returns an issue, this is a multi-step process
// * Downloads graphs from grafana (these are specified in the yaml config)
// * Uploads the graphs to the project
// * Creates an issue using the issue template
func (r *OnCallReport) CreateReportIssue(title string) *gitlab.Issue {
graphs := r.downloadGraphs()
weekly_ops_graphs := r.uploadGraphs(graphs)
desc := r.generateTemplate(weekly_ops_graphs)
opts := gitlab.CreateIssueOptions{}
opts.Title = &title
opts.Description = &desc
log.Println("Creating issue ...")
start := time.Now()
issue, _, err := r.Clients.GitLab.Issues.CreateIssue(r.Config.ProjectId, &opts)
if err != nil {
log.Fatalf("Unable to create issue in GitLab project %d: %s", r.Config.ProjectId, err.Error())
}
secs := time.Since(start).Seconds()
log.Printf(" Created issue %s in %.2f seconds\n", issue.WebURL, secs)
return issue
}
// Upload graphs to the gitlab project
func (r *OnCallReport) uploadGraphs(graphs <-chan GraphData) (ops_graphs []WeeklyOpsGraph) {
log.Println("Uploading graphs to GitLab project ...")
start := time.Now()
git := gitlab.NewClient(nil, r.Config.GitLab.Token)
for graph := range graphs {
defer os.Remove(graph.Fname)
ops_graph := WeeklyOpsGraph{}
fmt.Println(" uploading", graph.Name)
pf, _, err := git.Projects.UploadFile(config.ProjectId, graph.Fname)
log.Println(" uploading", graph.Name)
pf, _, err := git.Projects.UploadFile(r.Config.ProjectId, graph.Fname)
if err != nil {
panic(err)
log.Fatalf("Unable to upload graphs to project id %d : %s", r.Config.ProjectId, err.Error())
}
ops_graph.Url = pf.URL
ops_graph.Name = graph.Name
ops_graphs = append(ops_graphs, ops_graph)
}
secs := time.Since(start).Seconds()
log.Printf(" Completed upload in %.2f seconds\n", secs)
return ops_graphs
}
func DownloadGraphs(config *config.Config) (graphs <-chan GraphData) {
// Downloads graphs from Grafana
func (r *OnCallReport) downloadGraphs() (graphs <-chan GraphData) {
log.Println("Downloading graphs from performance ...")
start := time.Now()
var wg sync.WaitGroup
num_graphs := len(weeklyOpsGraphs(config))
num_graphs := len(weeklyOpsGraphs(r.Config))
ch := make(chan GraphData, num_graphs)
wg.Add(num_graphs)
for _, graph := range weeklyOpsGraphs(config) {
go MakeRequest(graph.Url, graph.Name, ch, &wg, config.GrafanaKey)
for _, graph := range weeklyOpsGraphs(r.Config) {
go makeRequest(graph.Url, graph.Name, ch, &wg, r.Config.GrafanaKey)
}
wg.Wait()
close(ch)
return ch
}
func MakeRequest(url string, name string, ch chan<- GraphData, wg *sync.WaitGroup, grafana_key string) {
defer wg.Done()
start := time.Now()
file, _ := ioutil.TempFile(os.TempDir(), "oncall-graph")
graph_data := GraphData{}
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer "+grafana_key)
resp, err := client.Do(req)
defer resp.Body.Close()
if err != nil {
panic(err)
}
secs := time.Since(start).Seconds()
body, _ := ioutil.ReadAll(resp.Body)
err = ioutil.WriteFile(file.Name(), body, 0644)
if err != nil {
panic(err)
}
graph_data.Name = name
graph_data.Url = url
graph_data.Fname = file.Name()
graph_data.Info = fmt.Sprintf("%.2f elapsed with response length: %d %s", secs, len(body), url)
ch <- graph_data
}
func CreateReportIssue(config *config.Config, title string, report string) *gitlab.Issue {
git := gitlab.NewClient(nil, config.GitLab.Token)
opts := gitlab.CreateIssueOptions{}
opts.Title = &title
opts.Description = &report
if issue, _, err := git.Issues.CreateIssue(config.ProjectId, &opts); err != nil {
panic(err)
} else {
return issue
}
}
func weeklyOpsGraphs(config *config.Config) (graphs []WeeklyOpsGraph) {
for _, graph := range config.WeeklyOps {
ops_graph := WeeklyOpsGraph{}
ops_graph.Name = graph.Name
millis_to := time.Now().UnixNano() / 1000000
millis_from := millis_to - (86400000 * int64(config.DayOffset))
ops_graph.Url = graph.Url + fmt.Sprintf("&from=%d&to=%d", millis_from, millis_to)
graphs = append(graphs, ops_graph)
}
return graphs
log.Printf(" %d graphs took %.2f seconds to download\n", num_graphs, secs)
return ch
}
func GenerateTemplate(config *config.Config, weekly_ops_graphs []WeeklyOpsGraph) *bytes.Buffer {
// Generate an issue using a template
func (r *OnCallReport) generateTemplate(weekly_ops_graphs []WeeklyOpsGraph) string {
template_data := TemplateData{}
for _, schd := range config.PagerDuty.Schedules {
onCallUsers := getOncallPersons(config, schd.Id)
for _, schd := range r.Config.PagerDuty.Schedules {
onCallUsers := getOncallPersons(r.Config, schd.Id)
for _, u := range onCallUsers {
otm := OnCallTeamMember{}
otm.Schedule = schd.Name
......@@ -115,7 +118,7 @@ func GenerateTemplate(config *config.Config, weekly_ops_graphs []WeeklyOpsGraph)
}
}
incidents := getOncallIncidents(config)
incidents := getOncallIncidents(r.Config)
template_data.IncidentCount = len(incidents)
// Populate list of incidents for the template
for _, p := range incidents {
......@@ -125,9 +128,9 @@ func GenerateTemplate(config *config.Config, weekly_ops_graphs []WeeklyOpsGraph)
inc.CreatedAt = p.CreatedAt
template_data.Incidents = append(template_data.Incidents, inc)
}
oncall_issues := getIssuesOpenedDuringShift(config)
closed_issues := getIssuesClosedDuringMilestone(config)
all_open_issues := getIssuesOpenAll(config)
oncall_issues := getIssuesOpenedDuringShift(r.Config)
closed_issues := getIssuesClosedDuringMilestone(r.Config)
all_open_issues := getIssuesOpenAll(r.Config)
// Issue stats
template_data.IssuesOpenedDuringShift.Count = len(oncall_issues)
......@@ -176,5 +179,50 @@ func GenerateTemplate(config *config.Config, weekly_ops_graphs []WeeklyOpsGraph)
}
var desc bytes.Buffer
tmpl.Execute(&desc, template_data)
return &desc
return desc.String()
}
func newReportClients(opts OnCallReportOptions, config *config.Config) *OnCallReportClients {
tc := OnCallReportClients{
GitLab: gitlab.NewClient(nil, config.GitLab.Token),
}
return &tc
}
func makeRequest(url string, name string, ch chan<- GraphData, wg *sync.WaitGroup, grafana_key string) {
defer wg.Done()
start := time.Now()
file, _ := ioutil.TempFile(os.TempDir(), "oncall-graph")
graph_data := GraphData{}
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer "+grafana_key)
resp, err := client.Do(req)
defer resp.Body.Close()
if err != nil {
log.Fatalf("Unable to request graphs from grafana: %s", err.Error())
}
secs := time.Since(start).Seconds()
body, _ := ioutil.ReadAll(resp.Body)
err = ioutil.WriteFile(file.Name(), body, 0644)
if err != nil {
log.Fatalf("Unable to write graph images: %s", err.Error())
}
graph_data.Name = name
graph_data.Url = url
graph_data.Fname = file.Name()
graph_data.Info = fmt.Sprintf("%.2f elapsed with response length: %d %s", secs, len(body), url)
ch <- graph_data
}
func weeklyOpsGraphs(config *config.Config) (graphs []WeeklyOpsGraph) {
for _, graph := range config.WeeklyOps {
ops_graph := WeeklyOpsGraph{}
ops_graph.Name = graph.Name
millis_to := time.Now().UnixNano() / 1000000
millis_from := millis_to - (86400000 * int64(config.DayOffset))
ops_graph.Url = graph.Url + fmt.Sprintf("&from=%d&to=%d", millis_from, millis_to)
graphs = append(graphs, ops_graph)
}
return graphs
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment