예제 #1
0
    def test_create_metricdata(self):
        r = MetricData(name='name', messages={})

        self.assertEqual('swiftlm.name', r.name)
        self.assertEqual('', r.message)
        self.assertEqual(None, r.value)
        self.assertIn('hostname', r.dimensions)
예제 #2
0
    def test_dict_behaviour(self):
        r = MetricData(name='name', messages={})

        r['test'] = 1000
        # dimension values must be strings so we check they are converted
        # properly
        self.assertEqual('1000', r['test'])
        del r['test']

        self.assertNotIn('test', r)
예제 #3
0
    def test_child_msgkeys(self):
        r = MetricData(name='name',
                       messages={
                           'ok': 'test message',
                           'test':
                           'test with meta {test_value} and {test_value2}',
                       })

        c = r.child(dimensions={'test_value': '123'},
                    msgkeys={'test_value2': '456'})
        c.message = 'test'

        self.assertEqual('test with meta 123 and 456', str(c))
예제 #4
0
    def test_response_child(self):
        r = MetricData(name='name', messages={'a': 'b'})
        r['test'] = 'test'

        c = r.child(dimensions={'test2': 'test2'})
        self.assertIn('test', c)
        self.assertIn('test2', c)
        self.assertDictEqual({'a': 'b'}, c.messages)
        self.assertEqual('swiftlm.name', c.name)

        c = r.child()
        self.assertIn('test', c)
        self.assertNotIn('test2', c)
예제 #5
0
    def test_message(self):
        r = MetricData(name='name',
                       messages={
                           'ok': 'test message',
                           'test': 'test with meta {test_value}',
                       })

        # Test automatic message assignment when a the Status Enum is used
        # as the value
        self.assertEqual('', r.message)
        r.value = Severity.ok
        self.assertEqual('test message', r.message)

        # Test that an error is raised when trying to use a message without
        # providing all of the dimension values first.
        with self.assertRaisesRegexp(ValueError, 'requires a dimension value'):
            r.message = 'test'

        r['test_value'] = '123'
        r.message = 'test'

        self.assertEqual('test with meta 123', str(r))
예제 #6
0
# 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 json

from swiftlm.utils.metricdata import MetricData, timestamp, CheckFailure
from swiftlm.utils.values import Severity, ServerType

RECON_PATH = '/var/cache/swift/'
TIMEOUT = 2
BASE_RESULT = MetricData(
    name=__name__,
    messages={}
)


def _recon_check(st):
    """
    Parses the blah.recon file and returns the last replication.

    :param st: ServerType, Used to determine the metric names and recon
        file name.
    :param replication_field_name: string, name of the field in the json
        file that hold the last replication data.
    """
    results = []
    if not st.is_instance:
        return results
예제 #7
0
    def test_get_controller_info(self):
        expected_base = MetricData(
            name=hpssacli.__name__ + '.smart_array',
            messages=hpssacli.BASE_RESULT.messages,
            dimensions={
                'serial': 'PACCR0M9VZ41S4Q',
                'model': 'Smart Array P410',
                'slot': '1',
                'component': 'controller',
            })

        # List of tuples.
        # t[0] = Data set that hpssacli should return
        # t[1] = The failed component in the test data
        tests = [
            (SMART_ARRAY_DATA, []),
            (SMART_ARRAY_CACHE_FAIL, ['cache']),
            (SMART_ARRAY_BATTERY_FAIL, ['battery/capacitor']),
            (SMART_ARRAY_CONTROLLER_FAIL, ['controller']),
            (SMART_ARRAY_BATTERY_COUNT_FAIL, ['battery/capacitor count']),
        ]

        for test_data, failures in tests:
            mock_command = mock.Mock()
            mock_command.return_value = CommandResult(0, test_data)
            with mock.patch('swiftlm.hp_hardware.hpssacli.run_cmd',
                            mock_command):
                actual, actual_slots = hpssacli.get_smart_array_info()

            self.assertIsInstance(actual, list)
            self.assertEqual(len(actual), 5)

            expected_firmware = expected_base.child('firmware')
            expected_firmware.value = 6.60
            actual = self.check_metrics(expected_firmware, actual)

            bcc = 'battery/capacitor count'
            if bcc in failures:
                expected_battery_count = expected_base.child(dimensions={
                    'sub_component': bcc, 'count': '0'})
                expected_battery_count.value = Severity.fail
                expected_battery_count.message = 'no_battery'
            else:
                expected_battery_count = expected_base.child(dimensions={
                    'sub_component': bcc, 'count': '1'})
                expected_battery_count.value = Severity.ok

            actual = self.check_metrics(expected_battery_count, actual)

            for submetric in ('battery/capacitor', 'controller', 'cache'):
                if submetric in failures:
                    expected_status = expected_base.child(dimensions={
                        'sub_component': submetric, 'status': 'FAIL'})
                    expected_status.value = Severity.fail
                    expected_status.message = 'controller_status'
                else:
                    expected_status = expected_base.child(dimensions={
                        'sub_component': submetric, 'status': 'OK'})
                    expected_status.value = Severity.ok

                actual = self.check_metrics(expected_status, actual)

            self.assertFalse(actual, 'Got more metrics than expected')
예제 #8
0
    def test_equality_behaviour(self):
        m_a = MetricData('name', self.messages, self.dimensions)
        m_b = MetricData('name', self.messages, self.dimensions)
        self.assertEqual(m_a, m_b)

        m_a = MetricData('name', self.messages, self.dimensions)
        m_b = MetricData('not-name', self.messages, self.dimensions)
        self.assertNotEqual(m_a, m_b)

        m_a = MetricData('name', {'a': 1}, self.dimensions)
        m_b = MetricData('name', {'b': 2}, self.dimensions)
        self.assertEqual(
            m_a, m_b, 'Message dictionaries should not '
            'affect equality of MetricData instances')

        m_a = MetricData('name', self.messages, self.dimensions)
        m_b = MetricData('name', self.messages, {})
        self.assertNotEqual(m_a, m_b)

        m_a = MetricData('name', self.messages, self.dimensions)
        m_b = MetricData('name', self.messages, self.dimensions)
        m_a.message = 'ok'
        m_b.message = 'fail'
        self.assertNotEqual(m_a, m_b)

        m_a = MetricData('name', self.messages, self.dimensions)
        m_b = MetricData('name', self.messages, self.dimensions)
        m_a.value = 1
        m_b.value = 2
        self.assertNotEqual(m_a, m_b)
예제 #9
0
import ast
import subprocess
import os
import ConfigParser

from swiftlm.utils.metricdata import MetricData
from swiftlm.utils.values import Severity

ERRORS_PATTERN = 'drive-audit: Errors found:'
DEVICES_PATTERN = 'drive-audit: Devices found:'
DRIVE_AUDIT_CONF = '/etc/swift/drive-audit.conf'

BASE_RESULT = MetricData(
    name=__name__,
    messages={
        'ok': 'No errors found on device mounted at: {mount_point}',
        'warn': 'No devices found',
        'fail': 'Errors found on device mounted at: {mount_point}',
        'unknown': 'Unrecoverable error: {error}'
    })


def get_devices(output):
    """
    Returns a list of devices as a dict of mount_point and device
    """
    # TODO use drive_model.yml to determine drives to check
    lines = [s.strip() for s in output.split('\n') if s]
    for line in lines:
        if DEVICES_PATTERN in line:
            devs = line.split(DEVICES_PATTERN)[1].strip()
            devices = ast.literal_eval(devs)
예제 #10
0
# 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.
#


from swiftlm.utils.utility import server_type, get_all_proc_and_cmdlines,\
                                  get_network_interface_conf,\
                                  get_rsync_target_conf
from swiftlm.utils.metricdata import MetricData, get_base_dimensions
from swiftlm.utils.values import Severity

BASE_RESULT = MetricData(name=__name__,
                         messages={
                             'fail': '{component} is not running',
                             'ok': '{component} is running',
                             'unknown': 'no swift services running',
                         })

SERVICES = [
    "account-auditor", "account-reaper", "account-replicator",
    "account-server", "container-replicator", "container-server",
    "container-updater", "container-auditor", "container-reconciler",
    "container-sync", "object-replicator", "object-server", "object-updater",
    "object-auditor", "object-reconstructor", "proxy-server"
]


def services_to_check():
    # Filter SERVICES down to what should be running on the node.
    # server_type returns a dict of {'object': bool, etc}
예제 #11
0
파일: system.py 프로젝트: ArdanaCLM/swiftlm
# 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 re

from swiftlm.utils.metricdata import MetricData, CheckFailure
from swiftlm.utils.values import Severity
from swiftlm.utils.utility import run_cmd

BASE_RESULT = MetricData(
    name='load.host',
    messages={}
)


def _get_proc_file(path):
    return open(path, mode='r').read()


def get_load_average():
    r = BASE_RESULT.child(name='val.five')
    load_avg_data = _get_proc_file('/proc/loadavg')
    r.value = float(load_avg_data.split()[1])
    return [r]


def main():
예제 #12
0
from swiftlm.utils.utility import (get_ring_hosts, server_type,
                                   UtilityExeception)
from swiftlm.utils.metricdata import MetricData, get_base_dimensions
from swiftlm.utils.values import Severity, ServerType
from swiftlm.utils.utility import run_cmd

# Connectivity needs to report out target hostname and observer hostname
# rather than the normal hostname dimension
_base_dimensions = dict(get_base_dimensions())
_base_dimensions['observer_host'] = _base_dimensions['hostname']
del _base_dimensions['hostname']

BASE_RESULT = MetricData(name=__name__,
                         messages={
                             'ok': '{hostname}:{target_port} ok',
                             'warn': 'No hosts to check',
                             'fail': '{hostname}:{target_port} {fail_message}',
                             'unknown': 'Unrecoverable error: {error}',
                         },
                         dimensions=_base_dimensions)

MAX_THREAD_LIMIT = 10
SWIFT_PROXY_PATH = '/opt/stack/service/swift-proxy-server/etc'


class HostPort(namedtuple('HostPort', ['host', 'port'])):
    @classmethod
    def from_string(cls, s):
        """ Create a HostPort instance from a string """
        # Supports:
        # http://host.name, http://host.name:port
        # host.name, host.name:port
예제 #13
0
    import configparser
except ImportError:
    import ConfigParser as configparser

from swiftlm.utils.metricdata import MetricData
from swiftlm.utils.values import Severity
from swiftlm.utils.utility import run_cmd
from swiftlm import CONFIG_FILE

LOCK_FILE_COMMAND = '/usr/bin/flock -w 10 /var/lock/hpssacli-swiftlm.lock '
BASE_RESULT = MetricData(
    name=__name__,
    messages={
        'no_battery': 'No cache battery',
        'unknown': 'hpssacli command failed: {error}',
        'controller_status': '{sub_component} status is {status}',
        'physical_drive': 'Drive {serial}: {box}:{bay} has status: {status}',
        'l_drive': 'Logical Drive {logical_drive} has status: {status}',
        'l_cache': 'Logical Drive {logical_drive} has cache status: {caching}',
        'ok': 'OK',
        'fail': 'FAIL',
    })


def is_cont_heading(line):
    """
    Returns "True" if the line is the controller heading
    example: Smart Array P410 in Slot 1
    """
    if ("Slot" in line) and (not line[0].isspace()):
        return True
    else:
예제 #14
0
try:
    import commands
except ImportError:
    import subprocess as commands
import string


from swiftlm.utils.utility import get_swift_bind_ips, UtilityExeception
from swiftlm.utils.utility import ip_to_interface
from swiftlm.utils.metricdata import MetricData
from swiftlm.utils.values import Severity

BASE_RESULT = MetricData(
    name=__name__,
    messages={
        'fail': 'Could not discover a valid interface name'
    }
)


def str_to_num(val):
    # if val is a number then convert it to a number literal
    try:
        return int(val)
    except ValueError:
        try:
            return float(val)
        except:
            return val

예제 #15
0
def is_valid_xfs(d, r):
    rc = run_cmd('xfs_info %s' % d.mount)
    if rc.exitcode == 0:
        return True
    else:
        return False


BASE_RESULT = MetricData(
    name=__name__,
    messages={
        is_mounted.__name__: '{device} not mounted at {mount}',
        is_mounted_775.__name__: ('{device} mounted at {mount} has permissions'
                                  ' {permissions} not 755'),
        is_ug_swift.__name__: ('{device} mounted at {mount} is not owned by'
                               ' swift, has user: {user}, group: {group}'),
        is_valid_label.__name__: ('{device} mounted at {mount} has invalid '
                                  'label {label}'),
        is_xfs.__name__: '{device} mounted at {mount} is not XFS',
        is_valid_xfs.__name__: '{device} mounted at {mount} is corrupt',
        'ok': '{device} mounted at {mount} ok',
        'no_devices': 'No devices found'
    }
)


def check_mounts():
    results = []
    checks = (
        is_mounted,
        is_mounted_775,
        is_ug_swift,
예제 #16
0
except ImportError:
    import ConfigParser as configparser
from collections import OrderedDict
from swiftlm.utils.metricdata import MetricData
from swiftlm.utils.values import Severity
from swiftlm.utils.utility import run_cmd
from swiftlm import CONFIG_FILE

LOCK_FILE_COMMAND = '/usr/bin/flock -w 10 /var/lock/hpssacli-swiftlm.lock '
BASE_RESULT = MetricData(
    name=__name__,
    messages={
        'no_battery': 'No cache battery',
        'unknown': 'hpssacli command failed',
        'controller_status': '{sub_component} status is {status}',
        'in_hba_mode': 'Controller is in HBA mode; performance will be poor',
        'physical_drive': 'Drive {serial_number}: '
        '{box}:{bay} has status: {status}',
        'l_drive': 'Logical Drive {logical_drive} has status: {status}',
        'l_cache': 'Logical Drive {logical_drive} has cache status: {caching}',
        'ok': 'OK',
        'fail': 'FAIL',
    })

# This is all the data we are looking for in the hpssacli output so we
# will _only_ gather whatever values are in this list
METRIC_KEYS = [
    'array', 'physicaldrive', 'logical_drive', 'caching', 'serial_number',
    'slot', 'firmware_version', 'controller_mode',
    'battery_capacitor_presence', 'battery_capacitor_status',
    'controller_status', 'cache_status', 'box', 'bay', 'status',
    'ld acceleration method'
예제 #17
0
import pwd

from swiftlm.utils.utility import server_type
from swiftlm.utils.metricdata import MetricData
from swiftlm.utils.values import Severity, ServerType

SWIFT_DIR = '/etc/swift'
CONF_DIR = '/etc'
NODE_DIR = '/srv/node'

ZERO_BYTE_EXCLUDE = frozenset(['reload-trigger', 'swauth_to_tenant_map.gz'])
SWIFT_OWNED_EXCLUDE = frozenset(['lost+found'])

BASE_RESULT = MetricData(name=__name__,
                         messages={
                             'empty': 'Path: {path} should not be empty',
                             'ownership': 'Path: {path} is not owned by swift',
                             'missing': 'Path: {path} is missing',
                         })


def add_result(results, path, reason):
    c = BASE_RESULT.child(dimensions={'path': path})
    c.value = Severity.fail
    c.message = reason
    results.add(c)


def _is_swift_owned(results, p):
    # True = good, False = bad
    owner = pwd.getpwuid(os.stat(p).st_uid).pw_name
    if owner == 'swift':
예제 #18
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 re

from swiftlm.utils.metricdata import MetricData, CheckFailure
from swiftlm.utils.values import Severity
from swiftlm.utils.utility import run_cmd

BASE_RESULT = MetricData(name=__name__,
                         messages={
                             'ok': 'OK',
                             'fail': 'ntpd not running: {error}',
                         })


def check_status():
    cmd_result = run_cmd('systemctl status ntp')
    r = BASE_RESULT.child()

    if cmd_result.exitcode != 0:
        r['error'] = cmd_result.output
        r.value = Severity.fail
    else:
        r.value = Severity.ok

    return [r]
예제 #19
0
from collections import namedtuple

from swiftlm.utils.utility import (get_ring_hosts, server_type,
                                   UtilityExeception)
from swiftlm.utils.metricdata import MetricData, get_base_dimensions
from swiftlm.utils.values import Severity, ServerType
from swiftlm.utils.utility import run_cmd

# Connectivity needs to report out target hostname and observer hostname
# rather than the normal hostname dimension
_base_dimensions = dict(get_base_dimensions())
_base_dimensions['observer_host'] = socket.gethostname()

BASE_RESULT = MetricData(name=__name__,
                         messages={
                             'ok': '{url} ok',
                             'fail': '{url} {fail_message}'
                         },
                         dimensions=_base_dimensions)

MAX_THREAD_LIMIT = 10
CONNECT_TIMEOUT = 2.0
JOIN_WAIT = 10.0
SWIFT_PROXY_PATH = '/opt/stack/service/swift-proxy-server/etc'
MEMCACHE_CONF_PATH = '/etc/swift'
SWIFTLM_SCAN_PATH = '/etc/swiftlm'


class HostPort(namedtuple('HostPort', ['host', 'port'])):
    @classmethod
    def from_string(cls, s):
        """ Create a HostPort instance from a string """