예제 #1
0
class ResourceBlock(base.ResourceBase):

    composition_status = CompositionStatusField('CompositionStatus',
                                                required=True)
    """The composition state of resource block"""

    description = base.Field('Description')
    """The resource block description"""

    identity = base.Field('Id', required=True)
    """The resource block identity string"""

    name = base.Field('Name', required=True)
    """The resource block name"""

    resource_block_type = base.MappedField(
        'ResourceBlockType',
        res_maps.RESOURCE_BLOCK_TYPE_VALUE_MAP,
        required=True)
    """The type of resource block"""

    status = common.StatusField('Status')
    """The status of resource block"""
    def __init__(self, connector, identity, redfish_version=None):
        """A class representing a ResourceBlock

        :param connector: A Connector instance
        :param identity: The identity of the ResourceBlock resource
        :param redfish_version: The version of RedFish. Used to construct
            the object according to schema of given version.
        """
        super(ResourceBlock, self).__init__(connector, identity,
                                            redfish_version)
예제 #2
0
class StorageControllersListField(base.ListField):
    """The set of storage controllers represented by this resource."""

    member_id = base.Field('MemberId', required=True)
    """Uniquely identifies the member within the collection."""

    name = base.Field('Name', required=True)
    """The name of the storage controller"""

    status = common.StatusField('Status')
    """Describes the status and health of the resource and its children."""

    identifiers = common.IdentifiersListField('Identifiers', default=[])
    """The Durable names for the storage controller."""

    speed_gbps = base.Field('SpeedGbps')
    """The maximum speed of the storage controller's device interface."""

    controller_protocols = base.MappedListField(
        'SupportedControllerProtocols', res_maps.PROTOCOL_TYPE_VALUE_MAP)
    """The protocols by which this storage controller can be communicated to"""

    device_protocols = base.MappedListField('SupportedDeviceProtocols',
                                            res_maps.PROTOCOL_TYPE_VALUE_MAP)
    """The protocols which the controller can use tocommunicate with devices"""
예제 #3
0
class ResourceZone(base.ResourceBase):

    # Note(dnuka): This patch doesn't contain 100% of the ResourceZone

    description = base.Field('Description')
    """The resources zone description"""

    identity = base.Field('Id', required=True)
    """The resource zone identity string"""

    links = LinksField('Links')
    """The references to other resources that are related to this
    resource"""

    name = base.Field('Name', required=True)
    """The resource zone name"""

    status = common.StatusField('Status')
    """The resource zone status"""
    def __init__(self,
                 connector,
                 identity,
                 redfish_version=None,
                 registries=None):
        """A class representing a ResourceZone

        :param connector: A Connector instance
        :param identity: The identity of the ResourceZone resource
        :param redfish_version: The version of RedFish. Used to construct
            the object according to schema of given version.
        :param registries: Dict of Redfish Message Registry objects to be
            used in any resource that needs registries to parse messages
        """
        super(ResourceZone, self).__init__(connector, identity,
                                           redfish_version, registries)
예제 #4
0
파일: power.py 프로젝트: spranjali/sushy
class PowerSupplyListField(base.ListField):
    """The power supplies associated with this Power resource"""

    firmware_version = base.Field('FirmwareVersion')
    """The firmware version for this Power Supply"""

    identity = base.Field('MemberId')
    """Identifier of the Power Supply"""

    indicator_led = base.MappedField('IndicatorLed',
                                     res_maps.INDICATOR_LED_VALUE_MAP)
    """The state of the indicator LED, used to identify the power supply"""

    input_ranges = InputRangeListField('InputRanges', default=[])
    """This is the input ranges that the power supply can use"""

    last_power_output_watts = base.Field('LastPowerOutputWatts',
                                         adapter=utils.int_or_none)
    """The average power output of this Power Supply"""

    line_input_voltage = base.Field('LineInputVoltage',
                                    adapter=utils.int_or_none)
    """The line input voltage at which the Power Supply is operating"""

    line_input_voltage_type = base.MappedField(
        'LineInputVoltageType',
        pow_maps.LINE_INPUT_VOLTAGE_TYPE_MAP)
    """The line voltage type supported as an input to this Power Supply"""

    manufacturer = base.Field('Manufacturer')
    """This is the manufacturer of this power supply"""

    model = base.Field('Model')
    """The model number for this Power Supply"""

    name = base.Field('Name')
    """Name of the Power Supply"""

    part_number = base.Field('PartNumber')
    """The part number for this Power Supply"""

    power_capacity_watts = base.Field('PowerCapacityWatts',
                                      adapter=utils.int_or_none)
    """The maximum capacity of this Power Supply"""

    power_supply_type = base.MappedField('PowerSupplyType',
                                         pow_maps.POWER_SUPPLY_TYPE_MAP)
    """The Power Supply type (AC or DC)"""

    serial_number = base.Field('SerialNumber')
    """The serial number for this Power Supply"""

    spare_part_number = base.Field('SparePartNumber')
    """The spare part number for this Power Supply"""

    status = common.StatusField('Status')
    """Status of the sensor"""
예제 #5
0
class DeviceListField(base.ListField):
    """The storage device/s associated with SimpleStorage."""

    name = base.Field('Name', required=True)
    """The name of the storage device"""

    capacity_bytes = base.Field('CapacityBytes', adapter=utils.int_or_none)
    """The size of the storage device."""

    status = common.StatusField('Status')
    """Describes the status and health of a storage device."""
예제 #6
0
class SoftwareInventory(base.ResourceBase):

    identity = base.Field('Id', required=True)
    """The software inventory identity"""

    lowest_supported_version = base.Field('LowestSupportedVersion')
    """The lowest supported version of the software"""

    manufacturer = base.Field('Manufacturer')
    """The manufacturer of the software"""

    name = base.Field('Name', required=True)
    """The software inventory name"""

    release_date = base.Field('ReleaseDate')
    """Release date of the software"""

    related_item = base.Field('RelatedItem')
    """The ID(s) of the resources associated with the software inventory
    item"""

    status = common.StatusField('Status')
    """The status of the software inventory"""

    software_id = base.Field('SoftwareId')
    """The identity of the software"""

    uefi_device_paths = base.Field('UefiDevicePaths')
    """Represents the UEFI Device Path(s)"""

    updateable = base.Field('Updateable')
    """Indicates whether this software can be updated by the update
    service"""

    version = base.Field('Version')
    """The version of the software"""
    def __init__(self,
                 connector,
                 identity,
                 redfish_version=None,
                 registries=None):
        """A class representing a SoftwareInventory

        :param connector: A Connector instance
        :param identity: The identity of the SoftwareInventory resources
        :param redfish_version: The version of RedFish. Used to construct
            the object according to schema of given version.
        :param registries: Dict of Redfish Message Registry objects to be
            used in any resource that needs registries to parse messages
        """
        super(SoftwareInventory, self).__init__(connector, identity,
                                                redfish_version, registries)
예제 #7
0
class Processor(base.ResourceBase):

    identity = base.Field('Id', required=True)
    """The processor identity string"""

    socket = base.Field('Socket')
    """The socket or location of the processor"""

    # TODO(deray): Create mappings for the processor_type
    processor_type = base.Field('ProcessorType')
    """The type of processor"""

    processor_architecture = base.MappedField(
        'ProcessorArchitecture', sys_maps.PROCESSOR_ARCH_VALUE_MAP)
    """The architecture of the processor"""

    # TODO(deray): Create mappings for the instruction_set
    instruction_set = base.Field('InstructionSet')
    """The instruction set of the processor"""

    manufacturer = base.Field('Manufacturer')
    """The processor manufacturer"""

    model = base.Field('Model')
    """The product model number of this device"""

    max_speed_mhz = base.Field('MaxSpeedMHz', adapter=utils.int_or_none)
    """The maximum clock speed of the processor in MHz."""

    processor_id = ProcessorIdField('ProcessorId')
    """The processor id"""

    status = common.StatusField('Status')
    """The processor status"""

    total_cores = base.Field('TotalCores', adapter=utils.int_or_none)
    """The total number of cores contained in this processor"""

    total_threads = base.Field('TotalThreads', adapter=utils.int_or_none)
    """The total number of execution threads supported by this processor"""

    def __init__(self, connector, identity, redfish_version=None):
        """A class representing a Processor

        :param connector: A Connector instance
        :param identity: The identity of the processor
        :param redfish_version: The version of RedFish. Used to construct
            the object according to schema of the given version.
        """
        super(Processor, self).__init__(connector, identity, redfish_version)
예제 #8
0
class TaskService(base.ResourceBase):

    identity = base.Field('Id', required=True)
    """The task service identity"""

    name = base.Field('Name', required=True)
    """The task service name"""

    service_enabled = base.Field('ServiceEnabled')
    """The status of whether this service is enabled"""

    status = common.StatusField('Status')
    """The status of the task service"""

    overwrite_policy = base.MappedField(
        'CompletedTaskOverWritePolicy', ts_maps.OVERWRITE_POLICY_VALUE_MAP)
    """The overwrite policy for completed tasks"""

    event_on_task_state_change = base.Field(
        'LifeCycleEventOnTaskStateChange', adapter=bool)
    """Whether a task state change sends an event"""

    def __init__(self, connector, identity, redfish_version=None,
                 registries=None):
        """A class representing a TaskService

        :param connector: A Connector instance
        :param identity: The identity of the TaskService resource
        :param redfish_version: The version of RedFish. Used to construct
            the object according to schema of given version
        :param registries: Dict of Redfish Message Registry objects to be
            used in any resource that needs registries to parse messages
        """
        super(TaskService, self).__init__(
            connector, identity, redfish_version, registries)

    @property
    @utils.cache_it
    def tasks(self):
        """Property to reference `TaskCollection` instance

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done).
        Here the actual refresh of the sub-resource happens, if stale.
        """
        return task.TaskCollection(
            self._conn, utils.get_sub_resource_path_by(self, 'Tasks'),
            redfish_version=self.redfish_version,
            registries=self.registries)
예제 #9
0
파일: fabric.py 프로젝트: spranjali/sushy
class Fabric(base.ResourceBase):
    """Fabric resource

    The Fabric represents a simple fabric consisting of one or more
    switches, zero or more endpoints, and zero or more zones.
    """

    identity = base.Field('Id', required=True)
    """Identifier for the fabric"""

    name = base.Field('Name', required=True)
    """The fabric name"""

    description = base.Field('Description')
    """The fabric description"""

    max_zones = base.Field('MaxZones', adapter=utils.int_or_none)
    """The maximum number of zones the switch can currently configure"""

    status = common.StatusField('Status')
    """The fabric status"""

    fabric_type = base.MappedField('FabricType',
                                   res_maps.PROTOCOL_TYPE_VALUE_MAP)
    """The protocol being sent over this fabric"""
    def __init__(self,
                 connector,
                 identity,
                 redfish_version=None,
                 registries=None):
        """A class representing a Fabric

        :param connector: A Connector instance
        :param identity: The identity of the Fabric resource
        :param redfish_version: The version of RedFish. Used to construct
            the object according to schema of the given version.
        :param registries: Dict of Redfish Message Registry objects to be
            used in any resource that needs registries to parse messages
        """
        super(Fabric, self).__init__(connector, identity, redfish_version,
                                     registries)

    @property
    @utils.cache_it
    def endpoints(self):
        return fab_endpoint.EndpointCollection(
            self._conn, utils.get_sub_resource_path_by(self, 'Endpoints'),
            self.redfish_version, self.registries)
예제 #10
0
class Thermal(base.ResourceBase):
    """This class represents a Thermal resource."""

    identity = base.Field('Id')
    """Identifier of the resource"""

    name = base.Field('Name')
    """The name of the resource"""

    status = common.StatusField('Status')
    """Status of the resource"""

    fans = FansListField('Fans', default=[])
    """A tuple of Fan identities"""

    temperatures = TemperaturesListField('Temperatures', default=[])
    """A tuple of Temperature identities"""
예제 #11
0
class Endpoint(base.ResourceBase):
    """This class represents a fabric endpoint.

    It represents the properties of an entity that sends or receives protocol
    defined messages over a transport.
    """

    identity = base.Field('Id', required=True)
    """Identifier for the endpoint"""

    name = base.Field('Name', required=True)
    """The endpoint name"""

    description = base.Field('Description')
    """The endpoint description"""

    status = common.StatusField('Status')
    """The endpoint status"""

    host_reservation_memory_bytes = base.Field('HostReservationMemoryBytes',
                                               adapter=utils.int_or_none)
    """The amount of memory in Bytes that the Host should allocate to connect
    to this endpoint.
    """

    endpoint_protocol = base.MappedField('EndpointProtocol',
                                         res_maps.PROTOCOL_TYPE_VALUE_MAP)
    """The protocol supported by this endpoint."""

    pci_id = PciIdField('PciId')
    """The PCI ID of the endpoint."""

    IP_transport_details = IPTransportDetailsListField('IPTransportDetails')
    """This array contains details for each IP transport supported by this
    endpoint. The array structure can be used to model multiple IP addresses
    for this endpoint."""

    connected_entities = ConnectedEntitiesListField('ConnectedEntities')
    """All entities connected to this endpoint."""
예제 #12
0
class Sensor(base.ListField):
    """The sensor device/s associated with Thermal."""

    identity = base.Field('MemberId', required=True)
    """Identifier of the Sensor"""

    lower_threshold_critical = base.Field('LowerThresholdCritical',
                                          adapter=utils.int_or_none)
    """Below normal range but not yet fatal"""

    lower_threshold_fatal = base.Field('LowerThresholdFatal',
                                       adapter=utils.int_or_none)
    """Below normal range and is fatal"""

    lower_threshold_non_critical = base.Field('LowerThresholdNonCritical',
                                              adapter=utils.int_or_none)
    """Below normal range"""

    name = base.Field('Name')
    """The name of this sensor"""

    physical_context = base.Field('PhysicalContext')
    """Area or device associated with this sensor"""

    status = common.StatusField('Status')
    """Status of the sensor"""

    upper_threshold_critical = base.Field('UpperThresholdCritical',
                                          adapter=utils.int_or_none)
    """Above normal range but not yet fatal"""

    upper_threshold_fatal = base.Field('UpperThresholdFatal',
                                       adapter=utils.int_or_none)
    """Above normal range and is fatal"""

    upper_threshold_non_critical = base.Field('UpperThresholdNonCritical',
                                              adapter=utils.int_or_none)
    """Above normal range"""
예제 #13
0
class EthernetInterface(base.ResourceBase):
    """This class adds the EthernetInterface resource"""

    identity = base.Field('Id', required=True)
    """The Ethernet Interface identity string"""

    name = base.Field('Name')
    """The name of the resource or array element"""

    description = base.Field('Description')
    """Description"""

    permanent_mac_address = base.Field('PermanentMACAddress')
    """This is the permanent MAC address assigned to this interface (port) """

    mac_address = base.Field('MACAddress')
    """This is the currently configured MAC address of the interface."""

    speed_mbps = base.Field('SpeedMbps')
    """This is the current speed in Mbps of this interface."""

    status = common.StatusField("Status")
    """Describes the status and health of this interface."""
예제 #14
0
class Chassis(base.ResourceBase):
    """Chassis resource

    The Chassis represents the physical components of a system. This
    resource represents the sheet-metal confined spaces and logical zones
    such as racks, enclosures, chassis and all other containers.
    """

    chassis_type = base.MappedField('ChassisType',
                                    cha_maps.CHASSIS_TYPE_VALUE_MAP,
                                    required=True)
    """The type of physical form factor of the chassis"""

    identity = base.Field('Id', required=True)
    """Identifier for the chassis"""

    name = base.Field('Name', required=True)
    """The chassis name"""

    asset_tag = base.Field('AssetTag')
    """The user assigned asset tag of this chassis"""

    depth_mm = base.Field('DepthMm')
    """Depth in millimeters
    The depth of the chassis. The value of this property shall represent
    the depth (length) of the chassis (in millimeters) as specified by the
    manufacturer.
    """

    description = base.Field('Description')
    """The chassis description"""

    height_mm = base.Field('HeightMm')
    """Height in millimeters
    The height of the chassis. The value of this property shall represent
    the height of the chassis (in millimeters) as specified by the
    manufacturer.
    """

    indicator_led = base.MappedField('IndicatorLED',
                                     res_maps.INDICATOR_LED_VALUE_MAP)
    """The state of the indicator LED, used to identify the chassis"""

    manufacturer = base.Field('Manufacturer')
    """The manufacturer of this chassis"""

    model = base.Field('Model')
    """The model number of the chassis"""

    part_number = base.Field('PartNumber')
    """The part number of the chassis"""

    physical_security = PhysicalSecurity('PhysicalSecurity')
    """PhysicalSecurity
    This value of this property shall contain the sensor state of the physical
    security.
    """

    power_state = base.MappedField('PowerState',
                                   res_maps.POWER_STATE_VALUE_MAP)
    """The current power state of the chassis"""

    serial_number = base.Field('SerialNumber')
    """The serial number of the chassis"""

    sku = base.Field('SKU')
    """Stock-keeping unit number (SKU)
    The value of this property shall be the stock-keeping unit number for
    this chassis.
    """

    status = common.StatusField('Status')
    """Status and Health
    This property describes the status and health of the chassis and its
    children.
    """

    uuid = base.Field('UUID')
    """The Universal Unique Identifier (UUID) for this Chassis."""

    weight_kg = base.Field('WeightKg')
    """Weight in kilograms
    The value of this property shall represent the published mass (commonly
    referred to as weight) of the chassis (in kilograms).
    """

    width_mm = base.Field('WidthMm')
    """Width in millimeters
    The value of this property shall represent the width of the chassis
    (in millimeters) as specified by the manufacturer.
    """

    _actions = ActionsField('Actions')

    def __init__(self,
                 connector,
                 identity,
                 redfish_version=None,
                 registries=None):
        """A class representing a Chassis

        :param connector: A Connector instance
        :param identity: The identity of the Chassis resource
        :param redfish_version: The version of RedFish. Used to construct
            the object according to schema of the given version.
        :param registries: Dict of Redfish Message Registry objects to be
            used in any resource that needs registries to parse messages
        """
        super(Chassis, self).__init__(connector, identity, redfish_version,
                                      registries)

    def _get_reset_action_element(self):
        reset_action = self._actions.reset

        if not reset_action:
            raise exceptions.MissingActionError(action='#Chassis.Reset',
                                                resource=self._path)
        return reset_action

    def get_allowed_reset_chassis_values(self):
        """Get the allowed values for resetting the chassis.

        :returns: A set of allowed values.
        :raises: MissingAttributeError, if Actions/#Chassis.Reset attribute
            not present.
        """
        reset_action = self._get_reset_action_element()

        if not reset_action.allowed_values:
            LOG.warning(
                'Could not figure out the allowed values for the '
                'reset chassis action for Chassis %s', self.identity)
            return set(res_maps.RESET_TYPE_VALUE_MAP_REV)

        return set([
            res_maps.RESET_TYPE_VALUE_MAP[v]
            for v in set(res_maps.RESET_TYPE_VALUE_MAP).intersection(
                reset_action.allowed_values)
        ])

    def reset_chassis(self, value):
        """Reset the chassis.

        :param value: The target value.
        :raises: InvalidParameterValueError, if the target value is not
            allowed.
        """
        valid_resets = self.get_allowed_reset_chassis_values()
        if value not in valid_resets:
            raise exceptions.InvalidParameterValueError(
                parameter='value', value=value, valid_values=valid_resets)

        value = res_maps.RESET_TYPE_VALUE_MAP_REV[value]
        target_uri = self._get_reset_action_element().target_uri

        LOG.debug('Resetting the Chassis %s ...', self.identity)
        self._conn.post(target_uri, data={'ResetType': value})
        LOG.info('The Chassis %s is being reset', self.identity)

    def set_indicator_led(self, state):
        """Set IndicatorLED to the given state.

        :param state: Desired LED state, lit (INDICATOR_LED_LIT), blinking
            (INDICATOR_LED_BLINKING), off (INDICATOR_LED_OFF)
        :raises: InvalidParameterValueError, if any information passed is
            invalid.
        """
        if state not in res_maps.INDICATOR_LED_VALUE_MAP_REV:
            raise exceptions.InvalidParameterValueError(
                parameter='state',
                value=state,
                valid_values=list(res_maps.INDICATOR_LED_VALUE_MAP_REV))

        data = {'IndicatorLED': res_maps.INDICATOR_LED_VALUE_MAP_REV[state]}

        self._conn.patch(self.path, data=data)
        self.invalidate()

    @property
    @utils.cache_it
    def managers(self):
        """A list of managers for this chassis.

        Returns a list of `Manager` objects representing the managers
        that manage this chassis.

        :raises: MissingAttributeError if '@odata.id' field is missing.
        :returns: A list of `Manager` instances
        """
        paths = utils.get_sub_resource_path_by(self, ["Links", "ManagedBy"],
                                               is_collection=True)

        return [
            manager.Manager(self._conn, path, self.redfish_version,
                            self.registries) for path in paths
        ]

    @property
    @utils.cache_it
    def systems(self):
        """A list of systems residing in this chassis.

        Returns a list of `System` objects representing systems being
        mounted in this chassis/cabinet.

        :raises: MissingAttributeError if '@odata.id' field is missing.
        :returns: A list of `System` instances
        """
        paths = utils.get_sub_resource_path_by(self,
                                               ["Links", "ComputerSystems"],
                                               is_collection=True)

        from sushy.resources.system import system
        return [
            system.System(self._conn, path, self.redfish_version,
                          self.registries) for path in paths
        ]

    @property
    @utils.cache_it
    def power(self):
        """Property to reference `Power` instance

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done).
        Here the actual refresh of the sub-resource happens, if stale.
        """
        return power.Power(self._conn,
                           utils.get_sub_resource_path_by(self, 'Power'),
                           self.redfish_version, self.registries)

    @property
    @utils.cache_it
    def thermal(self):
        """Property to reference `Thermal` instance

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done).
        Here the actual refresh of the sub-resource happens, if stale.
        """
        return thermal.Thermal(self._conn,
                               utils.get_sub_resource_path_by(self, 'Thermal'),
                               self.redfish_version, self.registries)
예제 #15
0
class Drive(base.ResourceBase):
    """This class represents a disk drive or other physical storage medium."""

    block_size_bytes = base.Field('BlockSizeBytes', adapter=utils.int_or_none)
    """The size of the smallest addressable unit of this drive in bytes"""

    capacity_bytes = base.Field('CapacityBytes', adapter=utils.int_or_none)
    """The size in bytes of this Drive"""

    identifiers = common.IdentifiersListField('Identifiers', default=[])
    """The Durable names for the drive"""

    identity = base.Field('Id', required=True)
    """The Drive identity string"""

    indicator_led = base.MappedField('IndicatorLED',
                                     res_maps.INDICATOR_LED_VALUE_MAP)
    """Whether the indicator LED is lit or off"""

    manufacturer = base.Field('Manufacturer')
    """This is the manufacturer of this drive"""

    media_type = base.Field('MediaType')
    """The type of media contained in this drive"""

    model = base.Field('Model')
    """This is the model number for the drive"""

    name = base.Field('Name')
    """The name of the resource"""

    part_number = base.Field('PartNumber')
    """The part number for this drive"""

    protocol = base.MappedField('Protocol', res_maps.PROTOCOL_TYPE_VALUE_MAP)
    """Protocol this drive is using to communicate to the storage controller"""

    serial_number = base.Field('SerialNumber')
    """The serial number for this drive"""

    status = common.StatusField('Status')
    """This type describes the status and health of the drive"""

    def set_indicator_led(self, state):
        """Set IndicatorLED to the given state.

        :param state: Desired LED state, lit (INDICATOR_LED_LIT), blinking
            (INDICATOR_LED_BLINKING), off (INDICATOR_LED_OFF)
        :raises: InvalidParameterValueError, if any information passed is
            invalid.
        """
        if state not in res_maps.INDICATOR_LED_VALUE_MAP_REV:
            raise exceptions.InvalidParameterValueError(
                parameter='state', value=state,
                valid_values=list(res_maps.INDICATOR_LED_VALUE_MAP_REV))

        data = {
            'IndicatorLED': res_maps.INDICATOR_LED_VALUE_MAP_REV[state]
        }

        self._conn.patch(self.path, data=data)
        self.invalidate()
예제 #16
0
class System(base.ResourceBase):

    asset_tag = base.Field('AssetTag')
    """The system asset tag"""

    bios_version = base.Field('BiosVersion')
    """The system BIOS version"""

    boot = BootField('Boot', required=True)
    """A dictionary containing the current boot device, frequency and mode"""

    description = base.Field('Description')
    """The system description"""

    hostname = base.Field('HostName')
    """The system hostname"""

    identity = base.Field('Id', required=True)
    """The system identity string"""

    indicator_led = base.MappedField('IndicatorLED',
                                     res_maps.INDICATOR_LED_VALUE_MAP)
    """Whether the indicator LED is lit or off"""

    manufacturer = base.Field('Manufacturer')
    """The system manufacturer"""

    name = base.Field('Name')
    """The system name"""

    part_number = base.Field('PartNumber')
    """The system part number"""

    power_state = base.MappedField('PowerState',
                                   res_maps.POWER_STATE_VALUE_MAP)
    """The system power state"""

    serial_number = base.Field('SerialNumber')
    """The system serial number"""

    sku = base.Field('SKU')
    """The system stock-keeping unit"""

    status = common.StatusField('Status')
    """The system status"""

    system_type = base.MappedField('SystemType',
                                   sys_maps.SYSTEM_TYPE_VALUE_MAP)
    """The system type"""

    uuid = base.Field('UUID')
    """The system UUID"""

    memory_summary = MemorySummaryField('MemorySummary')
    """The summary info of memory of the system in general detail"""

    maintenance_window = settings.MaintenanceWindowField(
        '@Redfish.MaintenanceWindow')
    """Indicates if a given resource has a maintenance window assignment
    for applying settings or operations"""

    _actions = ActionsField('Actions', required=True)

    def __init__(self,
                 connector,
                 identity,
                 redfish_version=None,
                 registries=None):
        """A class representing a ComputerSystem

        :param connector: A Connector instance
        :param identity: The identity of the System resource
        :param redfish_version: The version of RedFish. Used to construct
            the object according to schema of the given version.
        :param registries: Dict of registries to be used in any resource
            that needs registries to parse messages.
        """
        super(System, self).__init__(connector, identity, redfish_version,
                                     registries)

    def _get_reset_action_element(self):
        reset_action = self._actions.reset
        # TODO(dtantsur): make this check also declarative?
        if not reset_action:
            raise exceptions.MissingActionError(action='#ComputerSystem.Reset',
                                                resource=self._path)
        return reset_action

    def get_allowed_reset_system_values(self):
        """Get the allowed values for resetting the system.

        :returns: A set with the allowed values.
        """
        reset_action = self._get_reset_action_element()

        if not reset_action.allowed_values:
            LOG.warning(
                'Could not figure out the allowed values for the '
                'reset system action for System %s', self.identity)
            return set(sys_maps.RESET_SYSTEM_VALUE_MAP_REV)

        return set([
            sys_maps.RESET_SYSTEM_VALUE_MAP[v]
            for v in set(sys_maps.RESET_SYSTEM_VALUE_MAP).intersection(
                reset_action.allowed_values)
        ])

    def reset_system(self, value):
        """Reset the system.

        :param value: The target value.
        :raises: InvalidParameterValueError, if the target value is not
            allowed.
        """
        valid_resets = self.get_allowed_reset_system_values()
        if value not in valid_resets:
            raise exceptions.InvalidParameterValueError(
                parameter='value', value=value, valid_values=valid_resets)

        value = sys_maps.RESET_SYSTEM_VALUE_MAP_REV[value]
        target_uri = self._get_reset_action_element().target_uri

        # TODO(lucasagomes): Check the return code and response body ?
        #                    Probably we should call refresh() as well.
        self._conn.post(target_uri, data={'ResetType': value})

    def get_allowed_system_boot_source_values(self):
        """Get the allowed values for changing the boot source.

        :returns: A set with the allowed values.
        """
        if not self.boot.allowed_values:
            LOG.warning(
                'Could not figure out the allowed values for '
                'configuring the boot source for System %s', self.identity)
            return set(sys_maps.BOOT_SOURCE_TARGET_MAP_REV)

        return set([
            sys_maps.BOOT_SOURCE_TARGET_MAP[v]
            for v in set(sys_maps.BOOT_SOURCE_TARGET_MAP).intersection(
                self.boot.allowed_values)
        ])

    def set_system_boot_options(self, target=None, enabled=None, mode=None):
        """Set boot source and/or boot frequency and/or boot mode.

        Set the boot source and/or boot frequency and/or boot mode to use
        on next reboot of the System.

        :param target: The target boot source, optional.
        :param enabled: The frequency, whether to set it for the next
            reboot only (BOOT_SOURCE_ENABLED_ONCE) or persistent to all
            future reboots (BOOT_SOURCE_ENABLED_CONTINUOUS) or disabled
            (BOOT_SOURCE_ENABLED_DISABLED), optional.
        :param mode: The boot mode (UEFI: BOOT_SOURCE_MODE_UEFI or
            BIOS: BOOT_SOURCE_MODE_BIOS), optional.
        :raises: InvalidParameterValueError, if any information passed is
            invalid.
        """
        data = collections.defaultdict(dict)

        if target is not None:
            valid_targets = self.get_allowed_system_boot_source_values()
            if target not in valid_targets:
                raise exceptions.InvalidParameterValueError(
                    parameter='target',
                    value=target,
                    valid_values=valid_targets)

            fishy_target = sys_maps.BOOT_SOURCE_TARGET_MAP_REV[target]

            data['Boot']['BootSourceOverrideTarget'] = fishy_target

        if enabled is not None:
            if enabled not in sys_maps.BOOT_SOURCE_ENABLED_MAP_REV:
                raise exceptions.InvalidParameterValueError(
                    parameter='enabled',
                    value=enabled,
                    valid_values=list(sys_maps.BOOT_SOURCE_ENABLED_MAP_REV))

            fishy_freq = sys_maps.BOOT_SOURCE_ENABLED_MAP_REV[enabled]

            data['Boot']['BootSourceOverrideEnabled'] = fishy_freq

        if mode is not None:
            if mode not in sys_maps.BOOT_SOURCE_MODE_MAP_REV:
                raise exceptions.InvalidParameterValueError(
                    parameter='mode',
                    value=mode,
                    valid_values=list(sys_maps.BOOT_SOURCE_MODE_MAP_REV))

            fishy_mode = sys_maps.BOOT_SOURCE_MODE_MAP_REV[mode]

            data['Boot']['BootSourceOverrideMode'] = fishy_mode

        # TODO(lucasagomes): Check the return code and response body ?
        #                    Probably we should call refresh() as well.
        self._conn.patch(self.path, data=data)

    # TODO(etingof): we should remove this method, eventually
    def set_system_boot_source(self,
                               target,
                               enabled=sys_cons.BOOT_SOURCE_ENABLED_ONCE,
                               mode=None):
        """Set boot source and/or boot frequency and/or boot mode.

        Set the boot source and/or boot frequency and/or boot mode to use
        on next reboot of the System.

        This method is obsoleted by `set_system_boot_options`.

        :param target: The target boot source.
        :param enabled: The frequency, whether to set it for the next
            reboot only (BOOT_SOURCE_ENABLED_ONCE) or persistent to all
            future reboots (BOOT_SOURCE_ENABLED_CONTINUOUS) or disabled
            (BOOT_SOURCE_ENABLED_DISABLED).
            Default is `BOOT_SOURCE_ENABLED_ONCE`.
        :param mode: The boot mode (UEFI: BOOT_SOURCE_MODE_UEFI or
            BIOS: BOOT_SOURCE_MODE_BIOS), optional.
        :raises: InvalidParameterValueError, if any information passed is
            invalid.
        """
        self.set_system_boot_options(target, enabled, mode)

    def set_indicator_led(self, state):
        """Set IndicatorLED to the given state.

        :param state: Desired LED state, lit (INDICATOR_LED_LIT), blinking
            (INDICATOR_LED_BLINKING), off (INDICATOR_LED_OFF)
        :raises: InvalidParameterValueError, if any information passed is
            invalid.
        """
        if state not in res_maps.INDICATOR_LED_VALUE_MAP_REV:
            raise exceptions.InvalidParameterValueError(
                parameter='state',
                value=state,
                valid_values=list(res_maps.INDICATOR_LED_VALUE_MAP_REV))

        data = {'IndicatorLED': res_maps.INDICATOR_LED_VALUE_MAP_REV[state]}

        self._conn.patch(self.path, data=data)
        self.invalidate()

    def _get_processor_collection_path(self):
        """Helper function to find the ProcessorCollection path"""
        return utils.get_sub_resource_path_by(self, 'Processors')

    @property
    @utils.cache_it
    def processors(self):
        """Property to reference `ProcessorCollection` instance

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done).
        Here the actual refresh of the sub-resource happens, if stale.
        """
        return processor.ProcessorCollection(
            self._conn,
            self._get_processor_collection_path(),
            redfish_version=self.redfish_version,
            registries=self.registries)

    @property
    @utils.cache_it
    def ethernet_interfaces(self):
        """Property to reference `EthernetInterfaceCollection` instance

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done).
        Here the actual refresh of the sub-resource happens, if stale.
        """
        return ethernet_interface.EthernetInterfaceCollection(
            self._conn,
            utils.get_sub_resource_path_by(self, "EthernetInterfaces"),
            redfish_version=self.redfish_version,
            registries=self.registries)

    @property
    @utils.cache_it
    def bios(self):
        """Property to reference `Bios` instance

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done).
        Here the actual refresh of the sub-resource happens, if stale.
        """
        return bios.Bios(self._conn,
                         utils.get_sub_resource_path_by(self, 'Bios'),
                         redfish_version=self.redfish_version,
                         registries=self.registries)

    @property
    @utils.cache_it
    def simple_storage(self):
        """A collection of simple storage associated with system.

        This returns a reference to `SimpleStorageCollection` instance.
        SimpleStorage represents the properties of a storage controller and its
        directly-attached devices.

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done).
        Here the actual refresh of the sub-resource happens, if stale.

        :raises: MissingAttributeError if 'SimpleStorage/@odata.id' field
            is missing.
        :returns: `SimpleStorageCollection` instance
        """
        return sys_simple_storage.SimpleStorageCollection(
            self._conn,
            utils.get_sub_resource_path_by(self, "SimpleStorage"),
            redfish_version=self.redfish_version,
            registries=self.registries)

    @property
    @utils.cache_it
    def storage(self):
        """A collection of storage subsystems associated with system.

        This returns a reference to `StorageCollection` instance.
        A storage subsystem represents a set of storage controllers (physical
        or virtual) and the resources such as drives and volumes that can be
        accessed from that subsystem.

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done).
        Here the actual refresh of the sub-resource happens, if stale.

        :raises: MissingAttributeError if 'Storage/@odata.id' field
            is missing.
        :returns: `StorageCollection` instance
        """
        return sys_storage.StorageCollection(
            self._conn,
            utils.get_sub_resource_path_by(self, "Storage"),
            redfish_version=self.redfish_version,
            registries=self.registries)

    @property
    @utils.cache_it
    def managers(self):
        """A list of managers for this system.

        Returns a list of `Manager` objects representing the managers
        that manage this system.

        :raises: MissingAttributeError if '@odata.id' field is missing.
        :returns: A list of `Manager` instances
        """
        paths = utils.get_sub_resource_path_by(self, ["Links", "ManagedBy"],
                                               is_collection=True)

        return [
            manager.Manager(self._conn,
                            path,
                            redfish_version=self.redfish_version,
                            registries=self.registries) for path in paths
        ]

    @property
    @utils.cache_it
    def chassis(self):
        """A list of chassis where this system resides.

        Returns a list of `Chassis` objects representing the chassis
        or cabinets where this system is mounted.

        :raises: MissingAttributeError if '@odata.id' field is missing.
        :returns: A list of `Chassis` instances
        """
        paths = utils.get_sub_resource_path_by(self, ["Links", "Chassis"],
                                               is_collection=True)

        return [
            chassis.Chassis(self._conn,
                            path,
                            redfish_version=self.redfish_version,
                            registries=self.registries) for path in paths
        ]
예제 #17
0
class System(base.ResourceBase):

    asset_tag = base.Field('AssetTag')
    """The system asset tag"""

    bios_version = base.Field('BiosVersion')
    """The system BIOS version"""

    boot = BootField('Boot', required=True)
    """A dictionary containg the current boot device, frequency and mode"""

    description = base.Field('Description')
    """The system description"""

    hostname = base.Field('HostName')
    """The system hostname"""

    identity = base.Field('Id', required=True)
    """The system identity string"""

    indicator_led = base.MappedField('IndicatorLED',
                                     sys_maps.SYSTEM_INDICATOR_LED_MAP)
    """Whether the indicator LED is lit or off"""

    manufacturer = base.Field('Manufacturer')
    """The system manufacturer"""

    name = base.Field('Name')
    """The system name"""

    part_number = base.Field('PartNumber')
    """The system part number"""

    power_state = base.MappedField('PowerState',
                                   sys_maps.SYSTEM_POWER_STATE_MAP)
    """The system power state"""

    serial_number = base.Field('SerialNumber')
    """The system serial number"""

    sku = base.Field('SKU')
    """The system stock-keeping unit"""

    status = common.StatusField('Status')
    """The system status"""

    # TODO(lucasagomes): Create mappings for the system_type
    system_type = base.Field('SystemType')
    """The system type"""

    uuid = base.Field('UUID')
    """The system UUID"""

    memory_summary = MemorySummaryField('MemorySummary')
    """The summary info of memory of the system in general detail"""

    _actions = ActionsField('Actions', required=True)

    def __init__(self, connector, identity, redfish_version=None):
        """A class representing a ComputerSystem

        :param connector: A Connector instance
        :param identity: The identity of the System resource
        :param redfish_version: The version of RedFish. Used to construct
            the object according to schema of the given version.
        """
        super(System, self).__init__(connector, identity, redfish_version)

    def _get_reset_action_element(self):
        reset_action = self._actions.reset
        # TODO(dtantsur): make this check also declarative?
        if not reset_action:
            raise exceptions.MissingActionError(action='#ComputerSystem.Reset',
                                                resource=self._path)
        return reset_action

    def get_allowed_reset_system_values(self):
        """Get the allowed values for resetting the system.

        :returns: A set with the allowed values.
        """
        reset_action = self._get_reset_action_element()

        if not reset_action.allowed_values:
            LOG.warning(
                'Could not figure out the allowed values for the '
                'reset system action for System %s', self.identity)
            return set(sys_maps.RESET_SYSTEM_VALUE_MAP_REV)

        return set([
            sys_maps.RESET_SYSTEM_VALUE_MAP[v]
            for v in set(sys_maps.RESET_SYSTEM_VALUE_MAP).intersection(
                reset_action.allowed_values)
        ])

    def reset_system(self, value):
        """Reset the system.

        :param value: The target value.
        :raises: InvalidParameterValueError, if the target value is not
            allowed.
        """
        valid_resets = self.get_allowed_reset_system_values()
        if value not in valid_resets:
            raise exceptions.InvalidParameterValueError(
                parameter='value', value=value, valid_values=valid_resets)

        value = sys_maps.RESET_SYSTEM_VALUE_MAP_REV[value]
        target_uri = self._get_reset_action_element().target_uri

        # TODO(lucasagomes): Check the return code and response body ?
        #                    Probably we should call refresh() as well.
        self._conn.post(target_uri, data={'ResetType': value})

    def get_allowed_system_boot_source_values(self):
        """Get the allowed values for changing the boot source.

        :returns: A set with the allowed values.
        """
        if not self.boot.allowed_values:
            LOG.warning(
                'Could not figure out the allowed values for '
                'configuring the boot source for System %s', self.identity)
            return set(sys_maps.BOOT_SOURCE_TARGET_MAP_REV)

        return set([
            sys_maps.BOOT_SOURCE_TARGET_MAP[v]
            for v in set(sys_maps.BOOT_SOURCE_TARGET_MAP).intersection(
                self.boot.allowed_values)
        ])

    def set_system_boot_source(self,
                               target,
                               enabled=sys_cons.BOOT_SOURCE_ENABLED_ONCE,
                               mode=None):
        """Set the boot source.

        Set the boot source to use on next reboot of the System.

        :param target: The target boot source.
        :param enabled: The frequency, whether to set it for the next
            reboot only (BOOT_SOURCE_ENABLED_ONCE) or persistent to all
            future reboots (BOOT_SOURCE_ENABLED_CONTINUOUS) or disabled
            (BOOT_SOURCE_ENABLED_DISABLED).
        :param mode: The boot mode, UEFI (BOOT_SOURCE_MODE_UEFI) or
            BIOS (BOOT_SOURCE_MODE_BIOS).
        :raises: InvalidParameterValueError, if any information passed is
            invalid.
        """
        valid_targets = self.get_allowed_system_boot_source_values()
        if target not in valid_targets:
            raise exceptions.InvalidParameterValueError(
                parameter='target', value=target, valid_values=valid_targets)

        if enabled not in sys_maps.BOOT_SOURCE_ENABLED_MAP_REV:
            raise exceptions.InvalidParameterValueError(
                parameter='enabled',
                value=enabled,
                valid_values=list(sys_maps.BOOT_SOURCE_ENABLED_MAP_REV))

        data = {
            'Boot': {
                'BootSourceOverrideTarget':
                sys_maps.BOOT_SOURCE_TARGET_MAP_REV[target],
                'BootSourceOverrideEnabled':
                sys_maps.BOOT_SOURCE_ENABLED_MAP_REV[enabled]
            }
        }

        if mode is not None:
            if mode not in sys_maps.BOOT_SOURCE_MODE_MAP_REV:
                raise exceptions.InvalidParameterValueError(
                    parameter='mode',
                    value=mode,
                    valid_values=list(sys_maps.BOOT_SOURCE_MODE_MAP_REV))

            data['Boot']['BootSourceOverrideMode'] = (
                sys_maps.BOOT_SOURCE_MODE_MAP_REV[mode])

        # TODO(lucasagomes): Check the return code and response body ?
        #                    Probably we should call refresh() as well.
        self._conn.patch(self.path, data=data)

    # TODO(lucasagomes): All system have a Manager and Chassis object,
    # include a get_manager() and get_chassis() once we have an abstraction
    # for those resources.

    def _get_processor_collection_path(self):
        """Helper function to find the ProcessorCollection path"""
        return utils.get_sub_resource_path_by(self, 'Processors')

    @property
    @utils.cache_it
    def processors(self):
        """Property to reference `ProcessorCollection` instance

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done).
        Here the actual refresh of the sub-resource happens, if stale.
        """
        return processor.ProcessorCollection(
            self._conn,
            self._get_processor_collection_path(),
            redfish_version=self.redfish_version)

    @property
    @utils.cache_it
    def ethernet_interfaces(self):
        """Property to reference `EthernetInterfaceCollection` instance

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done).
        Here the actual refresh of the sub-resource happens, if stale.
        """
        return ethernet_interface.EthernetInterfaceCollection(
            self._conn,
            utils.get_sub_resource_path_by(self, "EthernetInterfaces"),
            redfish_version=self.redfish_version)

    @property
    @utils.cache_it
    def bios(self):
        """Property to reference `Bios` instance

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done).
        Here the actual refresh of the sub-resource happens, if stale.
        """
        return bios.Bios(self._conn,
                         utils.get_sub_resource_path_by(self, 'Bios'),
                         redfish_version=self.redfish_version)

    @property
    @utils.cache_it
    def simple_storage(self):
        """A collection of simple storage associated with system.

        This returns a reference to `SimpleStorageCollection` instance.
        SimpleStorage represents the properties of a storage controller and its
        directly-attached devices.

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done).
        Here the actual refresh of the sub-resource happens, if stale.

        :raises: MissingAttributeError if 'SimpleStorage/@odata.id' field
            is missing.
        :returns: `SimpleStorageCollection` instance
        """
        return sys_simple_storage.SimpleStorageCollection(
            self._conn,
            utils.get_sub_resource_path_by(self, "SimpleStorage"),
            redfish_version=self.redfish_version)

    @property
    @utils.cache_it
    def storage(self):
        """A collection of storage subsystems associated with system.

        This returns a reference to `StorageCollection` instance.
        A storage subsystem represents a set of storage controllers (physical
        or virtual) and the resources such as drives and volumes that can be
        accessed from that subsystem.

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done).
        Here the actual refresh of the sub-resource happens, if stale.

        :raises: MissingAttributeError if 'Storage/@odata.id' field
            is missing.
        :returns: `StorageCollection` instance
        """
        return sys_storage.StorageCollection(
            self._conn,
            utils.get_sub_resource_path_by(self, "Storage"),
            redfish_version=self.redfish_version)
예제 #18
0
class Storage(base.ResourceBase):
    """This class represents the storage subsystem resources.

    A storage subsystem represents a set of storage controllers (physical or
    virtual) and the resources such as drives and volumes that can be accessed
    from that subsystem.
    """

    identity = base.Field('Id', required=True)
    """The Storage identity string"""

    name = base.Field('Name')
    """The name of the resource"""

    drives_identities = base.Field('Drives',
                                   adapter=utils.get_members_identities)
    """A tuple with the drive identities"""

    status = common.StatusField('Status')
    """Describes the status and health of the resource and its children."""
    def get_drive(self, drive_identity):
        """Given the drive identity return a ``Drive`` object

        :param drive_identity: The identity of the ``Drive``
        :returns: The ``Drive`` object
        :raises: ResourceNotFoundError
        """
        return drive.Drive(self._conn,
                           drive_identity,
                           redfish_version=self.redfish_version,
                           registries=self.registries)

    @property
    @utils.cache_it
    def drives(self):
        """Return a list of `Drive` objects present in the storage resource.

        It is set once when the first time it is queried. On subsequent
        invocations, it returns a cached list of `Drives` objects until it is
        marked stale.

        :returns: A list of `Drive` objects
        :raises: ResourceNotFoundError
        """
        return [self.get_drive(id_) for id_ in self.drives_identities]

    @property
    @utils.cache_it
    def drives_sizes_bytes(self):
        """Sizes of all Drives in bytes in Storage resource.

        Returns the list of cached values until it (or its parent resource)
        is refreshed.
        """
        return sorted(drv.capacity_bytes for drv in self.drives)

    @property
    def drives_max_size_bytes(self):
        """Max size available in bytes among all Drives of this collection."""
        return utils.max_safe(self.drives_sizes_bytes)

    @property
    @utils.cache_it
    def volumes(self):
        """Property to reference `VolumeCollection` instance

        It is set once when the first time it is queried. On refresh,
        this property is marked as stale (greedy-refresh not done at that
        point). Here only the actual refresh of the sub-resource happens,
        if resource is stale.
        """
        return volume.VolumeCollection(self._conn,
                                       utils.get_sub_resource_path_by(
                                           self, 'Volumes'),
                                       redfish_version=self.redfish_version)

    storage_controllers = StorageControllersListField('StorageControllers',
                                                      default=[])
    """The storage devices associated with this resource."""
예제 #19
0
class UpdateService(base.ResourceBase):

    identity = base.Field('Id', required=True)
    """The update service identity"""

    http_push_uri = base.Field('HttpPushUri')
    """The URI used to perform an HTTP or HTTPS push update to the Update
    Service"""

    http_push_uri_targets = base.Field('HttpPushUriTargets')
    """The array of URIs indicating the target for applying the""" + \
        """update image"""

    http_push_uri_targets_busy = base.Field('HttpPushUriTargetsBusy')
    """This represents if the HttpPushUriTargets property is reserved""" + \
        """by anyclient"""

    name = base.Field('Name', required=True)
    """The update service name"""

    service_enabled = base.Field('ServiceEnabled')
    """The status of whether this service is enabled"""

    status = common.StatusField('Status')
    """The status of the update service"""

    _actions = ActionsField('Actions', required=True)

    _firmware_inventory_path = base.Field(['FirmwareInventory', '@odata.id'])

    _software_inventory_path = base.Field(['SoftwareInventory', '@odata.id'])

    def __init__(self,
                 connector,
                 identity,
                 redfish_version=None,
                 registries=None):
        """A class representing a UpdateService

        :param connector: A Connector instance
        :param identity: The identity of the UpdateService resource
        :param redfish_version: The version of RedFish. Used to construct
            the object according to schema of given version
        :param registries: Dict of Redfish Message Registry objects to be
            used in any resource that needs registries to parse messages
        """
        super(UpdateService, self).__init__(connector, identity,
                                            redfish_version, registries)

    def _get_simple_update_element(self):
        simple_update_action = self._actions.simple_update
        if not simple_update_action:
            raise exceptions.MissingAttributeError(
                action='#UpdateService.SimpleUpdate', resource=self._path)
        return simple_update_action

    def _get_legacy_transfer_protocols(self):
        """Get the backward-compatible values for transfer protocol.

        :returns: A set of allowed values.
        """
        LOG.warning(
            'Could not figure out the allowed values for the simple '
            'update action for UpdateService %s', self.identity)
        return set(up_maps.TRANSFER_PROTOCOL_TYPE_VALUE_MAP)

    def get_allowed_transfer_protocols(self):
        """Get the allowed values for transfer protocol.

        :returns: A set of allowed values.
        :raises: MissingAttributeError, if Actions/#UpdateService.SimpleUpdate
            attribute not present.
        """
        simple_update_action = self._get_simple_update_element()

        if not getattr(simple_update_action, 'transfer_protocol', None):
            LOG.debug(
                'Server does not constrain allowed transfer protocols for '
                'simple update action of UpdateService %s', self.identity)
            return set(up_maps.TRANSFER_PROTOCOL_TYPE_VALUE_MAP_REV)

        return {simple_update_action.transfer_protocol}

    def simple_update(self,
                      image_uri,
                      targets=None,
                      transfer_protocol=up_cons.UPDATE_PROTOCOL_HTTP):
        """Simple Update is used to update software components.

        :returns: A task monitor.
        """
        valid_transfer_protocols = self.get_allowed_transfer_protocols()

        if transfer_protocol in valid_transfer_protocols:
            transfer_protocol = up_maps.TRANSFER_PROTOCOL_TYPE_VALUE_MAP_REV[
                transfer_protocol]

        else:
            legacy_transfer_protocols = self._get_legacy_transfer_protocols()

            if transfer_protocol not in legacy_transfer_protocols:
                raise exceptions.InvalidParameterValueError(
                    parameter='transfer_protocol',
                    value=transfer_protocol,
                    valid_values=valid_transfer_protocols)

            LOG.warning(
                'Legacy transfer protocol constant %s is being used. '
                'Consider migrating to any of: %s', transfer_protocol,
                ', '.join(up_maps.TRANSFER_PROTOCOL_TYPE_VALUE_MAP_REV))

        target_uri = self._get_simple_update_element().target_uri

        LOG.debug('Updating software component %s via '
                  '%s ...', image_uri, target_uri)

        data = {'ImageURI': image_uri, 'TransferProtocol': transfer_protocol}
        if targets:
            data['Targets'] = targets
        rsp = self._conn.post(target_uri, data=data)

        json_data = rsp.json() if rsp.content else {}
        field_data = base.FieldData(rsp.status_code, rsp.headers, json_data)

        header = 'Location'
        task_monitor = rsp.headers.get(header)
        if not task_monitor:
            raise exceptions.MissingHeaderError(target_uri=target_uri,
                                                header=header)

        return taskmonitor.TaskMonitor(self._conn,
                                       task_monitor,
                                       redfish_version=self.redfish_version,
                                       registries=self.registries,
                                       field_data=field_data)

    def get_task_monitor(self, task_monitor):
        """Used to retrieve a TaskMonitor.

        :returns: A task monitor.
        """
        return taskmonitor.TaskMonitor(self._conn,
                                       task_monitor,
                                       redfish_version=self.redfish_version,
                                       registries=self.registries)

    @property
    @utils.cache_it
    def software_inventory(self):
        """Property to reference SoftwareInventory collection instance"""
        if not self._software_inventory_path:
            raise exceptions.MissingAttributeError(
                attribute='SoftwareInventory/@odata.id',
                resource=self._software_inventory_path)

        return softwareinventory.SoftwareInventoryCollection(
            self._conn,
            self._software_inventory_path,
            redfish_version=self.redfish_version,
            registries=self.registries)

    @property
    @utils.cache_it
    def firmware_inventory(self):
        """Property to reference FirmwareInventory collection instance"""
        if not self._firmware_inventory_path:
            raise exceptions.MissingAttributeError(
                attribute='FirmwareInventory/@odata.id',
                resource=self._firmware_inventory_path)

        return softwareinventory.SoftwareInventoryCollection(
            self._conn,
            self._firmware_inventory_path,
            redfish_version=self.redfish_version,
            registries=self.registries)
예제 #20
0
class Processor(base.ResourceBase):

    identity = base.Field('Id', required=True)
    """The processor identity string"""

    socket = base.Field('Socket')
    """The socket or location of the processor"""

    processor_type = base.MappedField('ProcessorType',
                                      sys_maps.PROCESSOR_TYPE_VALUE_MAP)
    """The type of processor"""

    processor_architecture = base.MappedField(
        'ProcessorArchitecture', sys_maps.PROCESSOR_ARCH_VALUE_MAP)
    """The architecture of the processor"""

    instruction_set = base.MappedField(
        'InstructionSet', sys_maps.PROCESSOR_INSTRUCTIONSET_VALUE_MAP)
    """The instruction set of the processor"""

    manufacturer = base.Field('Manufacturer')
    """The processor manufacturer"""

    model = base.Field('Model')
    """The product model number of this device"""

    max_speed_mhz = base.Field('MaxSpeedMHz', adapter=utils.int_or_none)
    """The maximum clock speed of the processor in MHz."""

    processor_id = ProcessorIdField('ProcessorId')
    """The processor id"""

    status = common.StatusField('Status')
    """The processor status"""

    total_cores = base.Field('TotalCores', adapter=utils.int_or_none)
    """The total number of cores contained in this processor"""

    total_threads = base.Field('TotalThreads', adapter=utils.int_or_none)
    """The total number of execution threads supported by this processor"""
    def __init__(self, connector, identity, redfish_version=None):
        """A class representing a Processor

        :param connector: A Connector instance
        :param identity: The identity of the processor
        :param redfish_version: The version of RedFish. Used to construct
            the object according to schema of the given version.
        """
        super(Processor, self).__init__(connector, identity, redfish_version)

    def _get_processor_collection_path(self):
        """Helper function to find the ProcessorCollection path"""
        pro_col = self.json.get('ProcessorCollection')
        if not pro_col:
            raise exceptions.MissingAttributeError(
                attribute='ProcessorCollection', resource=self._path)
        return pro_col.get('@odata.id')

    @property
    @utils.cache_it
    def sub_processors(self):
        """A reference to the collection of Sub-Processors"""
        return ProcessorCollection(self.conn,
                                   self._get_processor_collection_path,
                                   redfish_version=self.redfish_version)
예제 #21
0
class CompositionService(base.ResourceBase):

    allow_overprovisioning = base.Field('AllowOverprovisioning')
    """This indicates whether this service is allowed to overprovision"""

    allow_zone_affinity = base.Field('AllowZoneAffinity')
    """This indicates whether a client is allowed to request that given
    composition request"""

    description = base.Field('Description')
    """The composition service description"""

    identity = base.Field('Id', required=True)
    """The composition service identity string"""

    name = base.Field('Name', required=True)
    """The composition service name"""

    status = common.StatusField('Status')
    """The status of composition service"""

    service_enabled = base.Field('ServiceEnabled')
    """The status of composition service is enabled"""

    def __init__(self, connector, identity, redfish_version=None,
                 registries=None):
        """A class representing a CompositionService

        :param connector: A connector instance
        :param identity: The identity of the CompositionService resource
        :param redfish_version: The version of RedFish. Used to construct
            the object according to schema of given version
        :param registries: Dict of Redfish Message Registry objects to be
            used in any resource that needs registries to parse messages
        """
        super(CompositionService, self).__init__(
            connector, identity, redfish_version, registries)

    def _get_resource_blocks_collection_path(self):
        """Helper function to find the ResourceBlockCollections path"""
        res_block_col = self.json.get('ResourceBlocks')
        if not res_block_col:
            raise exceptions.MissingAttributeError(
                attribute='ResourceBlocks', resource=self._path)
        return res_block_col.get('@odata.id')

    def _get_resource_zones_collection_path(self):
        """Helper function to find the ResourceZoneCollections path"""
        res_zone_col = self.json.get('ResourceZones')
        if not res_zone_col:
            raise exceptions.MissingAttributeError(
                attribute='ResourceZones', resource=self._path)
        return res_zone_col.get('@odata.id')

    @property
    @utils.cache_it
    def resource_blocks(self):
        """Property to reference `ResourceBlockCollection` instance"""
        return resourceblock.ResourceBlockCollection(
            self._conn, self._get_resource_blocks_collection_path,
            self.redfish_version, self.registries)

    @property
    @utils.cache_it
    def resource_zones(self):
        """Property to reference `ResourceZoneCollection` instance"""
        return resourcezone.ResourceZoneCollection(
            self._conn, self._get_resource_zones_collection_path,
            self.redfish_version, self.registries)
예제 #22
0
class UpdateService(base.ResourceBase):

    identity = base.Field('Id', required=True)
    """The update service identity"""

    http_push_uri = base.Field('HttpPushUri')
    """The URI used to perform an HTTP or HTTPS push update to the Update
    Service"""

    http_push_uri_targets = base.Field('HttpPushUriTargets')
    """The array of URIs indicating the target for applying the""" + \
        """update image"""

    http_push_uri_targets_busy = base.Field('HttpPushUriTargetsBusy')
    """This represents if the HttpPushUriTargets property is reserved""" + \
        """by anyclient"""

    name = base.Field('Name', required=True)
    """The update service name"""

    service_enabled = base.Field('ServiceEnabled')
    """The status of whether this service is enabled"""

    status = common.StatusField('Status')
    """The status of the update service"""

    _actions = ActionsField('Actions', required=True)

    def __init__(self, connector, identity, redfish_version=None):
        """A class representing a UpdateService

        :param connector: A Connector instance
        :param identity: The identity of the UpdateService resource
        :param redfish_version: The version of RedFish. Used to construct
            the object according to schema of given version
        """
        super(UpdateService, self).__init__(connector, identity,
                                            redfish_version)

    def _get_simple_update_element(self):
        simple_update_action = self._actions.simple_update
        if not simple_update_action:
            raise exceptions.MissingAttributeError(
                action='#UpdateService.SimpleUpdate', resource=self._path)
        return simple_update_action

    def get_allowed_transfer_protocol_values(self):
        """Get the allowed values for transfer protocol.

        :returns: A set of allowed values.
        :raises: MissingAttributeError, if Actions/#UpdateService.SimpleUpdate
            attribute not present.
        """
        simple_update_action = self._get_simple_update_element()

        if not simple_update_action.transfer_protocol:
            LOG.warning(
                'Could not figure out the allowed values for the simple '
                'update action for UpdateService %s', self.identity)
            return set(up_maps.TRANSFER_PROTOCOL_TYPE_VALUE_MAP_REV)

        return set(up_maps.TRANSFER_PROTOCOL_TYPE_VALUE_MAP[v]
                   for v in simple_update_action.transfer_protocol
                   if v in up_maps.TRANSFER_PROTOCOL_TYPE_VALUE_MAP)

    def simple_update(self, image_uri, targets, transfer_protocol='HTTP'):
        """Simple Update is used to update software components"""
        transfer_protocol = transfer_protocol

        valid_transfer_protocols = self.get_allowed_transfer_protocol_values()
        if transfer_protocol not in valid_transfer_protocols:
            raise exceptions.InvalidParameterValueError(
                parameter='transfer_protocol',
                value=transfer_protocol,
                valid_values=valid_transfer_protocols)

        self._conn.post(
            data={
                'ImageURI': image_uri,
                'Targets': targets,
                'TransferProtocol': transfer_protocol
            })

    def _get_software_inventory_collection_path(self):
        """Helper function to find the SoftwareInventoryCollections path"""
        soft_inv_col = self.json.get('SoftwareInventory')
        if not soft_inv_col:
            raise exceptions.MissingAttributeError(
                attribute='SoftwareInventory', resource=self._path)
        return soft_inv_col.get('@odata.id')

    @property
    @utils.cache_it
    def software_inventory(self):
        """Property to reference SoftwareInventoryCollection instance"""
        return softwareinventory.SoftwareInventoryCollection(
            self._conn,
            self._get_software_inventory_collection_path,
            redfish_version=self.redfish_version)

    @property
    @utils.cache_it
    def firmware_inventory(self):
        """Property to reference SoftwareInventoryCollection instance"""
        return softwareinventory.SoftwareInventoryCollection(
            self._conn,
            self._get_software_inventory_collection_path,
            redfish_version=self.redfish_version)