254 lines
11 KiB
Python
254 lines
11 KiB
Python
# Copyright 2016 Mirantis, Inc.
|
|
#
|
|
# 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 bs4
|
|
import requests
|
|
import urllib
|
|
import urlparse
|
|
|
|
from devops.helpers import helpers as devops_helpers
|
|
from fuelweb_test import logger
|
|
from proboscis import asserts
|
|
from pyzabbix import ZabbixAPI
|
|
from stacklight_tests import base_test
|
|
from stacklight_tests.helpers import checkers
|
|
from stacklight_tests.helpers import helpers
|
|
from stacklight_tests.helpers import remote_ops
|
|
from stacklight_tests.zabbix import plugin_settings as zabbix_plugin_settings
|
|
|
|
|
|
class ZabbixWeb(object):
|
|
def __init__(self, zabbix_url, username, password, protocol, verify=False):
|
|
self.session = requests.Session()
|
|
adapter = requests.adapters.HTTPAdapter(max_retries=3)
|
|
self.session.mount('{}://'.format(protocol), adapter)
|
|
self.base_url = zabbix_url
|
|
self.username = username
|
|
self.password = password
|
|
self.verify = verify
|
|
|
|
def zabbix_web_login(self, autologin=1, expected_code=200):
|
|
login_params = urllib.urlencode({'request': '',
|
|
'name': self.username,
|
|
'password': self.password,
|
|
'autologin': autologin,
|
|
'enter': 'Sign in'})
|
|
url = urlparse.urljoin(self.base_url,
|
|
'?{0}'.format(login_params))
|
|
response = self.session.post(url, verify=self.verify)
|
|
|
|
asserts.assert_equal(
|
|
response.status_code, expected_code,
|
|
"Login to Zabbix failed: {0}".format(response.content))
|
|
|
|
def get_zabbix_web_screen(self, page='screens.php',
|
|
expected_code=200):
|
|
url = urlparse.urljoin(self.base_url, page)
|
|
response = self.session.get(url, verify=self.verify)
|
|
|
|
asserts.assert_equal(response.status_code, expected_code,
|
|
"Getting Zabbix screens failed: {0}".format(
|
|
response.content))
|
|
|
|
return bs4.BeautifulSoup(response.content)
|
|
|
|
|
|
class ZabbixApi(base_test.PluginApi):
|
|
def __init__(self):
|
|
super(ZabbixApi, self).__init__()
|
|
self.settings = zabbix_plugin_settings
|
|
self.helpers = helpers.PluginHelper(self.env)
|
|
self.checkers = checkers
|
|
self.remote_ops = remote_ops
|
|
|
|
@property
|
|
def protocol(self):
|
|
attributes = self.helpers.nailgun_client.get_cluster_attributes(
|
|
self.helpers.cluster_id)
|
|
ssl_enabled = attributes['editable']['public_ssl']['horizon']['value']
|
|
protocol = "https" if ssl_enabled else "http"
|
|
return protocol
|
|
|
|
def get_plugin_settings(self):
|
|
return zabbix_plugin_settings
|
|
|
|
def prepare_plugin(self, dependant_plugins=False):
|
|
self.helpers.prepare_plugin(self.settings.plugin_path)
|
|
if dependant_plugins:
|
|
for plugin in self.settings.dependant_plugins:
|
|
self.helpers.prepare_plugin(
|
|
self.settings.dependant_plugins[plugin]["plugin_path"])
|
|
|
|
def activate_plugin(self, options=None):
|
|
if options is None:
|
|
options = self.settings.default_options
|
|
self.helpers.activate_plugin(
|
|
self.settings.name, self.settings.version, options)
|
|
|
|
def activate_dependant_plugin(self, plugin, options=None):
|
|
if options is None:
|
|
options = self.settings.default_options
|
|
self.helpers.activate_plugin(
|
|
plugin["name"], plugin["version"], options)
|
|
|
|
def get_zabbix_url(self):
|
|
return "{0}://{1}/zabbix/".format(self.protocol, self.get_zabbix_vip())
|
|
|
|
def get_zabbix_vip(self):
|
|
return self.helpers.fuel_web.get_public_vip(self.helpers.cluster_id)
|
|
|
|
def get_zabbix_mgmt_vip(self):
|
|
return self.helpers.fuel_web.client.get_networks(
|
|
self.helpers.cluster_id)['vips']['zbx_vip_mgmt']['ipaddr']
|
|
|
|
def check_plugin_online(self):
|
|
controllers = [
|
|
controller for controller in
|
|
self.fuel_web.get_nailgun_cluster_nodes_by_roles(
|
|
self.helpers.cluster_id, ['controller'])
|
|
if controller["online"]]
|
|
with self.fuel_web.get_ssh_for_nailgun_node(controllers[0]) as remote:
|
|
remote.check_call("dpkg --get-selections | grep zabbix")
|
|
response = remote.execute("crm resource status "
|
|
"p_zabbix-server")["stdout"][0]
|
|
asserts.assert_true("p_zabbix-server is running" in response,
|
|
"p_zabbix-server resource wasn't found"
|
|
" in pacemaker:\n{0}".format(response))
|
|
|
|
zabbix_web = self.get_zabbix_web()
|
|
zabbix_web.zabbix_web_login()
|
|
screens_html = zabbix_web.get_zabbix_web_screen()
|
|
screens_links = screens_html.find_all('a')
|
|
asserts.assert_true(any('charts.php?graphid=' in link.get('href')
|
|
for link in screens_links),
|
|
"Zabbix screen page does not contain "
|
|
"graphs:\n{0}".format(screens_links))
|
|
|
|
def uninstall_plugin(self):
|
|
return self.helpers.uninstall_plugin(self.settings.name,
|
|
self.settings.version)
|
|
|
|
def check_uninstall_failure(self):
|
|
return self.helpers.check_plugin_cannot_be_uninstalled(
|
|
self.settings.name, self.settings.version)
|
|
|
|
def get_zabbix_web(self, username='', password='', protocol=None):
|
|
username = username or self.settings.zabbix_username
|
|
password = password or self.settings.zabbix_password
|
|
protocol = protocol if protocol else self.protocol
|
|
|
|
return ZabbixWeb(
|
|
self.get_zabbix_url(), username, password, protocol)
|
|
|
|
def get_zabbix_api(self, url='', user='', password=''):
|
|
url = url or self.get_zabbix_url()
|
|
user = user or self.settings.zabbix_username
|
|
password = password or self.settings.zabbix_password
|
|
zabbix_api = ZabbixAPI(url=url, user=user, password=password)
|
|
return zabbix_api
|
|
|
|
def get_node_with_zabbix_vip_fqdn(self):
|
|
controller = self.fuel_web.get_nailgun_cluster_nodes_by_roles(
|
|
self.helpers.cluster_id, ['controller'])[0]
|
|
|
|
with self.fuel_web.get_ssh_for_nailgun_node(controller) as remote:
|
|
result = remote.check_call(
|
|
"crm status | grep {} | awk '{{print $4}}'".format(
|
|
self.helpers.get_vip_resource_name(
|
|
self.settings.failover_vip)))
|
|
return result['stdout'][0].rstrip()
|
|
|
|
def get_triggers(self, params=None):
|
|
params = params or {
|
|
"output": ["triggerid", "description", "priority"],
|
|
"filter": {"value": 1}, "sortfield": "priority"
|
|
}
|
|
return self.get_zabbix_api().do_request('trigger.get', params)
|
|
|
|
def wait_for_trigger(self, triggers, params=None, timeout=3 * 60):
|
|
def check_triggers():
|
|
for trigger in triggers:
|
|
found = False
|
|
for line in self.get_triggers(params)['result']:
|
|
if line["description"] in trigger["description"]:
|
|
found = True
|
|
if line["priority"] != trigger["priority"]:
|
|
logger.error(
|
|
"Trigger '{0}' has wrong priority! Expected"
|
|
" '{1}' but found '{2}'".format(
|
|
line["description"], trigger["priority"],
|
|
line["priority"]))
|
|
return False
|
|
if not found:
|
|
logger.error("Failed to find trigger: {0}".format(
|
|
trigger["description"]))
|
|
return False
|
|
return True
|
|
devops_helpers.wait(
|
|
check_triggers, timeout=timeout,
|
|
timeout_msg="Failed to get all expected triggers!")
|
|
|
|
def send_extreme_snmptraps(self, remote, extreme_host_ip):
|
|
snmp_traps = {
|
|
'ps': "snmptrap -v 1 -c {snmp_community} {zabbix_vip} "
|
|
"'.1.3.6.1.4.1.1916' '{extreme_host_ip}' 6 {parameter} '10'"
|
|
" .1.3.6.1.4.1.1916 s \"null\" .1.3.6.1.4.1.1916 s \"null\""
|
|
" .1.3.6.1.4.1.1916 s \"2\"",
|
|
'port': "snmptrap -v 1 -c {snmp_community} {zabbix_vip}"
|
|
" '.1.3.6.1.6.3.1.1' '{extreme_host_ip}' {parameter} 10"
|
|
" '10' .1.3.6.1.6.3.1.1 s \"eth1\"",
|
|
'fan': "snmptrap -v 1 -c {snmp_community} {zabbix_vip}"
|
|
" '.1.3.6.1.4.1.1916' '{extreme_host_ip}' 6 {parameter}"
|
|
" '10' .1.3.6.1.4.1.1916 s \"null\" .1.3.6.1.4.1.1916 s"
|
|
" \"null\" .1.3.6.1.4.1.1916 s \"5\"",
|
|
}
|
|
remote.check_call(snmp_traps['ps'].format(
|
|
snmp_community='public', zabbix_vip=self.get_zabbix_mgmt_vip(),
|
|
extreme_host_ip=extreme_host_ip, parameter=10))
|
|
remote.check_call(snmp_traps['ps'].format(
|
|
snmp_community='public', zabbix_vip=self.get_zabbix_mgmt_vip(),
|
|
extreme_host_ip=extreme_host_ip, parameter=11))
|
|
remote.check_call(snmp_traps['port'].format(
|
|
snmp_community='public', zabbix_vip=self.get_zabbix_mgmt_vip(),
|
|
extreme_host_ip=extreme_host_ip, parameter=2))
|
|
remote.check_call(snmp_traps['port'].format(
|
|
snmp_community='public', zabbix_vip=self.get_zabbix_mgmt_vip(),
|
|
extreme_host_ip=extreme_host_ip, parameter=3))
|
|
remote.check_call(snmp_traps['fan'].format(
|
|
snmp_community='public', zabbix_vip=self.get_zabbix_mgmt_vip(),
|
|
extreme_host_ip=extreme_host_ip, parameter=7))
|
|
remote.check_call(snmp_traps['fan'].format(
|
|
snmp_community='public', zabbix_vip=self.get_zabbix_mgmt_vip(),
|
|
extreme_host_ip=extreme_host_ip, parameter=8))
|
|
|
|
def send_emc_snmptraps(self, remote, emc_host_ip):
|
|
emc_trap = (
|
|
"snmptrap -v 1 -c {snmp_community} {zabbix_vip}"
|
|
" '.1.3.6.1.4.1.1981' '{emc_host_ip}' 6 {parameter1} '10'"
|
|
" .1.3.6.1.4.1.1981 s \"null\" .1.3.6.1.4.1.1981 s \"null\""
|
|
" .1.3.6.1.4.1.1981 s \"{parameter2}\""
|
|
)
|
|
remote.check_call(emc_trap.format(
|
|
snmp_community='public', zabbix_vip=self.get_zabbix_mgmt_vip(),
|
|
emc_host_ip=emc_host_ip, parameter1=6, parameter2="a37"))
|
|
remote.check_call(emc_trap.format(
|
|
snmp_community='public', zabbix_vip=self.get_zabbix_mgmt_vip(),
|
|
emc_host_ip=emc_host_ip, parameter1=5, parameter2=966))
|
|
remote.check_call(emc_trap.format(
|
|
snmp_community='public', zabbix_vip=self.get_zabbix_mgmt_vip(),
|
|
emc_host_ip=emc_host_ip, parameter1=4, parameter2=7220))
|
|
remote.check_call(emc_trap.format(
|
|
snmp_community='public', zabbix_vip=self.get_zabbix_mgmt_vip(),
|
|
emc_host_ip=emc_host_ip, parameter1=3, parameter2=2004))
|