List difference inside a bundle

22 views
Skip to first unread message

Bob

unread,
Sep 16, 2016, 5:32:59 PM9/16/16
to help-cfengine
I've been looking into this and am stumped. I have a list of users and when I remove a user from that list I want cfengine to remove the user from the system.  Here's what I am attempting:

body common control
{
  bundlesequence  => { "example" };
  inputs          => {
                       "/var/lib/cfengine3/inputs/cfengine_stdlib.cf" ,
                     };
}

bundle agent example
{
vars:
  "users[user1234][gecos]"  string => "Bob,,,,";
  "users[user1234][group]"  string => "users";
  "users[user1234][groups]" string => "dialout";
  "users[user1234][shell]"  string => "/bin/bash";
  "staff[user9876][gecos]"  string => "Ray,,,,";
  "staff[user9876][group]"  string => "users";
  "staff[user9876][groups]" string => "sudo,adm,staff";
  "staff[user9876][shell]"  string => "/bin/bash";

  "std_users" slist => getindices("users");
  "staff_users" slist => getindices("staff");
  "active_users" slist => { @(std_users), @(staff_users) };

methods:
  linux::
    "rm_users" usebundle => remove_users("$(active_users)");
}

# Remove any users on the system that are not in the auth_users array
bundle agent remove_users(auth_users)
{
vars:
  linux::
    "all_users" slist => getusers("","");
    "real_users" slist => filter("user[0-9]+",all_users,true,false,32767);
    "unauth_users" slist => difference($(auth_users), real_users); # Nonsense

reports:
  cfengine_3::
    "$(unauth_users)";

}

and my output is:

R: $(unauth_users)

Which is not what I expect. Using cfengine 3.6.2 on Debian Jessie. Please help.

Nick Anderson

unread,
Sep 18, 2016, 1:54:51 AM9/18/16
to help-cfengine


On Friday, September 16, 2016 at 4:32:59 PM UTC-5, Bob wrote:
I've been looking into this and am stumped. I have a list of users and when I remove a user from that list I want cfengine to remove the user from the system.

Hey Bob,

  You can use [`intersection()'] to figure out which users on the system
  are authorized based on your white list. Then you can use
  [`difference()'] to figure out which users are on the system that are
  not authorized. [`filter()'] is useful when you want to use a regular
  expression to filter a list.

  Here is your example slightly re-factored, I think this is what you
  were looking for.

  ┌────
  │ bundle agent main
  │ {
  │   vars:

  │     "users[user1234][gecos]"  string => "Bob,,,,";
  │     "users[user1234][group]"  string => "users";
  │     "users[user1234][groups]" string => "dialout";
  │     "users[user1234][shell]"  string => "/bin/bash";
  │
  │     "staff[user9876][gecos]"  string => "Ray,,,,";
  │     "staff[user9876][group]"  string => "users";
  │     "staff[user9876][groups]" string => "sudo,adm,staff";
  │     "staff[user9876][shell]"  string => "/bin/bash";
  │
  │     "std_users" slist => getindices("users");
  │     "staff_users" slist => getindices("staff");
  │
  │   # I added my system users in while I was testing.
  │     "system_users" slist => { "root", "daemon", "bin", "sys", "games", "man",
  │       "lp", "mail", "news", "uucp", "proxy", "www-data", "backup", "list", "irc",
  │       "gnats", "nobody", "syslog", "messagebus", "usbmux", "dnsmasq", "ntp",
  │       "lightdm", "systemd-timesync", "systemd-network", "systemd-resolve",
  │       "systemd-bus-proxy", "uuidd", "_apt", "avahi", "colord" };
  │
  │   # I added my own user to the list while testing.
  │     "active_users" slist => { @(std_users), @(staff_users), @(system_users), "nickanderson" };
  │
  │   methods:
  │     linux::
  │
  │       # When you reference a list @() as a scalar $() the list is automatically
  │       # iterated over. That will result in the promise being actuated once for
  │       # each element in the list. In this case remove_users would get actuated 2
  │       # times (once for each user) instead of one time and passing in the entire
  │       # list.
  │
  │       #"rm_users" usebundle => remove_users("$(active_users)");
  │       "rm_users" usebundle => remove_users( @(active_users) );
  │
  │   reports:
  │     "CFEngine Version $(sys.cf_version)";
  │ }
  │
  │ # Remove any users on the system that are not in the auth_users list
  │ bundle agent remove_users(auth_users)

  │ {
  │   vars:
  │     linux::
  │       "all_users" slist => getusers("","");
  │
  │       # Which accounts on the system are authorized?
  │       "authorized_users_on_system"
  │         slist => intersection( auth_users, all_users );
  │
  │       # Which accounts on the system are not authorized?
  │       "users_on_system_who_are_not_authorized"
  │         slist => difference( all_users, authorized_users_on_system );
  │
  │       # filter() is useful when you want to operate on a regular expression.
  │       # Which users start with the letter s?
  │       "users_starting_with_s" slist => filter("s.*", all_users, "true", "false", 32767);
  │
  │       # Which users do not start with the letter s?
  │       "users_not_starting_with_s" slist => filter("s.*", all_users, "true", "true", 32767);
  │
  │   reports:
  │     cfengine_3::
  │       "The following users are found on the system, but not explicitly authorized";
  │       'They should be automatically removed ( users: "$(const.dollar)(users_on_system_who_are_not_authorized)" policy => "absent";';
  │       "$(users_on_system_who_are_not_authorized)";
  │ }
  └────
  Listing 1: Example using `intersection()', `difference()', and
  `filter()'.

  ┌────
  │ R: The following users are found on the system, but not explicitly authorized
  │ R: They should be automatically removed ( users: "$(users_on_system_who_are_not_authorized)" policy => "absent";
  │ R: sync
  │ R: whoopsie
  │ R: CFEngine Version 3.7.4
  └────

[`intersection()']
https://docs.cfengine.com/lts/reference-functions-intersection.html

[`difference()']
https://docs.cfengine.com/lts/reference-functions-difference.html

[`filter()']
https://docs.cfengine.com/lts/reference-functions-filter.html

Bob

unread,
Sep 19, 2016, 10:26:55 AM9/19/16
to help-c...@googlegroups.com
Thanks, Nick. Your technique is working great.
Reply all
Reply to author
Forward
0 new messages