2019-03-08 07:46:28 -06:00
|
|
|
#
|
|
|
|
# Copyright (C) 2018 FreeIPA Contributors see COPYING for license
|
|
|
|
#
|
|
|
|
|
|
|
|
"""This module provides tests for NFS-related features like
|
|
|
|
krb5 NFS and automount locations.
|
|
|
|
|
|
|
|
Wishlist
|
|
|
|
* add automount direct and indirect maps
|
|
|
|
* add automount /home for the "seattle" location only
|
|
|
|
* validate it is not available in another location
|
2019-05-03 05:24:23 -05:00
|
|
|
* krb5 /home for IdM users in test_automount
|
2019-03-08 07:46:28 -06:00
|
|
|
* store nfs configuration in a single place
|
|
|
|
"""
|
|
|
|
|
|
|
|
from __future__ import absolute_import
|
|
|
|
|
|
|
|
import time
|
|
|
|
import re
|
|
|
|
|
|
|
|
from ipatests.test_integration.base import IntegrationTest
|
|
|
|
from ipatests.pytest_ipa.integration import tasks
|
|
|
|
from ipaplatform.paths import paths
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
|
|
|
# give some time for units to stabilize
|
|
|
|
# otherwise we get transient errors
|
|
|
|
WAIT_AFTER_INSTALL = 5
|
|
|
|
WAIT_AFTER_UNINSTALL = WAIT_AFTER_INSTALL
|
|
|
|
|
|
|
|
|
|
|
|
class TestInit(IntegrationTest):
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def fix_resolv_conf(cls, client, server):
|
|
|
|
|
|
|
|
contents = client.get_file_contents(paths.RESOLV_CONF,
|
|
|
|
encoding='utf-8')
|
|
|
|
nameserver = 'nameserver %s\n' % server.ip
|
|
|
|
if not contents.startswith(nameserver):
|
|
|
|
contents = nameserver + contents.replace(nameserver, '')
|
|
|
|
client.run_command([
|
|
|
|
'/usr/bin/cp', paths.RESOLV_CONF,
|
|
|
|
'%s.sav' % paths.RESOLV_CONF
|
|
|
|
])
|
|
|
|
client.put_file_contents(paths.RESOLV_CONF, contents)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def restore_resolv_conf(cls, client):
|
|
|
|
client.run_command([
|
|
|
|
'/usr/bin/cp',
|
|
|
|
'%s.sav' % paths.RESOLV_CONF,
|
|
|
|
paths.RESOLV_CONF
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
class TestNFS(TestInit):
|
|
|
|
|
|
|
|
num_replicas = 2
|
|
|
|
num_clients = 1
|
|
|
|
topology = 'star'
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def install(cls, mh):
|
|
|
|
|
|
|
|
tasks.install_master(cls.master, setup_dns=True)
|
|
|
|
clients = (cls.clients[0], cls.replicas[0], cls.replicas[1])
|
|
|
|
for client in clients:
|
|
|
|
cls.fix_resolv_conf(client, cls.master)
|
|
|
|
tasks.install_client(cls.master, client)
|
|
|
|
client.run_command(["cat", "/etc/resolv.conf"])
|
|
|
|
|
|
|
|
def cleanup(self):
|
|
|
|
|
|
|
|
nfssrv = self.clients[0]
|
|
|
|
nfsclt = self.replicas[0]
|
|
|
|
automntclt = self.replicas[1]
|
|
|
|
|
|
|
|
nfsclt.run_command(["umount", "-a", "-t", "nfs4"])
|
|
|
|
nfsclt.run_command(["systemctl", "stop", "rpc-gssd"])
|
|
|
|
|
|
|
|
nfssrv.run_command(["systemctl", "stop", "nfs-server"])
|
|
|
|
nfssrv.run_command(["systemctl", "disable", "nfs-server"])
|
|
|
|
nfssrv.run_command([
|
|
|
|
"rm", "-f", "/etc/exports.d/krbnfs.exports",
|
|
|
|
"/etc/exports.d/stdnfs.exports"
|
|
|
|
])
|
|
|
|
|
|
|
|
nfssrv.run_command(["rm", "-rf", "/exports"])
|
|
|
|
|
|
|
|
tasks.uninstall_client(nfsclt)
|
|
|
|
tasks.uninstall_client(nfssrv)
|
|
|
|
self.master.run_command([
|
|
|
|
"ipa", "host-mod", automntclt.hostname,
|
|
|
|
"--location", "''"
|
|
|
|
])
|
|
|
|
# not strictly necessary, but this exercises automountlocation-del
|
|
|
|
self.master.run_command([
|
|
|
|
"ipa", "automountlocation-del", "seattle"
|
|
|
|
])
|
|
|
|
nfsclt.run_command(["systemctl", "restart", "nfs-utils"])
|
|
|
|
nfssrv.run_command(["systemctl", "restart", "nfs-utils"])
|
|
|
|
for client in (nfssrv, nfsclt, automntclt):
|
|
|
|
self.restore_resolv_conf(client)
|
|
|
|
tasks.uninstall_master(self.master)
|
|
|
|
|
|
|
|
def test_prepare_users(self):
|
|
|
|
|
|
|
|
users = {
|
|
|
|
"athena": "p",
|
|
|
|
"euripides": "s"
|
|
|
|
}
|
|
|
|
temp_pass = 'temppass'
|
|
|
|
for user in users:
|
|
|
|
self.master.run_command([
|
|
|
|
"ipa", "user-add",
|
|
|
|
"%s" % user, "--first", "%s" % user,
|
|
|
|
"--last", "%s" % users[user],
|
2019-06-14 08:11:41 -05:00
|
|
|
'--password'], stdin_text="%s\n%s\n" % (temp_pass, temp_pass)
|
2019-03-08 07:46:28 -06:00
|
|
|
)
|
|
|
|
self.master.run_command(["kdestroy", "-A"])
|
|
|
|
password = "Secret123"
|
|
|
|
user_kinit = "%s\n%s\n%s\n" % (temp_pass, password, password)
|
|
|
|
self.master.run_command(
|
|
|
|
['kinit', user], stdin_text=user_kinit
|
|
|
|
)
|
|
|
|
self.master.run_command(["kdestroy", "-A"])
|
|
|
|
tasks.kinit_admin(self.master)
|
|
|
|
|
|
|
|
def test_krb5_nfsd(self):
|
|
|
|
|
|
|
|
nfssrv = self.clients[0]
|
|
|
|
|
|
|
|
# NFS keytab management
|
|
|
|
self.master.run_command([
|
|
|
|
"ipa", "service-add", "nfs/%s" % nfssrv.hostname
|
|
|
|
])
|
|
|
|
nfssrv.run_command([
|
|
|
|
"ipa-getkeytab", "-p", "nfs/%s" % nfssrv.hostname,
|
|
|
|
"-k", "/etc/krb5.keytab"
|
|
|
|
])
|
|
|
|
nfssrv.run_command(["systemctl", "restart", "nfs-server"])
|
|
|
|
nfssrv.run_command(["systemctl", "enable", "nfs-server"])
|
|
|
|
time.sleep(WAIT_AFTER_INSTALL)
|
|
|
|
|
|
|
|
basedir = "exports"
|
|
|
|
exports = {
|
|
|
|
"krbnfs": "*(sec=krb5p,rw)",
|
|
|
|
"stdnfs": "*(ro)",
|
|
|
|
"home": "*(sec=krb5p,rw)"
|
|
|
|
}
|
|
|
|
for export in exports:
|
|
|
|
exportpath = os.sep.join(('', basedir, export))
|
|
|
|
exportfile = os.sep.join((
|
|
|
|
'', 'etc', 'exports.d', "%s.exports" % export
|
|
|
|
))
|
|
|
|
exportline = " ".join((exportpath, exports[export]))
|
|
|
|
nfssrv.run_command(["mkdir", "-p", exportpath])
|
|
|
|
nfssrv.run_command(["chmod", "770", exportpath])
|
|
|
|
nfssrv.put_file_contents(exportfile, exportline)
|
|
|
|
nfssrv.run_command(["cat", exportfile])
|
|
|
|
nfssrv.run_command(["exportfs", "-r"])
|
|
|
|
nfssrv.run_command(["exportfs", "-s"])
|
|
|
|
|
|
|
|
def test_krb5_nfs_manual_configuration(self):
|
|
|
|
|
|
|
|
nfssrv = self.clients[0]
|
|
|
|
nfsclt = self.replicas[0]
|
|
|
|
|
|
|
|
nfsclt.run_command(["systemctl", "restart", "rpc-gssd"])
|
|
|
|
time.sleep(WAIT_AFTER_INSTALL)
|
|
|
|
mountpoints = ("/mnt/krb", "/mnt/std", "/home")
|
|
|
|
for mountpoint in mountpoints:
|
|
|
|
nfsclt.run_command(["mkdir", "-p", mountpoint])
|
|
|
|
nfsclt.run_command([
|
|
|
|
"systemctl", "status", "gssproxy"
|
|
|
|
])
|
|
|
|
nfsclt.run_command([
|
|
|
|
"systemctl", "status", "rpc-gssd"
|
|
|
|
])
|
|
|
|
nfsclt.run_command([
|
|
|
|
"mount", "-t", "nfs4", "-o", "sec=krb5p,vers=4.0",
|
|
|
|
"%s:/exports/krbnfs" % nfssrv.hostname, "/mnt/krb", "-v"
|
|
|
|
])
|
|
|
|
nfsclt.run_command([
|
|
|
|
"mount", "-t", "nfs4", "-o", "sec=krb5p,vers=4.0",
|
|
|
|
"%s:/exports/home" % nfssrv.hostname, "/home", "-v"
|
|
|
|
])
|
|
|
|
|
2019-05-03 05:24:23 -05:00
|
|
|
def test_automount(self):
|
2019-03-08 07:46:28 -06:00
|
|
|
"""
|
|
|
|
Test if ipa-client-automount behaves as expected
|
|
|
|
"""
|
|
|
|
|
|
|
|
nfssrv = self.clients[0]
|
|
|
|
automntclt = self.replicas[1]
|
|
|
|
|
|
|
|
self.master.run_command([
|
|
|
|
"ipa", "automountlocation-add", "seattle"
|
|
|
|
])
|
|
|
|
self.master.run_command([
|
|
|
|
"ipa", "automountmap-add", "seattle", "auto.home"
|
|
|
|
])
|
|
|
|
self.master.run_command([
|
|
|
|
"ipa", "automountkey-add", "seattle", "auto.home",
|
|
|
|
"--key='*'", "--info=sec=krb5p,vers=4"
|
|
|
|
" 'rhel8-nfsserver0.laptop.example.org:/export/home/&'"
|
|
|
|
])
|
|
|
|
self.master.run_command([
|
|
|
|
"ipa", "automountkey-add", "seattle", "auto.master",
|
|
|
|
"--key=/home", "--info=auto.home"
|
|
|
|
])
|
|
|
|
|
|
|
|
self.master.run_command([
|
|
|
|
"ipa", "host-mod", automntclt.hostname,
|
|
|
|
"--location", "seattle"
|
|
|
|
])
|
|
|
|
|
|
|
|
# systemctl non-fatal errors will only be displayed
|
|
|
|
# if ipa-client-automount is launched with --debug
|
|
|
|
result1 = automntclt.run_command([
|
|
|
|
'ipa-client-automount', '--location', 'seattle',
|
|
|
|
'-U', '--debug'
|
|
|
|
])
|
|
|
|
|
2019-06-25 09:24:15 -05:00
|
|
|
time.sleep(WAIT_AFTER_INSTALL)
|
|
|
|
|
2019-03-08 07:46:28 -06:00
|
|
|
# systemctl non-fatal errors will show up like this:
|
|
|
|
# stderr=Failed to restart nfs-secure.service: \
|
|
|
|
# Unit nfs-secure.service not found.
|
|
|
|
# normal output:
|
|
|
|
# stderr=
|
|
|
|
m1 = re.search(r'(?<=stderr\=Failed).+', result1.stderr_text)
|
|
|
|
# maybe re-use m1.group(0) if it exists.
|
|
|
|
assert m1 is None
|
|
|
|
|
2019-05-03 05:24:23 -05:00
|
|
|
# https://pagure.io/freeipa/issue/7918
|
|
|
|
# check whether idmapd.conf was setup using the IPA domain
|
|
|
|
automntclt.run_command([
|
|
|
|
"grep", "Domain = %s" % self.master.domain.name, "/etc/idmapd.conf"
|
|
|
|
])
|
|
|
|
|
2019-03-08 07:46:28 -06:00
|
|
|
automntclt.run_command([
|
|
|
|
"mount", "-t", "nfs4", "-o", "sec=krb5p,vers=4.0",
|
|
|
|
"%s:/exports/home" % nfssrv.hostname, "/home", "-v"
|
|
|
|
])
|
|
|
|
|
2019-05-03 05:24:23 -05:00
|
|
|
# TODO leverage users
|
|
|
|
|
2019-03-08 07:46:28 -06:00
|
|
|
automntclt.run_command(["umount", "-a", "-t", "nfs4"])
|
|
|
|
|
|
|
|
result2 = automntclt.run_command([
|
2019-05-03 05:24:23 -05:00
|
|
|
'ipa-client-automount', '--uninstall', '-U', '--debug'
|
2019-03-08 07:46:28 -06:00
|
|
|
])
|
|
|
|
m2 = re.search(r'(?<=stderr\=Failed).+', result2.stderr_text)
|
|
|
|
assert m2 is None
|
|
|
|
|
|
|
|
time.sleep(WAIT_AFTER_UNINSTALL)
|
2019-05-03 05:24:23 -05:00
|
|
|
|
|
|
|
# https://pagure.io/freeipa/issue/7918
|
|
|
|
# test for --idmap-domain DNS
|
|
|
|
automntclt.run_command([
|
|
|
|
'ipa-client-automount', '--location', 'default',
|
|
|
|
'-U', '--debug', "--idmap-domain", "DNS"
|
|
|
|
])
|
2019-06-25 09:24:15 -05:00
|
|
|
|
|
|
|
time.sleep(WAIT_AFTER_INSTALL)
|
|
|
|
|
2019-05-03 05:24:23 -05:00
|
|
|
# check whether idmapd.conf was setup properly:
|
|
|
|
# grep must not find any configured Domain.
|
|
|
|
result = automntclt.run_command(
|
|
|
|
["grep", "^Domain =", "/etc/idmapd.conf"], raiseonerr=False
|
|
|
|
)
|
|
|
|
assert result.returncode == 1
|
|
|
|
|
|
|
|
automntclt.run_command([
|
|
|
|
'ipa-client-automount', '--uninstall', '-U', '--debug'
|
|
|
|
])
|
|
|
|
|
2019-06-25 09:24:15 -05:00
|
|
|
time.sleep(WAIT_AFTER_UNINSTALL)
|
|
|
|
|
2019-05-03 05:24:23 -05:00
|
|
|
# https://pagure.io/freeipa/issue/7918
|
|
|
|
# test for --idmap-domain exampledomain.net
|
|
|
|
nfs_domain = "exampledomain.net"
|
|
|
|
automntclt.run_command([
|
|
|
|
'ipa-client-automount', '--location', 'default',
|
|
|
|
'-U', '--debug', "--idmap-domain", nfs_domain
|
|
|
|
])
|
|
|
|
# check whether idmapd.conf was setup using nfs_domain
|
|
|
|
automntclt.run_command([
|
|
|
|
"grep", "Domain = %s" % nfs_domain, "/etc/idmapd.conf"
|
|
|
|
])
|
|
|
|
|
2019-06-25 09:24:15 -05:00
|
|
|
time.sleep(WAIT_AFTER_INSTALL)
|
|
|
|
|
2019-05-03 05:24:23 -05:00
|
|
|
automntclt.run_command([
|
|
|
|
'ipa-client-automount', '--uninstall', '-U', '--debug'
|
|
|
|
])
|
2019-06-25 09:24:15 -05:00
|
|
|
|
|
|
|
time.sleep(WAIT_AFTER_UNINSTALL)
|
|
|
|
|
2019-03-08 07:46:28 -06:00
|
|
|
self.cleanup()
|