-
Notifications
You must be signed in to change notification settings - Fork 577
Description
Related to issue #930
The current behaviour for artifacts called by the Artifact plugin is that preconditions are disabled. This means that artifacts that are designed to be called from other artifacts have to be written and tested with this limitation in mind.
If the called artifact needs to implement conditional behaviour equivalent to multiple sources with a precondition for each source, then this has to be done using the switch() and if() functions in one block of VQL. This is far less visually comprehensible than an artifact with multiple sources with a precondition for each source, especially if viewing the artifact in a text editor that doesn't do VQL syntax highlighting.
If preconditions are only possible on top-level artifacts then this encourages the development of monolithic/standalone artifacts and discourages modular artifact development, and therefore discourages code reusability.
As an example consider this artifact that uses preconditions:
parameters:
- name: foo
type: bool
default: true
sources:
- name: A
precondition: SELECT log(message="precondition A") FROM scope() WHERE foo
query: SELECT "A ran" AS message FROM scope()
- name: B
precondition: SELECT log(message="precondition B") FROM scope() WHERE NOT foo
query: SELECT "B ran" AS message FROM scope()
- name: C
precondition: SELECT log(message="precondition C") FROM scope()
query: SELECT "C ran" AS message FROM scope()If the above artifact needs to be called from another artifact then it has to be written thusly:
parameters:
- name: foo
type: bool
default: true
sources:
- name: AorBandC
query: |
SELECT * FROM chain(
x={ SELECT * FROM switch(
a={ SELECT *
FROM if(condition={ SELECT log(message="precondition A")
FROM scope() WHERE foo },
then={ SELECT "A ran" AS message FROM scope() } ) },
b={ SELECT *
FROM if(condition={ SELECT log(message="precondition B")
FROM scope() WHERE NOT foo },
then={ SELECT "B ran" AS message FROM scope() } ) }
)},
c={ SELECT *
FROM if(condition={ SELECT log(message="precondition C")
FROM scope() },
then={ SELECT "C ran" AS message FROM scope() } ) }
)The 2nd version is obviously far less comprehensible, even though it's still a relatively simple artifact (in the real world I have far more complicated artifacts) 🤮
I would like to propose that we allow preconditions to be optionally enabled when calling an artifact via the Artifact plugin. This option could be presented to the user as a new argument on the Artifact plugin, for example:
SELECT * FROM Artifact.Foo.Bar(preconditions=enabled)
The current behaviour of disabling preconditions in called artifacts could be preserved by making preconditions=disabled the default for the Artifact plugin.