├── .coveragerc ├── .gitignore ├── .gitreview ├── .mailmap ├── .stestr.conf ├── .zuul.yaml ├── CONTRIBUTING.rst ├── HACKING.rst ├── LICENSE ├── MAINTAINERS ├── README.rst ├── aodh ├── __init__.py ├── api │ ├── __init__.py │ ├── api-paste.ini │ ├── app.py │ ├── app.wsgi │ ├── controllers │ │ ├── __init__.py │ │ ├── root.py │ │ └── v2 │ │ │ ├── __init__.py │ │ │ ├── alarm_rules │ │ │ ├── __init__.py │ │ │ ├── composite.py │ │ │ ├── event.py │ │ │ ├── gnocchi.py │ │ │ ├── loadbalancer.py │ │ │ └── prometheus.py │ │ │ ├── alarms.py │ │ │ ├── base.py │ │ │ ├── capabilities.py │ │ │ ├── metrics.py │ │ │ ├── query.py │ │ │ ├── quotas.py │ │ │ ├── root.py │ │ │ └── utils.py │ ├── hooks.py │ ├── middleware.py │ ├── policies.py │ └── rbac.py ├── cmd │ ├── __init__.py │ ├── alarm.py │ ├── aodh-config-generator.conf │ ├── aodh-policy-generator.conf │ ├── status.py │ └── storage.py ├── conf │ ├── __init__.py │ └── defaults.py ├── coordination.py ├── evaluator │ ├── __init__.py │ ├── composite.py │ ├── event.py │ ├── gnocchi.py │ ├── loadbalancer.py │ ├── prometheus.py │ ├── threshold.py │ └── utils.py ├── event.py ├── i18n.py ├── keystone_client.py ├── locale │ ├── de │ │ └── LC_MESSAGES │ │ │ └── aodh.po │ ├── en_GB │ │ └── LC_MESSAGES │ │ │ └── aodh.po │ ├── es │ │ └── LC_MESSAGES │ │ │ └── aodh.po │ ├── fr │ │ └── LC_MESSAGES │ │ │ └── aodh.po │ ├── it │ │ └── LC_MESSAGES │ │ │ └── aodh.po │ ├── ja │ │ └── LC_MESSAGES │ │ │ └── aodh.po │ ├── ko_KR │ │ └── LC_MESSAGES │ │ │ └── aodh.po │ ├── pt │ │ └── LC_MESSAGES │ │ │ └── aodh.po │ ├── pt_BR │ │ └── LC_MESSAGES │ │ │ └── aodh.po │ ├── ru │ │ └── LC_MESSAGES │ │ │ └── aodh.po │ ├── zh_CN │ │ └── LC_MESSAGES │ │ │ └── aodh.po │ └── zh_TW │ │ └── LC_MESSAGES │ │ └── aodh.po ├── messaging.py ├── notifier │ ├── __init__.py │ ├── heat.py │ ├── log.py │ ├── rest.py │ ├── test.py │ ├── trust.py │ └── zaqar.py ├── opts.py ├── profiler.py ├── queue.py ├── service.py ├── storage │ ├── __init__.py │ ├── base.py │ ├── impl_log.py │ ├── impl_sqlalchemy.py │ ├── models.py │ └── sqlalchemy │ │ ├── __init__.py │ │ ├── alembic │ │ ├── alembic.ini │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── 006_add_evaluate_timestamp_to_alarm.py │ │ │ ├── 007_add_quota_table.py │ │ │ ├── 008_added_counter_table.py │ │ │ ├── 12fe8fac9fe4_initial_base.py │ │ │ ├── 367aadf5485f_precisetimestamp_to_datetime.py │ │ │ ├── 6ae0d05d9451_add_reason_column.py │ │ │ ├── bb07adac380_add_severity_to_alarm_history.py │ │ │ └── f8c31b1ffe11_add_index_for_enabled_and_type.py │ │ ├── models.py │ │ └── utils.py ├── tests │ ├── __init__.py │ ├── base.py │ ├── constants.py │ ├── functional │ │ ├── __init__.py │ │ ├── api │ │ │ ├── __init__.py │ │ │ └── v2 │ │ │ │ ├── __init__.py │ │ │ │ ├── policy.yaml-test │ │ │ │ ├── test_alarm_scenarios.py │ │ │ │ ├── test_app.py │ │ │ │ ├── test_complex_query.py │ │ │ │ ├── test_complex_query_scenarios.py │ │ │ │ ├── test_metrics.py │ │ │ │ └── test_quotas.py │ │ ├── db.py │ │ ├── hooks │ │ │ └── post_test_hook.sh │ │ └── storage │ │ │ ├── __init__.py │ │ │ ├── sqlalchemy │ │ │ ├── __init__.py │ │ │ └── test_migrations.py │ │ │ ├── test_get_connection.py │ │ │ ├── test_impl_log.py │ │ │ ├── test_impl_sqlalchemy.py │ │ │ └── test_storage_scenarios.py │ └── unit │ │ ├── __init__.py │ │ ├── cmd │ │ ├── __init__.py │ │ └── test_status.py │ │ ├── evaluator │ │ ├── __init__.py │ │ ├── base.py │ │ ├── test_base.py │ │ ├── test_composite.py │ │ ├── test_event.py │ │ ├── test_gnocchi.py │ │ └── test_loadbalancer.py │ │ ├── notifier │ │ ├── __init__.py │ │ ├── base.py │ │ └── test_heat.py │ │ ├── test_api_v2_capabilities.py │ │ ├── test_bin.py │ │ ├── test_coordination.py │ │ ├── test_evaluator.py │ │ ├── test_event.py │ │ ├── test_messaging.py │ │ ├── test_notifier.py │ │ ├── test_query.py │ │ └── test_wsme_custom_type.py ├── utils.py ├── version.py └── wsgi │ ├── __init__.py │ └── api.py ├── bindep.txt ├── devstack ├── README.rst ├── plugin.sh └── settings ├── doc ├── Makefile ├── requirements.txt └── source │ ├── _static │ └── .placeholder │ ├── admin │ ├── index.rst │ ├── resource-quota.rst │ └── telemetry-alarms.rst │ ├── cli │ ├── aodh-status.rst │ └── index.rst │ ├── conf.py │ ├── configuration │ ├── aodh-config-file.rst │ ├── aodh-config-options.rst │ ├── index.rst │ ├── policy.rst │ └── sample-policy-yaml.rst │ ├── contributor │ ├── architecture.rst │ ├── contributing.rst │ ├── event-alarm.rst │ ├── gmr.rst │ ├── index.rst │ ├── install │ │ ├── development.rst │ │ ├── index.rst │ │ ├── manual.rst │ │ ├── mod_wsgi.rst │ │ └── uwsgi.rst │ ├── releasenotes │ │ └── index.rst │ ├── testing.rst │ └── webapi │ │ ├── index.rst │ │ └── v2.rst │ ├── glossary.rst │ ├── index.rst │ └── install │ ├── configure-common.rst │ ├── get_started.rst │ ├── index.rst │ ├── install-obs.rst │ ├── install-rdo.rst │ ├── install-ubuntu.rst │ ├── next-steps.rst │ ├── prereq-common.rst │ └── verify.rst ├── rally-jobs ├── README.rst ├── ceilometer.yaml ├── extra │ ├── README.rst │ └── fake.img └── plugins │ ├── README.rst │ └── plugin_sample.py ├── releasenotes ├── notes │ ├── .placeholder │ ├── Add-state-reason-to-the-API-7bc5a9465466db2b.yaml │ ├── add-a-data-migration-tool-daa14b0cb5d4cc62.yaml │ ├── add-metrics-endpoint-and-evaluation-counter-collection-f324ebda00fa5c6c.yaml │ ├── add-upgrade-check-framework-ab35e6eb65504bc3.yaml │ ├── auto-healing-notifier-794b64de776811e9.yaml │ ├── bug-1929178-46493335946174a5.yaml │ ├── bug1540395-reason-string-0aad56966007d0e3.yaml │ ├── composite-alarm-1b1ca9ea0e8f55c8.yaml │ ├── deprecate-combination-alarms-7ff26b73b61a0e59.yaml │ ├── deprecate-json-formatted-policy-file-fgb26387a9bdb3b9.yaml │ ├── deprecate-nosql-backends-13079883eec7e8e5.yaml │ ├── deprecate-threshold-alarm-d89da351d4f6f50f.yaml │ ├── deprecate-unused-http_timeout-74fd60a4c26afd88.yaml │ ├── drop-py-2-7-54a9be4bfb8e9172.yaml │ ├── drop-python-3-6-and-3-7-89f2b7300c0166ca.yaml │ ├── drop-python-3-8-24f35246e92cf9af.yaml │ ├── enable-aodh-service-multi-processes-67ed9a0b7fac69aa.yaml │ ├── event-listener-batch-support-04e6ff159ef34d8c.yaml │ ├── fix-ceilometerclient-init-8bc7a6742937c3e2.yaml │ ├── fix-combination-alarms-8097adf08b837a50.yaml │ ├── fix-empty-statistics-3852da99b1c0b297.yaml │ ├── fix-gnocchi-aggregation-eval-7c2c1c67bdf2d11c.yaml │ ├── fix-prometheus-alarm-rbac-6ee2f0abbd060184.yaml │ ├── fix-rbac-50825144e0897d7d.yaml │ ├── fix-ssl-request-8107616b6a85a217.yaml │ ├── get-quotas-policy-b0338f314ec06ae9.yaml │ ├── gmr-3dd0a582af010bd4.yaml │ ├── gnocchi-capability-cache-75d011e77b8ecc72.yaml │ ├── gnocchi-client-a62ca5a0c717807e.yaml │ ├── gnocchi-external-resource-owner-3fad253d30746b0d.yaml │ ├── healthcheck-560700b72ae68e18.yaml │ ├── heartbeat_interval-d46e0f5efbd56264.yaml │ ├── ingestion-lag-2317725887287fbc.yaml │ ├── keystone-v3-support-ffc0f804dbe9d7e9.yaml │ ├── load-api-paste-ini-from-config-dirs-69480861a9633df4.yaml │ ├── loadbalancer-evaluator-85732c5e5f6e11e9.yaml │ ├── migrate-evaluation_interval-c65ba5cbe5fabb35.yaml │ ├── mysql-precise-datetime-e374c77e6707985e.yaml │ ├── notifier-batch-listener-01796e2cb06344dd.yaml │ ├── partition-coordinator-improvement-ff1c257f69f120ac.yaml │ ├── pecan-debug-removed-7c7a528a1aea98bf.yaml │ ├── policy-defaults-refresh-95b565bee059f611.yaml │ ├── policy-in-code-79edd9282f1e4603.yaml │ ├── queue-communication-1b884feab4078dde.yaml │ ├── remove-alarm-name-unique-constraint-4fb0b14f3ad46f0b.yaml │ ├── remove-check_watchers-df14cecc258a3510.yaml │ ├── remove-combination-alarms-a1a53655f3f7d1d1.yaml │ ├── remove-eventlet-18ada1cff213af5e.yaml │ ├── remove-no-sql-drivers-21dfdbd750751340.yaml │ ├── remove-threshold-alarm-a7901991d2da09f2.yaml │ ├── support-batch-delete-events-32496f15b1169887.yaml │ ├── support-combination-to-composite-conversion-3e688a6b7d01a57e.yaml │ ├── ussuri-support-builtin-active-active-aodh-evaluator-a935577e17a211ea.yaml │ ├── ussuri-support-query-all-projects-alarms-by-admin-3ecccf2217d711ea.yaml │ └── ussuri-support-quota-api-92f2fd0643d311ea.yaml └── source │ ├── 2023.1.rst │ ├── 2023.2.rst │ ├── 2024.1.rst │ ├── 2024.2.rst │ ├── 2025.1.rst │ ├── _static │ └── .placeholder │ ├── conf.py │ ├── index.rst │ ├── liberty.rst │ ├── locale │ ├── de │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ ├── en_GB │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ ├── fr │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ ├── ja │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ ├── ko_KR │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ └── pt_BR │ │ └── LC_MESSAGES │ │ └── releasenotes.po │ ├── mitaka.rst │ ├── newton.rst │ ├── ocata.rst │ ├── pike.rst │ ├── queens.rst │ ├── rocky.rst │ ├── stein.rst │ ├── train.rst │ ├── unreleased.rst │ ├── ussuri.rst │ ├── victoria.rst │ ├── wallaby.rst │ ├── xena.rst │ ├── yoga.rst │ └── zed.rst ├── requirements.txt ├── setup.cfg ├── setup.py ├── test-requirements.txt └── tox.ini /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch = True 3 | source = aodh 4 | omit = aodh/tests/* 5 | 6 | [report] 7 | ignore_errors = True 8 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.egg* 2 | *.mo 3 | *.pyc 4 | *~ 5 | .*.swp 6 | .*sw? 7 | .coverage 8 | .stestr 9 | .tox 10 | AUTHORS 11 | build/* 12 | ChangeLog 13 | cover/* 14 | dist/* 15 | doc/build 16 | etc/aodh/aodh.conf 17 | subunit.log 18 | 19 | # Files created by releasenotes build 20 | releasenotes/build 21 | /doc/source/contributor/api/ 22 | doc/source/_static/aodh.policy.yaml.sample 23 | doc/source/_static/aodh.conf.sample 24 | 25 | .vscode/ 26 | -------------------------------------------------------------------------------- /.gitreview: -------------------------------------------------------------------------------- 1 | [gerrit] 2 | host=review.opendev.org 3 | port=29418 4 | project=openstack/aodh.git 5 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | # Format is: 2 | # 3 | # 4 | Adam Gandelman 5 | Alan Pevec 6 | Alexei Kornienko 7 | ChangBo Guo(gcb) Chang Bo Guo 8 | Chinmaya Bharadwaj chinmay 9 | Clark Boylan 10 | Doug Hellmann 11 | Fei Long Wang 12 | Fengqian Gao Fengqian 13 | Fengqian Gao Fengqian.Gao 14 | Gordon Chung gordon chung 15 | Gordon Chung Gordon Chung 16 | Gordon Chung gordon chung 17 | Ildiko Vancsa Ildiko 18 | John H. Tran John Tran 19 | Julien Danjou 20 | LiuSheng liu-sheng 21 | Mehdi Abaakouk 22 | Nejc Saje 23 | Nejc Saje 24 | Nicolas Barcet (nijaba) 25 | Pádraig Brady 26 | Rich Bowen 27 | Sandy Walsh 28 | Sascha Peilicke 29 | Sean Dague 30 | Shengjie Min shengjie-min 31 | Shuangtai Tian shuangtai 32 | Swann Croiset 33 | ZhiQiang Fan 34 | -------------------------------------------------------------------------------- /.stestr.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | test_path=${OS_TEST_PATH:-./aodh/tests/unit} 3 | top_dir=./ 4 | # The group_regex describes how stestr will group tests into the same process 5 | # when running concurently. The following ensures that gabbi tests coming from 6 | # the same YAML file are all in the same process. This is important because 7 | # each YAML file represents an ordered sequence of HTTP requests. Note that 8 | # tests which do not match this regex will not be grouped in any special way. 9 | # See the following for more details. 10 | # http://stestr.readthedocs.io/en/latest/MANUAL.html#grouping-tests 11 | # https://gabbi.readthedocs.io/en/latest/#purpose 12 | group_regex=(gabbi\.(suitemaker|driver)\.test_gabbi_([^_]+))_ 13 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | If you would like to contribute to the development of OpenStack, 2 | you must follow the steps documented at: 3 | 4 | https://docs.openstack.org/infra/manual/developers.html#development-workflow 5 | 6 | Once those steps have been completed, changes to OpenStack 7 | should be submitted for review via the Gerrit tool, following 8 | the workflow documented at: 9 | 10 | https://docs.openstack.org/infra/manual/developers.html#development-workflow 11 | 12 | Pull requests submitted through GitHub will be ignored. 13 | 14 | Bugs should be filed on Launchpad, not GitHub: 15 | 16 | https://bugs.launchpad.net/aodh 17 | -------------------------------------------------------------------------------- /HACKING.rst: -------------------------------------------------------------------------------- 1 | Aodh Style Commandments 2 | ======================= 3 | 4 | - Step 1: Read the OpenStack Style Commandments 5 | https://docs.openstack.org/hacking/latest/ 6 | - Step 2: Read on 7 | 8 | Aodh Specific Commandments 9 | -------------------------- 10 | -------------------------------------------------------------------------------- /MAINTAINERS: -------------------------------------------------------------------------------- 1 | = Generalist Code Reviewers = 2 | 3 | The current members of aodh-core are listed here: 4 | 5 | https://launchpad.net/~aodh-drivers/+members#active 6 | 7 | This group can +2 and approve patches in aodh. However, they may 8 | choose to seek feedback from the appropriate specialist maintainer before 9 | approving a patch if it is in any way controversial or risky. 10 | 11 | = IRC handles of maintainers = 12 | gordc 13 | jd_ 14 | sileht 15 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | aodh 2 | ==== 3 | 4 | Aodh is the alarming service for OpenStack. 5 | 6 | ------------- 7 | Documentation 8 | ------------- 9 | 10 | Documentation for the project can be found at: 11 | https://docs.openstack.org/aodh/latest/ 12 | 13 | Release notes can be read online at: 14 | https://docs.openstack.org/aodh/latest/contributor/releasenotes/index.html 15 | 16 | 17 | Code Repository 18 | --------------- 19 | 20 | - Server: https://opendev.org/openstack/aodh/ 21 | 22 | Bug Tracking 23 | ------------ 24 | 25 | Bugs and feature requests are tracked on Launchpad at: 26 | https://bugs.launchpad.net/aodh/ 27 | 28 | IRC 29 | --- 30 | 31 | IRC Channel: #openstack-telemetry on `OFTC`_. 32 | 33 | .. _OFTC: https://oftc.net/ 34 | -------------------------------------------------------------------------------- /aodh/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 eNovance 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | 16 | class NotImplementedError(NotImplementedError): 17 | # FIXME(jd) This is used by WSME to return a correct HTTP code. We should 18 | # not expose it here but wrap our methods in the API to convert it to a 19 | # proper HTTP error. 20 | code = 501 21 | -------------------------------------------------------------------------------- /aodh/api/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012 New Dream Network, LLC (DreamHost) 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | from oslo_config import cfg 16 | 17 | # Register options for the service 18 | OPTS = [ 19 | cfg.StrOpt('paste_config', 20 | default='api-paste.ini', 21 | help="Configuration file for WSGI definition of API."), 22 | cfg.StrOpt( 23 | 'auth_mode', 24 | default="keystone", 25 | help="Authentication mode to use. Unset to disable authentication"), 26 | ] 27 | -------------------------------------------------------------------------------- /aodh/api/api-paste.ini: -------------------------------------------------------------------------------- 1 | [composite:aodh+noauth] 2 | use = egg:Paste#urlmap 3 | / = aodhversions_pipeline 4 | /v2 = aodhv2_noauth_pipeline 5 | /healthcheck = healthcheck 6 | 7 | [composite:aodh+keystone] 8 | use = egg:Paste#urlmap 9 | / = aodhversions_pipeline 10 | /v2 = aodhv2_keystone_pipeline 11 | /healthcheck = healthcheck 12 | 13 | [app:healthcheck] 14 | use = egg:oslo.middleware#healthcheck 15 | oslo_config_project = aodh 16 | 17 | [pipeline:aodhversions_pipeline] 18 | pipeline = cors http_proxy_to_wsgi aodhversions 19 | 20 | [app:aodhversions] 21 | paste.app_factory = aodh.api.app:app_factory 22 | root = aodh.api.controllers.root.VersionsController 23 | 24 | [pipeline:aodhv2_keystone_pipeline] 25 | pipeline = cors http_proxy_to_wsgi request_id osprofiler authtoken aodhv2 26 | 27 | [pipeline:aodhv2_noauth_pipeline] 28 | pipeline = cors http_proxy_to_wsgi request_id osprofiler aodhv2 29 | 30 | [app:aodhv2] 31 | paste.app_factory = aodh.api.app:app_factory 32 | root = aodh.api.controllers.v2.root.V2Controller 33 | 34 | [filter:authtoken] 35 | paste.filter_factory = keystonemiddleware.auth_token:filter_factory 36 | oslo_config_project = aodh 37 | 38 | [filter:request_id] 39 | paste.filter_factory = oslo_middleware:RequestId.factory 40 | 41 | [filter:cors] 42 | paste.filter_factory = oslo_middleware.cors:filter_factory 43 | oslo_config_project = aodh 44 | 45 | [filter:http_proxy_to_wsgi] 46 | paste.filter_factory = oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory 47 | oslo_config_project = aodh 48 | 49 | [filter:osprofiler] 50 | paste.filter_factory = aodh.profiler:WsgiMiddleware.factory 51 | oslo_config_project = aodh 52 | -------------------------------------------------------------------------------- /aodh/api/app.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012 New Dream Network, LLC (DreamHost) 3 | # Copyright 2015-2016 Red Hat, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | import os 18 | import uuid 19 | 20 | from oslo_log import log 21 | from paste import deploy 22 | import pecan 23 | 24 | from aodh.api import hooks 25 | from aodh.api import middleware 26 | from aodh import service 27 | from aodh import storage 28 | 29 | LOG = log.getLogger(__name__) 30 | 31 | 32 | # NOTE(sileht): pastedeploy uses ConfigParser to handle 33 | # global_conf, since python 3 ConfigParser doesn't 34 | # allow storing object as config value, only strings are 35 | # permit, so to be able to pass an object created before paste load 36 | # the app, we store them into a global var. But the each loaded app 37 | # store it's configuration in unique key to be concurrency safe. 38 | global APPCONFIGS 39 | APPCONFIGS = {} 40 | 41 | 42 | def setup_app(root, conf): 43 | app_hooks = [hooks.ConfigHook(conf), 44 | hooks.DBHook( 45 | storage.get_connection_from_config(conf)), 46 | hooks.TranslationHook()] 47 | return pecan.make_app( 48 | root, 49 | hooks=app_hooks, 50 | wrap_app=middleware.ParsableErrorMiddleware, 51 | guess_content_type_from_ext=False 52 | ) 53 | 54 | 55 | def load_app(conf): 56 | global APPCONFIGS 57 | 58 | # Build the WSGI app 59 | cfg_path = conf.api.paste_config 60 | if not os.path.isabs(cfg_path): 61 | cfg_path = conf.find_file(cfg_path) 62 | 63 | if cfg_path is None or not os.path.exists(cfg_path): 64 | LOG.debug("No api-paste configuration file found! Using default.") 65 | cfg_path = os.path.abspath( 66 | os.path.join( 67 | os.path.dirname(__file__), "api-paste.ini")) 68 | 69 | config = dict(conf=conf) 70 | configkey = str(uuid.uuid4()) 71 | APPCONFIGS[configkey] = config 72 | 73 | LOG.info("WSGI config used: %s", cfg_path) 74 | return deploy.loadapp("config:" + cfg_path, 75 | name="aodh+" + ( 76 | conf.api.auth_mode 77 | if conf.api.auth_mode else "noauth" 78 | ), 79 | global_conf={'configkey': configkey}) 80 | 81 | 82 | def app_factory(global_config, **local_conf): 83 | global APPCONFIGS 84 | appconfig = APPCONFIGS.get(global_config.get('configkey')) 85 | return setup_app(root=local_conf.get('root'), **appconfig) 86 | 87 | 88 | def build_wsgi_app(argv=None): 89 | conf = service.prepare_service(argv=argv) 90 | conf.log_opt_values(LOG, log.DEBUG) 91 | return load_app(conf) 92 | -------------------------------------------------------------------------------- /aodh/api/app.wsgi: -------------------------------------------------------------------------------- 1 | # -*- mode: python -*- 2 | # 3 | # Copyright 2013 New Dream Network, LLC (DreamHost) 4 | # Copyright 2015 Red Hat, Inc. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 7 | # not use this file except in compliance with the License. You may obtain 8 | # a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | # License for the specific language governing permissions and limitations 16 | # under the License. 17 | """Use this file for deploying the API under mod_wsgi. 18 | 19 | See http://pecan.readthedocs.org/en/latest/deployment.html for details. 20 | """ 21 | from aodh.api import app 22 | import warnings 23 | 24 | 25 | warnings.warn('Using app.wsgi is deprecated. Use aodh.wsgi.api instead') 26 | 27 | application = app.build_wsgi_app(argv=[]) 28 | -------------------------------------------------------------------------------- /aodh/api/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/api/controllers/__init__.py -------------------------------------------------------------------------------- /aodh/api/controllers/root.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012 New Dream Network, LLC (DreamHost) 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import pecan 17 | 18 | MEDIA_TYPE_JSON = 'application/vnd.openstack.telemetry-%s+json' 19 | MEDIA_TYPE_XML = 'application/vnd.openstack.telemetry-%s+xml' 20 | 21 | 22 | class VersionsController(object): 23 | 24 | @pecan.expose('json') 25 | def index(self): 26 | base_url = pecan.request.host_url 27 | available = [{'tag': 'v2', 'date': '2013-02-13T00:00:00Z', }] 28 | collected = [version_descriptor(base_url, v['tag'], v['date']) 29 | for v in available] 30 | versions = {'versions': {'values': collected}} 31 | return versions 32 | 33 | 34 | def version_descriptor(base_url, version, released_on): 35 | url = version_url(base_url, version) 36 | return { 37 | 'id': version, 38 | 'links': [ 39 | {'href': url, 'rel': 'self', }, 40 | {'href': 'https://docs.openstack.org/', 41 | 'rel': 'describedby', 'type': 'text/html', }], 42 | 'media-types': [ 43 | {'base': 'application/json', 'type': MEDIA_TYPE_JSON % version, }, 44 | {'base': 'application/xml', 'type': MEDIA_TYPE_XML % version, }], 45 | 'status': 'stable', 46 | 'updated': released_on, 47 | } 48 | 49 | 50 | def version_url(base_url, version_number): 51 | return '%s/%s' % (base_url, version_number) 52 | -------------------------------------------------------------------------------- /aodh/api/controllers/v2/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/api/controllers/v2/__init__.py -------------------------------------------------------------------------------- /aodh/api/controllers/v2/alarm_rules/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/api/controllers/v2/alarm_rules/__init__.py -------------------------------------------------------------------------------- /aodh/api/controllers/v2/alarm_rules/event.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015 NEC Corporation. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import voluptuous 17 | import wsme 18 | from wsme import types as wtypes 19 | 20 | from aodh.api.controllers.v2 import base 21 | from aodh.i18n import _ 22 | 23 | 24 | # Schema validation for the event type query. 25 | _q_validator = voluptuous.Schema( 26 | {"field": voluptuous.Match(r"^[a-zA-Z.',0-9_-]*$"), 27 | "op": voluptuous.In(base.operation_kind), 28 | "value": voluptuous.In(["string", "integer", "float", "boolean", ""])}) 29 | 30 | 31 | class AlarmEventRule(base.AlarmRule): 32 | """Alarm Event Rule. 33 | 34 | Describe when to trigger the alarm based on an event 35 | """ 36 | 37 | event_type = wsme.wsattr(wtypes.text) 38 | "The type of event (default is '*')" 39 | 40 | query = wsme.wsattr([base.Query]) 41 | "The query to find the event (default is [])" 42 | 43 | def __init__(self, event_type=None, query=None): 44 | event_type = event_type or '*' 45 | query = [base.Query(**q) for q in query or []] 46 | super(AlarmEventRule, self).__init__(event_type=event_type, 47 | query=query) 48 | 49 | @classmethod 50 | def validate_alarm(cls, alarm): 51 | super(AlarmEventRule, cls).validate_alarm(alarm) 52 | for i in alarm.event_rule.query: 53 | i.get_value() 54 | try: 55 | _q_validator({"field": i.field, "op": i.op, 56 | "value": i.type}) 57 | except voluptuous.MultipleInvalid as e: 58 | raise base.ClientSideError( 59 | _("Query value or traits invalid: %s") % str(e)) 60 | 61 | @property 62 | def default_description(self): 63 | return _('Alarm when %s event occurred.') % self.event_type 64 | 65 | def as_dict(self): 66 | rule = self.as_dict_from_keys(['event_type']) 67 | rule['query'] = [q.as_dict() for q in self.query] 68 | return rule 69 | 70 | @classmethod 71 | def sample(cls): 72 | return cls(event_type='compute.instance.update', 73 | query=[{'field': 'traits.instance_id"', 74 | 'value': '153462d0-a9b8-4b5b-8175-9e4b05e9b856', 75 | 'op': 'eq', 76 | 'type': 'string'}]) 77 | -------------------------------------------------------------------------------- /aodh/api/controllers/v2/alarm_rules/loadbalancer.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Catalyst Cloud Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import wsme 16 | from wsme import types as wtypes 17 | 18 | from aodh.api.controllers.v2 import base 19 | 20 | 21 | class LoadBalancerMemberHealthRule(base.AlarmRule): 22 | pool_id = wsme.wsattr(wtypes.text, mandatory=True) 23 | "ID of a load balancer pool the members belongs to." 24 | 25 | stack_id = wsme.wsattr(wtypes.text, mandatory=True) 26 | "ID of a Heat stack which contains the load balancer member." 27 | 28 | autoscaling_group_id = wsme.wsattr(wtypes.text, mandatory=True) 29 | "ID of a Heat autoscaling group that contains the load balancer member." 30 | 31 | def as_dict(self): 32 | rule = self.as_dict_from_keys( 33 | ['pool_id', 'stack_id', 'autoscaling_group_id'] 34 | ) 35 | return rule 36 | 37 | @staticmethod 38 | def create_hook(alarm): 39 | pass 40 | -------------------------------------------------------------------------------- /aodh/api/controllers/v2/alarm_rules/prometheus.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2023 Red Hat, Inc 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from oslo_log import log 17 | import wsme 18 | from wsme import types as wtypes 19 | 20 | from aodh.api.controllers.v2 import base 21 | 22 | 23 | LOG = log.getLogger(__name__) 24 | 25 | 26 | class PrometheusRule(base.AlarmRule): 27 | comparison_operator = base.AdvEnum('comparison_operator', str, 28 | 'lt', 'le', 'eq', 'ne', 'ge', 'gt', 29 | default='eq') 30 | "The comparison against the alarm threshold" 31 | 32 | threshold = wsme.wsattr(float, mandatory=True) 33 | "The threshold of the alarm" 34 | 35 | query = wsme.wsattr(wtypes.text, mandatory=True) 36 | "The Prometheus query" 37 | 38 | @staticmethod 39 | def validate(rule): 40 | # TO-DO(mmagr): validate Prometheus query maybe? 41 | return rule 42 | 43 | def as_dict(self): 44 | rule = self.as_dict_from_keys(['comparison_operator', 'threshold', 45 | 'query']) 46 | return rule 47 | -------------------------------------------------------------------------------- /aodh/api/controllers/v2/root.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012 New Dream Network, LLC (DreamHost) 3 | # Copyright 2013 IBM Corp. 4 | # Copyright 2013 eNovance 5 | # Copyright Ericsson AB 2013. All rights reserved 6 | # Copyright 2014 Hewlett-Packard Company 7 | # Copyright 2015 Huawei Technologies Co., Ltd. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | # not use this file except in compliance with the License. You may obtain 11 | # a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 18 | # License for the specific language governing permissions and limitations 19 | # under the License. 20 | 21 | from aodh.api.controllers.v2 import alarms 22 | from aodh.api.controllers.v2 import capabilities 23 | from aodh.api.controllers.v2 import metrics 24 | from aodh.api.controllers.v2 import query 25 | from aodh.api.controllers.v2 import quotas 26 | 27 | 28 | class V2Controller(object): 29 | """Version 2 API controller root.""" 30 | 31 | alarms = alarms.AlarmsController() 32 | query = query.QueryController() 33 | capabilities = capabilities.CapabilitiesController() 34 | quotas = quotas.QuotasController() 35 | metrics = metrics.MetricsController() 36 | -------------------------------------------------------------------------------- /aodh/api/hooks.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012 New Dream Network, LLC (DreamHost) 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from oslo_config import cfg 17 | from oslo_policy import opts 18 | from pecan import hooks 19 | 20 | from aodh.api import policies 21 | 22 | # TODO(gmann): Remove overriding the default value of config options: 23 | # - 'enforce_scope', and 'enforce_new_defaults' once aodh is ready with the 24 | # new RBAC (oslo_policy enable them by default) 25 | opts.set_defaults( 26 | cfg.CONF, 27 | enforce_scope=False, 28 | enforce_new_defaults=False) 29 | 30 | 31 | class ConfigHook(hooks.PecanHook): 32 | """Attach the configuration and policy enforcer object to the request. 33 | 34 | That allows controllers to get it. 35 | """ 36 | 37 | def __init__(self, conf): 38 | self.conf = conf 39 | self.enforcer = policies.init(conf) 40 | 41 | def before(self, state): 42 | state.request.cfg = self.conf 43 | state.request.enforcer = self.enforcer 44 | 45 | 46 | class DBHook(hooks.PecanHook): 47 | 48 | def __init__(self, alarm_conn): 49 | self.storage = alarm_conn 50 | 51 | def before(self, state): 52 | state.request.storage = self.storage 53 | 54 | 55 | class TranslationHook(hooks.PecanHook): 56 | 57 | def after(self, state): 58 | # After a request has been done, we need to see if 59 | # ClientSideError has added an error onto the response. 60 | # If it has we need to get it info the thread-safe WSGI 61 | # environ to be used by the ParsableErrorMiddleware. 62 | if hasattr(state.response, 'translatable_error'): 63 | state.request.environ['translatable_error'] = ( 64 | state.response.translatable_error) 65 | -------------------------------------------------------------------------------- /aodh/api/rbac.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012 New Dream Network, LLC (DreamHost) 3 | # Copyright 2014 Hewlett-Packard Company 4 | # Copyright 2015 Red Hat, Inc. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 7 | # not use this file except in compliance with the License. You may obtain 8 | # a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | # License for the specific language governing permissions and limitations 16 | # under the License. 17 | 18 | """Access Control Lists (ACL's) control access the API server.""" 19 | 20 | from oslo_context import context 21 | import pecan 22 | 23 | 24 | def target_from_segregation_rule(req, enforcer): 25 | """Return a target corresponding to an alarm returned by segregation rule 26 | 27 | This allows to use project_id: in an oslo_policy rule for query/listing. 28 | 29 | :param req: Webob Request object 30 | :param enforcer: policy enforcer 31 | 32 | :returns: target 33 | """ 34 | 35 | project_id = get_limited_to_project(req, enforcer) 36 | if project_id is not None: 37 | return {'project_id': project_id} 38 | return {} 39 | 40 | 41 | def enforce(policy_name, req, enforcer, target): 42 | """Return the user and project the request should be limited to. 43 | 44 | :param policy_name: the policy name to validate authz against. 45 | :param req: Webob Request object 46 | :param enforcer: policy enforcer 47 | :param target: the alarm or "auto" to 48 | 49 | """ 50 | rule_method = "telemetry:" + policy_name 51 | ctxt = context.RequestContext.from_environ(req.environ) 52 | 53 | if not enforcer.enforce(rule_method, target, ctxt.to_dict()): 54 | pecan.core.abort(status_code=403, 55 | detail='RBAC Authorization Failed') 56 | 57 | 58 | # TODO(fabiog): these methods are still used because the scoping part is really 59 | # convoluted and difficult to separate out. 60 | 61 | def get_limited_to(req, enforcer): 62 | """Return the user and project the request should be limited to. 63 | 64 | :param req: Webob Request object 65 | :param enforcer: policy enforcer 66 | :return: A tuple of (user, project), set to None if there's no limit on 67 | one of these. 68 | 69 | """ 70 | ctxt = context.RequestContext.from_environ(req.environ) 71 | if not enforcer.enforce('segregation', {}, ctxt.to_dict()): 72 | return ctxt.user_id, ctxt.project_id 73 | 74 | return None, None 75 | 76 | 77 | def get_limited_to_project(req, enforcer): 78 | """Return the project the request should be limited to. 79 | 80 | :param req: Webob Request object 81 | :param enforcer: policy enforcer 82 | :return: A project, or None if there's no limit on it. 83 | 84 | """ 85 | return get_limited_to(req, enforcer)[1] 86 | 87 | 88 | def is_admin(req, enforcer): 89 | ctxt = context.RequestContext.from_environ(req.environ) 90 | return enforcer.enforce('context_is_admin', {}, ctxt.to_dict()) 91 | -------------------------------------------------------------------------------- /aodh/cmd/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # 3 | # Copyright 2017 Red Hat, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | import os 17 | import sys 18 | 19 | 20 | def config_generator(): 21 | try: 22 | from oslo_config import generator 23 | generator.main( 24 | ['--config-file', 25 | '%s/aodh-config-generator.conf' % os.path.dirname(__file__)] 26 | + sys.argv[1:]) 27 | except Exception as e: 28 | print("Unable to build sample configuration file: %s" % e) 29 | return 1 30 | -------------------------------------------------------------------------------- /aodh/cmd/alarm.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # 3 | # Copyright 2014 OpenStack Foundation 4 | # Copyright 2015 Red Hat, Inc. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 7 | # not use this file except in compliance with the License. You may obtain 8 | # a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | # License for the specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import cotyledon 19 | from oslo_log import log 20 | 21 | from aodh import evaluator as evaluator_svc 22 | from aodh import event as event_svc 23 | from aodh import notifier as notifier_svc 24 | from aodh import service 25 | 26 | LOG = log.getLogger(__name__) 27 | 28 | 29 | def notifier(): 30 | conf = service.prepare_service() 31 | conf.log_opt_values(LOG, log.DEBUG) 32 | sm = cotyledon.ServiceManager() 33 | sm.add(notifier_svc.AlarmNotifierService, 34 | workers=conf.notifier.workers, args=(conf,)) 35 | sm.run() 36 | 37 | 38 | def evaluator(): 39 | conf = service.prepare_service() 40 | conf.log_opt_values(LOG, log.DEBUG) 41 | sm = cotyledon.ServiceManager() 42 | sm.add(evaluator_svc.AlarmEvaluationService, 43 | workers=conf.evaluator.workers, args=(conf,)) 44 | sm.run() 45 | 46 | 47 | def listener(): 48 | conf = service.prepare_service() 49 | conf.log_opt_values(LOG, log.DEBUG) 50 | sm = cotyledon.ServiceManager() 51 | sm.add(event_svc.EventAlarmEvaluationService, 52 | workers=conf.listener.workers, args=(conf,)) 53 | sm.run() 54 | -------------------------------------------------------------------------------- /aodh/cmd/aodh-config-generator.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | wrap_width = 79 3 | namespace = aodh 4 | namespace = aodh-auth 5 | namespace = oslo.db 6 | namespace = oslo.log 7 | namespace = oslo.messaging 8 | namespace = oslo.middleware.cors 9 | namespace = oslo.middleware.healthcheck 10 | namespace = oslo.middleware.http_proxy_to_wsgi 11 | namespace = oslo.policy 12 | namespace = oslo.reports 13 | namespace = keystonemiddleware.auth_token 14 | -------------------------------------------------------------------------------- /aodh/cmd/aodh-policy-generator.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | namespace = aodh 3 | -------------------------------------------------------------------------------- /aodh/cmd/status.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018 NEC, Corp. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | import sys 16 | 17 | from oslo_config import cfg 18 | from oslo_upgradecheck import common_checks 19 | from oslo_upgradecheck import upgradecheck 20 | 21 | from aodh.i18n import _ 22 | 23 | CONF = cfg.CONF 24 | 25 | 26 | class Checks(upgradecheck.UpgradeCommands): 27 | 28 | """Contains upgrade checks 29 | 30 | Various upgrade checks should be added as separate methods in this class 31 | and added to _upgrade_checks tuple. 32 | """ 33 | 34 | _upgrade_checks = ( 35 | (_('policy File JSON to YAML Migration'), 36 | (common_checks.check_policy_json, {'conf': CONF})), 37 | ) 38 | 39 | 40 | def main(): 41 | return upgradecheck.main( 42 | CONF, project='aodh', upgrade_command=Checks()) 43 | 44 | 45 | if __name__ == '__main__': 46 | sys.exit(main()) 47 | -------------------------------------------------------------------------------- /aodh/cmd/storage.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # 3 | # Copyright 2014 OpenStack Foundation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from oslo_log import log 18 | 19 | from aodh import service 20 | from aodh import storage 21 | 22 | 23 | LOG = log.getLogger(__name__) 24 | 25 | 26 | def dbsync(): 27 | conf = service.prepare_service() 28 | storage.get_connection_from_config(conf).upgrade() 29 | 30 | 31 | def expirer(): 32 | conf = service.prepare_service() 33 | 34 | if conf.database.alarm_history_time_to_live > 0: 35 | LOG.debug("Clearing expired alarm history data") 36 | conn = storage.get_connection_from_config(conf) 37 | max_count = conf.database.alarm_histories_delete_batch_size 38 | try: 39 | if max_count > 0: 40 | conn.clear_expired_alarm_history_data( 41 | conf.database.alarm_history_time_to_live, 42 | max_count) 43 | else: 44 | deleted = max_count = 100 45 | while deleted and deleted > 0: 46 | deleted = conn.clear_expired_alarm_history_data( 47 | conf.database.alarm_history_time_to_live, 48 | max_count) 49 | except TypeError: 50 | LOG.warning("Storage driver does not support " 51 | "'alarm_histories_delete_batch_size' config option.") 52 | else: 53 | LOG.info("Nothing to clean, database alarm history time to live " 54 | "is disabled") 55 | -------------------------------------------------------------------------------- /aodh/conf/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/conf/__init__.py -------------------------------------------------------------------------------- /aodh/conf/defaults.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Hewlett Packard Enterprise Development Company, L.P. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | from oslo_config import cfg 16 | from oslo_middleware import cors 17 | from oslo_policy import opts as policy_opts 18 | 19 | 20 | def set_lib_defaults(): 21 | """Update default value for configuration options from other namespace. 22 | 23 | Example, oslo lib config options. This is needed for 24 | config generator tool to pick these default value changes. 25 | https://docs.openstack.org/oslo.config/latest/cli/ 26 | generator.html#modifying-defaults-from-other-namespaces 27 | """ 28 | set_cors_middleware_defaults() 29 | 30 | # Update default value of oslo.policy policy_file, , 31 | # enforce_scope, and enforce_new_defaults config options. 32 | policy_opts.set_defaults(cfg.CONF, 'policy.yaml', 33 | enforce_scope=False, 34 | enforce_new_defaults=False) 35 | 36 | 37 | def set_cors_middleware_defaults(): 38 | """Update default configuration options for oslo.middleware.""" 39 | cors.set_defaults( 40 | allow_headers=['X-Auth-Token', 41 | 'X-Openstack-Request-Id', 42 | 'X-Subject-Token'], 43 | expose_headers=['X-Auth-Token', 44 | 'X-Openstack-Request-Id', 45 | 'X-Subject-Token'], 46 | allow_methods=['GET', 47 | 'PUT', 48 | 'POST', 49 | 'DELETE', 50 | 'PATCH'] 51 | ) 52 | -------------------------------------------------------------------------------- /aodh/evaluator/prometheus.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2023 Red Hat, Inc 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from oslo_config import cfg 17 | from oslo_log import log 18 | 19 | from observabilityclient import client 20 | 21 | from aodh.evaluator import threshold 22 | from aodh import keystone_client 23 | 24 | 25 | LOG = log.getLogger(__name__) 26 | OPTS = [ 27 | cfg.BoolOpt('prometheus_disable_rbac', 28 | default=False, 29 | help='Disable RBAC for Prometheus evaluator.', 30 | deprecated_for_removal=True, 31 | deprecated_reason="Prometheus RBAC is always disabled. " 32 | "It's not possible to correctly use " 33 | "client-side rbac enforcement from within " 34 | "services. Using it can cause issues.", 35 | deprecated_since="Flamingo") 36 | ] 37 | 38 | 39 | class PrometheusBase(threshold.ThresholdEvaluator): 40 | def __init__(self, conf): 41 | super(PrometheusBase, self).__init__(conf) 42 | self._set_obsclient(conf) 43 | 44 | def _set_obsclient(self, conf): 45 | session = keystone_client.get_session(conf) 46 | opts = {'interface': conf.service_credentials.interface, 47 | 'region_name': conf.service_credentials.region_name} 48 | self._prom = client.Client('1', session, adapter_options=opts) 49 | 50 | def _get_metric_data(self, query): 51 | LOG.debug(f'Querying Prometheus instance on: {query}') 52 | return self._prom.query.query(query, disable_rbac=True) 53 | 54 | 55 | class PrometheusEvaluator(PrometheusBase): 56 | 57 | def _sanitize(self, metric_data): 58 | sanitized = [float(m.value) for m in metric_data] 59 | LOG.debug(f'Sanited Prometheus metric data: {metric_data}' 60 | f' to statistics: {sanitized}') 61 | return sanitized 62 | 63 | def evaluate_rule(self, alarm_rule): 64 | """Evaluate alarm rule. 65 | 66 | :returns: state, trending state, statistics, number of samples outside 67 | threshold and reason 68 | """ 69 | metrics = self._get_metric_data(alarm_rule['query']) 70 | if not metrics: 71 | LOG.warning("Empty result fetched from Prometheus for query" 72 | f" {alarm_rule['query']}") 73 | 74 | statistics = self._sanitize(metrics) 75 | if not statistics: 76 | raise threshold.InsufficientDataError('datapoints are unknown', 77 | statistics) 78 | return self._process_statistics(alarm_rule, statistics) 79 | 80 | def _unknown_reason_data(self, alarm, statistics): 81 | LOG.warning(f'Transfering alarm {alarm} on unknown reason') 82 | last = None if not statistics else statistics[-1] 83 | return self._reason_data('unknown', len(statistics), last) 84 | -------------------------------------------------------------------------------- /aodh/evaluator/utils.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2014 Red Hat, Inc 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import math 17 | 18 | 19 | def mean(s, key=lambda x: x): 20 | """Calculate the mean of a numeric list.""" 21 | count = float(len(s)) 22 | if count: 23 | return math.fsum(map(key, s)) / count 24 | return 0.0 25 | 26 | 27 | def deltas(s, key, m=None): 28 | """Calculate the squared distances from mean for a numeric list.""" 29 | m = m or mean(s, key) 30 | return [(key(i) - m) ** 2 for i in s] 31 | 32 | 33 | def variance(s, key, m=None): 34 | """Calculate the variance of a numeric list.""" 35 | return mean(deltas(s, key, m)) 36 | 37 | 38 | def stddev(s, key, m=None): 39 | """Calculate the standard deviation of a numeric list.""" 40 | return math.sqrt(variance(s, key, m)) 41 | 42 | 43 | def outside(s, key, lower=0.0, upper=0.0): 44 | """Determine if value falls outside upper and lower bounds.""" 45 | v = key(s) 46 | return v < lower or v > upper 47 | 48 | 49 | def anomalies(s, key, lower=0.0, upper=0.0): 50 | """Separate anomalous data points from the in-liers.""" 51 | inliers = [] 52 | outliers = [] 53 | for i in s: 54 | if outside(i, key, lower, upper): 55 | outliers.append(i) 56 | else: 57 | inliers.append(i) 58 | return inliers, outliers 59 | -------------------------------------------------------------------------------- /aodh/event.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015 NEC Corporation. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import cotyledon 17 | from oslo_config import cfg 18 | from oslo_log import log 19 | import oslo_messaging 20 | 21 | from aodh.evaluator import event 22 | from aodh import messaging 23 | from aodh import storage 24 | 25 | LOG = log.getLogger(__name__) 26 | 27 | OPTS = [ 28 | cfg.StrOpt('event_alarm_topic', 29 | default='alarm.all', 30 | deprecated_group='DEFAULT', 31 | help='The topic that aodh uses for event alarm evaluation.'), 32 | cfg.IntOpt('batch_size', 33 | default=1, 34 | help='Number of notification messages to wait before ' 35 | 'dispatching them.'), 36 | cfg.IntOpt('batch_timeout', 37 | help='Number of seconds to wait before dispatching samples ' 38 | 'when batch_size is not reached (None means indefinitely).'), 39 | ] 40 | 41 | 42 | class EventAlarmEndpoint(object): 43 | 44 | def __init__(self, evaluator): 45 | self.evaluator = evaluator 46 | 47 | def sample(self, notifications): 48 | LOG.debug('Received %s messages in batch.', len(notifications)) 49 | for notification in notifications: 50 | self.evaluator.evaluate_events(notification['payload']) 51 | 52 | 53 | class EventAlarmEvaluationService(cotyledon.Service): 54 | def __init__(self, worker_id, conf): 55 | super(EventAlarmEvaluationService, self).__init__(worker_id) 56 | self.conf = conf 57 | self.storage_conn = storage.get_connection_from_config(self.conf) 58 | self.evaluator = event.EventAlarmEvaluator(self.conf) 59 | self.listener = messaging.get_batch_notification_listener( 60 | messaging.get_transport(self.conf), 61 | [oslo_messaging.Target( 62 | topic=self.conf.listener.event_alarm_topic)], 63 | [EventAlarmEndpoint(self.evaluator)], False, 64 | self.conf.listener.batch_size, 65 | self.conf.listener.batch_timeout) 66 | self.listener.start() 67 | 68 | def terminate(self): 69 | self.listener.stop() 70 | self.listener.wait() 71 | -------------------------------------------------------------------------------- /aodh/i18n.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Huawei Technologies Co., Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | """oslo.i18n integration module. 16 | 17 | See https://docs.openstack.org/oslo.i18n/latest/user/usage.html 18 | 19 | """ 20 | 21 | import oslo_i18n 22 | 23 | DOMAIN = 'aodh' 24 | 25 | _translators = oslo_i18n.TranslatorFactory(domain=DOMAIN) 26 | 27 | # The primary translation function using the well-known name "_" 28 | _ = _translators.primary 29 | 30 | 31 | def translate(value, user_locale): 32 | return oslo_i18n.translate(value, user_locale) 33 | 34 | 35 | def get_available_languages(): 36 | return oslo_i18n.get_available_languages(DOMAIN) 37 | -------------------------------------------------------------------------------- /aodh/locale/zh_TW/LC_MESSAGES/aodh.po: -------------------------------------------------------------------------------- 1 | # Lucas Palm , 2015. #zanata 2 | # Jennifer , 2016. #zanata 3 | # KATO Tomoyuki , 2016. #zanata 4 | msgid "" 5 | msgstr "" 6 | "Project-Id-Version: aodh VERSION\n" 7 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 8 | "POT-Creation-Date: 2021-09-15 16:30+0000\n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "PO-Revision-Date: 2016-06-03 07:04+0000\n" 13 | "Last-Translator: KATO Tomoyuki \n" 14 | "Language-Team: Chinese (Taiwan)\n" 15 | "Language: zh_TW\n" 16 | "X-Generator: Zanata 4.3.3\n" 17 | "Plural-Forms: nplurals=1; plural=0\n" 18 | 19 | #, python-format 20 | msgid "%(rule)s must be set for %(type)s type alarm" 21 | msgstr "必須為 %(type)s 類型警示設定 %(rule)s" 22 | 23 | #, python-format 24 | msgid "%(rule1)s and %(rule2)s cannot be set at the same time" 25 | msgstr "無法同時設定 %(rule1)s 和 %(rule2)s" 26 | 27 | #, python-format 28 | msgid "%s is not JSON serializable" 29 | msgstr "%s 不可進行 JSON 序列化" 30 | 31 | #, python-format 32 | msgid "Alarm %(alarm_id)s not found in project %(project)s" 33 | msgstr "在專案 %(project)s 中找不到警示 %(alarm_id)s" 34 | 35 | #, python-format 36 | msgid "Alarm %s not found" 37 | msgstr "找不到警示 %s" 38 | 39 | msgid "Alarm incorrect" 40 | msgstr "警示不正確" 41 | 42 | #, python-format 43 | msgid "Alarm quota exceeded for user %(u)s on project %(p)s" 44 | msgstr "在專案 %(p)s 上,針對使用者 %(u)s 已超出的警示配額" 45 | 46 | #, python-format 47 | msgid "Failed to parse the timestamp value %s" 48 | msgstr "無法剖析時間戳記值 %s" 49 | 50 | #, python-format 51 | msgid "Filter expression not valid: %s" 52 | msgstr "過濾表示式無效:%s" 53 | 54 | #, python-format 55 | msgid "Not Authorized to access %(aspect)s %(id)s" 56 | msgstr "未獲授權來存取 %(aspect)s %(id)s" 57 | 58 | #, python-format 59 | msgid "" 60 | "Notifying alarm %(alarm_name)s %(alarm_id)s of %(severity)s priority from " 61 | "%(previous)s to %(current)s with action %(action)s because %(reason)s." 62 | msgstr "" 63 | "正在以動作 %(action)s 通知優先順序為 %(severity)s 的警示 %(alarm_name)s " 64 | "%(alarm_id)s(從 %(previous)s 至 %(current)s),因為 %(reason)s。" 65 | 66 | #, python-format 67 | msgid "Order-by expression not valid: %s" 68 | msgstr "排序方式表示式無效:%s" 69 | 70 | #, python-format 71 | msgid "" 72 | "The data type %(type)s is not supported. The supported data type list is: " 73 | "%(supported)s" 74 | msgstr "不支援資料類型 %(type)s。支援的資料類型清單為:%(supported)s" 75 | 76 | msgid "Time constraint names must be unique for a given alarm." 77 | msgstr "針對給定的警示,時間限制名稱必須是唯一的。" 78 | 79 | #, python-format 80 | msgid "Timezone %s is not valid" 81 | msgstr "時區 %s 無效" 82 | 83 | #, python-format 84 | msgid "" 85 | "Unable to convert the value %(value)s to the expected data type %(type)s." 86 | msgstr "無法將值 %(value)s 轉換成預期的資料類型 %(type)s。" 87 | 88 | #, python-format 89 | msgid "Unable to parse action %s" 90 | msgstr "無法剖析動作 %s" 91 | 92 | #, python-format 93 | msgid "" 94 | "Unexpected exception converting %(value)s to the expected data type %(type)s." 95 | msgstr "將 %(value)s 轉換為預期的資料類型%(type)s 時發生非預期的異常狀況。" 96 | 97 | #, python-format 98 | msgid "Unsupported action %s" 99 | msgstr "不受支援的動作 %s" 100 | 101 | msgid "state invalid" 102 | msgstr "狀態無效" 103 | 104 | msgid "state_timestamp should be datetime object" 105 | msgstr "state_timestamp 應該為日期時間物件" 106 | 107 | msgid "timestamp should be datetime object" 108 | msgstr "時間戳記應該為日期時間物件" 109 | -------------------------------------------------------------------------------- /aodh/messaging.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2013-2015 eNovance 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import oslo_messaging 17 | from oslo_messaging import serializer as oslo_serializer 18 | 19 | DEFAULT_URL = "__default__" 20 | TRANSPORTS = {} 21 | _SERIALIZER = oslo_serializer.JsonPayloadSerializer() 22 | 23 | 24 | def setup(): 25 | oslo_messaging.set_transport_defaults('aodh') 26 | 27 | 28 | def get_transport(conf, url=None, optional=False, cache=True): 29 | """Initialise the oslo_messaging layer.""" 30 | global TRANSPORTS, DEFAULT_URL 31 | cache_key = url or DEFAULT_URL 32 | transport = TRANSPORTS.get(cache_key) 33 | if not transport or not cache: 34 | try: 35 | transport = oslo_messaging.get_notification_transport(conf, url) 36 | except (oslo_messaging.InvalidTransportURL, 37 | oslo_messaging.DriverLoadFailure): 38 | if not optional or url: 39 | # NOTE(sileht): oslo_messaging is configured but unloadable 40 | # so reraise the exception 41 | raise 42 | return None 43 | else: 44 | if cache: 45 | TRANSPORTS[cache_key] = transport 46 | return transport 47 | 48 | 49 | def get_batch_notification_listener(transport, targets, endpoints, 50 | allow_requeue=False, 51 | batch_size=1, batch_timeout=None): 52 | """Return a configured oslo_messaging notification listener.""" 53 | return oslo_messaging.get_batch_notification_listener( 54 | transport, targets, endpoints, executor='threading', 55 | allow_requeue=allow_requeue, 56 | batch_size=batch_size, batch_timeout=batch_timeout) 57 | 58 | 59 | def get_notifier(transport, publisher_id): 60 | """Return a configured oslo_messaging notifier.""" 61 | notifier = oslo_messaging.Notifier(transport, serializer=_SERIALIZER) 62 | return notifier.prepare(publisher_id=publisher_id) 63 | -------------------------------------------------------------------------------- /aodh/notifier/log.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2013 eNovance 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | """Log alarm notifier.""" 16 | 17 | from oslo_log import log 18 | 19 | from aodh.i18n import _ 20 | from aodh import notifier 21 | 22 | LOG = log.getLogger(__name__) 23 | 24 | 25 | class LogAlarmNotifier(notifier.AlarmNotifier): 26 | "Log alarm notifier.""" 27 | 28 | @staticmethod 29 | def notify(action, alarm_id, alarm_name, severity, previous, current, 30 | reason, reason_data): 31 | LOG.info(_( 32 | "Notifying alarm %(alarm_name)s %(alarm_id)s of %(severity)s " 33 | "priority from %(previous)s to %(current)s with action %(action)s" 34 | " because %(reason)s.") % ({'alarm_name': alarm_name, 35 | 'alarm_id': alarm_id, 36 | 'severity': severity, 37 | 'previous': previous, 38 | 'current': current, 39 | 'action': action.geturl(), 40 | 'reason': reason})) 41 | -------------------------------------------------------------------------------- /aodh/notifier/test.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2013-2015 eNovance 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | """Test alarm notifier.""" 16 | 17 | from aodh import notifier 18 | 19 | 20 | class TestAlarmNotifier(notifier.AlarmNotifier): 21 | "Test alarm notifier.""" 22 | 23 | def __init__(self, conf): 24 | super(TestAlarmNotifier, self).__init__(conf) 25 | self.notifications = [] 26 | 27 | def notify(self, action, alarm_id, alarm_name, severity, 28 | previous, current, reason, reason_data): 29 | self.notifications.append((action, 30 | alarm_id, 31 | alarm_name, 32 | severity, 33 | previous, 34 | current, 35 | reason, 36 | reason_data)) 37 | -------------------------------------------------------------------------------- /aodh/notifier/trust.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2014 eNovance 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | """Rest alarm notifier with trusted authentication.""" 16 | 17 | from urllib import parse 18 | 19 | from aodh import keystone_client 20 | from aodh.notifier import rest 21 | 22 | 23 | class TrustAlarmNotifierMixin(object): 24 | """Mixin class to add Keystone trust support to an AlarmNotifier. 25 | 26 | Provides a notify() method that interprets the trust ID and then calls 27 | the parent class's notify(), passing the necessary authentication data in 28 | the headers. 29 | """ 30 | 31 | def notify(self, action, alarm_id, alarm_name, severity, previous, current, 32 | reason, reason_data): 33 | trust_id = action.username 34 | 35 | client = keystone_client.get_trusted_client(self.conf, trust_id) 36 | 37 | # Remove the fake user 38 | netloc = action.netloc.split("@")[1] 39 | # Remove the trust prefix 40 | scheme = action.scheme[6:] 41 | 42 | action = parse.SplitResult(scheme, netloc, action.path, action.query, 43 | action.fragment) 44 | 45 | headers = {'X-Auth-Token': keystone_client.get_auth_token(client)} 46 | super(TrustAlarmNotifierMixin, self).notify( 47 | action, alarm_id, alarm_name, severity, previous, current, reason, 48 | reason_data, headers) 49 | 50 | 51 | class TrustRestAlarmNotifier(TrustAlarmNotifierMixin, rest.RestAlarmNotifier): 52 | """Notifier supporting keystone trust authentication. 53 | 54 | This alarm notifier is intended to be used to call an endpoint using 55 | keystone authentication. It uses the aodh service user to 56 | authenticate using the trust ID provided. 57 | 58 | The URL must be in the form ``trust+http://host/action``. 59 | """ 60 | -------------------------------------------------------------------------------- /aodh/opts.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2015 eNovance 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | import itertools 15 | 16 | from keystoneauth1 import loading 17 | from oslo_config import cfg 18 | 19 | import aodh.api 20 | import aodh.api.controllers.v2.alarm_rules.gnocchi 21 | import aodh.api.controllers.v2.alarms 22 | import aodh.coordination 23 | import aodh.evaluator 24 | import aodh.evaluator.event 25 | import aodh.evaluator.gnocchi 26 | import aodh.evaluator.loadbalancer 27 | import aodh.evaluator.prometheus 28 | import aodh.evaluator.threshold 29 | import aodh.event 30 | import aodh.keystone_client 31 | import aodh.notifier.rest 32 | import aodh.notifier.zaqar 33 | import aodh.service 34 | import aodh.storage 35 | 36 | OPTS = [ 37 | cfg.BoolOpt('enable_evaluation_results_metrics', 38 | default=False, 39 | help=("Whether metric collection should be enabled.")), 40 | ] 41 | 42 | 43 | def list_opts(): 44 | return [ 45 | ('DEFAULT', 46 | itertools.chain( 47 | aodh.evaluator.OPTS, 48 | aodh.evaluator.event.OPTS, 49 | aodh.evaluator.prometheus.OPTS, 50 | aodh.evaluator.threshold.OPTS, 51 | aodh.evaluator.loadbalancer.OPTS, 52 | aodh.notifier.rest.OPTS, 53 | aodh.queue.OPTS, 54 | aodh.service.OPTS, 55 | OPTS)), 56 | ('api', 57 | itertools.chain( 58 | aodh.api.OPTS, 59 | aodh.api.controllers.v2.alarm_rules.gnocchi.GNOCCHI_OPTS, 60 | aodh.api.controllers.v2.alarms.ALARM_API_OPTS)), 61 | ('coordination', aodh.coordination.OPTS), 62 | ('database', aodh.storage.OPTS), 63 | ('evaluator', aodh.service.EVALUATOR_OPTS), 64 | ('listener', itertools.chain(aodh.service.LISTENER_OPTS, 65 | aodh.event.OPTS)), 66 | ('notifier', itertools.chain(aodh.notifier.OPTS, 67 | aodh.service.NOTIFIER_OPTS)), 68 | ('service_credentials', aodh.keystone_client.OPTS), 69 | ('service_types', aodh.notifier.zaqar.SERVICE_OPTS), 70 | ] 71 | 72 | 73 | def list_keystoneauth_opts(): 74 | # NOTE(sileht): the configuration file contains only the options 75 | # for the password plugin that handles keystone v2 and v3 API 76 | # with discovery. But other options are possible. 77 | return [('service_credentials', ( 78 | loading.get_auth_common_conf_options() + 79 | loading.get_auth_plugin_conf_options('password')))] 80 | -------------------------------------------------------------------------------- /aodh/profiler.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Fujitsu Ltd. 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import socket 17 | 18 | from oslo_log import log 19 | from oslo_utils import importutils 20 | import webob.dec 21 | 22 | profiler = importutils.try_import('osprofiler.profiler') 23 | profiler_initializer = importutils.try_import('osprofiler.initializer') 24 | profiler_web = importutils.try_import('osprofiler.web') 25 | 26 | LOG = log.getLogger(__name__) 27 | 28 | 29 | class WsgiMiddleware(object): 30 | 31 | def __init__(self, application, **kwargs): 32 | self.application = application 33 | 34 | @classmethod 35 | def factory(cls, global_conf, **local_conf): 36 | if profiler_web: 37 | return profiler_web.WsgiMiddleware.factory(global_conf) 38 | 39 | def filter_(app): 40 | return cls(app) 41 | 42 | return filter_ 43 | 44 | @webob.dec.wsgify 45 | def __call__(self, request): 46 | return request.get_response(self.application) 47 | 48 | 49 | def setup(conf): 50 | if hasattr(conf, 'profiler') and conf.profiler.enabled: 51 | profiler_initializer.init_from_conf( 52 | conf=conf, 53 | context={}, 54 | project=conf.project, 55 | service=conf.prog, 56 | host=socket.gethostbyname(socket.gethostname())) 57 | LOG.info('OSprofiler is enabled.') 58 | 59 | 60 | def trace_cls(name, **kwargs): 61 | """Wrap the OSprofiler trace_cls. 62 | 63 | Wrap the OSprofiler trace_cls decorator so that it will not try to 64 | patch the class unless OSprofiler is present. 65 | 66 | :param name: The name of action. For example, wsgi, rpc, db, ... 67 | :param kwargs: Any other keyword args used by profiler.trace_cls 68 | """ 69 | 70 | def decorator(cls): 71 | if profiler: 72 | trace_decorator = profiler.trace_cls(name, **kwargs) 73 | return trace_decorator(cls) 74 | return cls 75 | 76 | return decorator 77 | -------------------------------------------------------------------------------- /aodh/queue.py: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 3 | # not use this file except in compliance with the License. You may obtain 4 | # a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | # License for the specific language governing permissions and limitations 12 | # under the License. 13 | 14 | from oslo_config import cfg 15 | from oslo_log import log 16 | import oslo_messaging 17 | 18 | from aodh import messaging 19 | from aodh.storage import models 20 | 21 | OPTS = [ 22 | cfg.StrOpt('notifier_topic', 23 | default='alarming', 24 | help='The topic that aodh uses for alarm notifier ' 25 | 'messages.'), 26 | ] 27 | 28 | LOG = log.getLogger(__name__) 29 | 30 | 31 | class AlarmNotifier(object): 32 | def __init__(self, conf): 33 | self.notifier = oslo_messaging.Notifier( 34 | messaging.get_transport(conf), 35 | driver='messagingv2', 36 | publisher_id="alarming.evaluator", 37 | topics=[conf.notifier_topic]) 38 | 39 | def notify(self, alarm, previous, reason, reason_data): 40 | actions = getattr(alarm, models.Alarm.ALARM_ACTIONS_MAP[alarm.state]) 41 | if not actions: 42 | LOG.debug('alarm %(alarm_id)s has no action configured ' 43 | 'for state transition from %(previous)s to ' 44 | 'state %(state)s, skipping the notification.', 45 | {'alarm_id': alarm.alarm_id, 46 | 'previous': previous, 47 | 'state': alarm.state}) 48 | return 49 | payload = {'actions': actions, 50 | 'alarm_id': alarm.alarm_id, 51 | 'alarm_name': alarm.name, 52 | 'severity': alarm.severity, 53 | 'previous': previous, 54 | 'current': alarm.state, 55 | 'reason': str(reason), 56 | 'reason_data': reason_data} 57 | self.notifier.sample({}, 'alarm.update', payload) 58 | -------------------------------------------------------------------------------- /aodh/storage/impl_log.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012 New Dream Network, LLC (DreamHost) 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | """Simple logging storage backend. 16 | """ 17 | 18 | from oslo_log import log 19 | 20 | from aodh.storage import base 21 | 22 | LOG = log.getLogger(__name__) 23 | 24 | 25 | class Connection(base.Connection): 26 | """Log the data.""" 27 | 28 | @staticmethod 29 | def upgrade(): 30 | pass 31 | 32 | @staticmethod 33 | def clear(): 34 | pass 35 | 36 | @staticmethod 37 | def get_alarms(name=None, user=None, state=None, meter=None, 38 | project=None, enabled=None, alarm_id=None, 39 | alarm_type=None, severity=None, exclude=None, 40 | pagination=None): 41 | """Yields a lists of alarms that match filters.""" 42 | return [] 43 | 44 | @staticmethod 45 | def create_alarm(alarm): 46 | """Create alarm.""" 47 | return alarm 48 | 49 | @staticmethod 50 | def update_alarm(alarm): 51 | """Update alarm.""" 52 | return alarm 53 | 54 | @staticmethod 55 | def delete_alarm(alarm_id): 56 | """Delete an alarm and its history data.""" 57 | 58 | @staticmethod 59 | def clear_expired_alarm_history_data(ttl, max_count=None): 60 | """Clear expired alarm history data from the backend storage system. 61 | 62 | Clearing occurs according to the time-to-live. 63 | 64 | :param ttl: Number of seconds to keep alarm history records for. 65 | :param max_count: Number of records to delete. 66 | """ 67 | LOG.info('Dropping alarm history %d data with TTL %d', max_count, ttl) 68 | -------------------------------------------------------------------------------- /aodh/storage/sqlalchemy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/storage/sqlalchemy/__init__.py -------------------------------------------------------------------------------- /aodh/storage/sqlalchemy/alembic/alembic.ini: -------------------------------------------------------------------------------- 1 | [alembic] 2 | script_location = aodh.storage.sqlalchemy:alembic 3 | sqlalchemy.url = sqlite:///aodh.db 4 | 5 | [loggers] 6 | keys = root,sqlalchemy,alembic 7 | 8 | [handlers] 9 | keys = console 10 | 11 | [formatters] 12 | keys = generic 13 | 14 | [logger_root] 15 | level = WARN 16 | handlers = console 17 | qualname = 18 | 19 | [logger_sqlalchemy] 20 | level = WARN 21 | handlers = 22 | qualname = sqlalchemy.engine 23 | 24 | [logger_alembic] 25 | level = WARN 26 | handlers = 27 | qualname = alembic 28 | 29 | [handler_console] 30 | class = StreamHandler 31 | args = (sys.stderr,) 32 | level = NOTSET 33 | formatter = generic 34 | 35 | [formatter_generic] 36 | format = %(levelname)-5.5s [%(name)s] %(message)s 37 | datefmt = %H:%M:%S 38 | -------------------------------------------------------------------------------- /aodh/storage/sqlalchemy/alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | # Copyright ${create_date.year} OpenStack Foundation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | # 15 | 16 | """${message} 17 | 18 | Revision ID: ${up_revision} 19 | Revises: ${down_revision | comma,n} 20 | Create Date: ${create_date} 21 | 22 | """ 23 | 24 | # revision identifiers, used by Alembic. 25 | revision = ${repr(up_revision)} 26 | down_revision = ${repr(down_revision)} 27 | branch_labels = ${repr(branch_labels)} 28 | depends_on = ${repr(depends_on)} 29 | 30 | from alembic import op 31 | import sqlalchemy as sa 32 | ${imports if imports else ""} 33 | 34 | def upgrade(): 35 | ${upgrades if upgrades else "pass"} 36 | -------------------------------------------------------------------------------- /aodh/storage/sqlalchemy/alembic/versions/006_add_evaluate_timestamp_to_alarm.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Catalyst Cloud Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Add evaluate_timestamp column to alarm table 16 | 17 | Revision ID: 006 18 | Revises: 6ae0d05d9451 19 | Create Date: 2019-12-05 11:23:42.379029 20 | """ 21 | 22 | # revision identifiers, used by Alembic. 23 | revision = '006' 24 | down_revision = '6ae0d05d9451' 25 | 26 | from alembic import op 27 | from oslo_utils import timeutils 28 | import sqlalchemy as sa 29 | 30 | 31 | def upgrade(): 32 | op.add_column( 33 | 'alarm', 34 | sa.Column('evaluate_timestamp', sa.DateTime(), nullable=True, 35 | server_default=str(timeutils.utcnow())) 36 | ) 37 | -------------------------------------------------------------------------------- /aodh/storage/sqlalchemy/alembic/versions/007_add_quota_table.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Catalyst Cloud Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Add quota table 16 | 17 | Revision ID: 007 18 | Revises: 006 19 | Create Date: 2020-01-28 20 | """ 21 | 22 | # revision identifiers, used by Alembic. 23 | revision = '007' 24 | down_revision = '006' 25 | 26 | from alembic import op 27 | import sqlalchemy as sa 28 | 29 | 30 | def upgrade(): 31 | op.create_table( 32 | 'quota', 33 | sa.Column('id', sa.String(length=36), nullable=False), 34 | sa.Column('resource', sa.String(length=50), nullable=False), 35 | sa.Column('project_id', sa.String(length=128), nullable=False), 36 | sa.Column('limit', sa.Integer, nullable=False), 37 | sa.PrimaryKeyConstraint('id'), 38 | sa.UniqueConstraint('project_id', 'resource'), 39 | sa.Index( 40 | 'ix_quota_project_id_resource', 41 | 'project_id', 'resource' 42 | ) 43 | ) 44 | -------------------------------------------------------------------------------- /aodh/storage/sqlalchemy/alembic/versions/008_added_counter_table.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 OpenStack Foundation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | # 15 | 16 | """added_counter_table 17 | 18 | Revision ID: 008 19 | Revises: 007 20 | Create Date: 2025-01-15 10:28:02.087788 21 | 22 | """ 23 | 24 | # revision identifiers, used by Alembic. 25 | revision = '008' 26 | down_revision = '007' 27 | branch_labels = None 28 | depends_on = None 29 | 30 | from alembic import op 31 | import sqlalchemy as sa 32 | 33 | 34 | def upgrade(): 35 | op.create_table( 36 | 'alarm_counter', 37 | sa.Column('id', sa.String(length=36), nullable=False), 38 | sa.Column('alarm_id', sa.String(length=128), nullable=False), 39 | sa.Column('project_id', sa.String(length=128), nullable=False), 40 | sa.Column('state', sa.String(length=128), nullable=False), 41 | sa.Column('value', sa.Integer(), nullable=False), 42 | sa.ForeignKeyConstraint( 43 | ['alarm_id'], 44 | ['alarm.alarm_id'], 45 | name='alarm_fkey_ref', 46 | ), 47 | sa.PrimaryKeyConstraint('id'), 48 | sa.UniqueConstraint('alarm_id', 'project_id', 'state') 49 | ) 50 | op.create_index( 51 | 'ix_alarm_counter_alarm_id', 52 | 'alarm_counter', 53 | ['alarm_id'], 54 | unique=False 55 | ) 56 | op.create_index( 57 | 'ix_alarm_counter_project_id', 58 | 'alarm_counter', 59 | ['project_id'], 60 | unique=False 61 | ) 62 | op.create_index( 63 | 'ix_alarm_counter_state', 64 | 'alarm_counter', 65 | ['state'], 66 | unique=False 67 | ) 68 | -------------------------------------------------------------------------------- /aodh/storage/sqlalchemy/alembic/versions/367aadf5485f_precisetimestamp_to_datetime.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # 3 | # Copyright 2016 OpenStack Foundation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | # 17 | 18 | """precisetimestamp_to_datetime 19 | 20 | Revision ID: 367aadf5485f 21 | Revises: f8c31b1ffe11 22 | Create Date: 2016-09-19 16:43:34.379029 23 | 24 | """ 25 | 26 | # revision identifiers, used by Alembic. 27 | revision = '367aadf5485f' 28 | down_revision = 'f8c31b1ffe11' 29 | branch_labels = None 30 | depends_on = None 31 | 32 | from alembic import op 33 | import sqlalchemy as sa 34 | from sqlalchemy import func 35 | 36 | from aodh.storage.sqlalchemy import models 37 | 38 | 39 | def upgrade(): 40 | bind = op.get_bind() 41 | if bind and bind.engine.name == "mysql": 42 | # NOTE(jd) So that crappy engine that is MySQL does not have "ALTER 43 | # TABLE … USING …". We need to copy everything and convert… 44 | for table_name, column_name in (("alarm", "timestamp"), 45 | ("alarm", "state_timestamp"), 46 | ("alarm_history", "timestamp")): 47 | existing_type = sa.types.DECIMAL( 48 | precision=20, scale=6, asdecimal=True) 49 | existing_col = sa.Column( 50 | column_name, 51 | existing_type, 52 | nullable=True) 53 | temp_col = sa.Column( 54 | column_name + "_ts", 55 | models.TimestampUTC(), 56 | nullable=True) 57 | op.add_column(table_name, temp_col) 58 | t = sa.sql.table(table_name, existing_col, temp_col) 59 | op.execute(t.update().values( 60 | **{column_name + "_ts": func.from_unixtime(existing_col)})) 61 | op.drop_column(table_name, column_name) 62 | op.alter_column(table_name, 63 | column_name + "_ts", 64 | nullable=True, 65 | type_=models.TimestampUTC(), 66 | existing_nullable=True, 67 | existing_type=existing_type, 68 | new_column_name=column_name) 69 | -------------------------------------------------------------------------------- /aodh/storage/sqlalchemy/alembic/versions/6ae0d05d9451_add_reason_column.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # 3 | # Copyright 2017 OpenStack Foundation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | # 17 | 18 | """add_reason_column 19 | 20 | Revision ID: 6ae0d05d9451 21 | Revises: 367aadf5485f 22 | Create Date: 2017-06-05 16:42:42.379029 23 | 24 | """ 25 | 26 | # revision identifiers, used by Alembic. 27 | revision = '6ae0d05d9451' 28 | down_revision = '367aadf5485f' 29 | branch_labels = None 30 | depends_on = None 31 | 32 | from alembic import op 33 | import sqlalchemy as sa 34 | 35 | 36 | def upgrade(): 37 | op.add_column('alarm', sa.Column('state_reason', sa.Text, nullable=True)) 38 | -------------------------------------------------------------------------------- /aodh/storage/sqlalchemy/alembic/versions/bb07adac380_add_severity_to_alarm_history.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 OpenStack Foundation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | # 15 | 16 | """add severity to alarm history 17 | 18 | Revision ID: bb07adac380 19 | Revises: 12fe8fac9fe4 20 | Create Date: 2015-08-06 15:15:43.717068 21 | 22 | """ 23 | 24 | # revision identifiers, used by Alembic. 25 | revision = 'bb07adac380' 26 | down_revision = '12fe8fac9fe4' 27 | branch_labels = None 28 | depends_on = None 29 | 30 | from alembic import op 31 | import sqlalchemy as sa 32 | 33 | 34 | def upgrade(): 35 | op.add_column('alarm_history', 36 | sa.Column('severity', sa.String(length=50), nullable=True)) 37 | -------------------------------------------------------------------------------- /aodh/storage/sqlalchemy/alembic/versions/f8c31b1ffe11_add_index_for_enabled_and_type.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 OpenStack Foundation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | # 15 | 16 | """add index for enabled and type 17 | 18 | Revision ID: f8c31b1ffe11 19 | Revises: bb07adac380 20 | Create Date: 2016-06-02 19:39:42.495020 21 | 22 | """ 23 | 24 | # revision identifiers, used by Alembic. 25 | revision = 'f8c31b1ffe11' 26 | down_revision = 'bb07adac380' 27 | branch_labels = None 28 | depends_on = None 29 | 30 | from alembic import op 31 | 32 | 33 | def upgrade(): 34 | op.create_index( 35 | 'ix_alarm_enabled', 'alarm', ['enabled'], unique=False) 36 | op.create_index( 37 | 'ix_alarm_type', 'alarm', ['type'], unique=False) 38 | -------------------------------------------------------------------------------- /aodh/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/tests/__init__.py -------------------------------------------------------------------------------- /aodh/tests/constants.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Huawei Technologies Co., Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | import datetime 16 | 17 | MIN_DATETIME = datetime.datetime(datetime.MINYEAR, 1, 1) 18 | -------------------------------------------------------------------------------- /aodh/tests/functional/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/tests/functional/__init__.py -------------------------------------------------------------------------------- /aodh/tests/functional/api/v2/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012 New Dream Network, LLC (DreamHost) 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from aodh.tests.functional import api 17 | 18 | 19 | class FunctionalTest(api.FunctionalTest): 20 | PATH_PREFIX = '/v2' 21 | -------------------------------------------------------------------------------- /aodh/tests/functional/api/v2/policy.yaml-test: -------------------------------------------------------------------------------- 1 | # WARNING: Below rules are either deprecated rules 2 | # or extra rules in policy file, it is strongly 3 | # recommended to switch to new rules. 4 | "context_is_admin": "role:admin" 5 | "segregation": "rule:context_is_admin" 6 | "admin_or_owner": "rule:context_is_admin or project_id:%(project_id)s" 7 | "default": "rule:admin_or_owner" 8 | "telemetry:get_alarms": "role:admin" 9 | "telemetry:get_metrics": "role:admin" 10 | -------------------------------------------------------------------------------- /aodh/tests/functional/hooks/post_test_hook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | 3 | #FIXME(sileht): remove me when dsvm gate job is removed 4 | 5 | 6 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 7 | # not use this file except in compliance with the License. You may obtain 8 | # a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | # License for the specific language governing permissions and limitations 16 | # under the License. 17 | 18 | # This script is executed inside post_test_hook function in devstack gate. 19 | 20 | set -e 21 | exit 0 22 | -------------------------------------------------------------------------------- /aodh/tests/functional/storage/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/tests/functional/storage/__init__.py -------------------------------------------------------------------------------- /aodh/tests/functional/storage/sqlalchemy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/tests/functional/storage/sqlalchemy/__init__.py -------------------------------------------------------------------------------- /aodh/tests/functional/storage/sqlalchemy/test_migrations.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Huawei Technologies Co., Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | import abc 16 | from unittest import mock 17 | 18 | from oslo_db.sqlalchemy import enginefacade 19 | from oslo_db.sqlalchemy import test_migrations 20 | 21 | from aodh.storage.sqlalchemy import models 22 | from aodh.tests import base 23 | from aodh.tests.functional import db as tests_db 24 | 25 | 26 | class ABCSkip(base.SkipNotImplementedMeta, abc.ABCMeta): 27 | pass 28 | 29 | 30 | class ModelsMigrationsSync(tests_db.TestBase, 31 | test_migrations.ModelsMigrationsSync, 32 | metaclass=ABCSkip): 33 | 34 | def setUp(self): 35 | super(ModelsMigrationsSync, self).setUp() 36 | self.db = mock.Mock() 37 | 38 | @staticmethod 39 | def get_metadata(): 40 | return models.Base.metadata 41 | 42 | def get_engine(self): 43 | return enginefacade.writer.get_engine() 44 | 45 | def db_sync(self, engine): 46 | pass 47 | -------------------------------------------------------------------------------- /aodh/tests/functional/storage/test_get_connection.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012 New Dream Network, LLC (DreamHost) 3 | # Copyright 2015 Red Hat, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | """Tests for aodh/storage/ 17 | """ 18 | from unittest import mock 19 | 20 | from oslo_config import fixture as fixture_config 21 | from oslotest import base 22 | 23 | from aodh import service 24 | from aodh import storage 25 | from aodh.storage import impl_log 26 | 27 | 28 | class EngineTest(base.BaseTestCase): 29 | def setUp(self): 30 | super(EngineTest, self).setUp() 31 | conf = service.prepare_service(argv=[], config_files=[]) 32 | self.CONF = self.useFixture(fixture_config.Config(conf)).conf 33 | 34 | def test_get_connection(self): 35 | self.CONF.set_override('connection', 'log://localhost', 36 | group='database') 37 | engine = storage.get_connection_from_config(self.CONF) 38 | self.assertIsInstance(engine, impl_log.Connection) 39 | 40 | def test_get_connection_no_such_engine(self): 41 | self.CONF.set_override('connection', 'no-such-engine://localhost', 42 | group='database') 43 | self.CONF.set_override('max_retries', 0, 'database') 44 | try: 45 | storage.get_connection_from_config(self.CONF) 46 | except RuntimeError as err: 47 | self.assertIn('no-such-engine', str(err)) 48 | 49 | 50 | class ConnectionRetryTest(base.BaseTestCase): 51 | def setUp(self): 52 | super(ConnectionRetryTest, self).setUp() 53 | conf = service.prepare_service(argv=[], config_files=[]) 54 | self.CONF = self.useFixture(fixture_config.Config(conf)).conf 55 | 56 | def test_retries(self): 57 | max_retries = 5 58 | with mock.patch.object( 59 | storage.impl_log.Connection, '__init__') as log_init: 60 | 61 | class ConnectionError(Exception): 62 | pass 63 | 64 | def x(conf): 65 | raise ConnectionError 66 | 67 | log_init.side_effect = x 68 | self.CONF.set_override("connection", "log://", "database") 69 | self.CONF.set_override("retry_interval", 0.00001, "database") 70 | self.CONF.set_override("max_retries", max_retries, "database") 71 | self.assertRaises(ConnectionError, 72 | storage.get_connection_from_config, 73 | self.CONF) 74 | self.assertEqual(max_retries, log_init.call_count) 75 | 76 | 77 | class ConnectionConfigTest(base.BaseTestCase): 78 | def setUp(self): 79 | super(ConnectionConfigTest, self).setUp() 80 | conf = service.prepare_service(argv=[], config_files=[]) 81 | self.CONF = self.useFixture(fixture_config.Config(conf)).conf 82 | 83 | def test_only_default_url(self): 84 | self.CONF.set_override("connection", "log://", group="database") 85 | conn = storage.get_connection_from_config(self.CONF) 86 | self.assertIsInstance(conn, impl_log.Connection) 87 | -------------------------------------------------------------------------------- /aodh/tests/functional/storage/test_impl_log.py: -------------------------------------------------------------------------------- 1 | # Copyright 2012 New Dream Network, LLC (DreamHost) 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | from oslo_config import cfg 16 | from oslotest import base 17 | 18 | from aodh.storage import impl_log 19 | 20 | 21 | class ConnectionTest(base.BaseTestCase): 22 | @staticmethod 23 | def test_get_connection(): 24 | impl_log.Connection(cfg.CONF) 25 | -------------------------------------------------------------------------------- /aodh/tests/functional/storage/test_impl_sqlalchemy.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | """Tests for aodh/storage/impl_sqlalchemy.py 13 | 14 | .. note:: 15 | In order to run the tests against real SQL server set the environment 16 | variable aodh_TEST_SQL_URL to point to a SQL server before running 17 | the tests. 18 | 19 | """ 20 | 21 | from aodh.storage import impl_sqlalchemy as impl_sqla_alarm 22 | from aodh.tests import base as test_base 23 | 24 | 25 | class CapabilitiesTest(test_base.BaseTestCase): 26 | def test_alarm_capabilities(self): 27 | expected_capabilities = { 28 | 'alarms': {'query': {'simple': True, 29 | 'complex': True}, 30 | 'history': {'query': {'simple': True, 31 | 'complex': True}}}, 32 | } 33 | 34 | actual_capabilities = impl_sqla_alarm.Connection.get_capabilities() 35 | self.assertEqual(expected_capabilities, actual_capabilities) 36 | -------------------------------------------------------------------------------- /aodh/tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/tests/unit/__init__.py -------------------------------------------------------------------------------- /aodh/tests/unit/cmd/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/tests/unit/cmd/__init__.py -------------------------------------------------------------------------------- /aodh/tests/unit/cmd/test_status.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018 NEC, Corp. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | from oslo_config import cfg 16 | from oslo_upgradecheck.upgradecheck import Code 17 | 18 | from aodh.cmd import status 19 | from aodh.tests import base 20 | 21 | 22 | class TestUpgradeChecks(base.BaseTestCase): 23 | 24 | def setUp(self): 25 | super(TestUpgradeChecks, self).setUp() 26 | self.cmd = status.Checks() 27 | cfg.CONF(args=[], project='aodh') 28 | 29 | def test_checks(self): 30 | for name, func in self.cmd._upgrade_checks: 31 | if isinstance(func, tuple): 32 | func_name, kwargs = func 33 | result = func_name(self, **kwargs) 34 | else: 35 | result = func(self) 36 | self.assertEqual(Code.SUCCESS, result.code) 37 | -------------------------------------------------------------------------------- /aodh/tests/unit/evaluator/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/tests/unit/evaluator/__init__.py -------------------------------------------------------------------------------- /aodh/tests/unit/evaluator/base.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2013 eNovance 3 | # Copyright 2015 Red Hat, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | from unittest import mock 17 | 18 | from oslo_config import fixture 19 | from oslotest import base 20 | 21 | from aodh import service 22 | 23 | 24 | class TestEvaluatorBase(base.BaseTestCase): 25 | def setUp(self): 26 | super(TestEvaluatorBase, self).setUp() 27 | conf = service.prepare_service(argv=[], config_files=[]) 28 | self.conf = self.useFixture(fixture.Config(conf)).conf 29 | self.evaluator = self.EVALUATOR(self.conf) 30 | self.notifier = mock.MagicMock() 31 | self.evaluator.notifier = self.notifier 32 | self.storage_conn = mock.MagicMock() 33 | self.evaluator.storage_conn = self.storage_conn 34 | self.evaluator._ks_client = mock.Mock(user_id='fake_user_id', 35 | project_id='fake_project_id', 36 | auth_token='fake_token') 37 | self.prepare_alarms() 38 | 39 | def prepare_alarms(self): 40 | self.alarms = [] 41 | 42 | def _evaluate_all_alarms(self): 43 | for alarm in self.alarms: 44 | self.evaluator.evaluate(alarm) 45 | 46 | def _set_all_alarms(self, state): 47 | for alarm in self.alarms: 48 | alarm.state = state 49 | 50 | def _assert_all_alarms(self, state): 51 | for alarm in self.alarms: 52 | self.assertEqual(state, alarm.state) 53 | -------------------------------------------------------------------------------- /aodh/tests/unit/notifier/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/tests/unit/notifier/__init__.py -------------------------------------------------------------------------------- /aodh/tests/unit/notifier/base.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Catalyst Cloud Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from oslo_config import fixture 16 | from oslotest import base 17 | 18 | from aodh import service 19 | 20 | 21 | class TestNotifierBase(base.BaseTestCase): 22 | def setUp(self): 23 | super(TestNotifierBase, self).setUp() 24 | 25 | conf = service.prepare_service(argv=[], config_files=[]) 26 | 27 | self.conf = self.useFixture(fixture.Config(conf)).conf 28 | -------------------------------------------------------------------------------- /aodh/tests/unit/notifier/test_heat.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Catalyst Cloud Ltd. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from unittest import mock 16 | 17 | from oslo_utils import netutils 18 | 19 | from aodh.notifier import heat as heat_notifier 20 | from aodh.tests.unit.notifier import base 21 | 22 | 23 | class TestTrustHeatAlarmNotifier(base.TestNotifierBase): 24 | @mock.patch("aodh.keystone_client.get_heat_client_from_trust") 25 | def test_notify(self, mock_heatclient): 26 | action = netutils.urlsplit("trust+autohealer://fake_trust_id:delete@") 27 | alarm_id = "fake_alarm_id" 28 | alarm_name = "fake_alarm_name" 29 | severity = "low" 30 | previous = "ok" 31 | current = "alarm" 32 | reason = "no good reason" 33 | reason_data = { 34 | "stack_id": "fake_stack_id", 35 | "asg_id": "fake_asg_id", 36 | "unhealthy_members": [ 37 | {"id": "3bd8bc5a-7632-11e9-84cd-00224d6b7bc1"} 38 | ] 39 | } 40 | 41 | class FakeResource(object): 42 | def __init__(self, resource_name): 43 | self.parent_resource = resource_name 44 | 45 | mock_client = mock_heatclient.return_value 46 | mock_client.resources.list.return_value = [ 47 | FakeResource("fake_resource_name") 48 | ] 49 | 50 | notifier = heat_notifier.TrustHeatAlarmNotifier(self.conf) 51 | notifier.notify(action, alarm_id, alarm_name, severity, previous, 52 | current, reason, reason_data) 53 | 54 | mock_heatclient.assert_called_once_with(self.conf, "fake_trust_id") 55 | mock_client.resources.mark_unhealthy.assert_called_once_with( 56 | "fake_asg_id", 57 | "fake_resource_name", 58 | True, 59 | "unhealthy load balancer member" 60 | ) 61 | mock_client.stacks.update.assert_called_once_with( 62 | "fake_stack_id", existing=True 63 | ) 64 | 65 | @mock.patch("aodh.keystone_client.get_heat_client_from_trust") 66 | def test_notify_stack_id_missing(self, mock_heatclient): 67 | action = netutils.urlsplit("trust+autohealer://fake_trust_id:delete@") 68 | alarm_id = "fake_alarm_id" 69 | alarm_name = "fake_alarm_name" 70 | severity = "low" 71 | previous = "ok" 72 | current = "alarm" 73 | reason = "no good reason" 74 | reason_data = { 75 | "asg_id": "fake_asg_id", 76 | "unhealthy_members": [ 77 | {"tags": ["3bd8bc5a-7632-11e9-84cd-00224d6b7bc1"]} 78 | ] 79 | } 80 | 81 | notifier = heat_notifier.TrustHeatAlarmNotifier(self.conf) 82 | notifier.notify(action, alarm_id, alarm_name, severity, previous, 83 | current, reason, reason_data) 84 | 85 | self.assertFalse(mock_heatclient.called) 86 | -------------------------------------------------------------------------------- /aodh/tests/unit/test_api_v2_capabilities.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | from oslotest import base 13 | 14 | from aodh.api.controllers.v2 import capabilities 15 | 16 | 17 | class TestCapabilities(base.BaseTestCase): 18 | 19 | def test_recursive_keypairs(self): 20 | data = {'a': 'A', 'b': 'B', 21 | 'nested': {'a': 'A', 'b': 'B'}} 22 | pairs = list(capabilities._recursive_keypairs(data)) 23 | self.assertEqual([('a', 'A'), ('b', 'B'), 24 | ('nested:a', 'A'), ('nested:b', 'B')], 25 | pairs) 26 | 27 | def test_recursive_keypairs_with_separator(self): 28 | data = {'a': 'A', 29 | 'b': 'B', 30 | 'nested': {'a': 'A', 31 | 'b': 'B', 32 | }, 33 | } 34 | separator = '.' 35 | pairs = list(capabilities._recursive_keypairs(data, separator)) 36 | self.assertEqual([('a', 'A'), 37 | ('b', 'B'), 38 | ('nested.a', 'A'), 39 | ('nested.b', 'B')], 40 | pairs) 41 | 42 | def test_recursive_keypairs_with_list_of_dict(self): 43 | small = 1 44 | big = 1 << 64 45 | expected = [('a', 'A'), 46 | ('b', 'B'), 47 | ('nested:list', [{small: 99, big: 42}])] 48 | data = {'a': 'A', 49 | 'b': 'B', 50 | 'nested': {'list': [{small: 99, big: 42}]}} 51 | pairs = list(capabilities._recursive_keypairs(data)) 52 | self.assertEqual(len(expected), len(pairs)) 53 | for k, v in pairs: 54 | # the keys 1 and 1<<64 cause a hash collision on 64bit platforms 55 | if k == 'nested:list': 56 | self.assertIn(v, 57 | [[{small: 99, big: 42}], 58 | [{big: 42, small: 99}]]) 59 | else: 60 | self.assertIn((k, v), expected) 61 | -------------------------------------------------------------------------------- /aodh/tests/unit/test_event.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015 NEC Corporation. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import time 17 | from unittest import mock 18 | 19 | from oslo_config import fixture as fixture_config 20 | import oslo_messaging 21 | 22 | from aodh import event 23 | from aodh import service 24 | from aodh.tests import base as tests_base 25 | 26 | 27 | class TestEventAlarmEvaluationService(tests_base.BaseTestCase): 28 | 29 | def setUp(self): 30 | super(TestEventAlarmEvaluationService, self).setUp() 31 | conf = service.prepare_service(argv=[], config_files=[]) 32 | self.CONF = self.useFixture(fixture_config.Config(conf)).conf 33 | self.CONF.set_override("batch_size", 2, 'listener') 34 | self.setup_messaging(self.CONF) 35 | 36 | @mock.patch('aodh.storage.get_connection_from_config', 37 | mock.MagicMock()) 38 | @mock.patch('aodh.event.EventAlarmEndpoint.sample') 39 | def test_batch_event_listener(self, mocked): 40 | msg_notifier = oslo_messaging.Notifier( 41 | self.transport, topics=['alarm.all'], driver='messaging', 42 | publisher_id='test-publisher') 43 | 44 | received_events = [] 45 | mocked.side_effect = lambda msg: received_events.append(msg) 46 | event1 = {'event_type': 'compute.instance.update', 47 | 'traits': ['foo', 'bar'], 48 | 'message_id': '20d03d17-4aba-4900-a179-dba1281a3451', 49 | 'generated': '2016-04-23T06:50:21.622739'} 50 | event2 = {'event_type': 'compute.instance.update', 51 | 'traits': ['foo', 'bar'], 52 | 'message_id': '20d03d17-4aba-4900-a179-dba1281a3452', 53 | 'generated': '2016-04-23T06:50:23.622739'} 54 | msg_notifier.sample({}, 'event', event1) 55 | msg_notifier.sample({}, 'event', event2) 56 | 57 | svc = event.EventAlarmEvaluationService(0, self.CONF) 58 | self.addCleanup(svc.terminate) 59 | 60 | time.sleep(1) 61 | self.assertEqual(1, len(received_events)) 62 | self.assertEqual(2, len(received_events[0])) 63 | -------------------------------------------------------------------------------- /aodh/tests/unit/test_messaging.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2014 eNovance SAS 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | from oslo_config import fixture as fixture_config 16 | import oslo_messaging.conffixture 17 | from oslotest import base 18 | 19 | from aodh import messaging 20 | 21 | 22 | class MessagingTests(base.BaseTestCase): 23 | def setUp(self): 24 | super(MessagingTests, self).setUp() 25 | self.CONF = self.useFixture(fixture_config.Config()).conf 26 | self.useFixture(oslo_messaging.conffixture.ConfFixture(self.CONF)) 27 | 28 | def test_get_transport_invalid_url(self): 29 | self.assertRaises(oslo_messaging.InvalidTransportURL, 30 | messaging.get_transport, self.CONF, "notvalid!") 31 | 32 | def test_get_transport_url_caching(self): 33 | t1 = messaging.get_transport(self.CONF, 'fake://') 34 | t2 = messaging.get_transport(self.CONF, 'fake://') 35 | self.assertEqual(t1, t2) 36 | 37 | def test_get_transport_default_url_caching(self): 38 | t1 = messaging.get_transport(self.CONF, ) 39 | t2 = messaging.get_transport(self.CONF, ) 40 | self.assertEqual(t1, t2) 41 | 42 | def test_get_transport_default_url_no_caching(self): 43 | t1 = messaging.get_transport(self.CONF, cache=False) 44 | t2 = messaging.get_transport(self.CONF, cache=False) 45 | self.assertNotEqual(t1, t2) 46 | 47 | def test_get_transport_url_no_caching(self): 48 | t1 = messaging.get_transport(self.CONF, 'fake://', cache=False) 49 | t2 = messaging.get_transport(self.CONF, 'fake://', cache=False) 50 | self.assertNotEqual(t1, t2) 51 | 52 | def test_get_transport_default_url_caching_mix(self): 53 | t1 = messaging.get_transport(self.CONF, ) 54 | t2 = messaging.get_transport(self.CONF, cache=False) 55 | self.assertNotEqual(t1, t2) 56 | 57 | def test_get_transport_url_caching_mix(self): 58 | t1 = messaging.get_transport(self.CONF, 'fake://') 59 | t2 = messaging.get_transport(self.CONF, 'fake://', cache=False) 60 | self.assertNotEqual(t1, t2) 61 | 62 | def test_get_transport_optional(self): 63 | self.CONF.set_override('transport_url', 'non-url') 64 | self.assertIsNone(messaging.get_transport(self.CONF, optional=True, 65 | cache=False)) 66 | -------------------------------------------------------------------------------- /aodh/tests/unit/test_wsme_custom_type.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2013 eNovance 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | from oslotest import base 16 | import wsme 17 | 18 | from aodh.api.controllers.v2 import base as v2_base 19 | 20 | 21 | class TestWsmeCustomType(base.BaseTestCase): 22 | 23 | def test_advenum_default(self): 24 | class dummybase(wsme.types.Base): 25 | ae = v2_base.AdvEnum("name", str, "one", "other", default="other") 26 | 27 | obj = dummybase() 28 | self.assertEqual("other", obj.ae) 29 | 30 | obj = dummybase(ae="one") 31 | self.assertEqual("one", obj.ae) 32 | 33 | self.assertRaises(wsme.exc.InvalidInput, dummybase, ae="not exists") 34 | -------------------------------------------------------------------------------- /aodh/utils.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 - Nokia Corporation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | import inspect 15 | 16 | 17 | def get_func_valid_keys(func): 18 | return inspect.getfullargspec(func)[0] 19 | -------------------------------------------------------------------------------- /aodh/version.py: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 3 | # not use this file except in compliance with the License. You may obtain 4 | # a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | # License for the specific language governing permissions and limitations 12 | # under the License. 13 | 14 | 15 | import pbr.version 16 | 17 | version_info = pbr.version.VersionInfo('aodh') 18 | -------------------------------------------------------------------------------- /aodh/wsgi/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/aodh/wsgi/__init__.py -------------------------------------------------------------------------------- /aodh/wsgi/api.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | """WSGI application entry-point for Aodh API.""" 13 | 14 | import threading 15 | 16 | from aodh.api import app 17 | 18 | 19 | application = None 20 | with threading.Lock(): 21 | if application is None: 22 | application = app.build_wsgi_app(argv=[]) 23 | -------------------------------------------------------------------------------- /bindep.txt: -------------------------------------------------------------------------------- 1 | postgresql 2 | postgresql-client [platform:dpkg] 3 | libpq-dev [platform:dpkg] 4 | postgresql-devel [platform:rpm] 5 | postgresql-server [platform:rpm] 6 | 7 | mysql-server [!platform:debian] 8 | mariadb-server [platform:debian] 9 | mysql-client [platform:dpkg !platform:debian] 10 | mysql [platform:rpm] 11 | 12 | gettext [platform:dpkg] 13 | python37 [platform:rpm py37] 14 | -------------------------------------------------------------------------------- /devstack/README.rst: -------------------------------------------------------------------------------- 1 | ========================= 2 | Enabling Aodh in DevStack 3 | ========================= 4 | 5 | 1. Download DevStack:: 6 | 7 | git clone https://opendev.org/openstack/devstack.git 8 | cd devstack 9 | 10 | 2. Add this repo as an external repository in ``local.conf`` file:: 11 | 12 | [[local|localrc]] 13 | enable_plugin aodh https://opendev.org/openstack/aodh 14 | 15 | To use stable branches, make sure devstack is on that branch, and specify 16 | the branch name to enable_plugin, for example:: 17 | 18 | enable_plugin aodh https://opendev.org/openstack/aodh stable/mitaka 19 | 20 | There are some options, such as AODH_BACKEND, defined in 21 | ``aodh/devstack/settings``, they can be used to configure the installation 22 | of Aodh. If you don't want to use their default value, you can set a new 23 | one in ``local.conf``. 24 | 25 | 3. Run ``stack.sh``. 26 | -------------------------------------------------------------------------------- /devstack/settings: -------------------------------------------------------------------------------- 1 | # turn on all the aodh services by default 2 | # API service 3 | enable_service aodh-api 4 | # Alarming 5 | enable_service aodh-notifier aodh-evaluator 6 | # Listener for Event Alarming 7 | enable_service aodh-listener 8 | 9 | # Default directories 10 | AODH_DIR=$DEST/aodh 11 | AODH_CONF_DIR=/etc/aodh 12 | AODH_CONF=$AODH_CONF_DIR/aodh.conf 13 | AODH_UWSGI_CONF=$AODH_CONF_DIR/aodh-uwsgi.ini 14 | AODH_UWSGI=aodh.wsgi.api:application 15 | 16 | # Set up database backend 17 | AODH_BACKEND=${AODH_BACKEND:-mysql} 18 | 19 | # Aodh connection info. 20 | AODH_SERVICE_PROTOCOL=http 21 | AODH_SERVICE_HOST=${AODH_SERVICE_HOST:-$SERVICE_HOST} 22 | 23 | AODH_NOTIFICATION_TOPICS=${AODH_NOTIFICATION_TOPICS:-notifications} 24 | 25 | AODH_COORDINATION_URL=${AODH_COORDINATION_URL:-} 26 | 27 | # Set up default directories for client 28 | GITDIR["python-aodhclient"]=$DEST/python-aodhclient 29 | GITREPO["python-aodhclient"]=$GIT_BASE/openstack/python-aodhclient.git 30 | 31 | # Get rid of this before done. 32 | # Tell emacs to use shell-script-mode 33 | ## Local variables: 34 | ## mode: shell-script 35 | ## End: 36 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | openstackdocstheme>=2.2.1 # Apache-2.0 2 | reno>=3.1.0 # Apache-2.0 3 | sphinx>=2.1.1 # BSD 4 | sphinxcontrib-httpdomain>=1.8.1 # BSD 5 | sphinxcontrib-pecanwsme>=0.10.0 # BSD 6 | -------------------------------------------------------------------------------- /doc/source/_static/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/doc/source/_static/.placeholder -------------------------------------------------------------------------------- /doc/source/admin/index.rst: -------------------------------------------------------------------------------- 1 | ==================== 2 | Administration Guide 3 | ==================== 4 | 5 | This guide contains information that will help you understand how to deploy, 6 | operate, and upgrade Aodh 7 | 8 | .. toctree:: 9 | 10 | telemetry-alarms.rst 11 | resource-quota.rst 12 | -------------------------------------------------------------------------------- /doc/source/admin/resource-quota.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright (c) 2020 Catalyst Cloud Limited 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | ========================= 17 | Resource Quota Management 18 | ========================= 19 | 20 | The amount of resources(e.g. alarms) that could be created by each OpenStack 21 | project is controlled by quota. The default resource quota for each project is 22 | set in Aodh config file as follows unless changed by the cloud administrator 23 | via Quota API. 24 | 25 | .. code-block:: ini 26 | 27 | [api] 28 | user_alarm_quota = -1 29 | project_alarm_quota = -1 30 | alarm_max_actions = -1 31 | 32 | user_alarm_quota 33 | The default alarm quota for an openstack user, default is unlimited. 34 | Sometimes the alarm creation request satisfies the project quota but fails 35 | the user quota. 36 | 37 | project_alarm_quota 38 | The default alarm quota for an openstack project, default is unlimited. The 39 | cloud administrator can change project quota using Quota API, see examples 40 | below. 41 | 42 | alarm_max_actions 43 | The maximum number of alarm actions could be created per alarm, default is 44 | unlimited. 45 | 46 | 47 | Quota API 48 | --------- 49 | Aodh Quota API is aiming for multi-tenancy support. By default, only the admin 50 | user is able to change the resource quota for projects as defined by the 51 | default policy rule 'telemetry:update_quotas'. User alarm quota and alarm 52 | action quota are not supported in Quota API. 53 | 54 | An HTTP request example using ``httpie`` command: 55 | 56 | .. code-block:: console 57 | 58 | cat < [] 15 | 16 | Description 17 | =========== 18 | 19 | :program:`aodh-status` is a tool that provides routines for checking the 20 | status of a Aodh deployment. 21 | 22 | Options 23 | ======= 24 | 25 | The standard pattern for executing a :program:`aodh-status` command is:: 26 | 27 | aodh-status [] 28 | 29 | Run without arguments to see a list of available command categories:: 30 | 31 | aodh-status 32 | 33 | Categories are: 34 | 35 | * ``upgrade`` 36 | 37 | Detailed descriptions are below: 38 | 39 | You can also run with a category argument such as ``upgrade`` to see a list of 40 | all commands in that category:: 41 | 42 | aodh-status upgrade 43 | 44 | These sections describe the available categories and arguments for 45 | :program:`aodh-status`. 46 | 47 | Upgrade 48 | ~~~~~~~ 49 | 50 | .. _aodh-status-checks: 51 | 52 | ``aodh-status upgrade check`` 53 | Performs a release-specific readiness check before restarting services with 54 | new code. For example, missing or changed configuration options, 55 | incompatible object states, or other conditions that could lead to 56 | failures while upgrading. 57 | 58 | **Return Codes** 59 | 60 | .. list-table:: 61 | :widths: 20 80 62 | :header-rows: 1 63 | 64 | * - Return code 65 | - Description 66 | * - 0 67 | - All upgrade readiness checks passed successfully and there is nothing 68 | to do. 69 | * - 1 70 | - At least one check encountered an issue and requires further 71 | investigation. This is considered a warning but the upgrade may be OK. 72 | * - 2 73 | - There was an upgrade status check failure that needs to be 74 | investigated. This should be considered something that stops an 75 | upgrade. 76 | * - 255 77 | - An unexpected error occurred. 78 | 79 | **History of Checks** 80 | 81 | **8.0.0 (Stein)** 82 | 83 | * Sample check to be filled in with checks as they are added in Stein. 84 | -------------------------------------------------------------------------------- /doc/source/cli/index.rst: -------------------------------------------------------------------------------- 1 | ====================== 2 | Aodh CLI Documentation 3 | ====================== 4 | 5 | In this section you will find information on Aodh’s command line 6 | interface. 7 | 8 | .. toctree:: 9 | :maxdepth: 1 10 | 11 | aodh-status 12 | -------------------------------------------------------------------------------- /doc/source/configuration/aodh-config-file.rst: -------------------------------------------------------------------------------- 1 | .. _aodh-config-file: 2 | 3 | Aodh Sample Configuration File 4 | ============================== 5 | 6 | Configure Aodh by editing /etc/aodh/aodh.conf. 7 | 8 | No config file is provided with the source code, it will be created during 9 | the installation. In case where no configuration file was installed, one 10 | can be easily created by running:: 11 | 12 | aodh-config-generator 13 | 14 | 15 | .. only:: html 16 | 17 | The following is a sample Aodh configuration for adaptation and use. 18 | It is auto-generated from Aodh when this documentation is built, and 19 | can also be viewed in `file form <../_static/aodh.conf.sample>`_. 20 | 21 | .. literalinclude:: ../_static/aodh.conf.sample 22 | -------------------------------------------------------------------------------- /doc/source/configuration/aodh-config-options.rst: -------------------------------------------------------------------------------- 1 | Aodh Configuration Options 2 | ========================== 3 | 4 | .. show-options:: 5 | :split-namespaces: 6 | 7 | aodh 8 | -------------------------------------------------------------------------------- /doc/source/configuration/index.rst: -------------------------------------------------------------------------------- 1 | .. _configuring: 2 | 3 | =================== 4 | Configuration Guide 5 | =================== 6 | 7 | .. toctree:: 8 | aodh-config-file.rst 9 | aodh-config-options.rst 10 | policy 11 | sample-policy-yaml 12 | -------------------------------------------------------------------------------- /doc/source/configuration/policy.rst: -------------------------------------------------------------------------------- 1 | ===================================== 2 | Aodh Sample Policy Configuration File 3 | ===================================== 4 | 5 | .. warning:: 6 | 7 | JSON formatted policy file is deprecated since Aodh 12.0.0 (Wallaby). 8 | This `oslopolicy-convert-json-to-yaml`__ tool will migrate your existing 9 | JSON-formatted policy file to YAML in a backward-compatible way. 10 | 11 | .. __: https://docs.openstack.org/oslo.policy/latest/cli/oslopolicy-convert-json-to-yaml.html 12 | 13 | The following is an overview of all available policies in Aodh. 14 | For a sample configuration file, refer to :doc:`sample-policy-yaml`. 15 | 16 | .. show-policy:: 17 | :config-file: ../../aodh/cmd/aodh-policy-generator.conf 18 | -------------------------------------------------------------------------------- /doc/source/configuration/sample-policy-yaml.rst: -------------------------------------------------------------------------------- 1 | =========== 2 | policy.yaml 3 | =========== 4 | 5 | .. warning:: 6 | 7 | JSON formatted policy file is deprecated since Aodh 12.0.0 (Wallaby). 8 | This `oslopolicy-convert-json-to-yaml`__ tool will migrate your existing 9 | JSON-formatted policy file to YAML in a backward-compatible way. 10 | 11 | .. __: https://docs.openstack.org/oslo.policy/latest/cli/oslopolicy-convert-json-to-yaml.html 12 | 13 | Use the ``policy.yaml`` file to define additional access controls that will be 14 | applied to Aodh: 15 | 16 | .. literalinclude:: ../_static/aodh.policy.yaml.sample 17 | -------------------------------------------------------------------------------- /doc/source/contributor/architecture.rst: -------------------------------------------------------------------------------- 1 | .. _architecture: 2 | 3 | =================== 4 | System Architecture 5 | =================== 6 | 7 | High-Level Architecture 8 | ======================= 9 | 10 | Each of Aodh's services are designed to scale horizontally. Additional 11 | workers and nodes can be added depending on the expected load. It provides 12 | daemons to evaluate and notify based on defined alarming rules. 13 | 14 | Evaluating the data 15 | =================== 16 | 17 | Alarming Service 18 | ---------------- 19 | 20 | The alarming component of Aodh, first delivered in Ceilometer service during 21 | Havana development cycle then split out to this independent project in Liberty 22 | development cycle, allows you to set alarms based on threshold evaluation for 23 | a collection of samples or a dedicate event. An alarm can be set on a single 24 | meter, or on a combination. For example, you may want to trigger an alarm when 25 | the memory consumption reaches 70% on a given instance if the instance has been 26 | up for more than 10 min. To setup an alarm, you will call 27 | :ref:`Aodh's API server ` specifying the alarm conditions and 28 | an action to take. 29 | 30 | Of course, if you are not administrator of the cloud itself, you can only set 31 | alarms on meters for your own components. 32 | 33 | There can be multiple form of actions, but only several actions have been 34 | implemented so far: 35 | 36 | 1. :term:`HTTP callback`: you provide a URL to be called whenever the alarm has 37 | been set off. The payload of the request contains all the details of why the 38 | alarm was triggered. 39 | 2. :term:`log`: mostly useful for debugging, stores alarms in a log file. 40 | 3. :term:`zaqar`: Send notification to messaging service via Zaqar API. 41 | 42 | Alarm Rules 43 | =========== 44 | 45 | .. list-plugins:: aodh.alarm.rule 46 | :detailed: 47 | 48 | Alarm Evaluators 49 | ================ 50 | 51 | .. list-plugins:: aodh.evaluator 52 | :detailed: 53 | 54 | Alarm Notifiers 55 | =============== 56 | 57 | .. list-plugins:: aodh.notifier 58 | :detailed: 59 | 60 | Alarm Storage 61 | ============= 62 | 63 | .. list-plugins:: aodh.storage 64 | :detailed: 65 | -------------------------------------------------------------------------------- /doc/source/contributor/contributing.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Licensed under the Apache License, Version 2.0 (the "License"); you may 3 | not use this file except in compliance with the License. You may obtain 4 | a copy of the License at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | License for the specific language governing permissions and limitations 12 | under the License. 13 | 14 | .. _contributing: 15 | 16 | ==================== 17 | Contributing to Aodh 18 | ==================== 19 | 20 | Aodh follows the same workflow as other OpenStack projects. To start 21 | contributing to Aodh, please follow the workflow found here_. 22 | 23 | .. _here: https://wiki.openstack.org/wiki/Gerrit_Workflow 24 | 25 | 26 | Project Hosting Details 27 | ======================= 28 | 29 | :Bug tracker: https://bugs.launchpad.net/aodh 30 | :Mailing list: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev (prefix subjects with ``[Aodh]`` for faster responses) 31 | :Code Hosting: https://opendev.org/openstack/aodh/ 32 | :Code Review: https://review.opendev.org/#/q/status:open+project:openstack/aodh,n,z 33 | -------------------------------------------------------------------------------- /doc/source/contributor/event-alarm.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2014 Huawei Technologies Co., Ltd. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | =========== 17 | Event alarm 18 | =========== 19 | 20 | Aodh allows users to define alarms which can be evaluated based on events 21 | passed from other OpenStack services. The events can be emitted when the 22 | resources from other OpenStack services have been updated, created or deleted, 23 | such as 'compute.instance.reboot.end', 'scheduler.select_destinations.end'. 24 | When creating an alarm with type of "event", an event_type can be specified to 25 | identify the type of event that will trigger the alarm. The event_type field 26 | support fuzzy matching with wildcard. Additionally, users can also specify 27 | query conditions to filter specific events used to trigger the alarm. 28 | 29 | This feature was implemented with proposal event-alarm_. 30 | 31 | .. _event-alarm: https://blueprints.launchpad.net/ceilometer/+spec/event-alarm-evaluator 32 | 33 | Usage 34 | ===== 35 | 36 | When creating an alarm of "event" type, the "event_rule" need to be specified, 37 | which includes an "event_type" field and a "query" field, the "event_type" 38 | allow users to specify a specific event type used to match the incoming events 39 | when evaluating alarm, and the "query" field includes a list of query 40 | conditions used to filter specific events when evaluating the alarm. 41 | 42 | The following is an example of event alarm rule:: 43 | 44 | "event_rule": { 45 | "event_type": "compute.instance.update", 46 | "query" : [ 47 | { 48 | "field" : "traits.instance_id", 49 | "type" : "string", 50 | "value" : "153462d0-a9b8-4b5b-8175-9e4b05e9b856", 51 | "op" : "eq", 52 | }, 53 | { 54 | "field" : "traits.state", 55 | "type" : "string", 56 | "value" : "error", 57 | "op" : "eq", 58 | }, 59 | ] 60 | } 61 | 62 | 63 | Configuration 64 | ============= 65 | 66 | To enable this functionality, config the Ceilometer to be able to 67 | publish events to the queue the aodh-listener service listen on. The 68 | *event_alarm_topic* config option of Aodh identify which messaging 69 | topic the aodh-listener on, the default value is "alarm.all". In 70 | Ceilometer side, a publisher of notifier type need to be configured in 71 | the event pipeline config file(``event_pipeline.yaml`` as default), 72 | the notifier should be with a messaging topic same as the 73 | *event_alarm_topic* option defined. For an example:: 74 | 75 | --- 76 | sources: 77 | - name: event_source 78 | events: 79 | - "*" 80 | sinks: 81 | - event_sink 82 | sinks: 83 | - name: event_sink 84 | transformers: 85 | publishers: 86 | - notifier:// 87 | - notifier://?topic=alarm.all 88 | -------------------------------------------------------------------------------- /doc/source/contributor/gmr.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright (c) 2021 OpenStack Foundation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | Guru Meditation Reports 17 | ======================= 18 | 19 | Aodh contains a mechanism whereby developers and system administrators can 20 | generate a report about the state of a running Aodh executable. This report is 21 | called a *Guru Meditation Report* (*GMR* for short). 22 | 23 | Generating a GMR 24 | ---------------- 25 | 26 | A *GMR* can be generated by sending the *USR1* signal to any Aodh process with 27 | support (see below). The *GMR* will then be outputted standard error for that 28 | particular process. 29 | 30 | For example, suppose that ``aodh-listener`` has process id ``8675``, and 31 | was run with ``2>/var/log/aodh/aodh-listener.log``. Then, ``kill -USR1 8675`` 32 | will trigger the Guru Meditation report to be printed to 33 | ``/var/log/aodh/aodh-listener.log``. 34 | 35 | Structure of a GMR 36 | ------------------ 37 | 38 | The *GMR* is designed to be extensible; any particular executable may add its 39 | own sections. However, the base *GMR* consists of several sections: 40 | 41 | Package 42 | Shows information about the package to which this process belongs, including 43 | version information 44 | 45 | Threads 46 | Shows stack traces and thread ids for each of the threads within this process 47 | 48 | Green Threads 49 | Shows stack traces for each of the green threads within this process (green 50 | threads don't have thread ids) 51 | 52 | Configuration 53 | Lists all the configuration options currently accessible via the CONF object 54 | for the current process 55 | 56 | Adding Support for GMRs to New Executables 57 | ------------------------------------------ 58 | 59 | Adding support for a *GMR* to a given executable is fairly easy. 60 | 61 | First import the module (currently residing in oslo-incubator), as well as the 62 | Aodh version module: 63 | 64 | .. code-block:: python 65 | 66 | from oslo_reports import guru_meditation_report as gmr 67 | from aodh import version 68 | 69 | Then, register any additional sections (optional): 70 | 71 | .. code-block:: python 72 | 73 | TextGuruMeditation.register_section('Some Special Section', 74 | some_section_generator) 75 | 76 | Finally (under main), before running the "main loop" of the executable (usually 77 | ``service.server(server)`` or something similar), register the *GMR* hook: 78 | 79 | .. code-block:: python 80 | 81 | TextGuruMeditation.setup_autorun(version) 82 | 83 | Extending the GMR 84 | ----------------- 85 | 86 | As mentioned above, additional sections can be added to the GMR for a 87 | particular executable. For more information, see the inline documentation 88 | about oslo.reports: 89 | `oslo.reports `_ 90 | -------------------------------------------------------------------------------- /doc/source/contributor/index.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2012 Nicolas Barcet for Canonical 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | ================= 17 | Contributor Guide 18 | ================= 19 | 20 | In the Contributions Guide, you will find documented policies for developing 21 | with Aodh. This includes the processes we use for bugs, contributor onboarding, 22 | core reviewer memberships, and other procedural items. 23 | 24 | Overview 25 | ======== 26 | 27 | .. toctree:: 28 | :maxdepth: 2 29 | 30 | architecture 31 | webapi/index 32 | 33 | Developer Documentation 34 | ======================= 35 | 36 | .. toctree:: 37 | :maxdepth: 2 38 | 39 | install/index 40 | testing 41 | contributing 42 | event-alarm 43 | gmr 44 | 45 | Appendix 46 | ======== 47 | 48 | .. toctree:: 49 | :maxdepth: 1 50 | 51 | releasenotes/index 52 | 53 | .. update index 54 | 55 | Indices and tables 56 | ================== 57 | 58 | * :ref:`genindex` 59 | * :ref:`modindex` 60 | * :ref:`search` 61 | -------------------------------------------------------------------------------- /doc/source/contributor/install/development.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2012 Nicolas Barcet for Canonical 3 | 2013 New Dream Network, LLC (DreamHost) 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | not use this file except in compliance with the License. You may obtain 7 | a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | License for the specific language governing permissions and limitations 15 | under the License. 16 | 17 | ============================== 18 | Installing development sandbox 19 | ============================== 20 | 21 | Configuring devstack 22 | ==================== 23 | 24 | .. index:: 25 | double: installing; devstack 26 | 27 | 1. Download devstack_. 28 | 29 | 2. Create a ``local.conf`` file as input to devstack. 30 | 31 | .. note:: 32 | 33 | ``local.conf`` replaces the former configuration file called ``localrc``. 34 | If you used localrc before, remove it to switch to using the new file. 35 | For further information see the `devstack configuration 36 | `_. 37 | 38 | 3. The aodh services are not enabled by default, so they must be 39 | enabled in ``local.conf`` before running ``stack.sh``. 40 | 41 | This example ``local.conf`` file shows all of the settings required for 42 | aodh:: 43 | 44 | [[local|localrc]] 45 | 46 | # Enable the aodh alarming services 47 | enable_plugin aodh https://opendev.org/openstack/aodh master 48 | 49 | .. _devstack: https://docs.openstack.org/devstack/latest/ 50 | -------------------------------------------------------------------------------- /doc/source/contributor/install/index.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2013 New Dream Network, LLC (DreamHost) 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | .. _install: 17 | 18 | =============== 19 | Installing Aodh 20 | =============== 21 | 22 | .. toctree:: 23 | :maxdepth: 2 24 | 25 | development 26 | manual 27 | mod_wsgi 28 | uwsgi 29 | -------------------------------------------------------------------------------- /doc/source/contributor/install/manual.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2012 Nicolas Barcet for Canonical 3 | 2013 New Dream Network, LLC (DreamHost) 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | not use this file except in compliance with the License. You may obtain 7 | a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | License for the specific language governing permissions and limitations 15 | under the License. 16 | 17 | .. _installing_manually: 18 | 19 | =================== 20 | Installing Manually 21 | =================== 22 | 23 | Installing the API Server 24 | ========================= 25 | There are two recommended ways to start api server: 26 | 1. Starting API server through mod_wsgi_; 27 | 2. Starting API server through: uwsgi_. 28 | 29 | Not recommended, for testing purpose, we can also start api server by 30 | aodh-api binary:: 31 | 32 | aodh-api --port 8042 -- --config-file /etc/aodh/aodh.conf 33 | 34 | Database configuration 35 | ====================== 36 | 37 | You can use any SQLAlchemy-supported DB such as `PostgreSQL` or `MySQL`. 38 | To use MySQL as the storage backend, change the 'database' section in 39 | aodh.conf as follows:: 40 | 41 | [database] 42 | connection = mysql+pymysql://username:password@host/aodh?charset=utf8 43 | 44 | .. _mod_wsgi: ../install/mod_wsgi.html 45 | .. _uwsgi: ../install/uwsgi.html 46 | -------------------------------------------------------------------------------- /doc/source/contributor/install/mod_wsgi.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2013 New Dream Network, LLC (DreamHost) 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | ================================== 17 | Installing the API behind mod_wsgi 18 | ================================== 19 | 20 | Aodh comes with a WSGI application file named `aodh/api/app.wsgi` for 21 | configuring the API service to run behind Apache with ``mod_wsgi``. This file 22 | is installed with the rest of the Aodh application code, and should not need to 23 | be modified. 24 | 25 | You can then configure Apache with something like this:: 26 | 27 | Listen 8042 28 | 29 | 30 | WSGIDaemonProcess aodh-api processes=2 threads=10 user=SOMEUSER display-name=%{GROUP} 31 | WSGIProcessGroup aodh-api 32 | WSGIScriptAlias / /usr/lib/python2.7/dist-packages/aodh/api/app 33 | WSGIApplicationGroup %{GLOBAL} 34 | = 2.4> 35 | ErrorLogFormat "%{cu}t %M" 36 | 37 | ErrorLog /var/log/httpd/aodh_error.log 38 | CustomLog /var/log/httpd/aodh_access.log combined 39 | 40 | 41 | WSGISocketPrefix /var/run/httpd 42 | 43 | 44 | Modify the ``WSGIDaemonProcess`` directive to set the ``user`` and ``group`` 45 | values to an appropriate user on your server. In many installations ``aodh`` 46 | will be correct. 47 | -------------------------------------------------------------------------------- /doc/source/contributor/install/uwsgi.rst: -------------------------------------------------------------------------------- 1 | ============================= 2 | Installing the API with uwsgi 3 | ============================= 4 | 5 | Aodh comes with a few example files for configuring the API 6 | service to run behind Apache with ``mod_wsgi``. 7 | 8 | app.wsgi 9 | ======== 10 | 11 | The file ``aodh/api/app.wsgi`` sets up the V2 API WSGI 12 | application. The file is installed with the rest of the Aodh 13 | application code, and should not need to be modified. 14 | 15 | Example of uwsgi configuration file 16 | =================================== 17 | 18 | 19 | Create aodh-uwsgi.ini file:: 20 | 21 | [uwsgi] 22 | http = 0.0.0.0:8041 23 | wsgi-file = /aodh/api/app.wsgi 24 | plugins = python 25 | # This is running standalone 26 | master = true 27 | # Set die-on-term & exit-on-reload so that uwsgi shuts down 28 | exit-on-reload = true 29 | die-on-term = true 30 | # uwsgi recommends this to prevent thundering herd on accept. 31 | thunder-lock = true 32 | # Override the default size for headers from the 4k default. (mainly for keystone token) 33 | buffer-size = 65535 34 | enable-threads = true 35 | # Set the number of threads usually with the returns of command nproc 36 | threads = 8 37 | # Make sure the client doesn't try to re-use the connection. 38 | add-header = Connection: close 39 | # Set uid and gip to an appropriate user on your server. In many 40 | # installations ``aodh`` will be correct. 41 | uid = aodh 42 | gid = aodh 43 | 44 | Then start the uwsgi server:: 45 | 46 | uwsgi ./aodh-uwsgi.ini 47 | 48 | Or start in background with:: 49 | 50 | uwsgi -d ./aodh-uwsgi.ini 51 | 52 | Configuring with uwsgi-plugin-python on Debian/Ubuntu 53 | ===================================================== 54 | 55 | Install the Python plugin for uwsgi: 56 | 57 | apt-get install uwsgi-plugin-python 58 | 59 | Run the server: 60 | 61 | uwsgi_python --master --die-on-term --logto /var/log/aodh/aodh-api.log \ 62 | --http-socket :8042 --wsgi-file /usr/share/aodh-common/app.wsgi 63 | -------------------------------------------------------------------------------- /doc/source/contributor/releasenotes/index.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright (c) 2016 Hewlett Packard Enterprise Development Company, L.P. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | ============= 17 | Release Notes 18 | ============= 19 | 20 | .. toctree:: 21 | :hidden: 22 | 23 | * `Liberty`_ 24 | 25 | Since Mitaka development cycle, we start to host release notes on: 26 | `Aodh Release Notes`_ 27 | 28 | .. _Liberty: https://wiki.openstack.org/wiki/ReleaseNotes/Liberty#OpenStack_Telemetry_.28Ceilometer.29 29 | .. _Aodh Release Notes: https://docs.openstack.org/releasenotes/aodh/ 30 | -------------------------------------------------------------------------------- /doc/source/contributor/testing.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2012 New Dream Network, LLC (DreamHost) 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | not use this file except in compliance with the License. You may obtain 6 | a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | License for the specific language governing permissions and limitations 14 | under the License. 15 | 16 | ================= 17 | Running the Tests 18 | ================= 19 | 20 | Aodh includes an extensive set of automated unit tests which are 21 | run through tox_. 22 | 23 | 1. Install ``tox``:: 24 | 25 | $ sudo pip install tox 26 | 27 | 2. On Ubuntu install ``libmysqlclient-dev`` packages:: 28 | 29 | $ sudo apt-get install libmysqlclient-dev 30 | 31 | For Fedora20 there is no ``libmysqlclient-dev`` package, so you’ll need 32 | to install ``mariadb-devel.x86-64`` (or ``mariadb-devel.i386``) instead:: 33 | 34 | $ sudo yum install mariadb-devel.x86_64 35 | 36 | 3. Run the unit and code-style tests:: 37 | 38 | $ cd /opt/stack/aodh 39 | $ tox -e py27,pep8 40 | 41 | As tox is a wrapper around testr, it also accepts the same flags as testr. 42 | See the `testr documentation`_ for details about these additional flags. 43 | 44 | Use a double hyphen to pass options to testr. For example, to run only tests under tests/functional/api/v2:: 45 | 46 | $ tox -e py27 -- functional.api.v2 47 | 48 | To debug tests (ie. break into pdb debugger), you can use ''debug'' tox 49 | environment. Here's an example, passing the name of a test since you'll 50 | normally only want to run the test that hits your breakpoint:: 51 | 52 | $ tox -e debug aodh.tests.unit.test_bin 53 | 54 | For reference, the ``debug`` tox environment implements the instructions 55 | here: https://wiki.openstack.org/wiki/Testr#Debugging_.28pdb.29_Tests 56 | 57 | .. _testr documentation: https://testrepository.readthedocs.org/en/latest/MANUAL.html 58 | 59 | 4. There is a growing suite of tests which use a tool called `gabbi`_ to 60 | test and validate the behavior of the Aodh API. These tests are run 61 | when using the usual ``functional`` tox target but if desired they can be 62 | run by themselves:: 63 | 64 | $ tox -e gabbi 65 | 66 | The YAML files used to drive the gabbi tests can be found in 67 | ``aodh/tests/functional/gabbi/gabbits``. If you are adding to or adjusting 68 | the API you should consider adding tests here. 69 | 70 | .. _gabbi: https://gabbi.readthedocs.io/en/latest/ 71 | 72 | .. seealso:: 73 | 74 | * tox_ 75 | 76 | .. _tox: https://tox.readthedocs.io/en/latest/ 77 | -------------------------------------------------------------------------------- /doc/source/contributor/webapi/index.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | Web API 3 | ======= 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | v2 9 | 10 | You can get API version list via request to endpoint root path. For example:: 11 | 12 | curl -H "X-AUTH-TOKEN: fa2ec18631f94039a5b9a8b4fe8f56ad" http://127.0.0.1:8042 13 | 14 | Sample response:: 15 | 16 | { 17 | "versions": { 18 | "values": [ 19 | { 20 | "id": "v2", 21 | "links": [ 22 | { 23 | "href": "http://127.0.0.1:8042/v2", 24 | "rel": "self" 25 | }, 26 | { 27 | "href": "https://docs.openstack.org/", 28 | "rel": "describedby", 29 | "type": "text/html" 30 | } 31 | ], 32 | "media-types": [ 33 | { 34 | "base": "application/json", 35 | "type": "application/vnd.openstack.telemetry-v2+json" 36 | }, 37 | { 38 | "base": "application/xml", 39 | "type": "application/vnd.openstack.telemetry-v2+xml" 40 | } 41 | ], 42 | "status": "stable", 43 | "updated": "2013-02-13T00:00:00Z" 44 | } 45 | ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /doc/source/glossary.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2012 New Dream Network (DreamHost) 3 | Copyright 2013 eNovance 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | not use this file except in compliance with the License. You may obtain 7 | a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | License for the specific language governing permissions and limitations 15 | under the License. 16 | 17 | ======== 18 | Glossary 19 | ======== 20 | 21 | .. glossary:: 22 | 23 | alarm 24 | An action triggered whenever a meter reaches a certain threshold. 25 | 26 | API server 27 | HTTP REST API service for Aodh. 28 | 29 | HTTP callback 30 | HTTP callback is used for calling a predefined URL, whenever an 31 | alarm has been set off. The payload of the request contains 32 | all the details of why the alarm was triggered. 33 | 34 | log 35 | Logging is one of the alarm actions that is useful mostly for debugging, 36 | it stores the alarms in a log file. 37 | 38 | zaqar 39 | According to `Zaqar Developer Documentation`_: 40 | 41 | Zaqar is a multi-tenant cloud messaging and notification service for web 42 | and mobile developers. 43 | 44 | project 45 | The OpenStack tenant or project. 46 | 47 | resource 48 | The OpenStack entity being metered (e.g. instance, volume, image, etc). 49 | 50 | user 51 | An OpenStack user. 52 | 53 | .. _Zaqar Developer Documentation: https://docs.openstack.org/zaqar/latest/ 54 | -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2010 OpenStack Foundation 3 | All Rights Reserved. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | not use this file except in compliance with the License. You may obtain 7 | a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | License for the specific language governing permissions and limitations 15 | under the License. 16 | 17 | ================================ 18 | Welcome to Aodh's documentation! 19 | ================================ 20 | 21 | The Alarming service (aodh) project provides a service that enables the ability 22 | to trigger actions based on defined rules against metric or event data 23 | collected by Ceilometer or Gnocchi. 24 | 25 | .. toctree:: 26 | :maxdepth: 2 27 | 28 | install/index 29 | contributor/index 30 | admin/index 31 | configuration/index 32 | cli/index 33 | 34 | .. toctree:: 35 | :maxdepth: 1 36 | 37 | glossary 38 | -------------------------------------------------------------------------------- /doc/source/install/configure-common.rst: -------------------------------------------------------------------------------- 1 | 2. Edit the ``/etc/aodh/aodh.conf`` file and complete the following actions: 2 | 3 | * In the ``[database]`` section, configure database access: 4 | 5 | .. code-block:: ini 6 | 7 | [database] 8 | ... 9 | connection = mysql+pymysql://aodh:AODH_DBPASS@controller/aodh 10 | 11 | Replace ``AODH_DBPASS`` with the password you chose for the 12 | Telemetry Alarming module database. You must escape special characters 13 | such as ``:``, ``/``, ``+``, and ``@`` in the connection string in accordance 14 | with `RFC2396 `_. 15 | 16 | * In the ``[DEFAULT]`` section, 17 | configure ``RabbitMQ`` message queue access: 18 | 19 | .. code-block:: ini 20 | 21 | [DEFAULT] 22 | ... 23 | transport_url = rabbit://openstack:RABBIT_PASS@controller 24 | 25 | Replace ``RABBIT_PASS`` with the password you chose for the 26 | ``openstack`` account in ``RabbitMQ``. 27 | 28 | * In the ``[DEFAULT]`` and ``[keystone_authtoken]`` sections, 29 | configure Identity service access: 30 | 31 | .. code-block:: ini 32 | 33 | [DEFAULT] 34 | ... 35 | auth_strategy = keystone 36 | 37 | [keystone_authtoken] 38 | ... 39 | www_authenticate_uri = http://controller:5000 40 | auth_url = http://controller:5000 41 | memcached_servers = controller:11211 42 | auth_type = password 43 | project_domain_id = default 44 | user_domain_id = default 45 | project_name = service 46 | username = aodh 47 | password = AODH_PASS 48 | 49 | Replace ``AODH_PASS`` with the password you chose for 50 | the ``aodh`` user in the Identity service. 51 | 52 | * In the ``[service_credentials]`` section, configure service credentials: 53 | 54 | .. code-block:: ini 55 | 56 | [service_credentials] 57 | ... 58 | auth_type = password 59 | auth_url = http://controller:5000/v3 60 | project_domain_id = default 61 | user_domain_id = default 62 | project_name = service 63 | username = aodh 64 | password = AODH_PASS 65 | interface = internalURL 66 | region_name = RegionOne 67 | 68 | Replace ``AODH_PASS`` with the password you chose for 69 | the ``aodh`` user in the Identity service. 70 | 71 | 3. In order to initialize the database please run the ``aodh-dbsync`` script. 72 | -------------------------------------------------------------------------------- /doc/source/install/get_started.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Telemetry Alarming service overview 3 | =================================== 4 | 5 | The Telemetry Alarming services trigger alarms when the collected metering 6 | or event data break the defined rules. 7 | 8 | The Telemetry Alarming service consists of the following components: 9 | 10 | An API server (``aodh-api``) 11 | Runs on one or more central management servers to provide access 12 | to the alarm information stored in the data store. 13 | 14 | An alarm evaluator (``aodh-evaluator``) 15 | Runs on one or more central management servers to determine when 16 | alarms fire due to the associated statistic trend crossing a 17 | threshold over a sliding time window. 18 | 19 | A notification listener (``aodh-listener``) 20 | Runs on a central management server and determines when to fire alarms. 21 | The alarms are generated based on defined rules against events, which are 22 | captured by the Telemetry Data Collection service's notification agents. 23 | 24 | An alarm notifier (``aodh-notifier``) 25 | Runs on one or more central management servers to allow alarms to be 26 | set based on the threshold evaluation for a collection of samples. 27 | 28 | These services communicate by using the OpenStack messaging bus. 29 | -------------------------------------------------------------------------------- /doc/source/install/index.rst: -------------------------------------------------------------------------------- 1 | ================== 2 | Installation Guide 3 | ================== 4 | 5 | .. toctree:: 6 | 7 | get_started.rst 8 | install-obs.rst 9 | install-rdo.rst 10 | install-ubuntu.rst 11 | next-steps.rst 12 | .. verify.rst 13 | 14 | This chapter assumes a working setup of OpenStack following the 15 | `OpenStack Installation Tutorials and Guides `_. 16 | -------------------------------------------------------------------------------- /doc/source/install/install-obs.rst: -------------------------------------------------------------------------------- 1 | .. _install-obs: 2 | 3 | Install and configure for openSUSE and SUSE Linux Enterprise 4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 | 6 | This section describes how to install and configure the 7 | Telemetry Alarming service, code-named aodh, on the controller node. 8 | 9 | This section assumes that you already have a working OpenStack 10 | environment with at least the following components installed: 11 | Compute, Image Service, Identity. 12 | 13 | .. include:: prereq-common.rst 14 | 15 | Install and configure components 16 | -------------------------------- 17 | 18 | .. note:: 19 | 20 | Default configuration files vary by distribution. You might need to add 21 | these sections and options rather than modifying existing sections and 22 | options. Also, an ellipsis (...) in the configuration snippets indicates 23 | potential default configuration options that you should retain. 24 | 25 | 1. Install the packages: 26 | 27 | .. code-block:: console 28 | 29 | # zypper install openstack-aodh-api \ 30 | openstack-aodh-evaluator openstack-aodh-notifier \ 31 | openstack-aodh-listener openstack-aodh-expirer \ 32 | python-aodhclient 33 | 34 | .. include:: configure-common.rst 35 | 36 | Finalize installation 37 | --------------------- 38 | 39 | #. Start the Telemetry Alarming services and configure them to start 40 | when the system boots: 41 | 42 | .. code-block:: console 43 | 44 | # systemctl enable openstack-aodh-api.service \ 45 | openstack-aodh-evaluator.service \ 46 | openstack-aodh-notifier.service \ 47 | openstack-aodh-listener.service 48 | # systemctl start openstack-aodh-api.service \ 49 | openstack-aodh-evaluator.service \ 50 | openstack-aodh-notifier.service \ 51 | openstack-aodh-listener.service 52 | -------------------------------------------------------------------------------- /doc/source/install/install-rdo.rst: -------------------------------------------------------------------------------- 1 | .. _install-rdo: 2 | 3 | Install and configure for Red Hat Enterprise Linux and CentOS 4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 | 6 | This section describes how to install and configure the 7 | Telemetry Alarming service, code-named aodh, on the controller node. 8 | 9 | This section assumes that you already have a working OpenStack 10 | environment with at least the following components installed: 11 | Compute, Image Service, Identity. 12 | 13 | .. include:: prereq-common.rst 14 | 15 | Install and configure components 16 | -------------------------------- 17 | 18 | .. note:: 19 | 20 | Default configuration files vary by distribution. You might need to add 21 | these sections and options rather than modifying existing sections and 22 | options. Also, an ellipsis (...) in the configuration snippets indicates 23 | potential default configuration options that you should retain. 24 | 25 | 1. Install the packages: 26 | 27 | .. code-block:: console 28 | 29 | # dnf install openstack-aodh-api \ 30 | openstack-aodh-evaluator openstack-aodh-notifier \ 31 | openstack-aodh-listener openstack-aodh-expirer \ 32 | python3-aodhclient 33 | 34 | .. include:: configure-common.rst 35 | 36 | Finalize installation 37 | --------------------- 38 | 39 | #. Start the Telemetry Alarming services and configure them to start 40 | when the system boots: 41 | 42 | .. code-block:: console 43 | 44 | # systemctl enable openstack-aodh-api.service \ 45 | openstack-aodh-evaluator.service \ 46 | openstack-aodh-notifier.service \ 47 | openstack-aodh-listener.service 48 | # systemctl start openstack-aodh-api.service \ 49 | openstack-aodh-evaluator.service \ 50 | openstack-aodh-notifier.service \ 51 | openstack-aodh-listener.service 52 | -------------------------------------------------------------------------------- /doc/source/install/install-ubuntu.rst: -------------------------------------------------------------------------------- 1 | .. _install-ubuntu: 2 | 3 | Install and configure for Ubuntu 4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 | 6 | This section describes how to install and configure the 7 | Telemetry Alarming service, code-named aodh, on the controller node. 8 | 9 | This section assumes that you already have a working OpenStack 10 | environment with at least the following components installed: 11 | Compute, Image Service, Identity. 12 | 13 | .. include:: prereq-common.rst 14 | 15 | Install and configure components 16 | -------------------------------- 17 | 18 | .. note:: 19 | 20 | Default configuration files vary by distribution. You might need to add 21 | these sections and options rather than modifying existing sections and 22 | options. Also, an ellipsis (...) in the configuration snippets indicates 23 | potential default configuration options that you should retain. 24 | 25 | 1. Install the packages: 26 | 27 | .. code-block:: console 28 | 29 | # apt-get install aodh-api aodh-evaluator aodh-notifier \ 30 | aodh-listener aodh-expirer python-aodhclient 31 | 32 | .. include:: configure-common.rst 33 | 34 | Finalize installation 35 | --------------------- 36 | 37 | #. Restart the Alarming services: 38 | 39 | .. code-block:: console 40 | 41 | # service aodh-api restart 42 | # service aodh-evaluator restart 43 | # service aodh-notifier restart 44 | # service aodh-listener restart 45 | -------------------------------------------------------------------------------- /doc/source/install/next-steps.rst: -------------------------------------------------------------------------------- 1 | .. _next-steps: 2 | 3 | Next steps 4 | ~~~~~~~~~~ 5 | 6 | Your OpenStack environment now includes the aodh service. 7 | 8 | To add additional services, see the 9 | `OpenStack Installation Tutorials and Guides `_ 10 | -------------------------------------------------------------------------------- /doc/source/install/verify.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. _verify: 4 | 5 | Verify operation 6 | ~~~~~~~~~~~~~~~~ 7 | 8 | Verify operation of the Telemetry Alarming service. 9 | 10 | TBD 11 | -------------------------------------------------------------------------------- /rally-jobs/README.rst: -------------------------------------------------------------------------------- 1 | Rally job related files 2 | ======================= 3 | 4 | This directory contains rally tasks and plugins that are run by OpenStack CI. 5 | 6 | Structure 7 | --------- 8 | 9 | * plugins - directory where you can add rally plugins. Almost everything in 10 | Rally is a plugin. Benchmark context, Benchmark scenario, SLA checks, Generic 11 | cleanup resources, .... 12 | 13 | * extra - all files from this directory will be copy pasted to gates, so you 14 | are able to use absolute paths in rally tasks. 15 | Files will be located in ~/.rally/extra/* 16 | 17 | * aodh is a task that is run in gates against aodh 18 | 19 | 20 | Useful links 21 | ------------ 22 | 23 | * More about Rally: https://rally.readthedocs.org/en/latest/ 24 | 25 | * How to add rally-gates: https://rally.readthedocs.io/en/latest/quick_start/gates.html 26 | 27 | * About plugins: https://rally.readthedocs.io/en/latest/plugins/index.html 28 | 29 | * Plugin samples: https://github.com/openstack/rally/tree/master/samples/plugins 30 | -------------------------------------------------------------------------------- /rally-jobs/extra/README.rst: -------------------------------------------------------------------------------- 1 | Extra files 2 | =========== 3 | 4 | All files from this directory will be copy pasted to gates, so you are able to 5 | use absolute path in rally tasks. Files will be in ~/.rally/extra/* 6 | 7 | -------------------------------------------------------------------------------- /rally-jobs/extra/fake.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/rally-jobs/extra/fake.img -------------------------------------------------------------------------------- /rally-jobs/plugins/README.rst: -------------------------------------------------------------------------------- 1 | Rally plugins 2 | ============= 3 | 4 | All *.py modules from this directory will be auto-loaded by Rally and all 5 | plugins will be discoverable. There is no need of any extra configuration 6 | and there is no difference between writing them here and in rally code base. 7 | 8 | Note that it is better to push all interesting and useful benchmarks to Rally 9 | code base, this simplifies administration for Operators. 10 | -------------------------------------------------------------------------------- /rally-jobs/plugins/plugin_sample.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | 13 | """ Sample of plugin for Aodh. 14 | 15 | For more Aodh related benchmarks take a look here: 16 | github.com/openstack/rally/blob/master/rally/benchmark/scenarios/aodh/ 17 | 18 | About plugins: https://rally.readthedocs.io/en/latest/plugins/index.html 19 | 20 | Rally concepts https://wiki.openstack.org/wiki/Rally/Concepts 21 | """ 22 | 23 | from rally.benchmark.scenarios import base 24 | 25 | 26 | class AodhPlugin(base.Scenario): 27 | pass 28 | -------------------------------------------------------------------------------- /releasenotes/notes/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/releasenotes/notes/.placeholder -------------------------------------------------------------------------------- /releasenotes/notes/Add-state-reason-to-the-API-7bc5a9465466db2b.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | The reason of the state change is now part of the API as "state_reason" field of the alarm object. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/add-a-data-migration-tool-daa14b0cb5d4cc62.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - > 4 | Add a tool for migrating alarm and alarm history data from NoSQL storage 5 | to SQL storage. The migration tool has been tested OK in devstack 6 | environment, but users need to be cautious with this, because the data 7 | migration between storage backends is a bit dangerous. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/add-metrics-endpoint-and-evaluation-counter-collection-f324ebda00fa5c6c.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Added collection of alarm evaluation counters. These show the number of 5 | times alarms were evaluated as ``alarm``, ``ok`` and ``insufficient data`` 6 | per alarm. These counters are presented by the /v2/metrics API endpoint. 7 | This feature can be enabled or disabled with 8 | the ``[DEFAULT].enable_evaluation_results_metrics`` configuration option. 9 | It's disabled by default. 10 | -------------------------------------------------------------------------------- /releasenotes/notes/add-upgrade-check-framework-ab35e6eb65504bc3.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | prelude: > 3 | Added new tool ``aodh-status upgrade check``. 4 | features: 5 | - | 6 | New framework for ``aodh-status upgrade check`` command is added. 7 | This framework allows adding various checks which can be run before a 8 | Aodh upgrade to ensure if the upgrade can be performed safely. 9 | upgrade: 10 | - | 11 | Operator can now use new CLI tool ``aodh-status upgrade check`` 12 | to check if Aodh deployment can be safely upgraded from 13 | N-1 to N release. 14 | -------------------------------------------------------------------------------- /releasenotes/notes/auto-healing-notifier-794b64de776811e9.yaml: -------------------------------------------------------------------------------- 1 | features: 2 | - Added a new notifier(``trust+heat``) that works together with 3 | ``loadbalancer_member_health`` evaluator for auto-healing purpose. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/bug-1929178-46493335946174a5.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | The ``[coordination] check_watchers`` parameter has been deprecated since 5 | it has been ineffective. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/bug1540395-reason-string-0aad56966007d0e3.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - > 4 | [`bug 1540395 `_] 5 | Fix reason string to properly handle transitions when one sample is outside 6 | of defined threshold. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/composite-alarm-1b1ca9ea0e8f55c8.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - > 4 | Add a new composite type alarm, which allow users specifying a composite 5 | rule to define an alarm with multiple triggering conditions, using a 6 | combination of *and*, *or* relationships. The composite rule is composed of 7 | multiple threshold rules or gnocchi rules. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/deprecate-combination-alarms-7ff26b73b61a0e59.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - The combination alarms are officially deprecated and disabled by default. 4 | Set api.enable_combination_alarms to True to enable them. 5 | Existing alarms will still be evaluated, but access to them via the API is 6 | linked to whether that configuration option is turned on or off. 7 | It's advised to use composite alarms instead. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/deprecate-json-formatted-policy-file-fgb26387a9bdb3b9.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | The default value of ``[oslo_policy] policy_file`` config option has 5 | been changed from ``policy.json`` to ``policy.yaml``. 6 | Operators who are utilizing customized or previously generated 7 | static policy JSON files (which are not needed by default), should 8 | generate new policy files or convert them in YAML format. Use the 9 | `oslopolicy-convert-json-to-yaml 10 | `_ 11 | tool to convert a JSON to YAML formatted policy file in 12 | backward compatible way. 13 | deprecations: 14 | - | 15 | Use of JSON policy files was deprecated by the ``oslo.policy`` library 16 | during the Victoria development cycle. As a result, this deprecation is 17 | being noted in the Wallaby cycle with an anticipated future removal of support 18 | by ``oslo.policy``. As such operators will need to convert to YAML policy 19 | files. Please see the upgrade notes for details on migration of any 20 | custom policy files. 21 | -------------------------------------------------------------------------------- /releasenotes/notes/deprecate-nosql-backends-13079883eec7e8e5.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - > 4 | Drop support for NoSQL backends in Aodh. SQL is a prefectly sufficient 5 | backend for handling the scope of alarms. To maximise available resources, 6 | NoSQL backends are deprecated so developers do not need to worry about 7 | adding features to multiple backends. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/deprecate-threshold-alarm-d89da351d4f6f50f.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | Ceilometer's API is deprecated in Ocata. Therefore, threshold alarms are 5 | now deprecated as well. Threshold rules will be removed when Ceilometer's 6 | API is also removed. Similar functionality is provided through Gnocchi 7 | alarm rules: ``gnocchi_resources_threshold``, 8 | ``gnocchi_aggregation_by_metrics_threshold``, or 9 | ``gnocchi_aggregation_by_resources_threshold``. 10 | -------------------------------------------------------------------------------- /releasenotes/notes/deprecate-unused-http_timeout-74fd60a4c26afd88.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | The ``[DEFAULT] http_timeout`` parameter has been deprecated. This 5 | parameter has been unused thus has had no effect. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/drop-py-2-7-54a9be4bfb8e9172.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Python 2.7 support has been dropped. Last release of Aodh 5 | to support py2.7 is OpenStack Train. The minimum version of Python now 6 | supported by Aodh is Python 3.6. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/drop-python-3-6-and-3-7-89f2b7300c0166ca.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Python 3.6 & 3.7 support has been dropped. The minimum version of Python now 5 | supported is Python 3.8. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/drop-python-3-8-24f35246e92cf9af.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Python 3.8 support was dropped. The minimum version of Python now supported 5 | is Python 3.9. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/enable-aodh-service-multi-processes-67ed9a0b7fac69aa.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Enable aodh services, including aodh-evaluator, aodh-listener and 4 | aodh-notifier to run in multiple worker mode. 5 | 6 | New options are introduced corresponsively as [evaluator]workers, 7 | [listener]workers and [notifier]workers. They all default to 1. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/event-listener-batch-support-04e6ff159ef34d8c.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - > 4 | Add support for batch processing of messages from queue. This will allow 5 | the aodh-listener to grab multiple event messages per thread to enable more 6 | efficient processing. 7 | upgrade: 8 | - > 9 | batch_size and batch_timeout configuration options are added to [listener] 10 | section of configuration. The batch_size controls the number of messages to 11 | grab before processing. Similarly, the batch_timeout defines the wait time 12 | before processing. 13 | -------------------------------------------------------------------------------- /releasenotes/notes/fix-ceilometerclient-init-8bc7a6742937c3e2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - > 4 | [`bug 1518447 `_] 5 | Fix to ensure ceilometerclient is properly initialised on startup. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/fix-combination-alarms-8097adf08b837a50.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - > 4 | [`bug 1511252 `_] 5 | Fix an issue with combination alarms where it fails to evaluate 6 | all issues in the chain of alarms. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/fix-empty-statistics-3852da99b1c0b297.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - > 4 | [`bug 1539069 `_] 5 | Fix to handle scenario where no valid statistics exist for specified 6 | period. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/fix-gnocchi-aggregation-eval-7c2c1c67bdf2d11c.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - > 4 | [`bug 1513738 `_] 5 | Fix an issue where alarms using Gnocchi aggregations are not being 6 | evaluated. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/fix-prometheus-alarm-rbac-6ee2f0abbd060184.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - > 4 | Deprecate the prometheus_disable_rbac config option. 5 | The observabilityclient rbac feature isn't meant for services and will 6 | always be disabled from now on. 7 | fixes: 8 | - > 9 | [`bug 2106029 `_] 10 | Fix Prometheus type queries misusing observabilityclient rbac feature. 11 | -------------------------------------------------------------------------------- /releasenotes/notes/fix-rbac-50825144e0897d7d.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - > 4 | A new default policy.json is provided to properly handle RBAC control. 5 | Existing policy.json files may not grant the appropriate access. 6 | security: 7 | - > 8 | Patch was added to address inconsistent RBAC policy handling. 9 | Certain rules may not have been given appropriate access. 10 | fixes: 11 | - > 12 | [`bug 1504495 `_] 13 | Patch was added to address inconsistent RBAC policy handling. 14 | Certain rules may not have been given appropriate access. 15 | -------------------------------------------------------------------------------- /releasenotes/notes/fix-ssl-request-8107616b6a85a217.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - > 4 | [`bug 1582131 `_] 5 | Fix an issue with adding CA_BUNDLE certificate parth as value of "verify" 6 | parameter in SSL requests. 7 | 8 | features: 9 | - > 10 | A new option “rest_notifier_ca_bundle_certificate_path” has been added 11 | in the configuration file, set None as default value. If this option is 12 | present and SSL is used for alarm action the certificate path provided 13 | will be used as value of verify parameter in action request. 14 | -------------------------------------------------------------------------------- /releasenotes/notes/get-quotas-policy-b0338f314ec06ae9.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | The new ``telemetry::get_quotas`` policy has been added. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/gmr-3dd0a582af010bd4.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Aodh now supports generation of Guru Meditation Reports using oslo.reports 5 | library. Each service prints a report output when it receives SIGUSR1. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/gnocchi-capability-cache-75d011e77b8ecc72.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | other: 3 | - | 4 | Gnocchi aggregation capabilities are now cached to minimise redundant calls 5 | to Gnocchi when validating aggregation methods. The cache is stored 6 | in-memory for an hour. If additional aggregations are added to Gnocchi, 7 | they will not be proprogated to Aodh's API service for at most an hour or 8 | unless the service is restarted. 9 | -------------------------------------------------------------------------------- /releasenotes/notes/gnocchi-client-a62ca5a0c717807e.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - > 4 | Gnocchi dispatcher now uses client rather than direct http requests 5 | upgrade: 6 | - > 7 | gnocchiclient library is now a requirement if using ceilometer+gnocchi. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/gnocchi-external-resource-owner-3fad253d30746b0d.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | When an unprivileged user want to access to Gnocchi resources created by 5 | Ceilometer, that doesn't work because the filter scope the Gnocchi query to 6 | resource owner to the user. To fix we introduce a new configuration option 7 | "gnocchi_external_project_owner" set by default to "service". The new 8 | filter now allow two kind of Gnocchi resources: 9 | 10 | * owned by the user project 11 | * owned by "gnocchi_external_project_owner" and the original project_id of 12 | the resource is the user project. 13 | -------------------------------------------------------------------------------- /releasenotes/notes/healthcheck-560700b72ae68e18.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - A healthcheck endpoint is provided by default at /healthcheck. It leverages 4 | oslo_middleware healthcheck middleware. It allows to retrieve information 5 | about the health of the API service. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/heartbeat_interval-d46e0f5efbd56264.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | The ``[coordination] heartbeat`` parameter has been renamed to 5 | the ``[coordination] heartbeat_interval``. 6 | The old ``[coordination] heartbeat`` parameter is deprecated and will be 7 | removed in a future release. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/ingestion-lag-2317725887287fbc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Allow to extends the alarm evaluation windows to compensate the 4 | reporting/ingestion lag. 5 | 6 | An new option is introduced additional_ingestion_lag defaulted to 0. 7 | It represents the number of seconds of the window extension. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/keystone-v3-support-ffc0f804dbe9d7e9.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - > 4 | Add support for Keystone v3 authentication 5 | -------------------------------------------------------------------------------- /releasenotes/notes/load-api-paste-ini-from-config-dirs-69480861a9633df4.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Now the ``aodh-api`` service look for the paste config file (a.k.a. 5 | ``api-paste.ini`` from configruation directories like ``/etc/aodh``. 6 | If the file is not found in the configuration directories, it uses 7 | the default file. To use only a specific file, use a full file path for 8 | the ``[api] paste_confing`` parameter 9 | -------------------------------------------------------------------------------- /releasenotes/notes/loadbalancer-evaluator-85732c5e5f6e11e9.yaml: -------------------------------------------------------------------------------- 1 | features: 2 | - Added a new evaluator for the alarms of type 3 | ``loadbalancer_member_health`` which evaluates the alarm by checking the 4 | operating status of the members in a given load balancer pool. -------------------------------------------------------------------------------- /releasenotes/notes/migrate-evaluation_interval-c65ba5cbe5fabb35.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | The ``[DEFAULT] evaluation_interval`` parameter has been migrated to 5 | the ``[evaluator]`` section. The old parameter is still kept for backword 6 | compatibility but will be removed in a future release. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/mysql-precise-datetime-e374c77e6707985e.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | other: 3 | - Aodh now leverages microseconds timestamps available since MySQL 5.6.4, 4 | meaning it is now the minimum required version of MySQL. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/notifier-batch-listener-01796e2cb06344dd.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - > 4 | Add support for batch processing of messages from queue. This will allow 5 | the aodh-notifier to grab multiple messages per thread to enable more 6 | efficient processing. 7 | upgrade: 8 | - > 9 | batch_size and batch_timeout configuration options are added to [notifier] 10 | section of configuration. The batch_size controls the number of messages to 11 | grab before processing. Similarly, the batch_timeout defines the wait time 12 | before processing. 13 | -------------------------------------------------------------------------------- /releasenotes/notes/partition-coordinator-improvement-ff1c257f69f120ac.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - > 4 | [`bug 1575530 `_] 5 | Patch was added to fix and improve the partition coordinator, make sure 6 | the input tasks can be correctly distributed to partition members. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/pecan-debug-removed-7c7a528a1aea98bf.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - The api.pecan_debug option has been removed. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/policy-defaults-refresh-95b565bee059f611.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Aodh policies have been modified to isolate the system and project level 5 | APIs policy. Because of this change, system users will not be allowed to 6 | perform any operations on project level resources. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/policy-in-code-79edd9282f1e4603.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Aodh now support policy in code, which means if users didn't modify 5 | any of policy rules, they can leave policy file (in `json` or `yaml` 6 | format) empty or not deploy it at all. Because from now, Aodh keeps 7 | all default policies under `aodh/api/policies` module. 8 | Users can still modify/generate `policy.yaml` file which will override 9 | policy rules in code if those rules show in `policy.yaml` file. 10 | other: 11 | - | 12 | Default `policy.json` file is now removed as Aodh now generate the 13 | default policies from code. Please be aware that when using that file in 14 | your environment. 15 | -------------------------------------------------------------------------------- /releasenotes/notes/queue-communication-1b884feab4078dde.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - > 4 | Support for queue based communication between alarm evaluator service and 5 | alarm notifier services was added. Original implementation involved using 6 | RPC but there is significant overhead involved with using RPC. Work queues 7 | provided required functionality with better performance. 8 | upgrade: 9 | - > 10 | Queue based communication is the new default IPC protocol. RPC can still 11 | be used by choosing rpc as ipc_protocol option. Only one protocol can be 12 | run at any given time. 13 | deprecations: 14 | - > 15 | Because queues provide the equivalent functionality. RPC support is 16 | deprecated and will be removed after Mitaka. 17 | -------------------------------------------------------------------------------- /releasenotes/notes/remove-alarm-name-unique-constraint-4fb0b14f3ad46f0b.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | other: 3 | - Alarm name unique constraint for each project has been removed. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/remove-check_watchers-df14cecc258a3510.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | The ``[coordination] check_watchers`` parameter has been removed. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/remove-combination-alarms-a1a53655f3f7d1d1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - The deprecated combination alarms support have been removed. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/remove-eventlet-18ada1cff213af5e.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - > 4 | Remove eventlet from Aodh in favour of threaded approach 5 | -------------------------------------------------------------------------------- /releasenotes/notes/remove-no-sql-drivers-21dfdbd750751340.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - All the deprecated non-SQL drivers have been removed. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/remove-threshold-alarm-a7901991d2da09f2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | The deprecated 'threshold' alarm type has been removed. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/support-batch-delete-events-32496f15b1169887.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | A new ``alarm_histories_delete_bacth_size`` option has been added to limit 5 | a number of alarm histories deleted from the database by aodh-expirer in 6 | a single iteration. This parameter is useful when there are a lot of alarm 7 | histories in the database. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/support-combination-to-composite-conversion-3e688a6b7d01a57e.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - > 4 | Add a tool for converting combination alarms to composite alarms, 5 | since we have deprecated the combination alarm support and recommend 6 | to use composite alarm to perform multiple conditions alarming. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/ussuri-support-builtin-active-active-aodh-evaluator-a935577e17a211ea.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | The admin user can fetch alarms of all the projects, e.g. 5 | ``curl -X GET "${aodh_prefix}/v2/alarms?q.field=all_projects&q.op=eq&q.value=true" X-Auth-Token:$token`` 6 | -------------------------------------------------------------------------------- /releasenotes/notes/ussuri-support-query-all-projects-alarms-by-admin-3ecccf2217d711ea.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Support to deploy aodh-evaluator in active/active mode by leveraging 4 | database non-locking mechanism. With this feature, there could be multiple 5 | aodh-evaluator processes running without dependency of etcd or zookeeper. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/ussuri-support-quota-api-92f2fd0643d311ea.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Aodh Quota API is aiming for multi-tenancy support. By default, only the 4 | admin user is able to change or delete the resource quota for projects as 5 | defined by the default policy rule 'telemetry:update_quotas' and 6 | 'telemetry:delete_quotas'. User alarm quota and alarm action quota are not 7 | supported in Quota API. -------------------------------------------------------------------------------- /releasenotes/source/2023.1.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2023.1 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/2023.1 7 | -------------------------------------------------------------------------------- /releasenotes/source/2023.2.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2023.2 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/2023.2 7 | -------------------------------------------------------------------------------- /releasenotes/source/2024.1.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2024.1 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/2024.1 7 | -------------------------------------------------------------------------------- /releasenotes/source/2024.2.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2024.2 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/2024.2 7 | -------------------------------------------------------------------------------- /releasenotes/source/2025.1.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2025.1 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/2025.1 7 | -------------------------------------------------------------------------------- /releasenotes/source/_static/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/aodh/2d57b2312ce6f7c0daeb08e3a14730f8bf5d23cd/releasenotes/source/_static/.placeholder -------------------------------------------------------------------------------- /releasenotes/source/index.rst: -------------------------------------------------------------------------------- 1 | ==================== 2 | Aodh Release Notes 3 | ==================== 4 | 5 | .. toctree:: 6 | :maxdepth: 1 7 | 8 | unreleased 9 | 2025.1 10 | 2024.2 11 | 2024.1 12 | 2023.2 13 | 2023.1 14 | zed 15 | yoga 16 | xena 17 | wallaby 18 | victoria 19 | ussuri 20 | train 21 | stein 22 | rocky 23 | queens 24 | pike 25 | ocata 26 | newton 27 | mitaka 28 | liberty 29 | -------------------------------------------------------------------------------- /releasenotes/source/liberty.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | Liberty Series Release Notes 3 | ============================== 4 | 5 | .. release-notes:: 6 | :branch: origin/stable/liberty 7 | -------------------------------------------------------------------------------- /releasenotes/source/locale/fr/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # Gérald LONLAS , 2016. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: Aodh Release Notes 5.0.1\n" 5 | "Report-Msgid-Bugs-To: \n" 6 | "POT-Creation-Date: 2017-10-15 20:27+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2016-10-22 05:18+0000\n" 11 | "Last-Translator: Gérald LONLAS \n" 12 | "Language-Team: French\n" 13 | "Language: fr\n" 14 | "X-Generator: Zanata 3.9.6\n" 15 | "Plural-Forms: nplurals=2; plural=(n > 1)\n" 16 | 17 | msgid "1.1.1" 18 | msgstr "1.1.1" 19 | 20 | msgid "1.1.3" 21 | msgstr "1.1.3" 22 | 23 | msgid "2.0.0" 24 | msgstr "2.0.0" 25 | 26 | msgid "2.0.1" 27 | msgstr "2.0.1" 28 | 29 | msgid "2.0.2" 30 | msgstr "2.0.2" 31 | 32 | msgid "3.0.0" 33 | msgstr "3.0.0" 34 | 35 | msgid "Aodh Release Notes" 36 | msgstr "Note de release de Aodh" 37 | 38 | msgid "Bug Fixes" 39 | msgstr "Corrections de bugs" 40 | 41 | msgid "Current Series Release Notes" 42 | msgstr "Note de la release actuelle" 43 | 44 | msgid "Deprecation Notes" 45 | msgstr "Notes dépréciées " 46 | 47 | msgid "Liberty Series Release Notes" 48 | msgstr "Note de release pour Liberty" 49 | 50 | msgid "Mitaka Series Release Notes" 51 | msgstr "Note de release pour Mitaka" 52 | 53 | msgid "New Features" 54 | msgstr "Nouvelles fonctionnalités" 55 | 56 | msgid "Newton Series Release Notes" 57 | msgstr "Note de release pour Newton" 58 | 59 | msgid "Other Notes" 60 | msgstr "Autres notes" 61 | 62 | msgid "Security Issues" 63 | msgstr "Problèmes de sécurités" 64 | 65 | msgid "Upgrade Notes" 66 | msgstr "Notes de mises à jours" 67 | -------------------------------------------------------------------------------- /releasenotes/source/locale/ko_KR/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # Ian Y. Choi , 2016. #zanata 2 | # SEOKJAE BARK , 2017. #zanata 3 | # Sungjin Kang , 2017. #zanata 4 | msgid "" 5 | msgstr "" 6 | "Project-Id-Version: Aodh Release Notes\n" 7 | "Report-Msgid-Bugs-To: \n" 8 | "POT-Creation-Date: 2018-02-28 14:53+0000\n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "PO-Revision-Date: 2017-07-06 01:12+0000\n" 13 | "Last-Translator: SEOKJAE BARK \n" 14 | "Language-Team: Korean (South Korea)\n" 15 | "Language: ko_KR\n" 16 | "X-Generator: Zanata 4.3.3\n" 17 | "Plural-Forms: nplurals=1; plural=0\n" 18 | 19 | msgid "1.1.1" 20 | msgstr "1.1.1" 21 | 22 | msgid "1.1.3" 23 | msgstr "1.1.3" 24 | 25 | msgid "2.0.0" 26 | msgstr "2.0.0" 27 | 28 | msgid "2.0.1" 29 | msgstr "2.0.1" 30 | 31 | msgid "2.0.2" 32 | msgstr "2.0.2" 33 | 34 | msgid "3.0.0" 35 | msgstr "3.0.0" 36 | 37 | msgid "4.0.0" 38 | msgstr "4.0.0" 39 | 40 | msgid "" 41 | "A healthcheck endpoint is provided by default at /healthcheck. It leverages " 42 | "oslo_middleware healthcheck middleware. It allows to retrieve information " 43 | "about the health of the API service." 44 | msgstr "" 45 | "기본으로 /healthcheck 로 상태 체크 endpoint를 제공합니다. oslo_midlleware " 46 | "healthcheck 미들웨어를 활용하여 API 서비스 상태에 대한 정보를 검색할 수 있습" 47 | "니다." 48 | 49 | msgid "Aodh Release Notes" 50 | msgstr "Aodh 릴리즈 노트" 51 | 52 | msgid "Bug Fixes" 53 | msgstr "버그 수정" 54 | 55 | msgid "Current Series Release Notes" 56 | msgstr "현재 시리즈에 대한 릴리즈 노트" 57 | 58 | msgid "Deprecation Notes" 59 | msgstr "사용하지 않는 기능" 60 | 61 | msgid "Liberty Series Release Notes" 62 | msgstr "Liberty 시리즈에 대한 릴리즈 노트" 63 | 64 | msgid "Mitaka Series Release Notes" 65 | msgstr "Mitaka 시리즈에 대한 릴리즈 노트" 66 | 67 | msgid "New Features" 68 | msgstr "새로운 기능" 69 | 70 | msgid "Newton Series Release Notes" 71 | msgstr "Newton 시리즈 릴리즈 노트" 72 | 73 | msgid "Ocata Series Release Notes" 74 | msgstr "Ocata 시리즈 릴리즈 노트" 75 | 76 | msgid "Other Notes" 77 | msgstr "기타 기능" 78 | 79 | msgid "Security Issues" 80 | msgstr "보안 이슈" 81 | 82 | msgid "Upgrade Notes" 83 | msgstr "업그레이드 노트" 84 | 85 | msgid "gnocchiclient library is now a requirement if using ceilometer+gnocchi." 86 | msgstr "" 87 | "ceilometer+gnocchi 를 사용할 경우, gnocchiclient 라이브러리가 필요합니다." 88 | -------------------------------------------------------------------------------- /releasenotes/source/locale/pt_BR/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # Rodrigo Loures , 2018. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: Aodh Release Notes\n" 5 | "Report-Msgid-Bugs-To: \n" 6 | "POT-Creation-Date: 2018-02-28 14:53+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2018-01-23 04:15+0000\n" 11 | "Last-Translator: Rodrigo Loures \n" 12 | "Language-Team: Portuguese (Brazil)\n" 13 | "Language: pt_BR\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=2; plural=(n != 1)\n" 16 | 17 | msgid "1.1.1" 18 | msgstr "1.1.1" 19 | 20 | msgid "1.1.3" 21 | msgstr "1.1.3" 22 | 23 | msgid "2.0.0" 24 | msgstr "2.0.0" 25 | 26 | msgid "2.0.1" 27 | msgstr "2.0.1" 28 | 29 | msgid "2.0.2" 30 | msgstr "2.0.2" 31 | 32 | msgid "3.0.0" 33 | msgstr "3.0.0" 34 | 35 | msgid "3.0.3" 36 | msgstr "3.0.3" 37 | 38 | msgid "4.0.0" 39 | msgstr "4.0.0" 40 | 41 | msgid "4.0.1" 42 | msgstr "4.0.1" 43 | 44 | msgid "5.0.0" 45 | msgstr "5.0.0" 46 | 47 | msgid "Add support for Keystone v3 authentication" 48 | msgstr "Adicionado o suporte para autenticação Keystone v3" 49 | 50 | msgid "All the deprecated non-SQL drivers have been removed." 51 | msgstr "Todos os drivers non-SQL obsoletos foram removidos." 52 | 53 | msgid "Aodh Release Notes" 54 | msgstr "Aodh - Notas de Versão" 55 | 56 | msgid "Bug Fixes" 57 | msgstr "Correção de erros" 58 | 59 | msgid "Current Series Release Notes" 60 | msgstr "Atual - Séries de Notas de Versão" 61 | 62 | msgid "Deprecation Notes" 63 | msgstr "Notas de obsolência" 64 | 65 | msgid "Liberty Series Release Notes" 66 | msgstr "Liberty - Série de Notas de Versão" 67 | 68 | msgid "Mitaka Series Release Notes" 69 | msgstr "Mitaka - Série de Notas de Versão" 70 | 71 | msgid "New Features" 72 | msgstr "Novos recursos" 73 | 74 | msgid "Newton Series Release Notes" 75 | msgstr "Newton - Série de Notas de Versão" 76 | 77 | msgid "Ocata Series Release Notes" 78 | msgstr "Ocata - Série de Notas de Versão" 79 | 80 | msgid "Other Notes" 81 | msgstr "Outras notas" 82 | 83 | msgid "Pike Series Release Notes" 84 | msgstr "Pike - Série de Notas de Versão" 85 | 86 | msgid "Security Issues" 87 | msgstr "Problemas de segurança" 88 | 89 | msgid "Start using reno to manage release notes." 90 | msgstr "Comece a usar o reno para gerenciar notas de versão." 91 | 92 | msgid "The api.pecan_debug option has been removed." 93 | msgstr "A opção api.pecan_debug foi removida." 94 | 95 | msgid "The deprecated 'threshold' alarm type has been removed." 96 | msgstr "O tipo de alarme 'threshold' obsoleto foi removido." 97 | 98 | msgid "The deprecated combination alarms support have been removed." 99 | msgstr "O suporte a alarmes de combinação obsoleto foi removido." 100 | 101 | msgid "" 102 | "The reason of the state change is now part of the API as \"state_reason\" " 103 | "field of the alarm object." 104 | msgstr "" 105 | "O motivo de mudança de estado agora é parte da API com a coluna " 106 | "\"state_reason\" do objeto de alarme." 107 | 108 | msgid "Upgrade Notes" 109 | msgstr "Notas de atualização" 110 | -------------------------------------------------------------------------------- /releasenotes/source/mitaka.rst: -------------------------------------------------------------------------------- 1 | ============================= 2 | Mitaka Series Release Notes 3 | ============================= 4 | 5 | .. release-notes:: 6 | :branch: origin/stable/mitaka 7 | -------------------------------------------------------------------------------- /releasenotes/source/ocata.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | Ocata Series Release Notes 3 | ============================ 4 | 5 | .. release-notes:: 6 | :branch: origin/stable/ocata 7 | -------------------------------------------------------------------------------- /releasenotes/source/pike.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Pike Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: stable/pike 7 | -------------------------------------------------------------------------------- /releasenotes/source/queens.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Queens Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: stable/queens 7 | -------------------------------------------------------------------------------- /releasenotes/source/rocky.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Rocky Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: stable/rocky 7 | -------------------------------------------------------------------------------- /releasenotes/source/stein.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Stein Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: stable/stein 7 | -------------------------------------------------------------------------------- /releasenotes/source/train.rst: -------------------------------------------------------------------------------- 1 | ========================== 2 | Train Series Release Notes 3 | ========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/train 7 | -------------------------------------------------------------------------------- /releasenotes/source/unreleased.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | Current Series Release Notes 3 | ============================== 4 | 5 | .. release-notes:: 6 | -------------------------------------------------------------------------------- /releasenotes/source/ussuri.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | Ussuri Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/ussuri 7 | -------------------------------------------------------------------------------- /releasenotes/source/victoria.rst: -------------------------------------------------------------------------------- 1 | ============================= 2 | Victoria Series Release Notes 3 | ============================= 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/victoria 7 | -------------------------------------------------------------------------------- /releasenotes/source/wallaby.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | Wallaby Series Release Notes 3 | ============================ 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/wallaby 7 | -------------------------------------------------------------------------------- /releasenotes/source/xena.rst: -------------------------------------------------------------------------------- 1 | ========================= 2 | Xena Series Release Notes 3 | ========================= 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/xena 7 | -------------------------------------------------------------------------------- /releasenotes/source/yoga.rst: -------------------------------------------------------------------------------- 1 | ========================= 2 | Yoga Series Release Notes 3 | ========================= 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/yoga 7 | -------------------------------------------------------------------------------- /releasenotes/source/zed.rst: -------------------------------------------------------------------------------- 1 | ======================== 2 | Zed Series Release Notes 3 | ======================== 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/zed 7 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Requirements lower bounds listed here are our best effort to keep them up to 2 | # date but we do not test them so no guarantee of having them all correct. If 3 | # you find any incorrect lower bounds, let us know or propose a fix. 4 | 5 | tenacity>=3.2.1 # Apache-2.0 6 | croniter>=0.3.4 # MIT License 7 | futurist>=0.11.0 # Apache-2.0 8 | jsonschema>=3.2.0 # MIT 9 | keystonemiddleware>=5.1.0 # Apache-2.0 10 | gnocchiclient>=6.0.0 # Apache-2.0 11 | lxml>=2.3 # BSD 12 | oslo.db>=11.0.0 # Apache-2.0 13 | oslo.config>=6.8.0 # Apache-2.0 14 | oslo.i18n>=1.5.0 # Apache-2.0 15 | oslo.log>=4.3.0 # Apache-2.0 16 | oslo.reports>=1.18.0 # Apache-2.0 17 | oslo.policy>=4.5.0 # Apache-2.0 18 | oslo.upgradecheck>=1.3.0 # Apache-2.0 19 | PasteDeploy>=1.5.0 # MIT 20 | pbr>=2.0.0 # Apache-2.0 21 | pecan>=0.8.0 # BSD 22 | oslo.messaging>=5.2.0 # Apache-2.0 23 | oslo.middleware>=3.22.0 # Apache-2.0 24 | oslo.utils>=4.7.0 # Apache-2.0 25 | python-keystoneclient>=1.6.0 # Apache-2.0 26 | requests>=2.5.2 # Apache-2.0 27 | stevedore>=1.5.0 # Apache-2.0 28 | SQLAlchemy>=1.4.1 # MIT 29 | tooz>=1.28.0 # Apache-2.0 30 | voluptuous>=0.8.10 # BSD 31 | WebOb>=1.2.3 # MIT 32 | WSME>=0.12.1 # MIT 33 | cachetools>=1.1.6 # MIT 34 | cotyledon>=1.7.3 # Apache-2.0 35 | keystoneauth1>=2.1 # Apache-2.0 36 | python-observabilityclient>=0.0.4 # Apache-2.0 37 | python-octaviaclient>=1.8.0 # Apache-2.0 38 | python-dateutil>=2.5.3 # BSD 39 | python-heatclient>=1.17.0 # Apache-2.0 40 | tzdata>=2022.4 # MIT 41 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013 Hewlett-Packard Development Company, L.P. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import setuptools 17 | 18 | setuptools.setup( 19 | setup_requires=['pbr'], 20 | pbr=True) 21 | -------------------------------------------------------------------------------- /test-requirements.txt: -------------------------------------------------------------------------------- 1 | stestr>=2.0.0 # Apache-2.0 2 | oslotest>=2.15.0 # Apache-2.0 3 | coverage>=3.6 # Apache-2.0 4 | fixtures>=1.3.1 # Apache-2.0/BSD 5 | SQLAlchemy-Utils>=0.39.0 6 | # Provides subunit-trace 7 | WebTest>=3.0.0 # MIT 8 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | minversion = 4.2.5 3 | envlist = py3,pep8 4 | 5 | [testenv] 6 | usedevelop = False 7 | setenv = 8 | OS_STDOUT_CAPTURE=1 9 | OS_STDERR_CAPTURE=1 10 | OS_TEST_TIMEOUT=600 11 | 12 | deps = 13 | -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} 14 | -r{toxinidir}/test-requirements.txt 15 | -r{toxinidir}/requirements.txt 16 | passenv = 17 | OS_TEST_TIMEOUT 18 | OS_STDOUT_CAPTURE 19 | OS_STDERR_CAPTURE 20 | OS_LOG_CAPTURE 21 | commands = 22 | stestr --test-path=./aodh/tests run {posargs} 23 | aodh-config-generator 24 | allowlist_externals = 25 | bash 26 | stestr 27 | 28 | [testenv:cover] 29 | setenv = 30 | {[testenv]setenv} 31 | PYTHON=coverage run --source aodh --parallel-mode 32 | commands = 33 | coverage erase 34 | stestr --test-path=./aodh/tests run {posargs} 35 | coverage combine 36 | coverage html -d cover 37 | coverage xml -o cover/coverage.xml 38 | coverage report 39 | 40 | [testenv:pep8] 41 | deps = hacking>=6.1.0,<6.2.0 42 | commands = 43 | flake8 44 | 45 | [testenv:releasenotes] 46 | deps = {[testenv:docs]deps} 47 | commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html 48 | 49 | [testenv:docs] 50 | usedevelop = True 51 | deps = 52 | -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} 53 | -r{toxinidir}/requirements.txt 54 | -r{toxinidir}/doc/requirements.txt 55 | allowlist_externals = 56 | rm 57 | commands = 58 | rm -rf doc/build/html 59 | sphinx-build -W --keep-going -b html doc/source doc/build/html 60 | setenv = PYTHONHASHSEED=0 61 | 62 | [testenv:pdf-docs] 63 | usedevelop = {[testenv:docs]usedevelop} 64 | deps = {[testenv:docs]deps} 65 | allowlist_externals = 66 | make 67 | rm 68 | commands = 69 | rm -rf doc/build/pdf 70 | sphinx-build -W --keep-going -b latex doc/source doc/build/pdf 71 | make -C doc/build/pdf 72 | 73 | [testenv:venv] 74 | commands = {posargs} 75 | setenv = PYTHONHASHSEED=0 76 | 77 | [testenv:debug] 78 | commands = bash -x oslo_debug_helper {posargs} 79 | 80 | [flake8] 81 | # W503 line break before binary operator 82 | # W504 line break after binary operator 83 | # E402 module level import not at top of file 84 | ignore = W503,W504,E402 85 | exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build 86 | # [H106] Do not put vim configuration in source files. 87 | # [H203] Use assertIs(Not)None to check for None. 88 | # [H204] Use assert(Not)Equal to check for equality. 89 | # [H205] Use assert(Greater|Less)(Equal) for comparison. 90 | enable-extensions=H106,H203,H204,H205 91 | show-source = True 92 | 93 | [hacking] 94 | import_exceptions = 95 | aodh.i18n 96 | --------------------------------------------------------------------------------