]> Frank Brehm's Git Trees - salt/states.git/commitdiff
Adding some own modules and states and using them
authorFrank Brehm <frank@brehm-online.com>
Wed, 30 Mar 2016 20:47:34 +0000 (22:47 +0200)
committerFrank Brehm <frank@brehm-online.com>
Wed, 30 Mar 2016 20:47:34 +0000 (22:47 +0200)
_modules/str_manip.py [new file with mode: 0644]
_modules/user_info.py [new file with mode: 0644]
_states/user_info.py [new file with mode: 0644]
basic/root.sls [new file with mode: 0644]
top.sls

diff --git a/_modules/str_manip.py b/_modules/str_manip.py
new file mode 100644 (file)
index 0000000..68dc0fc
--- /dev/null
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+'''
+Performing some string manipulations.
+'''
+
+import re
+
+def camelCase(st):
+    output = ''.join(x for x in st.title() if x.isalnum())
+    return output[0].lower() + output[1:]
+
+def CamelCase(st):
+    return ''.join(x for x in st.title() if x.isalnum())
+
diff --git a/_modules/user_info.py b/_modules/user_info.py
new file mode 100644 (file)
index 0000000..b582245
--- /dev/null
@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+'''
+Manage user gecos with the usermod command
+'''
+
+# Import python libs
+#import re
+
+try:
+    import pwd
+except ImportError:
+    pass
+import logging
+#import copy
+
+# Import salt libs
+import salt.utils
+#from salt._compat import string_types
+
+log = logging.getLogger(__name__)
+
+
+# -----------------------------------------------------------------------------
+def _get_gecos(name):
+    '''
+    Retrieve GECOS field info
+    '''
+    gecos_field = pwd.getpwnam(name).pw_gecos
+    if not gecos_field:
+        return ''
+    return gecos_field.strip()
+
+
+# -----------------------------------------------------------------------------
+def chgecos(name, gecos):
+    '''
+    Change the gecos information of the user
+
+    CLI Example:
+
+    .. code-block:: bash
+
+        salt '*' user_info.chgecos root "root ServerXYZ"
+    '''
+
+    used_gecos = ''
+    if gecos is not None:
+        used_gecos = str(gecos).strip()
+
+    pre_gecos = _get_gecos(name)
+    if used_gecos == pre_gecos:
+        log.debug("User {0!r} has already gecos {1!r}.".format(name, used_gecos))
+        return True
+
+    log.info("Setting gecos of user {0!r} to {1!r} ...".format(name, used_gecos))
+
+    cmd = 'usermod -c "{0}" {1}'.format(used_gecos, name)
+    __salt__['cmd.run'](cmd)
+
+    post_gecos = _get_gecos(name)
+    if pre_gecos != post_gecos:
+        return post_gecos == used_gecos
+    return False
+
+
+# -----------------------------------------------------------------------------
+def info(name):
+    '''
+    Return user information
+
+    CLI Example:
+
+    .. code-block:: bash
+
+        salt '*' user.info root
+    '''
+
+    log.debug("Trying to get informations about user {0!r} ...".format(name))
+
+    try:
+        data = pwd.getpwnam(name)
+    except KeyError:
+        return {}
+    else:
+        return _format_info(data)
+
+
+# -----------------------------------------------------------------------------
+def list_groups(name):
+    '''
+    Return a list of groups the named user belongs to
+
+    CLI Example:
+
+    .. code-block:: bash
+
+        salt '*' user.list_groups foo
+    '''
+    return salt.utils.get_group_list(name)
+
+
+# -----------------------------------------------------------------------------
+def _format_info(data):
+    '''
+    Return user information in a pretty way
+    '''
+
+    return {'gid': data.pw_gid,
+            'groups': list_groups(data.pw_name),
+            'home': data.pw_dir,
+            'name': data.pw_name,
+            'passwd': data.pw_passwd,
+            'shell': data.pw_shell,
+            'uid': data.pw_uid,
+            'gecos': data.pw_gecos}
+
+
+# -----------------------------------------------------------------------------
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/_states/user_info.py b/_states/user_info.py
new file mode 100644 (file)
index 0000000..4967446
--- /dev/null
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+'''
+Management of user name (gecos)
+===============================
+
+The user_info state is designated for managing the full username
+in the passwd file (gecos).
+
+    fred:
+      user_info.present:
+        - gecos: Fred Jones
+
+'''
+
+# Import python libs
+import logging
+
+# Import salt libs
+import salt.utils
+
+log = logging.getLogger(__name__)
+
+
+# -----------------------------------------------------------------------------
+def _group_changes(cur, wanted, remove=True):
+    '''
+    Determine if the groups need to be changed
+    '''
+    old = set(cur)
+    new = set(wanted)
+    if (remove and old != new) or (not remove and not new.issubset(old)):
+        return True
+    return False
+
+
+# -----------------------------------------------------------------------------
+def _changes(name, gecos=None):
+    '''
+    Return a dict of the changes required for a user if the user is present,
+    otherwise return False.
+    '''
+
+    lusr = __salt__['user_info.info'](name)
+    if not lusr:
+        return False
+
+    change = {}
+    if gecos is not None:
+        gecos = gecos.strip()
+        if lusr['gecos'] != gecos:
+            change['gecos'] = gecos
+
+    return change
+
+
+# -----------------------------------------------------------------------------
+def present(name, gecos=None):
+    '''
+    Ensure, that the user information of the named user are correct.
+
+    name
+        The name of the user to manage
+
+    gecos
+        The gecos (the complete username) to assign.
+    '''
+
+    if gecos is not None:
+        gecos = str(gecos).strip()
+
+    ret = {'name': name,
+           'changes': {},
+           'result': True,
+           'comment': 'User {0!r} is present and up to date'.format(name)}
+
+    changes = _changes(name, gecos=gecos)
+    if not changes:
+        if changes is False:
+            msg = "User {0!r} to change the the user info does not exists.".format(name)
+            log.warning(msg)
+        else:
+            msg = "User {0!r} is up to date.".format(name)
+        ret['comment'] = msg
+        return ret
+
+    log.debug("Got following changes for user {0!r}: {1!r}".format(name, changes))
+
+    # The user is present
+    if __opts__['test']:
+        ret['result'] = None
+        ret['comment'] = ('The following user attributes are set to be changed:\n')
+        for key, val in changes.items():
+            ret['comment'] += '{0}: {1}\n'.format(key, val)
+        return ret
+
+    pre = __salt__['user_info.info'](name)
+
+    for key, val in changes.items():
+        if key == 'gecos':
+            __salt__['user_info.chgecos'](name, val)
+        else:
+            __salt__['user.ch{0}'.format(key)](name, val)
+
+    post = __salt__['user_info.info'](name)
+    spost = {}
+    # See if anything changed
+    for key in post:
+        if post[key] != pre[key]:
+            ret['changes'][key] = post[key]
+    if ret['changes']:
+        ret['comment'] = 'Updated user {0}'.format(name)
+    changes = _changes(name, gecos=gecos)
+    if changes:
+        ret['comment'] = 'These values could not be changed: {0}'.format(
+            changes
+        )
+        ret['result'] = False
+    return ret
+
+
+# -----------------------------------------------------------------------------
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/basic/root.sls b/basic/root.sls
new file mode 100644 (file)
index 0000000..d4df3f6
--- /dev/null
@@ -0,0 +1,5 @@
+#-------------------------------------
+root:
+  user_info.present:
+    - gecos: root {{ salt['str_manip.CamelCase'](salt['grains.get']('host')) }}
+
diff --git a/top.sls b/top.sls
index 5add5873911efba015485f0f60c0de9fa15efa5c..8e287debb278e20342f7a4c8b1d571b1fbb9acae 100644 (file)
--- a/top.sls
+++ b/top.sls
@@ -12,6 +12,7 @@ base:
     - basic.rsyslog
     - basic.shells
     - basic.skel
+    - basic.root
     - postfix.common
     - fail2ban
     - bind
@@ -27,4 +28,6 @@ base:
     - basic.chrony
     - basic.rsyslog
     - basic.shells
+    - basic.skel
+    - basic.root