#!/usr/bin/env python # (c) 2012, Stephen Fromm # # This file is part of Ansible # # Ansible 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, either version 3 of the License, or # (at your option) any later version. # # Ansible 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 Ansible. If not, see . try: import json except ImportError: import simplejson as json import os import grp import shlex import subprocess import sys GROUPADD = "/usr/sbin/groupadd" GROUPDEL = "/usr/sbin/groupdel" GROUPMOD = "/usr/sbin/groupmod" def debug(msg): # ansible ignores stderr, so it's safe to use for debug print >>sys.stderr, msg #pass def exit_json(rc=0, **kwargs): if 'name' in kwargs: debug("add group info to exit_json") add_group_info(kwargs) print json.dumps(kwargs) sys.exit(rc) def fail_json(**kwargs): kwargs['failed'] = True exit_json(rc=1, **kwargs) def add_group_info(kwargs): name = kwargs['name'] if group_exists(name): kwargs['state'] = 'present' info = group_info(name) kwargs['gid'] = info[2] else: kwargs['state'] = 'absent' return kwargs def group_del(group): cmd = [GROUPDEL, group] debug("Arguments to groupdel: %s" % (" ".join(cmd))) rc = subprocess.call(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if rc == 0: return True else: return False def group_add(group, **kwargs): cmd = [GROUPADD] for key in kwargs: if key == 'gid' and kwargs[key] is not None: cmd.append('-g') cmd.append(kwargs[key]) cmd.append(group) debug("Arguments to groupadd: %s" % (" ".join(cmd))) rc = subprocess.call(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if rc == 0: return True else: return False def group_mod(group, **kwargs): cmd = [GROUPMOD] info = group_info(group) for key in kwargs: if key == 'gid': if kwargs[key] is not None and info[2] != int(kwargs[key]): cmd.append('-g') cmd.append(kwargs[key]) if len(cmd) == 1: return False cmd.append(group) debug("Arguments to groupmod: %s" % (" ".join(cmd))) rc = subprocess.call(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if rc == 0: return True else: return False def group_exists(group): try: if grp.getgrnam(group): return True except KeyError: return False def group_info(group): if not group_exists(group): return False try: info = list(grp.getgrnam(group)) except KeyError: return False return info # =========================================== if not os.path.exists(GROUPADD): if os.path.exists("/sbin/groupadd"): GROUPADD = "/sbin/groupadd" else: fail_json(msg="Cannot find groupadd") if not os.path.exists(GROUPDEL): if os.path.exists("/sbin/groupdel"): GROUPDEL = "/sbin/groupdel" else: fail_json(msg="Cannot find groupdel") if not os.path.exists(GROUPMOD): if os.path.exists("/sbin/groupmod"): GROUPDEL = "/sbin/groupmod" else: fail_json(msg="Cannot find groupmod") if len(sys.argv) == 2 and os.path.exists(sys.argv[1]): argfile = sys.argv[1] args = open(argfile, 'r').read() else: args = ' '.join(sys.argv[1:]) items = shlex.split(args) if not len(items): fail_json(msg='the module requires arguments -a') sys.exit(1) params = {} for x in items: (k, v) = x.split("=") params[k] = v state = params.get('state','present') name = params.get('name', None) gid = params.get('gid', None) if state not in [ 'present', 'absent' ]: fail_json(msg='invalid state') if name is None: fail_json(msg='name is required') changed = False rc = 0 if state == 'absent': if group_exists(name): changed = group_del(name) exit_json(name=name, changed=changed) elif state == 'present': if not group_exists(name): changed = group_add(name, gid=gid) else: changed = group_mod(name, gid=gid) exit_json(name=name, changed=changed) fail_json(name=name, msg='Unexpected position reached')