Uploaded image for project: 'CFEngine Community'
  1. CFEngine Community
  2. CFE-2400

ifelse should be useable in control bodies

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Open
    • Priority: High
    • Resolution: Unresolved
    • Affects Version/s: 3.9.0, 3.7.3
    • Fix Version/s: None
    • Component/s: Evaluation
    • Labels:
      None

      Description

      In working on the MPF to make it easier to customize without modifying shipped files I found I am unable to use ifelse() in body common control. I get an error that "Function does not return the required type".

      I can use the same function call in a common body without issue.

      Consider this def.json. It will set def.ignore_missing_inputs to true, and it will define def.augments_inputs as a list that includes missing.cf (a policy input that does not exist).

      {
        "vars": {
          "ignore_missing_inputs": "true"
        },
        "inputs": [ "missing.cf" ]
      }
      

      I should be able to use the following policy to set body common control ignore_missing_inputs to the value specified in the def.json and default it in the case it is not defined.

      body common control
      {
        ignore_missing_inputs => ifelse( isvariable("def.ignore_missing_inputs"), $(def.ignore_missing_inputs), "false");
      
        inputs => { @(def.augments_inputs) };
      }
      
      bundle agent main
      {
        reports:
          "def.ignore_missing_inputs = '$(def.ignore_missing_inputs)'";
      }
      

      It is possible to work around this issue by adding a vars promie using the same ifelse function call inside the def bundle and pointing the body common control attribute to it. For example:

      body common control
      {
        ignore_missing_inputs => "$(def.ignore_missing_inputs)";
        inputs => { @(def.augments_inputs) };
      }
      
      bundle common def
      {
        vars:
           # I would like to avoid having to define this intermediary variable and
           # use the ifelse(isvariable directly in body common control.
      
           "ignore_missing_inputs"
             string => ifelse( isvariable("def.ignore_missing_inputs"),
                                          $(def.ignore_missing_inputs),
                               "false");
      }
      
      bundle agent main
      {
        reports:
          "def.ignore_missing_inputs = '$(def.ignore_missing_inputs)'";
      }
      

      Here is the policy run output on 3.9.0:

      [root@hub masterfiles]# cf-agent -Kf ./test.cf
      R: def.ignore_missing_inputs = 'true'
      

      And after changing def.json so that it should not ignore missing inputs:

      [root@hub masterfiles]# cat def.json
      {
        "vars": {
          "ignore_missing_inputs": "false"
        },
        "inputs": [ "missing.cf" ]
      }
      
      [root@hub masterfiles]# cf-agent -Kf ./test.cf
         error: Can't stat file './missing.cf' for parsing. (stat: No such file or directory)
         error: Policy failed validation with command '"/var/cfengine/bin/cf-promises" -c "./test.cf"'
         error: Failsafe condition triggered. Interactive session detected, skipping failsafe.cf execution.
         error: Error reading CFEngine policy. Exiting...
      

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                olehermanse Ole Herman Schumacher Elgesem
                Reporter:
                a10042 Nick Anderson
              • Votes:
                1 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:

                  Summary Panel