//Command Standard command parser func (x WinRM) Command(message models.Message, publishMsgs chan<- models.Message, connector models.Connector) { for _, command := range connector.Commands { if match, tokens := parse.Match(command.Match, message.In.Text); match { args := parse.Substitute(command.Args, tokens) tokens["STDOUT"] = sendCommand(command.Cmd, args, connector) var color = "NONE" var match = false if match, _ = parse.Match(command.Green, tokens["STDOUT"]); match { color = "SUCCESS" } if match, _ = parse.Match(command.Yellow, tokens["STDOUT"]); match { color = "WARN" } if match, _ = parse.Match(command.Red, tokens["STDOUT"]); match { color = "FAIL" } message.In.Tags = parse.TagAppend(message.In.Tags, connector.Tags+","+command.Tags) message.Out.Text = connector.ID + " " + command.Name message.Out.Detail = parse.Substitute(command.Output, tokens) message.Out.Status = color publishMsgs <- message } } }
// Command Matches wolfram command and queries the wolfram api func (x Wolfram) Command(message models.Message, publishMsgs chan<- models.Message, connector models.Connector) { if match, tokens := parse.Match("wolfram*", message.In.Text); match { message.In.Tags = parse.TagAppend(message.In.Tags, connector.Tags) message.Out.Text = callWolfram(tokens["*"], connector.Key) publishMsgs <- message } }
func commandBuild(message models.Message, publishMsgs chan<- models.Message, connector models.Connector) { tokens := strings.Split(message.In.Text, " ") queue := bambooapi.Queue(connector.Server, connector.Login, connector.Pass, tokens[2]) log.Printf("%+v", queue) message.In.Tags = parse.TagAppend(message.In.Tags, connector.Tags) if queue.StatusCode > 0 { message.Out.Text = "Problem queueing build: " + tokens[2] } else { message.Out.Text = "Queued build for " + queue.Plankey message.Out.Detail = "Build #" + strconv.Itoa(queue.Buildnumber) message.Out.Link = "https://" + connector.Server + "/builds/browse/" + queue.Plankey + "-" + strconv.Itoa(queue.Buildnumber) } publishMsgs <- message }
func parseJiraIssue(message models.Message, publishMsgs chan<- models.Message, connector models.Connector) { var jiraRegex = regexp.MustCompile("[a-zA-Z]{2,12}-[0-9]{1,10}") issues := jiraRegex.FindAllString(message.In.Text, -1) for _, issue := range issues { if connector.Debug { log.Println("Jira match: " + issue) } client := &http.Client{} auth := encodeB64(connector.Login + ":" + connector.Pass) req, err := http.NewRequest("GET", "https://"+connector.Server+"/rest/api/2/issue/"+issue, nil) if err != nil { log.Printf("Error creating jira request: %s", err) return } req.Header.Add("Content-Type", "application/json") req.Header.Add("Authorization", "Basic "+auth) response, err := client.Do(req) if err != nil { log.Printf("Error requesting jira issue: %s", err) return } defer response.Body.Close() body, err := ioutil.ReadAll(response.Body) if err != nil { log.Println(err) } var ticket ticket json.Unmarshal(body, &ticket) if connector.Debug { log.Printf("Jira result: %+v", ticket) } if ticket.Fields.Status.Name == "" { return } message.In.Tags = parse.TagAppend(message.In.Tags, connector.Tags) message.Out.Link = "https://" + connector.Server + "/browse/" + issue message.Out.Text = strings.ToUpper(issue) + " - " + ticket.Fields.Summary message.Out.Detail = fmt.Sprintf("Status: %s\nPriority: %s\nAssignee: %s\n", ticket.Fields.Status.Name, ticket.Fields.Priority.Name, ticket.Fields.Assignee.DisplayName) publishMsgs <- message } }
func (x Response) Command(message models.Message, publishMsgs chan<- models.Message, connector models.Connector) { if connector.Debug { log.Print("Incoming command message for " + connector.ID + " (" + connector.Type + ")") log.Printf("%+v", message) } for _, c := range connector.Commands { if match, tokens := parse.Match(c.Match, message.In.Text); match { if len(c.Outputs) == 0 { message.Out.Text = parse.Substitute(c.Output, tokens) } else { i := rand.Intn(len(c.Outputs)) message.Out.Text = parse.Substitute(c.Outputs[i], tokens) } message.In.Tags = parse.TagAppend(message.In.Tags, connector.Tags+","+c.Tags) publishMsgs <- message } } }
func commandBuildStatus(message models.Message, publishMsgs chan<- models.Message, connector models.Connector) { tokens := strings.Split(message.In.Text, " ") b := bambooapi.BuildResults(connector.Server, connector.Login, connector.Pass) for _, be := range b.Results.Result { if strings.Contains(strings.ToLower(be.Plan.Shortname), strings.ToLower(tokens[2])) { message.In.Tags = parse.TagAppend(message.In.Tags, connector.Tags) message.Out.Text = "Bamboo Build " + be.Plan.Shortname message.Out.Detail = be.Plan.Name + " #" + strconv.Itoa(be.Buildnumber) message.Out.Link = be.Link.Href if be.Buildstate == "Successful" { message.Out.Status = "SUCCESS" } else { message.Out.Status = "FAIL" } publishMsgs <- message } } }
func (x Redis) Command(message models.Message, publishMsgs chan<- models.Message, connector models.Connector) { for _, c := range connector.Commands { if match, _ := parse.Match(c.Match, message.In.Text); match { environment := Environment{ Address: connector.Server, Password: connector.Pass, DB: 0, } status := FlushDb(environment) log.Println(status.String()) message.In.Tags = parse.TagAppend(message.In.Tags, connector.Tags+","+c.Tags) message.Out.Text = fmt.Sprintf("Redis Server: %s\nStatus:%s", connector.Server, status.String()) publishMsgs <- message return } } }
func commandDeployStatus(message models.Message, publishMsgs chan<- models.Message, connector models.Connector) { tokens := strings.Split(message.In.Text, " ") d := bambooapi.DeployResults(connector.Server, connector.Login, connector.Pass) for _, de := range d { for _, e := range de.Environmentstatuses { detail := e.Deploymentresult.Deploymentversion.Name + " to " + e.Environment.Name if strings.Contains(strings.ToLower(detail), strings.ToLower(tokens[2])) { message.In.Tags = parse.TagAppend(message.In.Tags, connector.Tags) message.Out.Text = "Bamboo Deploy " + detail + " " + e.Deploymentresult.Deploymentstate message.Out.Detail = html.UnescapeString(sanitize.HTML(e.Deploymentresult.Reasonsummary)) message.Out.Link = "https://" + connector.Server + "/builds/deploy/viewDeploymentResult.action?deploymentResultId=" + strconv.Itoa(e.Deploymentresult.ID) if e.Deploymentresult.Deploymentstate == "SUCCESS" { message.Out.Status = "SUCCESS" } else { message.Out.Status = "FAIL" } publishMsgs <- message } } } }
func (x File) Listen(commandMsgs chan<- models.Message, connector models.Connector) { defer Recovery(connector) seek := tail.SeekInfo{Offset: 0, Whence: 2} t, err := tail.TailFile(connector.File, tail.Config{Follow: true, Location: &seek}) if err != nil { log.Print(err) } for line := range t.Lines { for _, c := range connector.Commands { if match, _ := parse.Match(c.Match, line.Text); match { var m models.Message m.In.ConnectorType = connector.Type m.In.ConnectorID = connector.ID m.In.Tags = parse.TagAppend(connector.Tags, c.Tags) m.In.Process = false m.Out.Text = connector.File + ": " + c.Name m.Out.Detail = line.Text commandMsgs <- m } } } }
func webhookHandler(w http.ResponseWriter, r *http.Request) { reqUrl := r.URL.Path reqQs, err := url.QueryUnescape(r.URL.RawQuery) if err != nil { log.Print(err) } if webhook.Connector.Debug { log.Print("Webhook Incoming URL: " + reqUrl) } rawbody, err := ioutil.ReadAll(r.Body) body := string(rawbody) if err != nil { log.Print(err) } defer r.Body.Close() if webhook.Connector.Debug { log.Print("Webhook Incoming Body: " + body) } // for new relic (lame) if strings.HasPrefix(body, "deployment=%7B") { body, err = url.QueryUnescape(strings.Replace(body, "deployment=", "", 1)) if err != nil { log.Print(err) } } if strings.HasPrefix(body, "alert=%7B") { body, err = url.QueryUnescape(strings.Replace(body, "alert=", "", 1)) if err != nil { log.Print(err) } } bodyParsed, err := gabs.ParseJSON([]byte(body)) isJson := true if err != nil { log.Print(err) isJson = false } for _, c := range webhook.Connector.Commands { if match, _ := parse.Match(c.Match, reqUrl); match { if webhook.Connector.Debug { log.Print("Webhook Match: " + c.Match) } tokens := make(map[string]string) tokens["?"] = reqQs tokens["*"] = body if isJson { if match, subs := parse.SubstitutionVars(c.Output); match { for _, sub := range subs { if webhook.Connector.Debug { log.Print("Webhook Sub: " + sub) } value, ok := bodyParsed.Path(parse.Strip(sub)).Data().(string) if ok { if webhook.Connector.Debug { log.Print("Webhook Val: " + value) } tokens[parse.Strip(sub)] = value } } } } out := parse.Substitute(c.Output, tokens) if c.Process { var m models.Message m.In.ConnectorType = webhook.Connector.Type m.In.ConnectorID = webhook.Connector.ID m.In.Tags = parse.TagAppend(webhook.Connector.Tags, c.Tags) m.In.Text = out m.In.Process = true webhook.CommandMsgs <- m } else { var color = "NONE" var match = false if match, _ = parse.Match(c.Green, out); match { color = "SUCCESS" } if match, _ = parse.Match(c.Yellow, out); match { color = "WARN" } if match, _ = parse.Match(c.Red, out); match { color = "FAIL" } var m models.Message m.In.ConnectorType = webhook.Connector.Type m.In.ConnectorID = webhook.Connector.ID m.In.Tags = parse.TagAppend(webhook.Connector.Tags, c.Tags) m.In.Text = reqUrl m.In.Process = false if c.Name != "" { m.Out.Text = c.Name m.Out.Detail = out } else { m.Out.Text = out } m.Out.Status = color webhook.CommandMsgs <- m } } } w.WriteHeader(http.StatusOK) w.Write([]byte("JaneBot")) }
func createJiraIssue(message models.Message, publishMsgs chan<- models.Message, connector models.Connector) { msg := strings.TrimSpace(strings.Replace(message.In.Text, "jira create", "", 1)) fields := strings.Fields(msg) summary := strings.Join(fields[2:], " ") client := &http.Client{} auth := encodeB64(connector.Login + ":" + connector.Pass) issuetype := issueType{ Name: fields[0], } project := project{ Key: fields[1], } issueFields := createFields{ Project: project, Summary: summary, IssueType: issuetype, } issue := createObject{ Fields: issueFields, } issueJSON, err := json.Marshal(issue) if err != nil { log.Printf("Error marshaling jira json: %s", err) return } req, err := http.NewRequest("POST", "https://"+connector.Server+"/rest/api/2/issue", bytes.NewBuffer(issueJSON)) if err != nil { log.Printf("Jira Create Error: %s", err) message.Out.Text = "Failed to create issue" publishMsgs <- message return } req.Header.Add("Content-Type", "application/json") req.Header.Add("Authorization", "Basic "+auth) response, err := client.Do(req) if err != nil { log.Printf("Error performing jira create request: %s", err) } defer response.Body.Close() body, err := ioutil.ReadAll(response.Body) if err != nil { log.Println(err) } var created createdIssue err = json.Unmarshal(body, &created) if err != nil { message.Out.Text = "Error creating ticket" publishMsgs <- message return } message.In.Tags = parse.TagAppend(message.In.Tags, connector.Tags) message.Out.Text = created.Key publishMsgs <- message }
func checkRM(commandMsgs chan<- models.Message, command models.Command, connector models.Connector) { // command vars var state = command.Green var stateReset = true var counter = 1 var interval = 1 var sampling = 1 var remind = 0 if command.Interval > 0 { interval = command.Interval } if command.Sampling > 0 { sampling = command.Sampling } if command.Remind > 0 { remind = command.Remind } // loop commands for { // reset vars var color = "NONE" var match = false var newstate = "" var sendAlert = false // make the call out := sendCommand(command.Cmd, command.Args, connector) // interpret results if match, _ = parse.Match(command.Green, out); match { newstate = command.Green color = "SUCCESS" } if match, _ = parse.Match(command.Yellow, out); match { newstate = command.Yellow color = "WARN" } if match, _ = parse.Match(command.Red, out); match { newstate = command.Red color = "FAIL" } // handle state change if newstate != state { if stateReset { counter = 1 stateReset = false } // sampling if counter == sampling { sendAlert = true } // change to green if newstate == command.Green { sendAlert = true } } // handle non-green state if newstate != command.Green && counter == remind && remind > 1 { sendAlert = true } // send message if sendAlert { var tokens = parse.Tokens() tokens["STDOUT"] = out var message models.Message message.In.ConnectorType = connector.Type message.In.ConnectorID = connector.ID message.In.Tags = parse.TagAppend(connector.Tags, command.Tags) message.In.Process = false message.Out.Text = connector.ID + " " + command.Name message.Out.Detail = parse.Substitute(command.Output, tokens) message.Out.Status = color commandMsgs <- message state = newstate counter = 0 stateReset = true } // wait counter += 1 time.Sleep(time.Duration(interval) * time.Minute) } }