go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/cli/reporter/json.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package reporter
     5  
     6  import (
     7  	"encoding/json"
     8  	"errors"
     9  
    10  	"go.mondoo.com/cnquery/explorer"
    11  	"go.mondoo.com/cnquery/llx"
    12  	"go.mondoo.com/cnquery/shared"
    13  )
    14  
    15  func BundleResultsToJSON(code *llx.CodeBundle, results map[string]*llx.RawResult, out shared.OutputHelper) error {
    16  	var checksums []string
    17  	eps := code.CodeV2.Entrypoints()
    18  	checksums = make([]string, len(eps))
    19  	for i, ref := range eps {
    20  		checksums[i] = code.CodeV2.Checksums[ref]
    21  	}
    22  
    23  	// since we iterate over checksums, we run into the situation that this could be a slice
    24  	// eg. cnquery run k8s --query "platform { name } k8s.pod.name" --json
    25  
    26  	out.WriteString("{")
    27  
    28  	for j, checksum := range checksums {
    29  		result := results[checksum]
    30  		if result == nil {
    31  			llx.JSONerror(errors.New("cannot find result for this query"))
    32  		} else {
    33  			jsonData := result.Data.JSONfield(checksum, code)
    34  			out.Write(jsonData)
    35  		}
    36  
    37  		if len(checksums) != j+1 {
    38  			out.WriteString(",")
    39  		}
    40  	}
    41  
    42  	out.WriteString("}")
    43  
    44  	return nil
    45  }
    46  
    47  func ReportCollectionToJSON(data *explorer.ReportCollection, out shared.OutputHelper) error {
    48  	if data == nil {
    49  		return nil
    50  	}
    51  
    52  	queryMrnIdx := map[string]string{}
    53  
    54  	// this case can happen when all assets error out, eg. no query pack is available that matches
    55  	if data.Bundle != nil {
    56  		for i := range data.Bundle.Packs {
    57  			pack := data.Bundle.Packs[i]
    58  			for j := range pack.Queries {
    59  				query := pack.Queries[j]
    60  				queryMrnIdx[query.CodeId] = query.Mrn
    61  			}
    62  		}
    63  	}
    64  
    65  	out.WriteString(
    66  		"{" +
    67  			"\"assets\":")
    68  	assets, err := json.Marshal(data.Assets)
    69  	if err != nil {
    70  		return err
    71  	}
    72  	out.WriteString(string(assets))
    73  
    74  	out.WriteString("," +
    75  		"\"data\":" +
    76  		"{")
    77  	pre := ""
    78  	for id, report := range data.Reports {
    79  		out.WriteString(pre + llx.PrettyPrintString(id) + ":{")
    80  		pre = ","
    81  
    82  		resolved, ok := data.Resolved[id]
    83  		if !ok {
    84  			return errors.New("cannot find resolved pack for " + id + " in report")
    85  		}
    86  
    87  		results := report.RawResults()
    88  		pre2 := ""
    89  		for qid, query := range resolved.ExecutionJob.Queries {
    90  			printID := queryMrnIdx[qid]
    91  			if printID == "" {
    92  				printID = qid
    93  			}
    94  
    95  			out.WriteString(pre2 + llx.PrettyPrintString(printID) + ":")
    96  			pre2 = ","
    97  
    98  			err := BundleResultsToJSON(query.Code, results, out)
    99  			if err != nil {
   100  				return err
   101  			}
   102  		}
   103  		out.WriteString("}")
   104  	}
   105  
   106  	out.WriteString("}," +
   107  		"\"errors\":" +
   108  		"{")
   109  	pre = ""
   110  	for id, errStatus := range data.Errors {
   111  		out.WriteString(pre + llx.PrettyPrintString(id) + ":" + llx.PrettyPrintString(errStatus.Message))
   112  		pre = ","
   113  	}
   114  	out.WriteString("}}")
   115  
   116  	return nil
   117  }