Principal properties

These are the principal properties used to build Scenarios Overview and other analysis. They are typically combined with the Shared properties and Requirement types.

Vars

Use the vars property to define one or more variables that can be referenced from other properties. Variables are defined as a mapping of key: value pairs. Values can be standard YAML types such as strings, integers and booleans:

vars:
  sfoo: foo
  ifoo: 400
  bfoo: true

They can also reference a Python property. Prefix the import path with @:

vars:
  foo: '@path.to.myproperty'

A factory reference can use the following form:

vars:
  foo: '@<modpath>.<factoryclassname>.<property>:<input>'

The property is resolved lazily when $foo is used.

Accessing

Access a variable from another property by prefixing its name with $:

vars:
  foo: true
checks:
  foo_is_true:
    requires:
      varops: [[$foo], [eq, true]]

Variables are accessible from any property within the file in which they are defined.

NOTE: global properties are not yet supported.

Checks

A dictionary of labelled checks, each of which groups one or more properties. Each check is executed independently and produces a boolean result. Multiple properties within a check are combined with logical AND by default; explicit LogicalGroupings are also supported.

Checks are normally implemented in conjunction with Conclusions as part of Scenarios.

Usage:

checks:
  error_found:
    input: var/log/myapp.log
    search:
      expr: 'ERROR: .+'
  service_ready:
    systemd:
      myapp: active

The following properties are supported:

Cache keys:

  • search - the search property cache, when the check contains a search. It contains num_results and files. The latter lists files that contain matches, rather than every file searched.

  • requires - the requires property cache, when the check contains a requirement.

Conclusions

A conclusion is used in Scenarios to derive an outcome from one or more checks. When a conclusion is matched, it raises a bug or issue with a message describing the identified problem and, where appropriate, suggested actions. Conclusions have priority 1 by default; set priority to an integer to override it. Conclusions with the highest priority take precedence.

The message can optionally use format fields which, if used, require format-dict to be provided with key/value pairs. The values must be an importable attribute, property or method.

Usage:

conclusions:
  <name>:
    priority: <int>
    decision: <check name or logical grouping>
    raises:
      type: <issue class name>
      message: <format string>
      format-dict:
        <key>: <value>

The following provides an explanation of the fields required to define a conclusion:

Decision

This property is used in Conclusions. Its value can be one check name, a list of check names (implicit AND), or check names organised with LogicalGroupings. Supported group operators include and, or, not and nor.

Usage:

  decision: check1

or:

.. code-block:: yaml

  decision: [check1, check2]

or:

.. code-block:: yaml

  decision:
    or:
    - check1
    - and: [check2, check3]

Priority

Defines an integer priority. This is a very simple property that is typically used by Conclusions to associate a priority or precedence to conclusions.

Usage:

priority: <int>

Raises

Defines an issue to raise and the message to display. type is the class name of an issue exported by hotsos.core.issues, not a Python import path. A Checks result can be used to format the message with values from Python properties, variables or property caches.

Usage:

raises:
  type: <type>
  bug-id: <str>
  cve-id: <str>
  message: <str>
  format-dict: <dict>

If type is a bug or cve type then a bug-id or cve-id must be provided respectively.

If message contains format fields, fill them with format-dict. Each key must match a field in the message. A value can be a Python import path, a $variable reference or a property cache reference. References can be suffixed with a supported renderer, for example :first or :unique_comma_join.

Requires

Defines one or more requirements that produce a pass/fail result. Within a check, requires is a mapped property, so its name can be omitted. For example, these definitions are equivalent:

checks:
  explicit:
    requires:
      systemd:
        ufw: active
  implicit:
    systemd:
      ufw: active

Usage:

The simplest form contains a single type e.g.:

requires:
  systemd:
    ufw: active

This requirement stipulates that a systemd service called ufw must exist and have state active for the result to be True.

A requirement can also contain a collection of types grouped as a LogicalGroupings e.g.

requires:
  or:
    - apt: ufw
    - snap: ufw
  systemd:
    ufw: active

This requires the ufw package be installed as a snap or apt package and the corresponding systemd service be in active state.

Note that if more than one item in a group has the same type, a list must used e.g.

requires:
  and:
    - systemd:
        ufw: active
    - systemd:
        ssh: active

The final result of a list, or of multiple ungrouped requirements, is obtained by applying AND to all results.

Requirement types that support ops accept a list of operations applied in sequence. Each operation is a one- or two-item list containing a function name from Python’s operator module and, when required, its second argument. Each operation receives the output of the previous operation. See Property and Varops for examples.

For supported “requirement type” properties see Requirement types