Skip to content

Commit

Permalink
Merge pull request #325 from flanksource/csv-export
Browse files Browse the repository at this point in the history
CSV export
  • Loading branch information
moshloop authored Sep 13, 2021
2 parents 27b9910 + e745974 commit 7f4dd67
Show file tree
Hide file tree
Showing 23 changed files with 159 additions and 76 deletions.
1 change: 1 addition & 0 deletions api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion checks/cloudwatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (c *CloudWatchChecker) Type() string {

func (c *CloudWatchChecker) Check(ctx *context.Context, extConfig external.Check) *pkg.CheckResult {
check := extConfig.(v1.CloudWatchCheck)
result := pkg.Success(check)
result := pkg.Success(check, ctx.Canary)
cfg, err := awsUtil.NewSession(ctx, check.AWSConnection)
if err != nil {
return result.ErrorMessage(err)
Expand Down
2 changes: 1 addition & 1 deletion checks/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ var resolvers = map[string]func(ctx context.Context, r *net.Resolver, check v1.D

func (c *DNSChecker) Check(ctx *canaryContext.Context, extConfig external.Check) *pkg.CheckResult {
check := extConfig.(v1.DNSCheck)
result := pkg.Success(check)
result := pkg.Success(check, ctx.Canary)

timeout := check.Timeout
if timeout == 0 {
Expand Down
2 changes: 1 addition & 1 deletion checks/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func getDigestFromOutput(out io.ReadCloser) string {
func (c *DockerPullChecker) Check(ctx *context.Context, extConfig external.Check) *pkg.CheckResult {
check := extConfig.(v1.DockerPullCheck)
namespace := ctx.Canary.Namespace
var result = pkg.Success(check)
var result = pkg.Success(check, ctx.Canary)
var authStr string
auth, err := GetAuthValues(check.Auth, ctx.Kommons, namespace)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion checks/gcs_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type GCS struct {

func (c *GCSBucketChecker) Check(ctx *context.Context, extConfig external.Check) *pkg.CheckResult {
check := extConfig.(v1.GCSBucketCheck)
result := pkg.Success(check)
result := pkg.Success(check, ctx.Canary)
cfg, err := gcp.NewSession(ctx, check.GCPConnection)
if err != nil {
return result.ErrorMessage(err)
Expand Down
2 changes: 1 addition & 1 deletion checks/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (c *HelmChecker) Run(ctx *context.Context) []*pkg.CheckResult {
func (c *HelmChecker) Check(ctx *context.Context, extConfig external.Check) *pkg.CheckResult {
config := extConfig.(v1.HelmCheck)
start := time.Now()
result := pkg.Success(config)
result := pkg.Success(config, ctx.Canary)
var uploadOK, downloadOK = true, true
logger.Tracef("Uploading test chart")
namespace := ctx.Canary.Namespace
Expand Down
2 changes: 1 addition & 1 deletion checks/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func truncate(text string, max int) string {

func (c *HTTPChecker) Check(ctx *context.Context, extConfig external.Check) *pkg.CheckResult {
check := extConfig.(v1.HTTPCheck)
result := pkg.Success(check)
result := pkg.Success(check, ctx.Canary)
if _, err := url.Parse(check.Endpoint); err != nil {
return result.ErrorMessage(err)
}
Expand Down
2 changes: 1 addition & 1 deletion checks/icmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (c *IcmpChecker) Check(ctx *context.Context, extConfig external.Check) *pkg
check := extConfig.(v1.ICMPCheck)
endpoint := check.Endpoint

result := pkg.Success(check)
result := pkg.Success(check, ctx.Canary)

ips, err := dns.Lookup("A", endpoint)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion checks/junit.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ func cleanupExistingPods(ctx *context.Context, k8s kubernetes.Interface, selecto
func (c *JunitChecker) Check(ctx *context.Context, extConfig external.Check) *pkg.CheckResult {
junitCheck := extConfig.(v1.JunitCheck)

result := pkg.Success(junitCheck)
result := pkg.Success(junitCheck, ctx.Canary)
k8s, err := ctx.Kommons.GetClientset()
if err != nil {
return result.ErrorMessage(err)
Expand Down
2 changes: 1 addition & 1 deletion checks/mongodb.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (c *MongoDBChecker) Run(ctx *context.Context) []*pkg.CheckResult {

func (c *MongoDBChecker) Check(ctx *context.Context, extConfig external.Check) *pkg.CheckResult {
check := extConfig.(v1.MongoDBCheck)
result := pkg.Success(check)
result := pkg.Success(check, ctx.Canary)
var err error

connection, err := GetConnection(ctx, &check.Connection, ctx.Namespace)
Expand Down
2 changes: 1 addition & 1 deletion checks/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (c *NamespaceChecker) Run(ctx *context.Context) []*pkg.CheckResult {
c.k8s, err = ctx.Kommons.GetClientset()
c.ctx = ctx
if err != nil {
return []*pkg.CheckResult{pkg.Fail(conf).ErrorMessage(err)}
return []*pkg.CheckResult{pkg.Fail(conf, ctx.Canary).ErrorMessage(err)}
}
}
results = append(results, c.Check(c.ctx, conf))
Expand Down
2 changes: 1 addition & 1 deletion checks/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func (c *PodChecker) Check(ctx *context.Context, extConfig external.Check) *pkg.
podCheck.Namespace = ctx.Namespace
}

result := pkg.Success(podCheck)
result := pkg.Success(podCheck, ctx.Canary)
startTimer := NewTimer()
pods := c.k8s.CoreV1().Pods(podCheck.Namespace)

Expand Down
2 changes: 1 addition & 1 deletion checks/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (c *PrometheusChecker) Run(ctx *context.Context) []*pkg.CheckResult {

func (c *PrometheusChecker) Check(ctx *context.Context, extConfig external.Check) *pkg.CheckResult {
check := extConfig.(v1.PrometheusCheck)
result := pkg.Success(check)
result := pkg.Success(check, ctx.Canary)

promClient, err := prometheus.NewPrometheusAPI(check.Host)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion checks/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (c *RedisChecker) Run(ctx *context.Context) []*pkg.CheckResult {

func (c *RedisChecker) Check(ctx *context.Context, extConfig external.Check) *pkg.CheckResult {
redisCheck := extConfig.(v1.RedisCheck)
result := pkg.Success(redisCheck)
result := pkg.Success(redisCheck, ctx.Canary)
namespace := ctx.Canary.Namespace
var err error
auth, err := GetAuthValues(redisCheck.Auth, ctx.Kommons, namespace)
Expand Down
2 changes: 1 addition & 1 deletion checks/s3_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func (conn *S3) CheckFolder(ctx *context.Context, filter v1.FolderFilter) (*Fold

func (c *S3BucketChecker) Check(ctx *context.Context, extConfig external.Check) *pkg.CheckResult {
bucket := extConfig.(v1.S3BucketCheck)
result := pkg.Success(bucket)
result := pkg.Success(bucket, ctx.Canary)

cfg, err := awsUtil.NewSession(ctx, bucket.AWSConnection)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion checks/smb.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func smbConnect(server string, share string, auth *v1.Authentication) (Filesyste

func (c *SmbChecker) Check(ctx *context.Context, extConfig external.Check) *pkg.CheckResult {
smbCheck := extConfig.(v1.SmbCheck)
result := pkg.Success(smbCheck)
result := pkg.Success(smbCheck, ctx.Canary)
namespace := ctx.Canary.Namespace

server, sharename, path, err := getServerDetails(smbCheck.Server, smbCheck.GetPort())
Expand Down
2 changes: 1 addition & 1 deletion checks/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func querySQL(driver string, connection string, query string) (*SQLDetails, erro
// driver and connection string
// Returns check result and metrics
func CheckSQL(ctx *context.Context, check v1.SQLCheck) *pkg.CheckResult { // nolint: golint
result := pkg.Success(check)
result := pkg.Success(check, ctx.Canary)
connection, err := GetConnection(ctx, &check.Connection, ctx.Namespace)
if err != nil {
return result.ErrorMessage(err)
Expand Down
43 changes: 43 additions & 0 deletions cmd/output/csv.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package output

import (
"strconv"

"github.com/flanksource/canary-checker/pkg"
"github.com/jszwec/csvutil"
)

type CSVResult struct {
Name string `csv:"name"`
Namespace string `csv:"namespace"`
Endpoint string `csv:"endpoint"`
CheckType string `csv:"checkType"`
Pass bool `csv:"pass"`
Duration string `csv:"duration"`
Description string `csv:"description,omitempty"`
Message string `csv:"message,omitempty"`
Error string `csv:"error,omitempty"`
Invalid bool `csv:"invalid,omitempty"`
}

func GetCSVReport(checkResults []*pkg.CheckResult) (string, error) {
var results []CSVResult
for _, checkResult := range checkResults {
result := CSVResult{
Name: checkResult.Canary.Name,
Namespace: checkResult.Canary.Namespace,
Endpoint: checkResult.Check.GetEndpoint(),
CheckType: checkResult.Check.GetType(),
Pass: checkResult.Pass,
Invalid: checkResult.Invalid,
Duration: strconv.Itoa(int(checkResult.Duration)),
Description: checkResult.Check.GetDescription(),
Message: checkResult.Message,
Error: checkResult.Error,
}
results = append(results, result)
}

csv, err := csvutil.Marshal(results)
return string(csv), err
}
47 changes: 47 additions & 0 deletions cmd/output/junit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package output

import (
"strconv"

"github.com/flanksource/canary-checker/pkg"
"github.com/flanksource/commons/console"
"github.com/flanksource/commons/logger"
)

func GetJunitReport(results []*pkg.CheckResult) string {
var testCases []console.JUnitTestCase
var failed int
var totalTime int64
for _, result := range results {
totalTime += result.Duration
testCase := console.JUnitTestCase{
Classname: result.Check.GetType(),
Name: result.Check.GetDescription(),
Time: strconv.Itoa(int(result.Duration)),
}
if !result.Pass {
failed++
testCase.Failure = &console.JUnitFailure{
Message: result.Message,
}
}
testCases = append(testCases, testCase)
}
testSuite := console.JUnitTestSuite{
Tests: len(results),
Failures: failed,
Time: strconv.Itoa(int(totalTime)),
Name: "canary-checker-run",
TestCases: testCases,
}
testSuites := console.JUnitTestSuites{
Suites: []console.JUnitTestSuite{
testSuite,
},
}
report, err := testSuites.ToXML()
if err != nil {
logger.Fatalf("error creating junit results: %v", err)
}
return report
}
18 changes: 18 additions & 0 deletions cmd/output/output.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package output

import (
"fmt"
"io/ioutil"
)

func HandleOutput(report, outputFile string) error {
if outputFile != "" {
err := ioutil.WriteFile(outputFile, []byte(report), 0755)
if err != nil {
return err
}
} else {
fmt.Println(report)
}
return nil
}
69 changes: 20 additions & 49 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ package cmd

import (
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"time"

"github.com/flanksource/commons/console"
"github.com/flanksource/commons/timer"

"github.com/flanksource/canary-checker/cmd/output"
"github.com/spf13/cobra"

"github.com/flanksource/canary-checker/api/context"
Expand All @@ -22,12 +20,13 @@ import (
"github.com/flanksource/commons/logger"
)

var outputFile string
var junit, csv bool

var Run = &cobra.Command{
Use: "run <canary.yaml>",
Short: "Execute checks and return",
Run: func(cmd *cobra.Command, configFiles []string) {
namespace, _ := cmd.Flags().GetString("namespace")
junitFile, _ := cmd.Flags().GetString("junit-file")
timer := timer.NewTimer()
if len(configFiles) == 0 {
log.Fatalln("Must specify at least one canary")
Expand Down Expand Up @@ -83,11 +82,19 @@ var Run = &cobra.Command{
}
}

if junitFile != "" {
report := getJunitReport(results)
err := ioutil.WriteFile(junitFile, []byte(report), 0755)
if junit {
report := output.GetJunitReport(results)
if err := output.HandleOutput(report, outputFile); err != nil {
logger.Fatalf("error writing output file: %v", err)
}
}
if csv {
report, err := output.GetCSVReport(results)
if err != nil {
logger.Fatalf("%d checks failed", failed)
logger.Fatalf("error generating CSV file: %v", err)
}
if err := output.HandleOutput(report, outputFile); err != nil {
logger.Fatalf("error writing output file: %v", err)
}
}

Expand All @@ -100,46 +107,10 @@ var Run = &cobra.Command{
}

func init() {
Run.Flags().StringP("namespace", "n", "", "Specify namespace")
Run.Flags().StringP("junit", "j", "", "Export JUnit XML formatted results to this file e.g: junit.xml")
}

func getJunitReport(results []*pkg.CheckResult) string {
var testCases []console.JUnitTestCase
var failed int
var totalTime int64
for _, result := range results {
totalTime += result.Duration
testCase := console.JUnitTestCase{
Classname: result.Check.GetType(),
Name: result.Check.GetDescription(),
Time: strconv.Itoa(int(result.Duration)),
}
if !result.Pass {
failed++
testCase.Failure = &console.JUnitFailure{
Message: result.Message,
}
}
testCases = append(testCases, testCase)
}
testSuite := console.JUnitTestSuite{
Tests: len(results),
Failures: failed,
Time: strconv.Itoa(int(totalTime)),
Name: "canary-checker-run",
TestCases: testCases,
}
testSuites := console.JUnitTestSuites{
Suites: []console.JUnitTestSuite{
testSuite,
},
}
report, err := testSuites.ToXML()
if err != nil {
logger.Fatalf("error creating junit results: %v", err)
}
return report
Run.Flags().StringVarP(&namespace, "namespace", "n", "", "Namespace to run canary checks in")
Run.Flags().StringVarP(&outputFile, "output-file", "o", "", "file to output the results in")
Run.Flags().BoolVarP(&junit, "junit", "j", false, "output results in junit format")
Run.Flags().BoolVar(&csv, "csv", false, "output results in csv format")
}

func CleanupFilename(fileName string) string {
Expand Down
3 changes: 2 additions & 1 deletion pkg/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ type CheckResult struct {
Error string
Metrics []Metric
// Check is the configuration
Check external.Check
Check external.Check
Canary v1.Canary
}

func (result CheckResult) GetDescription() string {
Expand Down
Loading

0 comments on commit 7f4dd67

Please sign in to comment.