Re: How to best NOT run a command

"'Nick Anderson' via help-cfengine" <[email protected]> Tue, 13 Feb 2024 10:46:05 -0600
Newsgroups gmane.comp.sysutils.cfengine.general
Message-ID <[email protected]>
        Nick:

        This is very helpful. I watched that Agent-is-In episode
        three times this weekend and worked on setting up my own
        cfengine installation. I've been working with Org-Mode
        since we talked about it a couple of months ago.

  Great, org-mode is fantastic, and paired with ob-cfengine3 at least I
  find it super great for prototyping small policy.

        My real question that I wanted to ask was about the
        structure of the `if` statement since I wanted to do
        something like this:

        bundle agent __main__ { vars: "el_authselect_features"
        slist => { "with-custom-group", "with-custom-passwd",
        "with-mkhomedir", "with-sudo", "with-files-domain",
        "without-nullok" };

        commands: "/usr/bin/authselect select sssd --force" AND
                      "/usr/bin/authselect enable-feature
                      $(el_authselect_features)" if => not(
                      returnzero( "/usr/bin/authselect current -r
                      | grep sssd > /dev/null 2>&1", "useshell" )
                      ); }

        I was thinking how to use `canonify`, but I'm not sure
        that works in this case. Is what I'm trying to do
        possible?

  It's not clear to me what you are looking for here.

  Is it that you want to run `authselect select sssd --force &&
  authselect enable-feature with-custom-group with-custom-password
  with-mkhomedir with-sudo with-files-domain without-nullok' or you want
  to run `authselect select sssd --force && authselect enable-feature
  with-custom-group && authselect enable-feature with-custom-password &&
  authselect enable-feature with-mkhomedir && authselect enable-feature
  with-sudo && authselect enable-feature with-files-domain && authselect
  enable-feature without-nullok'?

  There are few ways to run /multiple/ commands in a single promise. If
  that is what you want generally you put the multiple commands into a
  script and run the script as a commands promise. If you need to
  communicate more back to the agent then that script could output in
  the [variables and classes module protocol format]. Alternatively if
  you execute the commands promise in a shell you can use `&&' or `;' to
  separate the individual commands within the single statement.

  Also, what happens if after you get into your desired state an intern
  fed Gizmo after midnight, then Spike comes along and runs `authselect
  disable-feature with-custom-group'? Your condition (`authselect
  current -r | grep sssd') will pass, and no commands will be run. Just
  glancing [here] at some random doc result on `authselect' I see that
  `authselect current' returns a list of enabled features:

  ,----
  | $ authselect current
  | Profile ID: sssd
  | Enabled features:
  | - with-sudo
  | - with-mkhomedir
  | - with-smartcard
  `----

  It seems you can also get enabled features for a given profile with
  `authselect list-features profile_id'.

  ,----
  | # authselect list-features sssd
  | with-custom-automount
  | with-custom-group
  | with-custom-netgroup
  | with-custom-passwd
  | with-custom-services
  | with-faillock
  | with-files-access-provider
  | with-fingerprint
  | with-mkhomedir
  | with-pam-u2f
  | with-pam-u2f-2fa
  | with-pamaccess
  | with-silent-lastlog
  | with-smartcard
  | with-smartcard-lock-on-removal
  | with-smartcard-required
  | with-sudo
  | without-nullok
  | without-pam-u2f-nouserok
  `----

  You could use `difference()' to figure out which desired features are
  not enabled so that you can enable the proper ones, you could also use
  `difference()' to figure out which enabled features are not explicitly
  desired (maybe you want to disable those).

  ,----
  | bundle agent __main__
  | {
  |  vars:
  |      "current_features_enabled"
  |        # slist => string_split( "/usr/bin/authselect list-features", "\n", inf );
  |        slist => { "with-sudo",
  |                   "with-mkhomedir",
  |                   "with-smartcard"
  |        };
  |
  |      "desired_features_enabled"
  |        slist => {  "with-custom-group",
  |                    "with-custom-passwd",
  |                    "with-mkhomedir",
  |                    "with-sudo",
  |                    "with-files-domain",
  |                    "without-nullok",
  |        };
  |
  |      "desired_features_missing"
  |        slist => difference( "desired_features_enabled", "current_features_enabled" );
  |
  |      "enabled_features_not_explicitly_desired"
  |        slist => difference( "current_features_enabled","desired_features_enabled" );
  |
  |
  |       reports:
  |       "Missing desired feature: $(desired_features_missing)";
  |       "/usr/bin/authselect enable-feature $(desired_features_missing)";
  |       "Extra features enabled: $(with)"
  |         with => join( ", ", enabled_features_not_explicitly_desired );
  |       "/usr/bin/authselect disable-feature $(enabled_features_not_explicitly_desired)?";
  | }
  `----

  ,----
  | R: Missing desired feature: with-custom-group
  | R: Missing desired feature: with-custom-passwd
  | R: Missing desired feature: with-files-domain
  | R: Missing desired feature: without-nullok
  | R: /usr/bin/authselect enable-feature with-custom-group
  | R: /usr/bin/authselect enable-feature with-custom-passwd
  | R: /usr/bin/authselect enable-feature with-files-domain
  | R: /usr/bin/authselect enable-feature without-nullok
  | R: Extra features enabled: with-smartcard
  | R: /usr/bin/authselect disable-feature with-smartcard?
  `----

  So, that might result in some policy like this (no warranty,
  untested!):

  ,----
  | bundle agent authselect_sssd
  | {
  |     methods:
  |     "authselect_profile";
  |     "authselect_features";
  | }
  | bundle agent authselect_profile
  | {
  |     commands:
  |       "/usr/bin/authselect select sssd --force"
  |         if => not( returnszero( "/usr/bin/authselect current -r | grep sssd > /dev/null 2>&1", "useshell" ) );
  | }
  | bundle agent authselect_features
  | {
  |   vars:
  |       "current_profile"
  |         string => execresult( "/usr/bin/authselect current -r", noshell);
  |
  |       "current_features_enabled"
  |         slist => string_split( "/usr/bin/authselect list-features", "\n", inf );
  |
  |       "desired_features_enabled"
  |         slist => {  "with-custom-group",
  |                     "with-custom-passwd",
  |                     "with-mkhomedir",
  |                     "with-sudo",
  |                     "with-files-domain",
  |                     "without-nullok",
  |         };
  |
  |       "desired_features_missing"
  |         slist => difference( "desired_features_enabled", "current_features_enabled" );
  |
  |      "enabled_features_not_explicitly_desired"
  |        slist => difference( "current_features_enabled","desired_features_enabled" );
  |
  |   commands:
  |       # Run authselect enable-feature for each feature that is not currently enabled if the current profile is sssd
  |       "/usr/bin/authselect enable-feature $(desired_features_enabled)"
  |         if => and( strcmp( "$(current_profile)", "sssd" ),
  |                    isgreaterthan( length( desired_features_missing ), 0 ) ); # Alternatively I think you could use some() matching .*
  |
  |        "/usr/bin/authselect disable-feature $(enabled_features_not_explicitly_desired)"
  |         if => and( strcmp( "$(current_profile)", "sssd" ),
  |                    isgreaterthan( length( enabled_features_not_explicitly_desired ), 0 ) );
  |
  | }
  `----

  This will result in a fair number of commands being executed during
  each policy execution, if that turns out to be more overhead than
  desired for some reason then you could consider caching the result of
  the probing commands.


[variables and classes module protocol format]
<https://docs.cfengine.com/docs/3.23/reference-language-concepts-modules.html#variables-and-classes-modules>

[here]
<https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_authentication_and_authorization_in_rhel/configuring-user-authentication-using-authselect_configuring-authentication-and-authorization-in-rhel>

-- 
You received this message because you are subscribed to the Google Groups "help-cfengine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion on the web visit https://groups.google.com/d/msgid/help-cfengine/87r0hg5n3m.fsf%40northern.tech.