18

Is it possible to add an existing user to a group with puppet 2.7.18?

We have two modules, each one defines one class :

  • module "user" creates all users, including user foo and user bar.
  • module "subversion" deals with various conf files and creates group svn.

We would like to add user foo to group svn inside module "subversion".

I've tried the membership parameter as described in the existing feature request:

group {
"svn":
    ensure  => present,
    gid     => xxxxx;
}
user {
"foo":
    group      => ["svn"],
    membership => minimum;
}

But I get the following error :

err: Could not retrieve catalog from remote server: Error 400 on SERVER: Duplicate declaration: User[foo] is already declared in file /pathto/modules/subversion/manifests/init.pp at line xx; cannot redeclare at /pathto/modules/users/manifests/init.pp:xxx on node myserver.example.com

Is this feature is already implemented? If not, is there a good workaround?

3 Answers3

23

Using Puppet virtual resources is the right way to do it - but if you can't change the user definitions and need a workaround fix meanwhile, the following is horrible and hacky, but will work:

exec { 'foo somegroup membership':
  unless  => '/bin/grep -q "somegroup\\S*foo" /etc/group',
  command => '/sbin/usermod -aG somegroup foo',
  require => User['foo'],
}

Essentially we just check if somegroup contains user foo yet... if not, use the normal usermod commands to add it in addition to the existing groups that foo belongs to.

Greg Dubicki
  • 1,191
  • 1
  • 14
  • 30
dodocaptain
  • 231
  • 2
  • 3
  • 1
    Puppet might riquire fully qualified paths to the executables. Edited to reflect this. – h7r Apr 18 '14 at 13:12
  • 2
    Horrible & hacky, but really helpful. I was hoping not to have to learn a new language construct to do something a conceptually simple as adding a user to a group. – BillMan Jul 01 '14 at 14:45
  • 1
    Perhaps a more proper (while still being hacky of course) way would be to use `getent group somegroup|cut -d: -f4|grep -q foo` to not assume we're using `/etc/group`. – falstro Dec 05 '14 at 11:42
  • Super helpful - thanks. I had to change the "unless" and "usermod" to include the full path as follow: unless => "/user/bin/grep..." command => "/user/bin/usermod..." – JNP Web Developer Sep 18 '15 at 14:25
  • For @jnpWebDeveloper and those like them: as per the [documentation](https://docs.puppet.com/puppet/latest/types/exec.html#exec-attribute-path), you can specify a `path` parameter as well. I suggest having a global resource default, perhaps that pulls in `$PATH` from facter. – cincodenada Jan 27 '17 at 01:09
  • If we're going to implement portable ugly hacks, I'd be inclined to use `id -nG foo | grep somegroup`, as an environment using LDAP or similar could potentially have both local and remote groups with the same name. getent generally only returns the first one, which might miss some. Also, primary group membership isn't always in /etc/group, so one needs to check the gid field in /etc/passwd as well. Or just use id (or groups), which does all that work for you. :) – dannysauer Feb 20 '17 at 20:17
18

If you declare users as virtual resources , you can then use 'realize' or the collection syntax ( User <| ... |>). Here's an example:

@user { 'foo':
  groups     => ['somegroup'],
  membership => minimum,
}

Then realize that virtual user with then collection syntax:

User <| title == foo |>

And elsewhere you can add to the parameters for that virtual resource using plusignment:

User <| title == foo |> { groups +> "svn" }
рüффп
  • 620
  • 1
  • 11
  • 24
dotplus
  • 1,220
  • 7
  • 12
3

Thanks - ugly hack for sure, but it gets the job done. Here's a pathed example (combining the above comments) to add 'nrpe' to the 'nagios' group. I used a package require as the user here is RPM provided rather than by puppet.

  exec {"nrpe nagios membership":
    unless => "/bin/getent group nagios|/bin/cut -d: -f4|/bin/grep -q nrpe",
    command => "/usr/sbin/usermod -a -G nagios nrpe",
    require => Package['nrpe'],
  }
Bill McGonigle
  • 647
  • 5
  • 8