Host = namedtuple('Host', ['name', 'ip'])
+
+
+class Inspector(object):
+ CONGRESS = 'congress'
+ SAMPLE = 'sample'
+ VITRAGE = 'vitrage'
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),
_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',
}
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......')
--- /dev/null
+##############################################################################
+# 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......')
--- /dev/null
+##############################################################################
+# 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)
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
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()
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:
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
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
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
'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):
from keystoneclient.v2_0 import client as ks_client\r
from neutronclient.v2_0 import client as neutronclient\r
import novaclient.client as novaclient\r
+import vitrageclient.client as vitrageclient\r
\r
\r
OPTS = [\r
cfg.StrOpt('glance_version', default='2', help='glance version'),\r
cfg.StrOpt('nova_version', default='2.34', help='Nova version'),\r
cfg.StrOpt('aodh_version', default='2', help='aodh version'),\r
+ cfg.StrOpt('vitrage_version', default='1', help='vitrage version'),\r
]\r
\r
\r
def congress_client(session):\r
return congressclient.Client(session=session,\r
service_type='policy')\r
+\r
+\r
+def vitrage_client(version, session):\r
+ return vitrageclient.Client(version=version,\r
+ session=session)\r
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