Last active
April 13, 2018 10:52
-
-
Save oshiro-kazuma/6f0441a493f0d60bb9d02da84afd23b1 to your computer and use it in GitHub Desktop.
hipchat support #593
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
config/config.go | |
@@ -96,6 +96,7 @@ type Config struct { | |
EMail SMTPConf | |
Slack SlackConf | |
// config追加 | |
+ HipChat HipChatConf | |
Syslog SyslogConf | |
Default ServerInfo | |
Servers map[string]ServerInfo | |
@@ -263,6 +264,10 @@ func (c Config) ValidateOnReport() bool { | |
errs = append(errs, slackerrs...) | |
} | |
// 確かconfig validate的なコマンドがあって、hipchatのconfig validateも呼ぶように追加 | |
// そんなコマンドはないかも。ただ-to-hipchatオプションを付けたのにhipchatの設定がない場合 | |
// エラーが出ると思うので、そのへんの処理。 | |
+ if hipchaterrs := c.HipChat.Validate(); 0 < len(hipchaterrs) { | |
+ errs = append(errs, hipchaterrs...) | |
+ } | |
+ | |
if syslogerrs := c.Syslog.Validate(); 0 < len(syslogerrs) { | |
errs = append(errs, syslogerrs...) | |
} | |
@@ -451,6 +456,30 @@ func (c *SlackConf) Validate() (errs []error) { | |
return | |
} | |
// tomlのhip chat configを受け取る構造体 | |
+// HipChatConf is HipChat config | |
+type HipChatConf struct { | |
+ AuthToken string `json:"AuthToken"` | |
+ Room string `json:"Room"` | |
+} | |
+ | |
// configのvalidate処理 | |
+// Validate validates configuration | |
+func (c *HipChatConf) Validate() (errs []error) { | |
+ if len(c.Room) == 0 { | |
+ errs = append(errs, fmt.Errorf("room must not be empty")) | |
+ } | |
+ | |
+ if len(c.AuthToken) == 0 { | |
+ errs = append(errs, fmt.Errorf("AuthToken must not be empty")) | |
+ } | |
+ | |
+ _, err := valid.ValidateStruct(c) | |
+ if err != nil { | |
+ errs = append(errs, err) | |
+ } | |
+ | |
+ return | |
+} | |
+ | |
// SyslogConf is syslog config | |
type SyslogConf struct { | |
Protocol string |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// HipChatWriterの定義。Writeメソッドを定義して、vuls report -to-hipchatを実行されたとき、標準出力に加えてhipchatにもoutputする的なやつ。 | |
// ChatWorkWriterを作って、WriteでChatwork APIを呼べばおk | |
@@ -0,0 +1,70 @@ | |
+package report | |
+ | |
+import ( | |
+ "fmt" | |
+ "net/http" | |
+ "net/url" | |
+ "strconv" | |
+ "strings" | |
+ | |
+ "github.com/future-architect/vuls/config" | |
+ "github.com/future-architect/vuls/models" | |
+) | |
+ | |
+// HipChatWriter send report to HipChat | |
+type HipChatWriter struct{} | |
+ | |
+func (w HipChatWriter) Write(rs ...models.ScanResult) (err error) { | |
// tomlをパースしてconfig.Conf.HipChatに設定値が入るので取得。 | |
+ conf := config.Conf.HipChat | |
+ | |
+ var message string | |
+ for _, r := range rs { | |
// api call.まずはサーバー名を投稿しているっぽい。 | |
+ err = postMessage(conf.Room, conf.AuthToken, r.ServerName) | |
+ if err != nil { | |
+ return err | |
+ } | |
+ | |
// メッセージ組み立て処理、CVEの値をループ | |
+ for _, vinfo := range r.ScannedCves { | |
+ maxCvss := vinfo.MaxCvssScore() | |
+ severity := strings.ToUpper(maxCvss.Value.Severity) | |
+ if severity == "" { | |
+ severity = "?" | |
+ } | |
+ | |
// メッセージ生成 | |
+ message = `<a href="https://nvd.nist.gov/vuln/detail\">` + vinfo.CveID + "</a>" + "<br/>" + strconv.FormatFloat(maxCvss.Value.Score, 'f', 1, 64) + " " + "(" + severity + ")" + "<br/>" + vinfo.Summaries(config.Conf.Lang, r.Family)[0].Value | |
+ | |
// hipchat api call | |
+ err = postMessage(conf.Room, conf.AuthToken, message) | |
+ if err != nil { | |
+ return err | |
+ } | |
+ } | |
+ | |
+ } | |
+ return nil | |
+} | |
+ | |
+func postMessage(room, token, message string) error { | |
// hip chat api url生成、token埋め込み | |
+ uri := fmt.Sprintf("https://api.hipchat.com/v2/room/%s/notification?auth_token=%s", room, token) | |
+ | |
// payload生成 | |
+ payload := url.Values{ | |
+ "color": {"purple"}, | |
+ "message_format": {"html"}, | |
+ "message": {message}, | |
+ } | |
// hip chatにpayloadを添えてPOST | |
+ reqs, err := http.NewRequest("POST", uri, strings.NewReader(payload.Encode())) | |
+ | |
+ reqs.Header.Add("Content-Type", "application/x-www-form-urlencoded") | |
+ | |
+ if err != nil { | |
+ return err | |
+ } | |
+ client := &http.Client{} | |
+ | |
// ここでHTTP Requestをなげる | |
+ resp, err := client.Do(reqs) | |
+ if err != nil { | |
+ return err | |
+ } | |
// もうメソッド終わるのでdefer つけなくていいけどhttp body readerをclose | |
// deferをメソッドの頭につけると、この関数を抜ける(return)するときに必ず呼び出されるようになる。 | |
// もう直後でreturnしているのでdeferなくても良い。慣習的にやっているだけ。 | |
+ defer resp.Body.Close() | |
+ | |
+ return nil | |
+} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//https://github.com/future-architect/vuls/pull/593/files | |
7 commands/report.go | |
@@ -57,6 +57,7 @@ type ReportCmd struct { | |
ovalDBURL string | |
toSlack bool | |
// toHipChatオプションの変数追加 | |
+ toHipChat bool | |
toEMail bool | |
toSyslog bool | |
toLocalFile bool | |
@@ -114,6 +115,7 @@ func (*ReportCmd) Usage() string { | |
[-ignore-unfixed] | |
[-to-email] | |
[-to-slack] | |
// vuls report --helpやvuls report --helpを実行したときに表示されるusageに-to-hipchatオプションがある旨を追記している | |
+ [-to-hipchat] | |
[-to-localfile] | |
[-to-s3] | |
[-to-azure-blob] | |
@@ -264,6 +266,7 @@ func (p *ReportCmd) SetFlags(f *flag.FlagSet) { | |
f.BoolVar(&p.gzip, "gzip", false, "gzip compression") | |
f.BoolVar(&p.toSlack, "to-slack", false, "Send report via Slack") | |
// コマンドラインオプションを受け取って、初めの方で定義した to-hipchat にbooleanの値を入れている | |
+ f.BoolVar(&p.toHipChat, "to-hipchat", false, "Send report via hipchat") | |
f.BoolVar(&p.toEMail, "to-email", false, "Send report via Email") | |
f.BoolVar(&p.toSyslog, "to-syslog", false, "Send report via Syslog") | |
f.BoolVar(&p.toLocalFile, | |
@@ -361,6 +364,10 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{} | |
reports = append(reports, report.SlackWriter{}) | |
} | |
// toHipChatがtureだったらreport.HipChatWriterをreportsに入れる的な。 | |
// reportsの型は[]report.ResultWriterで、多分どっかでreportsのループ回してそれぞれの変数に対して.Write()を実行している | |
// ReportWriterはWrite(.../models.ScanResut)のメソッドを実装していないといけない。 | |
// | |
// | |
// type ResultWriter interface { | |
// Write(...models.ScanResult) error | |
// } | |
// | |
// chatworkに通知を飛ばしたいのであれば、ChatWorkWriter構造体を作って、Writeメソッドを生やしてここに追加すればおk | |
+ if p.toHipChat { | |
+ reports = append(reports, report.HipChatWriter{}) | |
+ } | |
+ | |
if p.toEMail { | |
reports = append(reports, report.EMailWriter{}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -44,6 +44,7 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error { | |
Conf.EMail = conf.EMail | |
Conf.Slack = conf.Slack | |
// tomlってる | |
+ Conf.HipChat = conf.HipChat | |
Conf.Syslog = conf.Syslog | |
d := conf.Default |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment