This file is indexed.

/usr/lib/python2.7/dist-packages/os_faults/drivers/power/ipmi.py is in python-os-faults 0.1.17-0ubuntu1.1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
149
150
151
152
153
154
155
156
157
158
159
# 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.

import logging

from pyghmi import exceptions as pyghmi_exception
from pyghmi.ipmi import command as ipmi_command

from os_faults.api import error
from os_faults.api import power_management
from os_faults import utils

LOG = logging.getLogger(__name__)


BMC_SCHEMA = {
    'type': 'object',
    'properties': {
        'address': {'type': 'string'},
        'username': {'type': 'string'},
        'password': {'type': 'string'},
    },
    'required': ['address', 'username', 'password']
}


class IPMIDriver(power_management.PowerDriver):
    """IPMI driver.

    **Example configuration:**

    .. code-block:: yaml

        power_managements:
        - driver: ipmi
          args:
            mac_to_bmc:
              aa:bb:cc:dd:ee:01:
                address: 170.0.10.50
                username: admin1
                password: Admin_123
              aa:bb:cc:dd:ee:02:
                address: 170.0.10.51
                username: admin2
                password: Admin_123
            fqdn_to_bmc:
              node3.local:
                address: 170.0.10.52
                username: admin1
                password: Admin_123

    parameters:

    - **mac_to_bmc** - list of dicts where keys are the node MACs and
      values are the corresponding BMC configurations with the folowing
      fields:

      - **address** - ip address of IPMI server
      - **username** - IPMI user
      - **password** - IPMI password
    """

    NAME = 'ipmi'
    DESCRIPTION = 'IPMI power management driver'
    CONFIG_SCHEMA = {
        'type': 'object',
        '$schema': 'http://json-schema.org/draft-04/schema#',
        'properties': {
            'mac_to_bmc': {
                'type': 'object',
                'patternProperties': {
                    utils.MACADDR_REGEXP: BMC_SCHEMA
                }
            },
            'fqdn_to_bmc': {
                'type': 'object',
                'patternProperties': {
                    utils.FQDN_REGEXP: BMC_SCHEMA
                }
            },
        },
        'anyOf': [
            {'required': ['mac_to_bmc']},
            {'required': ['fqdn_to_bmc']},
        ],
        'additionalProperties': False,
    }

    def __init__(self, params):
        self.mac_to_bmc = params.get('mac_to_bmc', {})
        self.fqdn_to_bmc = params.get('fqdn_to_bmc', {})
        # TODO(astudenov): make macs lowercased

    def _find_bmc_by_host(self, host):
        if host.mac in self.mac_to_bmc:
            return self.mac_to_bmc[host.mac]
        if host.fqdn in self.fqdn_to_bmc:
            return self.fqdn_to_bmc[host.fqdn]

        raise error.PowerManagementError(
            'BMC for {!r} not found!'.format(host))

    def _run_set_power_cmd(self, host, cmd, expected_state=None):
        bmc = self._find_bmc_by_host(host)
        try:
            ipmicmd = ipmi_command.Command(bmc=bmc['address'],
                                           userid=bmc['username'],
                                           password=bmc['password'])
            ret = ipmicmd.set_power(cmd, wait=True)
        except pyghmi_exception.IpmiException:
            msg = 'IPMI cmd {!r} failed on bmc {!r}, {!r}'.format(
                cmd, bmc['address'], host)
            LOG.error(msg, exc_info=True)
            raise

        LOG.debug('IPMI response: {}'.format(ret))
        if ret.get('powerstate') != expected_state or 'error' in ret:
            msg = ('Failed to change power state to {!r} on bmc {!r}, '
                   '{!r}'.format(expected_state, bmc['address'], host))
            raise error.PowerManagementError(msg)

    def supports(self, host):
        try:
            self._find_bmc_by_host(host)
        except error.PowerManagementError:
            return False
        return True

    def poweroff(self, host):
        LOG.debug('Power off Node: %s', host)
        self._run_set_power_cmd(host, cmd='off', expected_state='off')
        LOG.info('Node powered off: %s', host)

    def poweron(self, host):
        LOG.debug('Power on Node: %s', host)
        self._run_set_power_cmd(host, cmd='on', expected_state='on')
        LOG.info('Node powered on: %s', host)

    def reset(self, host):
        LOG.debug('Reset Node: %s', host)
        # boot -- If system is off, then 'on', else 'reset'
        self._run_set_power_cmd(host, cmd='boot')
        # NOTE(astudenov): This command does not wait for node to boot
        LOG.info('Node reset: %s', host)

    def shutdown(self, host):
        LOG.debug('Shutdown Node: %s', host)
        self._run_set_power_cmd(host, cmd='shutdown', expected_state='off')
        LOG.info('Node is off: %s', host)