Skip to content

CFE-4562: classfilterdata(): added support of object of arrays and object of objects #5850

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

larsewi
Copy link
Contributor

@larsewi larsewi commented Aug 5, 2025

  • classfilterdata() now supports object of objects
  • classfilterdata() now supports object of arrays
  • classfilterdata(): deduped code for getting class expression
  • classfilterdata(): added examples for object of arrays/objects

@larsewi larsewi force-pushed the classfilterdata-i2 branch from 0e7d1e7 to d96b4fe Compare August 5, 2025 14:35
@larsewi larsewi force-pushed the classfilterdata-i2 branch 4 times, most recently from 74876c4 to e73693f Compare August 5, 2025 15:51
@larsewi larsewi marked this pull request as ready for review August 5, 2025 21:02
@larsewi larsewi force-pushed the classfilterdata-i2 branch 2 times, most recently from 96a4953 to b7a2d8d Compare August 6, 2025 09:30
@larsewi
Copy link
Contributor Author

larsewi commented Aug 6, 2025

@cf-bottom Jenkins please :)

larsewi added 2 commits August 6, 2025 12:27
The class expression can be stored in either the objects exogenous key
(i.e., the key to the object itself) or the value of a specified
endogenous key (i.e., a key inside the object).

Ticket: CFE-4562
Changelog: Commit
Signed-off-by: Lars Erik Wik <[email protected]>
The class expression can be stored in either the objects exogenous key
(i.e., the key to the object itself) or the value of a specified
endogenous index (i.e., a index inside the object).

Changelog: Commit
Signed-off-by: Lars Erik Wik <[email protected]>
@larsewi larsewi force-pushed the classfilterdata-i2 branch from b7a2d8d to 9819c78 Compare August 6, 2025 10:27
@larsewi larsewi force-pushed the classfilterdata-i2 branch from 9819c78 to 1ef4707 Compare August 6, 2025 11:08
@cfengine cfengine deleted a comment from cf-bottom Aug 6, 2025
@cf-bottom
Copy link

larsewi added a commit to larsewi/documentation that referenced this pull request Aug 11, 2025
…/objects"

This commit broke docs because it depends on
cfengine/core#5850. Once the dependency is
merged, it should be safe to reapply this commit.

This reverts commit 3bc6348.

Ticket: CFE-4562
Signed-off-by: Lars Erik Wik <[email protected]>
@larsewi larsewi requested review from jakub-nt and victormlg August 12, 2025 10:55
Copy link
Contributor

@victormlg victormlg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool!

Copy link
Contributor

@craigcomstock craigcomstock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great! I would generally suggest replacing exogenous and the other term with more plain language that will be easier for maintenance programmers to handle.

@@ -7864,6 +7865,13 @@ static bool ClassFilterDataArray(
JsonElement *child,
bool *remove)
{
if (key_or_index == NULL) {
Log(LOG_LEVEL_VERBOSE,
"Function %s(): At least 3 arguments are required when the data structure is an array of arrays or array of objects",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe you could mention the third parameter is key or index so they don't have to check the manual.

ARG_UNUSED const char *fn_name,
ARG_UNUSED JsonElement *json_array,
ARG_UNUSED const char *class_expr_index,
ARG_UNUSED const char *exogenous_key,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't prefer the word exogenous as it is too specifically linguistically technical. Maybe self_key? 🚲 🏠 (bikeshed todo). Ideally you want to write code that a less smart maintainer can handle :)

const char *fn_name,
JsonElement *json_object,
const char *class_expr_key,
const char *exogenous_key,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe self_key?

if (json_child == NULL)
{
Log(LOG_LEVEL_VERBOSE,
"Function %s(): Bad class expression key '%s': Key not found",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we aren't validating if it is a "bad class expression" aka somehow not a well formed class expression then this message should only say "Function %s(): Key not found with class expression '%s'".

Do we have a function that can validate a class expression? Should add that to a static checking tool like cf-promises?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, I see, asserting that the class expression is not empty, maybe just say "Looking for key in the object itself and found none." or similar.

ctx, fn_name, child, key_or_index, exogenous_key, remove);
}
Log(LOG_LEVEL_VERBOSE,
"Function %s(): Expected child element to be of container type array",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be helpful to mention the type the item WAS? aka "to be of container type array but was %s", data_structure


while ((child != NULL))
{
const char *exogenous_key = JsonIteratorCurrentKey(&iter);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, I think you should change exogenous_key to self_key or something that is easier to understand.

if (remove)
{
NDEBUG_UNUSED bool success = JsonObjectRemoveKey(parent, exogenous_key);
assert(success);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why no production-time error handling here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It fails if the key-value pair you are trying to remove does not exist. However, we already know that it does. Thus, it should never return false.

Comment on lines +8128 to +8130
/* Only parent type array and object is supported */
Log(LOG_LEVEL_VERBOSE,
"Function %s(): Expected parent element to be of container type array or object",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe remove the comment since that is in the log message and remove "array or object" and just leave it at "container type"? Or maybe even remove "container type" and just specify "array or object type" since those are more generally understandable than our special use of the term "container".

{
meta:
"description" -> { "CFE-4562" }
string => "Test for expected results from classfilterdata() with object of objects using endogenous key";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace endogenous key with something less technical, as I suggested "self_key" for "exogenous_key", maybe this would be "internal_key"?

assert(SIZE_MAX >= ULONG_MAX); /* make sure returned value can fit in size_t */
if (StringToUlong(class_expr_index, &index) != 0) {
Log(LOG_LEVEL_VERBOSE,
"Function %s(): Bad class expression index '%s': Failed to parse integer",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is an index a class expression? shouldn't that just be an index, aka integer and specific to this function as an argument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants