Add support to exclude finger prints of certs
Currently while removing the CA certificates from the iLO, when certificate file list is empty, all the CA certificates from the iLO are removed. In some cases certain certificates are required to be retained on the iLO. This patch fixes the issue by accepting the list of certificates to be retained on the iLO. Change-Id: I4898361527e5785e181cffaf294557db0078c93d
This commit is contained in:
parent
2be2d0e18d
commit
06b4eed744
|
@ -913,7 +913,8 @@ class IloClient(operations.IloOperations):
|
||||||
"""
|
"""
|
||||||
return self._call_method('add_tls_certificate', cert_file_list)
|
return self._call_method('add_tls_certificate', cert_file_list)
|
||||||
|
|
||||||
def remove_tls_certificate(self, cert_file_list=[]):
|
def remove_tls_certificate(self, cert_file_list=[],
|
||||||
|
excl_cert_file_list=[]):
|
||||||
"""Removes the TLS certificate from the iLO
|
"""Removes the TLS certificate from the iLO
|
||||||
|
|
||||||
:param cert_file_list: List of TLS certificate files
|
:param cert_file_list: List of TLS certificate files
|
||||||
|
|
|
@ -558,7 +558,8 @@ class IloOperations(object):
|
||||||
"""
|
"""
|
||||||
raise exception.IloCommandNotSupportedError(ERRMSG)
|
raise exception.IloCommandNotSupportedError(ERRMSG)
|
||||||
|
|
||||||
def remove_tls_certificate(self, cert_file_list=[]):
|
def remove_tls_certificate(self, cert_file_list=[],
|
||||||
|
excl_cert_file_list=[]):
|
||||||
"""Removes the TLS certificate from the iLO
|
"""Removes the TLS certificate from the iLO
|
||||||
|
|
||||||
:param cert_file_list: List of TLS certificate files
|
:param cert_file_list: List of TLS certificate files
|
||||||
|
|
|
@ -1692,10 +1692,55 @@ class RedfishOperations(operations.IloOperations):
|
||||||
msg = 'TLS certificate cannot be upload in BIOS boot mode'
|
msg = 'TLS certificate cannot be upload in BIOS boot mode'
|
||||||
raise exception.IloCommandNotSupportedInBiosError(msg)
|
raise exception.IloCommandNotSupportedInBiosError(msg)
|
||||||
|
|
||||||
def remove_tls_certificate(self, cert_file_list=[]):
|
def _get_fps_from_file(self, cert_file):
|
||||||
"""Removes the TLS certificate from the iLO.
|
"""Gets the finger prints from the certificate file.
|
||||||
|
|
||||||
:param cert_file_list: List of TLS certificate files
|
Parse the file passed in to get the certificates. For each certificate,
|
||||||
|
find the fingerprint by calculating the digest of base64 decoded
|
||||||
|
content. Finally return the list of the fingerprints.
|
||||||
|
|
||||||
|
:param cert_file: TLS certificate file containing one or more
|
||||||
|
certificates.
|
||||||
|
|
||||||
|
:return: Returns the list of FPs for the certificates in the file.
|
||||||
|
"""
|
||||||
|
fp_list = []
|
||||||
|
with open(cert_file, 'r') as f:
|
||||||
|
data = json.dumps(f.read())
|
||||||
|
p = re.sub(r"\"", "", data)
|
||||||
|
q = re.sub(r"\\n", "\r\n", p).rstrip()
|
||||||
|
|
||||||
|
c_list = re.findall(_CERTIFICATE_PATTERN, q, re.DOTALL)
|
||||||
|
|
||||||
|
if len(c_list) == 0:
|
||||||
|
LOG.warning("Could not find any valid certificate in "
|
||||||
|
"%(cert_file)s. Ignoring." %
|
||||||
|
{"cert_file": cert_file})
|
||||||
|
return fp_list
|
||||||
|
|
||||||
|
for content in c_list:
|
||||||
|
pem_lines = [line.strip() for line in (
|
||||||
|
content.strip().split('\n'))]
|
||||||
|
|
||||||
|
try:
|
||||||
|
der_data = b64decode(''.join(pem_lines[1:-1]))
|
||||||
|
except ValueError:
|
||||||
|
LOG.warning("Illegal base64 encountered "
|
||||||
|
"in the certificate.")
|
||||||
|
else:
|
||||||
|
cert = load_certificate(FILETYPE_ASN1, der_data)
|
||||||
|
fp = cert.digest('sha256').decode('ascii')
|
||||||
|
fp_list.append(fp)
|
||||||
|
return fp_list
|
||||||
|
|
||||||
|
def remove_tls_certificate(self, cert_file_list=[],
|
||||||
|
excl_cert_file_list=[]):
|
||||||
|
"""Removes the TLS CA certificates from the iLO.
|
||||||
|
|
||||||
|
:param cert_file_list: List of TLS CA certificate files
|
||||||
|
:param excl_cert_file_list: List of TLS CA certificate files to be
|
||||||
|
retained on the iLO. These certificates will not be
|
||||||
|
removed from the iLO.
|
||||||
|
|
||||||
:raises: IloError, on an error from iLO.
|
:raises: IloError, on an error from iLO.
|
||||||
:raises: IloCommandNotSupportedError, if the command is
|
:raises: IloCommandNotSupportedError, if the command is
|
||||||
|
@ -1709,49 +1754,42 @@ class RedfishOperations(operations.IloOperations):
|
||||||
|
|
||||||
cert_dict = {}
|
cert_dict = {}
|
||||||
del_cert_list = []
|
del_cert_list = []
|
||||||
|
exc_fp_list = []
|
||||||
|
|
||||||
|
for exc_cert_file in excl_cert_file_list:
|
||||||
|
efp_list = self._get_fps_from_file(exc_cert_file)
|
||||||
|
exc_fp_list.extend(efp_list)
|
||||||
|
|
||||||
|
LOG.debug("Excluding certificates with FingerPrints: %(exc_fp_list)s",
|
||||||
|
{'exc_fp_list': exc_fp_list})
|
||||||
|
|
||||||
if not cert_file_list:
|
if not cert_file_list:
|
||||||
tls_certificates = (sushy_system.bios_settings.tls_config.
|
tls_certificates = (sushy_system.bios_settings.tls_config.
|
||||||
tls_certificates)
|
tls_certificates)
|
||||||
for cert in tls_certificates:
|
for cert in tls_certificates:
|
||||||
fp = cert.get("FingerPrint")
|
fp = cert.get("FingerPrint")
|
||||||
|
|
||||||
|
if fp not in exc_fp_list:
|
||||||
|
cert_fp = {
|
||||||
|
"FingerPrint": fp
|
||||||
|
}
|
||||||
|
del_cert_list.append(cert_fp)
|
||||||
|
|
||||||
|
else:
|
||||||
|
all_fp_list = []
|
||||||
|
|
||||||
|
for cert_file in cert_file_list:
|
||||||
|
afp_list = self._get_fps_from_file(cert_file)
|
||||||
|
all_fp_list.extend(afp_list)
|
||||||
|
|
||||||
|
final_fp_set = set(all_fp_list) - set(exc_fp_list)
|
||||||
|
|
||||||
|
for fp in final_fp_set:
|
||||||
cert_fp = {
|
cert_fp = {
|
||||||
"FingerPrint": fp
|
"FingerPrint": fp
|
||||||
}
|
}
|
||||||
del_cert_list.append(cert_fp)
|
del_cert_list.append(cert_fp)
|
||||||
|
|
||||||
else:
|
|
||||||
for cert_file in cert_file_list:
|
|
||||||
with open(cert_file, 'r') as f:
|
|
||||||
data = json.dumps(f.read())
|
|
||||||
p = re.sub(r"\"", "", data)
|
|
||||||
q = re.sub(r"\\n", "\r\n", p).rstrip()
|
|
||||||
|
|
||||||
c_list = re.findall(_CERTIFICATE_PATTERN, q, re.DOTALL)
|
|
||||||
|
|
||||||
if len(c_list) == 0:
|
|
||||||
LOG.warning("Could not find any valid certificate in "
|
|
||||||
"%(cert_file)s. Ignoring." %
|
|
||||||
{"cert_file": cert_file})
|
|
||||||
continue
|
|
||||||
|
|
||||||
for content in c_list:
|
|
||||||
pem_lines = [line.strip() for line in (
|
|
||||||
content.strip().split('\n'))]
|
|
||||||
|
|
||||||
try:
|
|
||||||
der_data = b64decode(''.join(pem_lines[1:-1]))
|
|
||||||
except ValueError:
|
|
||||||
LOG.warning("Illegal base64 encountered "
|
|
||||||
"in the certificate.")
|
|
||||||
else:
|
|
||||||
cert = load_certificate(FILETYPE_ASN1, der_data)
|
|
||||||
fp = cert.digest('sha256').decode('ascii')
|
|
||||||
cert_fp = {
|
|
||||||
"FingerPrint": fp
|
|
||||||
}
|
|
||||||
del_cert_list.append(cert_fp)
|
|
||||||
|
|
||||||
if len(del_cert_list) == 0:
|
if len(del_cert_list) == 0:
|
||||||
msg = (self._("No valid certificate in %(cert_file_list)s.") %
|
msg = (self._("No valid certificate in %(cert_file_list)s.") %
|
||||||
{"cert_file_list": cert_file_list})
|
{"cert_file_list": cert_file_list})
|
||||||
|
|
|
@ -43,7 +43,6 @@ from proliantutils.redfish.resources.system.storage import array_controller
|
||||||
from proliantutils.redfish.resources.system.storage \
|
from proliantutils.redfish.resources.system.storage \
|
||||||
import common as common_storage
|
import common as common_storage
|
||||||
from proliantutils.redfish.resources.system import system as pro_sys
|
from proliantutils.redfish.resources.system import system as pro_sys
|
||||||
from proliantutils.redfish.resources.system import tls_config
|
|
||||||
|
|
||||||
|
|
||||||
@ddt.ddt
|
@ddt.ddt
|
||||||
|
@ -2184,27 +2183,15 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
||||||
@mock.patch.object(redfish, 'load_certificate')
|
@mock.patch.object(redfish, 'load_certificate')
|
||||||
@mock.patch.object(redfish, 'b64decode')
|
@mock.patch.object(redfish, 'b64decode')
|
||||||
@mock.patch.object(builtins, 'open')
|
@mock.patch.object(builtins, 'open')
|
||||||
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
def test__get_fps_from_file(self, open_mock, decode_mock, load_cert_mock):
|
||||||
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
|
||||||
def test_remove_tls_certificate(self, get_sushy_system_mock,
|
|
||||||
_uefi_boot_mode_mock, open_mock,
|
|
||||||
decode_mock, load_cert_mock):
|
|
||||||
_uefi_boot_mode_mock.return_value = True
|
|
||||||
decode_mock.side_effect = ['first decoded data',
|
|
||||||
'second decoded data']
|
|
||||||
cert1_mock = mock.MagicMock()
|
|
||||||
cert2_mock = mock.MagicMock()
|
|
||||||
load_cert_mock.side_effect = [cert1_mock, cert2_mock]
|
|
||||||
cert1_mock.digest.return_value.decode.return_value = "humptydumpty"
|
|
||||||
cert2_mock.digest.return_value.decode.return_value = "hickerydickery"
|
|
||||||
|
|
||||||
data = (
|
data = (
|
||||||
"-----BEGIN CERTIFICATE-----\nMIID7TC\nCF"
|
"-----BEGIN CERTIFICATE-----\nMIID7TC\nCF"
|
||||||
"g879\n-----END CERTIFICATE-----\n"
|
"g879\n-----END CERTIFICATE-----\n"
|
||||||
"-----BEGIN CERTIFICATE-----\nKHY8UP\nGH"
|
"-----BEGIN CERTIFICATE-----\nKHY8UP\nGH"
|
||||||
"f792\n-----END CERTIFICATE-----\n"
|
"f792\n-----END CERTIFICATE-----\n"
|
||||||
)
|
)
|
||||||
|
decode_mock.side_effect = ['first decoded data',
|
||||||
|
'second decoded data']
|
||||||
fd_mock = mock.MagicMock(spec=io.BytesIO)
|
fd_mock = mock.MagicMock(spec=io.BytesIO)
|
||||||
open_mock.return_value = fd_mock
|
open_mock.return_value = fd_mock
|
||||||
fd_mock.__enter__.return_value = fd_mock
|
fd_mock.__enter__.return_value = fd_mock
|
||||||
|
@ -2218,97 +2205,155 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
||||||
mock.call(redfish.FILETYPE_ASN1, 'first decoded data'),
|
mock.call(redfish.FILETYPE_ASN1, 'first decoded data'),
|
||||||
mock.call(redfish.FILETYPE_ASN1, 'second decoded data')
|
mock.call(redfish.FILETYPE_ASN1, 'second decoded data')
|
||||||
]
|
]
|
||||||
|
cert1_mock = mock.MagicMock()
|
||||||
|
cert2_mock = mock.MagicMock()
|
||||||
|
load_cert_mock.side_effect = [cert1_mock, cert2_mock]
|
||||||
|
cert1_mock.digest.return_value.decode.return_value = "hickerydickery"
|
||||||
|
cert2_mock.digest.return_value.decode.return_value = "humptydumpty"
|
||||||
cert_file = '/path/to/certfile'
|
cert_file = '/path/to/certfile'
|
||||||
self.rf_client.remove_tls_certificate([cert_file])
|
expected_fp_list = ["hickerydickery", "humptydumpty"]
|
||||||
|
actual_fp_list = self.rf_client._get_fps_from_file(cert_file)
|
||||||
decode_mock.assert_has_calls(decode_calls)
|
decode_mock.assert_has_calls(decode_calls)
|
||||||
load_cert_mock.assert_has_calls(load_cert_calls)
|
load_cert_mock.assert_has_calls(load_cert_calls)
|
||||||
|
self.assertEqual(expected_fp_list, actual_fp_list)
|
||||||
|
|
||||||
expected_data = {
|
@mock.patch.object(redfish.RedfishOperations, '_get_fps_from_file')
|
||||||
"DeleteCertificates": [
|
|
||||||
{
|
|
||||||
"FingerPrint": "humptydumpty",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"FingerPrint": "hickerydickery"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
(get_sushy_system_mock.return_value.
|
|
||||||
bios_settings.tls_config.tls_config_settings.
|
|
||||||
remove_tls_certificate.assert_called_once_with(expected_data))
|
|
||||||
|
|
||||||
@mock.patch.object(redfish, 'load_certificate')
|
|
||||||
@mock.patch.object(redfish, 'b64decode')
|
|
||||||
@mock.patch.object(builtins, 'open')
|
|
||||||
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
||||||
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||||
def test_remove_tls_certificate_no_certificate(self,
|
def test_remove_tls_certificate_default_exclude_list(
|
||||||
get_sushy_system_mock,
|
self, get_sushy_system_mock, _uefi_boot_mode_mock,
|
||||||
_uefi_boot_mode_mock,
|
get_fps_mock):
|
||||||
open_mock, decode_mock,
|
|
||||||
load_cert_mock):
|
|
||||||
|
|
||||||
_uefi_boot_mode_mock.return_value = True
|
_uefi_boot_mode_mock.return_value = True
|
||||||
|
get_fps_calls = [
|
||||||
|
mock.call('/path/to/certfile1'),
|
||||||
|
mock.call('/path/to/certfile2')
|
||||||
|
]
|
||||||
|
get_fps_mock.side_effect = [
|
||||||
|
["AA:BB:CC", "DD:EE:FF"],
|
||||||
|
["XX:YY:ZZ"]
|
||||||
|
]
|
||||||
|
|
||||||
data = (
|
expected = ["AA:BB:CC", "DD:EE:FF", "XX:YY:ZZ"]
|
||||||
"-----UNFORMATED CERTIFICATE-----\nMIID7TC\nCF"
|
|
||||||
"g879\n-----END CERTIFICATE-----\n"
|
|
||||||
"-----UNFORMATED CERTIFICATE-----\nKHY8UP\nGH"
|
|
||||||
"f792\n-----END CERTIFICATE-----\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
fd_mock = mock.MagicMock(spec=io.BytesIO)
|
cert_file_list = ['/path/to/certfile1', '/path/to/certfile2']
|
||||||
open_mock.return_value = fd_mock
|
remove_tls_mock = (get_sushy_system_mock.return_value.
|
||||||
fd_mock.__enter__.return_value = fd_mock
|
bios_settings.tls_config.tls_config_settings.
|
||||||
fd_mock.read.return_value = data
|
remove_tls_certificate)
|
||||||
|
self.rf_client.remove_tls_certificate(cert_file_list)
|
||||||
|
get_fps_mock.assert_has_calls(get_fps_calls)
|
||||||
|
val_delete_certs = remove_tls_mock.call_args[0][0].get(
|
||||||
|
"DeleteCertificates")
|
||||||
|
actual = [item.get("FingerPrint") for item in val_delete_certs]
|
||||||
|
actual.sort()
|
||||||
|
get_fps_mock.assert_has_calls(get_fps_calls)
|
||||||
|
self.assertEqual(expected, actual)
|
||||||
|
|
||||||
cert_file = '/path/to/certfile'
|
@mock.patch.object(redfish.RedfishOperations, '_get_fps_from_file')
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||||
|
def test_remove_tls_certificate_empty_exclude_list(
|
||||||
|
self, get_sushy_system_mock, _uefi_boot_mode_mock,
|
||||||
|
get_fps_mock):
|
||||||
|
_uefi_boot_mode_mock.return_value = True
|
||||||
|
get_fps_calls = [
|
||||||
|
mock.call('/path/to/certfile1'),
|
||||||
|
mock.call('/path/to/certfile2')
|
||||||
|
]
|
||||||
|
get_fps_mock.side_effect = [
|
||||||
|
["AA:BB:CC", "DD:EE:FF"],
|
||||||
|
["XX:YY:ZZ"]
|
||||||
|
]
|
||||||
|
|
||||||
|
expected = ["AA:BB:CC", "DD:EE:FF", "XX:YY:ZZ"]
|
||||||
|
|
||||||
|
cert_file_list = ['/path/to/certfile1', '/path/to/certfile2']
|
||||||
|
excl_cert_file_list = []
|
||||||
|
remove_tls_mock = (get_sushy_system_mock.return_value.
|
||||||
|
bios_settings.tls_config.tls_config_settings.
|
||||||
|
remove_tls_certificate)
|
||||||
|
self.rf_client.remove_tls_certificate(cert_file_list,
|
||||||
|
excl_cert_file_list)
|
||||||
|
val_delete_certs = remove_tls_mock.call_args[0][0].get(
|
||||||
|
"DeleteCertificates")
|
||||||
|
actual = [item.get("FingerPrint") for item in val_delete_certs]
|
||||||
|
actual.sort()
|
||||||
|
get_fps_mock.assert_has_calls(get_fps_calls)
|
||||||
|
self.assertEqual(expected, actual)
|
||||||
|
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_get_fps_from_file')
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||||
|
def test_remove_tls_certificate_valid_exclude_list(
|
||||||
|
self, get_sushy_system_mock, _uefi_boot_mode_mock,
|
||||||
|
get_fps_mock):
|
||||||
|
_uefi_boot_mode_mock.return_value = True
|
||||||
|
get_fps_calls = [
|
||||||
|
mock.call('/path/to/certfile1'),
|
||||||
|
mock.call('/path/to/certfile2')
|
||||||
|
]
|
||||||
|
get_fps_mock.side_effect = [
|
||||||
|
["DD:EE:FF", "KK:LL:MM"],
|
||||||
|
["AA:BB:CC", "DD:EE:FF"],
|
||||||
|
["XX:YY:ZZ"]
|
||||||
|
]
|
||||||
|
|
||||||
|
expected = ["AA:BB:CC", "XX:YY:ZZ"]
|
||||||
|
cert_file_list = ['/path/to/certfile1', '/path/to/certfile2']
|
||||||
|
excl_cert_file_list = ['/path/to/certfile3']
|
||||||
|
|
||||||
|
remove_tls_mock = (get_sushy_system_mock.return_value.
|
||||||
|
bios_settings.tls_config.tls_config_settings.
|
||||||
|
remove_tls_certificate)
|
||||||
|
self.rf_client.remove_tls_certificate(
|
||||||
|
cert_file_list, excl_cert_file_list)
|
||||||
|
val_delete_certs = remove_tls_mock.call_args[0][0].get(
|
||||||
|
"DeleteCertificates")
|
||||||
|
actual = [item.get("FingerPrint") for item in val_delete_certs]
|
||||||
|
actual.sort()
|
||||||
|
|
||||||
|
get_fps_mock.assert_has_calls(get_fps_calls)
|
||||||
|
|
||||||
|
self.assertEqual(expected, actual)
|
||||||
|
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_get_fps_from_file')
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||||
|
def test_remove_tls_certificate_no_certificate(
|
||||||
|
self, get_sushy_system_mock, _uefi_boot_mode_mock, get_fps_mock):
|
||||||
|
_uefi_boot_mode_mock.return_value = True
|
||||||
|
cert_file_list = ['/path/to/certfile1', '/path/to/certfile2']
|
||||||
|
get_fps_calls = [
|
||||||
|
mock.call('/path/to/certfile1'),
|
||||||
|
mock.call('/path/to/certfile2')
|
||||||
|
]
|
||||||
|
get_fps_mock.return_value = []
|
||||||
|
|
||||||
self.assertRaisesRegex(
|
self.assertRaisesRegex(
|
||||||
exception.IloError,
|
exception.IloError,
|
||||||
"No valid certificate",
|
"No valid certificate",
|
||||||
self.rf_client.remove_tls_certificate, [cert_file])
|
self.rf_client.remove_tls_certificate, cert_file_list)
|
||||||
|
get_fps_mock.assert_has_calls(get_fps_calls)
|
||||||
decode_mock.assert_not_called()
|
|
||||||
load_cert_mock.assert_not_called()
|
|
||||||
|
|
||||||
(get_sushy_system_mock.return_value.
|
(get_sushy_system_mock.return_value.
|
||||||
bios_settings.tls_config.tls_config_settings.
|
bios_settings.tls_config.tls_config_settings.
|
||||||
remove_tls_certificate.assert_not_called())
|
remove_tls_certificate.assert_not_called())
|
||||||
|
|
||||||
@mock.patch.object(redfish, 'load_certificate')
|
@mock.patch.object(redfish.RedfishOperations, '_get_fps_from_file')
|
||||||
@mock.patch.object(redfish, 'b64decode')
|
|
||||||
@mock.patch.object(builtins, 'open')
|
|
||||||
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
||||||
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||||
def test_remove_tls_certificate_raises_ilo_error(self,
|
def test_remove_tls_certificate_raises_ilo_error(
|
||||||
get_sushy_system_mock,
|
self, get_sushy_system_mock, _uefi_boot_mode_mock, get_fps_mock):
|
||||||
_uefi_boot_mode_mock,
|
|
||||||
open_mock, decode_mock,
|
|
||||||
load_cert_mock):
|
|
||||||
_uefi_boot_mode_mock.return_value = True
|
_uefi_boot_mode_mock.return_value = True
|
||||||
decode_mock.side_effect = ['first decoded data',
|
get_fps_calls = [
|
||||||
'second decoded data']
|
mock.call('/path/to/certfile1'),
|
||||||
cert1_mock = mock.MagicMock()
|
mock.call('/path/to/certfile2')
|
||||||
cert2_mock = mock.MagicMock()
|
]
|
||||||
load_cert_mock.side_effect = [cert1_mock, cert2_mock]
|
get_fps_mock.side_effect = [
|
||||||
cert1_mock.digest.return_value.decode.return_value = "humptydumpty"
|
["AA:BB:CC", "DD:EE:FF"],
|
||||||
cert2_mock.digest.return_value.decode.return_value = "hickerydickery"
|
["XX:YY:ZZ"]
|
||||||
|
]
|
||||||
|
|
||||||
data = (
|
cert_file_list = ['/path/to/certfile1', '/path/to/certfile2']
|
||||||
"-----BEGIN CERTIFICATE-----\nMIID7TC\nCF"
|
|
||||||
"g879\n-----END CERTIFICATE-----\n"
|
|
||||||
"-----BEGIN CERTIFICATE-----\nKHY8UP\nGH"
|
|
||||||
"f792\n-----END CERTIFICATE-----\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
fd_mock = mock.MagicMock(spec=io.BytesIO)
|
|
||||||
open_mock.return_value = fd_mock
|
|
||||||
fd_mock.__enter__.return_value = fd_mock
|
|
||||||
fd_mock.read.return_value = data
|
|
||||||
|
|
||||||
cert_file = '/path/to/certfile'
|
|
||||||
(get_sushy_system_mock.return_value.
|
(get_sushy_system_mock.return_value.
|
||||||
bios_settings.tls_config.tls_config_settings.
|
bios_settings.tls_config.tls_config_settings.
|
||||||
remove_tls_certificate.side_effect) = (
|
remove_tls_certificate.side_effect) = (
|
||||||
|
@ -2317,7 +2362,8 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
||||||
self.assertRaisesRegex(
|
self.assertRaisesRegex(
|
||||||
exception.IloError,
|
exception.IloError,
|
||||||
'The Redfish controller has failed to remove TLS certificate.',
|
'The Redfish controller has failed to remove TLS certificate.',
|
||||||
self.rf_client.remove_tls_certificate, [cert_file])
|
self.rf_client.remove_tls_certificate, cert_file_list)
|
||||||
|
get_fps_mock.assert_has_calls(get_fps_calls)
|
||||||
|
|
||||||
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
||||||
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||||
|
@ -2332,41 +2378,6 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
||||||
'TLS certificates cannot be removed in BIOS boot mode',
|
'TLS certificates cannot be removed in BIOS boot mode',
|
||||||
self.rf_client.remove_tls_certificate, fp)
|
self.rf_client.remove_tls_certificate, fp)
|
||||||
|
|
||||||
@mock.patch.object(redfish, 'load_certificate')
|
|
||||||
@mock.patch.object(redfish, 'b64decode')
|
|
||||||
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
|
||||||
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
|
||||||
def test_remove_tls_certificate_default(self, get_sushy_system_mock,
|
|
||||||
_uefi_boot_mode_mock, decode_mock,
|
|
||||||
load_cert_mock):
|
|
||||||
_uefi_boot_mode_mock.return_value = True
|
|
||||||
with open('proliantutils/tests/redfish/'
|
|
||||||
'json_samples/tls_config.json', 'r') as f:
|
|
||||||
jsonval = json.loads(f.read())
|
|
||||||
tlsconfig_mock = mock.MagicMock(spec=tls_config.TLSConfig)
|
|
||||||
|
|
||||||
tls_mock = mock.PropertyMock(return_value=tlsconfig_mock)
|
|
||||||
|
|
||||||
type(get_sushy_system_mock.return_value.bios_settings).tls_config = (
|
|
||||||
tls_mock)
|
|
||||||
certificates = jsonval.get('Certificates')
|
|
||||||
certs_mock = mock.PropertyMock(return_value=certificates)
|
|
||||||
type(tlsconfig_mock).tls_certificates = certs_mock
|
|
||||||
del_cert_list = []
|
|
||||||
for cert in certificates:
|
|
||||||
fp = cert.get("FingerPrint")
|
|
||||||
cert_fp = {
|
|
||||||
"FingerPrint": fp
|
|
||||||
}
|
|
||||||
del_cert_list.append(cert_fp)
|
|
||||||
self.rf_client.remove_tls_certificate()
|
|
||||||
(get_sushy_system_mock.return_value.
|
|
||||||
bios_settings.tls_config.tls_config_settings.
|
|
||||||
remove_tls_certificate.assert_called_once_with(
|
|
||||||
{'DeleteCertificates': del_cert_list}))
|
|
||||||
decode_mock.assert_not_called()
|
|
||||||
load_cert_mock.assert_not_called()
|
|
||||||
|
|
||||||
@mock.patch.object(redfish.RedfishOperations,
|
@mock.patch.object(redfish.RedfishOperations,
|
||||||
'_update_security_parameter')
|
'_update_security_parameter')
|
||||||
@mock.patch.object(main.HPESushy, 'get_account_service')
|
@mock.patch.object(main.HPESushy, 'get_account_service')
|
||||||
|
|
Loading…
Reference in New Issue