Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
ncharles committed Mar 17, 2020
1 parent 6a8a5bc commit fc09fd3
Show file tree
Hide file tree
Showing 2 changed files with 244 additions and 0 deletions.
146 changes: 146 additions & 0 deletions tests/acceptance/30_generic_methods/unsafe/user_group.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#######################################################
#
# Test setting user secondary group
# Works with users rudder_{i}
# cleaned in post execution
#
#######################################################

bundle common acc_path
{
vars:
"root" string => getenv("NCF_TESTS_ACCEPTANCE", 1024);
}

body common control
{
inputs => { "${acc_path.root}/default.cf.sub", "${acc_path.root}/default_ncf.cf.sub", "@{ncf_inputs.default_files}" };
bundlesequence => { configuration, default("${this.promise_filename}") };
version => "1.0";
}

#######################################################

bundle agent init
{
vars:
# REPAIR

"user[1]" string => "rudder_1";
"group[1]" string => "ruddergroup_1";
"expected_group[1]" string => "ruddergroup_1";
"init_group[1]" string => ""; # init group for user
"create_group[1]" string => "false"; # precreate group, yes or no
"create_user[1]" string => "true"; # precreate user, yes or no
"mode[1]" string => "enforce";
"status[1]" string => "repaired";

"user[2]" string => "rudder_2";
"group[2]" string => "ruddergroup_2";
"expected_group[2]" string => "ruddergroup_1 ruddergroup_2";
"init_group[2]" string => "ruddergroup_1"; # init group for user
"create_group[2]" string => "true"; # precreate group, yes or no
"create_user[2]" string => "true"; # precreate user, yes or no
"mode[2]" string => "enforce";
"status[2]" string => "repaired";

# SUCCESS
"user[3]" string => "rudder_3";
"group[3]" string => "ruddergroup_3";
"expected_group[3]" string => "ruddergroup_3";
"init_group[3]" string => "ruddergroup_3"; # init group for user
"create_group[3]" string => "true"; # precreate group, yes or no
"create_user[3]" string => "true"; # precreate user, yes or no
"mode[3]" string => "enforce";
"status[3]" string => "success";

"user[4]" string => "rudder_4";
"group[4]" string => "ruddergroup_4";
"expected_group[4]" string => "ruddergroup_4 ruddergroup_1";
"init_group[4]" string => "ruddergroup_4,ruddergroup_1"; # init group for user
"create_group[4]" string => "true"; # precreate group, yes or no
"create_user[4]" string => "true"; # precreate user, yes or no
"mode[4]" string => "enforce";
"status[4]" string => "success";

"indices" slist => {1, 2, 3, 4, 5, 6, 7, 8};

classes:
# define create class
"create_user_${indices}" expression => strcmp("${create_user[${indices}]}", "true");
"create_group_${indices}" expression => strcmp("${create_group[${indices}]}", "true");

commands:
# create groups
"${paths.groupadd} ruddergroup_${indices}";

# create user
"${paths.useradd} ${user[${indices}]}"
if => "create_user_${indices}";

"${paths.usermod} -a -G ${init_group[${indices}]} ${user[${indices}]}"
if => "create_user_${indices}.create_group_${indices}";

}

#######################################################

bundle agent test
{
vars:
"args${init.indices}" slist => { "${init.user[${init.indices}]}", "${init.group[${init.indices}]}" };
classes:
"pass2" expression => "pass1";
"pass1" expression => "any";

methods:
pass1.!pass2::
#REPAIRED
"ph1" usebundle => apply_gm("user_group", @{args1}, "${init.status[1]}", "ph1", "${init.mode[1]}" );
"ph2" usebundle => apply_gm("user_group", @{args2}, "${init.status[2]}", "ph2", "${init.mode[2]}" );
# SUCCESS
"ph3" usebundle => apply_gm("user_group", @{args3}, "${init.status[3]}", "ph3", "${init.mode[3]}" );
"ph4" usebundle => apply_gm("user_group", @{args4}, "${init.status[4]}", "ph4", "${init.mode[4]}" );
}


#######################################################

bundle agent check
{
vars:
pass1::
"user_group[${init.indices}]" string => execresult("/bin/id -Gn ${init.user[${init.indices}]}", "useshell");


classes:
"pass3" expression => "pass2";
"pass2" expression => "pass1";
"pass1" expression => "any";

# checking mode only for enforce mode
"execute_${init.indices}" expression => strcmp("${init.mode[${init.indices}]}", "enforce");
"result_nok" not => strcmp("${user_group[${init.indices}]}", "${init.expected_group[${init.indices}]}"),
if => "execute_${init.indices}";

# classes_ok is just a placeholder. What we really want is find the not ok
"classes_not_ok" expression => or("classes_ok", "!ph${init.indices}_ok");
"ok" expression => "!classes_not_ok.!result_nok";

commands:
pass3::
"${paths.userdel} ${init.user[${init.indices}]}";
"${paths.groupdel} ruddergroup_${init.indices}";

reports:
pass3::
"Test for user_group nb ${init.indices} FAILED"
ifvarclass => "!ph${init.indices}_ok";

pass3.ok::
"$(this.promise_filename) Pass";
pass3.!ok::
"$(this.promise_filename) FAIL";
}

#######################################################
98 changes: 98 additions & 0 deletions tree/30_generic_methods/user_group.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#####################################################################################
# Copyright 2020 Normation SAS
#####################################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#####################################################################################

# @name User group
# @description Define secondary group for a user
# @documentation Ensure that a user is within a group
#
# #### Behavour
#
# Ensure that the user belongs in the given secondary group (non-exclusive)
#
# ##### Parameters
#
# `user` : the user login
# `group_name`: secondary group name the user should belong to (non-exclusive)
#
# #### Examples
#
# To ensure that user `test` belongs in group `dev`
#
# ```
# user_group("test", "99_rudder", "0", "")
# ```
# Note that it will make sure that user test is in group dev, but won't remove it
# from other groups it may belong to
#
# @parameter user User login
# @parameter group_name Secondary group name for the user
# @class_prefix user_group
# @class_parameter user



bundle agent user_group(user, group_name) {
vars:
"old_class_prefix" string => canonify("user_group_${user}");

"args" slist => { "${user}", "${group_name}" };
"report_param" string => join("_", args);
"full_class_prefix" string => canonify("user_group__${report_param}");
"class_prefix" string => string_head("${full_class_prefix}", "1000");

user_exists.group_exists::
"groups_test" string => execresult("/bin/id -Gn ${user}", "noshell");
"current_groups" slist => string_split("${groups_test}", " ", "999999");

pass2.user_exists.group_exists.!within_group::
"expected_group_list" slist => { @{current_groups}, ${group_name}};
pass2.user_exists.group_exists.within_group::
"expected_group_list" slist => { @{current_groups} };

classes:
"user_exists" expression => userexists("${user}");
"group_exists" expression => groupexists("${group_name}");

pass1::
# check if the required group is in the current groups
"within_group" expression => strcmp("${current_groups}", "${group_name}");

any::
"pass3" expression => "pass2";
"pass2" expression => "pass1";
"pass1" expression => "any";

users:
pass3.user_exists.group_exists::
"${user}"
policy => "present",
groups_secondary => { "@{expected_group_list}" },
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

methods:
!user_exists|!group_exists::
"error" usebundle => _classes_failure("${old_class_prefix}");
"error" usebundle => _classes_failure("${class_prefix}");

"report_failure"
usebundle => _log_v3("User ${user} or group ${group_name} don't exist,", "${user}", "${old_class_prefix}", "${class_prefix}", @{args});

pass3.user_exists.group_exists::
"report"
usebundle => _log_v3("Secondary group ${group_name} for user ${user}", "${user}", "${old_class_prefix}", "${class_prefix}", @{args});
}

0 comments on commit fc09fd3

Please sign in to comment.