├── .coveragerc ├── .gitignore ├── .gitreview ├── .mailmap ├── .pre-commit-config.yaml ├── .stestr.conf ├── .zuul.yaml ├── CONTRIBUTING.rst ├── HACKING.rst ├── LICENSE ├── README.rst ├── api-ref └── source │ ├── conf.py │ ├── index.rst │ ├── parameters.yaml │ ├── samples │ ├── actionplan-cancel-request-cancelling.json │ ├── actionplan-cancel-request-pending.json │ ├── actionplan-list-detailed-response.json │ ├── actionplan-list-response.json │ ├── actionplan-show-response.json │ ├── actionplan-start-response.json │ ├── actions-list-detailed-response.json │ ├── actions-list-response.json │ ├── actions-show-response.json │ ├── api-root-response.json │ ├── api-v1-root-response.json │ ├── audit-cancel-request.json │ ├── audit-cancel-response.json │ ├── audit-create-request-continuous.json │ ├── audit-create-request-oneshot.json │ ├── audit-create-response.json │ ├── audit-list-detailed-response.json │ ├── audit-list-response.json │ ├── audit-show-response.json │ ├── audit-update-request.json │ ├── audit-update-response.json │ ├── audittemplate-create-request-full.json │ ├── audittemplate-create-request-minimal.json │ ├── audittemplate-create-response.json │ ├── audittemplate-list-detailed-response.json │ ├── audittemplate-list-response.json │ ├── audittemplate-show-response.json │ ├── audittemplate-update-request.json │ ├── audittemplate-update-response.json │ ├── datamodel-list-response.json │ ├── goal-list-response.json │ ├── goal-show-response.json │ ├── scoring_engine-list-detailed-response.json │ ├── scoring_engine-list-response.json │ ├── scoring_engine-show-response.json │ ├── service-list-detailed-response.json │ ├── service-list-response.json │ ├── service-show-response.json │ ├── strategy-list-detailed-response.json │ ├── strategy-list-response.json │ ├── strategy-show-response.json │ └── strategy-state-response.json │ ├── watcher-api-v1-actionplans.inc │ ├── watcher-api-v1-actions.inc │ ├── watcher-api-v1-audits.inc │ ├── watcher-api-v1-audittemplates.inc │ ├── watcher-api-v1-datamodel.inc │ ├── watcher-api-v1-goals.inc │ ├── watcher-api-v1-scoring_engines.inc │ ├── watcher-api-v1-services.inc │ ├── watcher-api-v1-strategies.inc │ ├── watcher-api-v1-webhooks.inc │ └── watcher-api-versions.inc ├── bindep.txt ├── devstack ├── files │ └── apache-watcher-api.template ├── lib │ └── watcher ├── local.conf.compute ├── local.conf.controller ├── local_gnocchi.conf.compute ├── local_gnocchi.conf.controller ├── override-defaults ├── plugin.sh ├── prometheus.yml ├── settings └── upgrade │ ├── from_rocky │ └── upgrade-watcher │ ├── resources.sh │ ├── settings │ ├── shutdown.sh │ └── upgrade.sh ├── doc ├── dictionary.txt ├── ext │ ├── __init__.py │ ├── term.py │ └── versioned_notifications.py ├── notification_samples │ ├── action-cancel-end.json │ ├── action-cancel-error.json │ ├── action-cancel-start.json │ ├── action-create.json │ ├── action-delete.json │ ├── action-execution-end.json │ ├── action-execution-error.json │ ├── action-execution-start.json │ ├── action-update.json │ ├── action_plan-cancel-end.json │ ├── action_plan-cancel-error.json │ ├── action_plan-cancel-start.json │ ├── action_plan-create.json │ ├── action_plan-delete.json │ ├── action_plan-execution-end.json │ ├── action_plan-execution-error.json │ ├── action_plan-execution-start.json │ ├── action_plan-update.json │ ├── audit-create.json │ ├── audit-delete.json │ ├── audit-planner-end.json │ ├── audit-planner-error.json │ ├── audit-planner-start.json │ ├── audit-strategy-end.json │ ├── audit-strategy-error.json │ ├── audit-strategy-start.json │ ├── audit-update.json │ ├── infra-optim-exception.json │ └── service-update.json ├── requirements.txt └── source │ ├── _static │ └── .placeholder │ ├── admin │ ├── apache-mod-wsgi.rst │ ├── gmr.rst │ ├── index.rst │ └── policy.rst │ ├── architecture.rst │ ├── conf.py │ ├── configuration │ ├── configuring.rst │ ├── index.rst │ └── watcher.rst │ ├── contributor │ ├── api_microversion_history.rst │ ├── concurrency.rst │ ├── contributing.rst │ ├── devstack.rst │ ├── environment.rst │ ├── index.rst │ ├── notifications.rst │ ├── plugin │ │ ├── action-plugin.rst │ │ ├── base-setup.rst │ │ ├── cdmc-plugin.rst │ │ ├── goal-plugin.rst │ │ ├── index.rst │ │ ├── planner-plugin.rst │ │ ├── plugins.rst │ │ ├── scoring-engine-plugin.rst │ │ └── strategy-plugin.rst │ ├── rally_link.rst │ └── testing.rst │ ├── datasources │ ├── grafana.rst │ ├── index.rst │ └── prometheus.rst │ ├── glossary.rst │ ├── image_src │ ├── dia │ │ ├── architecture.dia │ │ └── functional_data_model.dia │ └── plantuml │ │ ├── README.rst │ │ ├── action_plan_state_machine.txt │ │ ├── audit_state_machine.txt │ │ ├── sequence_architecture_cdmc_sync.txt │ │ ├── sequence_create_and_launch_audit.txt │ │ ├── sequence_create_audit_template.txt │ │ ├── sequence_from_audit_execution_to_actionplan_creation.txt │ │ ├── sequence_launch_action_plan.txt │ │ ├── sequence_launch_action_plan_in_applier.txt │ │ ├── sequence_overview_watcher_usage.txt │ │ ├── sequence_trigger_audit_in_decision_engine.txt │ │ └── watcher_db_schema_diagram.txt │ ├── images │ ├── action_plan_state_machine.png │ ├── architecture.svg │ ├── audit_state_machine.png │ ├── functional_data_model.svg │ ├── sequence_architecture_cdmc_sync.png │ ├── sequence_create_and_launch_audit.png │ ├── sequence_create_audit_template.png │ ├── sequence_from_audit_execution_to_actionplan_creation.png │ ├── sequence_launch_action_plan.png │ ├── sequence_launch_action_plan_in_applier.png │ ├── sequence_overview_watcher_usage.png │ ├── sequence_trigger_audit_in_decision_engine.png │ └── watcher_db_schema_diagram.png │ ├── index.rst │ ├── install │ ├── common_configure.rst │ ├── common_prerequisites.rst │ ├── get_started.rst │ ├── index.rst │ ├── install-rdo.rst │ ├── install-ubuntu.rst │ ├── install.rst │ ├── next-steps.rst │ └── verify.rst │ ├── man │ ├── footer.rst │ ├── general-options.rst │ ├── index.rst │ ├── watcher-api.rst │ ├── watcher-applier.rst │ ├── watcher-db-manage.rst │ ├── watcher-decision-engine.rst │ └── watcher-status.rst │ ├── strategies │ ├── actuation.rst │ ├── basic-server-consolidation.rst │ ├── host_maintenance.rst │ ├── index.rst │ ├── node_resource_consolidation.rst │ ├── noisy_neighbor.rst │ ├── outlet_temp_control.rst │ ├── saving_energy.rst │ ├── storage_capacity_balance.rst │ ├── strategy-template.rst │ ├── uniform_airflow.rst │ ├── vm_workload_consolidation.rst │ ├── workload-stabilization.rst │ ├── workload_balance.rst │ └── zone_migration.rst │ └── user │ ├── event_type_audit.rst │ ├── index.rst │ ├── user-guide.rst │ └── ways-to-install.rst ├── etc ├── apache2 │ └── watcher └── watcher │ ├── README-watcher.conf.txt │ ├── oslo-config-generator │ └── watcher.conf │ └── oslo-policy-generator │ └── watcher-policy-generator.conf ├── playbooks ├── generate_prometheus_config.yml └── templates │ └── prometheus.yml.j2 ├── pyproject.toml ├── rally-jobs ├── README.rst └── watcher-watcher.yaml ├── releasenotes ├── notes │ ├── .placeholder │ ├── 2025.1-prelude-8be97eece4e1d1ff.yaml │ ├── action-plan-cancel-c54726378019e096.yaml │ ├── action-plan-versioned-notifications-api-e8ca4f5d37aa5b4b.yaml │ ├── action-versioned-notifications-api-ff94fc0f401292d0.yaml │ ├── add-baremetal-scoper-9ef23f5fb8f0be6a.yaml │ ├── add-force-field-to-audit-4bcaeedfe27233ad.yaml │ ├── add-ha-support-b9042255e5b76e42.yaml │ ├── add-instance-metrics-to-prometheus-datasource-9fba8c174ff845e1.yaml │ ├── add-name-for-audit-0df1f39f00736f06.yaml │ ├── add-plugins-parameters-376eb6b0b8978b44.yaml │ ├── add-power-on-off-a77673d482568a8b.yaml │ ├── add-scoring-module-fa00d013ed2d614e.yaml │ ├── add-start-end-time-for-continuous-audit-52c45052cb06d153.yaml │ ├── add-upgrade-check-framework-5bb9693c8a78931c.yaml │ ├── add-wsgi-module-support-597f479e31979270.yaml │ ├── api-call-retry-fef741ac684c58dd.yaml │ ├── api-microversioning-7999a3ee8073bf32.yaml │ ├── audit-scoper-for-storage-data-model-cdccc803542d22db.yaml │ ├── audit-tag-vm-metadata-47a3e4468748853c.yaml │ ├── audit-versioned-notifications-api-bca7738e16954bad.yaml │ ├── automatic-triggering-audit-8a9b0540d547db60.yaml │ ├── background-jobs-ha-9d3cf3fe356f4705.yaml │ ├── bp-audit-scope-exclude-project-511a7720aac00dff.yaml │ ├── bug-2103451-fixes-prometheus-queries-with-multiple-target-0e65d20711d1abe2.yaml │ ├── bug-2109494-e5bf401767fa6cd6.yaml │ ├── build-baremetal-data-model-in-watcher-3023453a47b61dab.yaml │ ├── cdm-scoping-8d9c307bad46bfa1.yaml │ ├── centralise-config-opts-95670987dfbdb0e7.yaml │ ├── change-ram-util-metric-4a3e6984b9dd968d.yaml │ ├── check-strategy-requirements-66f9e9262412f8ec.yaml │ ├── cinder-model-integration-baa394a72a0a33bf.yaml │ ├── cluster-model-objects-wrapper-9c799ea262c56a5b.yaml │ ├── compute-cdm-include-all-instances-f7506ded2d57732f.yaml │ ├── configurable-weights-default-planner-3746b33160bc7347.yaml │ ├── consume-nova-versioned-notifications-f98361b37e546b4d.yaml │ ├── continuously-optimization-35364f4d2c0b81fc.yaml │ ├── cron-based-continuous-audits-c3eedf28d9752b37.yaml │ ├── datasource-query-retry-00cba5f7e68aec39.yaml │ ├── db-migration-e1a705a8b54ccdd2.yaml │ ├── define-the-audit-scope-e89edc5051dcf3f2.yaml │ ├── deprecate-ceilometer-datasource-446b0be70fbce28b.yaml │ ├── deprecate-json-formatted-policy-file-3a92379e9f5dd203.yaml │ ├── deprecate-monasca-ds-9065f4d4bee09ab2.yaml │ ├── deprecate-noisy-neighbor-strat-7da910837ae8fa80.yaml │ ├── donot-run-host-migration-strategy-on-disabled-hosts-24084a22d4c8f914.yaml │ ├── drop-py-2-7-54f8e806d71f19a7.yaml │ ├── drop-python38-support-eeb19a0bc0160sw1.yaml │ ├── dynamic-action-description-0e947b9e7ef2a134.yaml │ ├── efficacy-indicator-95380ad7b84e3be2.yaml │ ├── enhance-watcher-applier-engine-86c676ce8f179e68.yaml │ ├── event-driven-optimization-based-4870f112bef8a560.yaml │ ├── file-based-metric-map-c2af62b5067895df.yaml │ ├── fix-action-plan-state-on-failure-69e498d902ada5c5.yaml │ ├── formal-datasource-interface-implementation-222769d55a127d33.yaml │ ├── general-purpose-decision-engine-threadpool-0711b23abfc9d409.yaml │ ├── get-goal-from-strategy-396c9b13a38bb650.yaml │ ├── global-datasource-preference-3ab47b4be09ff3a5.yaml │ ├── gnocchi-watcher-43c25d391fbd3e9c.yaml │ ├── grafana-datasource-b672367c23ffa0c6.yaml │ ├── graph-based-cluster-model-523937a6f5e66537.yaml │ ├── host-maintenance-strategy-41f640927948fb56.yaml │ ├── improve-compute-data-model-b427c85e4ed2b6fb.yaml │ ├── jsonschema-validation-79cab05d5295da00.yaml │ ├── min-required-nova-train-71f124192d88ae52.yaml │ ├── monasca-support-0b0486b8572ac38b.yaml │ ├── multiple-global-efficacy-indicator-fc11c4844a12a7d5.yaml │ ├── node-resource-consolidation-73bc0c0abfeb0b03.yaml │ ├── noisy-neighbor-strategy-a71342740b59dddc.yaml │ ├── notifications-actionplan-cancel-edb2a4a12543e2d0.yaml │ ├── optimization-threshold-21ad38f0470d0e1a.yaml │ ├── persistent-audit-parameters-ae41dd7252ba9672.yaml │ ├── planner-storage-action-plan-26ef37893c5e8648.yaml │ ├── prometheus-datasource-e56f2f7b8f3427c2.yaml │ ├── remove-ceilometer-datasource-8d9ab7d64d61e405.yaml │ ├── remove-nova-legacy-notifications-e1b6d10eff58f30a.yaml │ ├── replace-cold-migrate-to-use-nova-migration-api-cecd9a39ddd3bc58.yaml │ ├── return-error-400-on-bad-parameters-bb964e4f5cadc15c.yaml │ ├── scope-for-data-model-ea9792f90db14343.yaml │ ├── service-versioned-notifications-api-70367b79a565d900.yaml │ ├── show-datamodel-api-6945b744fd5d25d5.yaml │ ├── stale-action-plan-b6a6b08df873c128.yaml │ ├── standard-deviation-strategy-cd1d0c443fdfde9c.yaml │ ├── storage-workload-balance-0ecabbc1791e6894.yaml │ ├── support-keystoneclient-option-b30d1ff45f86a2e7.yaml │ ├── support-placement-api-58ce6bef1bbbe98a.yaml │ ├── suspended-audit-state-07f998c94e9d9a47.yaml │ ├── uniform-airflow-strategy-68cdba1419c3f770.yaml │ ├── uwsgi-support-8dcea6961e56dad0.yaml │ ├── volume-migrate-action-fc57b0ce0e4c39ae.yaml │ ├── watcher-notifications-ovo-7b44d52ef6400dd0.yaml │ ├── watcher-planner-selector-84d77549d46f362a.yaml │ ├── watcher-policies-1e86a30f0f11c6fa.yaml │ ├── watcher-service-list-7b2f4b64f71e9b89.yaml │ ├── watcher-versioned-objects-fc5abf5c81c4590c.yaml │ ├── workload-balance-base-on-cpu-or-ram-util-3ff4ee968c32b2ed.yaml │ ├── workload-balance-migration-strategy-a0b05148a57815c0.yaml │ ├── zone-migration-missing-dst-node-bd0377af1f1ed245.yaml │ └── zone-migration-strategy-10f7656a2a01e607.yaml └── source │ ├── 2023.1.rst │ ├── 2023.2.rst │ ├── 2024.1.rst │ ├── 2024.2.rst │ ├── 2025.1.rst │ ├── _static │ └── .placeholder │ ├── conf.py │ ├── index.rst │ ├── locale │ ├── en_GB │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ └── fr │ │ └── LC_MESSAGES │ │ └── releasenotes.po │ ├── 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 ├── tools └── test-setup.sh ├── tox.ini └── watcher ├── __init__.py ├── _i18n.py ├── api ├── __init__.py ├── acl.py ├── app.py ├── app.wsgi ├── config.py ├── controllers │ ├── __init__.py │ ├── base.py │ ├── link.py │ ├── rest_api_version_history.rst │ ├── root.py │ └── v1 │ │ ├── __init__.py │ │ ├── action.py │ │ ├── action_plan.py │ │ ├── audit.py │ │ ├── audit_template.py │ │ ├── collection.py │ │ ├── data_model.py │ │ ├── efficacy_indicator.py │ │ ├── goal.py │ │ ├── scoring_engine.py │ │ ├── service.py │ │ ├── strategy.py │ │ ├── types.py │ │ ├── utils.py │ │ ├── versions.py │ │ └── webhooks.py ├── hooks.py ├── middleware │ ├── __init__.py │ ├── auth_token.py │ └── parsable_error.py ├── scheduling.py └── wsgi.py ├── applier ├── __init__.py ├── action_plan │ ├── __init__.py │ ├── base.py │ └── default.py ├── actions │ ├── __init__.py │ ├── base.py │ ├── change_node_power_state.py │ ├── change_nova_service_state.py │ ├── factory.py │ ├── migration.py │ ├── nop.py │ ├── resize.py │ ├── sleep.py │ └── volume_migration.py ├── base.py ├── default.py ├── loading │ ├── __init__.py │ └── default.py ├── manager.py ├── messaging │ ├── __init__.py │ └── trigger.py ├── rpcapi.py ├── sync.py └── workflow_engine │ ├── __init__.py │ ├── base.py │ └── default.py ├── cmd ├── __init__.py ├── api.py ├── applier.py ├── dbmanage.py ├── decisionengine.py ├── status.py └── sync.py ├── common ├── __init__.py ├── cinder_helper.py ├── clients.py ├── config.py ├── context.py ├── exception.py ├── ironic_helper.py ├── keystone_helper.py ├── loader │ ├── __init__.py │ ├── base.py │ ├── default.py │ └── loadable.py ├── metal_helper │ ├── __init__.py │ ├── base.py │ ├── constants.py │ ├── factory.py │ ├── ironic.py │ └── maas.py ├── nova_helper.py ├── paths.py ├── placement_helper.py ├── policies │ ├── __init__.py │ ├── action.py │ ├── action_plan.py │ ├── audit.py │ ├── audit_template.py │ ├── base.py │ ├── data_model.py │ ├── goal.py │ ├── scoring_engine.py │ ├── service.py │ └── strategy.py ├── policy.py ├── rpc.py ├── scheduling.py ├── service.py ├── service_manager.py └── utils.py ├── conf ├── __init__.py ├── api.py ├── applier.py ├── cinder_client.py ├── clients_auth.py ├── collector.py ├── datasources.py ├── db.py ├── decision_engine.py ├── exception.py ├── glance_client.py ├── gnocchi_client.py ├── grafana_client.py ├── grafana_translators.py ├── ironic_client.py ├── keystone_client.py ├── maas_client.py ├── monasca_client.py ├── neutron_client.py ├── nova_client.py ├── opts.py ├── paths.py ├── placement_client.py ├── planner.py ├── plugins.py ├── prometheus_client.py └── service.py ├── db ├── __init__.py ├── api.py ├── migration.py ├── purge.py └── sqlalchemy │ ├── __init__.py │ ├── alembic.ini │ ├── alembic │ ├── README.rst │ ├── env.py │ ├── script.py.mako │ └── versions │ │ ├── 001_ocata.py │ │ ├── 0f6042416884_add_apscheduler_jobs.py │ │ ├── 15f7375ca737_change_efficiacy_indicator_decimals.py │ │ ├── 3cfc94cecf4e_add_name_for_audit.py │ │ ├── 4b16194c56bc_add_start_end_time.py │ │ ├── 52804f2498c4_add_hostname.py │ │ ├── 609bec748f2a_add_force_field.py │ │ ├── a86240e89a29_.py │ │ ├── d098df6021e2_cron_support_for_audit.py │ │ └── d09a5945e4a0_add_action_description_table.py │ ├── api.py │ ├── job_store.py │ ├── migration.py │ └── models.py ├── decision_engine ├── __init__.py ├── audit │ ├── __init__.py │ ├── base.py │ ├── continuous.py │ ├── event.py │ └── oneshot.py ├── datasources │ ├── __init__.py │ ├── base.py │ ├── gnocchi.py │ ├── grafana.py │ ├── grafana_translator │ │ ├── __init__.py │ │ ├── base.py │ │ └── influxdb.py │ ├── manager.py │ ├── monasca.py │ └── prometheus.py ├── gmr.py ├── goal │ ├── __init__.py │ ├── base.py │ ├── efficacy │ │ ├── __init__.py │ │ ├── base.py │ │ ├── indicators.py │ │ └── specs.py │ └── goals.py ├── loading │ ├── __init__.py │ └── default.py ├── manager.py ├── messaging │ ├── __init__.py │ ├── audit_endpoint.py │ └── data_model_endpoint.py ├── model │ ├── __init__.py │ ├── base.py │ ├── collector │ │ ├── __init__.py │ │ ├── base.py │ │ ├── cinder.py │ │ ├── ironic.py │ │ ├── manager.py │ │ └── nova.py │ ├── element │ │ ├── __init__.py │ │ ├── baremetal_resource.py │ │ ├── base.py │ │ ├── compute_resource.py │ │ ├── instance.py │ │ ├── node.py │ │ ├── storage_resource.py │ │ └── volume.py │ ├── model_root.py │ └── notification │ │ ├── __init__.py │ │ ├── base.py │ │ ├── cinder.py │ │ ├── filtering.py │ │ └── nova.py ├── planner │ ├── __init__.py │ ├── base.py │ ├── manager.py │ ├── node_resource_consolidation.py │ ├── weight.py │ └── workload_stabilization.py ├── rpcapi.py ├── scheduling.py ├── scope │ ├── __init__.py │ ├── baremetal.py │ ├── base.py │ ├── compute.py │ └── storage.py ├── scoring │ ├── __init__.py │ ├── base.py │ ├── dummy_scorer.py │ ├── dummy_scoring_container.py │ └── scoring_factory.py ├── solution │ ├── __init__.py │ ├── base.py │ ├── default.py │ ├── efficacy.py │ ├── solution_comparator.py │ └── solution_evaluator.py ├── strategy │ ├── __init__.py │ ├── common │ │ ├── __init__.py │ │ └── level.py │ ├── context │ │ ├── __init__.py │ │ ├── base.py │ │ └── default.py │ ├── selection │ │ ├── __init__.py │ │ ├── base.py │ │ └── default.py │ └── strategies │ │ ├── __init__.py │ │ ├── actuation.py │ │ ├── base.py │ │ ├── basic_consolidation.py │ │ ├── dummy_strategy.py │ │ ├── dummy_with_resize.py │ │ ├── dummy_with_scorer.py │ │ ├── host_maintenance.py │ │ ├── node_resource_consolidation.py │ │ ├── noisy_neighbor.py │ │ ├── outlet_temp_control.py │ │ ├── saving_energy.py │ │ ├── storage_capacity_balance.py │ │ ├── uniform_airflow.py │ │ ├── vm_workload_consolidation.py │ │ ├── workload_balance.py │ │ ├── workload_stabilization.py │ │ └── zone_migration.py ├── sync.py └── threading.py ├── eventlet.py ├── hacking ├── __init__.py └── checks.py ├── locale ├── de │ └── LC_MESSAGES │ │ └── watcher.po └── en_GB │ └── LC_MESSAGES │ └── watcher.po ├── notifications ├── __init__.py ├── action.py ├── action_plan.py ├── audit.py ├── base.py ├── exception.py ├── goal.py ├── service.py └── strategy.py ├── objects ├── __init__.py ├── action.py ├── action_description.py ├── action_plan.py ├── audit.py ├── audit_template.py ├── base.py ├── efficacy_indicator.py ├── fields.py ├── goal.py ├── scoring_engine.py ├── service.py └── strategy.py ├── tests ├── __init__.py ├── api │ ├── __init__.py │ ├── base.py │ ├── test_base.py │ ├── test_config.py │ ├── test_hooks.py │ ├── test_root.py │ ├── test_scheduling.py │ ├── test_utils.py │ ├── utils.py │ └── v1 │ │ ├── __init__.py │ │ ├── test_actions.py │ │ ├── test_actions_plans.py │ │ ├── test_audit_templates.py │ │ ├── test_audits.py │ │ ├── test_data_model.py │ │ ├── test_goals.py │ │ ├── test_microversions.py │ │ ├── test_root.py │ │ ├── test_scoring_engines.py │ │ ├── test_services.py │ │ ├── test_strategies.py │ │ ├── test_types.py │ │ ├── test_utils.py │ │ └── test_webhooks.py ├── applier │ ├── __init__.py │ ├── action_plan │ │ ├── __init__.py │ │ └── test_default_action_handler.py │ ├── actions │ │ ├── __init__.py │ │ ├── loading │ │ │ ├── __init__.py │ │ │ └── test_default_actions_loader.py │ │ ├── test_change_node_power_state.py │ │ ├── test_change_nova_service_state.py │ │ ├── test_migration.py │ │ ├── test_resize.py │ │ ├── test_sleep.py │ │ └── test_volume_migration.py │ ├── messaging │ │ ├── __init__.py │ │ └── test_trigger_action_plan_endpoint.py │ ├── test_applier_manager.py │ ├── test_rpcapi.py │ ├── test_sync.py │ └── workflow_engine │ │ ├── __init__.py │ │ ├── loading │ │ ├── __init__.py │ │ └── test_default_engine_loader.py │ │ ├── test_default_workflow_engine.py │ │ └── test_taskflow_action_container.py ├── base.py ├── cmd │ ├── __init__.py │ ├── test_api.py │ ├── test_applier.py │ ├── test_db_manage.py │ ├── test_decision_engine.py │ └── test_status.py ├── common │ ├── __init__.py │ ├── loader │ │ ├── __init__.py │ │ └── test_loader.py │ ├── metal_helper │ │ ├── __init__.py │ │ ├── test_base.py │ │ ├── test_factory.py │ │ ├── test_ironic.py │ │ └── test_maas.py │ ├── test_cinder_helper.py │ ├── test_clients.py │ ├── test_ironic_helper.py │ ├── test_nova_helper.py │ ├── test_placement_helper.py │ ├── test_scheduling.py │ ├── test_service.py │ └── test_utils.py ├── conf │ ├── __init__.py │ └── test_list_opts.py ├── conf_fixture.py ├── config.py ├── db │ ├── __init__.py │ ├── base.py │ ├── test_action.py │ ├── test_action_description.py │ ├── test_action_plan.py │ ├── test_audit.py │ ├── test_audit_template.py │ ├── test_efficacy_indicator.py │ ├── test_goal.py │ ├── test_migrations.py │ ├── test_purge.py │ ├── test_scoring_engine.py │ ├── test_service.py │ ├── test_strategy.py │ └── utils.py ├── decision_engine │ ├── __init__.py │ ├── audit │ │ ├── __init__.py │ │ └── test_audit_handlers.py │ ├── cluster │ │ ├── __init__.py │ │ ├── test_cinder_cdmc.py │ │ ├── test_cluster_data_model_collector.py │ │ └── test_nova_cdmc.py │ ├── datasources │ │ ├── __init__.py │ │ ├── grafana_translators │ │ │ ├── __init__.py │ │ │ ├── test_base.py │ │ │ └── test_influxdb.py │ │ ├── test_base.py │ │ ├── test_gnocchi_helper.py │ │ ├── test_grafana_helper.py │ │ ├── test_manager.py │ │ ├── test_monasca_helper.py │ │ └── test_prometheus_helper.py │ ├── event_consumer │ │ └── __init__.py │ ├── fake_goals.py │ ├── fake_metal_helper.py │ ├── fake_strategies.py │ ├── loading │ │ ├── __init__.py │ │ ├── test_collector_loader.py │ │ ├── test_default_planner_loader.py │ │ ├── test_default_strategy_loader.py │ │ └── test_goal_loader.py │ ├── messaging │ │ ├── __init__.py │ │ ├── test_audit_endpoint.py │ │ └── test_data_model_endpoint.py │ ├── model │ │ ├── __init__.py │ │ ├── data │ │ │ ├── ironic_scenario_1.xml │ │ │ ├── scenario_1.xml │ │ │ ├── scenario_10.xml │ │ │ ├── scenario_1_with_1_node_unavailable.xml │ │ │ ├── scenario_1_with_all_instances_exclude.xml │ │ │ ├── scenario_1_with_all_nodes_disable.xml │ │ │ ├── scenario_1_with_metrics.xml │ │ │ ├── scenario_2_with_metrics.xml │ │ │ ├── scenario_3_with_2_nodes.xml │ │ │ ├── scenario_3_with_metrics.xml │ │ │ ├── scenario_4_with_1_node_no_instance.xml │ │ │ ├── scenario_5_with_instance_disk_0.xml │ │ │ ├── scenario_6_with_2_nodes.xml │ │ │ ├── scenario_7_with_2_nodes.xml │ │ │ ├── scenario_8_with_4_nodes.xml │ │ │ ├── scenario_9_with_3_active_plus_1_disabled_nodes.xml │ │ │ └── storage_scenario_1.xml │ │ ├── faker_cluster_and_metrics.py │ │ ├── faker_cluster_state.py │ │ ├── gnocchi_metrics.py │ │ ├── monasca_metrics.py │ │ ├── notification │ │ │ ├── __init__.py │ │ │ ├── data │ │ │ │ ├── capacity.json │ │ │ │ ├── instance-create-end.json │ │ │ │ ├── instance-delete-end.json │ │ │ │ ├── instance-live_migration_force_complete-end.json │ │ │ │ ├── instance-live_migration_post-end.json │ │ │ │ ├── instance-lock.json │ │ │ │ ├── instance-pause-end.json │ │ │ │ ├── instance-power_off-end.json │ │ │ │ ├── instance-power_on-end.json │ │ │ │ ├── instance-rebuild-end.json │ │ │ │ ├── instance-rescue-end.json │ │ │ │ ├── instance-resize_confirm-end.json │ │ │ │ ├── instance-restore-end.json │ │ │ │ ├── instance-resume-end.json │ │ │ │ ├── instance-shelve-end.json │ │ │ │ ├── instance-shutdown-end.json │ │ │ │ ├── instance-soft_delete-end.json │ │ │ │ ├── instance-suspend-end.json │ │ │ │ ├── instance-unlock.json │ │ │ │ ├── instance-unpause-end.json │ │ │ │ ├── instance-unrescue-end.json │ │ │ │ ├── instance-unshelve-end.json │ │ │ │ ├── instance-update.json │ │ │ │ ├── scenario3_instance-update.json │ │ │ │ ├── scenario3_notfound_instance-update.json │ │ │ │ ├── scenario3_notfound_legacy_instance-update.json │ │ │ │ ├── scenario3_service-update-disabled.json │ │ │ │ ├── scenario3_service-update-enabled.json │ │ │ │ ├── scenario_1_bootable-volume-create.json │ │ │ │ ├── scenario_1_capacity.json │ │ │ │ ├── scenario_1_capacity_node_notfound.json │ │ │ │ ├── scenario_1_capacity_pool_notfound.json │ │ │ │ ├── scenario_1_error-volume-create.json │ │ │ │ ├── scenario_1_volume-attach.json │ │ │ │ ├── scenario_1_volume-create.json │ │ │ │ ├── scenario_1_volume-create_pool_notfound.json │ │ │ │ ├── scenario_1_volume-delete.json │ │ │ │ ├── scenario_1_volume-detach.json │ │ │ │ ├── scenario_1_volume-resize.json │ │ │ │ ├── scenario_1_volume-update.json │ │ │ │ ├── service-create.json │ │ │ │ ├── service-delete.json │ │ │ │ └── service-update.json │ │ │ ├── fake_managers.py │ │ │ ├── test_cinder_notifications.py │ │ │ ├── test_notifications.py │ │ │ └── test_nova_notifications.py │ │ ├── test_element.py │ │ └── test_model.py │ ├── planner │ │ ├── __init__.py │ │ ├── test_node_resource_consolidation.py │ │ ├── test_planner_manager.py │ │ ├── test_weight_planner.py │ │ └── test_workload_stabilization_planner.py │ ├── scope │ │ ├── __init__.py │ │ ├── fake_scopes.py │ │ ├── test_baremetal.py │ │ ├── test_compute.py │ │ └── test_storage.py │ ├── scoring │ │ ├── __init__.py │ │ ├── test_dummy_scorer.py │ │ ├── test_dummy_scoring_container.py │ │ └── test_scoring_factory.py │ ├── solution │ │ ├── __init__.py │ │ └── test_default_solution.py │ ├── strategy │ │ ├── __init__.py │ │ ├── context │ │ │ ├── __init__.py │ │ │ └── test_strategy_context.py │ │ ├── selector │ │ │ ├── __init__.py │ │ │ └── test_strategy_selector.py │ │ └── strategies │ │ │ ├── __init__.py │ │ │ ├── test_actuator.py │ │ │ ├── test_base.py │ │ │ ├── test_basic_consolidation.py │ │ │ ├── test_dummy_strategy.py │ │ │ ├── test_dummy_with_scorer.py │ │ │ ├── test_host_maintenance.py │ │ │ ├── test_node_resource_consolidation.py │ │ │ ├── test_noisy_neighbor.py │ │ │ ├── test_outlet_temp_control.py │ │ │ ├── test_saving_energy.py │ │ │ ├── test_storage_capacity_balance.py │ │ │ ├── test_strategy_endpoint.py │ │ │ ├── test_uniform_airflow.py │ │ │ ├── test_vm_workload_consolidation.py │ │ │ ├── test_workload_balance.py │ │ │ ├── test_workload_stabilization.py │ │ │ └── test_zone_migration.py │ ├── test_gmr.py │ ├── test_rpcapi.py │ ├── test_scheduling.py │ └── test_sync.py ├── fake_policy.py ├── fakes.py ├── fixtures │ ├── __init__.py │ └── watcher.py ├── notifications │ ├── __init__.py │ ├── test_action_notification.py │ ├── test_action_plan_notification.py │ ├── test_audit_notification.py │ ├── test_notification.py │ └── test_service_notifications.py ├── objects │ ├── __init__.py │ ├── test_action.py │ ├── test_action_description.py │ ├── test_action_plan.py │ ├── test_audit.py │ ├── test_audit_template.py │ ├── test_efficacy_indicator.py │ ├── test_goal.py │ ├── test_objects.py │ ├── test_scoring_engine.py │ ├── test_service.py │ ├── test_strategy.py │ └── utils.py ├── policy_fixture.py └── test_threading.py ├── version.py └── wsgi ├── __init__.py └── api.py /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch = True 3 | source = watcher 4 | omit = 5 | watcher/tests/* 6 | watcher/hacking/* 7 | 8 | [report] 9 | ignore_errors = True 10 | exclude_lines = 11 | @abc.abstract 12 | raise NotImplementedError 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg* 8 | dist 9 | build 10 | eggs 11 | parts 12 | bin 13 | var 14 | sdist 15 | develop-eggs 16 | .installed.cfg 17 | lib 18 | lib64 19 | 20 | # Installer logs 21 | pip-log.txt 22 | 23 | # Unit test / coverage reports 24 | .coverage* 25 | .tox 26 | .stestr/ 27 | .venv 28 | .idea 29 | .testrepository/ 30 | 31 | # Translations 32 | *.mo 33 | 34 | # Mr Developer 35 | .mr.developer.cfg 36 | .project 37 | .pydevproject 38 | 39 | # Complexity 40 | output/*.html 41 | output/*/index.html 42 | 43 | # Sphinx 44 | doc/build 45 | doc/source/api/* 46 | doc/source/samples 47 | doc/source/_static/*.sample 48 | !doc/source/api/index.rst 49 | !doc/source/api/v1.rst 50 | 51 | # pbr generates these 52 | AUTHORS 53 | ChangeLog 54 | 55 | # Editors 56 | *~ 57 | .*.swp 58 | .*sw? 59 | 60 | sftp-config.json 61 | /.idea/ 62 | /cover/ 63 | .settings/ 64 | .eclipse 65 | 66 | cover 67 | /demo/ 68 | 69 | 70 | # Files created by releasenotes build 71 | releasenotes/build 72 | 73 | # Desktop Service Store 74 | *.DS_Store 75 | 76 | # Autogenerated sample config file 77 | etc/watcher/watcher.conf.sample 78 | 79 | # Atom 80 | .remote-sync.json 81 | -------------------------------------------------------------------------------- /.gitreview: -------------------------------------------------------------------------------- 1 | [gerrit] 2 | host=review.opendev.org 3 | port=29418 4 | project=openstack/watcher.git 5 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | # Format is: 2 | # 3 | # 4 | -------------------------------------------------------------------------------- /.stestr.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | test_path=./watcher/tests 3 | top_dir=./ 4 | 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | If you would like to contribute to the development of OpenStack, 2 | you must follow the steps in this page: 3 | 4 | https://docs.openstack.org/infra/manual/developers.html 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/watcher 17 | -------------------------------------------------------------------------------- /HACKING.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Except where otherwise noted, this document is licensed under Creative 3 | Commons Attribution 3.0 License. You can view the license at: 4 | 5 | https://creativecommons.org/licenses/by/3.0/ 6 | 7 | ========================== 8 | watcher Style Commandments 9 | ========================== 10 | 11 | Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/ 12 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | Watcher 3 | ======= 4 | 5 | .. image:: https://governance.openstack.org/tc/badges/watcher.svg 6 | :target: https://governance.openstack.org/tc/reference/tags/index.html 7 | 8 | .. Change things from this point on 9 | 10 | .. 11 | Except where otherwise noted, this document is licensed under Creative 12 | Commons Attribution 3.0 License. You can view the license at: 13 | 14 | https://creativecommons.org/licenses/by/3.0/ 15 | 16 | OpenStack Watcher provides a flexible and scalable resource optimization 17 | service for multi-tenant OpenStack-based clouds. 18 | Watcher provides a robust framework to realize a wide range of cloud 19 | optimization goals, including the reduction of data center 20 | operating costs, increased system performance via intelligent virtual machine 21 | migration, increased energy efficiency and more! 22 | 23 | * Free software: Apache license 24 | * Wiki: https://wiki.openstack.org/wiki/Watcher 25 | * Source: https://opendev.org/openstack/watcher 26 | * Bugs: https://bugs.launchpad.net/watcher 27 | * Documentation: https://docs.openstack.org/watcher/latest/ 28 | * Release notes: https://docs.openstack.org/releasenotes/watcher/ 29 | * Design specifications: https://specs.openstack.org/openstack/watcher-specs/ 30 | -------------------------------------------------------------------------------- /api-ref/source/index.rst: -------------------------------------------------------------------------------- 1 | :tocdepth: 2 2 | 3 | =========== 4 | Watcher API 5 | =========== 6 | 7 | .. rest_expand_all:: 8 | 9 | .. include:: watcher-api-versions.inc 10 | .. include:: watcher-api-v1-audittemplates.inc 11 | .. include:: watcher-api-v1-audits.inc 12 | .. include:: watcher-api-v1-actionplans.inc 13 | .. include:: watcher-api-v1-actions.inc 14 | .. include:: watcher-api-v1-goals.inc 15 | .. include:: watcher-api-v1-strategies.inc 16 | .. include:: watcher-api-v1-services.inc 17 | .. include:: watcher-api-v1-scoring_engines.inc 18 | .. include:: watcher-api-v1-datamodel.inc 19 | .. include:: watcher-api-v1-webhooks.inc 20 | -------------------------------------------------------------------------------- /api-ref/source/samples/actionplan-cancel-request-cancelling.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "replace", 4 | "value": "CANCELLING", 5 | "path": "/state" 6 | } 7 | ] -------------------------------------------------------------------------------- /api-ref/source/samples/actionplan-cancel-request-pending.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "replace", 4 | "value": "CANCELLED", 5 | "path": "/state" 6 | } 7 | ] -------------------------------------------------------------------------------- /api-ref/source/samples/actionplan-list-detailed-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "action_plans": [ 3 | { 4 | "state": "ONGOING", 5 | "efficacy_indicators": [], 6 | "strategy_uuid": "7dae0eea-9df7-42b8-bb3e-313958ff2242", 7 | "global_efficacy": [], 8 | "links": [ 9 | { 10 | "rel": "self", 11 | "href": "http://controller:9322/v1/action_plans/4cbc4ede-0d25-481b-b86e-998dbbd4f8bf" 12 | }, 13 | { 14 | "rel": "bookmark", 15 | "href": "http://controller:9322/action_plans/4cbc4ede-0d25-481b-b86e-998dbbd4f8bf" 16 | } 17 | ], 18 | "updated_at": "2018-04-10T11:59:52.640067+00:00", 19 | "strategy_name": "dummy_with_resize", 20 | "deleted_at": null, 21 | "uuid": "4cbc4ede-0d25-481b-b86e-998dbbd4f8bf", 22 | "audit_uuid": "7d100b05-0a86-491f-98a7-f93da19b272a", 23 | "created_at": "2018-04-10T11:59:52.640067+00:00", 24 | "hostname": "controller" 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /api-ref/source/samples/actionplan-list-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "action_plans": [ 3 | { 4 | "state": "ONGOING", 5 | "efficacy_indicators": [], 6 | "strategy_uuid": "7dae0eea-9df7-42b8-bb3e-313958ff2242", 7 | "global_efficacy": [], 8 | "links": [ 9 | { 10 | "rel": "self", 11 | "href": "http://controller:9322/v1/action_plans/4cbc4ede-0d25-481b-b86e-998dbbd4f8bf" 12 | }, 13 | { 14 | "rel": "bookmark", 15 | "href": "http://controller:9322/action_plans/4cbc4ede-0d25-481b-b86e-998dbbd4f8bf" 16 | } 17 | ], 18 | "updated_at": "2018-04-10T11:59:52.640067+00:00", 19 | "strategy_name": "dummy_with_resize", 20 | "uuid": "4cbc4ede-0d25-481b-b86e-998dbbd4f8bf", 21 | "audit_uuid": "7d100b05-0a86-491f-98a7-f93da19b272a" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /api-ref/source/samples/actionplan-show-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "state": "ONGOING", 3 | "efficacy_indicators": [], 4 | "strategy_uuid": "7dae0eea-9df7-42b8-bb3e-313958ff2242", 5 | "global_efficacy": [], 6 | "links": [ 7 | { 8 | "rel": "self", 9 | "href": "http://controller:9322/v1/action_plans/4cbc4ede-0d25-481b-b86e-998dbbd4f8bf" 10 | }, 11 | { 12 | "rel": "bookmark", 13 | "href": "http://controller:9322/action_plans/4cbc4ede-0d25-481b-b86e-998dbbd4f8bf" 14 | } 15 | ], 16 | "updated_at": "2018-04-10T11:59:52.640067+00:00", 17 | "strategy_name": "dummy_with_resize", 18 | "uuid": "4cbc4ede-0d25-481b-b86e-998dbbd4f8bf", 19 | "audit_uuid": "7d100b05-0a86-491f-98a7-f93da19b272a", 20 | "hostname": "controller" 21 | } -------------------------------------------------------------------------------- /api-ref/source/samples/actionplan-start-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "state": "PENDING", 3 | "efficacy_indicators": [], 4 | "strategy_uuid": "7dae0eea-9df7-42b8-bb3e-313958ff2242", 5 | "global_efficacy": [], 6 | "links": [ 7 | { 8 | "rel": "self", 9 | "href": "http://controller:9322/v1/action_plans/4cbc4ede-0d25-481b-b86e-998dbbd4f8bf" 10 | }, 11 | { 12 | "rel": "bookmark", 13 | "href": "http://controller:9322/action_plans/4cbc4ede-0d25-481b-b86e-998dbbd4f8bf" 14 | } 15 | ], 16 | "updated_at": "2018-04-10T11:59:41.602430+00:00", 17 | "strategy_name": "dummy_with_resize", 18 | "uuid": "4cbc4ede-0d25-481b-b86e-998dbbd4f8bf", 19 | "audit_uuid": "7d100b05-0a86-491f-98a7-f93da19b272a", 20 | "created_at": "2018-04-10T11:59:12.592729+00:00", 21 | "deleted_at": null, 22 | "hostname": null 23 | } -------------------------------------------------------------------------------- /api-ref/source/samples/actions-list-detailed-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "actions": [ 3 | { 4 | "state": "PENDING", 5 | "description": "Wait for a given interval in seconds.", 6 | "parents": [ 7 | "8119d16e-b419-4729-b015-fc04c4e45783" 8 | ], 9 | "links": [ 10 | { 11 | "rel": "self", 12 | "href": "http://controller:9322/v1/actions/7182a988-e6c4-4152-a0d6-067119475c83" 13 | }, 14 | { 15 | "rel": "bookmark", 16 | "href": "http://controller:9322/actions/7182a988-e6c4-4152-a0d6-067119475c83" 17 | } 18 | ], 19 | "action_plan_uuid": "c6bba9ed-a7eb-4370-9993-d873e5e22cba", 20 | "uuid": "7182a988-e6c4-4152-a0d6-067119475c83", 21 | "deleted_at": null, 22 | "updated_at": null, 23 | "input_parameters": { 24 | "duration": 3.2 25 | }, 26 | "action_type": "sleep", 27 | "created_at": "2018-03-26T11:56:08.235226+00:00" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /api-ref/source/samples/actions-list-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "actions": [ 3 | { 4 | "state": "PENDING", 5 | "parents": [ 6 | "8119d16e-b419-4729-b015-fc04c4e45783" 7 | ], 8 | "links": [ 9 | { 10 | "rel": "self", 11 | "href": "http://controller:9322/v1/actions/7182a988-e6c4-4152-a0d6-067119475c83" 12 | }, 13 | { 14 | "rel": "bookmark", 15 | "href": "http://controller:9322/actions/7182a988-e6c4-4152-a0d6-067119475c83" 16 | } 17 | ], 18 | "action_plan_uuid": "c6bba9ed-a7eb-4370-9993-d873e5e22cba", 19 | "uuid": "7182a988-e6c4-4152-a0d6-067119475c83", 20 | "action_type": "sleep" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /api-ref/source/samples/actions-show-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "state": "SUCCEEDED", 3 | "description": "Logging a NOP message", 4 | "parents": [ 5 | "b4529294-1de6-4302-b57a-9b5d5dc363c6" 6 | ], 7 | "links": [ 8 | { 9 | "rel": "self", 10 | "href": "http://controller:9322/v1/actions/54acc7a0-91b0-46ea-a5f7-4ae2b9df0b0a" 11 | }, 12 | { 13 | "rel": "bookmark", 14 | "href": "http://controller:9322/actions/54acc7a0-91b0-46ea-a5f7-4ae2b9df0b0a" 15 | } 16 | ], 17 | "action_plan_uuid": "4cbc4ede-0d25-481b-b86e-998dbbd4f8bf", 18 | "uuid": "54acc7a0-91b0-46ea-a5f7-4ae2b9df0b0a", 19 | "deleted_at": null, 20 | "updated_at": "2018-04-10T11:59:44.026973+00:00", 21 | "input_parameters": { 22 | "message": "Welcome" 23 | }, 24 | "action_type": "nop", 25 | "created_at": "2018-04-10T11:59:12.725147+00:00" 26 | } -------------------------------------------------------------------------------- /api-ref/source/samples/api-root-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "default_version": { 3 | "id": "v1", 4 | "links": [ 5 | { 6 | "href": "http://controller:9322/v1/", 7 | "rel": "self" 8 | } 9 | ], 10 | "min_version": "1.0", 11 | "status": "CURRENT", 12 | "max_version": "1.1" 13 | }, 14 | "description": "Watcher is an OpenStack project which aims to improve physical resources usage through better VM placement.", 15 | "name": "OpenStack Watcher API", 16 | "versions": [ 17 | { 18 | "id": "v1", 19 | "links": [ 20 | { 21 | "href": "http://controller:9322/v1/", 22 | "rel": "self" 23 | } 24 | ], 25 | "min_version": "1.0", 26 | "status": "CURRENT", 27 | "max_version": "1.1" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /api-ref/source/samples/audit-cancel-request.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "replace", 4 | "value": "CANCELLED", 5 | "path": "/state" 6 | } 7 | ] -------------------------------------------------------------------------------- /api-ref/source/samples/audit-create-request-continuous.json: -------------------------------------------------------------------------------- 1 | { 2 | "auto_trigger": false, 3 | "force": false, 4 | "audit_template_uuid": "76fddfee-a9c4-40b0-8da0-c19ad6904f09", 5 | "name": "test_audit", 6 | "parameters": { 7 | "metrics": [ 8 | "cpu_util" 9 | ] 10 | }, 11 | "audit_type": "CONTINUOUS", 12 | "interval": "*/2 * * * *", 13 | "start_time":"2018-04-02 20:30:00", 14 | "end_time": "2018-04-04 20:30:00" 15 | } 16 | -------------------------------------------------------------------------------- /api-ref/source/samples/audit-create-request-oneshot.json: -------------------------------------------------------------------------------- 1 | { 2 | "audit_type": "ONESHOT", 3 | "auto_trigger": false, 4 | "force": true, 5 | "audit_template_uuid": "5e70a156-ced7-4012-b1c6-88fcb02ee0c1" 6 | } 7 | -------------------------------------------------------------------------------- /api-ref/source/samples/audit-list-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "audits": [ 3 | { 4 | "interval": null, 5 | "strategy_uuid": "e311727b-b9b3-43ef-a5f7-8bd7ea80df25", 6 | "goal_uuid": "4690f8ba-18ff-45c1-99e9-159556d23810", 7 | "name": "dummy-2018-03-26T11:56:07.950400", 8 | "auto_trigger": false, 9 | "uuid": "ccc69a5f-114e-46f4-b15e-a77eaa337b01", 10 | "goal_name": "dummy", 11 | "scope": [], 12 | "state": "SUCCEEDED", 13 | "audit_type": "ONESHOT", 14 | "links": [ 15 | { 16 | "rel": "self", 17 | "href": "http://controller:9322/v1/audits/ccc69a5f-114e-46f4-b15e-a77eaa337b01" 18 | }, 19 | { 20 | "rel": "bookmark", 21 | "href": "http://controller:9322/audits/ccc69a5f-114e-46f4-b15e-a77eaa337b01" 22 | } 23 | ], 24 | "strategy_name": "dummy", 25 | "next_run_time": null 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /api-ref/source/samples/audit-update-request.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "value": "CANCELLED", 4 | "path": "/state", 5 | "op": "replace" 6 | }, 7 | { 8 | "value": "audit1", 9 | "path": "/name", 10 | "op": "replace" 11 | } 12 | ] -------------------------------------------------------------------------------- /api-ref/source/samples/audittemplate-create-request-full.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "at2", 3 | "goal": "dummy", 4 | "strategy": "dummy", 5 | "description": "the second audit template", 6 | "scope": [] 7 | } -------------------------------------------------------------------------------- /api-ref/source/samples/audittemplate-create-request-minimal.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "at2", 3 | "goal": "dummy" 4 | } -------------------------------------------------------------------------------- /api-ref/source/samples/audittemplate-create-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": null, 3 | "strategy_uuid": null, 4 | "goal_uuid": "4690f8ba-18ff-45c1-99e9-159556d23810", 5 | "name": "at3", 6 | "uuid": "b4041d8c-85d7-4224-851d-649fe48b7196", 7 | "goal_name": "dummy", 8 | "scope": [], 9 | "created_at": "2018-04-04T08:38:33.110432+00:00", 10 | "deleted_at": null, 11 | "links": [ 12 | { 13 | "rel": "self", 14 | "href": "http://controller:9322/v1/audit_templates/b4041d8c-85d7-4224-851d-649fe48b7196" 15 | }, 16 | { 17 | "rel": "bookmark", 18 | "href": "http://controller:9322/audit_templates/b4041d8c-85d7-4224-851d-649fe48b7196" 19 | } 20 | ], 21 | "strategy_name": null, 22 | "updated_at": null 23 | } -------------------------------------------------------------------------------- /api-ref/source/samples/audittemplate-list-detailed-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "audit_templates":[ 3 | { 4 | "strategy_uuid": null, 5 | "goal_uuid": "4690f8ba-18ff-45c1-99e9-159556d23810", 6 | "name": "at3", 7 | "links": [ 8 | { 9 | "rel": "self", 10 | "href": "http://controller:9322/v1/audit_templates/b4041d8c-85d7-4224-851d-649fe48b7196" 11 | }, 12 | { 13 | "rel": "bookmark", "href": 14 | "http://controller:9322/audit_templates/b4041d8c-85d7-4224-851d-649fe48b7196" 15 | } 16 | ], 17 | "strategy_name": null, 18 | "uuid": "b4041d8c-85d7-4224-851d-649fe48b7196", 19 | "goal_name": "dummy", "scope": [], 20 | "description": null 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /api-ref/source/samples/audittemplate-list-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "audit_templates":[ 3 | { 4 | "strategy_uuid": null, 5 | "goal_uuid": "4690f8ba-18ff-45c1-99e9-159556d23810", 6 | "name": "at3", 7 | "links": [ 8 | { 9 | "rel": "self", 10 | "href": "http://controller:9322/v1/audit_templates/b4041d8c-85d7-4224-851d-649fe48b7196" 11 | }, 12 | { 13 | "rel": "bookmark", "href": 14 | "http://controller:9322/audit_templates/b4041d8c-85d7-4224-851d-649fe48b7196" 15 | } 16 | ], 17 | "strategy_name": null, 18 | "uuid": "b4041d8c-85d7-4224-851d-649fe48b7196", 19 | "goal_name": "dummy", "scope": [] 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /api-ref/source/samples/audittemplate-show-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "test 1", 3 | "strategy_uuid": null, 4 | "goal_uuid": "4690f8ba-18ff-45c1-99e9-159556d23810", 5 | "name": "at1", 6 | "uuid": "0d100c27-14af-4962-86fb-f6079287c9c6", 7 | "goal_name": "dummy", 8 | "scope": [], 9 | "created_at": "2018-04-04T07:48:36.175472+00:00", 10 | "deleted_at": null, 11 | "links": [ 12 | { 13 | "rel": "self", 14 | "href": "http://controller:9322/v1/audit_templates/0d100c27-14af-4962-86fb-f6079287c9c6" 15 | }, 16 | { 17 | "rel": "bookmark", 18 | "href": "http://controller:9322/audit_templates/0d100c27-14af-4962-86fb-f6079287c9c6" 19 | } 20 | ], 21 | "strategy_name": null, 22 | "updated_at": "2018-04-05T07:57:55.803650+00:00" 23 | } -------------------------------------------------------------------------------- /api-ref/source/samples/audittemplate-update-request.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "op": "replace", 4 | "value": "PENDING", 5 | "path": "/state" 6 | } 7 | ] -------------------------------------------------------------------------------- /api-ref/source/samples/audittemplate-update-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "test 1", 3 | "strategy_uuid": null, 4 | "goal_uuid": "4690f8ba-18ff-45c1-99e9-159556d23810", 5 | "name": "at11", 6 | "uuid": "0d100c27-14af-4962-86fb-f6079287c9c6", 7 | "goal_name": "dummy", 8 | "scope": [], 9 | "created_at": "2018-04-04T07:48:36.175472+00:00", 10 | "deleted_at": null, 11 | "links": [ 12 | { 13 | "rel": "self", 14 | "href": "http://controller:9322/v1/audit_templates/0d100c27-14af-4962-86fb-f6079287c9c6" 15 | }, 16 | { 17 | "rel": "bookmark", 18 | "href": "http://controller:9322/audit_templates/0d100c27-14af-4962-86fb-f6079287c9c6" 19 | } 20 | ], 21 | "strategy_name": null, 22 | "updated_at": "2018-04-05T07:57:42.139127+00:00" 23 | } -------------------------------------------------------------------------------- /api-ref/source/samples/goal-show-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "efficacy_specification": [], 3 | "name": "saving_energy", 4 | "links": [ 5 | { 6 | "rel": "self", 7 | "href": "http://controller:9322/v1/goals/6f52889a-9dd4-4dbb-8e70-39b56c4836cc" 8 | }, 9 | { 10 | "rel": "bookmark", 11 | "href": "http://controller:9322/goals/6f52889a-9dd4-4dbb-8e70-39b56c4836cc" 12 | } 13 | ], 14 | "uuid": "6f52889a-9dd4-4dbb-8e70-39b56c4836cc", 15 | "updated_at": null, 16 | "display_name": "Saving Energy", 17 | "created_at": "2018-03-26T11:55:24.365584+00:00", 18 | "deleted_at": null 19 | } -------------------------------------------------------------------------------- /api-ref/source/samples/scoring_engine-list-detailed-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "scoring_engines": [ 3 | { 4 | "description": "Dummy Scorer calculating the average value", 5 | "uuid": "5a44f007-55b1-423c-809f-6a274a9bd93b", 6 | "links": [ 7 | { 8 | "rel": "self", 9 | "href": "http://controller:9322/v1/scoring_engines/5a44f007-55b1-423c-809f-6a274a9bd93b" 10 | }, 11 | { 12 | "rel": "bookmark", 13 | "href": "http://controller:9322/scoring_engines/5a44f007-55b1-423c-809f-6a274a9bd93b" 14 | } 15 | ], 16 | "name": "dummy_avg_scorer", 17 | "metainfo": "" 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /api-ref/source/samples/scoring_engine-list-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "scoring_engines": [ 3 | { 4 | "description": "Dummy Scorer calculating the average value", 5 | "uuid": "5a44f007-55b1-423c-809f-6a274a9bd93b", 6 | "links": [ 7 | { 8 | "rel": "self", 9 | "href": "http://controller:9322/v1/scoring_engines/5a44f007-55b1-423c-809f-6a274a9bd93b" 10 | }, 11 | { 12 | "rel": "bookmark", 13 | "href": "http://controller:9322/scoring_engines/5a44f007-55b1-423c-809f-6a274a9bd93b" 14 | } 15 | ], 16 | "name": "dummy_avg_scorer" 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /api-ref/source/samples/scoring_engine-show-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Dummy Scorer calculating the maximum value", 3 | "uuid": "1ac42282-4e77-473e-898b-62ea007f1deb", 4 | "links": [ 5 | { 6 | "rel": "self", 7 | "href": "http://controller:9322/v1/scoring_engines/1ac42282-4e77-473e-898b-62ea007f1deb" 8 | }, 9 | { 10 | "rel": "bookmark", 11 | "href": "http://controller:9322/scoring_engines/1ac42282-4e77-473e-898b-62ea007f1deb" 12 | } 13 | ], 14 | "name": "dummy_max_scorer", 15 | "metainfo": "" 16 | } -------------------------------------------------------------------------------- /api-ref/source/samples/service-list-detailed-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "services": [ 3 | { 4 | "status": "ACTIVE", 5 | "name": "watcher-applier", 6 | "host": "controller", 7 | "links": [ 8 | { 9 | "rel": "self", 10 | "href": "http://controller:9322/v1/services/1" 11 | }, 12 | { 13 | "rel": "bookmark", 14 | "href": "http://controller:9322/services/1" 15 | } 16 | ], 17 | "id": 1, 18 | "deleted_at": null, 19 | "updated_at": "2018-04-26T08:52:37.652895+00:00", 20 | "last_seen_up": "2018-04-26T08:52:37.648572", 21 | "created_at": "2018-03-26T11:55:24.075093+00:00" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /api-ref/source/samples/service-list-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "services": [ 3 | { 4 | "id": 1, 5 | "status": "ACTIVE", 6 | "name": "watcher-applier", 7 | "host": "controller", 8 | "links": [ 9 | { 10 | "rel": "self", 11 | "href": "http://controller:9322/v1/services/1" 12 | }, 13 | { 14 | "rel": "bookmark", 15 | "href": "http://controller:9322/services/1" 16 | } 17 | ] 18 | }, 19 | { 20 | "id": 2, 21 | "status": "ACTIVE", 22 | "name": "watcher-decision-engine", 23 | "host": "controller", 24 | "links": [ 25 | { 26 | "rel": "self", 27 | "href": "http://controller:9322/v1/services/2" 28 | }, 29 | { 30 | "rel": "bookmark", 31 | "href": "http://controller:9322/services/2" 32 | } 33 | ] 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /api-ref/source/samples/service-show-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "ACTIVE", 3 | "name": "watcher-applier", 4 | "host": "controller", 5 | "links": [ 6 | { 7 | "rel": "self", 8 | "href": "http://controller:9322/v1/services/1" 9 | }, 10 | { 11 | "rel": "bookmark", 12 | "href": "http://controller:9322/services/1" 13 | } 14 | ], 15 | "id": 1, 16 | "deleted_at": null, 17 | "updated_at": "2018-04-26T09:45:37.653061+00:00", 18 | "last_seen_up": "2018-04-26T09:45:37.649314", 19 | "created_at": "2018-03-26T11:55:24.075093+00:00" 20 | } -------------------------------------------------------------------------------- /api-ref/source/samples/strategy-list-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "strategies": [ 3 | { 4 | "goal_uuid": "4690f8ba-18ff-45c1-99e9-159556d23810", 5 | "name": "dummy", 6 | "links": [ 7 | { 8 | "rel": "self", 9 | "href": "http://controller:9322/v1/strategies/e311727b-b9b3-43ef-a5f7-8bd7ea80df25" 10 | }, 11 | { 12 | "rel": "bookmark", 13 | "href": "http://controller:9322/strategies/e311727b-b9b3-43ef-a5f7-8bd7ea80df25" 14 | } 15 | ], 16 | "uuid": "e311727b-b9b3-43ef-a5f7-8bd7ea80df25", 17 | "goal_name": "dummy", 18 | "display_name": "Dummy strategy" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /api-ref/source/samples/strategy-show-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "goal_uuid": "4690f8ba-18ff-45c1-99e9-159556d23810", 3 | "name": "dummy", 4 | "links": [ 5 | { 6 | "rel": "self", 7 | "href": "http://controller:9322/v1/strategies/e311727b-b9b3-43ef-a5f7-8bd7ea80df25" 8 | }, 9 | { 10 | "rel": "bookmark", 11 | "href": "http://controller:9322/strategies/e311727b-b9b3-43ef-a5f7-8bd7ea80df25" 12 | } 13 | ], 14 | "parameters_spec": { 15 | "properties": { 16 | "para2": { 17 | "default": "hello", 18 | "type": "string", 19 | "description": "string parameter example" 20 | }, 21 | "para1": { 22 | "maximum": 10.2, 23 | "type": "number", 24 | "minimum": 1.0, 25 | "description": "number parameter example", 26 | "default": 3.2 27 | } 28 | } 29 | }, 30 | "uuid": "e311727b-b9b3-43ef-a5f7-8bd7ea80df25", 31 | "goal_name": "dummy", 32 | "display_name": "Dummy strategy" 33 | } -------------------------------------------------------------------------------- /api-ref/source/samples/strategy-state-response.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "state": "gnocchi: available", 4 | "comment": "", 5 | "mandatory": true, 6 | "type": "Datasource" 7 | }, 8 | { 9 | "state": [ 10 | { 11 | "compute.node.cpu.percent": "available" 12 | }, 13 | { 14 | "cpu_util": "available" 15 | }, 16 | { 17 | "memory.resident": "available" 18 | }, 19 | { 20 | "hardware.memory.used": "available" 21 | } 22 | ], 23 | "comment": "", 24 | "mandatory": false, 25 | "type": "Metrics" 26 | }, 27 | { 28 | "state": [ 29 | { 30 | "compute_model": "available" 31 | }, 32 | { 33 | "storage_model": "not available" 34 | }, 35 | { 36 | "baremetal_model": "not available" 37 | } 38 | ], 39 | "comment": "", 40 | "mandatory": true, 41 | "type": "CDM" 42 | }, 43 | { 44 | "state": "workload_stabilization", 45 | "mandatory": "", 46 | "comment": "", 47 | "type": "Name" 48 | } 49 | ] -------------------------------------------------------------------------------- /api-ref/source/watcher-api-v1-webhooks.inc: -------------------------------------------------------------------------------- 1 | .. -*- rst -*- 2 | 3 | ======== 4 | Webhooks 5 | ======== 6 | 7 | .. versionadded:: 1.4 8 | 9 | Triggers an event based Audit. 10 | 11 | 12 | Trigger EVENT Audit 13 | =================== 14 | 15 | .. rest_method:: POST /v1/webhooks/{audit_ident} 16 | 17 | Normal response codes: 202 18 | 19 | Error codes: 400,404 20 | 21 | Request 22 | ------- 23 | 24 | .. rest_parameters:: parameters.yaml 25 | 26 | - audit_ident: audit_ident 27 | -------------------------------------------------------------------------------- /bindep.txt: -------------------------------------------------------------------------------- 1 | # This is a cross-platform list tracking distribution packages needed for install and tests; 2 | # see https://docs.openstack.org/infra/bindep/ for additional information. 3 | 4 | mysql [platform:rpm !platform:redhat test] 5 | mysql-client [platform:dpkg !platform:debian test] 6 | mysql-devel [platform:rpm !platform:redhat test] 7 | mysql-server [!platform:redhat !platform:debian test] 8 | mariadb-devel [platform:rpm platform:redhat test] 9 | mariadb-server [platform:rpm platform:redhat platform:debian test] 10 | python3-all [platform:dpkg test] 11 | python3-all-dev [platform:dpkg test] 12 | python3 [platform:rpm test] 13 | python3-devel [platform:rpm test] 14 | sqlite-devel [platform:rpm test] 15 | -------------------------------------------------------------------------------- /devstack/override-defaults: -------------------------------------------------------------------------------- 1 | # Plug-in overrides 2 | # https://docs.openstack.org/devstack/latest/plugins.html#plugin-interface 3 | 4 | # Enable both versioned and unversioned notifications. Watcher only 5 | # uses versioned notifications but ceilometer uses unversioned. We 6 | # can change this to just versioned when ceilometer handles 7 | # versioned notifications from nova: 8 | # https://bugs.launchpad.net/ceilometer/+bug/1665449 9 | NOVA_NOTIFICATION_FORMAT=both -------------------------------------------------------------------------------- /devstack/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 10s 3 | scrape_configs: 4 | - job_name: "node" 5 | static_configs: 6 | - targets: ["controller:3000"] 7 | - targets: ["controller:9100"] 8 | labels: 9 | fqdn: "controller" # change the hostname here to your controller hostname 10 | - targets: ["compute-1:9100"] 11 | labels: 12 | fqdn: "compute-1" # change the hostname here to your fist compute hostname 13 | - targets: ["compute-2:9100"] 14 | labels: 15 | fqdn: "compute-2" # change the hostname her to your secondd compute hostname 16 | # add as many blocks as compute nodes you have 17 | -------------------------------------------------------------------------------- /devstack/settings: -------------------------------------------------------------------------------- 1 | # DevStack settings 2 | 3 | # Make sure rabbit is enabled 4 | enable_service rabbit 5 | 6 | # Make sure mysql is enabled 7 | enable_service mysql 8 | 9 | # Enable Watcher services 10 | enable_service watcher-api 11 | enable_service watcher-decision-engine 12 | enable_service watcher-applier 13 | -------------------------------------------------------------------------------- /devstack/upgrade/from_rocky/upgrade-watcher: -------------------------------------------------------------------------------- 1 | # ``upgrade-watcher`` 2 | 3 | function configure_watcher_upgrade { 4 | XTRACE=$(set +o | grep xtrace) 5 | set -o xtrace 6 | 7 | # Copy release-specific files 8 | sudo cp $TARGET_RELEASE_DIR/watcher/etc/watcher/watcher.conf $WATCHER_CONF_DIR/watcher.conf 9 | sudo cp $TARGET_RELEASE_DIR/watcher/etc/watcher/policy.yaml.sample $WATCHER_CONF_DIR/policy.yaml.sample 10 | 11 | # reset to previous state 12 | $XTRACE 13 | } 14 | -------------------------------------------------------------------------------- /devstack/upgrade/settings: -------------------------------------------------------------------------------- 1 | register_project_for_upgrade watcher 2 | register_db_to_save watcher 3 | 4 | devstack_localrc base enable_plugin watcher https://opendev.org/openstack/watcher $BASE_DEVSTACK_BRANCH 5 | devstack_localrc target enable_plugin watcher https://opendev.org/openstack/watcher 6 | 7 | devstack_localrc base enable_service watcher-api watcher-decision-engine watcher-applier 8 | devstack_localrc target enable_service watcher-api watcher-decision-engine watcher-applier 9 | 10 | BASE_RUN_SMOKE=False 11 | TARGET_RUN_SMOKE=False 12 | 13 | # Enable both versioned and unversioned notifications. Watcher only 14 | # uses versioned notifications but ceilometer uses unversioned. We 15 | # can change this to just versioned when ceilometer handles 16 | # versioned notifications from nova: 17 | # https://bugs.launchpad.net/ceilometer/+bug/1665449 18 | devstack_localrc base NOVA_NOTIFICATION_FORMAT=both 19 | -------------------------------------------------------------------------------- /devstack/upgrade/shutdown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | 5 | source $GRENADE_DIR/grenaderc 6 | source $GRENADE_DIR/functions 7 | 8 | # We need base DevStack functions for this 9 | source $BASE_DEVSTACK_DIR/functions 10 | source $BASE_DEVSTACK_DIR/stackrc # needed for status directory 11 | source $BASE_DEVSTACK_DIR/lib/tls 12 | source $BASE_DEVSTACK_DIR/lib/apache 13 | 14 | WATCHER_DEVSTACK_DIR=$(dirname $(dirname $0)) 15 | source $WATCHER_DEVSTACK_DIR/settings 16 | source $WATCHER_DEVSTACK_DIR/plugin.sh 17 | source $WATCHER_DEVSTACK_DIR/lib/watcher 18 | 19 | set -o xtrace 20 | 21 | stop_watcher 22 | 23 | # sanity check that service is actually down 24 | ensure_services_stopped watcher-api watcher-decision-engine watcher-applier 25 | -------------------------------------------------------------------------------- /doc/dictionary.txt: -------------------------------------------------------------------------------- 1 | thirdparty 2 | assertin 3 | notin 4 | 5 | -------------------------------------------------------------------------------- /doc/ext/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/ext/__init__.py -------------------------------------------------------------------------------- /doc/notification_samples/infra-optim-exception.json: -------------------------------------------------------------------------------- 1 | { 2 | "event_type": "infra-optim.exception", 3 | "payload": { 4 | "watcher_object.data": { 5 | "exception": "NoAvailableStrategyForGoal", 6 | "exception_message": "No strategy could be found to achieve the server_consolidation goal.", 7 | "function_name": "_aggregate_create_in_db", 8 | "module_name": "watcher.objects.aggregate" 9 | }, 10 | "watcher_object.name": "ExceptionPayload", 11 | "watcher_object.namespace": "watcher", 12 | "watcher_object.version": "1.0" 13 | }, 14 | "priority": "ERROR", 15 | "publisher_id": "watcher-api:fake-mini" 16 | } 17 | -------------------------------------------------------------------------------- /doc/notification_samples/service-update.json: -------------------------------------------------------------------------------- 1 | { 2 | "payload": { 3 | "watcher_object.name": "ServiceUpdatePayload", 4 | "watcher_object.namespace": "watcher", 5 | "watcher_object.data": { 6 | "status_update": { 7 | "watcher_object.name": "ServiceStatusUpdatePayload", 8 | "watcher_object.namespace": "watcher", 9 | "watcher_object.data": { 10 | "old_state": "ACTIVE", 11 | "state": "FAILED" 12 | }, 13 | "watcher_object.version": "1.0" 14 | }, 15 | "last_seen_up": "2016-09-22T08:32:06Z", 16 | "name": "watcher-service", 17 | "sevice_host": "controller" 18 | }, 19 | "watcher_object.version": "1.0" 20 | }, 21 | "event_type": "service.update", 22 | "priority": "INFO", 23 | "message_id": "3984dc2b-8aef-462b-a220-8ae04237a56e", 24 | "timestamp": "2016-10-18 09:52:05.219414", 25 | "publisher_id": "infra-optim:node0" 26 | } -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx>=2.1.1 # BSD 2 | sphinxcontrib-svg2pdfconverter>=0.1.0 # BSD 3 | sphinxcontrib-pecanwsme>=0.8.0 # Apache-2.0 4 | sphinxcontrib-apidoc>=0.2.0 # BSD 5 | # openstack 6 | os-api-ref>=1.4.0 # Apache-2.0 7 | openstackdocstheme>=2.2.1 # Apache-2.0 8 | # releasenotes 9 | reno>=3.1.0 # Apache-2.0 10 | 11 | -------------------------------------------------------------------------------- /doc/source/_static/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/_static/.placeholder -------------------------------------------------------------------------------- /doc/source/admin/index.rst: -------------------------------------------------------------------------------- 1 | =================== 2 | Administrator Guide 3 | =================== 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | apache-mod-wsgi 9 | gmr 10 | policy 11 | ../strategies/index 12 | ../datasources/index 13 | ../contributor/notifications 14 | ../contributor/concurrency 15 | -------------------------------------------------------------------------------- /doc/source/configuration/index.rst: -------------------------------------------------------------------------------- 1 | =================== 2 | Configuration Guide 3 | =================== 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | configuring 9 | watcher 10 | -------------------------------------------------------------------------------- /doc/source/configuration/watcher.rst: -------------------------------------------------------------------------------- 1 | .. _watcher_sample_configuration_files: 2 | 3 | ------------ 4 | watcher.conf 5 | ------------ 6 | 7 | The ``watcher.conf`` file contains most of the options to configure the 8 | Watcher services. 9 | 10 | .. show-options:: 11 | :config-file: etc/watcher/oslo-config-generator/watcher.conf 12 | -------------------------------------------------------------------------------- /doc/source/contributor/api_microversion_history.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../../../watcher/api/controllers/rest_api_version_history.rst 2 | -------------------------------------------------------------------------------- /doc/source/contributor/index.rst: -------------------------------------------------------------------------------- 1 | ================== 2 | Contribution Guide 3 | ================== 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | contributing 9 | environment 10 | devstack 11 | testing 12 | rally_link 13 | -------------------------------------------------------------------------------- /doc/source/contributor/notifications.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Except where otherwise noted, this document is licensed under Creative 3 | Commons Attribution 3.0 License. You can view the license at: 4 | 5 | https://creativecommons.org/licenses/by/3.0/ 6 | 7 | .. _watcher_notifications: 8 | 9 | ======================== 10 | Notifications in Watcher 11 | ======================== 12 | 13 | .. versioned_notifications:: 14 | -------------------------------------------------------------------------------- /doc/source/contributor/plugin/index.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Plugin Guide 3 | ============ 4 | 5 | .. toctree:: 6 | :maxdepth: 1 7 | 8 | base-setup 9 | action-plugin 10 | cdmc-plugin 11 | goal-plugin 12 | planner-plugin 13 | scoring-engine-plugin 14 | strategy-plugin 15 | plugins 16 | -------------------------------------------------------------------------------- /doc/source/contributor/rally_link.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../../../rally-jobs/README.rst 2 | -------------------------------------------------------------------------------- /doc/source/datasources/index.rst: -------------------------------------------------------------------------------- 1 | Datasources 2 | =========== 3 | 4 | .. toctree:: 5 | :glob: 6 | :maxdepth: 1 7 | 8 | ./* 9 | -------------------------------------------------------------------------------- /doc/source/image_src/dia/architecture.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/image_src/dia/architecture.dia -------------------------------------------------------------------------------- /doc/source/image_src/dia/functional_data_model.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/image_src/dia/functional_data_model.dia -------------------------------------------------------------------------------- /doc/source/image_src/plantuml/README.rst: -------------------------------------------------------------------------------- 1 | plantuml 2 | ======== 3 | 4 | 5 | To build an image from a source file, you have to upload the plantuml JAR file 6 | available on http://plantuml.com/download.html. 7 | After, just run this command to build your image: 8 | 9 | .. code-block:: shell 10 | 11 | $ cd doc/source/images 12 | $ java -jar /path/to/plantuml.jar doc/source/image_src/plantuml/my_image.txt 13 | $ ls doc/source/images/ 14 | my_image.png 15 | -------------------------------------------------------------------------------- /doc/source/image_src/plantuml/action_plan_state_machine.txt: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | [*] --> RECOMMENDED: The Watcher Planner\ncreates the Action Plan 4 | RECOMMENDED --> PENDING: Adminisrator launches\nthe Action Plan 5 | PENDING --> ONGOING: The Watcher Applier receives the request\nto launch the Action Plan 6 | ONGOING --> FAILED: Something failed while executing\nthe Action Plan in the Watcher Applier 7 | ONGOING --> SUCCEEDED: The Watcher Applier executed\nthe Action Plan successfully 8 | FAILED --> DELETED : Administrator removes\nAction Plan 9 | SUCCEEDED --> DELETED : Administrator removes\nAction Plan 10 | ONGOING --> CANCELLING : Administrator cancels\nAction Plan 11 | CANCELLING --> CANCELLED : The Watcher Applier cancelled\nthe Action Plan successfully 12 | CANCELLING --> FAILED : Something failed while cancelling\nthe Action Plan in the Watcher Applier 13 | RECOMMENDED --> CANCELLED : Administrator cancels\nAction Plan 14 | RECOMMENDED --> SUPERSEDED : The Watcher Decision Engine supersedes\nAction Plan 15 | PENDING --> CANCELLED : Administrator cancels\nAction Plan 16 | CANCELLED --> DELETED 17 | SUPERSEDED --> DELETED 18 | DELETED --> [*] 19 | 20 | @enduml 21 | -------------------------------------------------------------------------------- /doc/source/image_src/plantuml/audit_state_machine.txt: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | [*] --> PENDING: Audit requested by Administrator 4 | PENDING --> ONGOING: Audit request is received\nby the Watcher Decision Engine 5 | ONGOING --> FAILED: Audit fails\n(Exception occurred) 6 | ONGOING --> SUCCEEDED: The Watcher Decision Engine\ncould find at least one Solution 7 | ONGOING --> SUSPENDED: Administrator wants to\nsuspend the Audit 8 | SUSPENDED --> ONGOING: Administrator wants to\nresume the Audit 9 | FAILED --> DELETED : Administrator wants to\narchive/delete the Audit 10 | SUCCEEDED --> DELETED : Administrator wants to\narchive/delete the Audit 11 | PENDING --> CANCELLED : Administrator cancels\nthe Audit 12 | ONGOING --> CANCELLED : Administrator cancels\nthe Audit 13 | CANCELLED --> DELETED : Administrator wants to\narchive/delete the Audit 14 | SUSPENDED --> DELETED: Administrator wants to\narchive/delete the Audit 15 | DELETED --> [*] 16 | 17 | @enduml 18 | -------------------------------------------------------------------------------- /doc/source/image_src/plantuml/sequence_create_and_launch_audit.txt: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | 4 | actor Administrator 5 | 6 | Administrator -> "Watcher CLI" : watcher audit create -a 7 | 8 | "Watcher CLI" -> "Watcher API" : POST audit(parameters) 9 | "Watcher API" -> "Watcher Database" : create new audit in database (status=PENDING) 10 | 11 | "Watcher API" <-- "Watcher Database" : new audit uuid 12 | "Watcher CLI" <-- "Watcher API" : return new audit URL 13 | 14 | Administrator <-- "Watcher CLI" : new audit uuid 15 | 16 | "Watcher API" -> "AMQP Bus" : trigger_audit(new_audit.uuid) 17 | "AMQP Bus" -> "Watcher Decision Engine" : trigger_audit(new_audit.uuid) (status=ONGOING) 18 | 19 | ref over "Watcher Decision Engine" 20 | Trigger audit in the 21 | Watcher Decision Engine 22 | end ref 23 | 24 | @enduml 25 | -------------------------------------------------------------------------------- /doc/source/image_src/plantuml/sequence_create_audit_template.txt: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | actor Administrator 4 | 5 | Administrator -> "Watcher CLI" : watcher audittemplate create \ 6 | [--strategy-uuid ] 7 | "Watcher CLI" -> "Watcher API" : POST audit_template(parameters) 8 | 9 | "Watcher API" -> "Watcher Database" : Request if goal exists in database 10 | "Watcher API" <-- "Watcher Database" : OK 11 | 12 | "Watcher API" -> "Watcher Database" : Request if strategy exists in database (if provided) 13 | "Watcher API" <-- "Watcher Database" : OK 14 | 15 | "Watcher API" -> "Watcher Database" : Create new audit_template in database 16 | "Watcher API" <-- "Watcher Database" : New audit template UUID 17 | 18 | "Watcher CLI" <-- "Watcher API" : Return new audit template URL in HTTP Location Header 19 | Administrator <-- "Watcher CLI" : New audit template UUID 20 | 21 | @enduml 22 | 23 | -------------------------------------------------------------------------------- /doc/source/image_src/plantuml/sequence_launch_action_plan.txt: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | actor Administrator 4 | 5 | Administrator -> "Watcher CLI" : watcher actionplan start 6 | 7 | "Watcher CLI" -> "Watcher API" : PATCH action_plan(state=PENDING) 8 | "Watcher API" -> "Watcher Database" : action_plan.state=PENDING 9 | 10 | "Watcher CLI" <-- "Watcher API" : HTTP 200 11 | 12 | Administrator <-- "Watcher CLI" : OK 13 | 14 | "Watcher API" -> "AMQP Bus" : launch_action_plan(action_plan.uuid) 15 | "AMQP Bus" -> "Watcher Applier" : launch_action_plan(action_plan.uuid) 16 | 17 | ref over "Watcher Applier" 18 | Launch Action Plan in the 19 | Watcher Applier 20 | end ref 21 | 22 | @enduml 23 | 24 | -------------------------------------------------------------------------------- /doc/source/images/action_plan_state_machine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/images/action_plan_state_machine.png -------------------------------------------------------------------------------- /doc/source/images/audit_state_machine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/images/audit_state_machine.png -------------------------------------------------------------------------------- /doc/source/images/sequence_architecture_cdmc_sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/images/sequence_architecture_cdmc_sync.png -------------------------------------------------------------------------------- /doc/source/images/sequence_create_and_launch_audit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/images/sequence_create_and_launch_audit.png -------------------------------------------------------------------------------- /doc/source/images/sequence_create_audit_template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/images/sequence_create_audit_template.png -------------------------------------------------------------------------------- /doc/source/images/sequence_from_audit_execution_to_actionplan_creation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/images/sequence_from_audit_execution_to_actionplan_creation.png -------------------------------------------------------------------------------- /doc/source/images/sequence_launch_action_plan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/images/sequence_launch_action_plan.png -------------------------------------------------------------------------------- /doc/source/images/sequence_launch_action_plan_in_applier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/images/sequence_launch_action_plan_in_applier.png -------------------------------------------------------------------------------- /doc/source/images/sequence_overview_watcher_usage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/images/sequence_overview_watcher_usage.png -------------------------------------------------------------------------------- /doc/source/images/sequence_trigger_audit_in_decision_engine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/images/sequence_trigger_audit_in_decision_engine.png -------------------------------------------------------------------------------- /doc/source/images/watcher_db_schema_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/doc/source/images/watcher_db_schema_diagram.png -------------------------------------------------------------------------------- /doc/source/install/get_started.rst: -------------------------------------------------------------------------------- 1 | ============================================ 2 | Infrastructure Optimization service overview 3 | ============================================ 4 | The Infrastructure Optimization service provides flexible and scalable 5 | optimization service for multi-tenant OpenStack based clouds. 6 | 7 | The Infrastructure Optimization service consists of the following components: 8 | 9 | ``watcher`` command-line client 10 | A CLI to communicate with ``watcher-api`` to optimize the cloud. 11 | 12 | ``watcher-api`` service 13 | An OpenStack-native REST API that accepts and responds to end-user calls 14 | by processing them and forwarding to appropriate underlying watcher 15 | services via AMQP. 16 | 17 | ``watcher-decision-engine`` service 18 | It runs audit and return an action plan to achieve optimization goal 19 | specified by the end-user in audit. 20 | 21 | ``watcher-applier`` service 22 | It executes action plan built by watcher-decision-engine. It interacts with 23 | other OpenStack components like nova to execute the given action 24 | plan. 25 | 26 | ``watcher-dashboard`` 27 | Watcher UI implemented as a plugin for the OpenStack Dashboard. 28 | -------------------------------------------------------------------------------- /doc/source/install/install-rdo.rst: -------------------------------------------------------------------------------- 1 | .. _install-rdo: 2 | 3 | Install and configure for Red Hat Enterprise Linux and CentOS 4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 | 6 | 7 | This section describes how to install and configure the Infrastructure 8 | Optimization service for Red Hat Enterprise Linux 7 and CentOS 7. 9 | 10 | .. include:: common_prerequisites.rst 11 | 12 | Install and configure components 13 | -------------------------------- 14 | 15 | 1. Install the packages: 16 | 17 | .. code-block:: console 18 | 19 | # sudo yum install openstack-watcher-api openstack-watcher-applier \ 20 | openstack-watcher-decision-engine 21 | 22 | .. include:: common_configure.rst 23 | 24 | Finalize installation 25 | --------------------- 26 | 27 | Start the Infrastructure Optimization services and configure them to start when 28 | the system boots: 29 | 30 | .. code-block:: console 31 | 32 | # systemctl enable openstack-watcher-api.service \ 33 | openstack-watcher-decision-engine.service \ 34 | openstack-watcher-applier.service 35 | 36 | # systemctl start openstack-watcher-api.service \ 37 | openstack-watcher-decision-engine.service \ 38 | openstack-watcher-applier.service 39 | -------------------------------------------------------------------------------- /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 Infrastructure 7 | Optimization service for Ubuntu 16.04 (LTS). 8 | 9 | .. include:: common_prerequisites.rst 10 | 11 | Install and configure components 12 | -------------------------------- 13 | 14 | 1. Install the packages: 15 | 16 | .. code-block:: console 17 | 18 | # apt install watcher-api watcher-decision-engine \ 19 | watcher-applier 20 | 21 | # apt install python-watcherclient 22 | 23 | .. include:: common_configure.rst 24 | 25 | Finalize installation 26 | --------------------- 27 | 28 | Start the Infrastructure Optimization services and configure them to start when 29 | the system boots: 30 | 31 | .. code-block:: console 32 | 33 | # systemctl enable watcher-api.service \ 34 | watcher-decision-engine.service \ 35 | watcher-applier.service 36 | 37 | # systemctl start watcher-api.service \ 38 | watcher-decision-engine.service \ 39 | watcher-applier.service 40 | -------------------------------------------------------------------------------- /doc/source/install/install.rst: -------------------------------------------------------------------------------- 1 | .. _install: 2 | 3 | Install and configure 4 | ~~~~~~~~~~~~~~~~~~~~~ 5 | 6 | This section describes how to install and configure the Infrastructure 7 | Optimization service, code-named watcher, 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 | Identity Service, Compute Service, Telemetry data collection service. 12 | 13 | Note that installation and configuration vary by distribution. 14 | 15 | .. toctree:: 16 | :maxdepth: 2 17 | 18 | install-rdo.rst 19 | install-ubuntu.rst 20 | -------------------------------------------------------------------------------- /doc/source/install/next-steps.rst: -------------------------------------------------------------------------------- 1 | .. _next-steps: 2 | 3 | Next steps 4 | ~~~~~~~~~~ 5 | 6 | Your OpenStack environment now includes the watcher service. 7 | 8 | To add additional services, see 9 | https://docs.openstack.org/queens/install/. 10 | -------------------------------------------------------------------------------- /doc/source/man/footer.rst: -------------------------------------------------------------------------------- 1 | BUGS 2 | ==== 3 | 4 | * Watcher bugs are tracked in Launchpad at `OpenStack Watcher 5 | `__ 6 | -------------------------------------------------------------------------------- /doc/source/man/index.rst: -------------------------------------------------------------------------------- 1 | ==================== 2 | Watcher Manual Pages 3 | ==================== 4 | 5 | .. toctree:: 6 | :glob: 7 | :maxdepth: 1 8 | 9 | watcher-api 10 | watcher-applier 11 | watcher-db-manage 12 | watcher-decision-engine 13 | watcher-status 14 | -------------------------------------------------------------------------------- /doc/source/man/watcher-api.rst: -------------------------------------------------------------------------------- 1 | =========== 2 | watcher-api 3 | =========== 4 | 5 | --------------------------- 6 | Service for the Watcher API 7 | --------------------------- 8 | 9 | :Author: openstack@lists.launchpad.net 10 | :Copyright: OpenStack Foundation 11 | :Manual section: 1 12 | :Manual group: cloud computing 13 | 14 | SYNOPSIS 15 | ======== 16 | 17 | watcher-api [options] 18 | 19 | DESCRIPTION 20 | =========== 21 | 22 | watcher-api is a server daemon that serves the Watcher API 23 | 24 | OPTIONS 25 | ======= 26 | 27 | **General options** 28 | 29 | .. include:: general-options.rst 30 | 31 | FILES 32 | ===== 33 | 34 | **/etc/watcher/watcher.conf** 35 | Default configuration file for Watcher API 36 | 37 | .. include:: footer.rst 38 | -------------------------------------------------------------------------------- /doc/source/man/watcher-applier.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | watcher-applier 3 | =============== 4 | 5 | ------------------------------- 6 | Service for the Watcher Applier 7 | ------------------------------- 8 | 9 | :Author: openstack@lists.launchpad.net 10 | :Copyright: OpenStack Foundation 11 | :Manual section: 1 12 | :Manual group: cloud computing 13 | 14 | SYNOPSIS 15 | ======== 16 | 17 | watcher-applier [options] 18 | 19 | DESCRIPTION 20 | =========== 21 | 22 | :ref:`Watcher Applier ` 23 | 24 | OPTIONS 25 | ======= 26 | 27 | **General options** 28 | 29 | .. include:: general-options.rst 30 | 31 | FILES 32 | ===== 33 | 34 | **/etc/watcher/watcher.conf** 35 | Default configuration file for Watcher Applier 36 | 37 | .. include:: footer.rst 38 | -------------------------------------------------------------------------------- /doc/source/man/watcher-decision-engine.rst: -------------------------------------------------------------------------------- 1 | ======================= 2 | watcher-decision-engine 3 | ======================= 4 | 5 | --------------------------------------- 6 | Service for the Watcher Decision Engine 7 | --------------------------------------- 8 | 9 | :Author: openstack@lists.launchpad.net 10 | :Copyright: OpenStack Foundation 11 | :Manual section: 1 12 | :Manual group: cloud computing 13 | 14 | SYNOPSIS 15 | ======== 16 | 17 | watcher-decision-engine [options] 18 | 19 | DESCRIPTION 20 | =========== 21 | 22 | :ref:`Watcher Decision Engine ` 23 | 24 | OPTIONS 25 | ======= 26 | 27 | **General options** 28 | 29 | .. include:: general-options.rst 30 | 31 | FILES 32 | ===== 33 | 34 | **/etc/watcher/watcher.conf** 35 | Default configuration file for Watcher Decision Engine 36 | 37 | .. include:: footer.rst 38 | -------------------------------------------------------------------------------- /doc/source/strategies/index.rst: -------------------------------------------------------------------------------- 1 | Strategies 2 | ========== 3 | 4 | .. toctree:: 5 | :glob: 6 | :maxdepth: 1 7 | 8 | ./* 9 | -------------------------------------------------------------------------------- /doc/source/user/index.rst: -------------------------------------------------------------------------------- 1 | ========== 2 | User Guide 3 | ========== 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | ways-to-install 9 | user-guide 10 | event_type_audit 11 | -------------------------------------------------------------------------------- /etc/apache2/watcher: -------------------------------------------------------------------------------- 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 | # This is an example Apache2 configuration file for using 14 | # Watcher API through mod_wsgi 15 | Listen 9322 16 | 17 | 18 | WSGIDaemonProcess watcher-api user=stack group=stack processes=2 threads=2 display-name=%{GROUP} 19 | WSGIScriptAlias / /usr/local/bin/watcher-api-wsgi 20 | WSGIProcessGroup watcher-api 21 | 22 | ErrorLog /var/log/httpd/watcher_error.log 23 | LogLevel info 24 | CustomLog /var/log/httpd/watcher_access.log combined 25 | 26 | 27 | WSGIProcessGroup watcher-api 28 | WSGIApplicationGroup %{GLOBAL} 29 | AllowOverride All 30 | Require all granted 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /etc/watcher/README-watcher.conf.txt: -------------------------------------------------------------------------------- 1 | To generate the sample watcher.conf file, run the following 2 | command from the top level of the watcher directory: 3 | 4 | tox -e genconfig 5 | -------------------------------------------------------------------------------- /etc/watcher/oslo-config-generator/watcher.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | output_file = etc/watcher/watcher.conf.sample 3 | wrap_width = 79 4 | 5 | namespace = watcher 6 | namespace = keystonemiddleware.auth_token 7 | namespace = oslo.cache 8 | namespace = oslo.concurrency 9 | namespace = oslo.db 10 | namespace = oslo.log 11 | namespace = oslo.messaging 12 | namespace = oslo.policy 13 | namespace = oslo.reports 14 | namespace = oslo.service.periodic_task 15 | namespace = oslo.service.service 16 | namespace = oslo.service.wsgi 17 | -------------------------------------------------------------------------------- /etc/watcher/oslo-policy-generator/watcher-policy-generator.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | output_file = /etc/watcher/policy.yaml.sample 3 | namespace = watcher 4 | -------------------------------------------------------------------------------- /playbooks/generate_prometheus_config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | tasks: 4 | - name: Generate prometheus.yml config file 5 | delegate_to: controller 6 | template: 7 | src: "templates/prometheus.yml.j2" 8 | dest: "/home/zuul/prometheus.yml" 9 | mode: "0644" 10 | -------------------------------------------------------------------------------- /playbooks/templates/prometheus.yml.j2: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 10s 3 | scrape_configs: 4 | - job_name: "node" 5 | static_configs: 6 | - targets: ["localhost:3000"] 7 | {% if 'compute' in groups %} 8 | {% for host in groups['compute'] %} 9 | - targets: ["{{ hostvars[host]['ansible_fqdn'] }}:9100"] 10 | labels: 11 | fqdn: "{{ hostvars[host]['ansible_fqdn'] }}" 12 | {% endfor %} 13 | {% endif %} 14 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["pbr>=6.0.0", "setuptools>=64.0.0"] 3 | build-backend = "pbr.build" 4 | -------------------------------------------------------------------------------- /releasenotes/notes/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/releasenotes/notes/.placeholder -------------------------------------------------------------------------------- /releasenotes/notes/action-plan-cancel-c54726378019e096.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Adds feature to cancel an action-plan. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/action-plan-versioned-notifications-api-e8ca4f5d37aa5b4b.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Add notifications related to Action plan object. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/action-versioned-notifications-api-ff94fc0f401292d0.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Add notifications related to Action object. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/add-baremetal-scoper-9ef23f5fb8f0be6a.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Baremetal Model gets Audit scoper with an ability to exclude Ironic nodes. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/add-force-field-to-audit-4bcaeedfe27233ad.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Add force field to Audit. User can set --force to enable the new option when 5 | launching audit. If force is True, audit will be executed despite of ongoing 6 | actionplan. The new audit may create a wrong actionplan if they use the same 7 | data model. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/add-ha-support-b9042255e5b76e42.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Watcher services can be launched in HA mode. From now on Watcher Decision 4 | Engine and Watcher Applier services may be deployed on different nodes to 5 | run in active-active or active-passive mode. Any ONGOING Audits or Action Plans 6 | will be CANCELLED if service they are executed on is restarted. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/add-instance-metrics-to-prometheus-datasource-9fba8c174ff845e1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Support for instance metrics has been added to the prometheus data source. 5 | The included metrics are `instance_cpu_usage`, `instance_ram_usage`, 6 | `instance_ram_allocated` and `instance_root_disk_size`. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/add-name-for-audit-0df1f39f00736f06.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Audits have 'name' field now, that is more friendly to end users. 4 | Audit's name can't exceed 63 characters. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/add-plugins-parameters-376eb6b0b8978b44.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added a standard way to both declare and fetch 4 | configuration options so that whenever the 5 | administrator generates the Watcher 6 | configuration sample file, it contains the 7 | configuration options of the plugins that are 8 | currently available. 9 | -------------------------------------------------------------------------------- /releasenotes/notes/add-power-on-off-a77673d482568a8b.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Add action for compute node power on/off 4 | -------------------------------------------------------------------------------- /releasenotes/notes/add-scoring-module-fa00d013ed2d614e.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added a generic scoring engine module, which 4 | will standardize interactions with scoring engines 5 | through the common API. It is possible to use the 6 | scoring engine by different Strategies, which 7 | improve the code and data model reuse. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/add-start-end-time-for-continuous-audit-52c45052cb06d153.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Add start_time and end_time fields in audits table. User can set the start 5 | time and/or end time when creating CONTINUOUS audit. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/add-upgrade-check-framework-5bb9693c8a78931c.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | prelude: > 3 | Added new tool ``watcher-status upgrade check``. 4 | features: 5 | - | 6 | New framework for ``watcher-status upgrade check`` command is added. 7 | This framework allows adding various checks which can be run before a 8 | Watcher upgrade to ensure if the upgrade can be performed safely. 9 | upgrade: 10 | - | 11 | Operator can now use new CLI tool ``watcher-status upgrade check`` 12 | to check if Watcher deployment can be safely upgraded from 13 | N-1 to N release. 14 | -------------------------------------------------------------------------------- /releasenotes/notes/add-wsgi-module-support-597f479e31979270.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | A new module, ``watcher.wsgi``, has been added as a place to gather WSGI 5 | ``application`` objects. This is intended to ease deployment by providing 6 | a consistent location for these objects. For example, if using uWSGI then 7 | instead of: 8 | 9 | .. code-block:: ini 10 | 11 | [uwsgi] 12 | wsgi-file = /bin/watcher-api-wsgi 13 | 14 | You can now use: 15 | 16 | .. code-block:: ini 17 | 18 | [uwsgi] 19 | module = watcher.wsgi.api:application 20 | 21 | This also simplifies deployment with other WSGI servers that expect module 22 | paths such as gunicorn. 23 | deprecations: 24 | - | 25 | The watcher-api-wsgi console script is deprecated for removal 26 | in a future release. This artifact is generated using a setup-tools 27 | extension that is provide by PBR which is also deprecated. 28 | due to the changes in python packaging this custom extensions 29 | is planned to be removed form all OpenStack projects in a future 30 | PBR release in favor of module based wsgi applications entry points. 31 | -------------------------------------------------------------------------------- /releasenotes/notes/api-call-retry-fef741ac684c58dd.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | API calls while building the Compute data model will be retried upon 5 | failure. The amount of failures allowed before giving up and the time before 6 | reattempting are configurable. The `api_call_retries` and 7 | `api_query_timeout` parameters in the `[collector]` group can be used to 8 | adjust these parameters. 10 retries with a 1 second time in between 9 | reattempts is the default. 10 | -------------------------------------------------------------------------------- /releasenotes/notes/api-microversioning-7999a3ee8073bf32.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | Watcher starts to support API microversions since Stein cycle. From now 4 | onwards all API changes should be made with saving backward compatibility. 5 | To specify API version operator should use OpenStack-API-Version 6 | HTTP header. If operator wants to know the minimum and maximum supported 7 | versions by API, he/she can access /v1 resource and Watcher API will 8 | return appropriate headers in response. 9 | -------------------------------------------------------------------------------- /releasenotes/notes/audit-scoper-for-storage-data-model-cdccc803542d22db.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Adds audit scoper for storage data model, now watcher users can specify 5 | audit scope for storage CDM in the same manner as compute scope. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/audit-tag-vm-metadata-47a3e4468748853c.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added the functionality to filter out instances which have metadata field 4 | 'optimize' set to False. For now, this is only available for the 5 | basic_consolidation strategy (if "check_optimize_metadata" configuration 6 | option is enabled). 7 | -------------------------------------------------------------------------------- /releasenotes/notes/audit-versioned-notifications-api-bca7738e16954bad.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Add notifications related to Audit object. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/automatic-triggering-audit-8a9b0540d547db60.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Watcher can continuously optimize the OpenStack cloud for a specific 4 | strategy or goal by triggering an audit periodically which generates 5 | an action plan and run it automatically. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/background-jobs-ha-9d3cf3fe356f4705.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added binding between apscheduler job and Watcher decision engine service. 4 | It will allow to provide HA support in the future. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/bp-audit-scope-exclude-project-511a7720aac00dff.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Feature to exclude instances from audit scope based on project_id is added. 5 | Now instances from particular project in OpenStack can be excluded from audit 6 | defining scope in audit templates. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/bug-2103451-fixes-prometheus-queries-with-multiple-target-0e65d20711d1abe2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | When using prometheus datasource and more that one target has the same value 5 | for the ``fqdn_label``, the driver used the wrong instance label to query for host 6 | metrics. The ``instance`` label is no longer used in the queries but the ``fqdn_label`` 7 | which identifies all the metrics for a specific compute node. 8 | see Bug 2103451: https://bugs.launchpad.net/watcher/+bug/2103451 for more info. 9 | -------------------------------------------------------------------------------- /releasenotes/notes/bug-2109494-e5bf401767fa6cd6.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | The default value of ``[keystone_client] interface`` has been changed from 5 | ``admin`` to ``public``. 6 | fixes: 7 | - | 8 | When trying to do volume migration using the zone migration strategy, the 9 | keystone service is reached, by default through the admin endpoint. 10 | The default value of ``[keystone_client] interface`` has been fixed. 11 | see Bug https://bugs.launchpad.net/watcher/+bug/2109494 for more info. 12 | -------------------------------------------------------------------------------- /releasenotes/notes/build-baremetal-data-model-in-watcher-3023453a47b61dab.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Adds baremetal data model in Watcher 5 | -------------------------------------------------------------------------------- /releasenotes/notes/cdm-scoping-8d9c307bad46bfa1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Each CDM collector can have its own CDM scoper now. This changed Scope 5 | JSON schema definition for the audit template POST data. Please see audit 6 | template create help message in python-watcherclient. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/centralise-config-opts-95670987dfbdb0e7.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Centralize all configuration options for Watcher. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/change-ram-util-metric-4a3e6984b9dd968d.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Enhancement of vm_workload_consolidation strategy 4 | by using 'memory.resident' metric in place of 5 | 'memory.usage', as memory.usage shows the memory 6 | usage inside guest-os and memory.resident 7 | represents volume of RAM used by instance 8 | on host machine. 9 | -------------------------------------------------------------------------------- /releasenotes/notes/check-strategy-requirements-66f9e9262412f8ec.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added a way to check state of strategy before audit's execution. 4 | Administrator can use "watcher strategy state " command 5 | to get information about metrics' availability, datasource's availability 6 | and CDM's availability. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/cinder-model-integration-baa394a72a0a33bf.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Added cinder cluster data model 5 | -------------------------------------------------------------------------------- /releasenotes/notes/cluster-model-objects-wrapper-9c799ea262c56a5b.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added an in-memory cache of the cluster model 4 | built up and kept fresh via notifications from 5 | services of interest in addition to periodic 6 | syncing logic. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/compute-cdm-include-all-instances-f7506ded2d57732f.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Watcher has a whole scope of the cluster, when building 4 | compute CDM which includes all instances. 5 | It filters excluded instances when migration during the 6 | audit. -------------------------------------------------------------------------------- /releasenotes/notes/configurable-weights-default-planner-3746b33160bc7347.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added a way to add a new action without having to 4 | amend the source code of the default planner. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/consume-nova-versioned-notifications-f98361b37e546b4d.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Watcher consumes Nova notifications to update its internal 5 | Compute CDM(Cluster Data Model). 6 | All the notifications as below 7 | 8 | pre-existing: 9 | 10 | * service.update 11 | 12 | * instance.update 13 | 14 | * instance.delete.end 15 | 16 | new: 17 | 18 | * instance.lock 19 | 20 | * instance.unlock 21 | 22 | * instance.pause.end 23 | 24 | * instance.power_off.end 25 | 26 | * instance.power_on.end 27 | 28 | * instance.resize_confirm.end 29 | 30 | * instance.restore.end 31 | 32 | * instance.resume.end 33 | 34 | * instance.shelve.end 35 | 36 | * instance.shutdown.end 37 | 38 | * instance.suspend.end 39 | 40 | * instance.unpause.end 41 | 42 | * instance.unrescue.end 43 | 44 | * instance.unshelve.end 45 | 46 | * instance.rebuild.end 47 | 48 | * instance.rescue.end 49 | 50 | * instance.create.end 51 | 52 | * instance.live_migration_force_complete.end 53 | 54 | * instance.live_migration_post_dest.end 55 | 56 | * instance.soft_delete.end 57 | 58 | * service.create 59 | 60 | * service.delete 61 | -------------------------------------------------------------------------------- /releasenotes/notes/continuously-optimization-35364f4d2c0b81fc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added a way to create periodic audit to be able to 4 | optimize continuously the cloud infrastructure. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/cron-based-continuous-audits-c3eedf28d9752b37.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - There is new ability to create Watcher continuous audits with cron 4 | interval. It means you may use, for example, optional argument 5 | '--interval "\*/5 \* \* \* \*"' to launch audit every 5 minutes. 6 | These jobs are executed on a best effort basis and therefore, we 7 | recommend you to use a minimal cron interval of at least one minute. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/datasource-query-retry-00cba5f7e68aec39.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | All datasources can now be configured to retry retrieving a metric upon 5 | encountering an error. Between each attempt will be a set amount of time 6 | which can be adjusted from the configuration. These configuration 7 | options can be found in the `[watcher_datasources]` group and are named 8 | `query_max_retries` and `query_timeout`. 9 | upgrade: 10 | - | 11 | If Gnocchi was configured to have a custom amount of retries and or a 12 | custom timeout then the configuration needs to moved into the 13 | `[watcher_datasources]` group instead of the `[gnocchi_client]` group. 14 | deprecations: 15 | - | 16 | The configuration options for query retries in `[gnocchi_client]` are 17 | deprecated and the option in `[watcher_datasources]` should now be used. -------------------------------------------------------------------------------- /releasenotes/notes/db-migration-e1a705a8b54ccdd2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Watcher database can now be upgraded thanks to Alembic. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/define-the-audit-scope-e89edc5051dcf3f2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Provides a generic way to define the scope of an audit. The set of audited 4 | resources will be called "Audit scope" and will be defined in each audit 5 | template (which contains the audit settings). 6 | -------------------------------------------------------------------------------- /releasenotes/notes/deprecate-ceilometer-datasource-446b0be70fbce28b.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | Ceilometer Datasource has been deprecated since its API has been 5 | deprecated in Ocata cycle. Watcher has supported Ceilometer for some 6 | releases after Ocata to let users migrate to Gnocchi/Monasca datasources. 7 | Since Train release, Ceilometer support will be removed. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/deprecate-json-formatted-policy-file-3a92379e9f5dd203.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-monasca-ds-9065f4d4bee09ab2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | Monasca Data Source is deprecated and will be removed in the future, due 5 | to inactivity of Monasca project. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/deprecate-noisy-neighbor-strat-7da910837ae8fa80.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | Noisy Neighbor strategy is deprecated and will be removed in a future release. 5 | This strategy relies on Last Level Cache metrics that are not available in Nova 6 | since `Victoria release `_. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/donot-run-host-migration-strategy-on-disabled-hosts-24084a22d4c8f914.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | Host maintenance strategy should migrate servers based on backup node if specified 5 | or rely on nova scheduler. It was enabling disabled hosts with watcher_disabled 6 | reason and migrating servers to those nodes. It can impact customer workload. Compute 7 | nodes were disabled for a reason. 8 | 9 | Host maintenance strategy is fixed now to support migrating servers only on backup 10 | node or rely on nova scheduler if no backup node is provided. 11 | -------------------------------------------------------------------------------- /releasenotes/notes/drop-py-2-7-54f8e806d71f19a7.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Python 2.7 support has been dropped. Last release of Watcher 5 | to support py2.7 is OpenStack Train. The minimum version of Python now 6 | supported by Watcher is Python 3.6. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/drop-python38-support-eeb19a0bc0160sw1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Python 3.8 support has been dropped. Last release of watcher 5 | supporting python 3.8 is 13.0.0. 6 | The minimum version of Python now supported is Python 3.9. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/dynamic-action-description-0e947b9e7ef2a134.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Add description property for dynamic action. Admin can see detail information 4 | of any specify action. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/efficacy-indicator-95380ad7b84e3be2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added a way to compare the efficacy of different 4 | strategies for a give optimization goal. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/enhance-watcher-applier-engine-86c676ce8f179e68.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Added a new config option 'action_execution_rule' which is a dict type. 5 | Its key field is strategy name and the value is 'ALWAYS' or 'ANY'. 6 | 'ALWAYS' means the callback function returns True as usual. 7 | 'ANY' means the return depends on the result of previous action execution. 8 | The callback returns True if previous action gets failed, and the engine 9 | continues to run the next action. If previous action executes success, 10 | the callback returns False then the next action will be ignored. 11 | For strategies that aren't in 'action_execution_rule', the callback always 12 | returns True. 13 | Please add the next section in the watcher.conf file 14 | if your strategy needs this feature. 15 | [watcher_workflow_engines.taskflow] 16 | action_execution_rule = {'your strategy name': 'ANY'} 17 | -------------------------------------------------------------------------------- /releasenotes/notes/event-driven-optimization-based-4870f112bef8a560.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Add a new webhook API and a new audit type EVENT, the microversion is 1.4. 5 | Now Watcher user can create audit with EVENT type and the audit will be 6 | triggered by webhook API. 7 | The user guide is available online: 8 | https://docs.openstack.org/watcher/latest/user/event_type_audit.html 9 | -------------------------------------------------------------------------------- /releasenotes/notes/file-based-metric-map-c2af62b5067895df.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Allow using file to override metric map. Override the metric map of 5 | each datasource as soon as it is created by the manager. This override 6 | comes from a file whose path is provided by a setting in config file. 7 | The setting is `watcher_decision_engine/metric_map_path`. The file 8 | contains a map per datasource whose keys are the metric names as 9 | recognized by watcher and the value is the real name of the metric 10 | in the datasource. This setting defaults to `/etc/watcher/metric_map.yaml`, 11 | and presence of this file is optional. 12 | -------------------------------------------------------------------------------- /releasenotes/notes/fix-action-plan-state-on-failure-69e498d902ada5c5.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | Previously, if an action failed in an action plan, the state of the 5 | action plan was reported as SUCCEEDED if the execution of the action has 6 | finished regardless of the outcome. 7 | 8 | Watcher will now reflect the actual state of all the actions in the plan 9 | after the execution has finished. If any action has status FAILED, it 10 | will set the state of the action plan as FAILED. This is the expected 11 | behavior according to Watcher documentation. 12 | 13 | For more info see: https://bugs.launchpad.net/watcher/+bug/2106407 14 | -------------------------------------------------------------------------------- /releasenotes/notes/formal-datasource-interface-implementation-222769d55a127d33.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Improved interface for datasource baseclass that better defines expected 5 | values and types for parameters and return types of all abstract methods. 6 | This allows all strategies to work with every datasource provided the 7 | metrics are configured for that given datasource. 8 | deprecations: 9 | - | 10 | The new strategy baseclass has significant changes in method parameters 11 | and any out-of-tree strategies will have to be adopted. 12 | - | 13 | Several strategies have changed the `node` parameter to `compute_node` to 14 | be better aligned with terminology. These strategies include 15 | `basic_consolidation` and `workload_stabilzation`. The `node` parameter 16 | will remain supported during Train release and will be removed in the 17 | subsequent release. 18 | -------------------------------------------------------------------------------- /releasenotes/notes/general-purpose-decision-engine-threadpool-0711b23abfc9d409.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | prelude: > 3 | Many operations in the decision engine will block on I/O. Such I/O 4 | operations can stall the execution of a sequential application 5 | significantly. To reduce the potential bottleneck of many operations 6 | the general purpose decision engine threadpool is introduced. 7 | features: 8 | - | 9 | A new threadpool for the decision engine that contributors can use to 10 | improve the performance of many operations, primarily I/O bound ones. 11 | The amount of workers used by the decision engine threadpool can be 12 | configured to scale according to the available infrastructure using 13 | the `watcher_decision_engine.max_general_workers` config option. 14 | Documentation for contributors to effectively use this threadpool is 15 | available online: 16 | https://docs.openstack.org/watcher/latest/contributor/concurrency.html 17 | - | 18 | The building of the compute (Nova) data model will be done using the 19 | decision engine threadpool, thereby, significantly reducing the total 20 | time required to build it. 21 | -------------------------------------------------------------------------------- /releasenotes/notes/get-goal-from-strategy-396c9b13a38bb650.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added a way to return the of available goals depending 4 | on which strategies have been deployed on the node 5 | where the decision engine is running. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/global-datasource-preference-3ab47b4be09ff3a5.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Watcher now supports configuring which datasource to use and in which 5 | order. This configuration is done by specifying datasources in the 6 | watcher_datasources section: 7 | 8 | - ``[watcher_datasources] datasources = gnocchi,monasca,ceilometer`` 9 | 10 | Specific strategies can override this order and use datasources which 11 | are not listed in the global preference. -------------------------------------------------------------------------------- /releasenotes/notes/gnocchi-watcher-43c25d391fbd3e9c.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added gnocchi support as data source for metrics. Administrator can change 4 | data source for each strategy using config file. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/grafana-datasource-b672367c23ffa0c6.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Grafana has been added as datasource that can be used for collecting 5 | metrics. The configuration options allow to specify what metrics and how 6 | they are stored in grafana so that no matter how Grafana is configured it 7 | can still be used. The configuration can be done via the typical 8 | configuration file but it is recommended to configure most options in the 9 | yaml file for metrics. For a complete walkthrough on configuring Grafana 10 | see: https://docs.openstack.org/watcher/latest/datasources/grafana.html -------------------------------------------------------------------------------- /releasenotes/notes/graph-based-cluster-model-523937a6f5e66537.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - The graph model describes how VMs are associated to compute hosts. 4 | This allows for seeing relationships upfront between the entities and hence 5 | can be used to identify hot/cold spots in the data center and influence 6 | a strategy decision. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/host-maintenance-strategy-41f640927948fb56.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Added a strategy for one compute node maintenance, 5 | without having the user's application been interrupted. 6 | If given one backup node, the strategy will firstly 7 | migrate all instances from the maintenance node to 8 | the backup node. If the backup node is not provided, 9 | it will migrate all instances, relying on nova-scheduler. 10 | -------------------------------------------------------------------------------- /releasenotes/notes/improve-compute-data-model-b427c85e4ed2b6fb.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Watcher can get resource information such as total, allocation ratio and 5 | reserved information from Placement API. 6 | Now we add some new fields to the Watcher Data Model: 7 | 8 | * vcpu_reserved: The amount of cpu a node has reserved for its own use. 9 | * vcpu_ratio: CPU allocation ratio. 10 | * memory_mb_reserved: The amount of memory a node has reserved for 11 | its own use. 12 | * memory_ratio: Memory allocation ratio. 13 | * disk_gb_reserved: The amount of disk a node has reserved for its own use. 14 | * disk_ratio: Disk allocation ratio. 15 | 16 | We also add some new properties: 17 | 18 | * vcpu_capacity: The amount of vcpu, take allocation ratio into account, 19 | but do not include reserved. 20 | * memory_mb_capacity: The amount of memory, take allocation ratio into 21 | account, but do not include reserved. 22 | * disk_gb_capacity: The amount of disk, take allocation ratio into 23 | account, but do not include reserved. 24 | -------------------------------------------------------------------------------- /releasenotes/notes/jsonschema-validation-79cab05d5295da00.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added using of JSONSchema instead of voluptuous to validate Actions. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/min-required-nova-train-71f124192d88ae52.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | The minimum required version of the ``[nova_client]/api_version`` value 5 | is now enforced to be ``2.56`` which is available since the Queens version 6 | of the nova compute service. 7 | 8 | A ``watcher-status upgrade check`` has been added for this. 9 | -------------------------------------------------------------------------------- /releasenotes/notes/monasca-support-0b0486b8572ac38b.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Watcher supports multiple metrics backend and relies on Ceilometer and 4 | Monasca. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/multiple-global-efficacy-indicator-fc11c4844a12a7d5.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Watcher got an ability to calculate multiple global efficacy indicators 4 | during audit's execution. Now global efficacy can be calculated for many 5 | resource types (like volumes, instances, network) if strategy supports 6 | efficacy indicators. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/node-resource-consolidation-73bc0c0abfeb0b03.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Added strategy "node resource consolidation". This 5 | strategy is used to centralize VMs to as few nodes 6 | as possible by VM migration. User can set an input 7 | parameter to decide how to select the destination node. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/noisy-neighbor-strategy-a71342740b59dddc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added strategy to identify and migrate a Noisy Neighbor - a low priority VM 4 | that negatively affects performance of a high priority VM by over utilizing 5 | Last Level Cache. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/notifications-actionplan-cancel-edb2a4a12543e2d0.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added notifications about cancelling of action plan. 4 | Now event based plugins know when action plan cancel 5 | started and completed. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/optimization-threshold-21ad38f0470d0e1a.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Allow decision engine to pass strategy parameters, 4 | like optimization threshold, to selected strategy, 5 | also strategy to provide parameters info to end user. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/persistent-audit-parameters-ae41dd7252ba9672.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Copy all audit templates parameters into 4 | audit instead of having a reference to the 5 | audit template. 6 | 7 | -------------------------------------------------------------------------------- /releasenotes/notes/planner-storage-action-plan-26ef37893c5e8648.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Watcher can now run specific actions in parallel improving the performances 4 | dramatically when executing an action plan. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/prometheus-datasource-e56f2f7b8f3427c2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | A new Prometheus data source is added. This allows the watcher decision 5 | engine to collect metrics from Prometheus server. For more information 6 | about the Prometheus data source, including limitations and configuration 7 | options see 8 | https://docs.openstack.org/watcher/latest/datasources/prometheus.html 9 | -------------------------------------------------------------------------------- /releasenotes/notes/remove-ceilometer-datasource-8d9ab7d64d61e405.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Ceilometer datasource has been completely removed. The datasource requires 5 | ceilometer API which was already removed from Ceilometer. Use the other 6 | datasources such as Gnocchi. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/remove-nova-legacy-notifications-e1b6d10eff58f30a.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | deprecations: 3 | - | 4 | Watcher removes the support to Nova legacy notifications because of Nova 5 | will deprecate them. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/replace-cold-migrate-to-use-nova-migration-api-cecd9a39ddd3bc58.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Instance cold migration logic is now replaced with using Nova migrate 5 | Server(migrate Action) API which has host option since v2.56. 6 | upgrade: 7 | - | 8 | Nova API version is now set to 2.56 by default. This needs the migrate 9 | action of migration type cold with destination_node parameter to work. 10 | fixes: 11 | - | 12 | The migrate action of migration type cold with destination_node parameter 13 | was fixed. Before fixing, it booted an instance in the service project 14 | as a migrated instance. 15 | -------------------------------------------------------------------------------- /releasenotes/notes/return-error-400-on-bad-parameters-bb964e4f5cadc15c.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | `Bug #2110538 `_: 5 | Corrected the HTTP error code returned when watcher users try to create 6 | audits with invalid parameters. The API now correctly returns a 400 Bad 7 | Request error. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/scope-for-data-model-ea9792f90db14343.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | For a large cloud infrastructure, retrieving data from Nova may take 5 | a long time. To avoid getting too much data from Nova, building the 6 | compute data model according to the scope of audit. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/service-versioned-notifications-api-70367b79a565d900.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Add notifications related to Service object. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/show-datamodel-api-6945b744fd5d25d5.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Add show data model api for Watcher. New in version 1.3. 5 | User can use 'openstack optimize datamodel list' 6 | command to view the current data model information in memory. 7 | User can also add '--audit ' to view specific data model 8 | in memory filted by the scope in audit. 9 | User can also add '--detail' to view detailed information about current data model. 10 | User can also add '--type ' to specify the type of data model. 11 | Default type is 'compute'. In the future, type 'storage' and 'baremetal' 12 | will be supported. 13 | -------------------------------------------------------------------------------- /releasenotes/notes/stale-action-plan-b6a6b08df873c128.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Check the creation time of the action plan, 4 | and set its state to SUPERSEDED if it has expired. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/standard-deviation-strategy-cd1d0c443fdfde9c.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added a strategy that monitors if there is a higher 4 | load on some hosts compared to other hosts in the 5 | cluster and re-balances the work across hosts to 6 | minimize the standard deviation of the loads in 7 | the cluster. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/storage-workload-balance-0ecabbc1791e6894.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Added storage capacity balance strategy. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/support-keystoneclient-option-b30d1ff45f86a2e7.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Add keystone_client Group for user to configure 'interface' and 'region_name' 5 | by watcher.conf. The default value of 'interface' is 'admin'. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/support-placement-api-58ce6bef1bbbe98a.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Added Placement API helper to Watcher. Now Watcher can get information 5 | about resource providers, it can be used for the data model and strategies. 6 | Config group placement_client with options 'api_version', 'interface' and 7 | 'region_name' is also added. The default values for 'api_version' and 8 | 'interface' are 1.29 and 'public', respectively. 9 | -------------------------------------------------------------------------------- /releasenotes/notes/suspended-audit-state-07f998c94e9d9a47.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Added SUSPENDED audit state 5 | -------------------------------------------------------------------------------- /releasenotes/notes/uniform-airflow-strategy-68cdba1419c3f770.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added a new strategy based on the airflow 4 | of servers. This strategy makes decisions 5 | to migrate VMs to make the airflow uniform. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/uwsgi-support-8dcea6961e56dad0.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | An Watcher API WSGI application script ``watcher-api-wsgi`` is now 5 | available. It is auto-generated by ``pbr`` and allows to run the API 6 | service using WSGI server (for example Nginx and uWSGI). 7 | deprecations: 8 | - | 9 | Using ``watcher/api/app.wsgi`` script is deprecated and it will be removed 10 | in U release. 11 | Please switch to automatically generated ``watcher-api-wsgi`` script 12 | instead. 13 | -------------------------------------------------------------------------------- /releasenotes/notes/volume-migrate-action-fc57b0ce0e4c39ae.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Added volume migrate action 5 | -------------------------------------------------------------------------------- /releasenotes/notes/watcher-notifications-ovo-7b44d52ef6400dd0.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Provide a notification mechanism into Watcher that supports versioning. 4 | Whenever a Watcher object is created, updated or deleted, a versioned 5 | notification will, if it's relevant, be automatically sent to notify in order 6 | to allow an event-driven style of architecture within Watcher. Moreover, it 7 | will also give other services and/or 3rd party software (e.g. monitoring 8 | solutions or rules engines) the ability to react to such events. 9 | -------------------------------------------------------------------------------- /releasenotes/notes/watcher-planner-selector-84d77549d46f362a.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Now Watcher strategy can select specific planner 4 | beyond default. Strategy can set planner property 5 | to specify its own planner. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/watcher-policies-1e86a30f0f11c6fa.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added policies to handle user rights 4 | to access Watcher API. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/watcher-service-list-7b2f4b64f71e9b89.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Add a service supervisor to watch Watcher daemons. 4 | -------------------------------------------------------------------------------- /releasenotes/notes/watcher-versioned-objects-fc5abf5c81c4590c.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - all Watcher objects have been refactored to support OVO 4 | (oslo.versionedobjects) which was a prerequisite step in order to implement 5 | versioned notifications. 6 | -------------------------------------------------------------------------------- /releasenotes/notes/workload-balance-base-on-cpu-or-ram-util-3ff4ee968c32b2ed.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Existing workload_balance strategy based on 4 | the VM workloads of CPU. This feature improves 5 | the strategy. By the input parameter "metrics", 6 | it makes decision to migrate a VM base on CPU 7 | or memory utilization. -------------------------------------------------------------------------------- /releasenotes/notes/workload-balance-migration-strategy-a0b05148a57815c0.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added a strategy based on the VM workloads of 4 | hypervisors. This strategy makes decisions to 5 | migrate workloads to make the total VM workloads 6 | of each hypervisor balanced, when the total VM 7 | workloads of hypervisor reaches threshold. 8 | -------------------------------------------------------------------------------- /releasenotes/notes/zone-migration-missing-dst-node-bd0377af1f1ed245.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | The zone migration strategy no longer requires a dst_node to be passed. 5 | When unspecified, the Nova scheduler will select an appropriate host automatically. 6 | This brings the implementation of the strategy in line with the the api schema 7 | where dest_node is optional. 8 | 9 | See: https://bugs.launchpad.net/watcher/+bug/2108988 for more details. 10 | -------------------------------------------------------------------------------- /releasenotes/notes/zone-migration-strategy-10f7656a2a01e607.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Added strategy "Zone migration" and it's goal "Hardware maintenance". 5 | The strategy migrates many instances and volumes efficiently with 6 | minimum downtime automatically. 7 | -------------------------------------------------------------------------------- /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/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/releasenotes/source/_static/.placeholder -------------------------------------------------------------------------------- /releasenotes/source/index.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 | ================================================= 15 | Welcome to watcher's Release Notes documentation! 16 | ================================================= 17 | 18 | Contents: 19 | 20 | .. toctree:: 21 | :maxdepth: 1 22 | 23 | unreleased 24 | 2025.1 25 | 2024.2 26 | 2024.1 27 | 2023.2 28 | 2023.1 29 | zed 30 | yoga 31 | xena 32 | wallaby 33 | victoria 34 | ussuri 35 | train 36 | stein 37 | rocky 38 | queens 39 | pike 40 | ocata 41 | newton 42 | 43 | -------------------------------------------------------------------------------- /releasenotes/source/locale/fr/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # Gérald LONLAS , 2016. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: python-watcher\n" 5 | "Report-Msgid-Bugs-To: \n" 6 | "POT-Creation-Date: 2025-03-19 18:13+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 06:44+0000\n" 11 | "Last-Translator: Gérald LONLAS \n" 12 | "Language-Team: French\n" 13 | "Language: fr\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=2; plural=(n > 1)\n" 16 | 17 | msgid "0.29.0" 18 | msgstr "0.29.0" 19 | 20 | msgid "Contents:" 21 | msgstr "Contenu :" 22 | 23 | msgid "Current Series Release Notes" 24 | msgstr "Note de la release actuelle" 25 | 26 | msgid "New Features" 27 | msgstr "Nouvelles fonctionnalités" 28 | 29 | msgid "Newton Series Release Notes" 30 | msgstr "Note de release pour Newton" 31 | 32 | msgid "Welcome to watcher's Release Notes documentation!" 33 | msgstr "Bienvenue dans la documentation de la note de Release de Watcher" 34 | -------------------------------------------------------------------------------- /releasenotes/source/newton.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Newton Series Release Notes 3 | =================================== 4 | 5 | .. release-notes:: 6 | :branch: origin/stable/newton 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 | -------------------------------------------------------------------------------- /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>=2.0.0'], 20 | pbr=True) 21 | -------------------------------------------------------------------------------- /test-requirements.txt: -------------------------------------------------------------------------------- 1 | coverage>=4.5.1 # Apache-2.0 2 | freezegun>=0.3.10 # Apache-2.0 3 | oslotest>=3.3.0 # Apache-2.0 4 | testscenarios>=0.5.0 # Apache-2.0/BSD 5 | testtools>=2.3.0 # MIT 6 | stestr>=2.0.0 # Apache-2.0 7 | WebTest>=2.0.27 # MIT 8 | 9 | # Include drivers for opportunistic testing. 10 | oslo.db[mysql]>=6.0.0 # Apache-2.0 11 | -------------------------------------------------------------------------------- /watcher/__init__.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 | import pbr.version 14 | 15 | 16 | __version__ = pbr.version.VersionInfo('python-watcher').version_string() 17 | -------------------------------------------------------------------------------- /watcher/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/api/__init__.py -------------------------------------------------------------------------------- /watcher/api/app.wsgi: -------------------------------------------------------------------------------- 1 | # -*- mode: python -*- 2 | # -*- encoding: utf-8 -*- 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 | Use this file for deploying the API service under Apache2 mod_wsgi. 17 | """ 18 | 19 | 20 | # This script is deprecated and it will be removed in U release. 21 | # Please switch to automatically generated watcher-api-wsgi script instead. 22 | from watcher.api import wsgi 23 | 24 | application = wsgi.initialize_wsgi_app(show_deprecated=True) 25 | -------------------------------------------------------------------------------- /watcher/api/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/api/controllers/__init__.py -------------------------------------------------------------------------------- /watcher/api/controllers/rest_api_version_history.rst: -------------------------------------------------------------------------------- 1 | REST API Version History 2 | ======================== 3 | 4 | This documents the changes made to the REST API with every 5 | microversion change. The description for each version should be a 6 | verbose one which has enough information to be suitable for use in 7 | user documentation. 8 | 9 | 1.0 (Initial version) 10 | ----------------------- 11 | This is the initial version of the Watcher API which supports 12 | microversions. 13 | 14 | A user can specify a header in the API request:: 15 | 16 | OpenStack-API-Version: infra-optim 17 | 18 | where ```` is any valid api version for this API. 19 | 20 | If no version is specified then the API will behave as if version 1.0 21 | was requested. 22 | 23 | 1.1 24 | --- 25 | Added the parameters ``start_time`` and ``end_time`` to 26 | create audit request. Supported for start and end time of continuous 27 | audits. 28 | 29 | 1.2 30 | --- 31 | Added ``force`` into create audit request. If ``force`` is true, 32 | audit will be executed despite of ongoing actionplan. 33 | 34 | 1.3 35 | --- 36 | Added list data model API. 37 | 38 | 1.4 39 | --- 40 | Added Watcher webhook API. It can be used to trigger audit 41 | with ``event`` type. 42 | -------------------------------------------------------------------------------- /watcher/api/middleware/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/api/middleware/__init__.py -------------------------------------------------------------------------------- /watcher/applier/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/applier/__init__.py -------------------------------------------------------------------------------- /watcher/applier/action_plan/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/applier/action_plan/__init__.py -------------------------------------------------------------------------------- /watcher/applier/action_plan/base.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2015 b<>com 3 | # 4 | # Authors: Jean-Emile DARTOIS 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain 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, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | # implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | import abc 21 | 22 | 23 | class BaseActionPlanHandler(object, metaclass=abc.ABCMeta): 24 | @abc.abstractmethod 25 | def execute(self): 26 | raise NotImplementedError() 27 | -------------------------------------------------------------------------------- /watcher/applier/actions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/applier/actions/__init__.py -------------------------------------------------------------------------------- /watcher/applier/base.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2015 b<>com 3 | # 4 | # Authors: Jean-Emile DARTOIS 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain 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, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | # implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | """ 21 | This component is in charge of executing the 22 | :ref:`Action Plan ` built by the 23 | :ref:`Watcher Decision Engine `. 24 | 25 | See: :doc:`../architecture` for more details on this component. 26 | """ 27 | 28 | import abc 29 | 30 | 31 | class BaseApplier(object, metaclass=abc.ABCMeta): 32 | @abc.abstractmethod 33 | def execute(self, action_plan_uuid): 34 | raise NotImplementedError() 35 | -------------------------------------------------------------------------------- /watcher/applier/loading/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/applier/loading/__init__.py -------------------------------------------------------------------------------- /watcher/applier/loading/default.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); 2 | # you may not use this file except in compliance with the License. 3 | # You may obtain 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, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 10 | # implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | from watcher.common.loader import default 15 | 16 | 17 | class DefaultWorkFlowEngineLoader(default.DefaultLoader): 18 | def __init__(self): 19 | super(DefaultWorkFlowEngineLoader, self).__init__( 20 | namespace='watcher_workflow_engines') 21 | 22 | 23 | class DefaultActionLoader(default.DefaultLoader): 24 | def __init__(self): 25 | super(DefaultActionLoader, self).__init__( 26 | namespace='watcher_actions') 27 | -------------------------------------------------------------------------------- /watcher/applier/messaging/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/applier/messaging/__init__.py -------------------------------------------------------------------------------- /watcher/applier/workflow_engine/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/applier/workflow_engine/__init__.py -------------------------------------------------------------------------------- /watcher/cmd/sync.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # 3 | # Copyright (c) 2016 Intel 4 | # 5 | # Authors: Tomasz Kaczynski 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | """Script for the sync tool.""" 20 | 21 | import sys 22 | 23 | from oslo_log import log 24 | 25 | from watcher.common import service 26 | from watcher import conf 27 | from watcher.decision_engine import sync 28 | 29 | LOG = log.getLogger(__name__) 30 | CONF = conf.CONF 31 | 32 | 33 | def main(): 34 | LOG.info('Watcher sync started.') 35 | 36 | service.prepare_service(sys.argv, CONF) 37 | syncer = sync.Syncer() 38 | syncer.sync() 39 | 40 | LOG.info('Watcher sync finished.') 41 | -------------------------------------------------------------------------------- /watcher/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/common/__init__.py -------------------------------------------------------------------------------- /watcher/common/loader/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/common/loader/__init__.py -------------------------------------------------------------------------------- /watcher/common/loader/base.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2015 b<>com 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain 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, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 | # implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import abc 18 | 19 | 20 | class BaseLoader(object, metaclass=abc.ABCMeta): 21 | 22 | @abc.abstractmethod 23 | def list_available(self): 24 | raise NotImplementedError() 25 | 26 | @abc.abstractmethod 27 | def load(self, name): 28 | raise NotImplementedError() 29 | -------------------------------------------------------------------------------- /watcher/common/metal_helper/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/common/metal_helper/__init__.py -------------------------------------------------------------------------------- /watcher/common/metal_helper/constants.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Cloudbase Solutions 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 enum 17 | 18 | 19 | class PowerState(str, enum.Enum): 20 | ON = "on" 21 | OFF = "off" 22 | UNKNOWN = "unknown" 23 | ERROR = "error" 24 | -------------------------------------------------------------------------------- /watcher/common/metal_helper/factory.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Cloudbase Solutions 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 | from oslo_config import cfg 17 | 18 | from watcher.common import clients 19 | from watcher.common.metal_helper import ironic 20 | from watcher.common.metal_helper import maas 21 | 22 | CONF = cfg.CONF 23 | 24 | 25 | def get_helper(osc=None): 26 | # TODO(lpetrut): consider caching this client. 27 | if not osc: 28 | osc = clients.OpenStackClients() 29 | 30 | if CONF.maas_client.url: 31 | return maas.MaasHelper(osc) 32 | else: 33 | return ironic.IronicHelper(osc) 34 | -------------------------------------------------------------------------------- /watcher/common/paths.py: -------------------------------------------------------------------------------- 1 | # Copyright 2010 United States Government as represented by the 2 | # Administrator of the National Aeronautics and Space Administration. 3 | # All Rights Reserved. 4 | # Copyright 2012 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 os 19 | 20 | from watcher import conf 21 | 22 | CONF = conf.CONF 23 | 24 | 25 | def basedir_rel(*args): 26 | """Return a path relative to $pybasedir.""" 27 | return os.path.join(CONF.pybasedir, *args) 28 | 29 | 30 | def bindir_rel(*args): 31 | """Return a path relative to $bindir.""" 32 | return os.path.join(CONF.bindir, *args) 33 | 34 | 35 | def state_path_rel(*args): 36 | """Return a path relative to $state_path.""" 37 | return os.path.join(CONF.state_path, *args) 38 | -------------------------------------------------------------------------------- /watcher/common/policies/base.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 | from oslo_policy import policy 14 | 15 | RULE_ADMIN_API = 'rule:admin_api' 16 | ROLE_ADMIN_OR_ADMINISTRATOR = 'role:admin or role:administrator' 17 | ALWAYS_DENY = '!' 18 | 19 | rules = [ 20 | policy.RuleDefault( 21 | name='admin_api', 22 | check_str=ROLE_ADMIN_OR_ADMINISTRATOR 23 | ), 24 | policy.RuleDefault( 25 | name='show_password', 26 | check_str=ALWAYS_DENY 27 | ) 28 | ] 29 | 30 | 31 | def list_rules(): 32 | return rules 33 | -------------------------------------------------------------------------------- /watcher/common/policies/data_model.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 ZTE 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 | 15 | from oslo_policy import policy 16 | 17 | from watcher.common.policies import base 18 | 19 | DATA_MODEL = 'data_model:%s' 20 | 21 | rules = [ 22 | policy.DocumentedRuleDefault( 23 | name=DATA_MODEL % 'get_all', 24 | check_str=base.RULE_ADMIN_API, 25 | description='List data model.', 26 | operations=[ 27 | { 28 | 'path': '/v1/data_model', 29 | 'method': 'GET' 30 | } 31 | ] 32 | ), 33 | ] 34 | 35 | 36 | def list_rules(): 37 | return rules 38 | -------------------------------------------------------------------------------- /watcher/conf/clients_auth.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2016 Intel Corp 3 | # 4 | # Authors: Prudhvi Rao Shedimbi 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain 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, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | # implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | from keystoneauth1 import loading as ka_loading 20 | 21 | WATCHER_CLIENTS_AUTH = 'watcher_clients_auth' 22 | 23 | 24 | def register_opts(conf): 25 | ka_loading.register_session_conf_options(conf, WATCHER_CLIENTS_AUTH) 26 | ka_loading.register_auth_conf_options(conf, WATCHER_CLIENTS_AUTH) 27 | 28 | 29 | def list_opts(): 30 | return [(WATCHER_CLIENTS_AUTH, ka_loading.get_session_conf_options() + 31 | ka_loading.get_auth_common_conf_options())] 32 | -------------------------------------------------------------------------------- /watcher/conf/exception.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2016 Intel Corp 3 | # 4 | # Authors: Prudhvi Rao Shedimbi 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain 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, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | # implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | from oslo_config import cfg 20 | 21 | EXC_LOG_OPTS = [ 22 | cfg.BoolOpt('fatal_exception_format_errors', 23 | default=False, 24 | help='Make exception message format errors fatal.'), 25 | ] 26 | 27 | 28 | def register_opts(conf): 29 | conf.register_opts(EXC_LOG_OPTS) 30 | 31 | 32 | def list_opts(): 33 | return [('DEFAULT', EXC_LOG_OPTS)] 34 | -------------------------------------------------------------------------------- /watcher/db/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/db/__init__.py -------------------------------------------------------------------------------- /watcher/db/sqlalchemy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/db/sqlalchemy/__init__.py -------------------------------------------------------------------------------- /watcher/db/sqlalchemy/alembic.ini: -------------------------------------------------------------------------------- 1 | # A generic, single database configuration. 2 | 3 | [alembic] 4 | # path to migration scripts 5 | script_location = %(here)s/alembic 6 | 7 | # template used to generate migration files 8 | # file_template = %%(rev)s_%%(slug)s 9 | 10 | # max length of characters to apply to the 11 | # "slug" field 12 | #truncate_slug_length = 40 13 | 14 | # set to 'true' to run the environment during 15 | # the 'revision' command, regardless of autogenerate 16 | # revision_environment = false 17 | 18 | #sqlalchemy.url = driver://user:pass@localhost/dbname 19 | 20 | 21 | # Logging configuration 22 | [loggers] 23 | keys = root,sqlalchemy,alembic 24 | 25 | [handlers] 26 | keys = console 27 | 28 | [formatters] 29 | keys = generic 30 | 31 | [logger_root] 32 | level = WARN 33 | handlers = console 34 | qualname = 35 | 36 | [logger_sqlalchemy] 37 | level = WARN 38 | handlers = 39 | qualname = sqlalchemy.engine 40 | 41 | [logger_alembic] 42 | level = INFO 43 | handlers = 44 | qualname = alembic 45 | 46 | [handler_console] 47 | class = StreamHandler 48 | args = (sys.stderr,) 49 | level = NOTSET 50 | formatter = generic 51 | 52 | [formatter_generic] 53 | format = %(levelname)-5.5s [%(name)s] %(message)s 54 | datefmt = %H:%M:%S 55 | -------------------------------------------------------------------------------- /watcher/db/sqlalchemy/alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = ${repr(up_revision)} 11 | down_revision = ${repr(down_revision)} 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | ${imports if imports else ""} 16 | 17 | def upgrade(): 18 | ${upgrades if upgrades else "pass"} 19 | 20 | 21 | def downgrade(): 22 | ${downgrades if downgrades else "pass"} 23 | -------------------------------------------------------------------------------- /watcher/db/sqlalchemy/alembic/versions/0f6042416884_add_apscheduler_jobs.py: -------------------------------------------------------------------------------- 1 | """Add apscheduler_jobs table to store background jobs 2 | 3 | Revision ID: 0f6042416884 4 | Revises: 001 5 | Create Date: 2017-03-24 11:21:29.036532 6 | 7 | """ 8 | from alembic import op 9 | from sqlalchemy import inspect 10 | import sqlalchemy as sa 11 | 12 | from watcher.db.sqlalchemy import models 13 | 14 | # revision identifiers, used by Alembic. 15 | revision = '0f6042416884' 16 | down_revision = '001' 17 | 18 | def _table_exists(table_name): 19 | bind = op.get_context().bind 20 | insp = inspect(bind) 21 | names = insp.get_table_names() 22 | return any(t == table_name for t in names) 23 | 24 | 25 | def upgrade(): 26 | if _table_exists('apscheduler_jobs'): 27 | return 28 | 29 | op.create_table( 30 | 'apscheduler_jobs', 31 | sa.Column('id', sa.Unicode(191), 32 | nullable=False), 33 | sa.Column('next_run_time', sa.Float(25), index=True), 34 | sa.Column('job_state', sa.LargeBinary, nullable=False), 35 | sa.Column('service_id', sa.Integer(), nullable=False), 36 | sa.Column('tag', models.JSONEncodedDict(), nullable=True), 37 | sa.PrimaryKeyConstraint('id'), 38 | sa.ForeignKeyConstraint(['service_id'], ['services.id']) 39 | ) 40 | 41 | 42 | def downgrade(): 43 | op.drop_table('apscheduler_jobs') 44 | -------------------------------------------------------------------------------- /watcher/db/sqlalchemy/alembic/versions/15f7375ca737_change_efficiacy_indicator_decimals.py: -------------------------------------------------------------------------------- 1 | """change_efficiacy_indicator_decimals 2 | 3 | Revision ID: 15f7375ca737 4 | Revises: 609bec748f2a 5 | Create Date: 2025-03-24 10:15:19.269061 6 | 7 | """"" 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '15f7375ca737' 11 | down_revision = '609bec748f2a' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | def upgrade(): 17 | op.add_column('efficacy_indicators', 18 | sa.Column('data', sa.Float()) 19 | ) 20 | 21 | -------------------------------------------------------------------------------- /watcher/db/sqlalchemy/alembic/versions/3cfc94cecf4e_add_name_for_audit.py: -------------------------------------------------------------------------------- 1 | """add name for audit 2 | 3 | Revision ID: 3cfc94cecf4e 4 | Revises: d098df6021e2 5 | Create Date: 2017-07-19 15:44:57.661099 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '3cfc94cecf4e' 11 | down_revision = 'd09a5945e4a0' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | op.add_column('audits', sa.Column('name', sa.String(length=63), nullable=True)) 19 | 20 | 21 | def downgrade(): 22 | op.drop_column('audits', 'name') 23 | -------------------------------------------------------------------------------- /watcher/db/sqlalchemy/alembic/versions/4b16194c56bc_add_start_end_time.py: -------------------------------------------------------------------------------- 1 | """add_start_end_time 2 | 3 | Revision ID: 4b16194c56bc 4 | Revises: 52804f2498c4 5 | Create Date: 2018-03-23 00:36:29.031259 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '4b16194c56bc' 11 | down_revision = '52804f2498c4' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | op.add_column('audits', sa.Column('start_time', sa.DateTime(), nullable=True)) 19 | op.add_column('audits', sa.Column('end_time', sa.DateTime(), nullable=True)) 20 | 21 | 22 | def downgrade(): 23 | op.drop_column('audits', 'start_time') 24 | op.drop_column('audits', 'end_time') 25 | -------------------------------------------------------------------------------- /watcher/db/sqlalchemy/alembic/versions/52804f2498c4_add_hostname.py: -------------------------------------------------------------------------------- 1 | """Add hostname field to both Audit and Action Plan models 2 | 3 | Revision ID: 52804f2498c4 4 | Revises: a86240e89a29 5 | Create Date: 2018-06-26 13:06:45.530387 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '52804f2498c4' 11 | down_revision = 'a86240e89a29' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | for table in ('audits', 'action_plans'): 19 | op.add_column( 20 | table, 21 | sa.Column('hostname', sa.String(length=255), nullable=True)) 22 | 23 | 24 | def downgrade(): 25 | for table in ('audits', 'action_plans'): 26 | op.drop_column(table, 'hostname') 27 | -------------------------------------------------------------------------------- /watcher/db/sqlalchemy/alembic/versions/609bec748f2a_add_force_field.py: -------------------------------------------------------------------------------- 1 | """add_force_field 2 | 3 | Revision ID: 609bec748f2a 4 | Revises: 4b16194c56bc 5 | Create Date: 2019-05-05 14:06:14.249124 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '609bec748f2a' 11 | down_revision = '4b16194c56bc' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | op.add_column('audits', sa.Column('force', sa.Boolean, default=False)) 19 | 20 | 21 | def downgrade(): 22 | op.drop_column('audits', 'force') 23 | -------------------------------------------------------------------------------- /watcher/db/sqlalchemy/alembic/versions/d098df6021e2_cron_support_for_audit.py: -------------------------------------------------------------------------------- 1 | """Add cron support for audit table 2 | 3 | Revision ID: d098df6021e2 4 | Revises: 0f6042416884 5 | Create Date: 2017-06-08 16:21:35.746752 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | # revision identifiers, used by Alembic. 12 | revision = 'd098df6021e2' 13 | down_revision = '0f6042416884' 14 | 15 | 16 | def upgrade(): 17 | op.alter_column('audits', 'interval', existing_type=sa.String(36), 18 | nullable=True) 19 | op.add_column('audits', 20 | sa.Column('next_run_time', sa.DateTime(), nullable=True)) 21 | 22 | 23 | def downgrade(): 24 | op.alter_column('audits', 'interval', existing_type=sa.Integer(), 25 | nullable=True) 26 | op.drop_column('audits', 'next_run_time') 27 | -------------------------------------------------------------------------------- /watcher/db/sqlalchemy/alembic/versions/d09a5945e4a0_add_action_description_table.py: -------------------------------------------------------------------------------- 1 | """add action description table 2 | 3 | Revision ID: d09a5945e4a0 4 | Revises: d098df6021e2 5 | Create Date: 2017-07-13 20:33:01.473711 6 | 7 | """ 8 | 9 | from alembic import op 10 | import oslo_db 11 | import sqlalchemy as sa 12 | 13 | # revision identifiers, used by Alembic. 14 | revision = 'd09a5945e4a0' 15 | down_revision = 'd098df6021e2' 16 | 17 | 18 | def upgrade(): 19 | op.create_table( 20 | 'action_descriptions', 21 | sa.Column('created_at', sa.DateTime(), nullable=True), 22 | sa.Column('updated_at', sa.DateTime(), nullable=True), 23 | sa.Column('deleted_at', sa.DateTime(), nullable=True), 24 | sa.Column('deleted', oslo_db.sqlalchemy.types.SoftDeleteInteger(), 25 | nullable=True), 26 | sa.Column('id', sa.Integer(), nullable=False), 27 | sa.Column('action_type', sa.String(length=255), nullable=False), 28 | sa.Column('description', sa.String(length=255), nullable=False), 29 | sa.PrimaryKeyConstraint('id'), 30 | sa.UniqueConstraint('action_type', 31 | name='uniq_action_description0action_type') 32 | ) 33 | 34 | 35 | def downgrade(): 36 | op.drop_table('action_descriptions') 37 | -------------------------------------------------------------------------------- /watcher/decision_engine/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/audit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/audit/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/audit/event.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2019 ZTE Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain 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, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 | # implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | from watcher.decision_engine.audit import base 18 | from watcher import objects 19 | 20 | 21 | class EventAuditHandler(base.AuditHandler): 22 | 23 | def post_execute(self, audit, solution, request_context): 24 | super(EventAuditHandler, self).post_execute(audit, solution, 25 | request_context) 26 | # change state of the audit to SUCCEEDED 27 | self.update_audit_state(audit, objects.audit.State.SUCCEEDED) 28 | -------------------------------------------------------------------------------- /watcher/decision_engine/audit/oneshot.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2015 b<>com 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain 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, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 | # implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | from watcher.decision_engine.audit import base 18 | from watcher import objects 19 | 20 | 21 | class OneShotAuditHandler(base.AuditHandler): 22 | 23 | def post_execute(self, audit, solution, request_context): 24 | super(OneShotAuditHandler, self).post_execute(audit, solution, 25 | request_context) 26 | # change state of the audit to SUCCEEDED 27 | self.update_audit_state(audit, objects.audit.State.SUCCEEDED) 28 | -------------------------------------------------------------------------------- /watcher/decision_engine/datasources/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/datasources/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/datasources/grafana_translator/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/datasources/grafana_translator/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/goal/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2016 b<>com 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain 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, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 | # implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | from watcher.decision_engine.goal import goals 18 | 19 | Dummy = goals.Dummy 20 | ServerConsolidation = goals.ServerConsolidation 21 | ThermalOptimization = goals.ThermalOptimization 22 | Unclassified = goals.Unclassified 23 | WorkloadBalancing = goals.WorkloadBalancing 24 | NoisyNeighborOptimization = goals.NoisyNeighborOptimization 25 | SavingEnergy = goals.SavingEnergy 26 | HardwareMaintenance = goals.HardwareMaintenance 27 | 28 | 29 | __all__ = ("Dummy", "ServerConsolidation", "ThermalOptimization", 30 | "Unclassified", "WorkloadBalancing", 31 | "NoisyNeighborOptimization", "SavingEnergy", 32 | "HardwareMaintenance") 33 | -------------------------------------------------------------------------------- /watcher/decision_engine/goal/efficacy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/goal/efficacy/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/loading/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/loading/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/messaging/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/messaging/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/model/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/model/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/model/base.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2016 b<>com 3 | # 4 | # Authors: Vincent FRANCOISE 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain 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, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | # implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | """ 20 | This component is in charge of executing the 21 | :ref:`Action Plan ` built by the 22 | :ref:`Watcher Decision Engine `. 23 | 24 | See: :doc:`../architecture` for more details on this component. 25 | """ 26 | 27 | import abc 28 | 29 | 30 | class Model(object, metaclass=abc.ABCMeta): 31 | 32 | @abc.abstractmethod 33 | def to_string(self): 34 | raise NotImplementedError() 35 | 36 | @abc.abstractmethod 37 | def to_xml(self): 38 | raise NotImplementedError() 39 | -------------------------------------------------------------------------------- /watcher/decision_engine/model/collector/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/model/collector/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/model/element/baremetal_resource.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2017 ZTE Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain 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, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 | # implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import abc 18 | 19 | 20 | from watcher.decision_engine.model.element import base 21 | from watcher.objects import fields as wfields 22 | 23 | 24 | class BaremetalResource(base.Element, metaclass=abc.ABCMeta): 25 | 26 | VERSION = '1.0' 27 | 28 | fields = { 29 | "uuid": wfields.StringField(), 30 | "human_id": wfields.StringField(default=""), 31 | } 32 | -------------------------------------------------------------------------------- /watcher/decision_engine/model/element/compute_resource.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2015 b<>com 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain 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, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 | # implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import abc 18 | 19 | 20 | from watcher.decision_engine.model.element import base 21 | from watcher.objects import fields as wfields 22 | 23 | 24 | class ComputeResource(base.Element, metaclass=abc.ABCMeta): 25 | 26 | VERSION = '1.0' 27 | 28 | fields = { 29 | "uuid": wfields.StringField(), 30 | } 31 | -------------------------------------------------------------------------------- /watcher/decision_engine/model/element/storage_resource.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright 2017 NEC Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain 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, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 | # implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import abc 18 | 19 | 20 | from watcher.decision_engine.model.element import base 21 | from watcher.objects import fields as wfields 22 | 23 | 24 | class StorageResource(base.Element, metaclass=abc.ABCMeta): 25 | 26 | VERSION = '1.0' 27 | 28 | fields = { 29 | "uuid": wfields.StringField(default=""), 30 | "human_id": wfields.StringField(default=""), 31 | } 32 | -------------------------------------------------------------------------------- /watcher/decision_engine/model/notification/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/model/notification/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/model/notification/base.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2016 b<>com 3 | # 4 | # Authors: Vincent FRANCOISE 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain 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, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | # implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | import abc 20 | 21 | 22 | class NotificationEndpoint(object, metaclass=abc.ABCMeta): 23 | 24 | def __init__(self, collector): 25 | super(NotificationEndpoint, self).__init__() 26 | self.collector = collector 27 | self._notifier = None 28 | 29 | @property 30 | @abc.abstractmethod 31 | def filter_rule(self): 32 | """Notification Filter""" 33 | raise NotImplementedError() 34 | 35 | @property 36 | def cluster_data_model(self): 37 | return self.collector.cluster_data_model 38 | -------------------------------------------------------------------------------- /watcher/decision_engine/planner/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/planner/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/planner/manager.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2016 b<>com 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain 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, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 | # implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | from oslo_log import log 19 | 20 | from watcher.decision_engine.loading import default as loader 21 | 22 | LOG = log.getLogger(__name__) 23 | 24 | 25 | class PlannerManager(object): 26 | def __init__(self): 27 | self._loader = loader.DefaultPlannerLoader() 28 | 29 | @property 30 | def loader(self): 31 | return self._loader 32 | 33 | def load(self, planner_name): 34 | LOG.debug("Loading %s", planner_name) 35 | return self.loader.load(name=planner_name) 36 | -------------------------------------------------------------------------------- /watcher/decision_engine/scope/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/scope/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/scope/base.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2016 Servionica 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain 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, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 | # implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | import abc 19 | 20 | from watcher.common import context 21 | 22 | 23 | class BaseScope(object, metaclass=abc.ABCMeta): 24 | """A base class for Scope mechanism 25 | 26 | Child of this class is called when audit launches strategy. This strategy 27 | requires Cluster Data Model which can be segregated to achieve audit scope. 28 | """ 29 | 30 | def __init__(self, scope, config): 31 | self.ctx = context.make_context() 32 | self.scope = scope 33 | self.config = config 34 | 35 | @abc.abstractmethod 36 | def get_scoped_model(self, cluster_model): 37 | """Leave only nodes and instances proposed in the audit scope""" 38 | -------------------------------------------------------------------------------- /watcher/decision_engine/scoring/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/scoring/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/solution/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/solution/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/solution/solution_comparator.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2015 b<>com 3 | # 4 | # Authors: Jean-Emile DARTOIS 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain 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, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | # implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | import abc 20 | 21 | 22 | class BaseSolutionComparator(object, metaclass=abc.ABCMeta): 23 | @abc.abstractmethod 24 | def compare(self, sol1, sol2): 25 | raise NotImplementedError() 26 | -------------------------------------------------------------------------------- /watcher/decision_engine/solution/solution_evaluator.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2015 b<>com 3 | # 4 | # Authors: Jean-Emile DARTOIS 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain 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, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | # implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | import abc 20 | 21 | 22 | class BaseSolutionEvaluator(object, metaclass=abc.ABCMeta): 23 | @abc.abstractmethod 24 | def evaluate(self, solution): 25 | raise NotImplementedError() 26 | -------------------------------------------------------------------------------- /watcher/decision_engine/strategy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/strategy/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/strategy/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/strategy/common/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/strategy/common/level.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2015 b<>com 3 | # 4 | # Authors: Jean-Emile DARTOIS 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain 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, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | # implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | import enum 21 | 22 | 23 | class StrategyLevel(enum.Enum): 24 | conservative = "conservative" 25 | balanced = "balanced" 26 | growth = "growth" 27 | aggressive = "aggressive" 28 | -------------------------------------------------------------------------------- /watcher/decision_engine/strategy/context/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/strategy/context/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/strategy/selection/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/decision_engine/strategy/selection/__init__.py -------------------------------------------------------------------------------- /watcher/decision_engine/strategy/selection/base.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2015 b<>com 3 | # 4 | # Authors: Jean-Emile DARTOIS 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain 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, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 | # implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | import abc 20 | 21 | 22 | class BaseSelector(object, metaclass=abc.ABCMeta): 23 | 24 | @abc.abstractmethod 25 | def select(self): 26 | raise NotImplementedError() 27 | -------------------------------------------------------------------------------- /watcher/hacking/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/hacking/__init__.py -------------------------------------------------------------------------------- /watcher/tests/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/api/__init__.py -------------------------------------------------------------------------------- /watcher/tests/api/test_base.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Hewlett-Packard Development Company, L.P. 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 | from http import HTTPStatus 17 | 18 | from watcher.tests.api import base 19 | 20 | 21 | class TestBase(base.FunctionalTest): 22 | 23 | def test_api_setup(self): 24 | pass 25 | 26 | def test_bad_uri(self): 27 | response = self.get_json('/bad/path', 28 | expect_errors=True, 29 | headers={"Accept": "application/json"}) 30 | self.assertEqual(HTTPStatus.NOT_FOUND, response.status_int) 31 | self.assertEqual("application/json", response.content_type) 32 | self.assertTrue(response.json['error_message']) 33 | -------------------------------------------------------------------------------- /watcher/tests/api/v1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/api/v1/__init__.py -------------------------------------------------------------------------------- /watcher/tests/api/v1/test_root.py: -------------------------------------------------------------------------------- 1 | # All Rights Reserved. 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 watcher.tests.api import base as api_base 16 | 17 | 18 | class TestV1Routing(api_base.FunctionalTest): 19 | pass 20 | -------------------------------------------------------------------------------- /watcher/tests/applier/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/applier/__init__.py -------------------------------------------------------------------------------- /watcher/tests/applier/action_plan/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/applier/action_plan/__init__.py -------------------------------------------------------------------------------- /watcher/tests/applier/actions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/applier/actions/__init__.py -------------------------------------------------------------------------------- /watcher/tests/applier/actions/loading/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/applier/actions/loading/__init__.py -------------------------------------------------------------------------------- /watcher/tests/applier/actions/loading/test_default_actions_loader.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016 b<>com 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 | from watcher.applier.actions import base as abase 17 | from watcher.applier.loading import default 18 | from watcher.tests import base 19 | 20 | 21 | class TestDefaultActionLoader(base.TestCase): 22 | def setUp(self): 23 | super(TestDefaultActionLoader, self).setUp() 24 | self.loader = default.DefaultActionLoader() 25 | 26 | def test_endpoints(self): 27 | for endpoint in self.loader.list_available(): 28 | loaded = self.loader.load(endpoint) 29 | self.assertIsNotNone(loaded) 30 | self.assertIsInstance(loaded, abase.BaseAction) 31 | -------------------------------------------------------------------------------- /watcher/tests/applier/messaging/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/applier/messaging/__init__.py -------------------------------------------------------------------------------- /watcher/tests/applier/workflow_engine/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/applier/workflow_engine/__init__.py -------------------------------------------------------------------------------- /watcher/tests/applier/workflow_engine/loading/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/applier/workflow_engine/loading/__init__.py -------------------------------------------------------------------------------- /watcher/tests/applier/workflow_engine/loading/test_default_engine_loader.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2016 b<>com 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain 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, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 | # implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | from watcher.applier.loading import default 18 | from watcher.applier.workflow_engine import base as wbase 19 | from watcher.tests import base 20 | 21 | 22 | class TestDefaultActionLoader(base.TestCase): 23 | def setUp(self): 24 | super(TestDefaultActionLoader, self).setUp() 25 | self.loader = default.DefaultWorkFlowEngineLoader() 26 | 27 | def test_endpoints(self): 28 | for endpoint in self.loader.list_available(): 29 | loaded = self.loader.load(endpoint) 30 | self.assertIsNotNone(loaded) 31 | self.assertIsInstance(loaded, wbase.BaseWorkFlowEngine) 32 | -------------------------------------------------------------------------------- /watcher/tests/cmd/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/cmd/__init__.py -------------------------------------------------------------------------------- /watcher/tests/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/common/__init__.py -------------------------------------------------------------------------------- /watcher/tests/common/loader/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/common/loader/__init__.py -------------------------------------------------------------------------------- /watcher/tests/common/metal_helper/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/common/metal_helper/__init__.py -------------------------------------------------------------------------------- /watcher/tests/conf/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/conf/__init__.py -------------------------------------------------------------------------------- /watcher/tests/config.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); 2 | # you may not use this file except in compliance with the License. 3 | # You may obtain 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, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | 13 | from watcher.api import hooks 14 | 15 | # Server Specific Configurations 16 | server = { 17 | 'port': '9322', 18 | 'host': '0.0.0.0' 19 | } 20 | 21 | # Pecan Application Configurations 22 | app = { 23 | 'root': 'watcher.api.controllers.root.RootController', 24 | 'modules': ['watcher.api'], 25 | 'hooks': [ 26 | hooks.ContextHook(), 27 | ], 28 | 'acl_public_routes': [ 29 | '/' 30 | ], 31 | } 32 | 33 | # Custom Configurations must be in Python dictionary format:: 34 | # 35 | # foo = {'bar':'baz'} 36 | # 37 | # All configurations are accessible at:: 38 | # pecan.conf 39 | -------------------------------------------------------------------------------- /watcher/tests/db/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/db/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'Jean-Emile DARTOIS ' 2 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/audit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/audit/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/cluster/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/cluster/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/datasources/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/datasources/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/datasources/grafana_translators/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/datasources/grafana_translators/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/event_consumer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/event_consumer/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/loading/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/loading/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/loading/test_default_planner_loader.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2016 b<>com 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain 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, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 | # implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | from watcher.decision_engine.loading import default 18 | from watcher.decision_engine.planner import base as planner 19 | from watcher.tests import base 20 | 21 | 22 | class TestDefaultPlannerLoader(base.TestCase): 23 | def setUp(self): 24 | super(TestDefaultPlannerLoader, self).setUp() 25 | self.loader = default.DefaultPlannerLoader() 26 | 27 | def test_endpoints(self): 28 | for endpoint in self.loader.list_available(): 29 | loaded = self.loader.load(endpoint) 30 | self.assertIsNotNone(loaded) 31 | self.assertIsInstance(loaded, planner.BasePlanner) 32 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/messaging/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/messaging/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/model/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/data/ironic_scenario_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | 6 | 7 | 8 | 9 | 2 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/data/scenario_1_with_all_nodes_disable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/data/scenario_1_with_metrics.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/data/scenario_3_with_2_nodes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/data/scenario_4_with_1_node_no_instance.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/data/scenario_5_with_instance_disk_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/model/notification/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/capacity.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "publisher_id": "capacity.host1@backend1#pool1", 4 | "event_type": "capacity.pool", 5 | "payload": { 6 | "name_to_id": "capacity.host1@backend1#pool1", 7 | "total": 3, 8 | "free": 1, 9 | "allocated": 2, 10 | "provisioned": 2, 11 | "virtual_free": 1, 12 | "reported_at": "2017-05-15T13:42:11Z" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario3_service-update-disabled.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "payload": { 4 | "nova_object.namespace": "nova", 5 | "nova_object.name": "ServiceStatusPayload", 6 | "nova_object.version": "1.0", 7 | "nova_object.data": { 8 | "host": "hostname_0", 9 | "disabled": true, 10 | "last_seen_up": "2012-10-29T13:42:05Z", 11 | "binary": "nova-compute", 12 | "topic": "compute", 13 | "disabled_reason": "watcher_disabled", 14 | "report_count": 1, 15 | "forced_down": true, 16 | "version": 15 17 | } 18 | }, 19 | "event_type": "service.update", 20 | "publisher_id": "nova-compute:Node_0" 21 | } 22 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario3_service-update-enabled.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "payload": { 4 | "nova_object.namespace": "nova", 5 | "nova_object.name": "ServiceStatusPayload", 6 | "nova_object.version": "1.0", 7 | "nova_object.data": { 8 | "host": "hostname_0", 9 | "disabled": false, 10 | "last_seen_up": "2012-10-29T13:42:05Z", 11 | "binary": "nova-compute", 12 | "topic": "compute", 13 | "disabled_reason": null, 14 | "report_count": 1, 15 | "forced_down": false, 16 | "version": 15 17 | } 18 | }, 19 | "event_type": "service.update", 20 | "publisher_id": "nova-compute:Node_0" 21 | } 22 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario_1_bootable-volume-create.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "publisher_id": "volume.host_0@backend_0#pool_0", 4 | "event_type": "volume.create.end", 5 | "payload": { 6 | "host": "host_0@backend_0#pool_0", 7 | "volume_id": "990a723f-6c19-4f83-8526-6383c9e9389f", 8 | "display_name": "name_00", 9 | "size": "40", 10 | "status": "available", 11 | "volume_attachment": [{"server_id": "server", "attachment_id": "attachment"}], 12 | "snapshot_id": "", 13 | "tenant_id": "52044438-21f2-4a48-add4-d48bab20f7e1", 14 | "metadata": {"readonly": false, "attached_mode": "rw"}, 15 | "glance_metadata": {} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario_1_capacity.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "publisher_id": "capacity.host_0@backend_0#pool_0", 4 | "event_type": "capacity.pool", 5 | "payload": { 6 | "name_to_id": "host_0@backend_0#pool_0", 7 | "total": 500, 8 | "free": 460, 9 | "allocated": 40, 10 | "provisioned": 40, 11 | "virtual_free": 460, 12 | "reported_at": "2017-05-15T13:42:11Z" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario_1_capacity_node_notfound.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "publisher_id": "capacity.host_2@backend_2#pool_0", 4 | "event_type": "capacity.pool", 5 | "payload": { 6 | "name_to_id": "host_2@backend_2#pool_0", 7 | "total": 500, 8 | "free": 460, 9 | "allocated": 40, 10 | "provisioned": 40, 11 | "virtual_free": 460, 12 | "reported_at": "2017-05-15T13:42:11Z" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario_1_capacity_pool_notfound.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "publisher_id": "capacity.host_0@backend_0#pool_2", 4 | "event_type": "capacity.pool", 5 | "payload": { 6 | "name_to_id": "host_0@backend_0#pool_2", 7 | "total": 500, 8 | "free": 380, 9 | "allocated": 120, 10 | "provisioned": 120, 11 | "virtual_free": 380, 12 | "reported_at": "2017-05-15T13:42:11Z" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario_1_error-volume-create.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "publisher_id": "volume.host_0@backend_0#pool_0", 4 | "event_type": "volume.create.end", 5 | "payload": { 6 | "host": "", 7 | "volume_id": "990a723f-6c19-4f83-8526-6383c9e9389f", 8 | "display_name": "name_00", 9 | "size": "40", 10 | "status": "error", 11 | "volume_attachment": [], 12 | "snapshot_id": "", 13 | "tenant_id": "52044438-21f2-4a48-add4-d48bab20f7e1", 14 | "metadata": {} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario_1_volume-attach.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "publisher_id": "volume.host_0@backend_0#pool_0", 4 | "event_type": "volume.attach.end", 5 | "payload": { 6 | "host": "host_0@backend_0#pool_0", 7 | "volume_id": "5028b1eb-8749-48ae-a42c-5bdd1323976f", 8 | "display_name": "name_0", 9 | "size": "40", 10 | "status": "in-use", 11 | "volume_attachment": [{"server_id": "server", "attachment_id": "attachment"}], 12 | "snapshot_id": "", 13 | "tenant_id": "91FFFE30-78A0-4152-ACD2-8310FF274DC9", 14 | "metadata": {"readonly": false, "attached_mode": "rw"} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario_1_volume-create.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "publisher_id": "volume.host_0@backend_0#pool_0", 4 | "event_type": "volume.create.end", 5 | "payload": { 6 | "host": "host_0@backend_0#pool_0", 7 | "volume_id": "990a723f-6c19-4f83-8526-6383c9e9389f", 8 | "display_name": "name_00", 9 | "size": "40", 10 | "status": "available", 11 | "volume_attachment": [{"server_id": "server", "attachment_id": "attachment"}], 12 | "snapshot_id": "", 13 | "tenant_id": "52044438-21f2-4a48-add4-d48bab20f7e1", 14 | "metadata": {"readonly": false, "attached_mode": "rw"} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario_1_volume-create_pool_notfound.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "publisher_id": "volume.host_2@backend_2#pool_0", 4 | "event_type": "volume.create.end", 5 | "payload": { 6 | "host": "host_2@backend_2#pool_0", 7 | "volume_id": "990a723f-6c19-4f83-8526-6383c9e9389f", 8 | "display_name": "name_00", 9 | "size": "40", 10 | "status": "available", 11 | "volume_attachment": [{"server_id": "server", "attachment_id": "attachment"}], 12 | "snapshot_id": "", 13 | "tenant_id": "52044438-21f2-4a48-add4-d48bab20f7e1", 14 | "metadata": {"readonly": false, "attached_mode": "rw"} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario_1_volume-delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "publisher_id": "volume.host_0@backend_0#pool_0", 4 | "event_type": "volume.delete.end", 5 | "payload": { 6 | "host": "host_0@backend_0#pool_0", 7 | "volume_id": "5028b1eb-8749-48ae-a42c-5bdd1323976f", 8 | "display_name": "name_0", 9 | "size": "40", 10 | "status": "deleting", 11 | "volume_attachment": [{"server_id": "server", "attachment_id": "attachment"}], 12 | "snapshot_id": "", 13 | "tenant_id": "91FFFE30-78A0-4152-ACD2-8310FF274DC9", 14 | "metadata": {"readonly": false, "attached_mode": "rw"} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario_1_volume-detach.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "publisher_id": "volume.host_0@backend_0#pool_0", 4 | "event_type": "volume.detach.end", 5 | "payload": { 6 | "host": "host_0@backend_0#pool_0", 7 | "volume_id": "5028b1eb-8749-48ae-a42c-5bdd1323976f", 8 | "display_name": "name_0", 9 | "size": "40", 10 | "status": "available", 11 | "volume_attachment": [], 12 | "snapshot_id": "", 13 | "tenant_id": "91FFFE30-78A0-4152-ACD2-8310FF274DC9", 14 | "metadata": {} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario_1_volume-resize.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "publisher_id": "volume.host_0@backend_0#pool_0", 4 | "event_type": "volume.resize.end", 5 | "payload": { 6 | "host": "host_0@backend_0#pool_0", 7 | "volume_id": "5028b1eb-8749-48ae-a42c-5bdd1323976f", 8 | "display_name": "name_0", 9 | "size": "20", 10 | "status": "in-use", 11 | "volume_attachment": [{"server_id": "server", "attachment_id": "attachment"}], 12 | "snapshot_id": "", 13 | "tenant_id": "91FFFE30-78A0-4152-ACD2-8310FF274DC9", 14 | "metadata": {"readonly": false, "attached_mode": "rw"} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/scenario_1_volume-update.json: -------------------------------------------------------------------------------- 1 | { 2 | "priority": "INFO", 3 | "publisher_id": "volume.host_0@backend_0#pool_0", 4 | "event_type": "volume.update.end", 5 | "payload": { 6 | "host": "host_0@backend_0#pool_0", 7 | "volume_id": "5028b1eb-8749-48ae-a42c-5bdd1323976f", 8 | "display_name": "name_01", 9 | "size": "40", 10 | "status": "enabled", 11 | "volume_attachment": [{"server_id": "server", "attachment_id": "attachment"}], 12 | "snapshot_id": "", 13 | "tenant_id": "91FFFE30-78A0-4152-ACD2-8310FF274DC9", 14 | "metadata": {"readonly": false, "attached_mode": "rw"} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/service-create.json: -------------------------------------------------------------------------------- 1 | { 2 | "event_type": "service.create", 3 | "payload": { 4 | "nova_object.data": { 5 | "availability_zone": null, 6 | "binary": "nova-compute", 7 | "disabled": false, 8 | "disabled_reason": null, 9 | "forced_down": false, 10 | "host": "host2", 11 | "last_seen_up": null, 12 | "report_count": 0, 13 | "topic": "compute", 14 | "uuid": "fafac544-906b-4a6a-a9c6-c1f7a8078c73", 15 | "version": 23 16 | }, 17 | "nova_object.name": "ServiceStatusPayload", 18 | "nova_object.namespace": "nova", 19 | "nova_object.version": "1.1" 20 | }, 21 | "priority": "INFO", 22 | "publisher_id": "nova-compute:host2" 23 | } 24 | 25 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/service-delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "event_type": "service.delete", 3 | "payload": { 4 | "nova_object.data": { 5 | "availability_zone": null, 6 | "binary": "nova-compute", 7 | "disabled": false, 8 | "disabled_reason": null, 9 | "forced_down": false, 10 | "host": "hostname_0", 11 | "last_seen_up": null, 12 | "report_count": 0, 13 | "topic": "compute", 14 | "uuid": "fa69c544-906b-4a6a-a9c6-c1f7a8078c73", 15 | "version": 23 16 | }, 17 | "nova_object.name": "ServiceStatusPayload", 18 | "nova_object.namespace": "nova", 19 | "nova_object.version": "1.1" 20 | }, 21 | "priority": "INFO", 22 | "publisher_id": "nova-compute:host2" 23 | } 24 | 25 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/model/notification/data/service-update.json: -------------------------------------------------------------------------------- 1 | { 2 | "event_type": "service.update", 3 | "payload": { 4 | "nova_object.data": { 5 | "availability_zone": null, 6 | "binary": "nova-compute", 7 | "disabled": false, 8 | "disabled_reason": null, 9 | "forced_down": false, 10 | "host": "host1", 11 | "last_seen_up": "2012-10-29T13:42:05Z", 12 | "report_count": 1, 13 | "topic": "compute", 14 | "uuid": "fa69c544-906b-4a6a-a9c6-c1f7a8078c73", 15 | "version": 23 16 | }, 17 | "nova_object.name": "ServiceStatusPayload", 18 | "nova_object.namespace": "nova", 19 | "nova_object.version": "1.1" 20 | }, 21 | "priority": "INFO", 22 | "publisher_id": "nova-compute:host1" 23 | } 24 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/planner/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/planner/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/planner/test_planner_manager.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | # Copyright (c) 2016 b<>com 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain 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, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 | # implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | from oslo_config import cfg 18 | 19 | from watcher.decision_engine.planner import manager as planner 20 | from watcher.decision_engine.planner import weight 21 | from watcher.tests import base 22 | 23 | 24 | class TestPlannerManager(base.TestCase): 25 | def test_load(self): 26 | cfg.CONF.set_override('planner', "weight", group='watcher_planner') 27 | manager = planner.PlannerManager() 28 | selected_planner = cfg.CONF.watcher_planner.planner 29 | self.assertIsInstance(manager.load(selected_planner), 30 | weight.WeightPlanner) 31 | -------------------------------------------------------------------------------- /watcher/tests/decision_engine/scope/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/scope/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/scoring/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/scoring/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/solution/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/solution/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/strategy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/strategy/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/strategy/context/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/strategy/context/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/strategy/selector/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/strategy/selector/__init__.py -------------------------------------------------------------------------------- /watcher/tests/decision_engine/strategy/strategies/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/decision_engine/strategy/strategies/__init__.py -------------------------------------------------------------------------------- /watcher/tests/fixtures/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/fixtures/__init__.py -------------------------------------------------------------------------------- /watcher/tests/notifications/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/notifications/__init__.py -------------------------------------------------------------------------------- /watcher/tests/objects/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/tests/objects/__init__.py -------------------------------------------------------------------------------- /watcher/version.py: -------------------------------------------------------------------------------- 1 | # Copyright 2011 OpenStack Foundation 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 pbr.version 17 | 18 | version_info = pbr.version.VersionInfo('python-watcher') 19 | version_string = version_info.version_string() 20 | -------------------------------------------------------------------------------- /watcher/wsgi/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/watcher/59757249bbbbb45bead28bfb2899242aea97dfc1/watcher/wsgi/__init__.py -------------------------------------------------------------------------------- /watcher/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 Watcher API.""" 13 | import threading 14 | from watcher.api import wsgi 15 | application = None 16 | with threading.Lock(): 17 | if application is None: 18 | application = wsgi.initialize_wsgi_app() 19 | --------------------------------------------------------------------------------