summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doctor_tests/common/constants.py6
-rw-r--r--doctor_tests/inspector/__init__.py9
-rw-r--r--doctor_tests/inspector/sample.py2
-rw-r--r--doctor_tests/inspector/vitrage.py38
-rw-r--r--doctor_tests/installer/common/vitrage.py98
-rw-r--r--doctor_tests/installer/local.py11
-rw-r--r--doctor_tests/monitor/sample.py31
-rw-r--r--doctor_tests/os_clients.py7
-rw-r--r--requirements.txt1
9 files changed, 179 insertions, 24 deletions
diff --git a/doctor_tests/common/constants.py b/doctor_tests/common/constants.py
index 72d037af..088ff633 100644
--- a/doctor_tests/common/constants.py
+++ b/doctor_tests/common/constants.py
@@ -10,3 +10,9 @@ from collections import namedtuple
Host = namedtuple('Host', ['name', 'ip'])
+
+
+class Inspector(object):
+ CONGRESS = 'congress'
+ SAMPLE = 'sample'
+ VITRAGE = 'vitrage'
diff --git a/doctor_tests/inspector/__init__.py b/doctor_tests/inspector/__init__.py
index a9a86ece..31291baf 100644
--- a/doctor_tests/inspector/__init__.py
+++ b/doctor_tests/inspector/__init__.py
@@ -11,10 +11,12 @@ import os
from oslo_config import cfg
from oslo_utils import importutils
+from doctor_tests.common.constants import Inspector
+
OPTS = [
cfg.StrOpt('type',
- default=os.environ.get('INSPECTOR_TYPE', 'sample'),
+ default=os.environ.get('INSPECTOR_TYPE', Inspector.SAMPLE),
choices=['sample', 'congress', 'vitrage'],
help='the component of doctor inspector',
required=True),
@@ -34,8 +36,9 @@ OPTS = [
_inspector_name_class_mapping = {
- 'sample': 'doctor_tests.inspector.sample.SampleInspector',
- 'congress': 'doctor_tests.inspector.congress.CongressInspector',
+ Inspector.SAMPLE: 'doctor_tests.inspector.sample.SampleInspector',
+ Inspector.CONGRESS: 'doctor_tests.inspector.congress.CongressInspector',
+ Inspector.VITRAGE: 'doctor_tests.inspector.vitrage.VitrageInspector',
}
diff --git a/doctor_tests/inspector/sample.py b/doctor_tests/inspector/sample.py
index 54328727..fe67a903 100644
--- a/doctor_tests/inspector/sample.py
+++ b/doctor_tests/inspector/sample.py
@@ -63,7 +63,7 @@ class SampleInspector(BaseInspector):
self.log.info('can not get hostname from server=%s' % server)
def get_inspector_url(self):
- return 'http://%s:%s' % (self.conf.inspector.ip, self.conf.inspector.port)
+ return 'http://%s:%s/events' % (self.conf.inspector.ip, self.conf.inspector.port)
def start(self):
self.log.info('sample inspector start......')
diff --git a/doctor_tests/inspector/vitrage.py b/doctor_tests/inspector/vitrage.py
new file mode 100644
index 00000000..7d1dbc1c
--- /dev/null
+++ b/doctor_tests/inspector/vitrage.py
@@ -0,0 +1,38 @@
+##############################################################################
+# Copyright (c) 2017 ZTE Corporation 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
+##############################################################################
+from doctor_tests.identity_auth import get_identity_auth
+from doctor_tests.identity_auth import get_session
+from doctor_tests.os_clients import keystone_client
+from doctor_tests.os_clients import vitrage_client
+
+from doctor_tests.inspector.base import BaseInspector
+
+
+class VitrageInspector(BaseInspector):
+
+ def __init__(self, conf, log):
+ super(VitrageInspector, self).__init__(conf, log)
+ self.auth = get_identity_auth()
+ self.keystone = keystone_client(get_session(auth=self.auth))
+ self.vitrage = vitrage_client(self.conf.vitrage_version,
+ get_session(auth=self.auth))
+ self.inspector_url = self.get_inspector_url()
+
+ def get_inspector_url(self):
+ vitrage_endpoint = \
+ self.keystone.session.get_endpoint(
+ service_type='rca',
+ interface='publicURL')
+ return '%s/v1/event' % vitrage_endpoint
+
+ def start(self):
+ self.log.info('vitrage inspector start......')
+
+ def stop(self):
+ self.log.info('vitrage inspector stop......')
diff --git a/doctor_tests/installer/common/vitrage.py b/doctor_tests/installer/common/vitrage.py
new file mode 100644
index 00000000..9ea32271
--- /dev/null
+++ b/doctor_tests/installer/common/vitrage.py
@@ -0,0 +1,98 @@
+##############################################################################
+# Copyright (c) 2017 ZTE Corporation 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
+
+
+vitrage_template_file = '/etc/vitrage/templates/vitrage_host_down_scenarios.yaml'
+
+template = """
+metadata:
+ name: host_down_scenarios
+ description: scenarios triggered by Doctor monitor 'compute.host.down' alarm
+definitions:
+ entities:
+ - entity:
+ category: ALARM
+ name: compute.host.down
+ template_id: host_down_alarm
+ - entity:
+ category: ALARM
+ type: vitrage
+ name: Instance Down
+ template_id: instance_alarm
+ - entity:
+ category: RESOURCE
+ type: nova.instance
+ template_id: instance
+ - entity:
+ category: RESOURCE
+ type: nova.host
+ template_id: host
+ relationships:
+ - relationship:
+ source: host_down_alarm
+ relationship_type: on
+ target: host
+ template_id : host_down_alarm_on_host
+ - relationship:
+ source: host
+ relationship_type: contains
+ target: instance
+ template_id : host_contains_instance
+ - relationship:
+ source: instance_alarm
+ relationship_type: on
+ target: instance
+ template_id : alarm_on_instance
+scenarios:
+ - scenario:
+ condition: host_down_alarm_on_host
+ actions:
+ - action:
+ action_type: set_state
+ action_target:
+ target: host
+ properties:
+ state: ERROR
+ - action:
+ action_type: mark_down
+ action_target:
+ target: host
+ - scenario:
+ condition: host_down_alarm_on_host and host_contains_instance
+ actions:
+ - action:
+ action_type: raise_alarm
+ action_target:
+ target: instance
+ properties:
+ alarm_name: Instance Down
+ severity: critical
+ - scenario:
+ condition: host_down_alarm_on_host and host_contains_instance and alarm_on_instance
+ actions:
+ - action:
+ action_type: add_causal_relationship
+ action_target:
+ source: host_down_alarm
+ target: instance_alarm
+ - action:
+ action_type: mark_down
+ action_target:
+ target: instance
+"""
+
+
+def set_vitrage_host_down_template():
+ if os.path.isfile(vitrage_template_file):
+ print('Vitrage host_down template file: %s already exists.' % vitrage_template_file)
+ else:
+ print('Create Vitrage host_down template file:%s.' % vitrage_template_file)
+ with open(vitrage_template_file, 'w') as file:
+ file.write(template)
diff --git a/doctor_tests/installer/local.py b/doctor_tests/installer/local.py
index 7d0ae542..453755c2 100644
--- a/doctor_tests/installer/local.py
+++ b/doctor_tests/installer/local.py
@@ -11,6 +11,8 @@ import shutil
import subprocess
from doctor_tests.installer.base import BaseInstaller
+from doctor_tests.installer.common.vitrage import set_vitrage_host_down_template
+from doctor_tests.common.constants import Inspector
from doctor_tests.common.utils import load_json_file
from doctor_tests.common.utils import write_json_file
@@ -43,13 +45,16 @@ class LocalInstaller(BaseInstaller):
cmd = "getent hosts %s | awk '{ print $1 }'" % (hostname)
server = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
stdout, stderr = server.communicate()
- host_ip = stdout.strip()
+ host_ip = stdout.strip().decode("utf-8")
self.log.info('Get host_ip:%s from host_name:%s in local installer' % (host_ip, hostname))
return host_ip
def set_apply_patches(self):
self._set_nova_policy()
+ if self.conf.inspector.type == Inspector.VITRAGE:
+ set_vitrage_host_down_template()
+ os.system('sudo systemctl restart devstack@vitrage-graph.service')
def restore_apply_patches(self):
self._restore_nova_policy()
@@ -94,7 +99,7 @@ class LocalInstaller(BaseInstaller):
if self.policy_modified or self.add_policy_file:
write_json_file(self.nova_policy_file, data)
- os.system('screen -S stack -p n-api -X stuff "^C^M^[[A^M"')
+ os.system('sudo systemctl restart devstack@n-api.service')
def _restore_nova_policy(self):
if self.policy_modified:
@@ -104,6 +109,6 @@ class LocalInstaller(BaseInstaller):
os.remove(self.nova_policy_file)
if self.add_policy_file or self.policy_modified:
- os.system('screen -S stack -p n-api -X stuff "^C^M^[[A^M"')
+ os.system('sudo systemctl restart devstack@n-api.service')
self.add_policy_file = False
self.policy_modified = False
diff --git a/doctor_tests/monitor/sample.py b/doctor_tests/monitor/sample.py
index 7a463048..4dc5e603 100644
--- a/doctor_tests/monitor/sample.py
+++ b/doctor_tests/monitor/sample.py
@@ -13,6 +13,7 @@ import socket
from threading import Thread
import time
+from doctor_tests.common.constants import Inspector
from doctor_tests.identity_auth import get_session
from doctor_tests.monitor.base import BaseMonitor
@@ -38,19 +39,16 @@ class SampleMonitor(BaseMonitor):
def report_error(self, hostname):
self.log.info('sample monitor report error......')
- data = [
- {
- 'id': 'monitor_sample_id1',
- 'time': datetime.now().isoformat(),
- 'type': self.event_type,
- 'details': {
- 'hostname': hostname,
- 'status': 'down',
- 'monitor': 'monitor_sample',
- 'monitor_event_id': 'monitor_sample_event1'
- },
+ data = {
+ 'time': datetime.now().isoformat(),
+ 'type': self.event_type,
+ 'details': {
+ 'hostname': hostname,
+ 'status': 'down',
+ 'monitor': 'monitor_sample',
+ 'monitor_event_id': 'monitor_sample_event1'
},
- ]
+ }
auth_token = self.session.get_token() if \
self.conf.inspector.type != 'sample' else None
@@ -59,11 +57,10 @@ class SampleMonitor(BaseMonitor):
'Accept': 'application/json',
'X-Auth-Token': auth_token,
}
-
- url = '%s%s' % (self.inspector_url, 'events') \
- if self.inspector_url.endswith('/') else \
- '%s%s' % (self.inspector_url, '/events')
- requests.put(url, data=json.dumps(data), headers=headers)
+ if self.conf.inspector.type != Inspector.VITRAGE:
+ requests.put(self.inspector_url, data=json.dumps([data]), headers=headers)
+ else:
+ requests.post(self.inspector_url, data=json.dumps(data), headers=headers)
class Pinger(Thread):
diff --git a/doctor_tests/os_clients.py b/doctor_tests/os_clients.py
index 44fa3aad..5606d40a 100644
--- a/doctor_tests/os_clients.py
+++ b/doctor_tests/os_clients.py
@@ -14,12 +14,14 @@ import glanceclient.client as glanceclient
from keystoneclient.v2_0 import client as ks_client
from neutronclient.v2_0 import client as neutronclient
import novaclient.client as novaclient
+import vitrageclient.client as vitrageclient
OPTS = [
cfg.StrOpt('glance_version', default='2', help='glance version'),
cfg.StrOpt('nova_version', default='2.34', help='Nova version'),
cfg.StrOpt('aodh_version', default='2', help='aodh version'),
+ cfg.StrOpt('vitrage_version', default='1', help='vitrage version'),
]
@@ -48,3 +50,8 @@ def aodh_client(version, session):
def congress_client(session):
return congressclient.Client(session=session,
service_type='policy')
+
+
+def vitrage_client(version, session):
+ return vitrageclient.Client(version=version,
+ session=session)
diff --git a/requirements.txt b/requirements.txt
index 289aae2d..0f4e88be 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -14,4 +14,5 @@ python-neutronclient>=6.3.0 # Apache-2.0
python-novaclient>=9.0.0 # Apache-2.0
python-congressclient<2000,>=1.3.0 # Apache-2.0
python-glanceclient>=2.8.0 # Apache-2.0
+python-vitrageclient>=1.2.0 # Apache-2.0
virtualenv>=13.1.0 # MIT