diff --git a/cmd/common.go b/cmd/common.go index de24273..9297ea7 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -15,6 +15,7 @@ package cmd import ( + "bufio" "fmt" "io/ioutil" "os" @@ -112,7 +113,7 @@ func runChecks(nodetype check.NodeType) { exitWithError(fmt.Errorf("failed to output in JSON format: %v", err)) } - fmt.Println(string(out)) + PrintOutput(string(out), outputFile) } else { // if we want to store in PostgreSQL, convert to JSON and save it if (summary.Fail > 0 || summary.Warn > 0 || summary.Pass > 0 || summary.Info > 0) && pgSQL { @@ -251,3 +252,26 @@ func printRawOutput(output string) { fmt.Println(fmt.Sprintf("\t %s", row)) } } + +func writeOutputToFile(output string, outputFile string) error { + file, err := os.Create(outputFile) + if err != nil { + return err + } + defer file.Close() + + w := bufio.NewWriter(file) + fmt.Fprintln(w, output) + return w.Flush() +} + +func PrintOutput(output string, outputFile string) { + if len(outputFile) == 0 { + fmt.Println(output) + } else { + err := writeOutputToFile(output, outputFile) + if err != nil { + exitWithError(fmt.Errorf("Failed to write to output file %s: %v", outputFile, err)) + } + } +} diff --git a/cmd/root.go b/cmd/root.go index 7b09fcd..41973fd 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -47,7 +47,8 @@ var ( noSummary bool noRemediations bool filterOpts FilterOpts - includeTestOutput bool + includeTestOutput bool + outputFile string ) // RootCmd represents the base command when called without any subcommands @@ -89,6 +90,7 @@ func init() { RootCmd.PersistentFlags().BoolVar(&filterOpts.Scored, "scored", true, "Run the scored CIS checks") RootCmd.PersistentFlags().BoolVar(&filterOpts.Unscored, "unscored", true, "Run the unscored CIS checks") RootCmd.PersistentFlags().BoolVar(&includeTestOutput, "include-test-output", false, "Prints the actual result when test fails") + RootCmd.PersistentFlags().StringVar(&outputFile, "outputfile", "", "Writes the JSON results to output file") RootCmd.PersistentFlags().StringVarP( &filterOpts.CheckList,