aboutsummaryrefslogtreecommitdiffstats
path: root/app/monitoring/setup/sensu_client_installer.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/monitoring/setup/sensu_client_installer.py')
-rw-r--r--app/monitoring/setup/sensu_client_installer.py158
1 files changed, 158 insertions, 0 deletions
diff --git a/app/monitoring/setup/sensu_client_installer.py b/app/monitoring/setup/sensu_client_installer.py
new file mode 100644
index 0000000..72a8bbb
--- /dev/null
+++ b/app/monitoring/setup/sensu_client_installer.py
@@ -0,0 +1,158 @@
+###############################################################################
+# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) #
+# and others #
+# #
+# All rights reserved. This program and the accompanying materials #
+# are made available under the terms of the Apache License, Version 2.0 #
+# which accompanies this distribution, and is available at #
+# http://www.apache.org/licenses/LICENSE-2.0 #
+###############################################################################
+import os.path
+from pkg_resources import parse_version
+
+from monitoring.setup.monitoring_handler import MonitoringHandler
+from utils.inventory_mgr import InventoryMgr
+
+
+class SensuClientInstaller(MonitoringHandler):
+
+ UBUNTU = 'ubuntu'
+ CENTOS = 'centos'
+
+ INSTALL_CMD = {
+ UBUNTU: 'dpkg -i {}',
+ CENTOS: 'rpm -i {}'
+ }
+ PERMISSIONS_CMD = {
+ UBUNTU: '',
+ CENTOS: 'usermod -aG wheel sensu'
+ }
+ SUDOERS_FILE = '/etc/sudoers'
+
+ available_downloads = {}
+
+ def __init__(self, env: str, host_id: str):
+ super().__init__(env)
+ self.cli_ssh = self.get_ssh(host_id)
+ self.inv = InventoryMgr()
+ self.host = self.inv.get_by_id(env, host_id)
+ self.server = self.env_monitoring_config.get('server_ip')
+ self.server_cli_ssh = self.get_ssh(self.server)
+ self.ubuntu_dist = None
+ self.required_package = None
+
+ def install(self):
+ pkg_to_install = self.get_pkg_to_install()
+ if not pkg_to_install:
+ return
+ try:
+ self.fetch_package(pkg_to_install)
+ self.install_package(pkg_to_install)
+ self.set_permissions()
+ except SystemError as e:
+ self.log.error('Sensu install on host {} failed: {}'
+ .format(self.host, str(e)))
+ return
+
+ @staticmethod
+ def get_attr_from_output(output_lines: list, attr: str) -> str:
+ matches = [l for l in output_lines if l.startswith(attr)]
+ if not matches:
+ return ''
+ line = matches[0]
+ return SensuClientInstaller.get_attr_from_output_line(line)
+
+ @staticmethod
+ def get_attr_from_output_line(output_line: str):
+ val = output_line[output_line.index(':')+1:].strip()
+ return val
+
+ INSTALLED = 'Installed: '
+ CANDIDATE = 'Candidate: '
+ SENSU_DIR = '/opt/sensu'
+ SENSU_PKG_DIR = '/etc/sensu/pkg'
+ SENSU_PKG_DIR_LOCAL = '/tmp/sensu_pkg'
+ SENSU_VERSION_FILE = '/opt/sensu/version-manifest.txt'
+
+ def find_available_downloads(self):
+ ls_output = self.server_cli_ssh.exec('ls -R {}'
+ .format(self.SENSU_PKG_DIR))
+ ls_lines = ls_output.splitlines()
+ last_target_dir = None
+ for line in ls_lines:
+ if line[-4:] in ['/32:', '/64:']:
+ last_target_dir = line.replace(self.SENSU_PKG_DIR, '')
+ continue
+ elif last_target_dir:
+ target_dir = last_target_dir.strip(os.path.sep).strip(':')
+ self.available_downloads[target_dir] = line
+ last_target_dir = None
+ else:
+ last_target_dir = None
+
+ def find_available_package(self, os_details: dict):
+ if not self.available_downloads:
+ self.find_available_downloads()
+ distribution = os_details['ID']
+ version = os_details['version'].split()[-2].lower()
+ arch = os_details['architecure'][-2:]
+ download_dir = os.path.join(distribution, version, arch)
+ download_file = self.available_downloads.get(download_dir)
+ full_path = '' if not download_file \
+ else os.path.join(self.SENSU_PKG_DIR, download_dir, download_file)
+ return download_file, full_path
+
+ @staticmethod
+ def find_available_version(download_file: str) -> str:
+ ver = download_file.replace('sensu', '').strip('-_')
+ ver = ver[:ver.index('-')]
+ return ver
+
+ def get_pkg_to_install(self) -> str:
+ if self.provision == self.provision_levels['none']:
+ return ''
+ if not self.host:
+ return ''
+ supported_os = [self.UBUNTU, self.CENTOS]
+ distribution = self.host['OS']['ID']
+ if distribution not in [self.UBUNTU, self.CENTOS]:
+ self.log.error('Sensu client auto-install only supported for: {}'
+ .format(', '.join(supported_os)))
+ return ''
+ cmd = 'if [ -d {} ]; then head -1 {} | sed "s/sensu //"; fi' \
+ .format(self.SENSU_DIR, self.SENSU_VERSION_FILE)
+ installed_version = self.cli_ssh.exec(cmd).strip()
+ os_details = self.host['OS']
+ available_pkg, pkg_path = self.find_available_package(os_details)
+ available_version = self.find_available_version(available_pkg)
+ if parse_version(available_version) <= parse_version(installed_version):
+ return ''
+ return pkg_path
+
+ def get_local_path(self, pkg_to_install: str):
+ return os.path.join(self.SENSU_PKG_DIR_LOCAL,
+ os.path.basename(pkg_to_install))
+
+ def fetch_package(self, pkg_to_install: str):
+ self.make_directory(self.SENSU_PKG_DIR_LOCAL)
+ self.get_file(self.server, pkg_to_install,
+ self.get_local_path(pkg_to_install))
+ local_path = self.get_local_path(pkg_to_install)
+ self.copy_to_remote_host(self.host['host'],
+ local_path=local_path,
+ remote_path=local_path)
+
+ def install_package(self, pkg_to_install):
+ local_path = self.get_local_path(pkg_to_install)
+ install_cmd = self.INSTALL_CMD[self.host['OS']['ID']]
+ self.cli_ssh.exec(install_cmd.format(local_path))
+
+ def set_permissions(self):
+ cmd = self.PERMISSIONS_CMD[self.host['OS']['ID']]
+ if cmd:
+ self.cli_ssh.exec(cmd)
+ # add to sudoers file
+ sudoer_permission = 'sensu ALL=(ALL) NOPASSWD: ALL'
+ sudoer_cmd = 'grep --silent -w sensu {} || echo "{}" >> {}'\
+ .format(self.SUDOERS_FILE, sudoer_permission, self.SUDOERS_FILE)
+ self.cli_ssh.exec(sudoer_cmd)