[Redfish] Provides APIs to add/remove TLS certificate
Change-Id: I25c827b5dbd443c2827c0faeb9c92c06e7f778f7
This commit is contained in:
parent
c57437dc85
commit
af96983b3d
|
@ -121,7 +121,9 @@ SUPPORTED_REDFISH_METHODS = [
|
||||||
'get_iscsi_initiator_info',
|
'get_iscsi_initiator_info',
|
||||||
'set_iscsi_initiator_info',
|
'set_iscsi_initiator_info',
|
||||||
'set_http_boot_url',
|
'set_http_boot_url',
|
||||||
'get_http_boot_url'
|
'get_http_boot_url',
|
||||||
|
'add_tls_certificate',
|
||||||
|
'remove_tls_certificate'
|
||||||
]
|
]
|
||||||
|
|
||||||
LOG = log.get_logger(__name__)
|
LOG = log.get_logger(__name__)
|
||||||
|
@ -879,3 +881,17 @@ class IloClient(operations.IloOperations):
|
||||||
:raises: IloError, on an error from iLO.
|
:raises: IloError, on an error from iLO.
|
||||||
"""
|
"""
|
||||||
return self._call_method('get_available_disk_types')
|
return self._call_method('get_available_disk_types')
|
||||||
|
|
||||||
|
def add_tls_certificate(self, cert_file_list):
|
||||||
|
"""Adds the TLS certificate to the iLO
|
||||||
|
|
||||||
|
:raises: IloError, on an error from iLO.
|
||||||
|
"""
|
||||||
|
return self._call_method('add_tls_certificate', cert_file_list)
|
||||||
|
|
||||||
|
def remove_tls_certificate(self, fp_list):
|
||||||
|
"""Removes the TLS certificate from the iLO
|
||||||
|
|
||||||
|
:raises: IloError, on an error from iLO.
|
||||||
|
"""
|
||||||
|
return self._call_method('remove_tls_certificate', fp_list)
|
||||||
|
|
|
@ -533,3 +533,23 @@ class IloOperations(object):
|
||||||
not supported on the server.
|
not supported on the server.
|
||||||
"""
|
"""
|
||||||
raise exception.IloCommandNotSupportedError(ERRMSG)
|
raise exception.IloCommandNotSupportedError(ERRMSG)
|
||||||
|
|
||||||
|
def add_tls_certificate(self, cert_file_list):
|
||||||
|
"""Adds the TLS certificate to the iLO
|
||||||
|
|
||||||
|
:param cert_file_list: List of TLS certificate files
|
||||||
|
:raises: IloError, on an error from iLO.
|
||||||
|
:raises: IloCommandNotSupportedError, if the command is
|
||||||
|
not supported on the server.
|
||||||
|
"""
|
||||||
|
raise exception.IloCommandNotSupportedError(ERRMSG)
|
||||||
|
|
||||||
|
def remove_tls_certificate(self, fp_list):
|
||||||
|
"""Removes the TLS certificate from the iLO
|
||||||
|
|
||||||
|
:param fp_list: List of finger prints of the certificates
|
||||||
|
:raises: IloError, on an error from iLO.
|
||||||
|
:raises: IloCommandNotSupportedError, if the command is
|
||||||
|
not supported on the server.
|
||||||
|
"""
|
||||||
|
raise exception.IloCommandNotSupportedError(ERRMSG)
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
__author__ = 'HPE'
|
__author__ = 'HPE'
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import re
|
||||||
|
|
||||||
from six.moves.urllib import parse
|
from six.moves.urllib import parse
|
||||||
import sushy
|
import sushy
|
||||||
|
@ -1327,3 +1328,72 @@ class RedfishOperations(operations.IloOperations):
|
||||||
{'error': str(e)})
|
{'error': str(e)})
|
||||||
LOG.debug(msg)
|
LOG.debug(msg)
|
||||||
raise exception.IloError(msg)
|
raise exception.IloError(msg)
|
||||||
|
|
||||||
|
def add_tls_certificate(self, cert_file_list):
|
||||||
|
"""Adds the TLS certificates to the iLO.
|
||||||
|
|
||||||
|
:param cert_file_list: List of TLS certificate files
|
||||||
|
|
||||||
|
:raises: IloError, on an error from iLO.
|
||||||
|
:raises: IloCommandNotSupportedError, if the command is
|
||||||
|
not supported on the server.
|
||||||
|
"""
|
||||||
|
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
|
||||||
|
if(self._is_boot_mode_uefi()):
|
||||||
|
cert_list = []
|
||||||
|
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)
|
||||||
|
r = q.rstrip()
|
||||||
|
cert = {}
|
||||||
|
cert['X509Certificate'] = r
|
||||||
|
cert_list.append(cert)
|
||||||
|
|
||||||
|
cert_dict = {}
|
||||||
|
cert_dict['NewCertificates'] = cert_list
|
||||||
|
try:
|
||||||
|
(sushy_system.bios_settings.tls_config.
|
||||||
|
tls_config_settings.add_tls_certificate(cert_dict))
|
||||||
|
except sushy.exceptions.SushyError as e:
|
||||||
|
msg = (self._("The Redfish controller has failed to upload "
|
||||||
|
"TLS certificate. Error %(error)s") %
|
||||||
|
{'error': str(e)})
|
||||||
|
LOG.debug(msg)
|
||||||
|
raise exception.IloError(msg)
|
||||||
|
else:
|
||||||
|
msg = 'TLS certificate cannot be upload in BIOS boot mode'
|
||||||
|
raise exception.IloCommandNotSupportedInBiosError(msg)
|
||||||
|
|
||||||
|
def remove_tls_certificate(self, fp_list):
|
||||||
|
"""Removes the TLS certificate from the iLO.
|
||||||
|
|
||||||
|
:param fp_list: List of finger prints of the TLS certificates
|
||||||
|
|
||||||
|
:raises: IloError, on an error from iLO.
|
||||||
|
:raises: IloCommandNotSupportedError, if the command is
|
||||||
|
not supported on the server.
|
||||||
|
"""
|
||||||
|
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
|
||||||
|
if(self._is_boot_mode_uefi()):
|
||||||
|
cert = {}
|
||||||
|
del_cert_list = []
|
||||||
|
for fp in fp_list:
|
||||||
|
cert_fp = {
|
||||||
|
"FingerPrint": fp
|
||||||
|
}
|
||||||
|
del_cert_list.append(cert_fp)
|
||||||
|
cert.update({"DeleteCertificates": del_cert_list})
|
||||||
|
try:
|
||||||
|
(sushy_system.bios_settings.tls_config.
|
||||||
|
tls_config_settings.remove_tls_certificate(cert))
|
||||||
|
except sushy.exceptions.SushyError as e:
|
||||||
|
msg = (self._("The Redfish controller has failed to remove "
|
||||||
|
"TLS certificate. Error %(error)s") %
|
||||||
|
{'error': str(e)})
|
||||||
|
LOG.debug(msg)
|
||||||
|
raise exception.IloError(msg)
|
||||||
|
else:
|
||||||
|
msg = 'TLS certificate cannot be removed in BIOS boot mode'
|
||||||
|
raise exception.IloCommandNotSupportedInBiosError(msg)
|
||||||
|
|
|
@ -21,6 +21,7 @@ from proliantutils import log
|
||||||
from proliantutils.redfish.resources.system import constants as sys_cons
|
from proliantutils.redfish.resources.system import constants as sys_cons
|
||||||
from proliantutils.redfish.resources.system import iscsi
|
from proliantutils.redfish.resources.system import iscsi
|
||||||
from proliantutils.redfish.resources.system import mappings
|
from proliantutils.redfish.resources.system import mappings
|
||||||
|
from proliantutils.redfish.resources.system import tls_config
|
||||||
from proliantutils.redfish import utils
|
from proliantutils.redfish import utils
|
||||||
|
|
||||||
LOG = log.get_logger(__name__)
|
LOG = log.get_logger(__name__)
|
||||||
|
@ -94,6 +95,19 @@ class BIOSSettings(base.ResourceBase):
|
||||||
self, ["Oem", "Hpe", "Links", "iScsi"]),
|
self, ["Oem", "Hpe", "Links", "iScsi"]),
|
||||||
redfish_version=self.redfish_version)
|
redfish_version=self.redfish_version)
|
||||||
|
|
||||||
|
@property
|
||||||
|
@sushy_utils.cache_it
|
||||||
|
def tls_config(self):
|
||||||
|
"""Property to provide reference to BIOS TLS configuration instance
|
||||||
|
|
||||||
|
It is calculated once when the first time it is queried. On refresh,
|
||||||
|
this property gets reset.
|
||||||
|
"""
|
||||||
|
return tls_config.TLSConfig(
|
||||||
|
self._conn, utils.get_subresource_path_by(
|
||||||
|
self, ["Oem", "Hpe", "Links", "TlsConfig"]),
|
||||||
|
redfish_version=self.redfish_version)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@sushy_utils.cache_it
|
@sushy_utils.cache_it
|
||||||
def bios_mappings(self):
|
def bios_mappings(self):
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
# Copyright 2017 Hewlett Packard Enterprise Development LP
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from sushy.resources import base
|
||||||
|
from sushy import utils as sushy_utils
|
||||||
|
|
||||||
|
from proliantutils.redfish import utils
|
||||||
|
|
||||||
|
|
||||||
|
class TLSConfig(base.ResourceBase):
|
||||||
|
"""Class that represents the TLS Configuration.
|
||||||
|
|
||||||
|
This class extends the functionality of base resource class
|
||||||
|
from sushy.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
@sushy_utils.cache_it
|
||||||
|
def tls_config_settings(self):
|
||||||
|
"""Property to provide reference to TLS configuration settings instance
|
||||||
|
|
||||||
|
It is calculated once when the first time it is queried. On refresh,
|
||||||
|
this property gets reset.
|
||||||
|
"""
|
||||||
|
return TLSConfigSettings(
|
||||||
|
self._conn,
|
||||||
|
utils.get_subresource_path_by(
|
||||||
|
self, ["@Redfish.Settings", "SettingsObject"]),
|
||||||
|
redfish_version=self.redfish_version)
|
||||||
|
|
||||||
|
|
||||||
|
class TLSConfigSettings(base.ResourceBase):
|
||||||
|
"""Class that represents the TLS configuration settings.
|
||||||
|
|
||||||
|
This class extends the functionality of base resource class
|
||||||
|
from sushy.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def add_tls_certificate(self, cert_data):
|
||||||
|
"""Update tls certificate
|
||||||
|
|
||||||
|
:param data: default tls certs data
|
||||||
|
"""
|
||||||
|
self._conn.put(self.path, data=cert_data)
|
||||||
|
|
||||||
|
def remove_tls_certificate(self, cert_data):
|
||||||
|
"""Update tls certificate
|
||||||
|
|
||||||
|
:param data: default tls certs data
|
||||||
|
"""
|
||||||
|
self._conn.put(self.path, data=cert_data)
|
|
@ -0,0 +1,24 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIID7TCCAtWgAwIBAgIJAPpdOt6Qt3FFMA0GCSqGSIb3DQEBCwUAMIGMMQswCQYD
|
||||||
|
VQQGEwJJTjESMBAGA1UECAwJVGVsYW5nYW5hMRIwEAYDVQQHDAlIeWRlcmFiYWQx
|
||||||
|
DDAKBgNVBAoMA0hQRTELMAkGA1UECwwCU0cxFDASBgNVBAMMCzE3Mi4xNy4xLjg4
|
||||||
|
MSQwIgYJKoZIhvcNAQkBFhV2aW5heS5tLmt1bWFyQGhwZS5jb20wHhcNMTkwNDI0
|
||||||
|
MDg1MTI4WhcNMjAwNDIzMDg1MTI4WjCBjDELMAkGA1UEBhMCSU4xEjAQBgNVBAgM
|
||||||
|
CVRlbGFuZ2FuYTESMBAGA1UEBwwJSHlkZXJhYmFkMQwwCgYDVQQKDANIUEUxCzAJ
|
||||||
|
BgNVBAsMAlNHMRQwEgYDVQQDDAsxNzIuMTcuMS44ODEkMCIGCSqGSIb3DQEJARYV
|
||||||
|
dmluYXkubS5rdW1hckBocGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||||
|
CgKCAQEA3afHTbbueWjZMp0w0g4XN5VaGD17kk2fjjpJn0Ltgx2L4SSbEabM/491
|
||||||
|
A79wZlr0WSo53IYH7AB2ZA0Ze8ZBML6F4FBhSf6lPoGJN/cHDz5z/bDhNV/KrXLA
|
||||||
|
uqpghDQS0hiv0KHsk3JXaRz/FM+MmmoKdOWSLCWReGOOIGYwEyaB4CFAXefppTlP
|
||||||
|
ii0IyzGLMfUERxP3x/UpsR/hejun8QNOKcf5mpTbGbh1Ro+yvoJbeXy7ivkOX9QG
|
||||||
|
7w8UMzGxFXgQ/U3VvpfY5C1A23wAvX9F+lwNQQ71XfmB9ascC7luzWQ3WqVHVpKh
|
||||||
|
Ksv0vQ3MM17xEuHzlUrUJJSzltsb+wIDAQABo1AwTjAdBgNVHQ4EFgQUB6xKvLMe
|
||||||
|
R0JVdSSJZH37aEBh5zQwHwYDVR0jBBgwFoAUB6xKvLMeR0JVdSSJZH37aEBh5zQw
|
||||||
|
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAU3fBFSyx19SMgvBVzelP
|
||||||
|
NyudGhNKm+3zmKndi2HYdKQWHqg6dMSR9zE8FE6viUgB2v1V+5JpF7NhDbgCaNng
|
||||||
|
DmC8sm3p6lNpvcEDnPak6759K6yT/k6tlPsZ5GsIGXQhBMJdVw0zJPNHEMIV8SnV
|
||||||
|
D0SGSG5F+pcPvnQtdLzGl18kIOj0NmjzKnz+l/jBd7bckb7vXM+M/KRmrTE6cLF0
|
||||||
|
yB6IQ/UPWiuOIflxSxhSPaVYNWiaRALCJEiIYagoWr6mOUxqCnAdR50Pfwxz7KGI
|
||||||
|
txLjc4+qa6ZgWEBx3uDQ9ehysBrMOmWg5nXRlO/nbtyFXi+GzZChiNA75fgnb6e/
|
||||||
|
YQ==
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
"@Redfish.Settings":
|
||||||
|
{
|
||||||
|
"@odata.type": "#Settings.v1_0_0.Settings",
|
||||||
|
"ETag": "",
|
||||||
|
"Messages":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"MessageId": "Base.1.0.Success"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"SettingsObject":
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/systems/1/bios/tlsconfig/settings/"
|
||||||
|
},
|
||||||
|
"Time": null
|
||||||
|
},
|
||||||
|
"@odata.context": "/redfish/v1/$metadata#HpeTlsConfig.HpeTlsConfig",
|
||||||
|
"@odata.etag": "W/\"32F7F4DB0288E0E0E071C693DD579D6C\"",
|
||||||
|
"@odata.id": "/redfish/v1/systems/1/bios/tlsconfig/",
|
||||||
|
"@odata.type": "#HpeTlsConfig.v1_0_0.HpeTlsConfig",
|
||||||
|
"Certificates":
|
||||||
|
[
|
||||||
|
],
|
||||||
|
"Ciphers": "AES128-SHA:AES256-SHA:AES128-SHA256:AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384",
|
||||||
|
"DeleteCertificates":
|
||||||
|
[
|
||||||
|
],
|
||||||
|
"HostnameCheck": "Disabled",
|
||||||
|
"Id": "tlsconfig",
|
||||||
|
"Name": "TLS Current Settings",
|
||||||
|
"NewCertificates":
|
||||||
|
[
|
||||||
|
],
|
||||||
|
"Oem":
|
||||||
|
{
|
||||||
|
"Hpe":
|
||||||
|
{
|
||||||
|
"@odata.type": "#HpeBiosExt.v2_0_0.HpeBiosExt",
|
||||||
|
"Links":
|
||||||
|
{
|
||||||
|
"BaseConfigs":
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/systems/1/bios/tlsconfig/baseconfigs/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SettingsObject":
|
||||||
|
{
|
||||||
|
"UnmodifiedETag": "W/\"28F385EA989AD0D0D053F745E614B9D6\""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ProtocolVersion": "AUTO",
|
||||||
|
"TlsCaCertificateCount": 0,
|
||||||
|
"VerifyMode": "PEER"
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
"@Redfish.Settings":
|
||||||
|
{
|
||||||
|
"@odata.type": "#Settings.v1_0_0.Settings",
|
||||||
|
"ETag": "C6239FAE",
|
||||||
|
"Messages":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"MessageId": "Base.1.0.Success"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"SettingsObject":
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/systems/1/bios/tlsconfig/settings/"
|
||||||
|
},
|
||||||
|
"Time": "2020-06-11T21:20:31+00:00"
|
||||||
|
},
|
||||||
|
"@odata.context": "/redfish/v1/$metadata#HpeTlsConfig.HpeTlsConfig",
|
||||||
|
"@odata.etag": "W/\"885481367F69969696DE63CCE9D97509\"",
|
||||||
|
"@odata.id": "/redfish/v1/systems/1/bios/tlsconfig/",
|
||||||
|
"@odata.type": "#HpeTlsConfig.v1_0_0.HpeTlsConfig",
|
||||||
|
"Certificates":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"FingerPrint": "FA:3A:68:C7:7E:ED:90:21:D2:FA:3E:54:6B:0C:14:D3:2F:8D:43:50:F7:05:A7:0F:1C:68:35:DB:5C:D2:53:28",
|
||||||
|
"Issuer": "C=IN, ST=Karnataka, L=Bengaluru, O=HPE, OU=BCOS, CN=Vinay Muddu, emailAddress=vinay.m.kumar@hpe.com",
|
||||||
|
"SerialNumber": "92DF813625F950E5",
|
||||||
|
"Subject": "C=IN, ST=Karnataka, L=Bengaluru, O=HPE, OU=BCOS, CN=Vinay Muddu, emailAddress=vinay.m.kumar@hpe.com",
|
||||||
|
"ValidNotAfter": "06/08/2021 06:40",
|
||||||
|
"ValidNotBefore": "06/08/2020 06:40"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Ciphers": "AES128-SHA:AES256-SHA:AES128-SHA256:AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384",
|
||||||
|
"DeleteCertificates":
|
||||||
|
[
|
||||||
|
],
|
||||||
|
"HostnameCheck": "Disabled",
|
||||||
|
"Id": "tlsconfig",
|
||||||
|
"Name": "TLS Current Settings",
|
||||||
|
"NewCertificates":
|
||||||
|
[
|
||||||
|
],
|
||||||
|
"Oem":
|
||||||
|
{
|
||||||
|
"Hpe":
|
||||||
|
{
|
||||||
|
"@odata.type": "#HpeBiosExt.v2_0_0.HpeBiosExt",
|
||||||
|
"Links":
|
||||||
|
{
|
||||||
|
"BaseConfigs":
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/systems/1/bios/tlsconfig/baseconfigs/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SettingsObject":
|
||||||
|
{
|
||||||
|
"UnmodifiedETag": "W/\"89BE572CAA977F7F7FE56E1ADBF4F043\""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ProtocolVersion": "AUTO",
|
||||||
|
"TlsCaCertificateCount": 1,
|
||||||
|
"VerifyMode": "PEER"
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ from proliantutils import exception
|
||||||
from proliantutils.redfish.resources.system import bios
|
from proliantutils.redfish.resources.system import bios
|
||||||
from proliantutils.redfish.resources.system import constants as sys_cons
|
from proliantutils.redfish.resources.system import constants as sys_cons
|
||||||
from proliantutils.redfish.resources.system import iscsi
|
from proliantutils.redfish.resources.system import iscsi
|
||||||
|
from proliantutils.redfish.resources.system import tls_config
|
||||||
|
|
||||||
|
|
||||||
class BIOSSettingsTestCase(testtools.TestCase):
|
class BIOSSettingsTestCase(testtools.TestCase):
|
||||||
|
@ -111,6 +112,22 @@ class BIOSSettingsTestCase(testtools.TestCase):
|
||||||
self.bios_inst.iscsi_resource)
|
self.bios_inst.iscsi_resource)
|
||||||
self.conn.get.return_value.json.assert_not_called()
|
self.conn.get.return_value.json.assert_not_called()
|
||||||
|
|
||||||
|
def test_tls_config(self):
|
||||||
|
self.conn.get.return_value.json.reset_mock()
|
||||||
|
with open('proliantutils/tests/redfish/'
|
||||||
|
'json_samples/tls_config.json', 'r') as f:
|
||||||
|
self.conn.get.return_value.json.return_value = (
|
||||||
|
json.loads(f.read()))
|
||||||
|
actual_settings = self.bios_inst.tls_config
|
||||||
|
self.assertIsInstance(actual_settings,
|
||||||
|
tls_config.TLSConfig)
|
||||||
|
self.conn.get.return_value.json.assert_called_once_with()
|
||||||
|
# reset mock
|
||||||
|
self.conn.get.return_value.json.reset_mock()
|
||||||
|
self.assertIs(actual_settings,
|
||||||
|
self.bios_inst.tls_config)
|
||||||
|
self.conn.get.return_value.json.assert_not_called()
|
||||||
|
|
||||||
def test__get_base_configs(self):
|
def test__get_base_configs(self):
|
||||||
with open('proliantutils/tests/redfish/'
|
with open('proliantutils/tests/redfish/'
|
||||||
'json_samples/bios_base_configs.json', 'r') as f:
|
'json_samples/bios_base_configs.json', 'r') as f:
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
# Copyright 2017 Hewlett Packard Enterprise Development LP
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
import mock
|
||||||
|
import testtools
|
||||||
|
|
||||||
|
from proliantutils.redfish.resources.system import tls_config
|
||||||
|
|
||||||
|
|
||||||
|
class TLSConfigTestCase(testtools.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TLSConfigTestCase, self).setUp()
|
||||||
|
self.conn = mock.MagicMock()
|
||||||
|
with open('proliantutils/tests/redfish/'
|
||||||
|
'json_samples/tls_config.json', 'r') as f:
|
||||||
|
self.conn.get.return_value.json.return_value = (
|
||||||
|
json.loads(f.read()))
|
||||||
|
|
||||||
|
self.tls_config_inst = tls_config.TLSConfig(
|
||||||
|
self.conn, '/redfish/v1/Systems/1/bios/tlsconfig',
|
||||||
|
redfish_version='1.0.2')
|
||||||
|
|
||||||
|
def test_tls_config_settings(self):
|
||||||
|
self.conn.get.return_value.json.reset_mock()
|
||||||
|
with open('proliantutils/tests/redfish/'
|
||||||
|
'json_samples/tls_config_settings.json', 'r') as f:
|
||||||
|
self.conn.get.return_value.json.return_value = (
|
||||||
|
json.loads(f.read()))
|
||||||
|
actual_settings = self.tls_config_inst.tls_config_settings
|
||||||
|
self.assertIsInstance(actual_settings,
|
||||||
|
tls_config.TLSConfigSettings)
|
||||||
|
self.conn.get.return_value.json.assert_called_once_with()
|
||||||
|
# reset mock
|
||||||
|
self.conn.get.return_value.json.reset_mock()
|
||||||
|
self.assertIs(actual_settings,
|
||||||
|
self.tls_config_inst.tls_config_settings)
|
||||||
|
self.conn.get.return_value.json.assert_not_called()
|
||||||
|
|
||||||
|
def test_iscsi_settings_on_refresh(self):
|
||||||
|
with open('proliantutils/tests/redfish/'
|
||||||
|
'json_samples/tls_config_settings.json', 'r') as f:
|
||||||
|
self.conn.get.return_value.json.return_value = (
|
||||||
|
json.loads(f.read()))
|
||||||
|
actual_settings = self.tls_config_inst.tls_config_settings
|
||||||
|
self.assertIsInstance(actual_settings,
|
||||||
|
tls_config.TLSConfigSettings)
|
||||||
|
|
||||||
|
with open('proliantutils/tests/redfish/'
|
||||||
|
'json_samples/tls_config.json', 'r') as f:
|
||||||
|
self.conn.get.return_value.json.return_value = (
|
||||||
|
json.loads(f.read()))
|
||||||
|
|
||||||
|
self.tls_config_inst.invalidate()
|
||||||
|
self.tls_config_inst.refresh(force=False)
|
||||||
|
|
||||||
|
self.assertTrue(actual_settings._is_stale)
|
||||||
|
|
||||||
|
with open('proliantutils/tests/redfish/'
|
||||||
|
'json_samples/tls_config_settings.json', 'r') as f:
|
||||||
|
self.conn.get.return_value.json.return_value = (
|
||||||
|
json.loads(f.read()))
|
||||||
|
self.assertIsInstance(self.tls_config_inst.tls_config_settings,
|
||||||
|
tls_config.TLSConfigSettings)
|
||||||
|
self.assertFalse(actual_settings._is_stale)
|
||||||
|
|
||||||
|
|
||||||
|
class TLSConfigSettingsTestCase(testtools.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TLSConfigSettingsTestCase, self).setUp()
|
||||||
|
self.conn = mock.MagicMock()
|
||||||
|
with open('proliantutils/tests/redfish/'
|
||||||
|
'json_samples/tls_config_settings.json', 'r') as f:
|
||||||
|
self.conn.get.return_value.json.return_value = (
|
||||||
|
json.loads(f.read()))
|
||||||
|
|
||||||
|
self.tls_config_settings_inst = tls_config.TLSConfigSettings(
|
||||||
|
self.conn, '/redfish/v1/Systems/1/bios/tlsconfig/settings',
|
||||||
|
redfish_version='1.0.2')
|
||||||
|
|
||||||
|
def test_add_tls_certificate(self):
|
||||||
|
target_uri = '/redfish/v1/Systems/1/bios/tlsconfig/settings'
|
||||||
|
cert_data = {
|
||||||
|
"NewCertificates": [
|
||||||
|
{
|
||||||
|
"X509Certificate": "abc"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
self.tls_config_settings_inst.add_tls_certificate(cert_data)
|
||||||
|
self.tls_config_settings_inst._conn.put.assert_called_once_with(
|
||||||
|
target_uri, data=cert_data)
|
||||||
|
|
||||||
|
def test_remove_tls_certificate(self):
|
||||||
|
target_uri = '/redfish/v1/Systems/1/bios/tlsconfig/settings'
|
||||||
|
fp = ('FA:3A:68:C7:7E:ED:90:21:D2:FA:3E:54:6B:0C:14:D3:'
|
||||||
|
'2F:8D:43:50:F7:05:A7:0F:1C:68:35:DB:5C:D2:53:28')
|
||||||
|
cert = {}
|
||||||
|
del_cert_list = [{"FingerPrint": fp}]
|
||||||
|
cert.update({"DeleteCertificates": del_cert_list})
|
||||||
|
|
||||||
|
self.tls_config_settings_inst.remove_tls_certificate(cert)
|
||||||
|
self.tls_config_settings_inst._conn.put.assert_called_once_with(
|
||||||
|
target_uri, data=cert)
|
|
@ -2008,3 +2008,99 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
||||||
exception.IloError,
|
exception.IloError,
|
||||||
'Could not set HTTPS URL on the iLO.',
|
'Could not set HTTPS URL on the iLO.',
|
||||||
self.rf_client.set_http_boot_url, url, dhcp_enabled)
|
self.rf_client.set_http_boot_url, url, dhcp_enabled)
|
||||||
|
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||||
|
def test_add_tls_certificate_bios(self, get_sushy_system_mock,
|
||||||
|
_uefi_boot_mode_mock):
|
||||||
|
_uefi_boot_mode_mock.return_value = False
|
||||||
|
data = {
|
||||||
|
"NewCertificates": [
|
||||||
|
{
|
||||||
|
"X509Certificate": "Some data"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
exception.IloCommandNotSupportedInBiosError,
|
||||||
|
'TLS certificate cannot be upload in BIOS boot mode',
|
||||||
|
self.rf_client.add_tls_certificate,
|
||||||
|
data)
|
||||||
|
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||||
|
def test_add_tls_certificate(self, get_sushy_system_mock,
|
||||||
|
_uefi_boot_mode_mock):
|
||||||
|
_uefi_boot_mode_mock.return_value = True
|
||||||
|
cert_file = 'proliantutils/tests/redfish/json_samples/certfile.crt'
|
||||||
|
with open('proliantutils/tests/redfish/'
|
||||||
|
'json_samples/certfile.crt', 'r') as f:
|
||||||
|
cert_data = f.read()
|
||||||
|
|
||||||
|
import re
|
||||||
|
cert_data = cert_data.rstrip()
|
||||||
|
ref_data = re.sub(r"\n", "\r\n", cert_data)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"NewCertificates": [
|
||||||
|
{
|
||||||
|
"X509Certificate": ref_data
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
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_called_once_with(data))
|
||||||
|
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||||
|
def test_add_tls_certificate_raises_ilo_error(self, get_sushy_system_mock,
|
||||||
|
_uefi_boot_mode_mock):
|
||||||
|
_uefi_boot_mode_mock.return_value = True
|
||||||
|
cert_file = 'proliantutils/tests/redfish/json_samples/certfile.crt'
|
||||||
|
(get_sushy_system_mock.return_value.
|
||||||
|
bios_settings.tls_config.tls_config_settings.
|
||||||
|
add_tls_certificate.side_effect) = (
|
||||||
|
sushy.exceptions.SushyError)
|
||||||
|
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
exception.IloError,
|
||||||
|
'The Redfish controller has failed to upload TLS certificate.',
|
||||||
|
self.rf_client.add_tls_certificate, [cert_file])
|
||||||
|
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||||
|
def test_remove_tls_certificate(self, get_sushy_system_mock,
|
||||||
|
_uefi_boot_mode_mock):
|
||||||
|
_uefi_boot_mode_mock.return_value = True
|
||||||
|
fp = ('FA:3A:68:C7:7E:ED:90:21:D2:FA:3E:54:6B:0C:14:D3:'
|
||||||
|
'2F:8D:43:50:F7:05:A7:0F:1C:68:35:DB:5C:D2:53:28')
|
||||||
|
|
||||||
|
cert = {}
|
||||||
|
del_cert_list = []
|
||||||
|
cert_fp = {
|
||||||
|
"FingerPrint": fp
|
||||||
|
}
|
||||||
|
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.
|
||||||
|
bios_settings.tls_config.tls_config_settings.
|
||||||
|
remove_tls_certificate.assert_called_once_with(cert))
|
||||||
|
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_is_boot_mode_uefi')
|
||||||
|
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||||
|
def test_remove_tls_certificate_bios(self, get_sushy_system_mock,
|
||||||
|
_uefi_boot_mode_mock):
|
||||||
|
_uefi_boot_mode_mock.return_value = False
|
||||||
|
fp = ('FA:3A:68:C7:7E:ED:90:21:D2:FA:3E:54:6B:0C:14:D3:'
|
||||||
|
'2F:8D:43:50:F7:05:A7:0F:1C:68:35:DB:5C:D2:53:28')
|
||||||
|
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
exception.IloCommandNotSupportedInBiosError,
|
||||||
|
'TLS certificate cannot be removed in BIOS boot mode',
|
||||||
|
self.rf_client.remove_tls_certificate, fp)
|
||||||
|
|
Loading…
Reference in New Issue