Merge "Configure /etc/default/useradd through 'defaults'"
diff --git a/.gitreview b/.gitreview
new file mode 100644
index 0000000..443a01c
--- /dev/null
+++ b/.gitreview
@@ -0,0 +1,3 @@
+[gerrit]
+host=gerrit.mcp.mirantis.com
+project=salt-formulas/linux.git
diff --git a/README.rst b/README.rst
index c844aef..2993b55 100644
--- a/README.rst
+++ b/README.rst
@@ -76,6 +76,50 @@
             home: '/home/elizabeth'
             password: "$6$nUI7QEz3$dFYjzQqK5cJ6HQ38KqG4gTWA9eJu3aKx6TRVDFh6BVJxJgFWg2akfAA7f1fCxcSUeOJ2arCO6EEI6XXnHXxG10"
 
+Setting user defaults
+---------------------
+Default parameters that will be used by `useradd` command could be configured
+the following way:
+
+.. code-block:: yaml
+
+  linux:
+    system:
+      ...
+      defaults:
+        user:
+          shell: <SHELL>
+          gid: <GROUP>
+          home: <HOME>
+          inactdays: <INACTIVE>
+          expire: <EXPIRE>
+          skeleton: <SKEL>
+          create_mail_spool: <CREATE_MAIL_SPOOL>
+
+Other parameters that are used when creating user profile could be configured
+as well, acting as global defaults:
+
+.. code-block:: yaml
+
+  linux:
+    system:
+      ...
+      defaults:
+        user:
+          ...
+          maxdays: <PASS_MAX_DAYS>
+          mindays: <PASS_MIN_DAYS>
+          warndays: <PASS_WARN_AGE>
+
+.. note::
+
+  The three options above ('maxdays', 'mindays', 'warndays') could be
+  overriden in linux:system:login_defs using their 'real' names.
+  The reason they could be defined here is that it's quite logical to
+  have these parameters related to configuration of user account
+  behaviour in one place.
+
+
 Configure password expiration parameters
 ----------------------------------------
 The following login.defs parameters can be overridden per-user:
@@ -83,7 +127,6 @@
 * PASS_MAX_DAYS
 * PASS_MIN_DAYS
 * PASS_WARN_DAYS
-* INACTIVE
 
 .. code-block:: yaml
 
@@ -97,8 +140,7 @@
             ...
             maxdays: <PASS_MAX_DAYS>
             mindays: <PASS_MIN_DAYS>
-            warndays: <PASS_WARN_DAYS>
-            inactdays: <INACTIVE>
+            warndays: <PASS_WARN_AGE>
 
 Configure sudo for users and groups under ``/etc/sudoers.d/``.
 This ways ``linux.system.sudo`` pillar map to actual sudo attributes:
diff --git a/linux/files/etc_default_useradd.jinja b/linux/files/etc_default_useradd.jinja
new file mode 100644
index 0000000..076cfeb
--- /dev/null
+++ b/linux/files/etc_default_useradd.jinja
@@ -0,0 +1,50 @@
+# This file is managed by Salt, do not edit
+{%- macro define_option(option_name, option_key, default=None) %}
+  {%- set value = defaults.get(option_key, default) %}
+  {%- if value != None %}
+{{ option_name }}={{ value }}
+  {%- endif %}
+{%- endmacro %}
+# Default values for useradd(8)
+#
+# The SHELL variable specifies the default login shell on your
+# system.
+# Similar to DHSELL in adduser. However, we use "sh" here because
+# useradd is a low level utility and should be as general
+# as possible
+# SHELL=/bin/sh
+{{- define_option('SHELL', 'shell', default='/bin/sh') }}
+#
+# The default group for users
+# 100=users on Debian systems
+# Same as USERS_GID in adduser
+# This argument is used when the -n flag is specified.
+# The default behavior (when -n and -g are not specified) is to create a
+# primary user group with the same name as the user being added to the
+# system.
+# GROUP=100
+{{- define_option('GROUP', 'gid') }}
+#
+# The default home directory. Same as DHOME for adduser
+# HOME=/home
+{{- define_option('HOME', 'home') }}
+#
+# The number of days after a password expires until the account
+# is permanently disabled
+# INACTIVE=-1
+{{- define_option('INACTIVE', 'inactdays') }}
+#
+# The default expire date
+# EXPIRE=
+{{- define_option('EXPIRE', 'expire') }}
+#
+# The SKEL variable specifies the directory containing "skeletal" user
+# files; in other words, files such as a sample .profile that will be
+# copied to the new user's home directory when it is created.
+# SKEL=/etc/skel
+{{- define_option('SKEL', 'skeleton') }}
+#
+# Defines whether the mail spool should be created while
+# creating the account
+# CREATE_MAIL_SPOOL=yes
+{{- define_option('CREATE_MAIN_SPOOL', 'create_mail_spool')}}
\ No newline at end of file
diff --git a/linux/files/login.defs.jinja b/linux/files/login.defs.jinja
index 572c558..ad4d6d3 100644
--- a/linux/files/login.defs.jinja
+++ b/linux/files/login.defs.jinja
@@ -52,11 +52,30 @@
     'USERDEL_CMD',
     'USERGROUPS_ENAB'
 ] %}
+{#
+  'defaults' could be passed externally, in this case it should be dictionary
+#}
+{%- if defaults is not defined %}
+  {%- set defaults = {} %}
+{%- endif %}
+{#
+  Override values in 'defaults' with those defined in system:login_defs as they
+  are of highest priority.
+#}
 {%- for opt_name in allowed_options %}
   {%- if opt_name in login_defs %}
     {%- set opt_params = login_defs.get(opt_name) %}
     {%- if opt_params.get('enabled', true) %}
-{{ opt_name.ljust(20) }} {{ opt_params.value }}
+      {%- do defaults.update({opt_name: opt_params.value}) %}
     {%- endif %}
   {%- endif %}
 {%- endfor %}
+{#
+  Now we can write merged data to file, keeping order of items as in the list above
+#}
+{%- for opt_name in allowed_options %}
+  {%- set value = defaults.get(opt_name, None) %}
+  {%- if value != None %}
+{{ opt_name.ljust(20) }} {{ value }}
+  {%- endif %}
+{%- endfor %}
diff --git a/linux/system/login_defs.sls b/linux/system/login_defs.sls
index f94348a..914e6eb 100644
--- a/linux/system/login_defs.sls
+++ b/linux/system/login_defs.sls
@@ -1,6 +1,16 @@
 {%- from "linux/map.jinja" import system with context %}
 {%- if system.enabled %}
-  {%- if system.login_defs is defined %}
+  {%- set defaults = {} %}
+  {%- set user_defaults = system.get('defaults', {}).get('user', {}) %}
+  {%- for option_name, login_defs_name in [('maxdays', 'PASS_MAX_DAYS'),
+                                           ('mindays', 'PASS_MIN_DAYS'),
+                                           ('warndays', 'PASS_WARN_AGE')] %}
+    {%- set value = user_defaults.get(option_name, None) %}
+    {%- if value != None %}
+      {%- do defaults.update({login_defs_name: value}) %}
+    {%- endif %}
+  {%- endfor %}
+  {%- if system.login_defs is defined or defaults %}
 login_defs:
   file.managed:
     - name: /etc/login.defs
@@ -9,5 +19,7 @@
     - user: root
     - group: root
     - mode: 644
+    - defaults:
+        defaults: {{ defaults|yaml }}
   {%- endif %}
 {%- endif %}
diff --git a/linux/system/user.sls b/linux/system/user.sls
index 64636f3..ca95c34 100644
--- a/linux/system/user.sls
+++ b/linux/system/user.sls
@@ -4,74 +4,86 @@
 include:
   - linux.system.group
 
-{%- for name, user in system.user.items() %}
-
-{%- if user.enabled %}
-
-{%- set requires = [] %}
-{%- for group in user.get('groups', []) %}
-  {%- if group in system.get('group', {}).keys() %}
-    {%- do requires.append({'group': 'system_group_'+group}) %}
+  {%- set defaults = system.get('defaults', {}).get('user', {}) %}
+  {%- if defaults %}
+etc_default_useradd:
+  file.managed:
+    - name: /etc/default/useradd
+    - source: salt://linux/files/etc_default_useradd.jinja
+    - template: jinja
+    - user: root
+    - group: root
+    - mode: 644
+    - defaults:
+        defaults: {{ defaults|yaml }}
   {%- endif %}
-{%- endfor %}
 
-{%- if user.gid is not defined %}
+  {%- for name, user in system.user.items() %}
+    {%- if user.enabled %}
+      {%- set requires = [] %}
+      {%- for group in user.get('groups', []) %}
+        {%- if group in system.get('group', {}).keys() %}
+          {%- do requires.append({'group': 'system_group_'+group}) %}
+        {%- endif %}
+      {%- endfor %}
+
+      {%- if user.gid is not defined %}
 system_group_{{ name }}:
   group.present:
   - name: {{ name }}
   - require_in:
     - user: system_user_{{ name }}
-{%- endif %}
+      {%- endif %}
 
 system_user_{{ name }}:
   user.present:
   - name: {{ name }}
   - home: {{ user.home }}
-  {% if user.get('password') == False %}
+      {% if user.get('password') == False %}
   - enforce_password: false
-  {% elif user.get('password') == None %}
+      {% elif user.get('password') == None %}
   - enforce_password: true
   - password: '*'
-  {% elif user.get('password') %}
+      {% elif user.get('password') %}
   - enforce_password: true
   - password: {{ user.password }}
   - hash_password: {{ user.get('hash_password', False) }}
-  {% endif %}
-  {%- if user.gid is defined and user.gid %}
+      {% endif %}
+      {%- if user.gid is defined and user.gid %}
   - gid: {{ user.gid }}
-  {%- else %}
+      {%- else %}
   - gid_from_name: true
-  {%- endif %}
-  {%- if user.groups is defined %}
+      {%- endif %}
+      {%- if user.groups is defined %}
   - groups: {{ user.groups }}
-  {%- endif %}
-  {%- if user.optional_groups is defined %}
+      {%- endif %}
+      {%- if user.optional_groups is defined %}
   - optional_groups: {{ user.optional_groups }}
-  {%- endif %}
-  {%- if user.system is defined and user.system %}
+      {%- endif %}
+      {%- if user.system is defined and user.system %}
   - system: True
   - shell: {{ user.get('shell', '/bin/false') }}
-  {%- else %}
+      {%- else %}
   - shell: {{ user.get('shell', '/bin/bash') }}
-  {%- endif %}
-  {%- if user.uid is defined and user.uid %}
+      {%- endif %}
+      {%- if user.uid is defined and user.uid %}
   - uid: {{ user.uid }}
-  {%- endif %}
-  {%- if user.unique is defined %}
+      {%- endif %}
+      {%- if user.unique is defined %}
   - unique: {{ user.unique }}
-  {%- endif %}
-  {%- if user.maxdays is defined %}
+      {%- endif %}
+      {%- if user.maxdays is defined %}
   - maxdays: {{ user.maxdays }}
-  {%- endif %}
-  {%- if user.mindays is defined %}
+      {%- endif %}
+      {%- if user.mindays is defined %}
   - mindays: {{ user.mindays }}
-  {%- endif %}
-  {%- if user.warndays is defined %}
+      {%- endif %}
+      {%- if user.warndays is defined %}
   - warndays: {{ user.warndays }}
-  {%- endif %}
-  {%- if user.inactdays is defined %}
+      {%- endif %}
+      {%- if user.inactdays is defined %}
   - inactdays: {{ user.inactdays }}
-  {%- endif %}
+      {%- endif %}
   - require: {{ requires|yaml }}
 
 system_user_home_{{ user.home }}:
@@ -83,7 +95,7 @@
   - require:
     - user: system_user_{{ name }}
 
-{%- if user.get('sudo', False) %}
+      {%- if user.get('sudo', False) %}
 
 /etc/sudoers.d/90-salt-user-{{ name|replace('.', '-') }}:
   file.managed:
@@ -98,14 +110,13 @@
     - user: system_user_{{ name }}
   - check_cmd: /usr/sbin/visudo -c -f
 
-{%- else %}
+      {%- else %}
 
 /etc/sudoers.d/90-salt-user-{{ name|replace('.', '-') }}:
   file.absent
 
-{%- endif %}
-
-{%- else %}
+      {%- endif %}
+    {%- else %}
 
 system_user_{{ name }}:
   user.absent:
@@ -118,8 +129,6 @@
 /etc/sudoers.d/90-salt-user-{{ name|replace('.', '-') }}:
   file.absent
 
-{%- endif %}
-
-{%- endfor %}
-
+    {%- endif %}
+  {%- endfor %}
 {%- endif %}