aboutsummaryrefslogtreecommitdiffstats
path: root/roles/nfs_server/tasks
diff options
context:
space:
mode:
Diffstat (limited to 'roles/nfs_server/tasks')
-rw-r--r--roles/nfs_server/tasks/autofs.yml57
-rw-r--r--roles/nfs_server/tasks/exports.yml55
-rw-r--r--roles/nfs_server/tasks/homedirs.yml112
-rw-r--r--roles/nfs_server/tasks/main.yml19
-rw-r--r--roles/nfs_server/tasks/nfs.yml41
-rw-r--r--roles/nfs_server/tasks/smb.yml54
6 files changed, 338 insertions, 0 deletions
diff --git a/roles/nfs_server/tasks/autofs.yml b/roles/nfs_server/tasks/autofs.yml
new file mode 100644
index 0000000..57bb862
--- /dev/null
+++ b/roles/nfs_server/tasks/autofs.yml
@@ -0,0 +1,57 @@
+- name: create automount maps for exports
+ ipaautomountmap:
+ ipaadmin_principal: '{{ ipa_user }}'
+ ipaadmin_password: '{{ ipa_pass }}'
+ name: '{{ item }}'
+ location: default
+ state: present
+ loop: "{{ nfs_exports | selectattr('automount_map', 'defined') | map(attribute='automount_map') | unique }}"
+
+- name: create automount keys for exports
+ ipaautomountkey:
+ ipaadmin_principal: '{{ ipa_user }}'
+ ipaadmin_password: '{{ ipa_pass }}'
+ location: default
+ mapname: '{{ item.automount_map }}'
+ key: '{{ item.automount_key | default(zfs_mountpoints[item.dataset] | basename) }}'
+ info: '-fstype=nfs4 {{ ansible_fqdn }}:{{ zfs_mountpoints[item.dataset] }}'
+ state: present
+ loop: "{{ nfs_exports | selectattr('automount_map', 'defined') }}"
+ loop_control:
+ label: '{{ item.dataset }}'
+
+- name: create automount maps for homedirs
+ ipaautomountmap:
+ ipaadmin_principal: '{{ ipa_user }}'
+ ipaadmin_password: '{{ ipa_pass }}'
+ name: '{{ item }}'
+ location: default
+ state: present
+ loop:
+ - '{{ nfs_homedir_home_automount_map }}'
+ - '{{ nfs_homedir_user_automount_map }}'
+ - '{{ nfs_homedir_group_automount_map }}'
+
+- name: create automount keys for homedirs
+ ipaautomountkey:
+ ipaadmin_principal: '{{ ipa_user }}'
+ ipaadmin_password: '{{ ipa_pass }}'
+ location: default
+ mapname: '{{ nfs_homedir_group_automount_map if item.group is defined else nfs_homedir_user_automount_map }}'
+ key: '{{ item.group if item.group is defined else item.user }}'
+ info: >-
+ /priv -fstype=nfs4 {{ ansible_fqdn }}:{{ zfs_mountpoints[nfs_homedir_group_dataset if item.group is defined else nfs_homedir_user_dataset] }}/{{ item.group if item.group is defined else item.user }}/priv
+ /pub -fstype=nfs4 {{ ansible_fqdn }}:{{ zfs_mountpoints[nfs_homedir_group_dataset if item.group is defined else nfs_homedir_user_dataset] }}/{{ item.group if item.group is defined else item.user }}/pub
+ state: present
+ loop: '{{ nfs_homedirs }}'
+
+- name: create /home automount keys
+ ipaautomountkey:
+ ipaadmin_principal: '{{ ipa_user }}'
+ ipaadmin_password: '{{ ipa_pass }}'
+ location: default
+ mapname: '{{ nfs_homedir_home_automount_map }}'
+ key: '{{ item }}'
+ info: '-fstype=nfs4 {{ ansible_fqdn }}:{{ zfs_mountpoints[nfs_homedir_user_dataset] }}/{{ item }}/priv'
+ state: present
+ loop: "{{ nfs_homedirs | selectattr('user', 'defined') | map(attribute='user') }}"
diff --git a/roles/nfs_server/tasks/exports.yml b/roles/nfs_server/tasks/exports.yml
new file mode 100644
index 0000000..10ff894
--- /dev/null
+++ b/roles/nfs_server/tasks/exports.yml
@@ -0,0 +1,55 @@
+- name: create zfs datasets for exports
+ zfs:
+ name: '{{ item.dataset }}'
+ state: present
+ extra_zfs_properties: '{{ item.zfs_properties if item.zfs_properties is defined else omit }}'
+ loop: "{{ nfs_exports | selectattr('dataset', 'defined') }}"
+ loop_control:
+ label: '{{ item.dataset }}'
+
+- name: collect zfs mountpoints
+ shell: "zfs list -Hp -o name,mountpoint | sed 's/\t/: /'"
+ changed_when: False
+ register: zfs_list_mountpoints
+
+- name: set zfs_mountpoints fact
+ set_fact:
+ zfs_mountpoints: '{{ zfs_list_mountpoints.stdout | from_yaml }}'
+
+- name: set directory permissions for exports
+ file:
+ path: '{{ zfs_mountpoints[item.dataset] }}'
+ owner: '{{ item.owner | default(omit) }}'
+ group: '{{ item.group | default(omit) }}'
+ mode: "{{ '0%0o' % item.mode if item.mode is defined else omit }}"
+ setype: _default
+ state: directory
+ loop: '{{ nfs_exports }}'
+ loop_control:
+ label: '{{ item.dataset }}'
+
+- name: set directory ACLs for exports
+ acl:
+ path: '{{ zfs_mountpoints[item.0.dataset] }}'
+ default: '{{ item.1.default | default(omit) }}'
+ entity: '{{ item.1.entity }}'
+ etype: '{{ item.1.etype }}'
+ permissions: '{{ item.1.permissions }}'
+ recalculate_mask: mask
+ state: present
+ loop: "{{ nfs_exports | selectattr('acl', 'defined') | subelements('acl') }}"
+ loop_control:
+ label: '{{ item.0.dataset }}: {{ item.1 }}'
+
+- name: for exports with a "default" ACL, ensure the ACL is set on the directory itself
+ acl:
+ path: '{{ zfs_mountpoints[item.0.dataset] }}'
+ default: no
+ entity: '{{ item.1.entity }}'
+ etype: '{{ item.1.etype }}'
+ permissions: '{{ item.1.permissions }}'
+ recalculate_mask: mask
+ state: present
+ loop: "{{ nfs_exports | selectattr('acl', 'defined') | subelements('acl') | selectattr('1.default', 'defined') | selectattr('1.default', 'equalto', True) }}"
+ loop_control:
+ label: '{{ item.0.dataset }}: {{ item.1 }}'
diff --git a/roles/nfs_server/tasks/homedirs.yml b/roles/nfs_server/tasks/homedirs.yml
new file mode 100644
index 0000000..0241a6e
--- /dev/null
+++ b/roles/nfs_server/tasks/homedirs.yml
@@ -0,0 +1,112 @@
+- name: create parent zfs datasets for home directories
+ zfs:
+ name: '{{ item }}'
+ state: present
+ loop:
+ - '{{ nfs_homedir_user_dataset }}'
+ - '{{ nfs_homedir_group_dataset }}'
+
+- name: collect zfs mountpoints
+ shell: "zfs list -Hp -o name,mountpoint | sed 's/\t/: /'"
+ changed_when: false
+ register: zfs_list_mountpoints
+
+- name: set zfs_mountpoints fact
+ set_fact:
+ zfs_mountpoints: '{{ zfs_list_mountpoints.stdout | from_yaml }}'
+
+- name: set selinux context for home directories
+ sefcontext:
+ target: '{{ item }}'
+ setype: samba_share_t
+ state: present
+ loop:
+ - '{{ zfs_mountpoints[nfs_homedir_group_dataset] }}(/.*)?'
+ - '{{ zfs_mountpoints[nfs_homedir_user_dataset] }}(/.*)?'
+ register: nfs_homedir_sefcontext
+
+- name: apply selinux context to home directories
+ command: 'restorecon -R {{ zfs_mountpoints[nfs_homedir_group_dataset] }} {{ zfs_mountpoints[nfs_homedir_user_dataset] }}'
+ when: nfs_homedir_sefcontext.changed
+
+- name: check which home directories already exist
+ stat:
+ path: '{{ zfs_mountpoints[nfs_homedir_group_dataset if item.group is defined else nfs_homedir_user_dataset] }}/{{ item.group if item.group is defined else item.user }}/priv'
+ loop: '{{ nfs_homedirs }}'
+ register: nfs_homedir_stat
+
+- name: create zfs datasets for public home directories
+ zfs:
+ name: '{{ nfs_homedir_group_dataset if item.group is defined else nfs_homedir_user_dataset }}/{{ item.group if item.group is defined else item.user }}/pub'
+ state: present
+ extra_zfs_properties:
+ refquota: '{{ item.pub_quota | default(nfs_homedir_pub_quota) }}'
+ loop: '{{ nfs_homedirs }}'
+ loop_control:
+ label: '{{ item }}'
+
+- name: create zfs datasets for private home directories
+ zfs:
+ name: '{{ nfs_homedir_group_dataset if item.group is defined else nfs_homedir_user_dataset }}/{{ item.group if item.group is defined else item.user }}/priv'
+ state: present
+ extra_zfs_properties:
+ refquota: '{{ item.priv_quota | default(nfs_homedir_priv_quota) }}'
+ loop: '{{ nfs_homedirs }}'
+ loop_control:
+ label: '{{ item }}'
+
+- name: copy skel files into any newly-created home directories
+ copy:
+ src: /etc/skel/
+ dest: '{{ zfs_mountpoints[nfs_homedir_user_dataset] }}/{{ item.user }}/priv'
+ remote_src: yes
+ owner: '{{ item.user }}'
+ group: '{{ item.user }}'
+ mode: preserve
+ when:
+ - item.user is defined
+ - not nfs_homedir_stat.results[index].stat.exists
+ loop: '{{ nfs_homedirs }}'
+ loop_control:
+ index_var: index
+
+- name: set directory permissions for user home directories
+ file:
+ path: "{{ zfs_mountpoints[nfs_homedir_user_dataset] }}/{{ item.0 }}/{{ item.1.name }}"
+ state: directory
+ owner: '{{ item.0 }}'
+ group: '{{ item.0 }}'
+ mode: '{{ item.1.mode }}'
+ setype: _default
+ loop: "{{ nfs_homedirs | selectattr('user', 'defined') | map(attribute='user') | product(subdirs) }}"
+ vars:
+ subdirs:
+ - { name: pub, mode: '755' }
+ - { name: priv, mode: '700' }
+
+- name: set directory permissions for group directories
+ file:
+ path: "{{ zfs_mountpoints[nfs_homedir_group_dataset] }}/{{ item.0 }}/{{ item.1.name }}"
+ state: directory
+ owner: root
+ group: '{{ item.0 }}'
+ mode: '{{ item.1.mode }}'
+ setype: _default
+ loop: "{{ nfs_homedirs | selectattr('group', 'defined') | map(attribute='group') | product(subdirs) }}"
+ vars:
+ subdirs:
+ - { name: pub, mode: '02775' }
+ - { name: priv, mode: '02770' }
+
+- name: set directory ACLs for group directories
+ acl:
+ path: '{{ zfs_mountpoints[nfs_homedir_group_dataset] }}/{{ item.0 }}/{{ item.1 }}'
+ default: yes
+ entity: '{{ item.0 }}'
+ etype: group
+ permissions: rwX
+ recalculate_mask: mask
+ state: present
+ loop: "{{ nfs_homedirs | selectattr('group', 'defined') | map(attribute='group') | product(['pub', 'priv']) }}"
+ loop_control:
+ label: '{{ item.0 }}: {{ item.1 }}'
diff --git a/roles/nfs_server/tasks/main.yml b/roles/nfs_server/tasks/main.yml
new file mode 100644
index 0000000..56e7099
--- /dev/null
+++ b/roles/nfs_server/tasks/main.yml
@@ -0,0 +1,19 @@
+- name: install packages
+ dnf:
+ name: '{{ nfs_packages }}'
+ state: present
+
+- name: create zfs filesystems for exports
+ import_tasks: exports.yml
+
+- name: create zfs filesystems for home directories
+ import_tasks: homedirs.yml
+
+- name: configure nfs shares
+ import_tasks: nfs.yml
+
+- name: configure smb shares
+ import_tasks: smb.yml
+
+- name: generate autofs maps
+ import_tasks: autofs.yml
diff --git a/roles/nfs_server/tasks/nfs.yml b/roles/nfs_server/tasks/nfs.yml
new file mode 100644
index 0000000..b32e48f
--- /dev/null
+++ b/roles/nfs_server/tasks/nfs.yml
@@ -0,0 +1,41 @@
+- name: create nfs service
+ ipaservice:
+ ipaadmin_principal: '{{ ipa_user }}'
+ ipaadmin_password: '{{ ipa_pass }}'
+ name: 'nfs/{{ ansible_fqdn }}'
+ state: present
+
+- name: retrieve nfs service keytab
+ include_role:
+ name: freeipa_keytab
+ vars:
+ keytab_principal: 'nfs/{{ ansible_fqdn }}'
+
+- name: generate nfs.conf
+ template:
+ src: etc/nfs.conf.j2
+ dest: /etc/nfs.conf
+ notify: restart nfs-server
+
+- name: generate export list
+ template:
+ src: etc/exports.j2
+ dest: /etc/exports
+ notify: reload nfs-server
+
+- name: start nfs server
+ systemd:
+ name: nfs-server
+ state: started
+ enabled: yes
+
+- name: open firewall ports
+ firewalld:
+ service: '{{ item }}'
+ permanent: yes
+ immediate: yes
+ state: enabled
+ loop:
+ - nfs
+ - rpc-bind
+ - mountd
diff --git a/roles/nfs_server/tasks/smb.yml b/roles/nfs_server/tasks/smb.yml
new file mode 100644
index 0000000..ee050d0
--- /dev/null
+++ b/roles/nfs_server/tasks/smb.yml
@@ -0,0 +1,54 @@
+- name: configure samba domain member
+ command:
+ cmd: ipa-client-samba --no-homes --unattended
+ creates: /etc/samba/samba.keytab
+
+- name: add include statement to smb.conf
+ lineinfile:
+ path: /etc/samba/smb.conf
+ line: include = /etc/samba/local.conf
+ insertafter: EOF
+ notify: restart samba
+
+- name: copy samba configuration
+ copy:
+ src: etc/samba/local.conf
+ dest: /etc/samba/local.conf
+ notify: restart samba
+
+- name: create samba shares
+ template:
+ src: etc/samba/shares.conf.j2
+ dest: /etc/samba/shares.conf
+ notify: reload samba
+
+- name: set selinux context for samba shares
+ sefcontext:
+ target: '{{ zfs_mountpoints[item.dataset] if item.dataset is defined else item.path }}(/.*)?'
+ setype: samba_share_t
+ state: present
+ loop: "{{ (nfs_exports | selectattr('smb_share', 'defined')) + smb_shares }}"
+ register: nfs_export_sefcontext
+
+- name: apply selinux context to samba shares
+ command: 'restorecon -R {{ zfs_mountpoints[item.dataset] if item.dataset is defined else item.path }}'
+ when: nfs_export_sefcontext.results[index].changed
+ loop: "{{ (nfs_exports | selectattr('smb_share', 'defined')) + smb_shares }}"
+ loop_control:
+ index_var: index
+
+- name: start samba services
+ systemd:
+ name: '{{ item }}'
+ enabled: yes
+ state: started
+ loop:
+ - smb
+ - winbind
+
+- name: open firewall ports
+ firewalld:
+ service: samba
+ permanent: yes
+ immediate: yes
+ state: enabled