How can I use or with a classes type promise where an element is negated with not().

It's not currently possible to use not() directly within an or classes promise since it returns a string and not boolean.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
   bundle agent main
   {
     vars:
       "f" string => "/tmp/missing"; 

     classes:

       "missing"
         or => { not( fileexists( $(f) ) ) };
      
       "exists"
         or => { fileexists( $(f) ) };

      reports:
       missing:: 
        "$(f) is missing";

       exists:: 
        "$(f) is present";
  }
Using not() inside a classes or results in syntax error

Running the policy results in a syntax error

   error: Function does not return the required type
     "missing" or => { not( fileexists( $(f) ) ) };
                                                  ^
   error: There are syntax errors in policy files

Since the string returned by not() is any, if it evaluates to false and !any if it evaluates to true we can use classify() to see if the result matches a currently defined class.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
  bundle agent main
  {
    vars:
      "f" string => "/tmp/missing"; 
      
    classes:
      "missing"
        or => {
                classify( not( fileexists( $(f) ) ) )
              };

      "exists"
        or => { fileexists( $(f) )  };

      reports:
       missing:: 
        "$(f) is missing";

       exists:: 
        "$(f) is present";
  }
Use classify to cast the result of not as a boolean

Now the policy works as expected.

R: /tmp/missing is missing