From aa91c1345291807d5b80ba5bf5533b4f36378b53 Mon Sep 17 00:00:00 2001 From: Victor Holanda Date: Fri, 21 Jul 2023 14:04:43 +0200 Subject: [PATCH 1/3] Add host_keys_check test This test checks the ssh host keys age. The list of host keys and the maximum age allowed are parameters and variables of the test. If the key file is not found, the test is skipped --- hpctestlib/system/ssh/host_keys.py | 66 ++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 hpctestlib/system/ssh/host_keys.py diff --git a/hpctestlib/system/ssh/host_keys.py b/hpctestlib/system/ssh/host_keys.py new file mode 100644 index 0000000000..eabb470b03 --- /dev/null +++ b/hpctestlib/system/ssh/host_keys.py @@ -0,0 +1,66 @@ +# Copyright 2016-2022 Swiss National Supercomputing Centre (CSCS/ETH Zurich) +# ReFrame Project Developers. See the top-level LICENSE file for details. +# +# SPDX-License-Identifier: BSD-3-Clause + +import time + +from datetime import timedelta + +import reframe as rfm +import reframe.utility.sanity as sn +import reframe.utility.typecheck as typ + + +@rfm.simple_test +class host_keys_check(rfm.RunOnlyRegressionTest): + '''host keys age check + + The host keys should be renewed regularly. + In this case, we are checking against the + max_key_age variable + ''' + + #: Parameter list with all host keys to check + #: + #: The test skips if a key is not found + #: + #: :type: :class:`str` + #: :values: ``['/etc/ssh/ssh_host_rsa_key', + #: '/etc/ssh/ssh_host_ecdsa_key', + #: '/etc/ssh/ssh_host_ed25519_key']`` + host_keys = parameter([ + '/etc/ssh/ssh_host_rsa_key', + '/etc/ssh/ssh_host_ecdsa_key', + '/etc/ssh/ssh_host_ed25519_key', + ], fmt=lambda x: x.split('_')[2], loggable=True) + + #: The max age of the keys in ReFrame duration format + #: + #: :type: :class:`str` + #: :default: ``'365d'`` + max_key_age = variable(str, value='365d', loggable=True) + + executable = 'stat' + executable_opts = ['-c', '%Y'] + tags = {'system', 'ssh'} + + @run_after('init') + def set_hosts_keys(self): + self.executable_opts += [self.host_keys] + + @sanity_function + def assert_file_age(self): + current_time = time.time() + + skip_me = sn.extractall('No such file or directory', self.stderr) + self.skip_if(skip_me, msg=f'Skipping test because {self.host_keys}' + f' was not found') + + return sn.all([ + sn.assert_lt(current_time - + sn.extractsingle(r'\d+', self.stdout, 0, int), + typ.Duration(self.max_key_age), + msg=f'File {self.host_keys} is older than ' + f'{self.max_key_age}') + ]) From 0398eaa0ebd5ef9d84892c0ed9962e3e789f2ff5 Mon Sep 17 00:00:00 2001 From: Victor Holanda Date: Fri, 21 Jul 2023 14:08:00 +0200 Subject: [PATCH 2/3] Remove unused import --- hpctestlib/system/ssh/host_keys.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/hpctestlib/system/ssh/host_keys.py b/hpctestlib/system/ssh/host_keys.py index eabb470b03..46f2e9b812 100644 --- a/hpctestlib/system/ssh/host_keys.py +++ b/hpctestlib/system/ssh/host_keys.py @@ -5,8 +5,6 @@ import time -from datetime import timedelta - import reframe as rfm import reframe.utility.sanity as sn import reframe.utility.typecheck as typ From 7e674efb7d86d360791f69bc1e7c5abaf5c74407 Mon Sep 17 00:00:00 2001 From: Victor Holanda Date: Tue, 25 Jul 2023 14:22:53 +0200 Subject: [PATCH 3/3] Address PR remarks --- hpctestlib/system/ssh/host_keys.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/hpctestlib/system/ssh/host_keys.py b/hpctestlib/system/ssh/host_keys.py index 46f2e9b812..642e054731 100644 --- a/hpctestlib/system/ssh/host_keys.py +++ b/hpctestlib/system/ssh/host_keys.py @@ -1,4 +1,4 @@ -# Copyright 2016-2022 Swiss National Supercomputing Centre (CSCS/ETH Zurich) +# Copyright 2016-2023 Swiss National Supercomputing Centre (CSCS/ETH Zurich) # ReFrame Project Developers. See the top-level LICENSE file for details. # # SPDX-License-Identifier: BSD-3-Clause @@ -11,23 +11,23 @@ @rfm.simple_test -class host_keys_check(rfm.RunOnlyRegressionTest): - '''host keys age check +class ssh_host_keys_check(rfm.RunOnlyRegressionTest): + '''SSH host keys age check - The host keys should be renewed regularly. + The ssh host keys should be renewed regularly. In this case, we are checking against the max_key_age variable ''' #: Parameter list with all host keys to check #: - #: The test skips if a key is not found + #: The test is skipped if a key is not found #: #: :type: :class:`str` #: :values: ``['/etc/ssh/ssh_host_rsa_key', #: '/etc/ssh/ssh_host_ecdsa_key', #: '/etc/ssh/ssh_host_ed25519_key']`` - host_keys = parameter([ + ssh_host_keys = parameter([ '/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_ecdsa_key', '/etc/ssh/ssh_host_ed25519_key', @@ -55,10 +55,8 @@ def assert_file_age(self): self.skip_if(skip_me, msg=f'Skipping test because {self.host_keys}' f' was not found') - return sn.all([ - sn.assert_lt(current_time - + return sn.assert_lt(current_time - sn.extractsingle(r'\d+', self.stdout, 0, int), typ.Duration(self.max_key_age), msg=f'File {self.host_keys} is older than ' f'{self.max_key_age}') - ])