Prototype: classfilterdata(data_container, data_structure, key_or_index)

Return type: data

Description: This function filters a data container (data_container) based on defined classes. Records within the data container containing a class expression located at a given key or index (key_or_index) are filtered out when they evaluate to false in the current context. The interpretation of the data container depends on the specified data structure (data_structure).

If the data_structure argument is specified to be:

  • "array_of_arrays", the data_container argument is interpreted as an array of arrays, and the key_or_index argument is interpreted as an index within the children arrays. The key_or_index argument is required.
  • "array_of_objects", the data_container argument is interpreted as an array of objects, and the key_or_index argument is interpreted as a key within the children objects. The key_or_index argument is required.
  • "object_of_arrays", the data_container argument is interpreted as an object of arrays, and the key_or_index argument is interpreted as an index within the children arrays (if specified). If the key_or_index argument is omitted, the key of the child array itself is used as a class expression.
  • "object_of_objects", the data_container argument is interpreted as an object if objects, and the key_or_index argument is interpreted as a key within the children objects (if specified). If the key_or_index argument is omitted, the key of the child object itself is used as a class expression.
  • "auto", the interpretation is automatically detected based on the data structure.

Arguments:

  • data_container: string - CFEngine variable identifier or inline JSON - in the range: .*
  • data_structure: - Specify type of data structure - one of
    • array_of_arrays
    • array_of_objects
    • object_of_arrays
    • object_of_objects
    • auto
  • key_or_index: string - Key or index of class expressions - in the range: .*

Example (with array of arrays):

Policy:

bundle agent __main__
{
  classes:
      "role_2";

  vars:
      "original"
        data => '[
            [ "role_1",  "alice",  32 ],
            [ "!role_1", "bob",    24 ],
            [ "role_2",  "malcom", 27 ]
          ]';

      "filtered"
        data => classfilterdata("original", "array_of_arrays", "0");

  reports:
      "Filtered data: $(with)"
        with => storejson("filtered");
}

Output:

R: Filtered data: [
  [
    "!role_1",
    "bob",
    24
  ],
  [
    "role_2",
    "malcom",
    27
  ]
]

Example (with array of objects):

Policy:

bundle agent __main__
{
  classes:
      "role_2";

  vars:
      "original"
        data => '[
            { "file": "/tmp/foo", "ifvarclass": "role_1"          },
            { "file": "/tmp/bar", "ifvarclass": "role_2"          },
            { "file": "/tmp/baz", "ifvarclass": "(role_1|role_2)" }
          ]';

      "filtered"
        data => classfilterdata("original", "array_of_objects", "ifvarclass");

  reports:
      "Filtered data: $(with)"
        with => storejson("filtered");
}

Output:

R: Filtered data: [
  {
    "file": "/tmp/bar",
    "ifvarclass": "role_2"
  },
  {
    "file": "/tmp/baz",
    "ifvarclass": "(role_1|role_2)"
  }
]

Example (with object of arrays):

Policy:

bundle agent __main__
{
  classes:
      "role_2";

  vars:
      "original"
        data => '{
            "alice":  [  "role_1", 32 ],
            "bob":    [ "!role_1", 24 ],
            "malcom": [  "role_2", 27 ]
          }';

      "filtered"
        data => classfilterdata("original", "object_of_arrays", "0");

  reports:
      "Filtered data: $(with)"
        with => storejson("filtered");
}

Output:

R: Filtered data: {
  "bob": [
    "!role_1",
    24
  ],
  "malcom": [
    "role_2",
    27
  ]
}

Example (with object of objects using key inside the object):

Policy:

bundle agent __main__
{
  classes:
      "role_2";

  vars:
      "original"
        data => '{
            "/tmp/foo": { "ifvarclass":          "role_1" },
            "/tmp/bar": { "ifvarclass":          "role_2" },
            "/tmp/baz": { "ifvarclass": "(role_1|role_2)" }
          }';

      "filtered"
        data => classfilterdata("original", "object_of_objects", "ifvarclass");

  reports:
      "Filtered data: $(with)"
        with => storejson("filtered");
}

Output:

R: Filtered data: {
  "/tmp/bar": {
    "ifvarclass": "role_2"
  },
  "/tmp/baz": {
    "ifvarclass": "(role_1|role_2)"
  }
}

Example (with object of arrays using key to the object itself):

Policy:

bundle agent __main__
{
  classes:
      "role_2";

  vars:
      "original"
        data => '{
            "role_1"  : [  "alice", 32 ],
            "!role_1" : [    "bob", 24 ],
            "role_2"  : [ "malcom", 27 ]
          }';

      # Using exogenous key (i.e., the key of the child array within the parent object)
      "filtered"
        data => classfilterdata("original", "object_of_arrays");

  reports:
      "Filtered data: $(with)"
        with => storejson("filtered");
}

Output:

R: Filtered data: {
  "!role_1": [
    "bob",
    24
  ],
  "role_2": [
    "malcom",
    27
  ]
}

Example (with object of objects using key to the object itself):

Policy:

bundle agent __main__
{
  classes:
      "role_2";

  vars:
      "original"
        data => '{
            "role_1":          { "file": "/tmp/foo" },
            "role_2":          { "file": "/tmp/bar" },
            "(role_1|role_2)": { "file": "/tmp/baz" }
          }';

      # Using exogenous key (i.e., the key of the child object within the parent object)
      "filtered"
        data => classfilterdata("original", "object_of_objects");

  reports:
      "Filtered data: $(with)"
        with => storejson("filtered");
}

Output:

R: Filtered data: {
  "(role_1|role_2)": {
    "file": "/tmp/baz"
  },
  "role_2": {
    "file": "/tmp/bar"
  }
}

Notes:

This function can accept many types of data parameters (See collecting function ).

See also: classfiltercsv() , data_expand() , classmatch()

History:

  • Introduced in CFEngine 3.27.0