Saltstack Official Users Formula
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
5.8KB

  1. # vim: sts=2 ts=2 sw=2 et ai
  2. {% from "users/map.jinja" import users with context %}
  3. {% set used_sudo = False %}
  4. {% for name, user in pillar.get('users', {}).items() if user.absent is not defined or not user.absent %}
  5. {%- if user == None -%}
  6. {%- set user = {} -%}
  7. {%- endif -%}
  8. {%- set home = user.get('home', "/home/%s" % name) -%}
  9. {%- if 'prime_group' in user and 'name' in user['prime_group'] %}
  10. {%- set user_group = user.prime_group.name -%}
  11. {%- else -%}
  12. {%- set user_group = name -%}
  13. {%- endif %}
  14. {% for group in user.get('groups', []) %}
  15. {{ name }}_{{ group }}_group:
  16. group:
  17. - name: {{ group }}
  18. - present
  19. {% endfor %}
  20. {{ name }}_user:
  21. file.directory:
  22. - name: {{ home }}
  23. - user: {{ name }}
  24. - group: {{ user_group }}
  25. - mode: {{ user.get('user_dir_mode', '0750') }}
  26. - require:
  27. - user: {{ name }}
  28. - group: {{ user_group }}
  29. group.present:
  30. - name: {{ user_group }}
  31. {%- if 'prime_group' in user and 'gid' in user['prime_group'] %}
  32. - gid: {{ user['prime_group']['gid'] }}
  33. {%- elif 'uid' in user %}
  34. - gid: {{ user['uid'] }}
  35. {%- endif %}
  36. user.present:
  37. - name: {{ name }}
  38. - home: {{ home }}
  39. - shell: {{ user.get('shell', users.get('shell', '/bin/bash')) }}
  40. {% if 'uid' in user -%}
  41. - uid: {{ user['uid'] }}
  42. {% endif -%}
  43. {% if 'password' in user -%}
  44. - password: '{{ user['password'] }}'
  45. {% endif -%}
  46. {% if 'prime_group' in user and 'gid' in user['prime_group'] -%}
  47. - gid: {{ user['prime_group']['gid'] }}
  48. {% else -%}
  49. - gid_from_name: True
  50. {% endif -%}
  51. {% if 'fullname' in user %}
  52. - fullname: {{ user['fullname'] }}
  53. {% endif -%}
  54. {% if not user.get('createhome', True) %}
  55. - createhome: False
  56. {% endif %}
  57. - remove_groups: {{ user.get('remove_groups', 'False') }}
  58. - groups:
  59. - {{ user_group }}
  60. {% for group in user.get('groups', []) -%}
  61. - {{ group }}
  62. {% endfor %}
  63. - require:
  64. - group: {{ user_group }}
  65. {% for group in user.get('groups', []) -%}
  66. - group: {{ group }}
  67. {% endfor %}
  68. user_keydir_{{ name }}:
  69. file.directory:
  70. - name: {{ user.get('home', '/home/{0}'.format(name)) }}/.ssh
  71. - user: {{ name }}
  72. - group: {{ user_group }}
  73. - makedirs: True
  74. - mode: 700
  75. - require:
  76. - user: {{ name }}
  77. - group: {{ user_group }}
  78. {%- for group in user.get('groups', []) %}
  79. - group: {{ group }}
  80. {%- endfor %}
  81. {% if 'ssh_keys' in user %}
  82. {% set key_type = 'id_' + user.get('ssh_key_type', 'rsa') %}
  83. user_{{ name }}_private_key:
  84. file.managed:
  85. - name: {{ user.get('home', '/home/{0}'.format(name)) }}/.ssh/{{ key_type }}
  86. - user: {{ name }}
  87. - group: {{ user_group }}
  88. - mode: 600
  89. - show_diff: False
  90. - contents_pillar: users:{{ name }}:ssh_keys:privkey
  91. - require:
  92. - user: {{ name }}_user
  93. {% for group in user.get('groups', []) %}
  94. - group: {{ name }}_{{ group }}_group
  95. {% endfor %}
  96. user_{{ name }}_public_key:
  97. file.managed:
  98. - name: {{ user.get('home', '/home/{0}'.format(name)) }}/.ssh/{{ key_type }}.pub
  99. - user: {{ name }}
  100. - group: {{ user_group }}
  101. - mode: 644
  102. - show_diff: False
  103. - contents_pillar: users:{{ name }}:ssh_keys:pubkey
  104. - require:
  105. - user: {{ name }}_user
  106. {% for group in user.get('groups', []) %}
  107. - group: {{ name }}_{{ group }}_group
  108. {% endfor %}
  109. {% endif %}
  110. {% if 'ssh_auth' in user %}
  111. {% for auth in user['ssh_auth'] %}
  112. ssh_auth_{{ name }}_{{ loop.index0 }}:
  113. ssh_auth.present:
  114. - user: {{ name }}
  115. - name: {{ auth }}
  116. - require:
  117. - file: {{ name }}_user
  118. - user: {{ name }}_user
  119. {% endfor %}
  120. {% endif %}
  121. {% if 'ssh_auth.absent' in user %}
  122. {% for auth in user['ssh_auth.absent'] %}
  123. ssh_auth_delete_{{ name }}_{{ loop.index0 }}:
  124. ssh_auth.absent:
  125. - user: {{ name }}
  126. - name: {{ auth }}
  127. - require:
  128. - file: {{ name }}_user
  129. - user: {{ name }}_user
  130. {% endfor %}
  131. {% endif %}
  132. {% if 'sudouser' in user and user['sudouser'] %}
  133. {% if not used_sudo %}
  134. {% set used_sudo = True %}
  135. include:
  136. - users.sudo
  137. {% endif %}
  138. sudoer-{{ name }}:
  139. file.managed:
  140. - name: {{ users.sudoers_dir }}/{{ name }}
  141. - user: root
  142. - group: {{ users.root_group }}
  143. - mode: '0440'
  144. {% if 'sudo_rules' in user %}
  145. {% for rule in user['sudo_rules'] %}
  146. "validate {{ name }} sudo rule {{ loop.index0 }} {{ name }} {{ rule }}":
  147. cmd.run:
  148. - name: 'visudo -cf - <<<"$rule" | { read output; if [[ $output != "stdin: parsed OK" ]] ; then echo $output ; fi }'
  149. - stateful: True
  150. - shell: {{ users.visudo_shell }}
  151. - env:
  152. # Specify the rule via an env var to avoid shell quoting issues.
  153. - rule: "{{ name }} {{ rule }}"
  154. - require_in:
  155. - file: {{ users.sudoers_dir }}/{{ name }}
  156. {% endfor %}
  157. {{ users.sudoers_dir }}/{{ name }}:
  158. file.managed:
  159. - contents: |
  160. {%- for rule in user['sudo_rules'] %}
  161. {{ name }} {{ rule }}
  162. {%- endfor %}
  163. - require:
  164. - file: sudoer-defaults
  165. - file: sudoer-{{ name }}
  166. {% endif %}
  167. {% else %}
  168. {{ users.sudoers_dir }}/{{ name }}:
  169. file.absent:
  170. - name: {{ users.sudoers_dir }}/{{ name }}
  171. {% endif %}
  172. {% endfor %}
  173. {% for name, user in pillar.get('users', {}).items() if user.absent is defined and user.absent %}
  174. {{ name }}:
  175. {% if 'purge' in user or 'force' in user %}
  176. user.absent:
  177. {% if 'purge' in user %}
  178. - purge: {{ user['purge'] }}
  179. {% endif %}
  180. {% if 'force' in user %}
  181. - force: {{ user['force'] }}
  182. {% endif %}
  183. {% else %}
  184. user.absent
  185. {% endif -%}
  186. {{ users.sudoers_dir }}/{{ name }}:
  187. file.absent:
  188. - name: {{ users.sudoers_dir }}/{{ name }}
  189. {% endfor %}
  190. {% for user in pillar.get('absent_users', []) %}
  191. {{ user }}:
  192. user.absent
  193. {{ users.sudoers_dir }}/{{ user }}:
  194. file.absent:
  195. - name: {{ users.sudoers_dir }}/{{ user }}
  196. {% endfor %}
  197. {% for group in pillar.get('absent_groups', []) %}
  198. {{ group }}:
  199. group.absent
  200. {% endfor %}