Various service detection fixes

* Move monasca-agent and extend user detection from postfix
  detection plugin to
  monasca_setup.detection.utils.get_agent_username()
* Use get_agent_username() rather than static user name in
  mon detection plugin
* Add logic for determining monasca-notification user from
  process to mon detection plugin

Change-Id: I6a00a8d6574da27274718a71fd813dedd61442b4
(cherry picked from commit f2e00f6ebc)
This commit is contained in:
Johannes Grassler 2017-06-12 17:56:33 +02:00
parent df3a66503b
commit 1a8335d088
5 changed files with 54 additions and 21 deletions

View File

@ -1,5 +1,6 @@
# Copyright 2016 FUJITSU LIMITED # Copyright 2016 FUJITSU LIMITED
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP # (C) Copyright 2016 Hewlett Packard Enterprise Development LP
# Copyright 2017 SUSE Linux GmbH
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
@ -185,11 +186,10 @@ class Kibana(detection.Plugin):
def _has_metrics_support(self, kibana_url): def _has_metrics_support(self, kibana_url):
resp = self._get_metrics_request(kibana_url, method='HEAD') resp = self._get_metrics_request(kibana_url, method='HEAD')
status_code = resp.status_code status_code = resp.status_code
# although Kibana will respond with 400:Bad Request # Some Kibana versions may respond with 400:Bad Request
# it means that URL is available but simply does # it means that URL is available but simply does
# not support HEAD request # not support HEAD request
# Looks like guys from Kibana just support GET for this url return (status_code == 400) or (status_code == 200)
return status_code == 400
def _get_metrics_request(self, url, method='GET'): def _get_metrics_request(self, url, method='GET'):
request_url = '%s/%s' % (url, _API_STATUS) request_url = '%s/%s' % (url, _API_STATUS)

View File

@ -1,4 +1,5 @@
# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP
# Copyright 2017 SUSE Linux GmbH
import ConfigParser import ConfigParser
import grp import grp
@ -12,6 +13,7 @@ import sys
from monasca_agent.common.psutil_wrapper import psutil from monasca_agent.common.psutil_wrapper import psutil
import monasca_setup.agent_config import monasca_setup.agent_config
from monasca_setup.detection import Plugin from monasca_setup.detection import Plugin
from monasca_setup.detection import utils
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -53,12 +55,7 @@ class Libvirt(Plugin):
def _detect(self): def _detect(self):
"""Set self.available True if the process and config file are detected """Set self.available True if the process and config file are detected
""" """
# Detect Agent's OS username by getting the group owner of confg file self.agent_user = utils.get_agent_username()
try:
gid = os.stat('/etc/monasca/agent/agent.yaml').st_gid
self.agent_user = grp.getgrgid(gid)[0]
except OSError:
self.agent_user = None
# Try to detect the location of the Nova configuration file. # Try to detect the location of the Nova configuration file.
# Walk through the list of processes, searching for 'nova-compute' # Walk through the list of processes, searching for 'nova-compute'
# process with 'nova.conf' inside one of the parameters # process with 'nova.conf' inside one of the parameters

View File

@ -1,5 +1,6 @@
# (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP # (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP
# Copyright 2016 FUJITSU LIMITED # Copyright 2016 FUJITSU LIMITED
# Copyright 2017 SUSE Linux GmbH
"""Classes for monitoring the monitoring server stack. """Classes for monitoring the monitoring server stack.
@ -18,6 +19,7 @@ import monasca_setup.agent_config
import monasca_setup.detection import monasca_setup.detection
from monasca_setup.detection import find_process_cmdline from monasca_setup.detection import find_process_cmdline
from monasca_setup.detection import find_process_name from monasca_setup.detection import find_process_name
from monasca_setup.detection.utils import get_agent_username
from monasca_setup.detection.utils import watch_process from monasca_setup.detection.utils import watch_process
from monasca_setup.detection.utils import watch_process_by_username from monasca_setup.detection.utils import watch_process_by_username
@ -72,8 +74,8 @@ class MonAgent(monasca_setup.detection.Plugin):
def build_config(self): def build_config(self):
"""Build the config as a Plugins object and return.""" """Build the config as a Plugins object and return."""
log.info("\tEnabling the Monasca Agent process check") log.info("\tEnabling the Monasca Agent process check")
return watch_process_by_username('mon-agent', 'monasca-agent', 'monitoring', return watch_process_by_username(get_agent_username(), 'monasca-agent',
'monasca-agent') 'monitoring', 'monasca-agent')
def dependencies_installed(self): def dependencies_installed(self):
return True return True
@ -197,8 +199,10 @@ class MonNotification(monasca_setup.detection.Plugin):
def build_config(self): def build_config(self):
"""Build the config as a Plugins object and return.""" """Build the config as a Plugins object and return."""
log.info("\tEnabling the Monasca Notification healthcheck") log.info("\tEnabling the Monasca Notification healthcheck")
return watch_process_by_username('mon-notification', 'monasca-notification', 'monitoring', notification_process = find_process_cmdline('monasca-notification')
'monasca-notification') notification_user = notification_process.as_dict(['username'])['username']
return watch_process_by_username(notification_user, 'monasca-notification',
'monitoring', 'monasca-notification')
def dependencies_installed(self): def dependencies_installed(self):
return True return True

View File

@ -1,9 +1,9 @@
# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP # (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP
# Copyright 2017 Fujitsu LIMITED # Copyright 2017 Fujitsu LIMITED
# Copyright 2017 SUSE Linux GmbH
import logging import logging
import os import os
import pwd
import yaml import yaml
from monasca_setup import agent_config from monasca_setup import agent_config
@ -34,7 +34,7 @@ class Postfix(plugin.Plugin):
try: try:
has_process = (utils.find_process_cmdline(_POSTFIX_PROC_NAME) has_process = (utils.find_process_cmdline(_POSTFIX_PROC_NAME)
is not None) is not None)
agent_user = self._get_agent_username() if has_process else None agent_user = utils.get_agent_username() if has_process else None
has_user = agent_user is not None has_user = agent_user is not None
has_sudoers = (self._has_sudoers(agent_user) has_sudoers = (self._has_sudoers(agent_user)
if agent_user else False) if agent_user else False)
@ -75,12 +75,6 @@ class Postfix(plugin.Plugin):
def dependencies_installed(self): def dependencies_installed(self):
return True return True
@staticmethod
def _get_agent_username():
uid = os.stat('/etc/monasca/agent/agent.yaml').st_uid
agent_user = pwd.getpwuid(uid).pw_name
return agent_user
@staticmethod @staticmethod
def _has_sudoers(agent_user): def _has_sudoers(agent_user):
test_sudo = os.system(_POSTFIX_CHECK_COMMAND.format(agent_user)) test_sudo = os.system(_POSTFIX_CHECK_COMMAND.format(agent_user))

View File

@ -1,8 +1,11 @@
# (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP # (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP
# Copyright 2017 SUSE Linux GmbH
""" Util functions to assist in detection. """ Util functions to assist in detection.
""" """
import logging import logging
import os
import pwd
import subprocess import subprocess
from subprocess import CalledProcessError from subprocess import CalledProcessError
from subprocess import PIPE from subprocess import PIPE
@ -13,6 +16,8 @@ from monasca_setup import agent_config
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
_DEFAULT_AGENT_USER = 'mon-agent'
_DETECTED_AGENT_USER = None
# check_output was introduced in python 2.7, function added # check_output was introduced in python 2.7, function added
# to accommodate python 2.6 # to accommodate python 2.6
@ -93,6 +98,39 @@ def find_addr_listening_on_port_over_tcp(port):
return ip[0].lstrip("::ffff:") return ip[0].lstrip("::ffff:")
def get_agent_username():
"""Determine the user monasca-agent runs as"""
global _DETECTED_AGENT_USER
# Use cached agent user in subsequent calls
if _DETECTED_AGENT_USER is not None:
return _DETECTED_AGENT_USER
# Try the owner of agent.yaml first
try:
uid = os.stat('/etc/monasca/agent/agent.yaml').st_uid
except OSError:
uid = None
if uid is not None:
_DETECTED_AGENT_USER = pwd.getpwuid(uid).pw_name
return _DETECTED_AGENT_USER
# No agent.yaml, so try to find a running monasca-agent process
agent_process = find_process_name('monasca-agent')
if agent_process is not None:
_DETECTED_AGENT_USER = agent_process.username()
return _DETECTED_AGENT_USER
# Fall back to static agent user
log.warn("Could not determine monasca-agent service user, falling "
"back to %s" % _DEFAULT_AGENT_USER)
_DETECTED_AGENT_USER = _DEFAULT_AGENT_USER
return _DETECTED_AGENT_USER
def watch_process(search_strings, service=None, component=None, def watch_process(search_strings, service=None, component=None,
exact_match=True, detailed=True, process_name=None): exact_match=True, detailed=True, process_name=None):
"""Takes a list of process search strings and returns a Plugins object with the config set. """Takes a list of process search strings and returns a Plugins object with the config set.