blackstork-io / fabric

An open-source command-line tool for cybersecurity reporting automation and a configuration language for reusable templates. Reporting-as-Code
https://blackstork.io/fabric/
Apache License 2.0
27 stars 2 forks source link

Syntax sugar for no-query-result condition #28

Open traut opened 8 months ago

traut commented 8 months ago

Background

https://github.com/blackstork-io/fabric/issues/142 introduces dynamic blocks. One typical pattern is to select which content to render based on the query result.

Design

Implement syntactic sugar t


content text {
  query = ".data.inline.my_elements"
  value = "The elements: {{ .data.inline.my_elements }}"

  when_empty_result content text {
    ...
  }
}

is unpacked into

dynamic content text {
  query = ".data.inline.my_elements"
  condition_query = "(.query_result == {} or .query_result == [] or .query_result == null) | not"

  value = "The elements: {{ .data.inline.my_elements }}"
}

dynamic content text {
  query = ".data.inline.my_elements"
  condition_query = ".query_result == {} or .query_result == [] or .query_result == null"

  value = "There are no elements"
}

Deliverables

dobarx commented 7 months ago

Shouldn't this be outside of the content block? Like using something like dynamic block with a condition when to render content.

traut commented 7 months ago

It is pretty close to the dynamic block concept (I'm still working on the issue for that), indeed! We need to figure out an unobstructed syntax here -- it would be too cumbersome for the template authors to wrap every content block into another dynamic block. It needs to be a small addition, not a syntax change. Maybe these in-block fields can be syntactic sugar implemented through the dynamic blocks in the logic.

traut commented 5 months ago

with https://github.com/blackstork-io/fabric/issues/142 in mind, I think this issue still stands -- dynamic blocks are not well suitable for not-null checks

dobarx commented 5 months ago

@traut What if we added a child block type for all content blocks? Something like:

content table {
  query = "..."
  ...
  empty_result {
    content text {
       value = "Empty data!"
    }
}

This would be a bit more flexible because we could specify any fallback content block.

traut commented 5 months ago

that's neat, it's declarative and provides more options. To reduce the nest-iness, maybe it can be a content block with some flag, like

content table {
  query = "..."
  ...
  when_empty content text {
     value = "Empty data!"
  }
}

?

and we can use ref as well:

content table {
  query = "..."
  ...
  when_empty content ref {
     base = content.text.empty_data
  }
}
traut commented 5 months ago

still not great :) it's confusing -- is empty_result / when_empty about the parent block or the nested block?

dobarx commented 5 months ago

on_empty? Could also extend in the future with fallbacks for errors on_error.

traut commented 5 months ago

oh, that's lovely.

content table {
  query = "..."
  ...
  on_empty content text {
     value = "Empty data!"
  }
}

content table {
  query = "..."
  ...
  on_empty content ref {
     base = content.text.empty_data
  }
}

would be ok, I think

traut commented 5 months ago

moving this to draft since https://github.com/blackstork-io/fabric/issues/142 already can provide the functionality, even though in a bit wordy way