Merge "[Redfish] Enhance removing TLS certificates"
This commit is contained in:
commit
9a29e32bb2
|
@ -900,13 +900,15 @@ class IloClient(operations.IloOperations):
|
||||||
def add_tls_certificate(self, cert_file_list):
|
def add_tls_certificate(self, cert_file_list):
|
||||||
"""Adds the TLS certificate to the iLO
|
"""Adds the TLS certificate to the iLO
|
||||||
|
|
||||||
|
:param cert_file_list: List of TLS certificate files
|
||||||
:raises: IloError, on an error from iLO.
|
:raises: IloError, on an error from iLO.
|
||||||
"""
|
"""
|
||||||
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, fp_list):
|
def remove_tls_certificate(self, 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
|
||||||
:raises: IloError, on an error from iLO.
|
:raises: IloError, on an error from iLO.
|
||||||
"""
|
"""
|
||||||
return self._call_method('remove_tls_certificate', fp_list)
|
return self._call_method('remove_tls_certificate', cert_file_list)
|
||||||
|
|
|
@ -558,10 +558,10 @@ class IloOperations(object):
|
||||||
"""
|
"""
|
||||||
raise exception.IloCommandNotSupportedError(ERRMSG)
|
raise exception.IloCommandNotSupportedError(ERRMSG)
|
||||||
|
|
||||||
def remove_tls_certificate(self, fp_list):
|
def remove_tls_certificate(self, cert_file_list):
|
||||||
"""Removes the TLS certificate from the iLO
|
"""Removes the TLS certificate from the iLO
|
||||||
|
|
||||||
:param fp_list: List of finger prints of the certificates
|
:param cert_file_list: List of TLS certificate files
|
||||||
: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
|
||||||
not supported on the server.
|
not supported on the server.
|
||||||
|
|
|
@ -14,9 +14,12 @@
|
||||||
|
|
||||||
__author__ = 'HPE'
|
__author__ = 'HPE'
|
||||||
|
|
||||||
|
from base64 import b64decode
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from OpenSSL.crypto import FILETYPE_ASN1
|
||||||
|
from OpenSSL.crypto import load_certificate
|
||||||
from six.moves.urllib import parse
|
from six.moves.urllib import parse
|
||||||
import sushy
|
import sushy
|
||||||
from sushy.resources.system import mappings as sushy_map
|
from sushy.resources.system import mappings as sushy_map
|
||||||
|
@ -114,6 +117,9 @@ SUPPORTED_BOOT_MODE_MAP = {
|
||||||
ilo_cons.SUPPORTED_BOOT_MODE_LEGACY_BIOS_AND_UEFI)
|
ilo_cons.SUPPORTED_BOOT_MODE_LEGACY_BIOS_AND_UEFI)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_CERTIFICATE_PATTERN = (
|
||||||
|
r'-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----')
|
||||||
|
|
||||||
LOG = log.get_logger(__name__)
|
LOG = log.get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1421,17 +1427,33 @@ class RedfishOperations(operations.IloOperations):
|
||||||
not supported on the server.
|
not supported on the server.
|
||||||
"""
|
"""
|
||||||
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
|
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
|
||||||
|
|
||||||
if(self._is_boot_mode_uefi()):
|
if(self._is_boot_mode_uefi()):
|
||||||
cert_list = []
|
cert_list = []
|
||||||
for cert_file in cert_file_list:
|
for cert_file in cert_file_list:
|
||||||
with open(cert_file, 'r') as f:
|
with open(cert_file, 'r') as f:
|
||||||
data = json.dumps(f.read())
|
data = json.dumps(f.read())
|
||||||
p = re.sub(r"\"", "", data)
|
p = re.sub(r"\"", "", data)
|
||||||
q = re.sub(r"\\n", "\r\n", p)
|
q = re.sub(r"\\n", "\r\n", p).rstrip()
|
||||||
r = q.rstrip()
|
|
||||||
cert = {}
|
c_list = re.findall(_CERTIFICATE_PATTERN, q, re.DOTALL)
|
||||||
cert['X509Certificate'] = r
|
|
||||||
cert_list.append(cert)
|
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:
|
||||||
|
cert = {}
|
||||||
|
cert['X509Certificate'] = content
|
||||||
|
cert_list.append(cert)
|
||||||
|
|
||||||
|
if len(cert_list) == 0:
|
||||||
|
msg = (self._("No valid certificate in %(cert_file_list)s.") %
|
||||||
|
{"cert_file_list": cert_file_list})
|
||||||
|
LOG.debug(msg)
|
||||||
|
raise exception.IloError(msg)
|
||||||
|
|
||||||
cert_dict = {}
|
cert_dict = {}
|
||||||
cert_dict['NewCertificates'] = cert_list
|
cert_dict['NewCertificates'] = cert_list
|
||||||
|
@ -1448,28 +1470,61 @@ 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, fp_list):
|
def remove_tls_certificate(self, cert_file_list):
|
||||||
"""Removes the TLS certificate from the iLO.
|
"""Removes the TLS certificate from the iLO.
|
||||||
|
|
||||||
:param fp_list: List of finger prints of the TLS certificates
|
:param cert_file_list: List of TLS certificate files
|
||||||
|
|
||||||
: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
|
||||||
not supported on the server.
|
not supported on the server.
|
||||||
"""
|
"""
|
||||||
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
|
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
|
||||||
|
|
||||||
if(self._is_boot_mode_uefi()):
|
if(self._is_boot_mode_uefi()):
|
||||||
cert = {}
|
cert_dict = {}
|
||||||
del_cert_list = []
|
del_cert_list = []
|
||||||
for fp in fp_list:
|
for cert_file in cert_file_list:
|
||||||
cert_fp = {
|
with open(cert_file, 'r') as f:
|
||||||
"FingerPrint": fp
|
data = json.dumps(f.read())
|
||||||
}
|
p = re.sub(r"\"", "", data)
|
||||||
del_cert_list.append(cert_fp)
|
q = re.sub(r"\\n", "\r\n", p).rstrip()
|
||||||
cert.update({"DeleteCertificates": del_cert_list})
|
|
||||||
|
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:
|
||||||
|
msg = (self._("No valid certificate in %(cert_file_list)s.") %
|
||||||
|
{"cert_file_list": cert_file_list})
|
||||||
|
raise exception.IloError(msg)
|
||||||
|
|
||||||
|
cert_dict.update({"DeleteCertificates": del_cert_list})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
(sushy_system.bios_settings.tls_config.
|
(sushy_system.bios_settings.tls_config.
|
||||||
tls_config_settings.remove_tls_certificate(cert))
|
tls_config_settings.remove_tls_certificate(cert_dict))
|
||||||
except sushy.exceptions.SushyError as e:
|
except sushy.exceptions.SushyError as e:
|
||||||
msg = (self._("The Redfish controller has failed to remove "
|
msg = (self._("The Redfish controller has failed to remove "
|
||||||
"TLS certificate. Error %(error)s") %
|
"TLS certificate. Error %(error)s") %
|
||||||
|
|
|
@ -13,7 +13,10 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
|
import builtins
|
||||||
import collections
|
import collections
|
||||||
|
import io
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import ddt
|
import ddt
|
||||||
|
@ -2050,39 +2053,98 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
||||||
self.rf_client.add_tls_certificate,
|
self.rf_client.add_tls_certificate,
|
||||||
data)
|
data)
|
||||||
|
|
||||||
|
@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_add_tls_certificate(self, get_sushy_system_mock,
|
def test_add_tls_certificate(self, get_sushy_system_mock,
|
||||||
_uefi_boot_mode_mock):
|
_uefi_boot_mode_mock, open_mock):
|
||||||
_uefi_boot_mode_mock.return_value = True
|
_uefi_boot_mode_mock.return_value = True
|
||||||
cert_file = 'proliantutils/tests/redfish/json_samples/certfile.crt'
|
data = (
|
||||||
with open('proliantutils/tests/redfish/'
|
"-----BEGIN CERTIFICATE-----\nMIID7TC\nCF"
|
||||||
'json_samples/certfile.crt', 'r') as f:
|
"g879\n-----END CERTIFICATE-----\n"
|
||||||
cert_data = f.read()
|
"-----BEGIN CERTIFICATE-----\nKHY8UP\nGH"
|
||||||
|
"f792\n-----END CERTIFICATE-----\n"
|
||||||
|
)
|
||||||
|
|
||||||
import re
|
fd_mock = mock.MagicMock(spec=io.BytesIO)
|
||||||
cert_data = cert_data.rstrip()
|
open_mock.return_value = fd_mock
|
||||||
ref_data = re.sub(r"\n", "\r\n", cert_data)
|
fd_mock.__enter__.return_value = fd_mock
|
||||||
|
fd_mock.read.return_value = data
|
||||||
|
c_l = [
|
||||||
|
"-----BEGIN CERTIFICATE-----\r\nMIID7TC\r\nCF"
|
||||||
|
"g879\r\n-----END CERTIFICATE-----",
|
||||||
|
"-----BEGIN CERTIFICATE-----\r\nKHY8UP\r\nGH"
|
||||||
|
"f792\r\n-----END CERTIFICATE-----"
|
||||||
|
]
|
||||||
|
|
||||||
data = {
|
expected_data = {
|
||||||
"NewCertificates": [
|
"NewCertificates": [
|
||||||
{
|
{
|
||||||
"X509Certificate": ref_data
|
"X509Certificate": c_l[0],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"X509Certificate": c_l[1],
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
cert_file = '/path/to/certfile'
|
||||||
|
|
||||||
self.rf_client.add_tls_certificate([cert_file])
|
self.rf_client.add_tls_certificate([cert_file])
|
||||||
|
|
||||||
(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.
|
||||||
add_tls_certificate.assert_called_once_with(data))
|
add_tls_certificate.assert_called_once_with(expected_data))
|
||||||
|
|
||||||
|
@mock.patch.object(builtins, 'open')
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||||
|
def test_add_tls_certificate_no_certificate(self, get_sushy_system_mock,
|
||||||
|
_uefi_boot_mode_mock,
|
||||||
|
open_mock):
|
||||||
|
_uefi_boot_mode_mock.return_value = True
|
||||||
|
data = (
|
||||||
|
"-----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)
|
||||||
|
open_mock.return_value = fd_mock
|
||||||
|
fd_mock.__enter__.return_value = fd_mock
|
||||||
|
fd_mock.read.return_value = data
|
||||||
|
cert_file = "/path/to/certfile"
|
||||||
|
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
exception.IloError,
|
||||||
|
"No valid certificate",
|
||||||
|
self.rf_client.add_tls_certificate, [cert_file])
|
||||||
|
|
||||||
|
(get_sushy_system_mock.return_value.
|
||||||
|
bios_settings.tls_config.tls_config_settings.
|
||||||
|
add_tls_certificate.assert_not_called())
|
||||||
|
|
||||||
|
@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_add_tls_certificate_raises_ilo_error(self, get_sushy_system_mock,
|
def test_add_tls_certificate_raises_ilo_error(self, get_sushy_system_mock,
|
||||||
_uefi_boot_mode_mock):
|
_uefi_boot_mode_mock,
|
||||||
|
open_mock):
|
||||||
_uefi_boot_mode_mock.return_value = True
|
_uefi_boot_mode_mock.return_value = True
|
||||||
cert_file = 'proliantutils/tests/redfish/json_samples/certfile.crt'
|
|
||||||
|
data = (
|
||||||
|
"-----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.
|
||||||
add_tls_certificate.side_effect) = (
|
add_tls_certificate.side_effect) = (
|
||||||
|
@ -2093,26 +2155,143 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
||||||
'The Redfish controller has failed to upload TLS certificate.',
|
'The Redfish controller has failed to upload TLS certificate.',
|
||||||
self.rf_client.add_tls_certificate, [cert_file])
|
self.rf_client.add_tls_certificate, [cert_file])
|
||||||
|
|
||||||
|
@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(self, get_sushy_system_mock,
|
def test_remove_tls_certificate(self, get_sushy_system_mock,
|
||||||
_uefi_boot_mode_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
|
||||||
fp = ('FA:3A:68:C7:7E:ED:90:21:D2:FA:3E:54:6B:0C:14:D3:'
|
decode_mock.side_effect = ['first decoded data',
|
||||||
'2F:8D:43:50:F7:05:A7:0F:1C:68:35:DB:5C:D2:53:28')
|
'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"
|
||||||
|
|
||||||
cert = {}
|
data = (
|
||||||
del_cert_list = []
|
"-----BEGIN CERTIFICATE-----\nMIID7TC\nCF"
|
||||||
cert_fp = {
|
"g879\n-----END CERTIFICATE-----\n"
|
||||||
"FingerPrint": fp
|
"-----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
|
||||||
|
|
||||||
|
decode_calls = [
|
||||||
|
mock.call('MIID7TCCFg879'),
|
||||||
|
mock.call('KHY8UPGHf792')
|
||||||
|
]
|
||||||
|
load_cert_calls = [
|
||||||
|
mock.call(redfish.FILETYPE_ASN1, 'first decoded data'),
|
||||||
|
mock.call(redfish.FILETYPE_ASN1, 'second decoded data')
|
||||||
|
]
|
||||||
|
cert_file = '/path/to/certfile'
|
||||||
|
self.rf_client.remove_tls_certificate([cert_file])
|
||||||
|
decode_mock.assert_has_calls(decode_calls)
|
||||||
|
load_cert_mock.assert_has_calls(load_cert_calls)
|
||||||
|
|
||||||
|
expected_data = {
|
||||||
|
"DeleteCertificates": [
|
||||||
|
{
|
||||||
|
"FingerPrint": "humptydumpty",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FingerPrint": "hickerydickery"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
del_cert_list.append(cert_fp)
|
|
||||||
cert.update({"DeleteCertificates": del_cert_list})
|
|
||||||
self.rf_client.remove_tls_certificate([fp])
|
|
||||||
|
|
||||||
(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_called_once_with(cert))
|
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, '_get_sushy_system')
|
||||||
|
def test_remove_tls_certificate_no_certificate(self,
|
||||||
|
get_sushy_system_mock,
|
||||||
|
_uefi_boot_mode_mock,
|
||||||
|
open_mock, decode_mock,
|
||||||
|
load_cert_mock):
|
||||||
|
|
||||||
|
_uefi_boot_mode_mock.return_value = True
|
||||||
|
|
||||||
|
data = (
|
||||||
|
"-----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)
|
||||||
|
open_mock.return_value = fd_mock
|
||||||
|
fd_mock.__enter__.return_value = fd_mock
|
||||||
|
fd_mock.read.return_value = data
|
||||||
|
|
||||||
|
cert_file = '/path/to/certfile'
|
||||||
|
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
exception.IloError,
|
||||||
|
"No valid certificate",
|
||||||
|
self.rf_client.remove_tls_certificate, [cert_file])
|
||||||
|
|
||||||
|
decode_mock.assert_not_called()
|
||||||
|
load_cert_mock.assert_not_called()
|
||||||
|
|
||||||
|
(get_sushy_system_mock.return_value.
|
||||||
|
bios_settings.tls_config.tls_config_settings.
|
||||||
|
remove_tls_certificate.assert_not_called())
|
||||||
|
|
||||||
|
@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, '_get_sushy_system')
|
||||||
|
def test_remove_tls_certificate_raises_ilo_error(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 = (
|
||||||
|
"-----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.
|
||||||
|
bios_settings.tls_config.tls_config_settings.
|
||||||
|
remove_tls_certificate.side_effect) = (
|
||||||
|
sushy.exceptions.SushyError)
|
||||||
|
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
exception.IloError,
|
||||||
|
'The Redfish controller has failed to remove TLS certificate.',
|
||||||
|
self.rf_client.remove_tls_certificate, [cert_file])
|
||||||
|
|
||||||
@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')
|
||||||
|
|
|
@ -10,3 +10,4 @@ pysnmp>=4.2.3,<5.0.0 # BSD
|
||||||
|
|
||||||
# Redfish communication uses the Sushy library
|
# Redfish communication uses the Sushy library
|
||||||
sushy>=3.1.0
|
sushy>=3.1.0
|
||||||
|
pyOpenSSL>=19.1.0
|
||||||
|
|
Loading…
Reference in New Issue