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.