github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/ui/dashboard/src/components/dashboards/check/common/Benchmark.ts (about)

     1  import Control from "./Control";
     2  import merge from "lodash/merge";
     3  import padStart from "lodash/padStart";
     4  import {
     5    AddControlResultsAction,
     6    CheckControlRun,
     7    CheckDynamicColsMap,
     8    CheckNode,
     9    CheckNodeStatus,
    10    CheckNodeType,
    11    CheckResult,
    12    CheckSeveritySummary,
    13    CheckSummary,
    14  } from "./index";
    15  import { DashboardLayoutNode, PanelsMap } from "../../../../types";
    16  import {
    17    LeafNodeData,
    18    LeafNodeDataColumn,
    19    LeafNodeDataRow,
    20  } from "../../common";
    21  
    22  class Benchmark implements CheckNode {
    23    private readonly _sortIndex: string;
    24    private readonly _name: string;
    25    private readonly _title: string;
    26    private readonly _description?: string;
    27    private readonly _benchmarks: Benchmark[];
    28    private readonly _controls: Control[];
    29    private readonly _add_control_results: AddControlResultsAction;
    30    private readonly _all_control_results: CheckResult[];
    31  
    32    constructor(
    33      sortIndex: string,
    34      name: string,
    35      title: string | undefined,
    36      description: string | undefined,
    37      benchmarks: DashboardLayoutNode[] | undefined,
    38      controls: DashboardLayoutNode[] | undefined,
    39      panelsMap: PanelsMap,
    40      trunk: Benchmark[],
    41      add_control_results?: AddControlResultsAction
    42    ) {
    43      this._sortIndex = sortIndex;
    44      this._all_control_results = [];
    45      this._name = name;
    46      this._title = title || name;
    47      this._description = description;
    48  
    49      if (!add_control_results) {
    50        this._add_control_results = this.add_control_results;
    51      } else {
    52        this._add_control_results = add_control_results;
    53      }
    54  
    55      const thisTrunk = [...trunk, this];
    56      const nestedBenchmarks: Benchmark[] = [];
    57      const benchmarksToAdd = benchmarks || [];
    58      const lengthMaxBenchmarkIndex = (benchmarksToAdd.length - 1).toString()
    59        .length;
    60      benchmarksToAdd.forEach((nestedBenchmark, benchmarkIndex) => {
    61        const nestedDefinition = panelsMap[nestedBenchmark.name];
    62        // @ts-ignore
    63        const benchmarks = nestedBenchmark.children?.filter(
    64          (child) => child.panel_type === "benchmark"
    65        );
    66        // @ts-ignore
    67        const controls = nestedBenchmark.children?.filter(
    68          (child) => child.panel_type === "control"
    69        );
    70        nestedBenchmarks.push(
    71          new Benchmark(
    72            `benchmark-${padStart(
    73              benchmarkIndex.toString(),
    74              lengthMaxBenchmarkIndex
    75            )}`,
    76            nestedDefinition.name,
    77            nestedDefinition.title,
    78            nestedDefinition.description,
    79            benchmarks,
    80            controls,
    81            panelsMap,
    82            thisTrunk,
    83            this._add_control_results
    84          )
    85        );
    86      });
    87      const nestedControls: Control[] = [];
    88      const controlsToAdd = controls || [];
    89      const lengthMaxControlIndex = (controlsToAdd.length - 1).toString().length;
    90      controlsToAdd.forEach((nestedControl, controlIndex) => {
    91        // @ts-ignore
    92        const control = panelsMap[nestedControl.name] as CheckControlRun;
    93        nestedControls.push(
    94          new Control(
    95            `control-${padStart(controlIndex.toString(), lengthMaxControlIndex)}`,
    96            this._name,
    97            this._title,
    98            this._description,
    99            control.name,
   100            control.title,
   101            control.description,
   102            control.properties?.severity || control.severity,
   103            control.data,
   104            control.summary,
   105            control.tags,
   106            control.status,
   107            control.error,
   108            panelsMap,
   109            thisTrunk,
   110            this._add_control_results
   111          )
   112        );
   113      });
   114      this._benchmarks = nestedBenchmarks;
   115      this._controls = nestedControls;
   116    }
   117  
   118    private add_control_results = (results: CheckResult[]) => {
   119      this._all_control_results.push(...results);
   120    };
   121  
   122    get all_control_results(): CheckResult[] {
   123      return this._all_control_results;
   124    }
   125  
   126    get sort(): string {
   127      return `${this._sortIndex}-${this.title}`;
   128    }
   129  
   130    get name(): string {
   131      return this._name;
   132    }
   133  
   134    get title(): string {
   135      return this._title || this._name;
   136    }
   137  
   138    get type(): CheckNodeType {
   139      return "benchmark";
   140    }
   141  
   142    get children(): CheckNode[] {
   143      return [...this._benchmarks, ...this._controls];
   144    }
   145  
   146    get benchmarks(): Benchmark[] {
   147      return this._benchmarks;
   148    }
   149  
   150    get controls(): Control[] {
   151      return this._controls;
   152    }
   153  
   154    get summary(): CheckSummary {
   155      const summary = {
   156        alarm: 0,
   157        ok: 0,
   158        info: 0,
   159        skip: 0,
   160        error: 0,
   161      };
   162      for (const benchmark of this._benchmarks) {
   163        const nestedSummary = benchmark.summary;
   164        summary.alarm += nestedSummary.alarm;
   165        summary.ok += nestedSummary.ok;
   166        summary.info += nestedSummary.info;
   167        summary.skip += nestedSummary.skip;
   168        summary.error += nestedSummary.error;
   169      }
   170      for (const control of this._controls) {
   171        const nestedSummary = control.summary;
   172        summary.alarm += nestedSummary.alarm;
   173        summary.ok += nestedSummary.ok;
   174        summary.info += nestedSummary.info;
   175        summary.skip += nestedSummary.skip;
   176        summary.error += nestedSummary.error;
   177      }
   178      return summary;
   179    }
   180  
   181    get severity_summary(): CheckSeveritySummary {
   182      return {};
   183    }
   184  
   185    get status(): CheckNodeStatus {
   186      for (const benchmark of this._benchmarks) {
   187        if (benchmark.status === "running") {
   188          return "running";
   189        }
   190      }
   191      for (const control of this._controls) {
   192        if (control.status === "running") {
   193          return "running";
   194        }
   195      }
   196      return "complete";
   197    }
   198  
   199    get_data_table(): LeafNodeData {
   200      const columns: LeafNodeDataColumn[] = [
   201        {
   202          name: "group_id",
   203          data_type: "TEXT",
   204        },
   205        {
   206          name: "title",
   207          data_type: "TEXT",
   208        },
   209        {
   210          name: "description",
   211          data_type: "TEXT",
   212        },
   213        {
   214          name: "control_id",
   215          data_type: "TEXT",
   216        },
   217        {
   218          name: "control_title",
   219          data_type: "TEXT",
   220        },
   221        {
   222          name: "control_description",
   223          data_type: "TEXT",
   224        },
   225        {
   226          name: "severity",
   227          data_type: "TEXT",
   228        },
   229        {
   230          name: "reason",
   231          data_type: "TEXT",
   232        },
   233        {
   234          name: "resource",
   235          data_type: "TEXT",
   236        },
   237        {
   238          name: "status",
   239          data_type: "TEXT",
   240        },
   241      ];
   242      const { dimensions, tags } = this.get_dynamic_cols();
   243      Object.keys(tags).forEach((tag) =>
   244        columns.push({
   245          name: tag,
   246          data_type: "TEXT",
   247        })
   248      );
   249      Object.keys(dimensions).forEach((dimension) =>
   250        columns.push({
   251          name: dimension,
   252          data_type: "TEXT",
   253        })
   254      );
   255      const rows = this.get_data_rows(Object.keys(tags), Object.keys(dimensions));
   256      // let rows: LeafNodeDataRow[] = [];
   257      // this._benchmarks.forEach(benchmark => {
   258      //   rows = [...rows, ...benchmark.get_data_rows()]
   259      // })
   260      // this._controls.forEach(control => {
   261      //   rows = [...rows, ...control.get_data_rows()]
   262      // })
   263  
   264      return {
   265        columns,
   266        rows,
   267      };
   268    }
   269  
   270    get_dynamic_cols(): CheckDynamicColsMap {
   271      let keys = {
   272        dimensions: {},
   273        tags: {},
   274      };
   275      this._benchmarks.forEach((benchmark) => {
   276        const subBenchmarkKeys = benchmark.get_dynamic_cols();
   277        keys = merge(keys, subBenchmarkKeys);
   278      });
   279      this._controls.forEach((control) => {
   280        const controlKeys = control.get_dynamic_cols();
   281        keys = merge(keys, controlKeys);
   282      });
   283      return keys;
   284    }
   285  
   286    get_data_rows(tags: string[], dimensions: string[]): LeafNodeDataRow[] {
   287      let rows: LeafNodeDataRow[] = [];
   288      this._benchmarks.forEach((benchmark) => {
   289        rows = [...rows, ...benchmark.get_data_rows(tags, dimensions)];
   290      });
   291      this._controls.forEach((control) => {
   292        rows = [...rows, ...control.get_data_rows(tags, dimensions)];
   293      });
   294      return rows;
   295    }
   296  }
   297  
   298  export default Benchmark;