Merge "Remove ceilometer datasource driver from congress"

This commit is contained in:
Zuul 2017-11-09 06:48:27 +00:00 committed by Gerrit Code Review
commit 4c4fcb300f
7 changed files with 7 additions and 678 deletions

View File

@ -1,284 +0,0 @@
# Copyright (c) 2014 Montavista Software, LLC.
#
# 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.
#
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
import copy
import ceilometerclient
import ceilometerclient.client as cc
from keystoneauth1 import exceptions
from oslo_log import log as logging
import six
from congress.datasources import constants
from congress.datasources import datasource_driver
from congress.datasources import datasource_utils as ds_utils
LOG = logging.getLogger(__name__)
# TODO(thinrichs): figure out how to move even more of this boilerplate
# into DataSourceDriver. E.g. change all the classes to Driver instead of
# NeutronDriver, CeilometerDriver, etc. and move the d6instantiate function
# to DataSourceDriver.
class CeilometerDriver(datasource_driver.PollingDataSourceDriver,
datasource_driver.ExecutionDriver):
METERS = "meters"
ALARMS = "alarms"
EVENTS = "events"
EVENT_TRAITS = "events.traits"
ALARM_THRESHOLD_RULE = "alarms.threshold_rule"
STATISTICS = "statistics"
value_trans = {'translation-type': 'VALUE'}
meters_translator = {
'translation-type': 'HDICT',
'table-name': METERS,
'selector-type': 'DICT_SELECTOR',
'field-translators':
({'fieldname': 'meter_id', 'translator': value_trans},
{'fieldname': 'name', 'translator': value_trans},
{'fieldname': 'type', 'translator': value_trans},
{'fieldname': 'unit', 'translator': value_trans},
{'fieldname': 'source', 'translator': value_trans},
{'fieldname': 'resource_id', 'translator': value_trans},
{'fieldname': 'user_id', 'translator': value_trans},
{'fieldname': 'project_id', 'translator': value_trans})}
alarms_translator = {
'translation-type': 'HDICT',
'table-name': ALARMS,
'selector-type': 'DICT_SELECTOR',
'field-translators':
({'fieldname': 'alarm_id', 'translator': value_trans},
{'fieldname': 'name', 'translator': value_trans},
{'fieldname': 'state', 'translator': value_trans},
{'fieldname': 'enabled', 'translator': value_trans},
{'fieldname': 'threshold_rule', 'col': 'threshold_rule_id',
'translator': {'translation-type': 'VDICT',
'table-name': ALARM_THRESHOLD_RULE,
'id-col': 'threshold_rule_id',
'key-col': 'key', 'val-col': 'value',
'translator': value_trans}},
{'fieldname': 'type', 'translator': value_trans},
{'fieldname': 'description', 'translator': value_trans},
{'fieldname': 'time_constraints', 'translator': value_trans},
{'fieldname': 'user_id', 'translator': value_trans},
{'fieldname': 'project_id', 'translator': value_trans},
{'fieldname': 'alarm_actions', 'translator': value_trans},
{'fieldname': 'ok_actions', 'translator': value_trans},
{'fieldname': 'insufficient_data_actions', 'translator':
value_trans},
{'fieldname': 'repeat_actions', 'translator': value_trans},
{'fieldname': 'timestamp', 'translator': value_trans},
{'fieldname': 'state_timestamp', 'translator': value_trans},
)}
events_translator = {
'translation-type': 'HDICT',
'table-name': EVENTS,
'selector-type': 'DICT_SELECTOR',
'field-translators':
({'fieldname': 'message_id', 'translator': value_trans},
{'fieldname': 'event_type', 'translator': value_trans},
{'fieldname': 'generated', 'translator': value_trans},
{'fieldname': 'traits',
'translator': {'translation-type': 'HDICT',
'table-name': EVENT_TRAITS,
'selector-type': 'DICT_SELECTOR',
'in-list': True,
'parent-key': 'message_id',
'parent-col-name': 'event_message_id',
'field-translators':
({'fieldname': 'name',
'translator': value_trans},
{'fieldname': 'type',
'translator': value_trans},
{'fieldname': 'value',
'translator': value_trans}
)}}
)}
def safe_id(x):
if isinstance(x, six.string_types):
return x
try:
return x['resource_id']
except KeyError:
return str(x)
statistics_translator = {
'translation-type': 'HDICT',
'table-name': STATISTICS,
'selector-type': 'DICT_SELECTOR',
'field-translators':
({'fieldname': 'meter_name', 'translator': value_trans},
{'fieldname': 'groupby', 'col': 'resource_id',
'translator': {'translation-type': 'VALUE',
'extract-fn': safe_id}},
{'fieldname': 'avg', 'translator': value_trans},
{'fieldname': 'count', 'translator': value_trans},
{'fieldname': 'duration', 'translator': value_trans},
{'fieldname': 'duration_start', 'translator': value_trans},
{'fieldname': 'duration_end', 'translator': value_trans},
{'fieldname': 'max', 'translator': value_trans},
{'fieldname': 'min', 'translator': value_trans},
{'fieldname': 'period', 'translator': value_trans},
{'fieldname': 'period_end', 'translator': value_trans},
{'fieldname': 'period_start', 'translator': value_trans},
{'fieldname': 'sum', 'translator': value_trans},
{'fieldname': 'unit', 'translator': value_trans})}
TRANSLATORS = [meters_translator, alarms_translator, events_translator,
statistics_translator]
def __init__(self, name='', args=None):
super(CeilometerDriver, self).__init__(name, args=args)
datasource_driver.ExecutionDriver.__init__(self)
session = ds_utils.get_keystone_session(args)
self.ceilometer_client = cc.get_client(version='2', session=session)
self.add_executable_client_methods(self.ceilometer_client,
'ceilometerclient.v2.')
self.initialize_update_method()
self._init_end_start_poll()
@staticmethod
def get_datasource_info():
result = {}
result['id'] = 'ceilometer'
result['description'] = ('Datasource driver that interfaces with '
'ceilometer.')
result['config'] = ds_utils.get_openstack_required_config()
result['config']['lazy_tables'] = constants.OPTIONAL
result['secret'] = ['password']
return result
def initialize_update_method(self):
meters_method = lambda: self._translate_meters(
self.ceilometer_client.meters.list())
self.add_update_method(meters_method, self.meters_translator)
def alarms_list_suppress_no_aodh_error(ceilometer_client):
'''Return alarms.list(), suppressing error due to Aodh absence
Requires python-ceilometerclient >= 2.6.2
'''
try:
return self.ceilometer_client.alarms.list()
except ceilometerclient.exc.HTTPException as e:
if 'alarms URLs is unavailable when Aodh is disabled or ' \
'unavailable' in str(e):
LOG.info('alarms not available because Aodh is '
'disabled or unavailable. '
'Empty alarms list reported instead.')
return []
else:
raise
except exceptions.ConnectFailure:
LOG.info('Unable to connect to Aodh service, not up '
'or configured')
return []
alarms_method = lambda: self._translate_alarms(
alarms_list_suppress_no_aodh_error(self.ceilometer_client))
self.add_update_method(alarms_method, self.alarms_translator)
events_method = lambda: self._translate_events(self._events_list())
self.add_update_method(events_method, self.events_translator)
statistics_method = lambda: self._translate_statistics(
self._get_statistics(self.ceilometer_client.meters.list()))
self.add_update_method(statistics_method, self.statistics_translator)
def _events_list(self):
try:
return self.ceilometer_client.events.list()
except (ceilometerclient.exc.HTTPException,
exceptions.ConnectFailure):
LOG.info('events list not available because Panko is disabled or '
'unavailable. Empty list reported instead')
return []
def _get_statistics(self, meters):
statistics = []
names = set()
for m in meters:
LOG.debug("Adding meter %s", m.name)
names.add(m.name)
for meter_name in names:
LOG.debug("Getting all Resource ID for meter: %s",
meter_name)
stat_list = self.ceilometer_client.statistics.list(
meter_name, groupby=['resource_id'])
LOG.debug("Statistics List: %s", stat_list)
if (stat_list):
for temp in stat_list:
temp_dict = copy.copy(temp.to_dict())
temp_dict['meter_name'] = meter_name
statistics.append(temp_dict)
return statistics
@ds_utils.update_state_on_changed(METERS)
def _translate_meters(self, obj):
"""Translate the meters represented by OBJ into tables."""
meters = [o.to_dict() for o in obj]
LOG.debug("METERS: %s", str(meters))
row_data = CeilometerDriver.convert_objs(meters,
self.meters_translator)
return row_data
@ds_utils.update_state_on_changed(ALARMS)
def _translate_alarms(self, obj):
"""Translate the alarms represented by OBJ into tables."""
alarms = [o.to_dict() for o in obj]
LOG.debug("ALARMS: %s", str(alarms))
row_data = CeilometerDriver.convert_objs(alarms,
self.alarms_translator)
return row_data
@ds_utils.update_state_on_changed(EVENTS)
def _translate_events(self, obj):
"""Translate the events represented by OBJ into tables."""
events = [o.to_dict() for o in obj]
LOG.debug("EVENTS: %s", str(events))
row_data = CeilometerDriver.convert_objs(events,
self.events_translator)
return row_data
@ds_utils.update_state_on_changed(STATISTICS)
def _translate_statistics(self, obj):
"""Translate the statistics represented by OBJ into tables."""
LOG.debug("STATISTICS: %s", str(obj))
row_data = CeilometerDriver.convert_objs(obj,
self.statistics_translator)
return row_data
def execute(self, action, action_args):
"""Overwrite ExecutionDriver.execute()."""
# action can be written as a method or an API call.
func = getattr(self, action, None)
if func and self.is_executable(func):
func(action_args)
else:
self._execute_api(self.ceilometer_client, action, action_args)

View File

@ -1,287 +0,0 @@
# Copyright (c) 2014 Montavista Software, LLC.
#
# 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.
#
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from ceilometerclient.v2 import client
import mock
from congress.datasources import ceilometer_driver
from congress.tests import base
from congress.tests.datasources import util
from congress.tests import helper
ResponseObj = util.ResponseObj
class TestCeilometerDriver(base.TestCase):
def setUp(self):
super(TestCeilometerDriver, self).setUp()
self.ceilometer_client = mock.MagicMock()
args = helper.datasource_openstack_args()
args['poll_time'] = 0
with mock.patch.object(client.Client, '__init__',
return_value=None):
self.driver = ceilometer_driver.CeilometerDriver(
name='testceilometer',
args=args)
def test_list_meters(self):
meters_data = [
ResponseObj({'name': 'instance:m1.tiny',
'type': 'gauge',
'unit': 'instance',
'resource_id': 'a257ba13-0b36-4a86-ae89-f78dd28b8ae5',
'user_id': '2b01323fd71345bc8cdc5dbbd6d127ea',
'project_id': '0020df0171ec41b597cd8b3002e21bee',
'meter_id': 'YTI1N2JhMTMtMGIzNi00YTg2LWFlODktZjc4ZG',
'source': 'openstack'}),
ResponseObj({'name': 'network.incoming.bytes',
'type': 'cumulative',
'unit': 'B',
'resource_id': 'instance-00000001-tap437ce69c-e5',
'user_id': '2b01323fd71345bc8cdc5dbbd6d127ea',
'project_id': '0020df0171ec41b597cd8b3002e21bee',
'meter_id': 'aW5zdGFuY2UtMDAwMDAwMDEtYTI1N2JhMT',
'source': 'openstack'})]
self.driver._translate_meters(meters_data)
meter_list = list(self.driver.state['meters'])
self.assertIsNotNone(meter_list)
self.assertEqual(2, len(meter_list))
for meter in meter_list:
if meter[1] == 'network.incoming.bytes':
meter1 = meter
elif meter[1] == 'instance:m1.tiny':
meter2 = meter
# Verifying individual tuple data
self.assertEqual(('aW5zdGFuY2UtMDAwMDAwMDEtYTI1N2JhMT',
'network.incoming.bytes',
'cumulative',
'B',
'openstack',
'instance-00000001-tap437ce69c-e5',
'2b01323fd71345bc8cdc5dbbd6d127ea',
'0020df0171ec41b597cd8b3002e21bee'),
meter1)
self.assertEqual(('YTI1N2JhMTMtMGIzNi00YTg2LWFlODktZjc4ZG',
'instance:m1.tiny',
'gauge',
'instance',
'openstack',
'a257ba13-0b36-4a86-ae89-f78dd28b8ae5',
'2b01323fd71345bc8cdc5dbbd6d127ea',
'0020df0171ec41b597cd8b3002e21bee'),
meter2)
def test_list_alarms(self):
threshold_rule1 = {'key1': 'value1',
'key2': 'value2',
'key3': 'value3'}
threshold_rule2 = {'key4': 'value4',
'key5': 'value5',
'key6': 'value6'}
alarms_data = [
ResponseObj({'alarm_id': '7ef99553-a73f-4b18-a617-997a479c48e9',
'name': 'cpu_high2',
'state': 'insufficient data',
'enabled': 'True',
'threshold_rule': threshold_rule1,
'type': 'threshold',
'description': 'instance running hot',
'time_constraints': '[]',
'user_id': '2b01323fd71345bc8cdc5dbbd6d127ea',
'project_id': '',
'alarm_actions': "[u'log://']",
'ok_actions': '[]',
'insufficient_data_actions': '[]',
'repeat_actions': 'False',
'timestamp': '2014-09-30T05:00:43.351041',
'state_timestamp': '2014-09-30T05:00:43.351041'}),
ResponseObj({'alarm_id': 'd1b2b7a7-9512-4290-97ca-2580ed72c375',
'name': 'cpu_high',
'state': 'insufficient data',
'enabled': 'True',
'threshold_rule': threshold_rule2,
'type': 'threshold',
'description': 'instance running hot',
'time_constraints': '[]',
'user_id': '2b01323fd71345bc8cdc5dbbd6d127ea',
'project_id': '',
'alarm_actions': "[u'log://']",
'ok_actions': '[]',
'insufficient_data_actions': '[]',
'repeat_actions': 'False',
'timestamp': '2014-09-30T04:55:36.015925',
'state_timestamp': '2014-09-30T04:55:36.015925'})]
self.driver._translate_alarms(alarms_data)
alarm_list = list(self.driver.state['alarms'])
self.assertIsNotNone(alarm_list)
self.assertEqual(2, len(alarm_list))
alarm_threshold_rule = list(self.driver.state['alarms.threshold_rule'])
self.assertIsNotNone(alarm_threshold_rule)
self.assertEqual(6, len(alarm_threshold_rule))
for alarm in alarm_list:
if alarm[1] == 'cpu_high2':
alarm1 = alarm
elif alarm[1] == 'cpu_high':
alarm2 = alarm
for thres in alarm_threshold_rule:
if thres[1] in ['key1', 'key2', 'key3']:
thresh_rule_id1 = thres[0]
elif thres[1] in ['key4', 'key5', 'key6']:
thresh_rule_id2 = thres[0]
# Verifying individual tuple data
self.assertEqual(('7ef99553-a73f-4b18-a617-997a479c48e9',
'cpu_high2', 'insufficient data',
'True',
thresh_rule_id1,
'threshold', 'instance running hot',
'[]', '2b01323fd71345bc8cdc5dbbd6d127ea',
'', "[u'log://']", '[]', '[]', 'False',
'2014-09-30T05:00:43.351041',
'2014-09-30T05:00:43.351041'),
alarm1)
self.assertEqual(('d1b2b7a7-9512-4290-97ca-2580ed72c375',
'cpu_high', 'insufficient data', 'True',
thresh_rule_id2,
'threshold', 'instance running hot',
'[]', '2b01323fd71345bc8cdc5dbbd6d127ea',
'', "[u'log://']", '[]', '[]',
'False', '2014-09-30T04:55:36.015925',
'2014-09-30T04:55:36.015925'),
alarm2)
def test_list_events(self):
trait1 = [{'name': 'value1', 'type': 'value2', 'value': 'value3'},
{'name': 'value7', 'type': 'value8', 'value': 'value9'}]
trait2 = [{'name': 'value4', 'type': 'value5', 'value': 'value6'}]
trait3 = []
events_data = [
ResponseObj({'message_id': '6834861c-ccb3-4c6f-ac00-fe8fe1ad4ed4',
'event_type': 'image.create',
'generated': '2014-09-29T08:19:45.556301',
'traits': trait1}),
ResponseObj({'message_id': '3676d6d4-5c65-4442-9eda-b78d750ea91f',
'event_type': 'compute.instance.update',
'generated': '2014-09-30T04:54:45.395522',
'traits': trait2}),
ResponseObj({'message_id': 'fae7b03d-b5b7-4b4f-b2ef-06d2af03f21e',
'event_type': 'telemetry.api',
'generated': '2015-09-02T10:12:50.338919',
'traits': trait3})]
self.driver._translate_events(events_data)
events_set = self.driver.state['events']
expected_events = {('6834861c-ccb3-4c6f-ac00-fe8fe1ad4ed4',
'image.create', '2014-09-29T08:19:45.556301'),
('3676d6d4-5c65-4442-9eda-b78d750ea91f',
'compute.instance.update',
'2014-09-30T04:54:45.395522'),
('fae7b03d-b5b7-4b4f-b2ef-06d2af03f21e',
'telemetry.api', '2015-09-02T10:12:50.338919')}
self.assertEqual(expected_events, events_set)
event_traits_set = self.driver.state['events.traits']
expected_traits = {('6834861c-ccb3-4c6f-ac00-fe8fe1ad4ed4',
'value1', 'value2', 'value3'),
('6834861c-ccb3-4c6f-ac00-fe8fe1ad4ed4',
'value7', 'value8', 'value9'),
('3676d6d4-5c65-4442-9eda-b78d750ea91f',
'value4', 'value5', 'value6')}
self.assertEqual(expected_traits, event_traits_set)
def test_list_statistics(self):
statistics_data = [
{'meter_name': 'network',
'period': 0, 'groupby':
{'resource_id': '2fdef98a-8a00-4094-b6b8-b3f742076417'},
'period_start': '2014-12-09T12:52:39.366015',
'period_end': '2014-12-09T12:52:56.478338',
'max': 0.0, 'min': 0.0, 'avg': 0.0, 'sum': 0.0,
'count': 10, 'duration': 17.112323, 'unit': 'GB',
'duration_start': '2014-12-09T12:52:39.366015',
'duration_end': '2014-12-09T12:52:56.478338'},
{'meter_name': 'instance',
'period': 0, 'groupby':
{'resource_id': '8a1340fa-fd43-4376-9deb-37c872c47e38'},
'period_start': '2014-12-09T12:52:39.366015',
'period_end': '2014-12-09T13:04:34',
'max': 1.0, 'min': 1.0, 'avg': 1.0, 'sum': 13.0,
'count': 13, 'duration': 714.633985,
'unit': 'instance',
'duration_start': '2014-12-09T12:52:39.366015',
'duration_end': '2014-12-09T13:04:34'}]
self.driver._translate_statistics(statistics_data)
statistics_list = list(self.driver.state['statistics'])
self.assertIsNotNone(statistics_list)
self.assertEqual(2, len(statistics_list))
# Verifying individual tuple data
s1 = next(x for x in statistics_list if x[0] == 'network')
s2 = next(x for x in statistics_list if x[0] == 'instance')
self.assertEqual(('network',
'2fdef98a-8a00-4094-b6b8-b3f742076417',
0.0, 10, 17.112323,
'2014-12-09T12:52:39.366015',
'2014-12-09T12:52:56.478338',
0.0, 0.0, 0,
'2014-12-09T12:52:56.478338',
'2014-12-09T12:52:39.366015',
0.0, 'GB'), s1)
self.assertEqual(('instance',
'8a1340fa-fd43-4376-9deb-37c872c47e38',
1.0, 13, 714.633985,
'2014-12-09T12:52:39.366015',
'2014-12-09T13:04:34',
1.0, 1.0, 0,
'2014-12-09T13:04:34',
'2014-12-09T12:52:39.366015',
13.0, 'instance'), s2)
def test_execute(self):
class CeilometerClient(object):
def __init__(self):
self.testkey = None
def setAlarm(self, arg1):
self.testkey = 'arg1=%s' % arg1
ceilometer_client = CeilometerClient()
self.driver.ceilometer_client = ceilometer_client
api_args = {
'positional': ['1']
}
expected_ans = 'arg1=1'
self.driver.execute('setAlarm', api_args)
self.assertEqual(ceilometer_client.testkey, expected_ans)

View File

@ -1,85 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# 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.
from tempest import config
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from tempest.lib import exceptions
from congress_tempest_tests.tests.scenario import manager_congress
CONF = config.CONF
class TestCeilometerDriver(manager_congress.ScenarioPolicyBase):
@classmethod
def skip_checks(cls):
super(TestCeilometerDriver, cls).skip_checks()
if not getattr(CONF.service_available, 'ceilometer', False):
msg = ("%s skipped as ceilometer is not available" %
cls.__class__.__name__)
raise cls.skipException(msg)
def setUp(self):
super(TestCeilometerDriver, self).setUp()
self.telemetry_client = self.os_admin.telemetry_client
self.datasource_id = manager_congress.get_datasource_id(
self.os_admin.congress_client, 'ceilometer')
@decorators.attr(type='smoke')
def test_ceilometer_meters_table(self):
meter_schema = (
self.os_admin.congress_client.show_datasource_table_schema(
self.datasource_id, 'meters')['columns'])
meter_id_col = next(i for i, c in enumerate(meter_schema)
if c['name'] == 'meter_id')
def _check_data_table_ceilometer_meters():
# Fetch data from ceilometer each time, because this test may start
# before ceilometer has all the users.
meters = self.telemetry_client.list_meters()
meter_map = {}
for meter in meters:
meter_map[meter['meter_id']] = meter
results = (
self.os_admin.congress_client.list_datasource_rows(
self.datasource_id, 'meters'))
for row in results['results']:
try:
meter_row = meter_map[row['data'][meter_id_col]]
except KeyError:
return False
for index in range(len(meter_schema)):
if (str(row['data'][index]) !=
str(meter_row[meter_schema[index]['name']])):
return False
return True
if not test_utils.call_until_true(
func=_check_data_table_ceilometer_meters,
duration=100, sleep_for=5):
raise exceptions.TimeoutException("Data did not converge in time "
"or failure in server")
@decorators.attr(type='smoke')
def test_update_no_error(self):
if not test_utils.call_until_true(
func=lambda: self.check_datasource_no_error('ceilometer'),
duration=30, sleep_for=5):
raise exceptions.TimeoutException('Datasource could not poll '
'without error.')

View File

@ -75,7 +75,6 @@ function configure_congress {
CONGRESS_DRIVERS+="congress.datasources.glancev2_driver.GlanceV2Driver,"
CONGRESS_DRIVERS+="congress.datasources.nova_driver.NovaDriver,"
CONGRESS_DRIVERS+="congress.datasources.keystonev3_driver.KeystoneV3Driver,"
CONGRESS_DRIVERS+="congress.datasources.ceilometer_driver.CeilometerDriver,"
CONGRESS_DRIVERS+="congress.datasources.cinder_driver.CinderDriver,"
CONGRESS_DRIVERS+="congress.datasources.swift_driver.SwiftDriver,"
CONGRESS_DRIVERS+="congress.datasources.plexxi_driver.PlexxiDriver,"
@ -100,7 +99,6 @@ function configure_congress_datasources {
_configure_service neutron neutronv2_qos
_configure_service nova nova
_configure_service key keystonev3
_configure_service ceilometer ceilometer
_configure_service cinder cinder
_configure_service swift swift
_configure_service glance glancev2

View File

@ -121,7 +121,7 @@ Add drivers:
.. code-block:: text
drivers = congress.datasources.neutronv2_driver.NeutronV2Driver,congress.datasources.glancev2_driver.GlanceV2Driver,congress.datasources.nova_driver.NovaDriver,congress.datasources.keystone_driver.KeystoneDriver,congress.datasources.ceilometer_driver.CeilometerDriver,congress.datasources.cinder_driver.CinderDriver,congress.datasources.swift_driver.SwiftDriver,congress.datasources.plexxi_driver.PlexxiDriver,congress.datasources.vCenter_driver.VCenterDriver,congress.datasources.murano_driver.MuranoDriver,congress.datasources.ironic_driver.IronicDriver
drivers = congress.datasources.neutronv2_driver.NeutronV2Driver,congress.datasources.glancev2_driver.GlanceV2Driver,congress.datasources.nova_driver.NovaDriver,congress.datasources.keystone_driver.KeystoneDriver,congress.datasources.cinder_driver.CinderDriver,congress.datasources.swift_driver.SwiftDriver,congress.datasources.plexxi_driver.PlexxiDriver,congress.datasources.vCenter_driver.VCenterDriver,congress.datasources.murano_driver.MuranoDriver,congress.datasources.ironic_driver.IronicDriver
The default auth_strategy is keystone. To set Congress to use no authorization strategy:

View File

@ -1,19 +0,0 @@
---
name: ServerUtilization
description: "Rules related to server utilization. For example, identifying underutilized servers."
rules:
-
comment: >
Identify all virtual machines whose CPU utilization averages less than 10%.
Affectionately called, the "deadbeat detector", this policy helps operators understand
whether a request for increased quota is warranted or not.
rule: >
underutilized_servers(server_id) :-
ceilometer:statistics(meter_name='cpu_util',resource_id=server_id, avg=avg),
builtin:lt(avg, 10)
-
comment: "User should customize this. Permitted flavors."
rule: >
warning(server_id, server_name, user_id) :-
underutilized_servers(server_id),
nova:servers(id=server_id, name=server_name, user_id=user_id)

View File

@ -0,0 +1,6 @@
---
deprecations:
- |
Ceilometer datasource is no longer supported in congress as the ceilometer API
has been deprecated in Ocata and removed in Queens release. So, congress
no longer supports retreiving data from ceilometer.