github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/ui/dashboard/spec.md (about)

     1  # Mods & Reports
     2  
     3  ## Resource Types
     4  
     5  You can compose reports using a number of resource types.
     6  
     7  | Name        | Purpose                                                                                                                                                           | Valid children types                                                                                               | Allowed at top-level |
     8  | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------------------- |
     9  | `report`    | A way to compose resources to meet a reporting requirement. Within the Steampipe reporting UIs, each `report` will be presented as an available item to run.      | `chart`<br/>`container`<br/>`control`<br/>`counter`<br/>`hierarchy`<br/>`image`<br/>`input`<br/>`table`<br/>`text` | Yes                  |
    10  | `container` | Conceptually identical to a report, except it will not be presented as an available item to run within the Steampipe reporting UIs.                               | `chart`<br/>`container`<br/>`control`<br/>`counter`<br/>`hierarchy`<br/>`image`<br/>`input`<br/>`table`<br/>`text` | Yes                  |
    11  | `chart`     | Chart SQL data in a number of ways e.g. `bar`, `column`, `line`, `pie` etc.                                                                                       | None                                                                                                               | Yes                  |
    12  | `control`   | Allow mod controls to be defined or re-used in reports.                                                                                                           | None                                                                                                               | Yes                  |
    13  | `counter`   | Allow anything from a simple value to change in value to be presented in different styles e.g. `plain`, `alert` etc. Supports static values, or derived from SQL. | None                                                                                                               | Yes                  |
    14  | `hierarchy` | Visualise hierarchical data using things such as `sankey` or `graph`.                                                                                             | None                                                                                                               | Yes                  |
    15  | `image`     | Allow embedding of images in reports. Supports static URLs, or can be derived from SQL.                                                                           | None                                                                                                               | Yes                  |
    16  | `input`     | Allow dynamic reporting based on user-provided `input`.                                                                                                           | None                                                                                                               | Yes                  |
    17  | `table`     | Show tabular data in a report.                                                                                                                                    | None                                                                                                               | Yes                  |
    18  | `text`      | Allow GitHub-flavoured markdown to be added to a report.                                                                                                          | None                                                                                                               | Yes                  |
    19  | more TBD... |                                                                                                                                                                   |                                                                                                                    |                      |
    20  
    21  ## Spec
    22  
    23  ### `report`
    24  
    25  A report is designed to be used by consumers of your mod to answer specific reporting questions, such as "How many public AWS buckets do I have?" or "Show me the number of aging Zendesk tickets by owner".
    26  
    27  Reports can only be declared at the top-level of a mod and can be re-used by using a `container`.
    28  
    29  For layout, a report consists of 12 grid units, where items inside it will consume the full 12 grid units, unless they specific an explicit [width](#width).
    30  
    31  #### Properties
    32  
    33  - `title`: Plain text title used to display in lists, page title etc. When viewing the report in a browser, will be rendered as a h1.
    34  
    35  #### Examples
    36  
    37  ```hcl
    38  report hello_world {
    39    text {
    40      value = "# Hello world!"
    41    }
    42  }
    43  ```
    44  
    45  ```hcl
    46  # Existing report re-used with `base`
    47  report compose_other {
    48    container {
    49      base = report.hello_world
    50    }
    51  }
    52  ```
    53  
    54  ### `container`
    55  
    56  A container is intended to be used to group/lay-out related items within a report. For example, you may want to group together a number of different charts for a specific AWS service.
    57  
    58  Containers can be declared as named resources at the top level of a mod, or be declared as anonymous blocks inside a `report` or `container`, or be re-used inside a `report` or `container` by using a `container` with `base = <mod>.container.<container_resource_name>`.
    59  
    60  #### Properties
    61  
    62  - `base`: A reference to a named `report` or `container` that this `container` should source its definition from. `title` and `width` can be overridden after sourcing via `base`.
    63  - `title`: A container title is a shorthand convenience for adding a `text` block with a h2 Markdown heading and wrapping both items in a container. E.g. a title of `AWS S3 Metrics` would end up as:
    64  
    65  ```hcl
    66  container {
    67    text {
    68      value = "## AWS S3 Metrics"
    69    }
    70  
    71    container {
    72      # Original container containing the title here...
    73    }
    74  }
    75  ```
    76  
    77  - `width`: See [width](#width).
    78  
    79  #### Examples
    80  
    81  ```hcl
    82  # Simple container with a text markdown panel
    83  
    84  container {
    85    text {
    86      value = "## AWS S3 Metrics"
    87    }
    88  }
    89  ```
    90  
    91  ```hcl
    92  # Full-width container with 2 side-by-side containers on larger screens.
    93  
    94  container {
    95    container {
    96      width = 6
    97      text {
    98        value = "## First text"
    99      }
   100    }
   101  
   102    container {
   103      width = 6
   104      text {
   105        value = "## Second text"
   106      }
   107    }
   108  }
   109  ```
   110  
   111  ```hcl
   112  # Re-use an existing named top-level container and override its width.
   113  
   114  container {
   115    base  = container.some_other_container
   116    width = 6
   117  }
   118  ```
   119  
   120  ### `chart`
   121  
   122  A chart will allow visualisation of queries in a variety of charting types such as `bar`, `column`, `donut`, `line` or `pie`.
   123  
   124  The chart types share key things such as shape of the date and common configuration, so by having a single `chart` type, this allows us to be flexible. For example, you could simply change the type of chart from `bar` to `line` and it will just work, or we could allow in the reporting UI for a user to switch the chart type - all made possible by having a consistent data structure and commonality across the charts.
   125  
   126  Chart blocks can be declared as named resources at the top level of a mod, or be declared as anonymous blocks inside a `report` or `container`, or be re-used inside a `report` or `container` by using a `chart` with `base = <mod>.chart.<chart_resource_name>`.
   127  
   128  #### Properties
   129  
   130  - `base`: A reference to a named `chart` resource that this `chart` should source its definition from. `title` and `width` can be overridden after sourcing via `base`.
   131  - `title`: As per the title for a `container` or `chart`, except as this is a leaf is rendered as h3.
   132  - `type`: The type of the chart. Can be `bar`, `column`, `donut`, `line` or `pie`.
   133  - `sql`: Inline SQL or named query.
   134  - `width`: See [width](#width).
   135  - `legend`: See [legend](#legend).
   136  - `series`: A named block matching the name of the series you wish to configure. See `Series`.
   137  - `axes`: See [axes](#axes).
   138  
   139  #### Data Format
   140  
   141  | X-Axis  | Y-Axis Series 1  | Y-Axis Series 2  | ... | Y-Axis Series N  |
   142  | ------- | ---------------- | ---------------- | --- | ---------------- |
   143  | Label 1 | Value 1 Series 1 | Value 1 Series 2 | ... | Value 1 Series N |
   144  | Label 2 | Value 2 Series 1 | Value 2 Series 2 | ... | Value 2 Series N |
   145  | ...     | ...              | ...              | ... | ...              |
   146  | Label N | Value N Series 1 | Value 1 Series 2 | ... | Value N Series N |
   147  
   148  #### Examples
   149  
   150  For the chart examples, we will be referring to the following single and multi-series queries:
   151  
   152  ```hcl
   153  query aws_a3_buckets_by_region {
   154    sql = <<EOF
   155  select
   156      region as Region,
   157      count(*) as Total
   158  from
   159      aws_s3_bucket
   160  group by
   161      region
   162  order by
   163      Total desc
   164  EOF
   165  }
   166  ```
   167  
   168  ```hcl
   169  query aws_a3_unencrypted_and_nonversioned_buckets_by_region {
   170    sql = <<EOF
   171  with unencrypted_buckets_by_region as (
   172    select
   173      region,
   174      count(*) as unencrypted
   175    from
   176      aws_morales_aaa.aws_s3_bucket
   177    where
   178      server_side_encryption_configuration is null
   179    group by
   180      region
   181  ),
   182  nonversioned_buckets_by_region as (
   183    select
   184      region,
   185      count(*) as nonversioned
   186    from
   187      aws_morales_aaa.aws_s3_bucket
   188    where
   189      not versioning_enabled
   190    group by
   191      region
   192  ),
   193  other_buckets_by_region as (
   194    select
   195      region,
   196      count(*) as "other"
   197    from
   198      aws_morales_aaa.aws_s3_bucket
   199    where
   200      server_side_encryption_configuration is not null
   201      and versioning_enabled
   202    group by
   203      region
   204  )
   205  select
   206    o.region,
   207    o.other,
   208    u.unencrypted,
   209    v.nonversioned
   210  from
   211    other_buckets_by_region o
   212    full join unencrypted_buckets_by_region u on o.region = u.region
   213    full join nonversioned_buckets_by_region v on o.region = v.region;
   214  EOF
   215  }
   216  ```
   217  
   218  ##### Bar
   219  
   220  ```hcl
   221  # Single-series bar chart accepting all of the defaults
   222  
   223  chart {
   224    type = "bar"
   225    sql = query.aws_a3_buckets_by_region.sql
   226    title = "AWS S3 Buckets by Region"
   227  }
   228  ```
   229  
   230  ```hcl
   231  # Multi-series bar chart providing custom properties for a variety of chart features
   232  
   233  chart {
   234    type = "bar"
   235    sql = query.aws_a3_unencrypted_and_nonversioned_buckets_by_region.sql
   236    title = "Unencrypted and Non-Versioned Buckets by Region"
   237    legend {
   238      display  = "auto"
   239      position = "top"
   240    }
   241    series other {
   242      title = "Configured Buckets"
   243      color = "green"
   244    }
   245    series unencrypted {
   246      title = "Unencrypted Buckets"
   247      color = "red"
   248    }
   249    series nonversioned {
   250      title = "Non-Versioned Buckets"
   251      color = "orange"
   252    }
   253    axes {
   254      x {
   255        title = "Regions"
   256        labels {
   257          display = "auto"
   258        }
   259      }
   260      y {
   261        title  = "Totals"
   262        labels {
   263          display = "show"
   264        }
   265        min    = 0
   266        max    = 100
   267        steps  = 10
   268      }
   269    }
   270  }
   271  ```
   272  
   273  ##### Column
   274  
   275  ```hcl
   276  # Single-series column chart accepting all of the defaults
   277  
   278  chart {
   279    type = "column"
   280    sql = query.aws_a3_buckets_by_region.sql
   281    title = "AWS S3 Buckets by Region"
   282  }
   283  ```
   284  
   285  ##### Donut
   286  
   287  ```hcl
   288  # Single-series donut chart accepting all of the defaults
   289  
   290  chart {
   291    type = "donut"
   292    sql = query.aws_a3_buckets_by_region.sql
   293    title = "AWS S3 Buckets by Region"
   294  }
   295  ```
   296  
   297  ##### Line
   298  
   299  ```hcl
   300  # Single-series line chart accepting all of the defaults
   301  
   302  chart {
   303    type = "line"
   304    sql = query.aws_a3_buckets_by_region.sql
   305    title = "AWS S3 Buckets by Region"
   306  }
   307  ```
   308  
   309  ##### Pie
   310  
   311  ```hcl
   312  # Single-series pie chart accepting all of the defaults
   313  
   314  chart {
   315    type = "pie"
   316    sql = query.aws_a3_buckets_by_region.sql
   317    title = "AWS S3 Buckets by Region"
   318  }
   319  ```
   320  
   321  ### `counter`
   322  
   323  A counter is used to show a value to the user, or some change in value. A counter can also present itself in different styles e.g. show me a count of public S3 buckets and if the value is greater than 0 show as an `alert`, else as `ok`.
   324  
   325  Counters can be declared as named resources at the top level of a mod, or be declared as anonymous blocks inside a `report` or `container`, or be re-used inside a `report` or `container` by using a `counter` with `base = <mod>.counter.<counter_resource_name>`.
   326  
   327  #### Properties
   328  
   329  - `base`: A reference to a named `counter` resource that this `counter` should source its definition from. `label`, `title`, `value`, `style` and `width` can be overridden after sourcing via `base`.
   330  - `title`: As per the title for a `container` or `chart`, except as this is a leaf is rendered as h3.
   331  - `label`: Inferred from the first column name in simple data format. Else can be set explicitly in HCL, or returned by the query in the `label` column in the formal data format.
   332  - `sql`: Inline SQL or named query.
   333  - `value`: Inferred from the first column's value in simple data format.
   334  - `style`: `plain` (default), `alert`, `info` or `ok`.
   335  - `width`: See [width](#width).
   336  
   337  #### Data Structure
   338  
   339  A counter supports 2 data structures.
   340  
   341  1. A simple structure where column 1's name is the counter `label` and column 1's value is the counter `value`.
   342  2. A formal data structure where the column names map to properties of the `counter`.
   343  
   344  Simple data structure:
   345  
   346  | \<label> |
   347  | -------- |
   348  | \<value> |
   349  
   350  Formal data structure:
   351  
   352  | label               | value | style |
   353  | ------------------- | ----- | ----- |
   354  | Unencrypted Buckets | 10    | alert |
   355  
   356  #### Examples
   357  
   358  ```hcl
   359  # Hard-code value and style declared in HCL. Useful for mocking report layouts.
   360  
   361  counter {
   362    title = "Mock Value"
   363    value = 10
   364    style = "alert"
   365  }
   366  ```
   367  
   368  ```hcl
   369  # Using simple data structure as above. Style is static.
   370  
   371  counter {
   372    sql = <<EOF
   373  select
   374    count(*) as "Unencrypted Buckets"
   375  from
   376    aws_s3_bucket
   377  where
   378    server_side_encryption_configuration is null;
   379  EOF
   380    style = "alert"
   381  }
   382  ```
   383  
   384  ```hcl
   385  # Using formal data structure as above, where the query determines properties of the counter. E.g. style is derived from the `style` column of the query.
   386  
   387  counter {
   388    sql = <<EOF
   389  select
   390    'Unencrypted Buckets' as title,
   391    count(*) as value,
   392    case
   393      when count(*) > 0 then 'alert'
   394      else 'ok'
   395    end style
   396  from
   397    aws_s3_bucket
   398  where
   399    server_side_encryption_configuration is null;
   400  EOF
   401  }
   402  ```
   403  
   404  ### `image`
   405  
   406  Display images in reports., either from a known publicly-accessible `src` URL, or from a `src` return in a SQL query.
   407  
   408  Image blocks can be declared as named resources at the top level of a mod, or be declared as anonymous blocks inside a `report` or `container`, or be re-used inside a `report` or `container` by using an `image` with `base = <mod>.image.<image_resource_name>`.
   409  
   410  #### Properties
   411  
   412  - `base`: A reference to a named `text` resource that this `text` should source its definition from. `title` and `width` can be overridden after sourcing via `base`.
   413  - `title`: As per the title for a `container` or `chart`, except as this is a leaf is rendered as h3.
   414  - `src`: Publicly-accessible URL for the image.
   415  - `alt`: Alternative text for the image.
   416  - `width`: See [width](#width).
   417  
   418  #### Data Structure
   419  
   420  If an image provides a `sql` query, it supports 2 data structures.
   421  
   422  1. A simple structure where column 1's name is the `alt` and column 1's value is the image `src`.
   423  2. A formal data structure where the column names map to properties of the `image`.
   424  
   425  Simple data structure:
   426  
   427  | \<alt> |
   428  | ------ |
   429  | \<src> |
   430  
   431  Formal data structure:
   432  
   433  | src                                  | alt            |
   434  | ------------------------------------ | -------------- |
   435  | https://steampipe.io/images/logo.png | Steampipe Logo |
   436  
   437  #### Examples
   438  
   439  ```hcl
   440  # Hard-code src and alt declared in HCL. Useful for known image URLs.
   441  
   442  image {
   443    src = "https://steampipe.io/images/logo.png"
   444    alt = "Steampipe Logo"
   445  }
   446  ```
   447  
   448  ```hcl
   449  # Using simple data structure as above.
   450  
   451  image {
   452    sql = <<EOF
   453  select
   454    favicon as "Steampipe Logo"
   455  from
   456    web
   457  where
   458    domain = "https://steampipe.io";
   459  EOF
   460  }
   461  ```
   462  
   463  ```hcl
   464  # Using formal data structure as above, where the query determines properties of the image. E.g. src is derived from the `src` column of the query.
   465  
   466  image {
   467    sql = <<EOF
   468  select
   469    favicon as src,
   470    "Steampipe Logo" as alt
   471  from
   472    web
   473  where
   474    domain = "https://steampipe.io";
   475  EOF
   476  }
   477  ```
   478  
   479  ### `input`
   480  
   481  Allow user input in reports using common form components such as inputs, selects etc. Data can either be static or derived from a SQL query.
   482  
   483  The value of an input is synced with the declared `variable`, which allows the default/initial value to be set by the `variable` and then allows other mod resources to consume this `variable` to enable dynamic behaviour.
   484  
   485  Input blocks can be declared as named resources at the top level of a mod, or be declared as anonymous blocks inside a `report` or `container`, or be re-used inside a `report` or `container` by using an `input` with `base = <mod>.input.<input_resource_name>`.
   486  
   487  #### Properties
   488  
   489  - `base`: A reference to a named `input` resource that this `input` should source its definition from. `title`, `sql`, `type`, `options` and `width` can be overridden after sourcing via `base`.
   490  - `title`: As per the title for a `container` or `chart`, except as this is a leaf is rendered as h3.
   491  - `sql`: Inline SQL or named query.
   492  - `type`: The type of the input. Can be `check`, `input`, `radio` or `select`.
   493  - `variable`: A reference to a mod `variable` that backs the input.
   494  - `options`: Only applicable for input types that display options e.g. `check`, `radio` or `select` that wish to display a static list of options. Inferred from the data first 2 columns value in simple data format.
   495  - `placeholder`: Only applicable for `input` type.
   496  - `width`: See [width](#width).
   497  
   498  #### Data Structure
   499  
   500  The data structure for an `input` will depend on the `type`.
   501  
   502  ##### Check / Radio / Select
   503  
   504  | label               | value                 |
   505  | ------------------- | --------------------- |
   506  | default             | vpc-05657e5bef9676266 |
   507  | acme @ 10.84.0.0/16 | vpc-03656e5eef967f366 |
   508  
   509  #### Examples
   510  
   511  ```hcl
   512  # Select with static options
   513  
   514  input {
   515    type = "select"
   516    variable = var.selected_vpc
   517    options = [
   518      {
   519        label = "default"
   520        value = "vpc-05657e5bef9676266"
   521      }
   522      {
   523        label = "acme @ 10.84.0.0/16"
   524        value = "vpc-03656e5eef967f366"
   525      }
   526    ]
   527  }
   528  ```
   529  
   530  ```hcl
   531  # Select with dynamic options
   532  
   533  input {
   534    type = "select"
   535    variable = var.selected_vpc
   536    sql = <<EOF
   537  select
   538    title as label
   539    vpc_id as value,
   540  from
   541    aws_vpc;
   542  EOF
   543  }
   544  ```
   545  
   546  ```hcl
   547  # Radio with static options
   548  
   549  input {
   550    type = "radio"
   551    variable = var.selected_vpc
   552    options = [
   553      {
   554        label = "default"
   555        value = "vpc-05657e5bef9676266"
   556      }
   557      {
   558        label = "acme @ 10.84.0.0/16"
   559        value = "vpc-03656e5eef967f366"
   560      }
   561    ]
   562  }
   563  ```
   564  
   565  ```hcl
   566  # Radio with dynamic options
   567  
   568  input {
   569    type = "radio"
   570    variable = var.selected_vpc
   571    sql = <<EOF
   572  select
   573    title as label
   574    vpc_id as value,
   575  from
   576    aws_vpc;
   577  EOF
   578  }
   579  ```
   580  
   581  ```hcl
   582  # Check with static options
   583  
   584  input {
   585    type = "check"
   586    variable = var.selected_vpc
   587    options = [
   588      {
   589        label = "default"
   590        value = "vpc-05657e5bef9676266"
   591      }
   592      {
   593        label = "acme @ 10.84.0.0/16"
   594        value = "vpc-03656e5eef967f366"
   595      }
   596    ]
   597  }
   598  ```
   599  
   600  ```hcl
   601  # Check with dynamic options
   602  
   603  input {
   604    type = "check"
   605    variable = var.selected_vpc
   606    sql = <<EOF
   607  select
   608    title as label
   609    vpc_id as value,
   610  from
   611    aws_vpc;
   612  EOF
   613  }
   614  ```
   615  
   616  ### `text`
   617  
   618  Display either rendered `markdown` ([GitHub Flavored Markdown](https://github.github.com/gfm/)) or `raw` text with no interpretation of markup. # TODO do we want HTML? How can we be sure it's safe before rendering in the browser?
   619  
   620  Text blocks can be declared as named resources at the top level of a mod, or be declared as anonymous blocks inside a `report` or `container`, or be re-used inside a `report` or `container` by using a `text` with `base = <mod>.text.<text_resource_name>`.
   621  
   622  #### Properties
   623  
   624  - `base`: A reference to a named `text` resource that this `text` should source its definition from. `title` and `width` can be overridden after sourcing via `base`.
   625  - `title`: As per the title for a `container` or `chart`, except as this is a leaf is rendered as h3.
   626  - `type`: `markdown` (default) or `raw`.
   627  - `value`: The `markdown` or `html` string to use. Can also be sourced using the HCL `file` function.
   628  - `width`: See [width](#width).
   629  
   630  #### Examples
   631  
   632  ```hcl
   633  # Render as markdown (default).
   634  
   635  text {
   636    value = <<EOF
   637  # I am some markdown text.
   638  
   639  Please respect my markdown.
   640  EOF
   641  }
   642  ```
   643  
   644  ```hcl
   645  # Explicitly specify markdown (but is optional as markdown is the default).
   646  
   647  text {
   648    type  = "markdown"
   649    value = <<EOF
   650  # I am some markdown text.
   651  
   652  Please respect my markdown.
   653  EOF
   654  }
   655  ```
   656  
   657  ```hcl
   658  # Render raw
   659  
   660  text {
   661    type  = "raw"
   662    value = "<h2>I am a HTML title, but I'll be displayed as-is</h2>"
   663  }
   664  ```
   665  
   666  ### Common Properties:
   667  
   668  #### `title`
   669  
   670  Optional `title` for an item. Provided as plain text, but will be rendered as a `text` panel with a `style` of `markdown` using h1 (for `report`), h2 (for `container`) or h3 (for any leaf nodes e.g. `chart`). This `text` block and the item it is titling will be wrapped by a `container`.
   671  
   672  #### `width`
   673  
   674  The number of grid units that this item should consume from its parent. In the browser, this is only used when in a large screen size and up (viewport min-width of 1024px), and will always be 12 for smaller viewports. Provided value must be between `0` and `12` (default). `0` would mean the `container` is hidden and will not consume any space on the report.
   675  
   676  ### Common Chart Properties
   677  
   678  #### `axes`
   679  
   680  Applicable to `bar`, `column`, `line` and `scatter`.
   681  
   682  - `x`:
   683  
   684  | Property | Type                         | Default | Values | Description |
   685  | -------- | ---------------------------- | ------- | ------ | ----------- |
   686  | `title`  | See [axistitle](#axis-title) |         |        |             |
   687  | `labels` | See [labels](#labels)        |         |        |             |
   688  
   689  - `y`:
   690  
   691  | Property | Type                         | Default                                                                                                                                                                   | Values            | Description |
   692  | -------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ----------- |
   693  | `title`  | See [axistitle](#axis-title) |                                                                                                                                                                           |                   |             |
   694  | `labels` | See [labels](#labels)        |                                                                                                                                                                           |                   |             |
   695  | `min`    | number                       | Determined by the range of values. For positive ranges, this will be `0`. For negative ranges, this will be scaled to the next appropriate value below the range min.     | Any valid number. |             |
   696  | `max`    | number                       | Determined by the range of values. For positive ranges, this will be scaled to the next appropriate value above the range max `0`. For negative ranges, this will be `0`. | Any valid number. |             |
   697  
   698  #### `axis title`
   699  
   700  | Property  | Type   | Default  | Values                                | Description                                                                                                                              |
   701  | --------- | ------ | -------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
   702  | `display` | string | `none`   | `always` or `none` (default).         | `always` will ensure the axis title is `always` shown, or `none` will never show it.                                                     |
   703  | `align`   | string | `center` | `start`, `center` (default) or `end`. | By default the chart will align the axis title in the `center` of the chart, but this can be overridden to `start` or `end` if required. |
   704  | `value`   | string |          | Max 50 characters.                    |                                                                                                                                          |
   705  
   706  #### `labels`
   707  
   708  | Property  | Type   | Default | Values                                | Description                                                                                                                                                                                                        |
   709  | --------- | ------ | ------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
   710  | `display` | string | `auto`  | `auto` (default), `always` or `none`. | `auto` will display as many labels as possible for the size of the chart. `always` will always show all labels, but will truncate them with an ellipsis as necessary. `none` will never show labels for this axis. |
   711  | `format`  | TBD    |         |                                       |                                                                                                                                                                                                                    |
   712  
   713  #### `legend`
   714  
   715  | Property   | Type   | Default | Values                              | Description                                                                                                                                        |
   716  | ---------- | ------ | ------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
   717  | `display`  | string | `auto`  | `auto`, `always` or `none`.         | `auto` will display a legend if there are multiple data series. `show` will ensure a legend is `always` shown, or `hide` will never show a legend. |
   718  | `position` | string | `top`   | `top`, `right`, `bottom` or `left`. | By default the chart will display a legend at the `top` of the chart, but this can be overridden to `right`, `bottom` or `left` if required.       |
   719  
   720  #### `series`:
   721  
   722  | Property | Type   | Default                                                              | Values                                                                                                                                  | Description |
   723  | -------- | ------ | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
   724  | `title`  | string | The column name that the series data resides in.                     | Max 50 characters                                                                                                                       |             |
   725  | `color`  | string | The matching color from the default theme for the data series index. | Any valid color from the HTML extended colors (e.g. `gold`), a valid Hex string (e.g. `#0000FF`) or a valid RGB (e.g. `rgb(0, 0, 100)`) |             |
   726  
   727  ---
   728  
   729  Inputs mock:
   730  
   731  ```hcl
   732  query aws_regions_input {
   733    sql = <<-EOT
   734  select
   735    name as value,
   736    title as label
   737  from
   738    aws_region;
   739  EOT
   740  }
   741  
   742  query aws_vpcs_for_region_input {
   743    sql = <<-EOT
   744  select
   745    vpc_id as value,
   746    title as label
   747  from
   748    aws_morales_aaa.aws_vpc
   749  where
   750    region = $1;
   751  EOT
   752    param region {
   753      description = "Region to filter VPCs by."
   754    }
   755  }
   756  
   757  execute
   758  {
   759    region = "us-east-1"
   760  }
   761  
   762  report inputs_mock {
   763    title = "Inputs Mock"
   764  
   765    param "region" {
   766      default = var.default_region
   767      sql = query.aws_regions_input.sql
   768      type = "select"
   769      description = "Selected region for the report."
   770    }
   771  
   772    param "region" {
   773      default = var.default_region
   774      description = "Selected region for the report."
   775    }
   776  
   777    param "region" {
   778      default = var.default_region
   779      value = input.region_select.value
   780      description = "Selected region for the report."
   781    }
   782  
   783    param "vpc_id" {
   784      default = input.vpc_select.value
   785      description = "Selected VPC for the report."
   786    }
   787  
   788    container {
   789      input "foo" {
   790        base = param.region
   791        width = 6
   792      }
   793  
   794      input {
   795        base = param.region
   796        sql = query.aws_regions_input.sql
   797        type = "select"
   798        width = 6
   799      }
   800  
   801      input "region_select" {
   802        type = "select"
   803        sql = query.aws_regions_input.sql
   804        width = 6
   805      }
   806  
   807      input {
   808        base = param.region
   809        type = "select"
   810        sql = query.aws_regions_input.sql
   811        width = 6
   812      }
   813  
   814      input "vpc_select" {
   815        type = "select"
   816        query = query.aws_vpcs_for_region_input
   817        args = {
   818          region = param.region
   819        }
   820        width = 6
   821      }
   822    }
   823  
   824    container {
   825      chart {
   826        type = "bar"
   827        # sql = query.foo.sql
   828        query = query.aws_blah_for_vpc
   829        args = {
   830          region = param.vpc_id
   831        }
   832      }
   833    }
   834  
   835    text {
   836      type = "markdown"
   837      value = "## Some text"
   838    }
   839  }
   840  ```
   841  
   842  ## OLD DOCS - ignore below here
   843  
   844  ### `bar`
   845  
   846  Display a `bar` chart for single or grouped multi-series. Maximum series count is `10`.
   847  
   848  #### Data Format
   849  
   850  | X-Axis  | Y-Axis Series 1  | Y-Axis Series 2  | ... | Y-Axis Series N  |
   851  | ------- | ---------------- | ---------------- | --- | ---------------- |
   852  | Label 1 | Value 1 Series 1 | Value 1 Series 2 | ... | Value 1 Series N |
   853  | Label 2 | Value 2 Series 1 | Value 2 Series 2 | ... | Value 2 Series N |
   854  | ...     | ...              | ...              | ... | ...              |
   855  | Label N | Value N Series 1 | Value 1 Series 2 | ... | Value N Series N |
   856  
   857  #### Properties
   858  
   859  - `title`: See [title](#title).
   860  - `sql`: Inline SQL or named query.
   861  - `legend`: See [legend](#legend).
   862  - `series`: A named block matching the name of the series you wish to configure. See `Series`.
   863  - `axes`: See [axes](#axes).
   864  
   865  ##### Basic
   866  
   867  Accept all defaults.
   868  
   869  ```hcl
   870  bar {
   871    sql = query.aws_a3_buckets_by_region.sql
   872    title = "AWS S3 Buckets by Region"
   873  }
   874  ```
   875  
   876  ##### Kitchen Sink
   877  
   878  Specify all options.
   879  
   880  # TODO should blocks assign with =? E.g. `legend { ...` vs `legend = { ...`
   881  
   882  ```hcl
   883  bar {
   884    sql = query.aws_a3_unencrypted_and_nonversioned_buckets_by_region.sql
   885    title = "Unencrypted and Non-Versioned Buckets by Region"
   886    legend {
   887      display  = "auto"
   888      position = "top"
   889    }
   890    series other {
   891      title = "Configured Buckets"
   892      color = "green"
   893    }
   894    series unencrypted {
   895      title = "Unencrypted Buckets"
   896      color = "red"
   897    }
   898    series nonversioned {
   899      title = "Non-Versioned Buckets"
   900      color = "orange"
   901    }
   902    axes {
   903      x {
   904        title = "Regions"
   905        labels {
   906          display = "auto"
   907        }
   908      }
   909      y {
   910        title  = "Totals"
   911        labels {
   912          display = "show"
   913        }
   914        min    = 0
   915        max    = 100
   916        steps  = 10
   917      }
   918    }
   919  }
   920  ```
   921  
   922  ### `column`
   923  
   924  Display a `column` chart for single or grouped multi-series. Maximum series count is 10.
   925  
   926  #### Data Format
   927  
   928  | X-Axis  | Y-Axis Series 1  | Y-Axis Series 2  | ... | Y-Axis Series N  |
   929  | ------- | ---------------- | ---------------- | --- | ---------------- |
   930  | Label 1 | Value 1 Series 1 | Value 1 Series 2 | ... | Value 1 Series N |
   931  | Label 2 | Value 2 Series 1 | Value 2 Series 2 | ... | Value 2 Series N |
   932  | ...     | ...              | ...              | ... | ...              |
   933  | Label N | Value N Series 1 | Value 1 Series 2 | ... | Value N Series N |
   934  
   935  #### Properties
   936  
   937  - `title`: See [title](#title).
   938  - `sql`: Inline SQL or named query.
   939  - `legend`: See [legend](#legend).
   940  - `series`: A named block matching the name of the series you wish to configure. See `Series`.
   941  - `axes`: See [axes](#axes).
   942  
   943  ##### Basic
   944  
   945  Accept all defaults.
   946  
   947  ```hcl
   948  column {
   949    sql = query.aws_a3_buckets_by_region.sql
   950    title = "AWS S3 Buckets by Region"
   951  }
   952  ```
   953  
   954  ##### Kitchen Sink
   955  
   956  Specify all options.
   957  
   958  ```hcl
   959  column {
   960    sql = query.aws_a3_unencrypted_and_nonversioned_buckets_by_region.sql
   961    title = "Unencrypted and Non-Versioned Buckets by Region"
   962    legend {
   963      display  = "auto"
   964      position = "top"
   965    }
   966    series other {
   967      title = "Configured Buckets"
   968      color = "green"
   969    }
   970    series unencrypted {
   971      title = "Unencrypted Buckets"
   972      color = "red"
   973    }
   974    series nonversioned {
   975      title = "Non-Versioned Buckets"
   976      color = "orange"
   977    }
   978    axes {
   979      x {
   980        title = "Regions"
   981        labels = "auto"
   982      }
   983      y {
   984        title  = "Totals"
   985        labels = {
   986          display = "show"
   987        }
   988        min    = 0
   989        max    = 100
   990        steps  = 10
   991      }
   992    }
   993  }
   994  ```
   995  
   996  ### `line`
   997  
   998  Display a `line` chart for single or multi-series. Maximum series count is 10.
   999  
  1000  #### Data Format
  1001  
  1002  | X-Axis  | Y-Axis Series 1  | Y-Axis Series 2  | ... | Y-Axis Series N  |
  1003  | ------- | ---------------- | ---------------- | --- | ---------------- |
  1004  | Label 1 | Value 1 Series 1 | Value 1 Series 2 | ... | Value 1 Series N |
  1005  | Label 2 | Value 2 Series 1 | Value 2 Series 2 | ... | Value 2 Series N |
  1006  | ...     | ...              | ...              | ... | ...              |
  1007  | Label N | Value N Series 1 | Value 1 Series 2 | ... | Value N Series N |
  1008  
  1009  #### Properties
  1010  
  1011  - `title`: See [title](#title).
  1012  - `sql`: Inline SQL or named query.
  1013  - `legend`: See [legend](#legend).
  1014  - `series`: A named block matching the name of the series you wish to configure. See `Series`.
  1015  - `axes`: See [axes](#axes).
  1016  
  1017  ##### Basic
  1018  
  1019  Accept all defaults.
  1020  
  1021  ```hcl
  1022  column {
  1023    sql = query.aws_a3_buckets_by_region.sql
  1024    title = "AWS S3 Buckets by Region"
  1025  }
  1026  ```
  1027  
  1028  ##### Kitchen Sink
  1029  
  1030  Specify all options.
  1031  
  1032  ```hcl
  1033  line {
  1034    sql = query.aws_a3_unencrypted_and_nonversioned_buckets_by_region.sql
  1035    title = "Unencrypted and Non-Versioned Buckets by Region"
  1036    legend = {
  1037      display  = "auto"
  1038      position = "top"
  1039    }
  1040    series other {
  1041      title = "Configured Buckets"
  1042      color = "green"
  1043    }
  1044    series unencrypted {
  1045      title = "Unencrypted Buckets"
  1046      color = "red"
  1047    }
  1048    series nonversioned {
  1049      title = "Non-Versioned Buckets"
  1050      color = "orange"
  1051    }
  1052    axes {
  1053      x {
  1054        title = "Regions"
  1055        labels = "auto"
  1056      }
  1057      y {
  1058        title  = "Totals"
  1059        labels = {
  1060          display = "show"
  1061        }
  1062        min    = 0
  1063        max    = 100
  1064        steps  = 10
  1065      }
  1066    }
  1067  }
  1068  ```
  1069  
  1070  ### `pie`
  1071  
  1072  Display a `pie` chart. Maximum 10 categories. Automatically puts the smallest category values into an `Other` category for large category counts.
  1073  
  1074  #### Data Format
  1075  
  1076  # TODO single series like simple charts
  1077  
  1078  | Category   | Value   |
  1079  | ---------- | ------- |
  1080  | Category 1 | Value 1 |
  1081  | Category 2 | Value 2 |
  1082  | ...        | ...     |
  1083  | Category N | Value N |
  1084  
  1085  #### Properties
  1086  
  1087  - `title`: See [title](#title).
  1088  - `sql`: Inline SQL or named query.
  1089  - `legend`: See [legend](#legend).
  1090  - `grouping`: `auto` (default) will automatically group the smallest values into an `Other` category when the number of categories is greater than 10, ensuring a maximum of 10 categories, or `off` will attempt to display the number of categories present.
  1091  - `categories`: A named block matching the name of the category you wish to configure. See [categories](#categories).
  1092  
  1093  ##### Basic
  1094  
  1095  Accept all defaults.
  1096  
  1097  ```hcl
  1098  pie {
  1099    sql = query.aws_a3_buckets_by_region.sql
  1100    title = "AWS S3 Buckets by Region"
  1101  }
  1102  ```
  1103  
  1104  ##### Kitchen Sink
  1105  
  1106  Specify all options.
  1107  
  1108  ```hcl
  1109  pie {
  1110    sql = query.aws_a3_unencrypted_and_nonversioned_buckets_by_region.sql
  1111    title = "Unencrypted and Non-Versioned Buckets by Region"
  1112    legend = {
  1113      display  = "auto"
  1114      position = "top"
  1115    }
  1116    series other {
  1117      title = "Configured Buckets"
  1118      color = "green"
  1119    }
  1120    series unencrypted {
  1121      title = "Unencrypted Buckets"
  1122      color = "red"
  1123    }
  1124    series nonversioned {
  1125      title = "Non-Versioned Buckets"
  1126      color = "orange"
  1127    }
  1128    axes {
  1129      x {
  1130        title = "Regions"
  1131        labels = "auto"
  1132      }
  1133      y {
  1134        title  = "Totals"
  1135        labels = {
  1136          display = "show"
  1137        }
  1138        min    = 0
  1139        max    = 100
  1140        steps  = 10
  1141      }
  1142    }
  1143  }
  1144  ```
  1145  
  1146  ---
  1147  
  1148  ## Old docs
  1149  
  1150  - A `container` is a new layout resource type that composes `panel` and/or `container` blocks. Supports width property:
  1151  
  1152  ```hcl
  1153  container s3_layout_panel {
  1154    width = 6
  1155  
  1156    panel s3_buckets_by_region {
  1157      type = "barchart"
  1158      sql  = query.aws_s3_buckets_by_region.sql
  1159    }
  1160  
  1161    panel ec2_instances_by_region {
  1162      type = "barchart"
  1163      sql  = query.ec2_instances_by_region.sql
  1164    }
  1165  
  1166    container layout {
  1167      width = 6
  1168  
  1169      panel ec2_instances_by_region {
  1170        type = "barchart"
  1171        sql  = query.ec2_instances_by_region.sql
  1172      }
  1173    }
  1174  }
  1175  ```
  1176  
  1177  - A `report` can contain `panel` and/or `container` blocks. (still supports `title` property):
  1178  
  1179  ```hcl
  1180  report my_report {
  1181    title = "My Report"
  1182  
  1183    panel s3_buckets_by_region {
  1184      type = "barchart"
  1185      sql  = query.aws_s3_buckets_by_region.sql
  1186    }
  1187  
  1188    container layout {
  1189      width = 6
  1190  
  1191      panel ec2_instances_by_region {
  1192        type = "barchart"
  1193        sql  = query.ec2_instances_by_region.sql
  1194      }
  1195    }
  1196  }
  1197  ```
  1198  
  1199  - A `panel` cannot compose anything else now. It is a leaf node in the tree:
  1200  
  1201  ```hcl
  1202  panel s3_buckets_by_region {
  1203    type = "barchart"
  1204    sql  = query.aws_s3_buckets_by_region.sql
  1205  }
  1206  ```
  1207  
  1208  - Only `report` and `panel` can exist at the top-level of a mod.
  1209  
  1210  - To re-use an existing panel, use `base`:
  1211  
  1212  ```hcl
  1213  panel s3_buckets_by_region {
  1214    type = "barchart"
  1215    sql  = query.aws_s3_buckets_by_region.sql
  1216  }
  1217  
  1218  panel re_use {
  1219    base = panel.s3_buckets_by_region
  1220  }
  1221  ```
  1222  
  1223  - To re-use and override a property of an existing panel, use `base` + override its property:
  1224  
  1225  ```hcl
  1226  panel s3_buckets_by_region {
  1227    type = "barchart"
  1228    sql  = query.aws_s3_buckets_by_region.sql
  1229  }
  1230  
  1231  panel re_use {
  1232    base = panel.s3_buckets_by_region
  1233    type = "linechart"
  1234  }
  1235  ```
  1236  
  1237  - To re-use an existing report, use a `panel` with `base`:
  1238  
  1239  ```hcl
  1240  report other_report {
  1241    panel s3_buckets_by_region {
  1242      type = "barchart"
  1243      sql  = query.aws_s3_buckets_by_region.sql
  1244    }
  1245  }
  1246  
  1247  report my_report {
  1248    panel nested_report {
  1249      base = report.other_report
  1250    }
  1251  }
  1252  ```
  1253  
  1254  - A `container` cannot be re-used unlike `panel` and `report`.
  1255  
  1256  - Panel `source` is now `type` and is not parse-time checked - it's just a (required) string:
  1257  
  1258  ```hcl
  1259  panel s3_buckets_by_region {
  1260    type = "barchart"
  1261    sql  = query.aws_s3_buckets_by_region.sql
  1262  }
  1263  ```
  1264  
  1265  - "Core" panel properties are `type` (required), `sql` (optional, named or inline query) and `width`.
  1266  
  1267  - Custom/extended properties for a `panel` are declared at the top-level of the block:
  1268  
  1269  ```hcl
  1270  panel s3_buckets_by_region {
  1271    type = "barchart"
  1272    sql  = query.aws_s3_buckets_by_region.sql
  1273    orientation = "horizontal"
  1274  }
  1275  ```
  1276  
  1277  - All internal lists of `container` and `panel` inside a `report` or `container` should be stored as `children` to align with `benchmark`.
  1278  
  1279  ## High-level design decisions
  1280  
  1281  - Mods can define >=0:
  1282    - `query`
  1283      - A named query that can be used to obtain data
  1284    - `panel`
  1285      - The building block of a report - effectively a named layout component
  1286      - A panel may render a report primitive:
  1287        - `report`
  1288        - `panel`
  1289        - `markdown`
  1290        - `table`
  1291        - `counter`
  1292        - `barchart` // TODO - is this just `chart` with further properties to define, or should be explicit like this?
  1293        - `linechart` // TODO - same as above
  1294        - `piechart` // TODO - same as above
  1295        - tbd...
  1296      - A panel can compose other reports and panels, allowing interesting and more complex layouts to be achieved
  1297      - A panel can be used in isolation if required, but is typically designed to be composed with other panels into a `report`
  1298    - `report`
  1299      - Conceptually no different to a `panel` in that it is a named layout component that composes `panel`s and/or `report`s
  1300      - The key differentiator is a `report` indicates that it will provide answers to specific reporting issues through composition, whereas a `panel` may only provide a subset of data that may not provide full context if used in isolation
  1301      - A mod is expected to provide a `main` report, which is the default report to use
  1302  - All reporting primitives must know how to display themselves across a variety of screen sizes and mediums
  1303    - The current in-scope mediums are:
  1304      - `web`
  1305        - Reports and panels will be mapped to a suitable grid system to provide simple, yet powerful layout constructs - spec below
  1306        - Ideal state:
  1307          - Support a rich and interactive reporting experience on larger devices, with graceful degradation of functionality as we move down through screen sizes
  1308          - Panels
  1309        - MVP state
  1310          - Support display of reports across large and small devices e.g. columns should be full-width on small devices
  1311      - `email`
  1312        - Spec TBD, but likely to contain images of report primitives - pure html and attachments will ensure maximum compatibility
  1313      - `slack`
  1314        - Likely to have the most constrained and succinct layout options - spec TBD
  1315  - All mod component are public, meaning that anyone using a mod can import any `query`, `panel`, `report` or `action`
  1316    - Action spec TBD - but effectively provides a consistent way to take action based on query data or the outcome of a report e.g. email a DG, send a Slack message
  1317    - Actions are just named compositions of basic primitives including http request, send slack message, send email etc
  1318  - Namespacing:
  1319    - Components are namespaced
  1320      - `<org>.<component>.<primitive>`
  1321      - e.g. `steampipe.panel.markdown`
  1322    - Omission of namespace refers to locally-defined components within that mod e.g.
  1323      - `panel.header`
  1324      - `panel.body`
  1325      - `panel.footer`
  1326      - `query.aging_aws_iam_access_keys`
  1327    - When building reports in custom mods you will always refer to the Steampipe reporting primitives with their full namespace e.g.
  1328      - `steampipe.panel.markdown`
  1329      - `steampipe.panel.counter`
  1330      - etc...
  1331  
  1332  ## Primitives
  1333  
  1334  Reports consist of a number of primitives, which allow various scenarios to be reported on. The following section will outline the available primitives, along with their required and optional parameters.
  1335  
  1336  ### Report
  1337  
  1338  - A report provides a 12-column grid system. It's child panels will consume grid units from left to right, wrapping to the next row when all 12 units have been consumed, or there are insufficient grid units left on that row.
  1339  - Properties:
  1340    - `title`: (optional) A human-friendly title for the report. This will be preferred over the HCL panel name whenever we need to present a list of reports to the user.
  1341  - Example:
  1342  
  1343  ```hcl
  1344  report hello_world {
  1345    title = "Hello World"
  1346  }
  1347  ```
  1348  
  1349  ### Panel
  1350  
  1351  - A panel is the primitive that you will use to lay out your reports and present the various reporting primitives.
  1352  - Each panel will consume the full available width of its parent. E.g. if your parent panel is 12 grid units, you will have up to 12 grid unit available, however if your parent panel/report only has 6/12 grid units, your panel will only have up to 6 grid units available.
  1353  - Properties:
  1354  
  1355    - `source`: (required) The source type of this panel, which will be one of the following:
  1356  
  1357      - `steampipe.panel.markdown`: A panel for rendering markdown
  1358      - `steampipe.panel.counter`: A panel for displaying counter data (e.g. totals)
  1359      - `steampipe.panel.table`: A panel for displaying tabular data
  1360      - `steampipe.panel.bar_chart`: A panel for displaying tabular data in a bar chart
  1361      - `steampipe.panel.line_chart`: A panel for displaying tabular data in a line chart
  1362      - `steampipe.panel.pie_chart`: A panel for displaying tabular data in a pie chart
  1363  
  1364      - `steampipe.panel.control_table`: A panel for displaying tabular data that conforms to the Steampipe [control query spec](https://steampipe.io/docs/using-steampipe/writing-controls).
  1365  
  1366    - `width`: (optional) The amount of grid unit that it should consume from its parent.
  1367      - If not specified this will default to 12 and the panel will consume the full width of its parent.
  1368      - Min: `1`
  1369      - Max: `12`
  1370    - `height`: (optional) A number of units relative to one grid unit width of itself.
  1371      - E.g. if `height` is 4 and the panel is 1200px wide / 12 grid units wide, then 1 grid unit width is 120px, so 4 height units would be 480px.
  1372      - If not specified the panel will be as tall as required to render its content
  1373  
  1374  ### Markdown
  1375  
  1376  Allow rendering of markdown content in a report.
  1377  
  1378  - `source: steampipe.panel.markdown`
  1379  - Supports [GitHub Flavored Markdown Spec](https://github.github.com/gfm/)
  1380  - If a panel `height` is specified and the content height exceeds the calculated height, the panel will scroll vertically.
  1381  - Properties:
  1382    - `text`: (required) The markdown string
  1383  
  1384  ```hcl
  1385  panel markdown {
  1386    source = steampipe.panel.markdown
  1387    text = <<-EOT
  1388      # It's just markdown
  1389      So go `wild`.
  1390    EOT
  1391  }
  1392  ```
  1393  
  1394  ### Counter
  1395  
  1396  Display a counter in a report.
  1397  
  1398  - `steampipe.panel.counter`
  1399  - Expects data in format
  1400  
  1401  | \<Title of counter\> |
  1402  | -------------------- |
  1403  | \<Counter value\>    |
  1404  
  1405  e.g.
  1406  
  1407  | AWS IAM Users |
  1408  | ------------- |
  1409  | 17            |
  1410  
  1411  - First row is expected to be the header with title
  1412  - Second row is the counter value itself
  1413  
  1414  ```hcl
  1415  panel aws_iam_user_count {
  1416    source = steampipe.panel.counter
  1417    query = "select count(*) as "AWS IAM Users" from aws_iam_user"
  1418  }
  1419  ```
  1420  
  1421  ### Table
  1422  
  1423  Allow rendering of table data in a report.
  1424  
  1425  - `source: steampipe.panel.table`
  1426  - Expects data in table (e.g. like CSV/Excel) format. First row assumed to be the header row. Subsequent rows assumed to be the data rows.
  1427  - Properties:
  1428    - `sql`: Either an inline query, or a named query
  1429  
  1430  Example with inline query:
  1431  
  1432  ```hcl
  1433  panel buckets_versioning_disabled {
  1434    source = steampipe.panel.table
  1435    sql = "select name as Name, region as Region from aws_s3_bucket where versioning = 'disabled'"
  1436  }
  1437  ```
  1438  
  1439  Example with named query:
  1440  
  1441  ```hcl
  1442  panel buckets_versioning_disabled {
  1443    source = steampipe.panel.table
  1444    sql = query.buckets_versioning_disabled_query.sql
  1445  }
  1446  ```
  1447  
  1448  ### Pie Chart
  1449  
  1450  Allow rendering of data as a pie chart in a report.
  1451  
  1452  - `steampipe.panel.piechart`
  1453  - First column will be projected across the X-axis
  1454  - Second column will be used as the series data
  1455  - Expects data in table format
  1456  
  1457  | Entity   | Total |
  1458  | -------- | ----- |
  1459  | Groups   | 2     |
  1460  | Policies | 102   |
  1461  | ...      | ...   |
  1462  | Users    | 10    |
  1463  
  1464  ```hcl
  1465  panel buckets_versioning_disabled {
  1466    source = steampipe.panel.barchart
  1467    title = "AWS IAM Entities"
  1468    query = "select entity as Entity, total as Total;"
  1469  }
  1470  ```
  1471  
  1472  ### Bar Chart
  1473  
  1474  Allow rendering of data as a bar chart in a report.
  1475  
  1476  - `steampipe.panel.barchart`
  1477  - First column will be projected across the X-axis
  1478  - Second column will be used as the series data
  1479  - Expects data in table format
  1480  
  1481  | Entity   | Total |
  1482  | -------- | ----- |
  1483  | Groups   | 2     |
  1484  | Policies | 102   |
  1485  | ...      | ...   |
  1486  | Users    | 10    |
  1487  
  1488  ```hcl
  1489  panel buckets_versioning_disabled {
  1490    source = steampipe.panel.barchart
  1491    title = "AWS IAM Entities"
  1492    query = "select entity as Entity, total as Total;"
  1493  }
  1494  ```
  1495  
  1496  ### Stacked Bar Chart
  1497  
  1498  Allow rendering of data as a stacked bar chart in a report.
  1499  
  1500  - `steampipe.panel.stackedbarchart`
  1501  - First column will be projected across the X-axis
  1502  - Each subsequent column will be used as the series data to stack
  1503  - Expects data in table format
  1504  
  1505  | Entity   | Used | Available |
  1506  | -------- | ---- | --------- |
  1507  | Groups   | 2    | 498       |
  1508  | Policies | 102  | 898       |
  1509  | ...      | ...  | ...       |
  1510  | Users    | 10   | 90        |
  1511  
  1512  ```hcl
  1513  panel buckets_versioning_disabled {
  1514    source = steampipe.panel.stackedbarchart
  1515    title = "AWS IAM Entity Quota Usage"
  1516    query = "select entity as Entity, total as Used, (total - quota) as Available from aws_iam_account_summary;"
  1517  }
  1518  ```
  1519  
  1520  ### Line Chart
  1521  
  1522  Allow rendering of data as a line chart in a report.
  1523  
  1524  - `steampipe.panel.linechart`
  1525  - First column will be projected across the X-axis
  1526  - Second column will be used as the series data
  1527  - Expects data in table format
  1528  
  1529  #### Single Line
  1530  
  1531  | Entity   | Total |
  1532  | -------- | ----- |
  1533  | Groups   | 2     |
  1534  | Policies | 102   |
  1535  | ...      | ...   |
  1536  | Users    | 10    |
  1537  
  1538  ```hcl
  1539  panel buckets_versioning_disabled {
  1540    source = steampipe.panel.linechart
  1541    title = "AWS IAM Entities"
  1542    query = "select entity as Entity, total as Total;"
  1543  }
  1544  ```
  1545  
  1546  #### Multi Line
  1547  
  1548  | Entity   | Used | Available |
  1549  | -------- | ---- | --------- |
  1550  | Groups   | 2    | 498       |
  1551  | Policies | 102  | 898       |
  1552  | ...      | ...  | ...       |
  1553  | Users    | 10   | 90        |
  1554  
  1555  ```hcl
  1556  panel buckets_versioning_disabled {
  1557    source = steampipe.panel.linechart
  1558    title = "AWS IAM Entity Quota Usage"
  1559    query = "select entity as Entity, total as Used, (total - quota) as Available from aws_iam_account_summary;"
  1560  }
  1561  ```
  1562  
  1563  ## Examples
  1564  
  1565  ### Report with single markdown panel
  1566  
  1567  - Single full-width panel rendered with a title in markdown
  1568    - <!---TODO: text? check this-->
  1569  
  1570  ```hcl
  1571  report hello_world {
  1572  
  1573    panel header {
  1574      source = steampipe.panel.markdown
  1575      text = "# Hello World!"
  1576    }
  1577  
  1578  }
  1579  ```
  1580  
  1581  ### 2-column, 1-row layout, single panel in each column
  1582  
  1583  - Top-level panel, but specifying a width of 6 columns each
  1584  
  1585  ```hcl
  1586  report two_column_one_row {
  1587  
  1588    panel left {
  1589      width = 6
  1590      source = steampipe.panel.markdown
  1591      text = "# Left Side"
  1592    }
  1593  
  1594    panel right {
  1595      width = 6
  1596      source = steampipe.panel.markdown
  1597      text = "# Right Side"
  1598    }
  1599  
  1600  }
  1601  ```
  1602  
  1603  ### 1-column, 2-row layout, single panel in each row
  1604  
  1605  - Top-level panel, so implicitly 12 columns wide
  1606  - Child panels
  1607  - No height specified, so will fill available height
  1608  
  1609  ```hcl
  1610  report one_column_two_row {
  1611  
  1612    panel main {
  1613  
  1614      panel first {
  1615        source = steampipe.panel.markdown
  1616        text = "# First Row"
  1617      }
  1618  
  1619      panel second {
  1620        source = steampipe.panel.markdown
  1621        text = "# Second Row"
  1622      }
  1623  
  1624    }
  1625  
  1626  }
  1627  ```
  1628  
  1629  ### Basic report with header, nav, content and footer
  1630  
  1631  ```hcl
  1632  report basic {
  1633  
  1634    panel header {
  1635      source = steampipe.panel.markdown
  1636      text = "# Header"
  1637    }
  1638  
  1639    panel main {
  1640  
  1641      panel nav {
  1642        width = 3
  1643        source = steampipe.panel.markdown
  1644        text = "# Nav"
  1645      }
  1646  
  1647      panel content {
  1648        width = 9
  1649        source = steampipe.panel.markdown
  1650        text = "# Content"
  1651      }
  1652  
  1653    }
  1654  
  1655    panel footer {
  1656      source = steampipe.panel.markdown
  1657      text = "# Footer"
  1658    }
  1659  
  1660  }
  1661  ```
  1662  
  1663  ### 2-column, 1-row layout with nested panels
  1664  
  1665  - Top-level panel, so implicitly 24 columns wide
  1666  - No height specified, so will fill available height
  1667  
  1668  ```hcl
  1669  panel header_top_row {
  1670  
  1671    panel left {
  1672      width = 6
  1673      source = steampipe.panel.markdown
  1674      text = "# Left"
  1675    }
  1676  
  1677    panel right {
  1678      width = 6
  1679      source = steampipe.panel.markdown
  1680      text = "# Right"
  1681    }
  1682  
  1683  }
  1684  
  1685  panel main {
  1686  
  1687    panel header {
  1688      source = panel.header_top_row
  1689    }
  1690  
  1691  }
  1692  ```
  1693  
  1694  ### 2-column, 1-row layout with 2 nested panels each containing 2 columns
  1695  
  1696  - Top-level panel, so implicitly 24 columns wide
  1697  - No height specified, so will fill available height
  1698  
  1699  ```hcl
  1700  panel content_left {
  1701  
  1702    panel left {
  1703      width = 6
  1704      source = steampipe.panel.markdown
  1705      text = "# One"
  1706    }
  1707  
  1708    panel right {
  1709      width = 6
  1710      source = steampipe.panel.markdown
  1711      text = "# Two"
  1712    }
  1713  
  1714  }
  1715  
  1716  panel content_right {
  1717  
  1718    panel left {
  1719      width = 6
  1720      source = steampipe.panel.markdown
  1721      text = "# Three"
  1722    }
  1723  
  1724    panel right {
  1725      width = 6
  1726      source = steampipe.panel.markdown
  1727      text = "# Four"
  1728    }
  1729  
  1730  }
  1731  
  1732  panel main {
  1733  
  1734    panel left {
  1735      width = 6
  1736      source = panel.content_left
  1737    }
  1738  
  1739    panel right {
  1740      width = 6
  1741      source = panel.content_right
  1742    }
  1743  
  1744  }
  1745  ```
  1746  
  1747  ## Primitives
  1748  
  1749  ### Panel
  1750  
  1751  The basic layout construct for reports
  1752  
  1753  ```hcl
  1754  panel header {
  1755    source = steampipe.panel.markdown
  1756    text = "# Render me"
  1757  }
  1758  ```
  1759  
  1760  ### Example AWS Report
  1761  
  1762  This example takes a few of the report primitives outlined above and composes them into a simple report
  1763  
  1764  ```hcl
  1765  report aws {
  1766  
  1767    panel header {
  1768      source = steampipe.panel.markdown
  1769      text = <<-EOT
  1770        # AWS Report
  1771        Overview of a variety of key AWS metrics.
  1772      EOT
  1773    }
  1774  
  1775    panel iam {
  1776  
  1777      panel iam-header {
  1778        source = steampipe.panel.markdown
  1779        text = "### IAM"
  1780      }
  1781  
  1782      panel iam-count {
  1783        width = 3
  1784        source = steampipe.panel.counter
  1785        query = "select count(*) as "Unused Access Keys" from aws_iam_user"
  1786      }
  1787  
  1788      panel iam-entities {
  1789        width = 9
  1790        source = steampipe.panel.barchart
  1791        query = "select groups, groups_quota, policies, policies_quota, roles, roles_quota, users, users_quota from aws_iam_account_summary;"
  1792      }
  1793  
  1794    }
  1795  
  1796    panel cost {
  1797      width = 8
  1798  
  1799      panel cost-header {
  1800        source = steampipe.panel.markdown
  1801        text = "### Cost"
  1802      }
  1803  
  1804      panel cost-monthly {
  1805        source = steampipe.panel.linechart
  1806        query = "select period_start as "Period Start", unblended_cost_amount as "Unblended Cost" from aws_cost_by_account where granularity = 'monthly' order by period_start;"
  1807      }
  1808  
  1809    }
  1810  
  1811    panel lambda {
  1812      width = 4
  1813  
  1814      panel lambda-header {
  1815        source = steampipe.panel.markdown
  1816        text = "### Lambda"
  1817      }
  1818  
  1819      panel lambda-runtimes {
  1820        source = steampipe.panel.piechart
  1821        query = "select runtime as "Runtime", count(runtime) as "Count" from aws_lambda_function group by runtime order by runtime;"
  1822      }
  1823  
  1824    }
  1825  
  1826    panel kms {
  1827  
  1828      panel kms-header {
  1829        source = steampipe.panel.markdown
  1830        text = "### KMS"
  1831      }
  1832  
  1833      panel kms-keys {
  1834        source = steampipe.panel.table
  1835        query = "select title as "Id", region as "Region", key_rotation_enabled as "Rotation Enabled", description as "Description" from aws_kms_key;"
  1836      }
  1837  
  1838    }
  1839  
  1840  }
  1841  ```