fb747ec53f2051a3c9ed91f6e8ddffced85e6023
[doctor.git] / doctor_tests / inspector / congress.py
1 ##############################################################################
2 # Copyright (c) 2017 ZTE Corporation and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9 from doctor_tests.identity_auth import get_identity_auth
10 from doctor_tests.identity_auth import get_session
11 from doctor_tests.os_clients import congress_client
12
13 from doctor_tests.inspector.base import BaseInspector
14
15
16 class CongressInspector(BaseInspector):
17     nova_api_min_version = '2.11'
18     doctor_driver = 'doctor'
19     doctor_datasource = 'doctor'
20     policy = 'classification'
21     rules = {
22         'host_down':
23             'host_down(host) :- doctor:events(hostname=host, type="compute.host.down", status="down")',       # noqa
24         'active_instance_in_host':
25             'active_instance_in_host(vmid, host) :- nova:servers(id=vmid, host_name=host, status="ACTIVE")',  # noqa
26         'host_force_down':
27             'execute[nova:services.force_down(host, "nova-compute", "True")] :- host_down(host)',             # noqa
28         'error_vm_states':
29             'execute[nova:servers.reset_state(vmid, "error")] :- host_down(host), active_instance_in_host(vmid, host)'    # noqa
30     }
31
32     def __init__(self, conf, log):
33         super(CongressInspector, self).__init__(conf, log)
34         self.auth = get_identity_auth()
35         self.congress = congress_client(get_session(auth=self.auth))
36         self._init_driver_and_ds()
37         self.inspector_url = self.get_inspector_url()
38
39     def _init_driver_and_ds(self):
40         datasources = \
41             {ds['name']: ds for ds in
42              self.congress.list_datasources()['results']}
43
44         # check nova_api version
45         nova_api_version = datasources['nova']['config'].get('api_version')
46         if nova_api_version and nova_api_version < self.nova_api_min_version:
47             raise Exception('Congress Nova datasource API '
48                             'version < nova_api_min_version(%s)'
49                             % self.nova_api_min_version)
50
51         # create doctor datasource if it's not exist
52         if self.doctor_datasource not in datasources:
53             self.congress.create_datasource(
54                 body={'driver': self.doctor_driver,
55                       'name': self.doctor_datasource})
56
57         # check whether doctor driver exist
58         drivers = \
59             {driver['id']: driver for driver in
60              self.congress.list_drivers()['results']}
61         if self.doctor_driver not in drivers:
62             raise Exception('Do not support doctor driver in congress')
63
64         self.policy_rules = \
65             {rule['name']: rule for rule in
66              self.congress.list_policy_rules(self.policy)['results']}
67
68     def get_inspector_url(self):
69         ds = self.congress.list_datasources()['results']
70         doctor_ds = next((item for item in ds if item['driver'] == 'doctor'),
71                          None)
72         congress_endpoint = \
73             self.congress.httpclient.get_endpoint(auth=self.auth)
74         return ('%s/v1/data-sources/%s/tables/events/rows' %
75                 (congress_endpoint, doctor_ds['id']))
76
77     def start(self):
78         self.log.info('congress inspector start......')
79
80         for rule_name, rule in self.rules.items():
81             self._add_rule(rule_name, rule)
82
83     def stop(self):
84         self.log.info('congress inspector stop......')
85
86         for rule_name in self.rules.keys():
87             self._del_rule(rule_name)
88
89     def _add_rule(self, rule_name, rule):
90         if rule_name not in self.policy_rules:
91             self.congress.create_policy_rule(self.policy,
92                                              body={'name': rule_name,
93                                                    'rule': rule})
94
95     def _del_rule(self, rule_name):
96         if rule_name in self.policy_rules:
97             rule_id = self.policy_rules[rule_name]['id']
98             self.congress.delete_policy_rule(self.policy, rule_id)