Add JSONWriter, Fix CVE sort order of report
This commit is contained in:
@@ -20,18 +20,43 @@ package report
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/future-architect/vuls/models"
|
||||
)
|
||||
|
||||
// JSONWriter writes report as JSON format
|
||||
// JSONWriter writes results to file.
|
||||
type JSONWriter struct{}
|
||||
|
||||
func (w JSONWriter) Write(scanResults []models.ScanResult) (err error) {
|
||||
var j []byte
|
||||
if j, err = json.MarshalIndent(scanResults, "", " "); err != nil {
|
||||
return
|
||||
|
||||
path, err := ensureResultDir()
|
||||
|
||||
var jsonBytes []byte
|
||||
if jsonBytes, err = json.MarshalIndent(scanResults, "", " "); err != nil {
|
||||
return fmt.Errorf("Failed to Marshal to JSON: %s", err)
|
||||
}
|
||||
all := filepath.Join(path, "all.json")
|
||||
if err := ioutil.WriteFile(all, jsonBytes, 0644); err != nil {
|
||||
return fmt.Errorf("Failed to write JSON. path: %s, err: %s", all, err)
|
||||
}
|
||||
|
||||
for _, r := range scanResults {
|
||||
jsonPath := ""
|
||||
if r.Container.ContainerID == "" {
|
||||
jsonPath = filepath.Join(path, fmt.Sprintf("%s.json", r.ServerName))
|
||||
} else {
|
||||
jsonPath = filepath.Join(path,
|
||||
fmt.Sprintf("%s_%s.json", r.ServerName, r.Container.Name))
|
||||
|
||||
}
|
||||
if jsonBytes, err = json.MarshalIndent(r, "", " "); err != nil {
|
||||
return fmt.Errorf("Failed to Marshal to JSON: %s", err)
|
||||
}
|
||||
if err := ioutil.WriteFile(jsonPath, jsonBytes, 0644); err != nil {
|
||||
return fmt.Errorf("Failed to write JSON. path: %s, err: %s", all, err)
|
||||
}
|
||||
}
|
||||
fmt.Println(string(j))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -113,9 +113,8 @@ func toSlackAttachments(scanResult models.ScanResult) (attaches []*attachment) {
|
||||
if !config.Conf.IgnoreUnscoredCves {
|
||||
cves = append(cves, scanResult.UnknownCves...)
|
||||
}
|
||||
scanResult.KnownCves = cves
|
||||
|
||||
for _, cveInfo := range scanResult.KnownCves {
|
||||
for _, cveInfo := range cves {
|
||||
cveID := cveInfo.CveDetail.CveID
|
||||
|
||||
curentPackages := []string{}
|
||||
@@ -176,8 +175,7 @@ func attachmentText(cveInfo models.CveInfo, osFamily string) string {
|
||||
|
||||
switch {
|
||||
case config.Conf.Lang == "ja" &&
|
||||
cveInfo.CveDetail.Jvn.ID != 0 &&
|
||||
0 < cveInfo.CveDetail.CvssScore("ja"):
|
||||
0 < cveInfo.CveDetail.Jvn.CvssScore():
|
||||
|
||||
jvn := cveInfo.CveDetail.Jvn
|
||||
return fmt.Sprintf("*%4.1f (%s)* <%s|%s>\n%s\n%s",
|
||||
|
||||
@@ -20,13 +20,44 @@ package report
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/gosuri/uitable"
|
||||
)
|
||||
|
||||
func ensureResultDir() (path string, err error) {
|
||||
if resultDirPath != "" {
|
||||
return resultDirPath, nil
|
||||
}
|
||||
|
||||
const timeLayout = "20060102_1504"
|
||||
timedir := time.Now().Format(timeLayout)
|
||||
wd, _ := os.Getwd()
|
||||
dir := filepath.Join(wd, "results", timedir)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
return "", fmt.Errorf("Failed to create dir: %s", err)
|
||||
}
|
||||
|
||||
symlinkPath := filepath.Join(wd, "results", "current")
|
||||
if _, err := os.Stat(symlinkPath); err == nil {
|
||||
if err := os.Remove(symlinkPath); err != nil {
|
||||
return "", fmt.Errorf(
|
||||
"Failed to remove symlink. path: %s, err: %s", symlinkPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.Symlink(dir, symlinkPath); err != nil {
|
||||
return "", fmt.Errorf(
|
||||
"Failed to create symlink: path: %s, err: %s", symlinkPath, err)
|
||||
}
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
func toPlainText(scanResult models.ScanResult) (string, error) {
|
||||
serverInfo := scanResult.ServerInfo()
|
||||
|
||||
@@ -83,8 +114,7 @@ func ToPlainTextSummary(r models.ScanResult) string {
|
||||
|
||||
switch {
|
||||
case config.Conf.Lang == "ja" &&
|
||||
d.CveDetail.Jvn.ID != 0 &&
|
||||
0 < d.CveDetail.CvssScore("ja"):
|
||||
0 < d.CveDetail.Jvn.CvssScore():
|
||||
|
||||
summary := d.CveDetail.Jvn.Title
|
||||
scols = []string{
|
||||
@@ -121,12 +151,11 @@ func ToPlainTextSummary(r models.ScanResult) string {
|
||||
return fmt.Sprintf("%s", stable)
|
||||
}
|
||||
|
||||
//TODO Distro Advisory
|
||||
func toPlainTextDetails(data models.ScanResult, osFamily string) (scoredReport, unscoredReport []string) {
|
||||
for _, cve := range data.KnownCves {
|
||||
switch config.Conf.Lang {
|
||||
case "en":
|
||||
if cve.CveDetail.Nvd.ID != 0 {
|
||||
if 0 < cve.CveDetail.Nvd.CvssScore() {
|
||||
scoredReport = append(
|
||||
scoredReport, toPlainTextDetailsLangEn(cve, osFamily))
|
||||
} else {
|
||||
@@ -134,10 +163,10 @@ func toPlainTextDetails(data models.ScanResult, osFamily string) (scoredReport,
|
||||
scoredReport, toPlainTextUnknownCve(cve, osFamily))
|
||||
}
|
||||
case "ja":
|
||||
if cve.CveDetail.Jvn.ID != 0 {
|
||||
if 0 < cve.CveDetail.Jvn.CvssScore() {
|
||||
scoredReport = append(
|
||||
scoredReport, toPlainTextDetailsLangJa(cve, osFamily))
|
||||
} else if cve.CveDetail.Nvd.ID != 0 {
|
||||
} else if 0 < cve.CveDetail.Nvd.CvssScore() {
|
||||
scoredReport = append(
|
||||
scoredReport, toPlainTextDetailsLangEn(cve, osFamily))
|
||||
} else {
|
||||
|
||||
@@ -37,3 +37,5 @@ const (
|
||||
type ResultWriter interface {
|
||||
Write([]models.ScanResult) error
|
||||
}
|
||||
|
||||
var resultDirPath string
|
||||
|
||||
Reference in New Issue
Block a user