Add chassis missing property and unitest
Change-Id: I1b968801b937ef4a3e92e678fe8934fa215ebac7
This commit is contained in:
parent
7754b87ba3
commit
113cbeaa8e
@ -16,6 +16,7 @@
|
|||||||
from sushy.resources import base
|
from sushy.resources import base
|
||||||
from sushy import utils
|
from sushy import utils
|
||||||
|
|
||||||
|
from rsd_lib.resources.v2_1.chassis import log_services
|
||||||
from rsd_lib.resources.v2_1.chassis import power
|
from rsd_lib.resources.v2_1.chassis import power
|
||||||
from rsd_lib.resources.v2_1.chassis import power_zone
|
from rsd_lib.resources.v2_1.chassis import power_zone
|
||||||
from rsd_lib.resources.v2_1.chassis import thermal
|
from rsd_lib.resources.v2_1.chassis import thermal
|
||||||
@ -54,6 +55,22 @@ class LinksField(base.CompositeField):
|
|||||||
adapter=utils.get_members_identities)
|
adapter=utils.get_members_identities)
|
||||||
"""The Ethernet switches contained in this chassis"""
|
"""The Ethernet switches contained in this chassis"""
|
||||||
|
|
||||||
|
drives = base.Field("Drives", adapter=utils.get_members_identities)
|
||||||
|
""""An array of references to the disk drives located in this Chassis"""
|
||||||
|
|
||||||
|
storage = base.Field("Storage", adapter=utils.get_members_identities)
|
||||||
|
"""An array of references to the storage subsystems connected to or inside
|
||||||
|
this Chassis
|
||||||
|
"""
|
||||||
|
|
||||||
|
cooled_by = base.Field("CooledBy",
|
||||||
|
adapter=utils.get_members_identities)
|
||||||
|
"""An array of ID[s] of resources that cool this chassis"""
|
||||||
|
|
||||||
|
powered_by = base.Field("PoweredBy",
|
||||||
|
adapter=utils.get_members_identities)
|
||||||
|
"""An array of ID[s] of resources that power this chassis"""
|
||||||
|
|
||||||
|
|
||||||
class LocationField(base.CompositeField):
|
class LocationField(base.CompositeField):
|
||||||
identity = base.Field('Id')
|
identity = base.Field('Id')
|
||||||
@ -83,6 +100,18 @@ class OemField(base.CompositeField):
|
|||||||
"""Provides info about the geographical location of this chassis"""
|
"""Provides info about the geographical location of this chassis"""
|
||||||
|
|
||||||
|
|
||||||
|
class PhysicalSecurityField(base.CompositeField):
|
||||||
|
intrusion_sensor_number = base.Field("IntrusionSensorNumber",
|
||||||
|
adapter=rsd_lib_utils.num_or_none)
|
||||||
|
""""The physical security intrusion sensor number"""
|
||||||
|
|
||||||
|
intrusion_sensor = base.Field("IntrusionSensor")
|
||||||
|
""""The physical security intrusion sensor"""
|
||||||
|
|
||||||
|
intrusion_sensor_rearm = base.Field("IntrusionSensorReArm")
|
||||||
|
""""The physical security intrusion sensor rearm"""
|
||||||
|
|
||||||
|
|
||||||
class Chassis(base.ResourceBase):
|
class Chassis(base.ResourceBase):
|
||||||
identity = base.Field('Id', required=True)
|
identity = base.Field('Id', required=True)
|
||||||
"""The chassis identity string"""
|
"""The chassis identity string"""
|
||||||
@ -126,6 +155,12 @@ class Chassis(base.ResourceBase):
|
|||||||
links = LinksField('Links')
|
links = LinksField('Links')
|
||||||
"""The link section of chassis"""
|
"""The link section of chassis"""
|
||||||
|
|
||||||
|
power_state = base.Field("PowerState")
|
||||||
|
"""The chassis power state"""
|
||||||
|
|
||||||
|
physical_security = PhysicalSecurityField("PhysicalSecurity")
|
||||||
|
"""The chassis physical security"""
|
||||||
|
|
||||||
def __init__(self, connector, identity, redfish_version=None):
|
def __init__(self, connector, identity, redfish_version=None):
|
||||||
"""A class representing a Chassis
|
"""A class representing a Chassis
|
||||||
|
|
||||||
@ -200,6 +235,22 @@ class Chassis(base.ResourceBase):
|
|||||||
self._conn, self._get_thermal_path(),
|
self._conn, self._get_thermal_path(),
|
||||||
redfish_version=self.redfish_version)
|
redfish_version=self.redfish_version)
|
||||||
|
|
||||||
|
def _get_log_service_collection_path(self):
|
||||||
|
"""Helper function to find the LogServices path"""
|
||||||
|
return utils.get_sub_resource_path_by(self, 'LogServices')
|
||||||
|
|
||||||
|
@property
|
||||||
|
@utils.cache_it
|
||||||
|
def log_services(self):
|
||||||
|
"""Property to provide reference to `LogServices` instance
|
||||||
|
|
||||||
|
It is calculated once when it is queried for the first time. On
|
||||||
|
refresh, this property is reset.
|
||||||
|
"""
|
||||||
|
return log_services.LogServicesCollection(
|
||||||
|
self._conn, self._get_log_service_collection_path(),
|
||||||
|
redfish_version=self.redfish_version)
|
||||||
|
|
||||||
def update(self, asset_tag=None, location_id=None):
|
def update(self, asset_tag=None, location_id=None):
|
||||||
"""Update AssetTag and Location->Id properties
|
"""Update AssetTag and Location->Id properties
|
||||||
|
|
||||||
|
96
rsd_lib/resources/v2_1/chassis/log_entry.py
Normal file
96
rsd_lib/resources/v2_1/chassis/log_entry.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# Copyright 2019 Intel, Inc.
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
from rsd_lib import utils as rsd_lib_utils
|
||||||
|
from sushy.resources import base
|
||||||
|
from sushy import utils
|
||||||
|
|
||||||
|
|
||||||
|
class LinksField(base.CompositeField):
|
||||||
|
OriginOfCondition = base.Field("OriginOfCondition",
|
||||||
|
adapter=utils.get_members_identities)
|
||||||
|
"""The URI of the resource that caused the log entry"""
|
||||||
|
|
||||||
|
|
||||||
|
class LogEntry(base.ResourceBase):
|
||||||
|
identity = base.Field('Id', required=True)
|
||||||
|
"""The log entry identity string"""
|
||||||
|
|
||||||
|
description = base.Field('Description')
|
||||||
|
"""The log entry description"""
|
||||||
|
|
||||||
|
name = base.Field('Name')
|
||||||
|
"""The log entry name"""
|
||||||
|
|
||||||
|
severity = base.Field("Severity")
|
||||||
|
"""The severity of the log entry"""
|
||||||
|
|
||||||
|
created = base.Field("Created")
|
||||||
|
"""The time the log entry was created"""
|
||||||
|
|
||||||
|
entry_type = base.Field("EntryType")
|
||||||
|
""""The type of log entry"""
|
||||||
|
|
||||||
|
oem_record_format = base.Field("OemRecordFormat")
|
||||||
|
"""The log entry oem record format"""
|
||||||
|
|
||||||
|
entry_code = base.Field("EntryCode")
|
||||||
|
"""The log entry code"""
|
||||||
|
|
||||||
|
sensor_type = base.Field("SensorType")
|
||||||
|
"""The log entry sensor type"""
|
||||||
|
|
||||||
|
sensor_number = base.Field("SensorNumber",
|
||||||
|
adapter=rsd_lib_utils.num_or_none)
|
||||||
|
"""The log entry sensor number"""
|
||||||
|
|
||||||
|
message = base.Field("Message")
|
||||||
|
"""The log entry message"""
|
||||||
|
|
||||||
|
message_id = base.Field("MessageId")
|
||||||
|
"""The log entry message id"""
|
||||||
|
|
||||||
|
message_args = base.Field("MessageArgs")
|
||||||
|
"""The log entry message args"""
|
||||||
|
|
||||||
|
links = LinksField("Links")
|
||||||
|
"""The log entry links"""
|
||||||
|
|
||||||
|
event_type = base.Field("EventType")
|
||||||
|
"""The type of an event recorded in this log"""
|
||||||
|
|
||||||
|
event_id = base.Field("EventId")
|
||||||
|
"""A unique instance identifier of an event"""
|
||||||
|
|
||||||
|
event_timestamp = base.Field("EventTimestamp")
|
||||||
|
"""Time the event occurred"""
|
||||||
|
|
||||||
|
|
||||||
|
class LogEntryCollection(base.ResourceCollectionBase):
|
||||||
|
@property
|
||||||
|
def _resource_type(self):
|
||||||
|
return LogEntry
|
||||||
|
|
||||||
|
def __init__(self, connector, path, redfish_version=None):
|
||||||
|
"""A class representing a LogEntry Collection
|
||||||
|
|
||||||
|
:param connector: A Connector instance
|
||||||
|
:param path: The canonical path to the LogEntry Collection resource
|
||||||
|
:param redfish_version: The version of RedFish. Used to construct
|
||||||
|
the object according to schema of the given version.
|
||||||
|
"""
|
||||||
|
super(LogEntryCollection, self).__init__(connector,
|
||||||
|
path,
|
||||||
|
redfish_version)
|
105
rsd_lib/resources/v2_1/chassis/log_services.py
Normal file
105
rsd_lib/resources/v2_1/chassis/log_services.py
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
# Copyright 2019 Intel, Inc.
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
from rsd_lib.resources.v2_1.chassis import log_entry
|
||||||
|
from rsd_lib import utils as rsd_lib_utils
|
||||||
|
from sushy.resources import base
|
||||||
|
from sushy import utils
|
||||||
|
|
||||||
|
|
||||||
|
class StatusField(base.CompositeField):
|
||||||
|
state = base.Field('State')
|
||||||
|
health = base.Field('Health')
|
||||||
|
health_rollup = base.Field('HealthRollup')
|
||||||
|
|
||||||
|
|
||||||
|
class LogService(base.ResourceBase):
|
||||||
|
identity = base.Field('Id', required=True)
|
||||||
|
"""The log service identity string"""
|
||||||
|
|
||||||
|
description = base.Field('Description')
|
||||||
|
"""The log service description"""
|
||||||
|
|
||||||
|
name = base.Field('Name')
|
||||||
|
"""The log service name"""
|
||||||
|
|
||||||
|
status = StatusField("Status")
|
||||||
|
"""The log service status"""
|
||||||
|
|
||||||
|
service_enabled = base.Field("ServiceEnabled", adapter=bool)
|
||||||
|
"""This indicates whether this service is enabled"""
|
||||||
|
|
||||||
|
max_number_of_records = base.Field("MaxNumberOfRecords",
|
||||||
|
adapter=rsd_lib_utils.num_or_none)
|
||||||
|
"""The maximum number of log entries this service can have"""
|
||||||
|
|
||||||
|
overwrite_policy = base.Field("OverWritePolicy")
|
||||||
|
"""The overwrite policy for this service that
|
||||||
|
takes place when the log is full
|
||||||
|
"""
|
||||||
|
|
||||||
|
date_time = base.Field("DateTime")
|
||||||
|
"""The current DateTime (with offset) for the log
|
||||||
|
service, used to set or read time
|
||||||
|
"""
|
||||||
|
|
||||||
|
date_time_local_offset = base.Field("DateTimeLocalOffset")
|
||||||
|
"""The time offset from UTC that the DateTime
|
||||||
|
property is set to in format: +06:00
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, connector, identity, redfish_version=None):
|
||||||
|
"""A class representing a LogService
|
||||||
|
|
||||||
|
:param connector: A Connector instance
|
||||||
|
:param identity: The identity of the log service resource
|
||||||
|
:param redfish_version: The version of RedFish. Used to construct
|
||||||
|
the object according to schema of the given version.
|
||||||
|
"""
|
||||||
|
super(LogService, self).__init__(connector, identity, redfish_version)
|
||||||
|
|
||||||
|
def _get_entry_collection_path(self):
|
||||||
|
"""Helper function to find the LogEntryCollection path"""
|
||||||
|
return utils.get_sub_resource_path_by(self, 'Entries')
|
||||||
|
|
||||||
|
@property
|
||||||
|
@utils.cache_it
|
||||||
|
def log_entries(self):
|
||||||
|
"""Property to provide reference to `LogEntryCollection` instance
|
||||||
|
|
||||||
|
It is calculated once when it is queried for the first time. On
|
||||||
|
refresh, this property is reset.
|
||||||
|
"""
|
||||||
|
return log_entry.LogEntryCollection(
|
||||||
|
self._conn, self._get_entry_collection_path(),
|
||||||
|
redfish_version=self.redfish_version)
|
||||||
|
|
||||||
|
|
||||||
|
class LogServicesCollection(base.ResourceCollectionBase):
|
||||||
|
@property
|
||||||
|
def _resource_type(self):
|
||||||
|
return LogService
|
||||||
|
|
||||||
|
def __init__(self, connector, path, redfish_version=None):
|
||||||
|
"""A class representing a LogService Collection
|
||||||
|
|
||||||
|
:param connector: A Connector instance
|
||||||
|
:param path: The canonical path to the LogService Collection resource
|
||||||
|
:param redfish_version: The version of RedFish. Used to construct
|
||||||
|
the object according to schema of the given version.
|
||||||
|
"""
|
||||||
|
super(LogServicesCollection, self).__init__(connector,
|
||||||
|
path,
|
||||||
|
redfish_version)
|
@ -13,6 +13,12 @@
|
|||||||
"PartNumber": "part-number-as-string",
|
"PartNumber": "part-number-as-string",
|
||||||
"AssetTag": "FlexChassis1",
|
"AssetTag": "FlexChassis1",
|
||||||
"IndicatorLED": "Unknown",
|
"IndicatorLED": "Unknown",
|
||||||
|
"PowerState": "On",
|
||||||
|
"PhysicalSecurity": {
|
||||||
|
"IntrusionSensorNumber": 1,
|
||||||
|
"IntrusionSensor": 2,
|
||||||
|
"IntrusionSensorReArm": 3
|
||||||
|
},
|
||||||
"Status": {
|
"Status": {
|
||||||
"State": "Enabled",
|
"State": "Enabled",
|
||||||
"Health": "OK"
|
"Health": "OK"
|
||||||
@ -64,6 +70,26 @@
|
|||||||
"@odata.id": "/redfish/v1/Systems/system4"
|
"@odata.id": "/redfish/v1/Systems/system4"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"Drives": [
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Drives/1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Storage": [
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Storage/1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"CooledBy": [
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Cool/1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"PoweredBy": [
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Power/1"
|
||||||
|
}
|
||||||
|
],
|
||||||
"ManagedBy": [
|
"ManagedBy": [
|
||||||
{
|
{
|
||||||
"@odata.id": "/redfish/v1/Managers/RMM"
|
"@odata.id": "/redfish/v1/Managers/RMM"
|
||||||
|
@ -80,6 +80,21 @@ class TestChassis(base.TestCase):
|
|||||||
self.chassis_inst.oem.rack_supports_disaggregated_power_cooling)
|
self.chassis_inst.oem.rack_supports_disaggregated_power_cooling)
|
||||||
self.assertEqual('Unique ID', self.chassis_inst.oem.uuid)
|
self.assertEqual('Unique ID', self.chassis_inst.oem.uuid)
|
||||||
self.assertEqual('54.348103, 18.645172', self.chassis_inst.oem.geo_tag)
|
self.assertEqual('54.348103, 18.645172', self.chassis_inst.oem.geo_tag)
|
||||||
|
self.assertEqual('On', self.chassis_inst.power_state)
|
||||||
|
self.assertEqual(
|
||||||
|
1, self.chassis_inst.physical_security.intrusion_sensor_number)
|
||||||
|
self.assertEqual(
|
||||||
|
2, self.chassis_inst.physical_security.intrusion_sensor)
|
||||||
|
self.assertEqual(
|
||||||
|
3, self.chassis_inst.physical_security.intrusion_sensor_rearm)
|
||||||
|
self.assertEqual(('/redfish/v1/Drives/1',),
|
||||||
|
self.chassis_inst.links.drives)
|
||||||
|
self.assertEqual(('/redfish/v1/Storage/1',),
|
||||||
|
self.chassis_inst.links.storage)
|
||||||
|
self.assertEqual(('/redfish/v1/Cool/1',),
|
||||||
|
self.chassis_inst.links.cooled_by)
|
||||||
|
self.assertEqual(('/redfish/v1/Power/1',),
|
||||||
|
self.chassis_inst.links.powered_by)
|
||||||
|
|
||||||
def test__get_power_zone_collection_path(self):
|
def test__get_power_zone_collection_path(self):
|
||||||
expected = '/redfish/v1/Chassis/Rack1/PowerZones'
|
expected = '/redfish/v1/Chassis/Rack1/PowerZones'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user