0423d93736
Currently our logging in processing is very inconsistent: some log strings mention node UUID, some - node BMC IP, some nothing. This change introduces a common prefix for all processing logs based on as much information as possible. Only code that actually have some context about the node (either NodeInfo or introspection data) is updated. Also logging BMC addresses can be disabled now. Updates example.conf (a lot of updated comments from oslo). Change-Id: Ib20f2acdc60bfaceed7a33467557b92857c32798
139 lines
3.9 KiB
Python
139 lines
3.9 KiB
Python
# 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.
|
|
|
|
"""Standard plugins for rules API."""
|
|
|
|
import operator
|
|
|
|
import netaddr
|
|
|
|
from ironic_inspector.plugins import base
|
|
from ironic_inspector import utils
|
|
|
|
|
|
LOG = utils.getProcessingLogger(__name__)
|
|
|
|
|
|
def coerce(value, expected):
|
|
if isinstance(expected, float):
|
|
return float(value)
|
|
elif isinstance(expected, int):
|
|
return int(value)
|
|
else:
|
|
return value
|
|
|
|
|
|
class SimpleCondition(base.RuleConditionPlugin):
|
|
op = None
|
|
|
|
def check(self, node_info, field, params, **kwargs):
|
|
value = params['value']
|
|
return self.op(coerce(field, value), value)
|
|
|
|
|
|
class EqCondition(SimpleCondition):
|
|
op = operator.eq
|
|
|
|
|
|
class LtCondition(SimpleCondition):
|
|
op = operator.lt
|
|
|
|
|
|
class GtCondition(SimpleCondition):
|
|
op = operator.gt
|
|
|
|
|
|
class LeCondition(SimpleCondition):
|
|
op = operator.le
|
|
|
|
|
|
class GeCondition(SimpleCondition):
|
|
op = operator.ge
|
|
|
|
|
|
class NeCondition(SimpleCondition):
|
|
op = operator.ne
|
|
|
|
|
|
class NetCondition(base.RuleConditionPlugin):
|
|
def validate(self, params, **kwargs):
|
|
super(NetCondition, self).validate(params, **kwargs)
|
|
# Make sure it does not raise
|
|
try:
|
|
netaddr.IPNetwork(params['value'])
|
|
except netaddr.AddrFormatError as exc:
|
|
raise ValueError('invalid value: %s' % exc)
|
|
|
|
def check(self, node_info, field, params, **kwargs):
|
|
network = netaddr.IPNetwork(params['value'])
|
|
return netaddr.IPAddress(field) in network
|
|
|
|
|
|
class FailAction(base.RuleActionPlugin):
|
|
REQUIRED_PARAMS = {'message'}
|
|
|
|
def apply(self, node_info, params, **kwargs):
|
|
raise utils.Error(params['message'], node_info=node_info)
|
|
|
|
|
|
class SetAttributeAction(base.RuleActionPlugin):
|
|
REQUIRED_PARAMS = {'path', 'value'}
|
|
# TODO(dtantsur): proper validation of path
|
|
|
|
def apply(self, node_info, params, **kwargs):
|
|
node_info.patch([{'op': 'add', 'path': params['path'],
|
|
'value': params['value']}])
|
|
|
|
def rollback(self, node_info, params, **kwargs):
|
|
try:
|
|
node_info.get_by_path(params['path'])
|
|
except KeyError:
|
|
LOG.debug('Field %s was not set, no need for rollback',
|
|
params['path'], node_info=node_info)
|
|
return
|
|
|
|
node_info.patch([{'op': 'remove', 'path': params['path']}])
|
|
|
|
|
|
class SetCapabilityAction(base.RuleActionPlugin):
|
|
REQUIRED_PARAMS = {'name'}
|
|
OPTIONAL_PARAMS = {'value'}
|
|
|
|
def apply(self, node_info, params, **kwargs):
|
|
node_info.update_capabilities(
|
|
**{params['name']: params.get('value')})
|
|
|
|
def rollback(self, node_info, params, **kwargs):
|
|
node_info.update_capabilities(**{params['name']: None})
|
|
|
|
|
|
class ExtendAttributeAction(base.RuleActionPlugin):
|
|
REQUIRED_PARAMS = {'path', 'value'}
|
|
OPTIONAL_PARAMS = {'unique'}
|
|
# TODO(dtantsur): proper validation of path
|
|
|
|
def apply(self, node_info, params, **kwargs):
|
|
def _replace(values):
|
|
value = params['value']
|
|
if not params.get('unique') or value not in values:
|
|
values.append(value)
|
|
return values
|
|
|
|
node_info.replace_field(params['path'], _replace, default=[])
|
|
|
|
def rollback(self, node_info, params, **kwargs):
|
|
def _replace(values):
|
|
return [v for v in values if v != params['value']]
|
|
|
|
node_info.replace_field(params['path'], _replace, default=[])
|