support vitrage inspector for local installer 35/47835/3
authordongwenjuan <dong.wenjuan@zte.com.cn>
Mon, 27 Nov 2017 09:42:17 +0000 (17:42 +0800)
committerdongwenjuan <dong.wenjuan@zte.com.cn>
Mon, 11 Dec 2017 07:21:00 +0000 (15:21 +0800)
JIRA: DOCTOR-122

Change-Id: I771f778767a204e809d892c70603e479c1ed2f5c
Signed-off-by: dongwenjuan <dong.wenjuan@zte.com.cn>
doctor_tests/common/constants.py
doctor_tests/inspector/__init__.py
doctor_tests/inspector/sample.py
doctor_tests/inspector/vitrage.py [new file with mode: 0644]
doctor_tests/installer/common/vitrage.py [new file with mode: 0644]
doctor_tests/installer/local.py
doctor_tests/monitor/sample.py
doctor_tests/os_clients.py
requirements.txt

index 72d037a..088ff63 100644 (file)
@@ -10,3 +10,9 @@ from collections import namedtuple
 
 
 Host = namedtuple('Host', ['name', 'ip'])
+
+
+class Inspector(object):
+    CONGRESS = 'congress'
+    SAMPLE = 'sample'
+    VITRAGE = 'vitrage'
index a9a86ec..31291ba 100644 (file)
@@ -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',
 }
 
 
index 5432872..fe67a90 100644 (file)
@@ -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 (file)
index 0000000..7d1dbc1
--- /dev/null
@@ -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 (file)
index 0000000..9ea3227
--- /dev/null
@@ -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)
index 7d0ae54..453755c 100644 (file)
@@ -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
index 7a46304..4dc5e60 100644 (file)
@@ -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):
index 44fa3aa..5606d40 100644 (file)
@@ -14,12 +14,14 @@ import glanceclient.client as glanceclient
 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
@@ -48,3 +50,8 @@ def aodh_client(version, session):
 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
index 289aae2..0f4e88b 100644 (file)
@@ -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