File: message_registry.py

package info (click to toggle)
python-sushy 5.7.1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 3,036 kB
  • sloc: python: 16,382; makefile: 24; sh: 2
file content (148 lines) | stat: -rw-r--r-- 5,422 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#    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.

# This is referred from Redfish standard schema.
# https://redfish.dmtf.org/schemas/v1/MessageRegistry.v1_1_1.json

import logging

from sushy.resources import base
from sushy.resources import constants as res_cons
from sushy.resources.registry import constants as reg_cons

LOG = logging.getLogger(__name__)


class MessageDictionaryField(base.DictionaryField):

    description = base.Field('Description', required=True, default='')
    """Indicates how and when the message is returned by the Redfish service"""

    message = base.Field('Message', required=True)
    """Template text of the message

    Template can include placeholders for message arguments in form
    %<integer> where <integer> denotes a position passed from MessageArgs.
    """

    number_of_args = base.Field('NumberOfArgs', required=True)
    """Number of arguments to be expected to be passed in as MessageArgs
    for this message
    """

    param_types = base.Field('ParamTypes',
                             adapter=lambda x:
                                 [reg_cons.MessageParamType(v.lower())
                                  for v in x])
    """Mapped MessageArg types, in order, for the message"""

    resolution = base.Field('Resolution', required=True)
    """Suggestions on how to resolve the situation that caused the error"""

    severity = base.MappedField('Severity',
                                res_cons.Severity,
                                required=True,
                                default=res_cons.Severity.WARNING)
    """Mapped severity of the message"""


class MessageRegistry(base.ResourceBase):

    _log_resource_body = False

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

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

    description = base.Field('Description')
    """Human-readable description of the message registry"""

    language = base.Field('Language', required=True)
    """RFC 5646 compliant language code for the registry"""

    owning_entity = base.Field('OwningEntity', required=True)
    """Organization or company that publishes this registry"""

    registry_prefix = base.Field('RegistryPrefix', required=True)
    """Prefix used in messageIDs which uniquely identifies all of
    the messages in this registry as belonging to this registry
    """

    registry_version = base.Field('RegistryVersion', required=True)
    """Message registry version which is used in the middle portion
    of a messageID
    """

    messages = MessageDictionaryField('Messages')
    """List of messages in this registry"""


def parse_message(message_registries, message_field):
    """Parse the messages in registries and substitute any params

    Check only registries that support messages.

    :param message_registries: dict of Message Registries
    :param message_field: settings.MessageListField to parse

    :returns: parsed settings.MessageListField with missing attributes filled
    """

    reg_msg = None
    if '.' in message_field.message_id:
        registry, msg_key = message_field.message_id.rsplit('.', 1)

        if (registry in message_registries
                and hasattr(message_registries[registry], "messages")
                and msg_key in message_registries[registry].messages):
            reg_msg = message_registries[registry].messages[msg_key]
    else:
        # Some firmware only reports the MessageKey and no RegistryName.
        # Fall back to the MessageRegistryFile with Id of Messages next, and
        # BaseMessages as a last resort
        registry = 'unknown'
        msg_key = message_field.message_id

        mrf_ids = ['Messages', 'BaseMessages']
        for mrf_id in mrf_ids:
            if (mrf_id in message_registries and msg_key in
                    message_registries[mrf_id].messages):
                reg_msg = message_registries[mrf_id].messages[msg_key]
                break

    if not reg_msg:
        LOG.warning(
            'Unable to find message for registry %(registry)s, '
            'message ID %(msg_key)s', {
                'registry': registry,
                'msg_key': msg_key})
        if message_field.message is None:
            message_field.message = 'unknown'
        return message_field

    msg = reg_msg.message
    for i in range(1, reg_msg.number_of_args + 1):
        if i <= len(message_field.message_args):
            msg = msg.replace('%%%i' % i,
                              str(message_field.message_args[i - 1]))
        else:
            msg = msg.replace('%%%i' % i, 'unknown')

    message_field.message = msg
    if not message_field.severity:
        message_field.severity = reg_msg.severity
    if not message_field.resolution:
        message_field.resolution = reg_msg.resolution

    return message_field