Compare commits

...

307 Commits

Author SHA1 Message Date
Zuul
d13adb4e3c Merge "Fix damodel list return None error When has a compute node" 2019-09-23 08:46:56 +00:00
Zuul
d11f43638c Merge "Fix misspelling" 2019-09-23 06:52:51 +00:00
chenke
2b63a35e86 Fix damodel list return None error When has a compute node
Reason:
When there is a compute node but no virtual machine,
the command 'watcher datamodel list' should display
the information of the compute node instead of return None.

Change-Id: Id5ff7f08ac8a9883af9f0313785b756d813ed5a2
Closes-Bug: #1844948
2019-09-23 14:04:16 +08:00
licanwei
4869449211 Fix misspelling
Depends-on: Ifa21645e19b8311de35cb9b0b8f39371b8713a2f
Depends-on:Ic2ae4cb758eba32f1b1529a24d12a57ca93a2a82
Change-Id: Ia1ea9814b8293e2bed989d700c7a813a97052f04
2019-09-23 04:29:47 +00:00
licanwei
42c1babfa4 skip deleted instance when creating datamodel
Change-Id: Ic2ae4cb758eba32f1b1529a24d12a57ca93a2a82
Closes-Bug: #1844949
2019-09-22 21:26:31 -07:00
licanwei
519ca2c9fb Fix unit test failed
ironic removed 'os_endpoint_type' and instead with 'interface'

Change-Id: Ifa21645e19b8311de35cb9b0b8f39371b8713a2f
2019-09-21 14:39:45 +08:00
Zuul
cca74f4698 Merge "Watcher planner slector releasenote" 2019-09-19 02:25:23 +00:00
Zuul
511a24e011 Merge "Set strategy planner" 2019-09-19 02:25:22 +00:00
Zuul
594a0d9b01 Merge "Get planner from solution" 2019-09-19 02:21:23 +00:00
licanwei
a88e076646 Watcher planner slector releasenote
Change-Id: I632a59d9e3cb6f5d0dad8987b1b01934d9ce0b42
Implements: bp watcher-planner-selector
2019-09-18 01:59:01 -07:00
licanwei
0559cd7a04 Set strategy planner
The default planner can not create actions with right order,
The node_resouce_consolidation strategy needs to use its
own planner.
Partially Implements: blueprint node-resource-consolidation
Depends-on: I586e67f782e2965234826634ba3ff51681af4df8
Change-Id: I05b02905a3335a73b6926966de6331c632842293
2019-09-17 19:42:32 -07:00
licanwei
0c191a2da9 Get planner from solution
support Strategy select different planner
Implements: bp watcher-planner-selector

Change-Id: I586e67f782e2965234826634ba3ff51681af4df8
2019-09-17 19:36:07 -07:00
Zuul
0b21ae333f Merge "Build pdf docs" 2019-09-18 02:00:24 +00:00
Zuul
62020cac30 Merge "Watcher Planner Selector" 2019-09-17 07:42:44 +00:00
Zuul
f5f9c95945 Merge "correct watcher project for oslo_config" 2019-09-17 06:57:22 +00:00
licanwei
ffd8e27bd1 Build pdf docs
Add a new pdf-docs environment to enable PDF build.
 sphinxcontrib-svg2pdfconverter is used to handle SVG properly.

Change-Id: I1563579486da8912ba8a220bb08a5331e7df910b
2019-09-16 23:09:25 -07:00
Zuul
004a46a98a Merge "Add node resource consolidation planner" 2019-09-17 04:44:21 +00:00
Zuul
3edd7f63c4 Merge "Add node_resource_consolidation doc" 2019-09-16 14:44:53 +00:00
Zuul
67e9e16d62 Merge "node resource consolidation" 2019-09-16 14:44:50 +00:00
licanwei
31460ac412 update test about cinderclient v1
Cinderclient removed support for Cinder v1 API
Closes-Bug: #1844094
https://review.opendev.org/#/c/653813/

Change-Id: I58c026f66ff210983367d0c98096347f7207c9fd
2019-09-16 15:18:32 +08:00
Guang Yee
86af6ab8a2 correct watcher project for oslo_config
It should've been "watcher" instead of "python-watcher" as the
config files are expected to be in /etc/watcher/. Though this is
unlikely to cause problems as this patch corrected the default
config dir.

https://review.opendev.org/#/c/658348/

Nevertheless, we should be using the correct name.

Change-Id: If6b58133eecf2fcc37e11d8c45eaa58f238ea2a8
2019-09-13 15:48:27 -07:00
Zuul
696d5d1fb5 Merge "Add releasenote about bp show-datamodel-api" 2019-09-12 05:57:42 +00:00
licanwei
605d7f228f Add node resource consolidation planner
Used for node resource consolidation strategy

Partially Implements: blueprint node-resource-consolidation

Change-Id: I7a51ddace86d512f2416dfd8af0bd3a31ca2d5c4
2019-09-12 11:03:59 +08:00
Egor Panfilov
aa2a084d22 Watcher Planner Selector
This component is responsible for selecting an appropriate Planner based
on predefined property value passed to concrete Strategy.

Change-Id: I86de95886df5d7e9558512569601e9ea3babb0e9
Implements: bp watcher-planner-selector
Co-Authored-By: Canwei Li <li.canwei2@zte.com.cn>
2019-09-12 11:01:47 +08:00
Zuul
e1b1d795a3 Merge "Fix misspell word" 2019-09-11 11:35:01 +00:00
Zuul
c356568fbe Merge "Remove redundant word 'strategy'" 2019-09-10 09:59:18 +00:00
Zuul
f274ef87ed Merge "Implement watcher datamodel list in watcher-api" 2019-09-10 07:34:13 +00:00
Zuul
0732485467 Merge "Implement watcher datamodel list in watcher-decision-engine" 2019-09-10 07:33:34 +00:00
Zuul
7d1b179d32 Merge "Add api-ref doc for data model api" 2019-09-10 07:02:10 +00:00
Zuul
0e40e72b45 Merge "add audit parameter to do_execute" 2019-09-10 07:02:09 +00:00
chenke
03a6216da0 Add releasenote about bp show-datamodel-api
Partially Implements:blueprint show-datamodel-api

Change-Id: I2f8a41cd8f9f805bd3796cbd639bec233546b521
2019-09-10 09:39:10 +08:00
licanwei
f1fe4b6c62 node resource consolidation
This strategy is used to centralize VMs to as few nodes as possible
by VM migration. User can set a input parameter to decide how to
select the destination node.

Implements: blueprint node-resource-consolidation
Closes-Bug: #1843016
Change-Id: I104c864d532c2092f5dc6f0c8f756ebeae12f09e
2019-09-06 18:03:43 -07:00
Q.hongtao
944fda338b Fix misspell word
Change-Id: I10e55a3305f7dbf3d4f5a35f61ba07783b49cc06
2019-09-06 16:49:33 +08:00
licanwei
020a99f077 Remove redundant word 'strategy'
Most of strategies have word 'strategy' in their display name.

Change-Id: I72504ba760c13685b5058524d202f00e01361403
2019-09-05 20:46:51 -07:00
licanwei
10d8a5fbc2 Add node_resource_consolidation doc
Partially Implements: blueprint node-resource-consolidation
Depends-on: Ia979781b32202c1821aa1cb91d24253fe6d7bd2d
Depends-on: I104c864d532c2092f5dc6f0c8f756ebeae12f09e

Change-Id: I8fa33a6559c9821e730f8e0babd8438ef45d7338
2019-09-05 00:58:58 -07:00
Zuul
845a9187e3 Merge "Add watcher-specs link to readme.rst" 2019-09-02 07:49:19 +00:00
liushuobj
3c0ee0caa6 Add watcher-specs link to readme.rst
Change-Id: Ie01f060846cd3876f39b0698879928abe4f504e7
2019-08-30 16:35:57 +08:00
licanwei
7eb10eee01 Add get node used and free resources
Many strategies need get node used or free resources, we define
two new method for the purpose in ModelRoot class.

Change-Id: I8cb41fd560dbac9a78d25bfdba51799533db83c2
2019-08-29 09:23:44 +08:00
Zuul
cdb81e43f6 Merge "improve strategies tempest" 2019-08-26 12:52:22 +00:00
chenke
d0a20fb072 Implement watcher datamodel list in watcher-api
1. Add datamodel api and policy_enfoce file.
2. Add related unittest for data_model api and policy.

Partially Implements:blueprint show-datamodel-api

Change-Id: I1654685d8cf04db5dd132d43a8640ddf91893cad
2019-08-26 20:09:23 +08:00
chenke
49fba60ecd Implement watcher datamodel list in watcher-decision-engine
1. Add datamodel list endpoint and rpc process.
2. Add datamodel list parased and return.
3. Add related unittest.

Partially Implements:blueprint show-datamodel-api

Change-Id: I758b7ca2bc3d8d596d3457277744336c6629bc4e
2019-08-26 18:46:27 +08:00
chenke
5aa4637fcf Add api-ref doc for data model api
Change-Id: I7d2203f35623ac6b0649ba5d99a04e9d6ca4430f
2019-08-26 17:31:06 +08:00
licanwei
b4a02a6d31 add audit parameter to do_execute
The new bp need to get audit type from audit,
so we need to add an audit parameter to do_execute

Partially Implements: blueprint node-resource-consolidation

Change-Id: Ia979781b32202c1821aa1cb91d24253fe6d7bd2d
2019-08-23 18:17:56 -07:00
licanwei
8ca5d65501 improve strategies tempest
watcher-tempest-strategies includes all strategies tempest,
we add it and remove all other individual strategy tempest.

Depends-on: I3e45d4a66a6e1bf55499def8550da38ddf01b638

Change-Id: I182bf0ddc528099f5115098b825e9bddae3b187a
2019-08-23 09:12:08 +00:00
licanwei
6ac6ab2444 add placement min_microversion
for tempest test

Change-Id: Ie98e2c000568ecac63e8981a8b7087029c0d3705
2019-08-22 23:48:11 -07:00
Zuul
7289243624 Merge "[train][goal] Define new 'watcher-tempest-functional-ipv6-only' job" 2019-08-23 03:05:20 +00:00
Zuul
1be3516d36 Merge "set compute min_microversion" 2019-08-22 08:01:23 +00:00
licanwei
d6fbc79742 set compute min_microversion
The min microversion that Watcher needed is 2.56.[1]

[1]:https://github.com/openstack/watcher/blob/master/watcher/common/clients.py

Change-Id: If21b0df50e2f2cc2884f531cb40084e95a688026
2019-08-20 14:18:08 +08:00
Ghanshyam Mann
26cce968e9 [train][goal] Define new 'watcher-tempest-functional-ipv6-only' job
As part of Train community goal 'Support IPv6-Only Deployments and Testing'[1],
Tempest has defined the base job 'devstack-tempest-ipv6' which will
deploy services on IPv6.

This commit adds the new job 'watcher-tempest-functional-ipv6-only'
run on gate which is derived from 'devstack-tempest-ipv6'.

Verification structure will be:
- 'devstack-IPv6' deploy the service on IPv6
- 'devstack-tempest-ipv6' run will verify the IPv6-only setting and listen address
- 'watcher-tempest-functional-ipv6-only' will run the tests.

Story: #2005477
Task: #35939

[1] https://governance.openstack.org/tc/goals/train/ipv6-support-and-testing.html

Change-Id: I42b7e5ff5fd64a21bdb8a32f319759a18c173601
2019-08-18 14:09:20 +00:00
Zuul
1bd580b7a8 Merge "Don't revert Migrate action" 2019-08-16 06:43:04 +00:00
licanwei
99cd009805 Remove unused disk_capacity field
The fields disk and disk_capacity have the same value,
we just need one, so remove disk_capacity field.
Partially Implements: blueprint improve-compute-data-model

Change-Id: If3d385c5e61713bbdc85e22f10cd75e161ff79f0
2019-08-13 17:15:52 +08:00
licanwei
c522e881b1 Don't revert Migrate action
If Migrate action succeed, don't revert instance when the actionplan failed.

Change-Id: Ic1c1151a3152e632ad90c6f006e8c7d5abded223
Closes-Bug: #1839909
2019-08-13 14:09:59 +08:00
Zuul
d55bb1fa95 Merge "update node resource capacity for basic_consolidation" 2019-08-12 02:15:58 +00:00
Zuul
5fe32a62e0 Merge "update workload_balance strategy" 2019-08-12 02:15:57 +00:00
Zuul
398532c995 Merge "update host_maintenance strategy" 2019-08-12 02:10:17 +00:00
Zuul
6d5a6b73e4 Merge "update vm_workload_consolidation strategy" 2019-08-12 02:10:16 +00:00
Zuul
44cd2a7421 Merge "add releasenote for bp improve-compute-data-model" 2019-08-12 02:10:16 +00:00
Zuul
4909c0203f Merge "update outlet_temp_control strategy" 2019-08-12 02:10:15 +00:00
Zuul
335e430f2a Merge "update noisy_neighbor strategy" 2019-08-12 02:07:04 +00:00
licanwei
5a26ceb1b9 update workload_balance strategy
For Compute node, we can use the new property to calculate
resource(VCPU, memory and disk).

Partially Implements: blueprint improve-compute-data-model
Depends-on: I3f9a3279a26f3df444117d9265e74cca57b38d6e
Change-Id: I9fe58603692a9850e86a2c36ad7a31c473070100
2019-08-09 14:30:43 +08:00
licanwei
33d7de12ef update node resource capacity for basic_consolidation
For Compute node, when calculating resource(VCPU, memory and disk)
capacity, we need to consider reserved resource and allocation ratio.

Partially Implements: blueprint improve-compute-data-model
Depends-on: I3f9a3279a26f3df444117d9265e74cca57b38d6e
Change-Id: I70257dd5fb342a67a3ffda1055eddc54b8360ca3
2019-08-09 14:19:51 +08:00
licanwei
3bcd25727f update host_maintenance strategy
For Compute node, we can use the new property to calculate
resource(VCPU, memory and disk).

Partially Implements: blueprint improve-compute-data-model
Depends-on: I3f9a3279a26f3df444117d9265e74cca57b38d6e
Change-Id: I2bb230b5f5a573fb3045261dfdee73f1a8434e0d
2019-08-09 14:15:52 +08:00
licanwei
60ef877626 update noisy_neighbor strategy
For Compute node, we can use the new property to calculate
resource(VCPU, memory and disk).

Partially Implements: blueprint improve-compute-data-model
Depends-on: I3f9a3279a26f3df444117d9265e74cca57b38d6e
Change-Id: I4f041ad25353d575c276fce87fe13c5e6705754f
2019-08-09 11:34:04 +08:00
licanwei
93b40e9262 update outlet_temp_control strategy
For Compute node, we can use the new property to calculate
resource(VCPU, memory and disk).

Partially Implements: blueprint improve-compute-data-model
Depends-on: I3f9a3279a26f3df444117d9265e74cca57b38d6e
Change-Id: Id113b4c19792946329e9ff448bfe636cc8eca057
2019-08-09 11:18:08 +08:00
licanwei
4b2238f9a5 add releasenote for bp improve-compute-data-model
Change-Id: I19780be28912cb0ea1cad49c7c0f43ab3ba8f6e7
Implements: blueprint improve-compute-data-model
2019-08-09 03:06:43 +00:00
licanwei
7420915244 update vm_workload_consolidation strategy
For Compute node, we can use the new property to calculate
resource(VCPU, memory and disk).

Partially Implements: blueprint improve-compute-data-model
Depends-on: I3f9a3279a26f3df444117d9265e74cca57b38d6e
Change-Id: I7872265b2378e5dc37aa2e086ff1f7fb9071db0b
2019-08-09 11:02:29 +08:00
licanwei
4e4cfc959b Remove resource used fields from ComputeNode
The node resource(vcpu, memory and disk) used infomation need
to change when creating or deleting instances. Now Placement do
not send notifications, so there is not a good way to capture
the change. We remove these fields and leave the process to strategy.

Partially Implements: blueprint improve-compute-data-model

Change-Id: I3f9a3279a26f3df444117d9265e74cca57b38d6e
2019-08-09 10:28:40 +08:00
Zuul
152af02bf1 Merge "Fix var src_extra_specs error" 2019-08-08 02:50:48 +00:00
chenke
cbc2b9eb37 Fix var src_extra_specs error
This error was discovered by tool coverity. If we don't
initialize this var src_extra_specs, line 225 may sometimes
raise an error.

Change-Id: I992b56b64d56f35c8355b22707c3db5112964b31
2019-08-06 11:34:59 +08:00
chenke
251ad35c8b Remove stale comment in method execute()
The code associated with virtual has been removed before,
and the relevant comments should be removed here.

Change-Id: I7104c1a6752ad0b8c9837a643e51b0a13194a81b
2019-08-05 09:10:13 +08:00
Zuul
f2020a9283 Merge "Getting data from placement when updating datamodel" 2019-07-29 06:03:32 +00:00
Zuul
503e67f82e Merge "Check resource class before using" 2019-07-29 03:45:25 +00:00
Zuul
c0bba3ecf3 Merge "replace disk_capacity by disk" 2019-07-29 03:43:52 +00:00
licanwei
0b25c884e6 Add resource capacity property
Resource(VCPU, memory and disk) capacity need to be calculated
through formula: capacity = (total-reserved)*ratio.

Partially Implements: blueprint improve-compute-data-model

Change-Id: I15ca66dd2c3a21c5acfebf6f04fa6601aff7918f
2019-07-27 15:41:04 +08:00
licanwei
86d9cf17a2 Getting data from placement when updating datamodel
We have some new fields(vcpus_ratio, vcpus_used, ...)
in the Watcher ComputeNode. During the process of updating
data model by notifications, we need to get data from
placement.

Partially Implements: blueprint improve-compute-data-model

Change-Id: I10587e93bb3e7be6af78bb3a50509d82d8228f78
2019-07-27 15:03:13 +08:00
Zuul
9b4693a105 Merge "set disk field to disk capacity" 2019-07-27 03:05:43 +00:00
licanwei
86ea9c8e7b replace disk_capacity by disk
Partially Implements: blueprint improve-compute-data-model

Change-Id: I9af8d3e5ad3288d56f9ef5ef998b56f9a3e6622d
2019-07-27 10:23:21 +08:00
Zuul
4ae51c58bd Merge "Optimize method list_opts() in watcher/conf/opts.py" 2019-07-26 10:12:38 +00:00
Zuul
56ab717d25 Merge "Remove useless gconfig process in watcher/api/scheduling.py" 2019-07-26 10:12:15 +00:00
licanwei
6cc9ea7cfb set disk field to disk capacity
The node.free_disk_gb does not take allocation ratios used
for overcommit into account so this value may be negative.
We do not need this field and plan to set disk to total disk
capacity and then remove disk_capacity.

Partially Implements: blueprint improve-compute-data-model

Change-Id: I72c4490f5a8d0fbd1039f70ff20f07b743b6bb2d
2019-07-26 17:23:18 +08:00
licanwei
0986168fe6 Check resource class before using
check if the resource class(VCPU, memory, disk) in the return
dictionary. If they are, don't need to use dict.get() with a
default value because the parameters are required.

Partially Implements: blueprint improve-compute-data-model

Change-Id: Icb8c672d0e87e6e5f030a2222f928d1bbd069e3c
2019-07-26 14:26:08 +08:00
Zuul
e0f70cb87c Merge "remove id field from CDM" 2019-07-24 07:30:00 +00:00
Zuul
672066d982 Merge "Update api-ref location" 2019-07-24 07:29:58 +00:00
licanwei
4b83bf33e2 remove id field from CDM
There are 3 related fields(id, uuid and hostname) in ComputeNode[1].
according to [2], after nova api 2.53, the id of the hypervisor as a UUID.
and service.host is equal to hypervisor name for compute node.
so we can remove id and only keep uuid then set uuid to node.id

[1]:https://github.com/openstack/watcher/blob/master/watcher/decision_engine/model/collector/nova.py#L306
[2]:https://developer.openstack.org/api-ref/compute/?expanded=list-hypervisors-details-detail#list-hypervisors-details

Change-Id: Ie1d1ad56808270d936ec25186061f7f12cc49fdc
Closes-Bug: #1835192
Depends-on: I752fbfa560313e28e87d83e46431c283b4db4f23
Depends-on: I0975500f359de92b6d6fdea2e01614cf0ba73f05
2019-07-23 10:28:47 +08:00
Andreas Jaeger
54344208fc Update api-ref location
The api documentation is now published on docs.openstack.org instead
of developer.openstack.org. Update all links that are changed to the
new location.

Note that redirects will be set up as well but let's point now to the
new location.

For details, see:
http://lists.openstack.org/pipermail/openstack-discuss/2019-July/007828.html

Change-Id: I4101eced9c4bd26741f760e5651204f5d2dfea0f
2019-07-22 19:00:11 +02:00
licanwei
3d741d05aa Improve Compute Data Model
The fields(vcpus, memory and disk_capacity) in the Watcher ComputeNode
do not take allocation ratios used for overcommit into account so there
may be disparity between this and the used count.
This patch added some new fields to solve this problem.

Partially Implements: blueprint improve-compute-data-model

Change-Id: Id33496f368fb23cb8e744c7e8451e1cd1397866b
2019-07-22 10:22:35 +08:00
Zuul
cd86e85ae8 Merge "Add reource_name for save_energy in action input parameter field" 2019-07-20 02:59:24 +00:00
Zuul
885ec20c94 Merge "Add call_retry for ModelBuilder for error recovery" 2019-07-20 02:58:10 +00:00
Zuul
1f9abe6785 Merge "Replace human_id with name in grafana doc" 2019-07-20 02:31:19 +00:00
Dantali0n
cadc000f32 Add call_retry for ModelBuilder for error recovery
Add call_retry method for ModelBuilder classes along with configuration
options. This allows ModelBuilder classes to reattempt any failed calls
to external services such as Nova or Ironic.

Change-Id: Ided697adebed957e5ff13b4c6b5b06c816f81c4a
2019-07-19 16:09:18 +02:00
Zuul
1af7ac107c Merge "Baseclass for ModelBuilder with audit scope" 2019-07-19 13:34:42 +00:00
Zuul
3a1e83dd9d Merge "Move datasources folder into decision_engine" 2019-07-19 13:27:10 +00:00
chenke
361f22638f Remove useless gconfig process in watcher/api/scheduling.py
Change-Id: I3849453286a735fbe95984e8496fd8a2fcb156b4
2019-07-18 16:05:24 +08:00
chenke
458ad08693 Optimize method list_opts() in watcher/conf/opts.py
Actually list_opts() return a list like[1], So we don't need to
convert list to dict and then convert to list[2].

The reason why we need to convert it before is to put together
the same group of configuration objects, but we don't need it
actually.

Now, the list_opts()'s result like this[3].

Reference:
[1]. [(Group1,[cfgObj1,cfgObj2....]),(Group2,[cfgObj3,cfgObj3....])..]
[2]. 375ae32fad/watcher/conf/opts.py (L51-L52)
[3]. [(Group1,[cfgObj1]),(Group1,[cfgObj2]),(Group2,[cfgObj3,cfgObj3....])..]

Change-Id: I50fcc5f812be42038852662639fb10c6dd2f6f72
2019-07-18 13:23:04 +08:00
Zuul
375ae32fad Merge "Fix watcher/conf/applier.py default worker value" 2019-07-18 03:08:56 +00:00
chenke
d5126174c0 Fix watcher/conf/applier.py default worker value
The default value of worker should be int type.

Change-Id: Ie2aa0c34ffbb7fa86154cc5c8ce2c365579d3fb1
2019-07-17 13:34:56 +08:00
chenke
904720b020 Remove useless _opts.py
This file has not been used.

Change-Id: Ie53dca6673f87bfeded74e336f3d60fbf500caf8
2019-07-16 19:36:16 +08:00
Zuul
4b8fe2745d Merge "Remove redundant human_id fields when creating and updating datamodel" 2019-07-16 11:11:26 +00:00
Dantali0n
933bc59b39 Baseclass for ModelBuilder with audit scope
This lets all the ModelBuilder classes use one baseclass and forces
ClusterDataModelCollector's to pass the scope.

The scopes are still unused in the case of Ironic and Cinder.

The idea is to do several follow ups to this and in the end have a
similar method to query_retry in the datasources baseclass.

Change-Id: Ibbdedd3087fef5298d7f4c9d3abdba05d1fbb2f0
2019-07-15 22:32:14 +02:00
Zuul
7cc5aef03f Merge "Add get_compute_node_by_uuid" 2019-07-13 08:42:08 +00:00
Dantali0n
433eabb8d1 Move datasources folder into decision_engine
The datasources are only used by the decision_engine, however, they
are placed in a directory one level higher. This patch moves the
datasources code into the decision_engine folder.

Change-Id: Ia54531fb899b79a59bb77adea079ff27c0d518fa
2019-07-12 08:54:09 +02:00
chenke
0727c0e302 Add reource_name for save_energy in action input parameter field
(Partial implement)
Implements: blueprint add-resource-name-in-action-input-parameter-field

Change-Id: Icd9ee099bb769679b0313025e841c898a0fa2c6f
2019-07-12 13:42:45 +08:00
licanwei
3009716ded Add get_compute_node_by_uuid
We want to set the value of uuid field of Watcher ComputeNode
to hypversion id(as uuid). So we need to get hypervisor
information by uuid.

Change-Id: I752fbfa560313e28e87d83e46431c283b4db4f23
Related-Bug: #1835192
2019-07-12 10:27:47 +08:00
Zuul
233a2b5585 Merge "Releasenote for grafana datasource" 2019-07-12 02:19:17 +00:00
Zuul
2365418e1b Merge "Grafana proxy datasource to retrieve metrics" 2019-07-12 02:19:16 +00:00
Zuul
cd70ad0d01 Merge "Add reource_name for zone_migration in action input parameter field" 2019-07-12 02:19:15 +00:00
Zuul
3bc426a590 Merge "remove baremetal nodes when building CDM" 2019-07-12 02:18:25 +00:00
Zuul
a4cbe69d57 Merge "Add get_node_by_name" 2019-07-12 02:18:24 +00:00
Dantali0n
80e8d0002a Resolve aggregate error in workload_stabilization
This error is caused because the condition "is not '':" is not always
true. Sometimes self.aggregation_method['node'] is u'' instead of ''.
This patch ensures that in both cases the behavior is the same.

Change-Id: I7453678cc76892ebeacca23c3501a10a08725d1d
Closes-bug: #1836195
2019-07-11 14:54:04 +02:00
Zuul
5259e5b332 Merge "Add marker option for get_instance_list()" 2019-07-11 09:21:17 +00:00
chenke
6dd35a0058 Remove redundant human_id fields when creating and updating datamodel
For the reason, please see:
[1]. http://eavesdrop.openstack.org/irclogs/%23openstack-watcher/%23openstack-watcher.2019-06-19.log.html
[2]. http://eavesdrop.openstack.org/meetings/watcher/2019/watcher.2019-06-19-08.00.log.html#l-47

Change-Id: I4284397aa987565f4cfc2697907a879d7d6492e9
Related-Bug: #1833665
2019-07-10 15:21:40 +08:00
chenke
8cb7158790 Replace human_id with name in grafana doc
This patch does two things:

1. replace instance's human_id with name.
2. remove ComputeNode human_id.

Now name field in Watcher Compute Data Model is availible.
Use name is better than human_id. For the reason, please see[1].

[1]. https://bugs.launchpad.net/watcher/+bug/1833665

Change-Id: I04f40e7d2a2bda48e9a362f9d0b23f449c40324e
2019-07-10 15:10:59 +08:00
Zuul
a01b4ddc81 Merge "Add reource_name in action input parameter field" 2019-07-10 06:57:36 +00:00
chenke
502ed741d6 Add marker option for get_instance_list()
Change-Id: Iee31369876052a22e5f3263cd5e7fad5d068f68d
2019-07-10 14:42:45 +08:00
licanwei
256104a38a remove baremetal nodes when building CDM
aggregate list and availability_zone list may return ironic type
compute nodes. When building compute data model we should check
the hypervisor_type and remove ironic compute nodes.

Change-Id: Idf404c104c30368baf95ef7d05ad8fc3e7adca38
Related-Bug: #1835183
2019-07-10 14:03:31 +08:00
chenke
612fc12af1 Add reource_name for zone_migration in action input parameter field
(Partial implement)
Implements: blueprint add-resource-name-in-action-input-parameter-field

Depends-on: I708cf63ff1d9a989604e1d5b834c8b7e5b087892
Change-Id: I5428fb7a1195a39f15f36509997ff5ad6fda4bb7
2019-07-10 09:57:42 +08:00
Dantali0n
0541d8c25b Grafana proxy datasource to retrieve metrics
New datasource to retrieve metrics that can be configured in a
flexible way depending on the deployment. Current implemenation only
works with InfluxDB. Slight changes to datasource manager were
necessary because grafana metric_map can only be built at runtime.

The yaml configuration file can still be used to define metrics
but will require that five different attributes are specified per
metric.

Specific databases accesible through grafana can be defined by
creating 'translators' for these specific databases. This patch
introduces a base class for these translators and their methods.

In addition the first translator specific for InfluxDB is
created.

Depends-on: I68475883529610e514aa82f1881105ab0cf24ec3
Depends-on: If1f27dc01e853c5b24bdb21f1e810f64eaee2e5c
Implements: blueprint grafana-proxy-datasource
Change-Id: Ib12b6a7882703e84a27c301e821c1a034b192508
2019-07-09 16:22:00 +02:00
chenke
dc2c361d04 Add reource_name in action input parameter field
(Partial implement)
Implements: blueprint add-resource-name-in-action-input-parameter-field

Depends-on: I51d879e31dee03652ee9d0d94a7f3168012cc060
Change-Id: I708cf63ff1d9a989604e1d5b834c8b7e5b087892
2019-07-09 18:40:49 +08:00
Zuul
de38a171fe Merge "remove baremetal nodes from hypversior list" 2019-07-09 08:38:46 +00:00
Zuul
5b12642c1d Merge "Remove notifier_driver option in Watcher devstack" 2019-07-09 08:24:50 +00:00
licanwei
a3c49cf8a4 Add get_node_by_name
We want to set the value of uuid field of Watcher ComputeNode
to hypversion id(as uuid). We need a method to get compute
node by name.

Change-Id: I0975500f359de92b6d6fdea2e01614cf0ba73f05
Related-Bug: #1835192
2019-07-09 07:03:29 +00:00
Zuul
46cc09f00e Merge "Reduce the query time of the instances when call get_instance_list()" 2019-07-09 03:54:20 +00:00
Zuul
651988448b Merge "Add name field for test data" 2019-07-08 02:36:46 +00:00
chenke
1e8b17ac46 Reduce the query time of the instances when call get_instance_list()
The problem is that watcher is passing limit=-1 to novaclient when
listing servers which will always make at least two API calls to be
sure it's done paging:

https://github.com/openstack/python-novaclient/blob/13.0.1/novaclient/v2/servers.py#L896

If we can determine before we list servers that there are only a
certain number where the number of servers is less than 1000. For
example: 4, we should just pass the limit=len(servers) to novaclient
and avoid the second call for paging which takes extra time and
yields no results.

Change-Id: I797ad934a0f8496dbcbf65798e28b0443f238137
Closes-Bug: #1834679
2019-07-08 09:58:01 +08:00
licanwei
ac53dbf005 remove baremetal nodes from hypversior list
openstack hypervisor list contains ironic nodes. we should
filter out baremetal nodes when get compute node list.

Change-Id: I4ab3e1a63dc6f61cdc3e99fa2cae749a711459cc
Closes-Bug: #1835183
2019-07-04 16:40:01 +08:00
Zuul
242c7feca7 Merge "Blacklist sphinx 2.1.0 (autodoc bug)" 2019-07-04 06:34:40 +00:00
licanwei
8bddafbdc3 Remove notifier_driver option in Watcher devstack
According to https://review.opendev.org/#/c/251791/,
watcher_messaging group and notifier_driver option
were deprecated.

Change-Id: I2cd114060d1960f77dfa8f4fe0a6d0fc05de5d4c
2019-07-04 01:59:57 +00:00
Zuul
e01382cd12 Merge "Add Python 3 Train unit tests" 2019-07-03 15:14:53 +00:00
Zuul
fd2885932d Merge "Improve logging in building of nova data model" 2019-07-03 14:14:07 +00:00
Zuul
daa70cf6b2 Merge "improve OptGroup consistency across configuration" 2019-07-03 11:45:00 +00:00
Dantali0n
052fae4b62 Improve logging in building of nova data model
Improves logging during the building of the nova data model

Change-Id: Ieff571a6ee2d1a2ced9776a8e4800d5d6f2d95eb
2019-07-03 11:25:20 +02:00
Zuul
8ccee88296 Merge "Configure nova notification_format for grenade" 2019-07-02 16:49:51 +00:00
Dantali0n
a45f5abe48 Releasenote for grafana datasource
This is the releasenote for the new grafana datasource it refers to
the documentation on configuring grafana.

Depends-on: Ib12b6a7882703e84a27c301e821c1a034b192508
Change-Id: Icb3939d772f06ad2d66eeba9a59fa8b60822ece0
2019-07-02 10:20:49 +02:00
Dantali0n
cebee2c4d7 improve OptGroup consistency across configuration
This is a follow-up to: https://review.opendev.org/#/c/666897/
and makes sure titles and help information get rendered in
the configuration documentation and configuration samples.

The options for the placement_client group are already changed
and left untouched as a result. The changes to grafana_client
are already done in another patch and also untouched.

Change-Id: Ia33cd4576e4b55e651f3f3779a01f2867126138d
2019-07-01 09:29:14 +02:00
pengyuesheng
dd1800fbc1 Blacklist sphinx 2.1.0 (autodoc bug)
See https://github.com/sphinx-doc/sphinx/issues/6440 for upstream details
Depend-On: https://review.opendev.org/#/c/663060/

Change-Id: I1a5b87b5771b9fd8f7ccdd6fd83f7ed0d7bfef64
2019-07-01 14:59:18 +08:00
pengyuesheng
148ae3688d Add Python 3 Train unit tests
See the Train python3-updates goal document for details:
https://governance.openstack.org/tc/goals/train/python3-updates.html

Change-Id: I11f7aafdfb3a45569b021df748ea32ebddc4ba6b
2019-07-01 14:57:27 +08:00
Zuul
4d35aabfdf Merge "Fix invalid assert states" 2019-07-01 06:24:53 +00:00
zhufl
8fc4a9cbee Fix invalid assert states
"self.assertTrue(action.state, objects.action.State.SUCCEEDED)"
and "self.assertTrue(action.state, objects.action.State.FAILED)"
should use assertEqual.

Co-Authored-By: Canwei Li <li.canwei2@zte.com.cn>
Change-Id: I8e28d651938ca6ed8d12e8a6f5ecf775cf01a39c
2019-07-01 03:20:19 +00:00
chenke
0a435f0b5e Add name field for test data
Change-Id: I51d879e31dee03652ee9d0d94a7f3168012cc060
2019-06-29 14:55:58 +08:00
Zuul
1b41d92b9e Merge "Add uWSGI support" 2019-06-28 02:29:16 +00:00
Zuul
c90c4989f6 Merge "Configure nova notification format in non-grenade CI jobs" 2019-06-28 02:29:14 +00:00
Zuul
f335b6dff2 Merge "improve the process of instance_created.end" 2019-06-28 02:29:11 +00:00
Zuul
0915d991b4 Merge "Add name for instance in Watcher datamodel" 2019-06-28 02:20:27 +00:00
Zuul
f75cf1ddff Merge "Improve the configuration parameters for grafana" 2019-06-27 07:03:21 +00:00
licanwei
c1a5e443fe Add uWSGI support
This patch implements uWSGI support for Watcher API service.
Because mod_wsgi is deprecated, using uwsgi to replace of mod_wsgi.
Most of Openstack projects have finished it.

Closes-Bug: #1834392
Change-Id: I3fad8d30a15aba493fb91da9337c2515ddea5167
2019-06-27 14:56:52 +08:00
Zuul
550b10b586 Merge "Documentation configuring grafana datasource" 2019-06-27 06:30:32 +00:00
chenke
b62965c2bf Add name for instance in Watcher datamodel
Now Watcher's datamodel uses human_id to store the display_name
of the intance. But the value of human_id is not reliable. About
the reason, please see[1].

The solution is to add a 'name' field to save the display_name of
the instance, and ensure that the value of this field is the same
when the datamodel is created and when the datamodel is updated.

About the 'human_id', We will remove it in the future.

References:
[1]. https://bugs.launchpad.net/watcher/+bug/1833665

20190619 Watcher meeting IRC Log:
[1]. http://eavesdrop.openstack.org/irclogs/%23openstack-watcher/%23openstack-watcher.2019-06-19.log.html
[2]. http://eavesdrop.openstack.org/meetings/watcher/2019/watcher.2019-06-19-08.00.log.html#l-47

Change-Id: I6976759629a4feedee09261cc1dac935e050202a
Closes-Bug: #1833665
2019-06-26 22:29:12 +08:00
Dantali0n
fa1642e323 Documentation configuring grafana datasource
Documentation for administrators on how to configure the Grafana
datasource.

Change-Id: I5d1d3129b5d225f0f2fc86d149c046f9aab94d47
2019-06-26 10:58:14 +02:00
Zuul
aa70cd8b1a Merge "Fix placement_client group help docs generation" 2019-06-26 07:29:05 +00:00
Matt Riedemann
9c9f336f10 Configure nova notification_format for grenade
Nova changed the default notification_format from "both" to
"unversioned" in Train [1]. Without configuring nova in the
grenade job we are not testing the nova versioned notification
handler code during upgrades.

Note that grenade only runs stack.sh on the base (old) side so
this change has to depend on a devstack stable/stein change to
add the NOVA_NOTIFICATION_FORMAT variable that we override.

Closes-Bug: #1831917

Depends-On: Ied9d50b07c368d5c2be658c744f340a8d1ee41e0

[1] https://review.opendev.org/603079/

Change-Id: I94c2d14477da185310e0fec596a1ad6436b802f1
2019-06-25 11:06:43 -04:00
Matt Riedemann
5f521471e1 Fix placement_client group help docs generation
To get the placement_client OptGroup help text to generate
in the docs, we have to use the OptGroup object in the
list_opts() method rather than a string for the group name.

https://docs.openstack.org/oslo.config/latest/cli/generator.html#defining-option-discovery-entry-points

Change-Id: Ie728081caa205ded2435c6b95f5e8d4bbd23372c
2019-06-24 14:52:02 -04:00
Dantali0n
d08d7c396e Improve the configuration parameters for grafana
This improves the documentation on configuration parameters for the
Grafana datasource.

Follow-up: If1f27dc01e853c5b24bdb21f1e810f64eaee2e5c
Depends-on: I5d1d3129b5d225f0f2fc86d149c046f9aab94d47
Change-Id: Ifd8be7491669c429482d880fdf0219be5ef03163
2019-06-24 14:38:42 -04:00
Matt Riedemann
966a4dfa5f Configure nova notification format in non-grenade CI jobs
Nova used to emit versioned and unversioned notiifcations
by default but that changed in https://review.opendev.org/603079/
so now nova emits only unversioned notifications by default.
Watcher listens for versioned notifications so we need to configure
nova to emit both versioned (for Watcher) and unversioned
(for Ceilometer) notifications explicitly.

This adds an override-defaults file so devstack will load up
the nova devstack variable to set the notification_format before
importing and stacking the nova lib script.

Note that this only fixes the non-grenade CI jobs since grenade
requires separate handling for overriding defaults which is proving
hard to do and will be addressed in a separate change.

Partial-Bug: #1831917

Change-Id: I7e441608b38338eecd80e663ed3abe66a89e504f
2019-06-24 13:09:34 -04:00
Zuul
899e534761 Merge "check instance state for instance.update" 2019-06-24 03:54:52 +00:00
Zuul
d046606a7e Merge "remove tail_log" 2019-06-22 02:31:12 +00:00
licanwei
dd321e9f21 improve the process of instance_created.end
In the process of handling instance_created.end,
there is a KeyError exception output log. This is because
invoking get_instance_by_uuid before creating the instance
in the data model.
During the review of https://review.opendev.org/#/c/663489/,
reviewers think that it's better to remove the KeyError exception.
This patche seperates the process of instance_created.end from
other Nova notifications and removes the call of get_instance_by_uuid.

Change-Id: Ie9e2d4f5b32ee7a5b52bbcd50abfa81dcabab7bb
2019-06-21 16:53:25 +08:00
Zuul
d98f51c452 Merge "Implement the configuration for Grafana datasource" 2019-06-21 02:52:24 +00:00
Zuul
5effcde632 Merge "Update strategy doc" 2019-06-21 01:37:39 +00:00
licanwei
9b8d1445f1 remove tail_log
tail_log is deprecated and should be removed
https://github.com/openstack/devstack/blob/master/functions-common#L1611

Change-Id: I6012fd63aa6b0cdb8ed1b278880f8f6c3e4d38cf
2019-06-20 15:28:33 +08:00
licanwei
90291923a1 Update strategy doc
Ceilometer removed cpu_util metric in [1].
Another metric compute.node.cpu.percent need to set
compute_monitors option to cpu.virt_driver in the
nova.conf, we should remind user about these.
[1]: https://review.opendev.org/#/c/580709/

Change-Id: I89306ef7c26fa2927945bd4f3ee88b670511d147
2019-06-20 10:57:05 +08:00
Dantali0n
06f8aa712a Implement the configuration for Grafana datasource
This implements the configuration parameters to implement
Grafana as a datasource including the influxdb translator

Change-Id: If1f27dc01e853c5b24bdb21f1e810f64eaee2e5c
Partially-implements: blueprint grafana-proxy-datasource
2019-06-19 15:58:18 +02:00
zhufl
37b11fa404 Fix missing print format
This is to add missing print format in placement_helper.py.

Change-Id: I23492fd33f3df8c8709f6d6317c936221f1108d4
2019-06-19 11:43:18 +08:00
Zuul
fd04c67ed8 Merge "Map instance to its node" 2019-06-19 02:44:58 +00:00
Zuul
08622c6c80 Merge "typo ceilometer url" 2019-06-19 02:44:57 +00:00
licanwei
e4fc5a08ed typo ceilometer url
Change-Id: I2cb24249ed1e82dd85c0f586532e5a7cbc57f2c0
2019-06-18 19:29:00 +08:00
Zuul
413028e527 Merge "Fix base enable_plugin branch for grenade run" 2019-06-18 07:53:31 +00:00
Zuul
f8fef7d774 Merge "Replace removed exceptions and prevent regression" 2019-06-18 05:04:24 +00:00
Zuul
81fc8ac6a8 Merge "Define a new InstanceNotMapped exception" 2019-06-18 02:32:33 +00:00
Zuul
5d385db8a1 Merge "Cleanup ConfFixture" 2019-06-16 08:32:41 +00:00
Zuul
a1dd90bb74 Merge "Fix property access in test_global_preference* tests" 2019-06-14 20:17:17 +00:00
Dantali0n
15754a14dd Replace removed exceptions and prevent regression
Replaces the NoSuchMetric exception that was replaced. The exception
is replaced with MetricNotAvailable and test cases are added to prevent
regression.

The changes in the exceptions were introduced in:
https://review.opendev.org/#/c/658127/

Change-Id: Id0f872e916aaa5dec59ed1ae6c0f653553b3fe46
2019-06-14 22:00:41 +02:00
Zuul
667d2d661a Merge "Move datasource query_retry into baseclass." 2019-06-14 09:04:15 +00:00
Zuul
b2111baf91 Merge "Backwards compatibility for node parameter" 2019-06-14 07:42:09 +00:00
licanwei
a4d978b893 Define a new InstanceNotMapped exception
In get_node_by_instance_uuid, an exception ComputeNodeNotFound
will be thrown if can't find a node through instance uuid.
But the exception information replaces the node name with
instance uuid, which is misleading, so we define a new exception.

Closes-Bug: #1832156

Change-Id: Ic6c44ae44da7c3b9a1c20e9b24a036063af266ba
2019-06-14 10:51:20 +08:00
Zuul
6495e42a60 Merge "Optimize NovaHelper.get_compute_node_by_hostname" 2019-06-14 02:31:13 +00:00
Zuul
e4f80b5461 Merge "Optimize hypervisor API calls" 2019-06-14 02:28:51 +00:00
Zuul
2a2f7902bd Merge "Improve DevStack documentation to support metrics" 2019-06-14 02:28:48 +00:00
Zuul
6502435dc5 Merge "Remove dead code" 2019-06-14 02:28:47 +00:00
Zuul
5f126cffe0 Merge "Add Placement helper" 2019-06-14 02:21:44 +00:00
Dantali0n
584eeefdc8 Move datasource query_retry into baseclass.
Moves the query_retry method into the baseclass and makes the query
retry and timeout options part of the watcher_datasources config group.
This makes the query_retry behavior uniform across all datasources.

A new baseclass method named query_retry_reset is added so datasources
can define operations to perform when recovering from a query error.
Test cases are added to verify the behavior of query_retry.

The query_max_retries and query_timeout config parameters are
deprecated in the gnocchi_client group and will be removed in a future
release.

Change-Id: I33e9dc2d1f5ba8f83fcf1488ff583ca5be5529cc
2019-06-13 15:52:53 +02:00
Matt Riedemann
28df60e275 Fix base enable_plugin branch for grenade run
We should be starting from stable/stein on the "old" side
of grenade runs now. Rather than hard-code the branch, just
use the BASE_DEVSTACK_BRANCH variable.

Change-Id: I1b0406f870ed0ae5622cfa7421a6cca00d0f891c
2019-06-13 09:51:19 -04:00
licanwei
7281f6184f Remove dead code
get_node_by_instance_uuid will never return None,
so the OR condition is dead code.

Change-Id: I26c553e1067a3cbeac6c0afe1c4bfdee4d939055
2019-06-13 17:31:49 +08:00
licanwei
79a57f67e6 Map instance to its node
When receiving Nova notification instance.create.end,
map instance to its node after adding instance to datamodel.
Related-Bug: #1832156

Change-Id: I6f39e8d935195c611f668f71590e1d9ff52ced0d
2019-06-13 15:58:28 +08:00
chenming
731d4bfdf2 update contraints url
http://lists.openstack.org/pipermail/openstack-discuss/2019-May/006478.html

Change-Id: I1929fc98cd728eb0dae66762481880e23cd793c7
2019-06-12 19:11:53 +00:00
Dantali0n
dd119ca1f8 Backwards compatibility for node parameter
Adds backwards compatibility for node parameter used by strategies. If
the node value is set by the user configuration it will override the
value for compute_node which is the value used by the strategies now.

This change was introduced in: https://review.opendev.org/#/c/656622/
Resolution discussed in the meeting on the 5th of June 2019
https://eavesdrop.openstack.org/meetings/watcher/2019/watcher.2019-06-05-08.00.log.html

Change-Id: Idaea062789a6b169e64f556fecc34cfbaaee5076
2019-06-12 16:23:58 +00:00
chenke
00f20ab1d4 Fix property access in test_global_preference* tests
In Python, when we use @property, the method will be
decorated by property.

When we call method self.strategy.datasource_backend()[1],
Actually it did two things:
1. call self.strategy.datasource_backend()
2. according to  the method's return value[2], call self._datasource_backend()

[1]. https://github.com/openstack/watcher/blob/bd8636f3f/watcher/tests/decision_engine/strategy/strategies/test_base.py#L87
[2]. https://github.com/openstack/watcher/blob/bd8636f3f/watcher/decision_engine/strategy/strategies/base.py#L368

But in this part, we just want it to perform the first step.
So we have to use self.strategy.datasource_backend instead of
self.strategy.datasource_backend()

The reason why the unittest does not report an error is
because the returned value is a mock object, and the second step
is executed without error, for example:

python -m unittest  watcher.tests.decision_engine.strategy.strategies.test_base
(Pdb) x=self.strategy.datasource_backend
(Pdb) type(x)
<class 'mock.mock.MagicMock'>
(Pdb) x
<MagicMock name='DataSourceManager().get_backend()' id='139740418102608'>
(Pdb) x()
<MagicMock name='DataSourceManager().get_backend()()' id='139740410824976'>
(Pdb) self.strategy.datasource_backend()
<MagicMock name='DataSourceManager().get_backend()()' id='139740410824976'>

To make the tests more robust, the underlying backend function
is mocked to be not callable.

Co-Authored-By: Matt Riedemann <mriedem.os@gmail.com>

Change-Id: I3305d9afe8ed79e1dc3affe02ba067ac06cece42
2019-06-12 12:00:45 -04:00
licanwei
b57feba5e8 Add Placement helper
This patch added Placement to Watcher
We plan to improve the data model and strategies in
the future specs.

Change-Id: I7141459eef66557cd5d525b5887bd2a381cdac3f
Implements: blueprint support-placement-api
2019-06-12 11:11:13 +08:00
Matt Riedemann
251264b1b6 Cleanup ConfFixture
This makes the ConfFixture extend the Config fixture from
oslo.config which handles cleanup for us. The module level
import_opt calls are also removed since they are no longer
needed.

Change-Id: I869e89c53284c8da45e0b1293f2d35011f5bfbf9
2019-06-11 20:18:20 -04:00
Zuul
46a36d1ad7 Merge "Fix string formatting" 2019-06-11 09:58:38 +00:00
licanwei
2d4bc095db Fix string formatting
Change-Id: Iaf995355ec542db076683374c6128656bee2ee6f
2019-06-10 17:16:51 +08:00
licanwei
f9e267fa42 check instance state for instance.update
In the process of creating an instance, Nova will emit an
instance.update notification with 'building' state.
This will cause a KeyError exception because this instance
isn't in Watcher datamodel.
So we should ignore the notification instance.update with
'building' state.

Closes-Bug: #1832154

Change-Id: I950eec50d2cee38bd22c47a70ae6f88bbf049080
2019-06-10 16:11:46 +08:00
Zuul
8000dd650f Merge "add strategy tempest job" 2019-06-06 09:11:19 +00:00
licanwei
c3e0e41fbf add strategy tempest job
Change-Id: I84a68f92fa34cf19487323f2afb89d379b8d80f5
2019-06-06 07:18:53 +00:00
licanwei
7f37f7b92a Remove apidoc
Now there are some errors when running apidoc,
actually we don't need apidoc, so remove it.
Closes-Bug: #1831515

Change-Id: I3b91a2c05ed62ae7bbd30a29e9db51d0e021410f
2019-06-04 11:34:07 +08:00
Matt Riedemann
374fd2791f Optimize NovaHelper.get_compute_node_by_hostname
The get_compute_node_by_hostname method is given a
compute service hostname and then does two queries to
find the matching hypervisor (compute node) with details:

1. List hypervisors with details and find the one that
   matches the given compute service hostname.

2. Using that node, search for hypervisors with the
   matching hypervisor_hostname.

There are two issues here:

1. The first query is inefficient in that it has to list
   all hypervisors in the deployment to try and match the
   one with the compute service hostname client side.

2. The second query is a fuzzy match on the server side [1]
   so even though we have matched on the node we want,
   get_compute_node_by_name can still return more than
   one hypervisor which will result in the helper method
   raising ComputeNodeNotFound. Consider having compute
   hosts with names compute1, compute10, compute11, compute100,
   and so on. The fuzzy match on compute1 would return all of
   those hypervisors.

For non-ironic nodes in nova, the compute service host and
hypervisor should be 1:1, meaning the hypervisor.service['host']
should be the same as hypervisor.hypervisor_hostname. Knowing
this, we can simplify the code to search just on the given
compute service hostname and if we get more than one result, it
is because of the fuzzy match and we can then do our client-side
filtering on the compute service hostname.

[1] https://github.com/openstack/nova/blob/d4f58f5eb/nova/db/sqlalchemy/api.py#L676

Change-Id: I84f387982f665d7cc11bffe8ec390cc7e7ed5278
2019-06-03 12:18:54 -04:00
Matt Riedemann
3f76f9cfdb Optimize hypervisor API calls
The nova CDM builder code and notification handling
code had some inefficiencies when it came to looking
up a hypevisor to get details. The general pattern
used before was:

1. get the minimal hypervisor information by hypervisor_hostname
2. make another query to get the hypervisor details by id

In the notifications case, it was actually three calls because
the first is listing hyprvisors to filter client-side by service
host.

This change collapses 1 and 2 above into a single API call
to get the hypervisor by hypervisor_hostname with details
which will include the service (compute) host information
which is what get_compute_node_by_id() was being used for.
Now that nothing is using get_compute_node_by_id it is removed.

There is more work we could do in get_compute_node_by_hostname
if the compute API allowed filtering hypervisors by service
host so a TODO is left for that.

One final thing: the TODO in get_compute_node_by_hostname about
there being more than one hypervisor per compute service host
for vmware vcenter is not accurate - nova's vcenter driver
hasn't supported a host:node 1:M topology like that since the
Liberty release [1]. The only in-tree driver in nova that supports
1:M is the ironic baremetal driver, so the comment is updated.

[1] Ifc17c5049e3ed29c8dd130339207907b00433960

Depends-On: https://review.opendev.org/661785/
Change-Id: I5e0e88d7b2dd1a69117ab03e0e66851c687606da
2019-06-03 12:18:54 -04:00
zhufl
9c1b83e610 Add missing ws separator between words
This is to add missing ws separator between words.

Change-Id: Iab23ce2ad081fef18978579594886950b8e2cb01
2019-05-31 14:51:30 +08:00
Zuul
5f94eef027 Merge "Group instance methods together in nova_helper" 2019-05-31 02:58:11 +00:00
Zuul
788f0055c1 Merge "Improve exceptions and logging in ds manager" 2019-05-31 02:57:33 +00:00
Zuul
88fb097539 Merge "Audit API supports new force option" 2019-05-29 10:01:04 +00:00
Zuul
ee3cbe46ef Merge "Fix test_metric_file_override metric from backend" 2019-05-29 08:13:31 +00:00
Dantali0n
a00daf9f26 Group instance methods together in nova_helper
Some of the methods for retrieving data about instances was placed
at the bottom of nova_helper instead of being close to the other
instance based methods.

Change-Id: I68475883529610e514aa82f1881105ab0cf24ec3
2019-05-29 09:02:21 +02:00
Zuul
855bfecf2f Merge "formal datasource interface implementation" 2019-05-28 12:15:06 +00:00
Zuul
5a3d1b741d Merge "Add force field to api-ref" 2019-05-28 02:10:42 +00:00
Zuul
15316a57db Merge "Optimize NovaClusterDataModelCollector.add_instance_node" 2019-05-27 03:02:53 +00:00
Zuul
38131a37b2 Merge "Remove 2.56 version compatibility check" 2019-05-27 03:01:48 +00:00
Zuul
59306b9a47 Merge "Require nova_client.api_version >= 2.56" 2019-05-27 03:01:47 +00:00
licanwei
2afd0dfcf5 Audit API supports new force option
Depends-on:Ia08694d2fb76907ea14e64116af2e722fe930063

Change-Id: Ib2d221ea9c994dea396c54cc8d2d32237025a1d4
Implements: blueprint add-force-field-to-audit
2019-05-27 02:08:33 +00:00
Matt Riedemann
fdea38fb06 Optimize NovaClusterDataModelCollector.add_instance_node
This does two things:

1. Rather than make an API call per server on the host,
   get all of the servers in a single API call by
   filtering on the host. The os-hypervisors API results
   to use make this require a bit of refactoring since
   get_compute_node_by_name does not have the service
   entry in it and get_compute_node_by_id does not have the
   servers entry in it. A TODO is added to clean that up
   with a single call to os-hypervisors once we have the
   support in python-novaclient.

2. Pulls get_node_by_uuid() out of the loop.

A test is added for the nova_helper get_instance_list method
since one did not exist before.

The fake compute node mocks in test_nova_cdmc_execute are
also cleaned up since, as noted above, get_compute_node_by_name
and get_compute_node_by_id don't both return all the details.

Change-Id: Ifd9f83c2f399d4c1765b0c520f4d5a62ad0f5fbd
2019-05-27 02:31:32 +03:00
Zuul
3b9364d4c7 Merge "Add force field to Audit" 2019-05-25 07:48:20 +00:00
Zuul
ba92791117 Merge "support-keystoneclient-option" 2019-05-25 07:01:10 +00:00
Dantali0n
5c492ea862 Fix test_metric_file_override metric from backend
Fix the list of required metrics from a datasource when testing the
existence of this metric in the metric map.

Change-Id: I19b7408a98893bc942c32edb09f1b3798ec8dc79
2019-05-24 15:32:55 +02:00
licanwei
62d181d925 Add force field to Audit
Partially Implements: blueprint add-force-field-to-audit

Change-Id: Ia08694d2fb76907ea14e64116af2e722fe930063
2019-05-24 00:05:13 -07:00
Matt Riedemann
a09cb3fa6c Remove 2.56 version compatibility check
With change Id34938c7bb8a5ca934d997e52cac3b365414c006
we require nova API version 2.56 or greater so we can
remove the compatibliity check in the
watcher_non_live_migrate_instance method.

The _check_nova_api_version method is left in place
for future compability checks.

Change-Id: I69040fbc13b03d90b9687c0d11104d4a5bae51d3
2019-05-23 16:01:44 -04:00
Matt Riedemann
7489126d83 Require nova_client.api_version >= 2.56
The [nova_client]/api_version defaults to 2.56 since
change Idd6ebc94f81ad5d65256c80885f2addc1aaeaae1. There
is compatibility code for that change but if 2.56 is
not available watcher_non_live_migrate_instance will
still fail if a destination host is used.

Since 2.56 has been available since the Queens version of
nova it should be reasonable to require at least that
version of nova is running for using Watcher.

This adds code which enforces the minimum version along
with a release note and "watcher-status upgrade check"
check method.

Note that it's kind of weird for watcher to have a config
option like nova_client.api_version since compute API
microversions are per API request even though novaclient
is constructed with the single configured version. It should
really be something the client (watcher in this case) determines
using version discovery and gracefully enables features if
the required nova API version is available, but that's a bigger
change.

Change-Id: Id34938c7bb8a5ca934d997e52cac3b365414c006
2019-05-23 15:49:19 -04:00
Zuul
1e6ce53273 Merge "Handle no nova CDM in notification code" 2019-05-22 02:57:56 +00:00
Dantali0n
e76c20d1c5 Improve exceptions and logging in ds manager
MetricNotAvailable and NoDatasourceAvailable allow to differentiate
between having no datasources configured and a required metric being
unavailable from the datasource. Both exceptions have comments so
that the use case is clear.

The input validation of the get_backend method in the datasource
manager is improved.

Additional logging information allows to identify which metric caused
the available datasource to be discarded.

Tests are updated to validate the correct functionality of the new
exceptions.

Change-Id: I512976cce2401dbcd249d42686b78843e111a0e7
2019-05-21 20:11:20 +02:00
Dantali0n
5a35b30763 Improve DevStack documentation to support metrics
Support DevStack setups with datasources configured starting with
Gnocchi.

Change-Id: Ibcf0909ccce2dbb646c23a179ca763b6c3e62633
2019-05-21 15:36:46 +02:00
Dantali0n
84cb589aa9 formal datasource interface implementation
Changes to the baseclass for datasources so strategies can be made
compatible with every datasource. Baseclass methods clearly describe
expected values and types for both parameters and for method returns.
query_retry has been added as base method since every current
datasource implements it.

Ceilometer is updated to work with the new baseclass. Several methods
which are not part of the baseclass and are not used by any strategies
are removed. The signature of these methods would have to be changed
to fit with the new base class while it would limit strategies to
only work with Ceilometer.

Gnocchi is updated to work with the new baseclass.

Gnocchi and Ceilometer will perform a transformation for the
host_airflow metric as it retrieves 1/10 th of the actual CFM

Monasca is updated to work with the new baseclass.

FakeMetrics for Gnocchi, Monasca and Ceilometer are updated to work
with the new method signatures of the baseclass.

FakeClusterAndMetrics for Ceilometer and Gnocchi are updated to work
with the new method signatures of the baseclass.

The strategies workload_balance, vm_workload_consolidation,
workload_stabilization, basic_consolidation, noisy_neighbour,
outlet_temp_control and uniform_airflow are updated to work with the
new datasource baseclass.

This patch will break compatibility with plugin strategies and
datasources due to the changes in signatures.

Depends-on: I7aa52a9b82f4aa849f2378d4d1c03453e45c0c78
Change-Id: Ie30ca3dbf01062cbb20d3be5d514ec6b5155cd7c
Implements: blueprint formal-datasource-interface
2019-05-21 11:18:08 +02:00
Zuul
f049815cf4 Merge "Enhance the collector_plugins option help text" 2019-05-21 09:10:12 +00:00
Zuul
7b1a7f0fe4 Merge "Allow using file to override metric map" 2019-05-21 09:04:40 +00:00
Zuul
3af43be7da Merge "Improve Gnocchi and Monasca datasource tests" 2019-05-21 09:04:39 +00:00
Zuul
f731aa1748 Merge "Fix Stein version in watcher-status docs" 2019-05-21 07:17:33 +00:00
Zuul
7d4c587014 Merge "Add doc/requirements.txt to venv tox target" 2019-05-21 07:17:32 +00:00
Zuul
124a942301 Merge "Remove dead code from NovaClusterDataModelCollector" 2019-05-20 13:00:16 +00:00
Dantali0n
dea32c5e1f Improve Gnocchi and Monasca datasource tests
As a follow up to the recent test improvements for Ceilometer this
patch ensures that the same test pattern is used for Gnocchi and
Monasca as well. This ensures that the mocked functions will be called
with matching signatures.

Change-Id: Ic14a4c087f3961a4b4f373e2e3d792aba71868f6
2019-05-20 14:41:24 +02:00
Sumit Jamgade
b620081714 Allow using file to override metric map
Override the metric map of each datasource as soon as it is created by
the manager. This override comes from a file whose path is provided by
a setting in config file.

Loading at creation time allows the correct datasource be used when
get_backend is called, this allows loading a datasource whose metric
names get updated outside the watcher's codebase.

The function 'load_metric_map' returns empty-dict in any error case.
Also in case the file is empty where safe_load is unable finds any
yaml documents, it will return None. [1]

Some minor refactoring in the test_manager file for readability and
added tests for file load and metric override.

1 - https://pyyaml.org/wiki/PyYAMLDocumentation

Change-Id: I1df16245f4c7dfd34066f3ab0553cd67154faa58
Implements: blueprint file-based-metric-map
2019-05-20 10:28:00 +02:00
Zuul
7456975445 Merge "Fix typo in ceilometer datasource" 2019-05-20 07:44:55 +00:00
chenke
f131825690 support-keystoneclient-option
Some users may want to create keystoneclient by specifying the
type of endpoint and region name, so we need to supply the option
for user to choose.

Implements: blueprint support-keystoneclient-option

Change-Id: I49b33a69ec99d2a91568ce27ef89dc80b75e7091
2019-05-18 18:36:19 +00:00
Zuul
1b328f5148 Merge "Update migration notification" 2019-05-18 08:30:15 +00:00
Zhenyu Zheng
f92f77f683 Fix typo in ceilometer datasource
Change I25b4cb0e1b85379ff0c4da9d0c1474380d75ce3a in
Queens refactored the statistic_aggregation method
and renamed the "aggregate" kwarg to "aggregation",
presumably to match the signature of the GnocchiHelper
statistic_aggregation method (the commit message does
not give details) so a base method could be added to
the parent class for all datasource helpers.

As a result, the CeilometerHelper calls to its
statistic_aggregation started passing the new
"granularity" kwarg but failed to match the rename
to the "aggregation" kwarg, which breaks the
CeilometerHelper. This was missed by the unit tests
because the tests were just asserting the erroneous
call that the runtime code made.

This change fixes the kwarg typo and makes the
tests more robust by using the mock spec kwarg
to define a spec for the statistic_aggregation
mock so that it must be called with the correct
parameters defined in the method signature. The
test is refactored to reduce duplicate mocking.
The same test hardening can and should be done
in the gnocchi and monasca helper tests but that
should be done in a separate change.

Co-Authored-By: Matt Riedemann <mriedem.os@gmail.com>

Closes-Bug: #1829542

Change-Id: Idfd099f718873d9056fdc35a97954771c9ae5762
2019-05-17 12:06:42 -04:00
Zuul
78d28427be Merge "pass default_config_dirs variable for config initialization." 2019-05-17 10:20:44 +00:00
Zuul
b45777c497 Merge "Use base_strategy's add_action_migrate method" 2019-05-17 10:13:41 +00:00
Zuul
a0e434042b Merge "Fix_inappropriate_name" 2019-05-17 10:11:52 +00:00
Zuul
ce1d64a16c Merge "Remove unused utilities file" 2019-05-17 03:36:35 +00:00
Matt Riedemann
8a206a6ae5 Handle no nova CDM in notification code
As of change Ic4659d1f18af181203439a8bf1b38805ff34c309 the
nova CDM will not be built until an audit is performed.

Instances and services (compute hosts) can be created and
deleted before an audit is performed which will attempt
to use the notification callback function which relies
on the CDM being built already, and if not results in
an AttributeError.

This change side-steps that issue by checking to see that the
nova CDM exists before trying to call the notification
callback function.

An alternative to this is forcefully create the nova CDM when
notifications are received before an audit which is what happend
before change Ic4659d1f18af181203439a8bf1b38805ff34c309.

Change-Id: I16990afb82019821c443c9df26d3e515e52efa69
Closes-Bug: #1828582
2019-05-16 17:45:44 -04:00
Zuul
a1fa9b8c3f Merge "Fix API version header" 2019-05-16 08:54:58 +00:00
Zuul
96d25d8bfe Merge "update api version history" 2019-05-16 08:10:59 +00:00
Dantali0n
76367afd1d Remove unused utilities file
Change-Id: I26495fe9b0f191f6df953b5c61e971969c767662
2019-05-16 10:10:34 +02:00
licanwei
6d96512188 Update migration notification
_post_live_migration[1] runs on the source host and calls
post_live_migration_at_destination on the dest host which
emits the instance.live_migration_post_dest.end notification:[2]
But it's not the last notification for the live migration operation.
so we should use instance.live_migration_post.end instead of
instance.live_migration_post_dest.end notification.

[1]daa2ac2287/nova/compute/manager.py (L6907)
[2]daa2ac2287/nova/compute/manager.py (L7035)

Change-Id: Id1e2d98f56d5a95d49e32f98d2910660b9f48ce6
2019-05-16 15:48:49 +08:00
Zuul
6b16e7e58f Merge "Remove bandit from lower-constraints" 2019-05-16 02:38:45 +00:00
Zuul
2834610fa6 Merge "docs: fix link to install guide from user guide" 2019-05-15 15:48:00 +00:00
chenke
86a537fe7f Remove bandit from lower-constraints
The version of bandit in lower-constraints (1.4.0) does
not match the version in test-requirements (1.6.0) however
bandit is a test-only dependency and there is no test coverage
for bandit in the lower-constraints tox job target, so there
is really no good reason to have bandit in lower-constraints.
As such, this change simply removes it from lower-constraints.

Co-Authored-By: Matt Riedemann <mriedem.os@gmail.com>

Change-Id: I35f66994e9a3a334b342232587d84491542da755
2019-05-15 14:37:52 +00:00
chenke
15c842fba2 Update Sphinx requirement
Sphinx 2.0 no longer works on python 2.7, so we need to start capping
it there as well.

The errors are as follow:

Requirement(package='sphinx', location='', specifiers='!=1.6.6,!=1.6.7,>=1.6.5'
does not match "python_version>='3.4'"
Requirement(package='sphinx', location='', specifiers='!=1.6.6,!=1.6.7,>=1.6.5'
does not match "python_version=='2.7'"
Could not find a global requirements entry to match package sphinx. If the package
is already included in the global list, the name or platform markers there may not
match the local settings.

Change-Id: I6dad56ffbb9e85e36cacea1a89565c2fc8248fbf
2019-05-15 11:03:48 +08:00
Matt Riedemann
3edafc9ba9 Fix Stein version in watcher-status docs
The final Stein version of Watcher was 2.0.0
so this fixes the version mentioned in the
watcher-status man page docs.

Change-Id: I7fce35471cf31222f9cdafc35e5a7b287bc4598e
2019-05-14 20:51:28 -04:00
Matt Riedemann
efb4aaa0cf Add doc/requirements.txt to venv tox target
This is needed to create a release note using the venv target:

  tox -e venv -- reno new <slug>

Change-Id: I1a0800a90781ede281b22db2892fb91e700d6e7b
2019-05-14 20:42:03 -04:00
Matt Riedemann
4cd8a2f46e Remove dead code from NovaClusterDataModelCollector
The _add_virtual_layer and _add_virtual_servers methods
have not been used since Ic4659d1f18af181203439a8bf1b38805ff34c309
in Stein so this change removes them.

Change-Id: I8c05f29c3c03aa5897cb182bb492948771c42881
2019-05-14 17:40:13 -04:00
Matt Riedemann
aa7442d795 Enhance the collector_plugins option help text
This enhances the [collector]/collector_plugins
config option help text to mention the storage
and baremetal in-tree collectors and the ability
to load out-of-tree collectors via extension point.

While doing this, the help text is formatted for
prettier rst rendering in the docs.

Change-Id: Ifd32c95c664c4e9586c250e6bceaeaba2e2df417
2019-05-14 14:18:32 -04:00
chenke
0df6c0d961 Use base_strategy's add_action_migrate method
Do this before implementing blueprint:
Add resource_name in action input parameter field

Change-Id: I1defb1f114d6eb6d0f2d1baffaa86712966e184a
2019-05-14 21:53:45 +08:00
chenke
d9eb925355 Fix_inappropriate_name
In these places, 'node' should be named 'node_uuid'

Change-Id: I60a7c9aa320e813d2f03c1f389188e142ca22daf
2019-05-14 20:37:42 +08:00
licanwei
a40892c302 update api version history
Partially Implements: blueprint add-force-field-to-audit

Change-Id: Iff858b63add6d3e5929780abfd52a2c4b1a87ed7
2019-05-14 13:42:00 +08:00
Zuul
9922dec025 Merge "allow building docs without ceilometer client" 2019-05-14 02:38:42 +00:00
Zuul
85de4472f1 Merge "Remove watcher.openstack.common=WARN from _DEFAULT_LOG_LEVELS" 2019-05-14 02:38:24 +00:00
Sumit Jamgade
241df0d5f4 allow building docs without ceilometer client
CeilometerClient has been deprecated and is no longer available for
master. Without ceilometer client installed docs fail to build with
an exception [1].

This patch marks the import optional.

1 -
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/sphinx/config.py", line 368, in
eval_config_file
    execfile_(filename, namespace)
  File "/usr/lib/python2.7/site-packages/sphinx/util/pycompat.py", line
150, in execfile_
    exec_(code, _globals)
  File "/usr/lib/python2.7/site-packages/six.py", line 709, in exec_
    exec(""exec _code_ in _globs_, _locs_"")
  File "<string>", line 1, in <module>
  File
"/home/abuild/rpmbuild/BUILD/python-watcher-2.1.0.dev45/doc/source/conf.py",
line 20, in <module>
    objects.register_all()
  File
"/home/abuild/rpmbuild/BUILD/python-watcher-2.1.0.dev45/watcher/objects/__init__.py",
line 31, in register_all
    __import__('watcher.objects.action_plan')
  File
"/home/abuild/rpmbuild/BUILD/python-watcher-2.1.0.dev45/watcher/objects/action_plan.py",
line 78, in <module>
    from watcher import conf
  File
"/home/abuild/rpmbuild/BUILD/python-watcher-2.1.0.dev45/watcher/conf/__init__.py",
line 28, in <module>
    from watcher.conf import datasources
  File
"/home/abuild/rpmbuild/BUILD/python-watcher-2.1.0.dev45/watcher/conf/datasources.py",
line 21, in <module>
    from watcher.datasources import manager
  File
"/home/abuild/rpmbuild/BUILD/python-watcher-2.1.0.dev45/watcher/datasources/manager.py",
line 19, in <module>
    from watcher.datasources import ceilometer as ceil
  File
"/home/abuild/rpmbuild/BUILD/python-watcher-2.1.0.dev45/watcher/datasources/ceilometer.py",
line 21, in <module>
    from ceilometerclient import exc
ImportError: No module named ceilometerclient
)

Change-Id: Idcf582c2495aab39aacf691b687759405bb94dca
2019-05-13 14:42:58 +02:00
Zuul
5722f5f994 Merge "Remove unused exceptions" 2019-05-13 11:19:51 +00:00
Sumit Jamgade
dce23d7eb4 pass default_config_dirs variable for config initialization.
Currently default config files are being for initialization of CONF from
oslo_config. However default config dirs are not being passed as a
result watcher components (eg: decision-engine) are unable to load
files from default directories (eg: /etc/watcher/watcher.conf.d)
supported by oslo_config. This is a short-coming on watcher's side.
Also this forces user to have multiple config for each component.

Without this default set, oslo_config will search for conf with string
'python-watcher' in it, eg: /etc/python-watcher/.... Since there is a
because project=python-watcher a couple of lines below

This patch adds the option after evaluating using project as 'watcher'
which is similar to evaluation of default_config_files and also allows
it to be passed in as a function parameter.

Change-Id: I013f9d03978f8716847f8d1ee6888629faf5779b
2019-05-13 10:59:55 +02:00
Matt Riedemann
14d4cb54fa docs: fix link to install guide from user guide
This fixes the wrong installation guide link from the
user guide which was pointing to the watcherclient docs
for some reason, maybe it was just a copy/paste error.

Change-Id: I38f536e187245523ac37d70054a2df8cdfcbe4b2
Closes-Bug: #1828584
2019-05-10 11:37:28 -04:00
Matt Riedemann
5c2939f23b Remove watcher.openstack.common=WARN from _DEFAULT_LOG_LEVELS
Hard-coding watcher.openstack.common to warning level logging
only makes it hard to debug watcher's interactions with other
services, like when it's triggering and monitoring a server live
migration.

Since debug logging is controlled via the "debug" configuration
option, we can just rely on that to filter out debug logs within
watcher itself.

Note this has been this way since change
I699e0ab082657880998d8618fe29eb7f56c6c661 back in 2015 and there
was no explanation why the watcher.openstack.common logging
was set to WARN level.

Change-Id: I939403a4ae36d1aa9ea83badb9404bc37d18a1a6
Related-Bug: #1828598
2019-05-10 11:29:08 -04:00
Zuul
64d841b3f2 Merge "Add tempest voting" 2019-05-10 07:15:29 +00:00
Zuul
9d15566945 Merge "Use the common logging setup function in devstack runs" 2019-05-10 07:04:29 +00:00
Zuul
583c9d8f6d Merge "Allow for global datasources preference from config" 2019-05-10 06:04:00 +00:00
Zuul
ba82e8b68e Merge "Fix reraising of exceptions" 2019-05-10 03:49:57 +00:00
Zuul
cc809a24ff Merge "update wsme types" 2019-05-10 03:49:56 +00:00
licanwei
76f0ce1d2c Add force field to api-ref
Change-Id: Iddea2359a13ba099e840b9501d4e9335905695f4
Implements: blueprint add-force-field-to-audit
2019-05-10 10:51:37 +08:00
licanwei
606f20b66e Fix API version header
X-OpenStack-Watcher-API-Version should be OpenStack-API-Version

Change-Id: Ibfb7362f4b5df0775e8215b6e0bd83f9bd784244
2019-05-10 09:51:21 +08:00
Dantali0n
567e079848 Remove unused exceptions
Change-Id: Ibb7e3fa4052f04a4e3fc1de60afa6fbafd4a7f9b
2019-05-09 18:54:47 +02:00
Matt Riedemann
838768c76e Fix bandit runs with 1.6.0
The -x option for bandit changed in 1.6.0 and now
supports glob patterns so use that to correctly
exclude test code from bandit scans.

Since this change requires bandit>=1.6.0, we have
to also fix the networkx requirement to pass the
requirements-check job so that the networkx requirement
matches what is in global-requirements from change
I0a9700926c9a0db93e782c853c33f1aaee3d4876.

Change-Id: I4fc1166daee5d8739296419216d11d684be27c0a
Closes-Bug: #1828419
2019-05-09 11:14:40 -04:00
Dantali0n
bd8636f3f0 Allow for global datasources preference from config
Allows to define a global preference for metric datasources with the
ability for strategy specific overrides. In addition, strategies which
do not require datasources have the config options removed this is
done to prevent confusion.

Some documentation that details the inner workings of selecting
datasources is updated.

Imports for some files in watcher/common have been changed to resolve
circular dependencies and now match the overall method to import
configuration.

Addtional datasources will be retrieved by the manager if the
datasource throws an error.

Implements: blueprint global-datasource-preference
Change-Id: I6fc455b288e338c20d2c4cfec5a0c95350bebc36
2019-05-09 11:02:15 +02:00
Matt Riedemann
173bf11a7d Use the common logging setup function in devstack runs
To get log formatting like the other openstack projects
running in devstack the setup_logging function should be
used. This will also give us the "Display level" formatting
in the logs via the os-loganalyze packaged used by infra.

Needed by: https://review.opendev.org/657652

Change-Id: I5e9bd5a142e45804e8d915b370746a2142243088
2019-05-07 13:26:37 -04:00
Sean McGinnis
af0f02d19b Fix reraising of exceptions
Exceptions should be reraised with just "raise" and not "raise e" to
preserve the traceback. This also addresses a couple cases where the
catching and reraising of the exception was not actually doing anything.

Change-Id: I94ba193f728ee7ca6f689f70fc08317a1dd50c92
Signed-off-by: Sean McGinnis <sean.mcginnis@gmail.com>
2019-05-07 11:50:57 -05:00
chenke
e2285777e2 Using node replace resource_id in method add_action_disable_node()
We have a bp to add resource_name in action input parameter field.

Before doing this, one of this method's parameter should be node
instead of resource_id.

Change-Id: I4ce5ae97efce98d80a460fd6003df3cc5cacab82
2019-05-07 15:07:07 +08:00
Zuul
30104ae4ae Merge "Put the method add_migration() in base.py" 2019-05-07 06:00:56 +00:00
chenke
4d480d5ccf Put the method add_migration() in base.py
Change-Id: I00bc03be6a59edf117b66388305486d8f74f77ce
2019-05-06 14:29:21 +08:00
licanwei
8fa8934424 update wsme types
wsproperty and wsattr are in module wsme.types

Change-Id: I6a33c81b7207e14b3bda512381ef809e4a7de4ce
2019-05-05 17:28:29 +08:00
Zuul
8ac5e620f4 Merge "Resolve problems with audit scope and add tests" 2019-04-30 09:20:27 +00:00
licanwei
c99e051a14 Add tempest voting
Change-Id: If09544e96ef23a6c52bde1f7211bf323d9609f63
2019-04-30 16:02:32 +08:00
Dantali0n
d84f8c50f5 Resolve problems with audit scope and add tests
This resolves problems with the audit scope such as the scope being
ignored, the scope not merging due to a type in .append, change update
into .add method when adding single elements to a set and making the
access of dict keys and values as lists work in python 3.7.

All these methods from the model builder now have tests to prevent
regressions.

Co-Authored-By: Canwei Li <li.canwei2@zte.com.cn>

Change-Id: I287763d5e426ff860aefabc4a1f3fe3f51accd76
2019-04-30 07:12:56 +00:00
chenke
d2e1d69d37 Replace git.openstack.org with opendev.org
Change-Id: Ibccf32b71d307d9c80c91035907dc8292722ab31
2019-04-29 09:49:24 +02:00
Zuul
92c94f61ca Merge "Add hardware.cpu_util in workload_stabilization" 2019-04-26 02:36:20 +00:00
Tatiana Kholkina
4db39c527d Add hardware.cpu_util in workload_stabilization
Since commit I8df8921337ea3f4e751c0c822d823e64e3ca7e1c
the check for hardware.cpu.util was removed.
But it can be still used in workload stabilization.

Change-Id: I301487837aac2e1e63bce16a79d0f8136452c313
2019-04-25 07:31:34 +00:00
Zuul
2a1c353014 Merge "separate launching audit scheduler" 2019-04-25 07:03:56 +00:00
zhulingjie
647b5e9483 Drop use of git.openstack.org
Our cgit instance will be going away and opendev.org is the new
preferred URL for browsing our git repos. Redirects will exist for the
foreseeable future, but it's more efficient to just go directly to the
new locations.

Change-Id: I7dd9d454da63167832bab02c89be98a2ce03b72a
2019-04-23 13:20:10 +02:00
Zuul
b880a57a8b Merge "Replace HOST_IP to SERVICE_HOST" 2019-04-20 04:56:17 +00:00
OpenDev Sysadmins
62da2984b8 OpenDev Migration Patch
This commit was bulk generated and pushed by the OpenDev sysadmins
as a part of the Git hosting and code review systems migration
detailed in these mailing list posts:

http://lists.openstack.org/pipermail/openstack-discuss/2019-March/003603.html
http://lists.openstack.org/pipermail/openstack-discuss/2019-April/004920.html

Attempts have been made to correct repository namespaces and
hostnames based on simple pattern matching, but it's possible some
were updated incorrectly or missed entirely. Please reach out to us
via the contact information listed at https://opendev.org/ with any
questions you may have.
2019-04-19 19:40:45 +00:00
licanwei
0def7b4d38 separate launching audit scheduler
Now there are only one scheduler for launching audit task and
executing audit jobs. We have found an exception where the scheduler
stops for some reason when executing audit.
In order to keep launching audit task normal, we need to split into
two schedulers.

Change-Id: I45dccaf062290cfc7d7fcfc27fe11d6f87f38afa
2019-04-19 14:30:09 +08:00
licanwei
f36c25b52f Replace HOST_IP to SERVICE_HOST
HOST_IP only used by ipv4, SERVICE_HOST is used by ipv4 or ipv6.

Change-Id: I50d66f4fbe9cd80e32fe4cf67f8a6ae19b500c0d
2019-04-19 11:42:59 +08:00
licanwei
f52716fcf9 remove py35
We hava python3.6 and python3.7 now, it's enough.

https://governance.openstack.org/tc/reference/runtimes/train.html

Change-Id: I54b18fb0bd7674760603de841c28c8b1fda77c56
2019-04-16 16:24:53 +08:00
Zuul
57fd68128e Merge "Adapt Watcher to Python3.7" 2019-04-12 04:36:42 +00:00
chenke
8cb4c8e406 Uncap jsonschema
Reference commit:
https://review.openstack.org/#/c/649799/
https://review.openstack.org/#/c/649669/2/global-requirements.txt

Change-Id: I01a056ee6ce89ec0416290de84b0043126aa668f
2019-04-11 20:03:42 +08:00
Zuul
721b710e2f Merge "Make datasource methods match names of metrics" 2019-04-11 03:13:51 +00:00
Zuul
0ed016182e Merge "Fix lower-constraint deps handling" 2019-04-04 13:11:21 +00:00
Zuul
33009db64a Merge "Move eventlet monkey patch code" 2019-04-04 11:28:54 +00:00
Zuul
9d96c12441 Merge "Fix openstack-tox-lower-constraint TIMED_OUT Error" 2019-04-04 11:27:58 +00:00
licanwei
2df5ab926e Fix docs gate failed
Change-Id: I334b76ce9284a41583e06bdd05900ba2baf4dc64
2019-04-04 14:56:41 +08:00
Zuul
187b0e6a4b Merge "Update meeting schedule to new bi-weekly format" 2019-04-01 01:28:16 +00:00
Zuul
eafeb94a01 Merge "Replace openstack.org git:// URLs with https://" 2019-04-01 01:28:14 +00:00
Alexander Chadin
6dfeeb7359 Adapt Watcher to Python3.7
There are some issues with bundle of eventlet, taskflow and
apscheduler on Python 3.7.
According to [0], replace ThreadPoolExecutor with
GreenThreadPoolExecutor

[0]: http://lists.openstack.org/pipermail/openstack-dev/2018-July/132481.html

Co-Authored-By: Canwei Li <li.canwei2@zte.com.cn>

Change-Id: I989d7155eb8764088f91b3ca0d1f47ac6332bf11
2019-03-30 14:43:31 +08:00
licanwei
ac3aa94599 Move eventlet monkey patch code
Eventlet monkey patching is not recommended on top level __init__ [1],
because Apache WSGI module uses own concurrency model [2] and API
service under Apache should be runned without eventlet. This patch
moves eventlet monkey patching code to watcher.cmd module __init__
(like in nova).

[1] https://specs.openstack.org/openstack/openstack-specs/specs/eventlet-best-practices.html
[2] http://modwsgi.readthedocs.io/en/develop/user-guides/processes-and-threading.html

Change-Id: Ie5cf67429ea9ef8d00dd7348ce288437ea105c08
2019-03-30 14:28:52 +08:00
Sean McGinnis
68a90b2cfa Fix lower-constraint deps handling
When the lower-constraints tox target was added, it was assumed the
install_command was just running the install and that the dependencies
and constraints were being set using "deps = ".

This fixed the install_command and deps to follow the expected pattern
so the lower-constraints job actual does install the lower constraints.

This also raises the oslo.context minimum as
Ic96c1f1e1a80099d9dafa95a014fc47f05b88e42 added a dependency on a newer
versions kwarg.

Depends-On: https://review.openstack.org/#/c/647726/

Change-Id: I4cc2c3ac158a607b22295c50f83896969a4007ee
Signed-off-by: Sean McGinnis <sean.mcginnis@gmail.com>
2019-03-28 04:43:05 +00:00
chenke
7f495e8e6f Fix openstack-tox-lower-constraint TIMED_OUT Error
When use tox-elower-constraint, we will meet these errors:

1. line 417, in test_clients_ironic:
b"AssertionError: Expected call: Client('1', endpoint_override...
b"Actual call: Client('1', 'http://localhost:6385/'...

2. line 39, in test_wrong_major_version:
b"KeyError: 'HTTP_ACCEPT'"

3. RUN END RESULT_TIMED_OUT:
[untrusted : git.openstack.org/openstack-infra/
zuul-jobs/playbooks/tox/run.yaml@master]

For the first error, The reason is that the unittest for the
ironicclient is too strict and must be adapted to the latest code.
In fact, the watcher can use the previous ironicclient version.
Therefore, we modified the unittest so that the watcher does not
have to rely on the latest ironicclient version.

For the second error, The reason is that we need to update the minimum
version of pecan and webOb.

For the third error, the reason is that the version of the oslo_messaging
is too low.

Change-Id: Icb3eda3d27fa4452e13e2dcd3c016cc76fc2c7c7
2019-03-28 12:34:31 +08:00
Dantali0n
3b80b35270 Update meeting schedule to new bi-weekly format
Change-Id: I24bca9cd07262387282acc9ba458e9ef50587146
2019-03-26 16:36:34 +01:00
Dantali0n
c8e4efcd0b Make datasource methods match names of metrics
Metrics for datasources now match the name of their corresponding
abstract methods. This ensures that developers know how the method
is named if they know the name of the metric and vice versa.

Change-Id: I0f9d400432d8182b3f10a0da97155e6cb786690e
2019-03-26 08:53:25 +01:00
Ian Wienand
b023c9076f Replace openstack.org git:// URLs with https://
This is a mechanically generated change to replace openstack.org
git:// URLs with https:// equivalents.

This is in aid of a planned future move of the git hosting
infrastructure to a self-hosted instance of gitea (https://gitea.io),
which does not support the git wire protocol at this stage.

This update should result in no functional change.

For more information see the thread at

 http://lists.openstack.org/pipermail/openstack-discuss/2019-March/003825.html

Change-Id: I3452a7802dde00d8be32c833d714b2974be58e16
2019-03-24 20:36:25 +00:00
OpenStack Proposal Bot
ab03bf9bb0 Imported Translations from Zanata
For more information about this automatic import see:
https://docs.openstack.org/i18n/latest/reviewing-translation-import.html

Change-Id: Ifa76c8ec76263a9c3af0c7d463ec686e4bf4fa22
2019-03-22 09:11:07 +00:00
OpenStack Release Bot
871a01f554 Update master for stable/stein
Add file to the reno documentation build to show release notes for
stable/stein.

Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/stein.

Change-Id: I25931207ed6066f905fe66ca504fa230e40d12dc
Sem-Ver: feature
2019-03-21 10:36:18 +00:00
Zuul
807857c85b Merge "Migrate legacy jobs to Ubuntu Bionic" 2019-03-19 04:04:17 +00:00
ghanshyam
a4865b64f6 Migrate legacy jobs to Ubuntu Bionic
We have migrated the zuulv3 job to Bionic during Dec/Jan month.
 - http://lists.openstack.org/pipermail/openstack-discuss/2018-December/000837.html
 - https://etherpad.openstack.org/p/devstack-bionic
But that effort does not move all gate job to Bionic as there are
large amount of jobs are still legacy jobs. All the legacy jobs still
use Xenial as nodeset.

As per the decided runtime for Stein, we need to test everything on openstack
CI/CD on Bionic - https://governance.openstack.org/tc/reference/runtimes/stein.html

Below patch move the legacy base jobs to bionic which will move the derived jobs
automatically to bionic. These jobs are modified with branch variant so that they will use
Bionic node from stein onwards and xenial for all other stable branches
until stable/rocky.
- https://review.openstack.org/#/c/639096

This commit remove the overridden nodeset from legacy jobs
so that it will start using the nodeset defined in parent job.

More Details: 
- https://etherpad.openstack.org/p/legacy-job-bionic
- http://lists.openstack.org/pipermail/openstack-discuss/2019-March/003614.html

Depends-On: https://review.openstack.org/#/c/639096
Change-Id: I99646904d3d0fb26f4e45df1be841a67c4c2477b
2019-03-13 04:15:50 +00:00
266 changed files with 9331 additions and 3955 deletions

View File

@@ -1,4 +1,4 @@
[gerrit]
host=review.openstack.org
host=review.opendev.org
port=29418
project=openstack/watcher.git

View File

@@ -4,54 +4,45 @@
- openstack-cover-jobs
- openstack-lower-constraints-jobs
- openstack-python-jobs
- openstack-python35-jobs
- openstack-python36-jobs
- openstack-python3-train-jobs
- publish-openstack-docs-pti
- release-notes-jobs-python3
check:
jobs:
- watcher-tempest-functional
- watcher-grenade
- watcher-tempest-dummy_optim
- watcher-tempest-strategies
- watcher-tempest-actuator
- watcher-tempest-basic_optim
- watcher-tempest-vm_workload_consolidation
- watcher-tempest-workload_balancing
- watcherclient-tempest-functional
- watcher-tempest-zone_migration
- watcher-tempest-host_maintenance
- watcher-tempest-storage_balance
- watcher-tls-test
- watcher-tempest-functional-ipv6-only
gate:
queue: watcher
jobs:
- watcher-tempest-functional
- watcher-tempest-functional-ipv6-only
- job:
name: watcher-tempest-dummy_optim
parent: watcher-tempest-multinode
voting: false
vars:
tempest_test_regex: watcher_tempest_plugin.tests.scenario.test_execute_dummy_optim
- job:
name: watcher-tempest-actuator
parent: watcher-tempest-multinode
voting: false
vars:
tempest_test_regex: watcher_tempest_plugin.tests.scenario.test_execute_actuator
- job:
name: watcher-tempest-basic_optim
parent: watcher-tempest-multinode
voting: false
vars:
tempest_test_regex: watcher_tempest_plugin.tests.scenario.test_execute_basic_optim
- job:
name: watcher-tempest-vm_workload_consolidation
parent: watcher-tempest-multinode
voting: false
vars:
tempest_test_regex: watcher_tempest_plugin.tests.scenario.test_execute_vm_workload_consolidation
devstack_local_conf:
@@ -63,28 +54,24 @@
- job:
name: watcher-tempest-workload_balancing
parent: watcher-tempest-multinode
voting: false
vars:
tempest_test_regex: watcher_tempest_plugin.tests.scenario.test_execute_workload_balancing
- job:
name: watcher-tempest-zone_migration
parent: watcher-tempest-multinode
voting: false
vars:
tempest_test_regex: watcher_tempest_plugin.tests.scenario.test_execute_zone_migration
- job:
name: watcher-tempest-host_maintenance
parent: watcher-tempest-multinode
voting: false
vars:
tempest_test_regex: watcher_tempest_plugin.tests.scenario.test_execute_host_maintenance
- job:
name: watcher-tempest-storage_balance
parent: watcher-tempest-multinode
voting: false
vars:
tempest_test_regex: watcher_tempest_plugin.tests.scenario.test_execute_storage_balance
devstack_local_conf:
@@ -95,6 +82,13 @@
volume-feature-enabled:
multi_backend: true
- job:
name: watcher-tempest-strategies
parent: watcher-tempest-multinode
vars:
tempest_concurrency: 1
tempest_test_regex: watcher_tempest_plugin.tests.scenario.test_execute_strategies
- job:
name: watcher-tls-test
parent: watcher-tempest-multinode
@@ -109,7 +103,7 @@
- job:
name: watcher-tempest-multinode
parent: watcher-tempest-functional
nodeset: openstack-two-node
nodeset: openstack-two-node-bionic
roles:
- zuul: openstack/tempest
group-vars:
@@ -152,27 +146,30 @@
$TEMPEST_CONFIG:
compute:
min_compute_nodes: 2
min_microversion: 2.56
compute-feature-enabled:
live_migration: true
block_migration_for_live_migration: true
placement:
min_microversion: 1.29
devstack_plugins:
ceilometer: https://git.openstack.org/openstack/ceilometer
ceilometer: https://opendev.org/openstack/ceilometer
- job:
name: watcher-tempest-functional
parent: devstack-tempest
timeout: 7200
required-projects:
required-projects: &base_required_projects
- openstack/ceilometer
- openstack-infra/devstack-gate
- openstack/devstack-gate
- openstack/python-openstackclient
- openstack/python-watcherclient
- openstack/watcher
- openstack/watcher-tempest-plugin
- openstack/tempest
vars:
vars: &base_vars
devstack_plugins:
watcher: https://git.openstack.org/openstack/watcher
watcher: https://opendev.org/openstack/watcher
devstack_services:
tls-proxy: false
watcher-api: true
@@ -193,6 +190,14 @@
zuul_copy_output:
/etc/hosts: logs
- job:
name: watcher-tempest-functional-ipv6-only
parent: devstack-tempest-ipv6
description: |
Watcher devstack tempest tests job for IPv6-only deployment
required-projects: *base_required_projects
vars: *base_vars
- job:
name: watcher-grenade
parent: legacy-dsvm-base
@@ -211,8 +216,8 @@
- ^tools/.*$
- ^tox.ini$
required-projects:
- openstack-dev/grenade
- openstack-infra/devstack-gate
- openstack/grenade
- openstack/devstack-gate
- openstack/watcher
- openstack/python-watcherclient
- openstack/watcher-tempest-plugin
@@ -221,7 +226,6 @@
# This job is used in python-watcherclient repo
name: watcherclient-tempest-functional
parent: watcher-tempest-functional
voting: false
timeout: 4200
vars:
tempest_concurrency: 1

View File

@@ -26,7 +26,8 @@ migration, increased energy efficiency and more!
* Free software: Apache license
* Wiki: https://wiki.openstack.org/wiki/Watcher
* Source: https://github.com/openstack/watcher
* Source: https://opendev.org/openstack/watcher
* Bugs: https://bugs.launchpad.net/watcher
* Documentation: https://docs.openstack.org/watcher/latest/
* Release notes: https://docs.openstack.org/releasenotes/watcher/
* Design specifications: https://specs.openstack.org/openstack/watcher-specs/

View File

@@ -15,3 +15,4 @@ Watcher API
.. include:: watcher-api-v1-strategies.inc
.. include:: watcher-api-v1-services.inc
.. include:: watcher-api-v1-scoring_engines.inc
.. include:: watcher-api-v1-datamodel.inc

View File

@@ -129,6 +129,14 @@ r_strategy:
in: query
required: false
type: string
r_type:
description: |
Type of data model user want to list. Default type is compute.
Supported values: compute.
Future support values: storage, baremetal.
in: query
required: false
type: string
sort_dir:
description: |
Sorts the response by the requested sort direction.
@@ -245,6 +253,13 @@ audit_endtime_resp:
required: false
type: string
min_version: 1.1
audit_force:
description: |
Launch audit even if action plan is ongoing.
in: body
required: false
type: boolean
min_version: 1.2
audit_goal:
description: |
The UUID or name of the Goal.
@@ -404,6 +419,62 @@ links:
required: true
type: array
# Data Model Node
node_disk:
description: |
The Disk of the node(in GiB).
in: body
required: true
type: integer
node_disk_ratio:
description: |
The Disk Ratio of the node.
in: body
required: true
type: float
node_hostname:
description: |
The Host Name of the node.
in: body
required: true
type: string
node_memory:
description: |
The Memory of the node(in MiB).
in: body
required: true
type: integer
node_memory_ratio:
description: |
The Memory Ratio of the node.
in: body
required: true
type: float
node_state:
description: |
The State of the node. The value is up or down.
in: body
required: true
type: string
node_uuid:
description: |
The Unique UUID of the node.
in: body
required: true
type: string
node_vcpu_ratio:
description: |
The Vcpu ratio of the node.
in: body
required: true
type: float
node_vcpus:
description: |
The Vcpu of the node.
in: body
required: true
type: integer
# Scoring Engine
scoring_engine_description:
description: |
@@ -423,34 +494,72 @@ scoring_engine_name:
in: body
required: true
type: string
# Data Model Server
server_disk:
description: |
The Disk of the server.
in: body
required: true
type: integer
server_memory:
description: |
The Memory of server.
in: body
required: true
type: integer
server_name:
description: |
The Name of the server.
in: body
required: true
type: string
server_state:
description: |
The State of the server.
in: body
required: true
type: string
server_uuid:
description: |
The Unique UUID of the server.
in: body
required: true
type: string
server_vcpus:
description: |
The Vcpu of the server.
in: body
required: true
type: integer
# Service
service_host:
description: |
Name of host where service is placed on.
The Name of host where service is placed on.
in: body
required: true
type: string
service_id:
description: |
ID of service.
The ID of service.
in: body
required: true
type: integer
service_last_seen_up:
description: |
Time when Watcher service sent latest heartbeat.
The Time when Watcher service sent latest heartbeat.
in: body
required: true
type: string
service_name:
description: |
Name of service like ``watcher-applier``.
The Name of service like ``watcher-applier``.
in: body
required: true
type: string
service_status:
description: |
State of service. It can be either in ACTIVE or FAILED state.
The State of service. It can be either in ACTIVE or FAILED state.
in: body
required: true
type: string

View File

@@ -28,6 +28,7 @@
}
},
"auto_trigger": false,
"force": false,
"uuid": "65a5da84-5819-4aea-8278-a28d2b489028",
"goal_name": "workload_balancing",
"scope": [],

View File

@@ -1,5 +1,6 @@
{
"auto_trigger": false,
"force": false,
"audit_template_uuid": "76fddfee-a9c4-40b0-8da0-c19ad6904f09",
"name": "test_audit",
"parameters": {

View File

@@ -1,5 +1,6 @@
{
"audit_type": "ONESHOT",
"auto_trigger": false,
"force": true,
"audit_template_uuid": "5e70a156-ced7-4012-b1c6-88fcb02ee0c1"
}
}

View File

@@ -28,6 +28,7 @@
}
},
"auto_trigger": false,
"force": false,
"uuid": "65a5da84-5819-4aea-8278-a28d2b489028",
"goal_name": "workload_balancing",
"scope": [],

View File

@@ -30,6 +30,7 @@
}
},
"auto_trigger": false,
"force": false,
"uuid": "65a5da84-5819-4aea-8278-a28d2b489028",
"goal_name": "workload_balancing",
"scope": [],

View File

@@ -28,6 +28,7 @@
}
},
"auto_trigger": false,
"force": false,
"uuid": "65a5da84-5819-4aea-8278-a28d2b489028",
"goal_name": "workload_balancing",
"scope": [],

View File

@@ -28,6 +28,7 @@
}
},
"auto_trigger": false,
"force": false,
"uuid": "65a5da84-5819-4aea-8278-a28d2b489028",
"goal_name": "workload_balancing",
"scope": [],

View File

@@ -0,0 +1,38 @@
{
"context": [
{
"server_uuid": "1bf91464-9b41-428d-a11e-af691e5563bb",
"server_name": "chenke-test1",
"server_vcpus": "1",
"server_memory": "512",
"server_disk": "1",
"server_state": "active",
"node_uuid": "253e5dd0-9384-41ab-af13-4f2c2ce26112",
"node_hostname": "localhost.localdomain",
"node_vcpus": "4",
"node_vcpu_ratio": "16.0",
"node_memory": "16383",
"node_memory_ratio": "1.5",
"node_disk": "37"
"node_disk_ratio": "1.0",
"node_state": "up",
},
{
"server_uuid": "e2cb5f6f-fa1d-4ba2-be1e-0bf02fa86ba4",
"server_name": "chenke-test2",
"server_vcpus": "1",
"server_memory": "512",
"server_disk": "1",
"server_state": "active",
"node_uuid": "253e5dd0-9384-41ab-af13-4f2c2ce26112",
"node_hostname": "localhost.localdomain",
"node_vcpus": "4",
"node_vcpu_ratio": "16.0",
"node_memory": "16383",
"node_memory_ratio": "1.5",
"node_disk": "37"
"node_disk_ratio": "1.0",
"node_state": "up",
}
]
}

View File

@@ -47,6 +47,7 @@ Request
- auto_trigger: audit_autotrigger
- start_time: audit_starttime_req
- end_time: audit_endtime_req
- force: audit_force
**Example ONESHOT Audit creation request:**
@@ -83,6 +84,7 @@ version 1:
- hostname: audit_hostname
- start_time: audit_starttime_resp
- end_time: audit_endtime_resp
- force: audit_force
**Example JSON representation of an Audit:**
@@ -181,6 +183,7 @@ Response
- hostname: audit_hostname
- start_time: audit_starttime_resp
- end_time: audit_endtime_resp
- force: audit_force
**Example JSON representation of an Audit:**
@@ -227,6 +230,7 @@ Response
- hostname: audit_hostname
- start_time: audit_starttime_resp
- end_time: audit_endtime_resp
- force: audit_force
**Example JSON representation of an Audit:**
@@ -281,6 +285,7 @@ version 1:
- hostname: audit_hostname
- start_time: audit_starttime_resp
- end_time: audit_endtime_resp
- force: audit_force
**Example JSON representation of an Audit:**
@@ -335,6 +340,7 @@ Response
- hostname: audit_hostname
- start_time: audit_starttime_resp
- end_time: audit_endtime_resp
- force: audit_force
**Example JSON representation of an Audit:**

View File

@@ -0,0 +1,55 @@
.. -*- rst -*-
==========
Data Model
==========
``Data Model`` is very important for Watcher to generate resource
optimization solutions. Users can easily view the data model by the
API.
List Data Model
===============
.. rest_method:: GET /v1/data_model
Returns the information about Data Model.
Normal response codes: 200
Error codes: 400,401
Request
-------
.. rest_parameters:: parameters.yaml
- audit: r_audit
- type: r_type
Response
--------
.. rest_parameters:: parameters.yaml
- server_uuid: server_uuid
- server_name: server_name
- server_vcpus: server_vcpus
- server_memory: server_memory
- server_disk: server_disk
- server_state: server_state
- node_uuid: node_uuid
- node_hostname: node_hostname
- node_vcpus: node_vcpus
- node_vcpu_ratio: node_vcpu_ratio
- node_memory: node_memory
- node_memory_ratio: node_memory_ratio
- node_disk: node_disk
- node_disk_ratio: node_disk_ratio
- node_state: node_state
**Example JSON representation of a Data Model:**
.. literalinclude:: samples/datamodel-list-response.json
:language: javascript

View File

@@ -51,7 +51,19 @@ if is_ssl_enabled_service "watcher" || is_service_enabled tls-proxy; then
WATCHER_SERVICE_PROTOCOL="https"
fi
WATCHER_USE_MOD_WSGI=$(trueorfalse True WATCHER_USE_MOD_WSGI)
# Support entry points installation of console scripts
if [[ -d $WATCHER_DIR/bin ]]; then
WATCHER_BIN_DIR=$WATCHER_DIR/bin
else
WATCHER_BIN_DIR=$(get_python_exec_prefix)
fi
# There are 2 modes, which is "uwsgi" which runs with an apache
# proxy uwsgi in front of it, or "mod_wsgi", which runs in
# apache. mod_wsgi is deprecated, don't use it.
WATCHER_USE_WSGI_MODE=${WATCHER_USE_WSGI_MODE:-$WSGI_MODE}
WATCHER_UWSGI=$WATCHER_BIN_DIR/watcher-api-wsgi
WATCHER_UWSGI_CONF=$WATCHER_CONF_DIR/watcher-uwsgi.ini
if is_suse; then
WATCHER_WSGI_DIR=${WATCHER_WSGI_DIR:-/srv/www/htdocs/watcher}
@@ -59,16 +71,15 @@ else
WATCHER_WSGI_DIR=${WATCHER_WSGI_DIR:-/var/www/watcher}
fi
# Public facing bits
WATCHER_SERVICE_HOST=${WATCHER_SERVICE_HOST:-$HOST_IP}
WATCHER_SERVICE_HOST=${WATCHER_SERVICE_HOST:-$SERVICE_HOST}
WATCHER_SERVICE_PORT=${WATCHER_SERVICE_PORT:-9322}
WATCHER_SERVICE_PORT_INT=${WATCHER_SERVICE_PORT_INT:-19322}
WATCHER_SERVICE_PROTOCOL=${WATCHER_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
# Support entry points installation of console scripts
if [[ -d $WATCHER_DIR/bin ]]; then
WATCHER_BIN_DIR=$WATCHER_DIR/bin
if [[ "$WATCHER_USE_WSGI_MODE" == "uwsgi" ]]; then
WATCHER_API_URL="$WATCHER_SERVICE_PROTOCOL://$WATCHER_SERVICE_HOST/infra-optim"
else
WATCHER_BIN_DIR=$(get_python_exec_prefix)
WATCHER_API_URL="$WATCHER_SERVICE_PROTOCOL://$WATCHER_SERVICE_HOST:$WATCHER_SERVICE_PORT"
fi
# Entry Points
@@ -93,7 +104,9 @@ function _cleanup_watcher_apache_wsgi {
# runs that a clean run would need to clean up
function cleanup_watcher {
sudo rm -rf $WATCHER_STATE_PATH $WATCHER_AUTH_CACHE_DIR
if [[ "$WATCHER_USE_MOD_WSGI" == "True" ]]; then
if [[ "$WATCHER_USE_WSGI_MODE" == "uwsgi" ]]; then
remove_uwsgi_config "$WATCHER_UWSGI_CONF" "$WATCHER_UWSGI"
else
_cleanup_watcher_apache_wsgi
fi
}
@@ -139,15 +152,15 @@ function create_watcher_accounts {
"infra-optim" "Watcher Infrastructure Optimization Service")
get_or_create_endpoint $watcher_service \
"$REGION_NAME" \
"$WATCHER_SERVICE_PROTOCOL://$WATCHER_SERVICE_HOST:$WATCHER_SERVICE_PORT" \
"$WATCHER_SERVICE_PROTOCOL://$WATCHER_SERVICE_HOST:$WATCHER_SERVICE_PORT" \
"$WATCHER_SERVICE_PROTOCOL://$WATCHER_SERVICE_HOST:$WATCHER_SERVICE_PORT"
"$WATCHER_API_URL"\
"$WATCHER_API_URL"\
"$WATCHER_API_URL"
}
# _config_watcher_apache_wsgi() - Set WSGI config files of watcher
function _config_watcher_apache_wsgi {
local watcher_apache_conf
if [[ "$WATCHER_USE_MOD_WSGI" == "True" ]]; then
if [[ "$WATCHER_USE_WSGI_MODE" == "mod_wsgi" ]]; then
local service_port=$WATCHER_SERVICE_PORT
if is_service_enabled tls-proxy; then
service_port=$WATCHER_SERVICE_PORT_INT
@@ -165,8 +178,6 @@ function _config_watcher_apache_wsgi {
s|%APACHE_NAME%|$APACHE_NAME|g;
" -i $watcher_apache_conf
enable_apache_site watcher-api
tail_log watcher-access /var/log/$APACHE_NAME/watcher-api-access.log
tail_log watcher-api /var/log/$APACHE_NAME/watcher-api.log
fi
}
@@ -182,13 +193,17 @@ function create_watcher_conf {
iniset_rpc_backend watcher $WATCHER_CONF
iniset $WATCHER_CONF database connection $(database_connection_url watcher)
iniset $WATCHER_CONF api host "$WATCHER_SERVICE_HOST"
iniset $WATCHER_CONF api host "$(ipv6_unquote $WATCHER_SERVICE_HOST)"
if is_service_enabled tls-proxy; then
iniset $WATCHER_CONF api host "$(ipv6_unquote $WATCHER_SERVICE_HOST)"
iniset $WATCHER_CONF api port "$WATCHER_SERVICE_PORT_INT"
# iniset $WATCHER_CONF api enable_ssl_api "True"
else
iniset $WATCHER_CONF api port "$WATCHER_SERVICE_PORT"
if [[ "$WATCHER_USE_WSGI_MODE" == "mod_wsgi" ]]; then
iniset $WATCHER_CONF api host "$(ipv6_unquote $WATCHER_SERVICE_HOST)"
iniset $WATCHER_CONF api port "$WATCHER_SERVICE_PORT"
fi
fi
iniset $WATCHER_CONF oslo_policy policy_file $WATCHER_POLICY_YAML
@@ -214,15 +229,12 @@ function create_watcher_conf {
fi
# Format logging
if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
setup_colorized_logging $WATCHER_CONF DEFAULT
else
# Show user_name and project_name instead of user_id and project_id
iniset $WATCHER_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(levelname)s %(name)s [%(request_id)s %(project_domain)s %(user_name)s %(project_name)s] %(instance)s%(message)s"
fi
setup_logging $WATCHER_CONF
#config apache files
if [[ "$WATCHER_USE_MOD_WSGI" == "True" ]]; then
if [[ "$WATCHER_USE_WSGI_MODE" == "uwsgi" ]]; then
write_uwsgi_config "$WATCHER_UWSGI_CONF" "$WATCHER_UWSGI" "/infra-optim"
else
_config_watcher_apache_wsgi
fi
# Register SSL certificates if provided
@@ -234,10 +246,6 @@ function create_watcher_conf {
iniset $WATCHER_CONF DEFAULT enabled_ssl_apis "$WATCHER_ENABLED_APIS"
fi
if is_service_enabled ceilometer; then
iniset $WATCHER_CONF watcher_messaging notifier_driver "messaging"
fi
}
# create_watcher_cache_dir() - Part of the init_watcher() process
@@ -273,7 +281,7 @@ function install_watcherclient {
function install_watcher {
git_clone $WATCHER_REPO $WATCHER_DIR $WATCHER_BRANCH
setup_develop $WATCHER_DIR
if [[ "$WATCHER_USE_MOD_WSGI" == "True" ]]; then
if [[ "$WATCHER_USE_WSGI_MODE" == "mod_wsgi" ]]; then
install_apache_wsgi
fi
}
@@ -284,24 +292,26 @@ function start_watcher_api {
local service_port=$WATCHER_SERVICE_PORT
local service_protocol=$WATCHER_SERVICE_PROTOCOL
local watcher_url
if is_service_enabled tls-proxy; then
service_port=$WATCHER_SERVICE_PORT_INT
service_protocol="http"
fi
if [[ "$WATCHER_USE_MOD_WSGI" == "True" ]]; then
if [[ "$WATCHER_USE_WSGI_MODE" == "uwsgi" ]]; then
run_process "watcher-api" "$WATCHER_BIN_DIR/uwsgi --ini $WATCHER_UWSGI_CONF"
watcher_url=$service_protocol://$SERVICE_HOST/infra-optim
else
watcher_url=$service_protocol://$SERVICE_HOST:$service_port
enable_apache_site watcher-api
restart_apache_server
else
run_process watcher-api "$WATCHER_BIN_DIR/watcher-api --config-file $WATCHER_CONF"
fi
# Start proxies if enabled
if is_service_enabled tls-proxy; then
start_tls_proxy watcher '*' $WATCHER_SERVICE_PORT $WATCHER_SERVICE_HOST $WATCHER_SERVICE_PORT_INT
# Start proxies if enabled
if is_service_enabled tls-proxy; then
start_tls_proxy watcher '*' $WATCHER_SERVICE_PORT $WATCHER_SERVICE_HOST $WATCHER_SERVICE_PORT_INT
fi
fi
echo "Waiting for watcher-api to start..."
if ! wait_for_service $SERVICE_TIMEOUT $service_protocol://$WATCHER_SERVICE_HOST:$service_port; then
if ! wait_for_service $SERVICE_TIMEOUT $watcher_url; then
die $LINENO "watcher-api did not start"
fi
@@ -317,11 +327,11 @@ function start_watcher {
# stop_watcher() - Stop running processes (non-screen)
function stop_watcher {
if [[ "$WATCHER_USE_MOD_WSGI" == "True" ]]; then
if [[ "$WATCHER_USE_WSGI_MODE" == "uwsgi" ]]; then
stop_process watcher-api
else
disable_apache_site watcher-api
restart_apache_server
else
stop_process watcher-api
fi
for serv in watcher-decision-engine watcher-applier; do
stop_process $serv

View File

@@ -10,6 +10,7 @@ SERVICE_PASSWORD=$ADMIN_PASSWORD
SERVICE_TOKEN=azertytoken
HOST_IP=192.168.42.2 # Change this to this compute node's IP address
#HOST_IPV6=2001:db8::7
FLAT_INTERFACE=eth0
FIXED_RANGE=10.254.1.0/24 # Change this to whatever your network is
@@ -30,12 +31,12 @@ ENABLED_SERVICES=n-cpu,n-api-meta,c-vol,q-agt,placement-client
NOVA_VNC_ENABLED=True
NOVNCPROXY_URL="http://$SERVICE_HOST:6080/vnc_auto.html"
VNCSERVER_LISTEN=0.0.0.0
VNCSERVER_PROXYCLIENT_ADDRESS=$HOST_IP
VNCSERVER_PROXYCLIENT_ADDRESS=$HOST_IP # or HOST_IPV6
NOVA_INSTANCES_PATH=/opt/stack/data/instances
# Enable the Ceilometer plugin for the compute agent
enable_plugin ceilometer git://git.openstack.org/openstack/ceilometer
enable_plugin ceilometer https://opendev.org/openstack/ceilometer
disable_service ceilometer-acentral,ceilometer-collector,ceilometer-api
LOGFILE=$DEST/logs/stack.sh.log
@@ -44,3 +45,9 @@ LOGDAYS=2
[[post-config|$NOVA_CONF]]
[DEFAULT]
compute_monitors=cpu.virt_driver
[notifications]
# Enable both versioned and unversioned notifications. Watcher only
# uses versioned notifications but ceilometer uses unversioned. We
# can change this to just versioned when ceilometer handles versioned
# notifications from nova: https://bugs.launchpad.net/ceilometer/+bug/1665449
notification_format=both

View File

@@ -10,6 +10,7 @@ SERVICE_PASSWORD=$ADMIN_PASSWORD
SERVICE_TOKEN=azertytoken
HOST_IP=192.168.42.1 # Change this to your controller node IP address
#HOST_IPV6=2001:db8::7
FLAT_INTERFACE=eth0
FIXED_RANGE=10.254.1.0/24 # Change this to whatever your network is
@@ -25,13 +26,13 @@ MULTI_HOST=1
disable_service n-cpu
# Enable the Watcher Dashboard plugin
enable_plugin watcher-dashboard git://git.openstack.org/openstack/watcher-dashboard
enable_plugin watcher-dashboard https://opendev.org/openstack/watcher-dashboard
# Enable the Watcher plugin
enable_plugin watcher git://git.openstack.org/openstack/watcher
enable_plugin watcher https://opendev.org/openstack/watcher
# Enable the Ceilometer plugin
enable_plugin ceilometer git://git.openstack.org/openstack/ceilometer
enable_plugin ceilometer https://opendev.org/openstack/ceilometer
# This is the controller node, so disable the ceilometer compute agent
disable_service ceilometer-acompute
@@ -48,3 +49,9 @@ LOGDAYS=2
[[post-config|$NOVA_CONF]]
[DEFAULT]
compute_monitors=cpu.virt_driver
[notifications]
# Enable both versioned and unversioned notifications. Watcher only
# uses versioned notifications but ceilometer uses unversioned. We
# can change this to just versioned when ceilometer handles versioned
# notifications from nova: https://bugs.launchpad.net/ceilometer/+bug/1665449
notification_format=both

View File

@@ -0,0 +1,9 @@
# Plug-in overrides
# https://docs.openstack.org/devstack/latest/plugins.html#plugin-interface
# Enable both versioned and unversioned notifications. Watcher only
# uses versioned notifications but ceilometer uses unversioned. We
# can change this to just versioned when ceilometer handles
# versioned notifications from nova:
# https://bugs.launchpad.net/ceilometer/+bug/1665449
NOVA_NOTIFICATION_FORMAT=both

View File

@@ -1,11 +1,18 @@
register_project_for_upgrade watcher
register_db_to_save watcher
devstack_localrc base enable_plugin watcher https://git.openstack.org/openstack/watcher stable/rocky
devstack_localrc target enable_plugin watcher https://git.openstack.org/openstack/watcher
devstack_localrc base enable_plugin watcher https://opendev.org/openstack/watcher $BASE_DEVSTACK_BRANCH
devstack_localrc target enable_plugin watcher https://opendev.org/openstack/watcher
devstack_localrc base enable_service watcher-api watcher-decision-engine watcher-applier
devstack_localrc target enable_service watcher-api watcher-decision-engine watcher-applier
BASE_RUN_SMOKE=False
TARGET_RUN_SMOKE=False
# Enable both versioned and unversioned notifications. Watcher only
# uses versioned notifications but ceilometer uses unversioned. We
# can change this to just versioned when ceilometer handles
# versioned notifications from nova:
# https://bugs.launchpad.net/ceilometer/+bug/1665449
devstack_localrc base NOVA_NOTIFICATION_FORMAT=both

View File

@@ -40,6 +40,10 @@ set -o errexit
source $TARGET_DEVSTACK_DIR/stackrc
source $TARGET_DEVSTACK_DIR/lib/apache
source $TARGET_DEVSTACK_DIR/lib/tls
source $TARGET_DEVSTACK_DIR/lib/keystone
source $TOP_DIR/openrc admin admin
source $(dirname $(dirname $BASH_SOURCE))/settings
source $(dirname $(dirname $BASH_SOURCE))/plugin.sh
@@ -56,6 +60,15 @@ install_watcher
# calls upgrade-watcher for specific release
upgrade_project watcher $RUN_DIR $BASE_DEVSTACK_BRANCH $TARGET_DEVSTACK_BRANCH
if [[ ! -f "$WATCHER_UWSGI_CONF" ]] && [[ "$WATCHER_USE_WSGI_MODE" == "uwsgi" ]]
then write_uwsgi_config "$WATCHER_UWSGI_CONF" "$WATCHER_UWSGI" "/infra-optim"
endpoints=$(openstack endpoint list --service watcher -c ID -f value)
for id in $endpoints; do
openstack endpoint delete $id
done
create_watcher_accounts
fi
# Migrate the database
watcher-db-manage upgrade || die $LINO "DB migration error"

View File

@@ -2,8 +2,10 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
openstackdocstheme>=1.20.0 # Apache-2.0
sphinx>=1.6.5,!=1.6.6,!=1.6.7 # BSD
sphinx>=1.6.5,!=1.6.6,!=1.6.7,<2.0.0;python_version=='2.7' # BSD
sphinx>=1.6.5,!=1.6.6,!=1.6.7,!=2.1.0;python_version>='3.4' # BSD
sphinxcontrib-pecanwsme>=0.8.0 # Apache-2.0
sphinxcontrib-svg2pdfconverter>=0.1.0 # BSD
reno>=2.7.0 # Apache-2.0
sphinxcontrib-apidoc>=0.2.0 # BSD
os-api-ref>=1.4.0 # Apache-2.0

View File

@@ -10,3 +10,4 @@ Administrator Guide
policy
ways-to-install
../strategies/index
../datasources/index

View File

@@ -51,7 +51,7 @@ Clone the Watcher repository:
.. code-block:: bash
$ git clone https://git.openstack.org/openstack/watcher.git
$ git clone https://opendev.org/openstack/watcher.git
$ cd watcher
Install the Watcher modules:
@@ -92,7 +92,7 @@ these commands:
By default, this will show logging on the console from which it was started.
Once started, you can use the `Watcher Client`_ to play with Watcher service.
.. _`Watcher Client`: https://git.openstack.org/cgit/openstack/python-watcherclient
.. _`Watcher Client`: https://opendev.org/openstack/python-watcherclient
Installing from packages: PyPI
--------------------------------

View File

@@ -479,4 +479,4 @@ change to a new value:
.. _Watcher API: https://developer.openstack.org/api-ref/resource-optimization/
.. _Watcher API: https://docs.openstack.org/api-ref/resource-optimization/

View File

@@ -32,7 +32,6 @@ sys.path.insert(0, os.path.abspath('./'))
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [
'oslo_config.sphinxext',
'sphinxcontrib.apidoc',
'sphinx.ext.viewcode',
'sphinxcontrib.httpdomain',
'sphinxcontrib.pecanwsme.rest',
@@ -43,6 +42,7 @@ extensions = [
'oslo_config.sphinxconfiggen',
'openstackdocstheme',
'sphinx.ext.napoleon',
'sphinxcontrib.rsvgconverter',
]
wsme_protocols = ['restjson']
@@ -51,22 +51,6 @@ config_generator_config_file = [(
'_static/watcher')]
sample_config_basename = 'watcher'
# autodoc generation is a bit aggressive and a nuisance when doing heavy
# text edit cycles.
# execute "export SPHINX_DEBUG=1" in your terminal to disable
# sphinxcontrib.apidoc options
apidoc_module_dir = '../../watcher'
apidoc_output_dir = 'api'
apidoc_excluded_paths = [
'tests/*',
'db',
'decision_engine',
'doc',
'objects',
]
apidoc_separate_modules = True
# The suffix of source filenames.
source_suffix = '.rst'
@@ -154,10 +138,21 @@ bug_tag = ''
# [howto/manual]).
latex_documents = [
('index',
'%s.tex' % project,
'doc-watcher.tex',
u'%s Documentation' % project,
u'OpenStack Foundation', 'manual'),
]
# If false, no module index is generated.
latex_domain_indices = False
latex_elements = {
'makeindex': '',
'printindex': '',
'preamble': r'\setcounter{tocdepth}{3}',
}
# Disable usage of xindy https://bugzilla.redhat.com/show_bug.cgi?id=1643664
latex_use_xindy = False
# Example configuration for intersphinx: refer to the Python standard library.
# intersphinx_mapping = {'http://docs.python.org/': None}

View File

@@ -178,7 +178,7 @@ You can easily generate and update a sample configuration file
named :ref:`watcher.conf.sample <watcher_sample_configuration_files>` by using
these following commands::
$ git clone git://git.openstack.org/openstack/watcher
$ git clone https://opendev.org/openstack/watcher.git
$ cd watcher/
$ tox -e genconfig
$ vi etc/watcher/watcher.conf.sample

View File

@@ -55,18 +55,17 @@ Wiki
https://wiki.openstack.org/Watcher
Code Hosting
https://git.openstack.org/cgit/openstack/watcher
https://opendev.org/openstack/watcher
Code Review
https://review.openstack.org/#/q/status:open+project:openstack/watcher,n,z
https://review.opendev.org/#/q/status:open+project:openstack/watcher,n,z
IRC Channel
``#openstack-watcher`` (changelog_)
Weekly Meetings
On Wednesdays at 14:00 UTC on even weeks in the ``#openstack-meeting-4``
IRC channel, 08:00 UTC on odd weeks in the ``#openstack-meeting-alt``
IRC channel (`meetings logs`_)
Bi-weekly, on Wednesdays at 08:00 UTC on odd weeks in the
``#openstack-meeting-alt`` IRC channel (`meetings logs`_)
.. _changelog: http://eavesdrop.openstack.org/irclogs/%23openstack-watcher/
.. _meetings logs: http://eavesdrop.openstack.org/meetings/watcher/

View File

@@ -19,7 +19,7 @@ model. To enable the Watcher plugin with DevStack, add the following to the
`[[local|localrc]]` section of your controller's `local.conf` to enable the
Watcher plugin::
enable_plugin watcher git://git.openstack.org/openstack/watcher
enable_plugin watcher https://opendev.org/openstack/watcher
For more detailed instructions, see `Detailed DevStack Instructions`_. Check
out the `DevStack documentation`_ for more information regarding DevStack.
@@ -27,6 +27,36 @@ out the `DevStack documentation`_ for more information regarding DevStack.
.. _PluginModelDocs: https://docs.openstack.org/devstack/latest/plugins.html
.. _DevStack documentation: https://docs.openstack.org/devstack/latest
Quick Devstack Instructions with Datasources
============================================
Watcher requires a datasource to collect metrics from compute nodes and
instances in order to execute most strategies. To enable this a
`[[local|localrc]]` to setup DevStack for some of the supported datasources
is provided. These examples specify the minimal configuration parameters to
get both Watcher and the datasource working but can be expanded is desired.
Gnocchi
-------
With the Gnocchi datasource most of the metrics for compute nodes and
instances will work with the provided configuration but metrics that
require Ironic such as `host_airflow and` `host_power` will still be
unavailable as well as `instance_l3_cpu_cache`::
[[local|localrc]]
enable_plugin watcher https://opendev.org/openstack/watcher
enable_plugin ceilometer https://opendev.org/openstack/ceilometer.git
CEILOMETER_BACKEND=gnocchi
enable_plugin aodh https://opendev.org/openstack/aodh
enable_plugin panko https://opendev.org/openstack/panko
[[post-config|$NOVA_CONF]]
[DEFAULT]
compute_monitors=cpu.virt_driver
Detailed DevStack Instructions
==============================
@@ -44,7 +74,7 @@ Detailed DevStack Instructions
sudo apt-get update
sudo apt-get install git
git clone https://git.openstack.org/openstack-dev/devstack
git clone https://opendev.org/openstack/devstack.git
sudo ./devstack/tools/create-stack-user.sh
Now you have a stack user that is used to run the DevStack processes. You
@@ -56,7 +86,7 @@ Detailed DevStack Instructions
sudo su stack
cd ~
git clone https://git.openstack.org/openstack-dev/devstack
git clone https://opendev.org/openstack/devstack.git
#. For each compute node, copy the provided `local.conf.compute`_ example file
to the compute node's system at ~/devstack/local.conf. Make sure the

View File

@@ -16,7 +16,7 @@ for development purposes.
To install Watcher from packaging, refer instead to Watcher `User
Documentation`_.
.. _`Git Repository`: https://git.openstack.org/cgit/openstack/watcher
.. _`Git Repository`: https://opendev.org/openstack/watcher
.. _`User Documentation`: https://docs.openstack.org/watcher/latest/
Prerequisites
@@ -47,7 +47,7 @@ Make a clone of the code from our `Git repository`:
.. code-block:: bash
$ git clone https://git.openstack.org/openstack/watcher.git
$ git clone https://opendev.org/openstack/watcher.git
When that is complete, you can:
@@ -99,7 +99,7 @@ useful to keep a clean environment for working on Watcher.
.. code-block:: bash
$ mkvirtualenv watcher
$ git clone https://git.openstack.org/openstack/watcher
$ git clone https://opendev.org/openstack/watcher.git
# Use 'python setup.py' to link Watcher into Python's site-packages
$ cd watcher && python setup.py install

View File

@@ -285,8 +285,15 @@ The following code snippet shows how datasource_backend is defined:
@property
def datasource_backend(self):
if not self._datasource_backend:
# Load the global preferred datasources order but override it
# if the strategy has a specific datasources config
datasources = CONF.watcher_datasources
if self.config.datasources:
datasources = self.config
self._datasource_backend = ds_manager.DataSourceManager(
config=self.config,
config=datasources,
osc=self.osc
).get_backend(self.DATASOURCE_METRICS)
return self._datasource_backend

View File

@@ -18,7 +18,7 @@ should download the latest `watcher`_ from the github. To run the same unit
tests that are executing onto `Gerrit`_ which includes ``py35``, ``py27`` and
``pep8``, you can issue the following command::
$ git clone https://git.openstack.org/openstack/watcher
$ git clone https://opendev.org/openstack/watcher
$ cd watcher
$ pip install tox
$ tox
@@ -31,8 +31,8 @@ the following::
$ tox -e pep8
.. _tox: https://tox.readthedocs.org/
.. _watcher: https://git.openstack.org/cgit/openstack/watcher
.. _Gerrit: https://review.openstack.org/
.. _watcher: https://opendev.org/openstack/watcher
.. _Gerrit: https://review.opendev.org/
If you only want to run specific unit test code and don't like to waste time
waiting for all unit tests to execute, you can add parameters ``--`` followed
@@ -48,4 +48,4 @@ Tempest tests
Tempest tests for Watcher has been migrated to the external repo
`watcher-tempest-plugin`_.
.. _watcher-tempest-plugin: https://git.openstack.org/cgit/openstack/watcher-tempest-plugin
.. _watcher-tempest-plugin: https://opendev.org/openstack/watcher-tempest-plugin

View File

@@ -0,0 +1,426 @@
==================
Grafana datasource
==================
Synopsis
--------
Grafana can interface with many different types of storage backends that
Grafana calls datasources_. Since the term datasources causes significant
confusion by overlapping definitions used in Watcher these **datasources are
called projects instead**. Some examples of supported projects are InfluxDB
or Elasticsearch while others might be more familiar such as Monasca or
Gnocchi. The Grafana datasource provides the functionality to retrieve metrics
from Grafana for different projects. This functionality is achieved by using
the proxy interface exposed in Grafana to communicate with Grafana projects
directly.
Background
**********
Since queries to retrieve metrics from Grafana are proxied to the project the
format of these queries will change significantly depending on the type of
project. The structure of the projects themselves will also change
significantly as they are structured by users and administrators. For instance,
some developers might decide to store metrics about compute_nodes in MySQL and
use the UUID as primary key while others use InfluxDB and use the hostname as
primary key. Furthermore, datasources in Watcher should return metrics in
specific units strictly defined in the baseclass_ depending on how the units
are stored in the projects they might require conversion before being returned.
The flexible configuration parameters of the Grafana datasource allow to
specify exactly how the deployment is configured and this will enable to
correct retrieval of metrics and with the correct units.
.. _datasources: https://grafana.com/plugins?type=datasource
.. _baseclass: https://github.com/openstack/watcher/blob/584eeefdc8/watcher/datasources/base.py
Requirements
------------
The use of the Grafana datasource requires a reachable Grafana endpoint and an
authentication token for access to the desired projects. The projects behind
Grafana will need to contain the metrics for compute_nodes_ or instances_ and
these need to be identifiable by an attribute of the Watcher datamodel_ for
instance hostname or UUID.
.. _compute_nodes: https://opendev.org/openstack/watcher/src/branch/master/watcher/decision_engine/model/element/node.py
.. _instances: https://opendev.org/openstack/watcher/src/branch/master/watcher/decision_engine/model/element/instance.py
.. _datamodel: https://opendev.org/openstack/watcher/src/branch/master/watcher/decision_engine/model/element
Limitations
***********
* Only the InfluxDB project is currently supported [#f1]_.
* All metrics must be retrieved from the same Grafana endpoint (same URL).
* All metrics must be retrieved with the same authentication token.
.. [#f1] A base class for projects is available_ and easily extensible.
.. _available: https://review.opendev.org/#/c/649341/24/watcher/datasources/grafana_translator/base.py
Configuration
-------------
Several steps are required in order to use the Grafana datasource, Most steps
are related configuring Watcher to match the deployed Grafana setup such as
queries proxied to the project or the type of project for any given metric.
Most of the configuration can either be supplied via the traditional
configuration file or in a `special yaml`_ file.
.. _special yaml: https://specs.openstack.org/openstack/watcher-specs/specs/train/approved/file-based-metricmap.html
token
*****
First step is to generate an access token with access to the required projects.
This can be done from the api_ or from the web interface_. Tokens generated
from the web interface will have the same access to projects as the user that
created them while using the cli allows to generate a key for a specific
role.The token will only be displayed once so store it well. This token will go
into the configuration file later and this parameter can not be placed in the
yaml.
.. _api: https://grafana.com/docs/http_api/auth/#create-api-key
.. _interface: https://grafana.com/docs/http_api/auth/#create-api-token
base_url
********
Next step is supplying the base url of the Grafana endpoint. The base url
parameter will need to specify the type of http protocol and the use of
plain text http is strongly discouraged due to the transmission of the access
token. Additionally the path to the proxy interface needs to be supplied as
well in case Grafana is placed in a sub directory of the web server. An example
would be: `https://mygrafana.org/api/datasource/proxy/` were
`/api/datasource/proxy` is the default path without any subdirectories.
Likewise, this parameter can not be placed in the yaml.
To prevent many errors from occurring and potentially filing the logs files it
is advised to specify the desired datasource in the configuration as it would
prevent the datasource manager from having to iterate and try possible
datasources with the launch of each audit. To do this specify `datasources` in
the `[watcher_datasources]` group.
The current configuration that is required to be placed in the traditional
configuration file would look like the following:
.. code-block:: shell
[grafana_client]
token = 0JLbF0oB4R3Q2Fl337Gh4Df5VN12D3adBE3f==
base_url = https://mygranfa.org/api/datasource/proxy
[watcher_datasources]
datasources = grafana
metric parameters
*****************
The last five remaining configuration parameters can all be placed both in the
traditional configuration file or in the yaml, however, it is not advised to
mix and match but in the case it does occur the yaml would override the
settings from the traditional configuration file. All five of these parameters
are dictionaries mapping specific metrics to a configuration parameter. For
instance the `project_id_map` will specify the specific project id in Grafana
to be used. The parameters are named as follow:
* project_id_map
* database_map
* translator_map
* attribute_map
* query_map
These five parameters are named differently if configured using the yaml
configuration file. The parameters are named as follows and are in
identical order as to the list of the traditional configuration file:
* project
* db
* translator
* attribute
* query
When specified in the yaml the parameters are no longer dictionaries instead
each parameter needs to be defined per metric as sub-parameters. Examples of
these parameters configured for both the yaml and traditional configuration
are described at the end of this document.
project_id
**********
The project id's can only be determined by someone with the admin role in
Grafana as that role is required to open the list of projects. The list of
projects can be found on `/datasources` in the web interface but
unfortunately it does not immediately display the project id. To display
the id one can best hover the mouse over the projects and the url will show the
project id's for example `/datasources/edit/7563`. Alternatively the entire
list of projects can be retrieved using the `REST api`_. To easily make
requests to the REST api a tool such as Postman can be used.
.. _REST api: https://grafana.com/docs/http_api/data_source/#get-all-datasources
database
********
The database is the parameter for the schema / database that is actually
defined in the project. For instance, if the project would be based on MySQL
this is were the name of schema used within the MySQL server would be
specified. For many different projects it is possible to list all the databases
currently available. Tools like Postman can be used to list all the available
databases per project. For InfluxDB based projects this would be with the
following path and query, however be sure to construct these request in Postman
as the header needs to contain the authorization token:
.. code-block:: shell
https://URL.DOMAIN/api/datasources/proxy/PROJECT_ID/query?q=SHOW%20DATABASES
translator
**********
Each translator is for a specific type of project will have a uniquely
identifiable name and the baseclass allows to easily support new types of
projects such as elasticsearch or prometheus. Currently only InfluxDB based
projects are supported as a result the only valid value for this parameter is `
influxdb`.
attribute
*********
The attribute parameter specifies which attribute to use from Watcher's
data model in order to construct the query. The available attributes differ
per type of object in the data model but the following table shows the
attributes for ComputeNodes, Instances and IronicNodes.
+-----------------+-----------------+--------------------+
| ComputeNode | Instance | IronicNode |
+=================+=================+====================+
| uuid | uuid | uuid |
+-----------------+-----------------+--------------------+
| id | name | human_id |
+-----------------+-----------------+--------------------+
| hostname | project_id | power_state |
+-----------------+-----------------+--------------------+
| status | watcher_exclude | maintenance |
+-----------------+-----------------+--------------------+
| disabled_reason | locked | maintenance_reason |
+-----------------+-----------------+--------------------+
| state | metadata | extra |
+-----------------+-----------------+--------------------+
| memory | state | |
+-----------------+-----------------+--------------------+
| disk | memory | |
+-----------------+-----------------+--------------------+
| disk_capacity | disk | |
+-----------------+-----------------+--------------------+
| vcpus | disk_capacity | |
+-----------------+-----------------+--------------------+
| | vcpus | |
+-----------------+-----------------+--------------------+
Many if not all of these attributes map to attributes of the objects that are
fetched from clients such as Nova. To see how these attributes are put into the
data model the following source files can be analyzed for Nova_ and Ironic_.
.. _Nova: https://opendev.org/openstack/watcher/src/branch/master/watcher/decision_engine/model/collector/nova.py#L304
.. _Ironic: https://opendev.org/openstack/watcher/src/branch/master/watcher/decision_engine/model/collector/ironic.py#L85
query
*****
The query is the single most important parameter it will be passed to the
project and should return the desired metric for the specific host and return
the value in the correct unit. The units for all available metrics are
documented in the `datasource baseclass`_. This might mean the query specified
in this parameter is responsible for converting the unit. The following query
demonstrates how such a conversion could be achieved and demonstrates the
conversion from bytes to megabytes.
.. code-block:: shell
SELECT value/1000000 FROM memory...
Queries will be formatted using the .format string method within Python. This
format will currently have give attributes exposed to it labeled `{0}` to
`{4}`. Every occurrence of these characters within the string will be replaced
with the specific attribute.
- {0} is the aggregate typically `mean`, `min`, `max` but `count` is also
supported.
- {1} is the attribute as specified in the attribute parameter.
- {2} is the period of time to aggregate data over in seconds.
- {3} is the granularity or the interval between data points in seconds.
- {4} is translator specific and in the case of InfluxDB it will be used for
retention_periods.
**InfluxDB**
Constructing the queries or rather anticipating how the results should look to
be correctly interpreted by Watcher can be a challenge. The following json
example demonstrates how what the result should look like and the query used to
get this result.
.. code-block:: json
{
"results": [
{
"statement_id": 0,
"series": [
{
"name": "vmstats",
"tags": {
"host": "autoserver01"
},
"columns": [
"time",
"mean"
],
"values": [
[
1560848284284,
7680000
]
]
}
]
}
]
}
.. code-block:: shell
SELECT {0}("{0}_value") FROM "vmstats" WHERE host =~ /^{1}$/ AND
"type_instance" =~ /^mem$/ AND time >= now() - {2}s GROUP BY host
.. _datasource baseclass: https://opendev.org/openstack/watcher/src/branch/master/watcher/datasources/base.py
Example configuration
---------------------
The example configurations will show both how to achieve the entire
configuration in the config file or use a combination of the regular file and
yaml. Using yaml to define all the parameters for each metric is recommended
since it has better human readability and supports mutli-line option
definitions.
Configuration file
******************
**It is important to note that the line breaks shown in between assignments of
parameters can not be used in the actual configuration and these are simply here
for readability reasons.**
.. code-block:: shell
[grafana_client]
# Authentication token to gain access (string value)
# Note: This option can be changed without restarting.
token = eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk==
# first part of the url (including https:// or http://) up until project id
# part. Example: https://secure.org/api/datasource/proxy/ (string value)
# Note: This option can be changed without restarting.
base_url = https://monitoring-grafana.com/api/datasources/proxy/
# Project id as in url (integer value)
# Note: This option can be changed without restarting.
project_id_map = host_cpu_usage:1337,host_ram_usage:6969,
instance_cpu_usage:1337,instance_ram_usage:9696
# Mapping of grafana databases to datasource metrics. (dict value)
# Note: This option can be changed without restarting.
database_map = host_cpu_usage:monit_production,
host_ram_usage:monit_production,instance_cpu_usage:prod_cloud,
instance_ram_usage:prod_cloud
translator_map = host_cpu_usage:influxdb,host_ram_usage:influxdb,
instance_cpu_usage:influxdb,instance_ram_usage:influxdb
attribute_map = host_cpu_usage:hostname,host_ram_usage:hostname,
instance_cpu_usage:name,instance_ram_usage:name
query_map = host_cpu_usage:SELECT 100-{0}("{0}_value") FROM {4}.cpu WHERE
("host" =~ /^{1}$/ AND "type_instance" =~/^idle$/ AND time > now()-{2}s),
host_ram_usage:SELECT {0}("{0}_value")/1000000 FROM {4}.memory WHERE
("host" =~ /^{1}$/) AND "type_instance" =~ /^used$/ AND time >= now()-{2}s
GROUP BY "type_instance",instance_cpu_usage:SELECT {0}("{0}_value") FROM
"vmstats" WHERE host =~ /^{1}$/ AND "type_instance" =~ /^cpu$/ AND time >=
now() - {2}s GROUP BY host,instance_ram_usage:SELECT {0}("{0}_value") FROM
"vmstats" WHERE host =~ /^{1}$/ AND "type_instance" =~ /^mem$/ AND time >=
now() - {2}s GROUP BY host
[grafana_translators]
retention_periods = one_week:10080,one_month:302400,five_years:525600
[watcher_datasources]
datasources = grafana
yaml
****
When using the yaml configuration file some parameters still need to be defined
using the regular configuration such as the path for the yaml file these
parameters are detailed below:
.. code-block:: shell
[grafana_client]
token = eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk==
base_url = https://monitoring-grafana.com/api/datasources/proxy/
[watcher_datasources]
datasources = grafana
[watcher_decision_engine]
metric_map_path = /etc/watcher/metric_map.yaml
Using the yaml allows to more effectively define the parameters per metric with
greater human readability due to the availability of multi line options. These
multi line options are demonstrated in the query parameters.
.. code-block:: yaml
grafana:
host_cpu_usage:
project: 1337
db: monit_production
translator: influxdb
attribute: hostname
query: >
SELECT 100-{0}("{0}_value") FROM {4}.cpu
WHERE ("host" =~ /^{1}$/ AND "type_instance" =~/^idle$/ AND
time > now()-{2}s)
host_ram_usage:
project: 6969
db: monit_production
translator: influxdb
attribute: hostname
query: >
SELECT {0}("{0}_value")/1000000 FROM {4}.memory WHERE
("host" =~ /^{1}$/) AND "type_instance" =~ /^used$/ AND time >=
now()-{2}s GROUP BY "type_instance"
instance_cpu_usage:
project: 1337
db: prod_cloud
translator: influxdb
attribute: name
query: >
SELECT {0}("{0}_value") FROM
"vmstats" WHERE host =~ /^{1}$/ AND "type_instance" =~ /^cpu$/ AND
time >= now() - {2}s GROUP BY host
instance_ram_usage:
project: 9696
db: prod_cloud
translator: influxdb
attribute: name
query: >
SELECT {0}("{0}_value") FROM
"vmstats" WHERE host =~ /^{1}$/ AND "type_instance" =~ /^mem$/ AND
time >= now() - {2}s GROUP BY host
External Links
--------------
- `List of Grafana datasources <https://grafana.com/plugins?type=datasource>`_

View File

@@ -0,0 +1,8 @@
Datasources
===========
.. toctree::
:glob:
:maxdepth: 1
./*

View File

@@ -8,7 +8,7 @@
Glossary
========
.. glossary::
.. _glossary:
:sorted:
This page explains the different terms used in the Watcher system.

View File

@@ -28,9 +28,9 @@ The documentation provided here is continually kept up-to-date based
on the latest code, and may not represent the state of the project at any
specific prior release.
.. _watcher: https://git.openstack.org/cgit/openstack/watcher/
.. _python-watcherclient: https://git.openstack.org/cgit/openstack/python-watcherclient/
.. _watcher-dashboard: https://git.openstack.org/cgit/openstack/watcher-dashboard/
.. _watcher: https://opendev.org/openstack/watcher/
.. _python-watcherclient: https://opendev.org/openstack/python-watcherclient/
.. _watcher-dashboard: https://opendev.org/openstack/watcher-dashboard/
Developer Guide
===============
@@ -83,7 +83,7 @@ API References
.. toctree::
:maxdepth: 1
API Reference <https://developer.openstack.org/api-ref/resource-optimization/>
API Reference <https://docs.openstack.org/api-ref/resource-optimization/>
Watcher API Microversion History </contributor/api_microversion_history>
Plugins
@@ -111,19 +111,12 @@ Watcher Manual Pages
man/index
.. # NOTE(mriedem): This is the section where we hide things that we don't
# actually want in the table of contents but sphinx build would fail if
# they aren't in the toctree somewhere. For example, we hide api/autoindex
# since that's already covered with modindex below.
.. toctree::
:hidden:
api/modules
.. only:: html
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@@ -78,6 +78,10 @@ Upgrade
**History of Checks**
**1.12.0 (Stein)**
**2.0.0 (Stein)**
* Sample check to be filled in with checks as they are added in Stein.
**3.0.0 (Train)**
* A check was added to enforce the minimum required version of nova API used.

View File

@@ -19,12 +19,16 @@ Metrics
The *basic* strategy requires the following metrics:
============================ ============ ======= =======
============================ ============ ======= ===========================
metric service name plugins comment
============================ ============ ======= =======
``compute.node.cpu.percent`` ceilometer_ none
``cpu_util`` ceilometer_ none
============================ ============ ======= =======
============================ ============ ======= ===========================
``compute.node.cpu.percent`` ceilometer_ none need to set the
``compute_monitors`` option
to ``cpu.virt_driver`` in
the nova.conf.
``cpu_util`` ceilometer_ none cpu_util has been removed
since Stein.
============================ ============ ======= ===========================
.. _ceilometer: https://docs.openstack.org/ceilometer/latest/admin/telemetry-measurements.html#openstack-compute

View File

@@ -0,0 +1,95 @@
====================================
Node Resource Consolidation Strategy
====================================
Synopsis
--------
**display name**: ``Node Resource Consolidation Strategy``
**goal**: ``Server Consolidation``
.. watcher-term:: watcher.decision_engine.strategy.strategies.node_resource_consolidation.NodeResourceConsolidation
Requirements
------------
None.
Metrics
*******
None
Cluster data model
******************
Default Watcher's Compute cluster data model:
.. watcher-term:: watcher.decision_engine.model.collector.nova.NovaClusterDataModelCollector
Actions
*******
Default Watcher's actions:
.. list-table::
:widths: 30 30
:header-rows: 1
* - action
- description
* - ``migration``
- .. watcher-term:: watcher.applier.actions.migration.Migrate
* - ``change_nova_service_state``
- .. watcher-term:: watcher.applier.actions.change_nova_service_state.ChangeNovaServiceState
Planner
*******
Default Watcher's planner:
.. watcher-term:: watcher.decision_engine.planner.weight.WeightPlanner
Configuration
-------------
Strategy parameters are:
==================== ====== =======================================
parameter type default Value description
==================== ====== =======================================
``host_choice`` String The way to select the server migration
destination node, The value auto means
that Nova schedular selects the
destination node, and specify means
the strategy specifies the destination.
==================== ====== =======================================
Efficacy Indicator
------------------
None
Algorithm
---------
For more information on the Node Resource Consolidation Strategy please refer
to: https://specs.openstack.org/openstack/watcher-specs/specs/train/approved/node-resource-consolidation.html
How to use it ?
---------------
.. code-block:: shell
$ openstack optimize audittemplate create \
at1 server_consolidation \
--strategy node_resource_consolidation
$ openstack optimize audit create \
-a at1 -p host_choice=auto
External Links
--------------
None.

View File

@@ -19,14 +19,15 @@ Metrics
The *vm_workload_consolidation* strategy requires the following metrics:
============================ ============ ======= =======
============================ ============ ======= =========================
metric service name plugins comment
============================ ============ ======= =======
``cpu_util`` ceilometer_ none
============================ ============ ======= =========================
``cpu_util`` ceilometer_ none cpu_util has been removed
since Stein.
``memory.resident`` ceilometer_ none
``memory`` ceilometer_ none
``disk.root.size`` ceilometer_ none
============================ ============ ======= =======
============================ ============ ======= =========================
.. _ceilometer: https://docs.openstack.org/ceilometer/latest/admin/telemetry-measurements.html#openstack-compute

View File

@@ -19,17 +19,21 @@ Metrics
The *workload_stabilization* strategy requires the following metrics:
============================ ============ ======= =======
============================ ============ ======= =============================
metric service name plugins comment
============================ ============ ======= =======
``compute.node.cpu.percent`` ceilometer_ none
============================ ============ ======= =============================
``compute.node.cpu.percent`` ceilometer_ none need to set the
``compute_monitors`` option
to ``cpu.virt_driver`` in the
nova.conf.
``hardware.memory.used`` ceilometer_ SNMP_
``cpu_util`` ceilometer_ none
``cpu_util`` ceilometer_ none cpu_util has been removed
since Stein.
``memory.resident`` ceilometer_ none
============================ ============ ======= =======
============================ ============ ======= =============================
.. _ceilometer: https://docs.openstack.org/ceilometer/latest/admin/telemetry-measurements.html#openstack-compute
.. _SNMP: http://docs.openstack.org/admin-guide/telemetry-measurements.html
.. _SNMP: https://docs.openstack.org/ceilometer/latest/admin/telemetry-measurements.html#snmp-based-meters
Cluster data model
******************

View File

@@ -21,12 +21,13 @@ Metrics
The *workload_balance* strategy requires the following metrics:
======================= ============ ======= =======
======================= ============ ======= =========================
metric service name plugins comment
======================= ============ ======= =======
``cpu_util`` ceilometer_ none
======================= ============ ======= =========================
``cpu_util`` ceilometer_ none cpu_util has been removed
since Stein.
``memory.resident`` ceilometer_ none
======================= ============ ======= =======
======================= ============ ======= =========================
.. _ceilometer: https://docs.openstack.org/ceilometer/latest/admin/telemetry-measurements.html#openstack-compute

View File

@@ -55,7 +55,7 @@ plugin installation guide`_.
$ watcher ...
.. _`installation guide`: https://docs.openstack.org/python-watcherclient/latest
.. _`installation guide`: https://docs.openstack.org/watcher/latest/install/
.. _`Watcher Horizon plugin installation guide`: https://docs.openstack.org/watcher-dashboard/latest/install/installation.html
.. _`OpenStack CLI`: https://docs.openstack.org/python-openstackclient/latest/cli/man/openstack.html
.. _`Watcher CLI`: https://docs.openstack.org/python-watcherclient/latest/cli/index.html

View File

@@ -16,7 +16,7 @@ Listen 9322
<VirtualHost *:9322>
WSGIDaemonProcess watcher-api user=stack group=stack processes=2 threads=2 display-name=%{GROUP}
WSGIScriptAlias / /opt/stack/watcher/watcher/api/app.wsgi
WSGIScriptAlias / /usr/local/bin/watcher-api-wsgi
WSGIProcessGroup watcher-api
ErrorLog /var/log/httpd/watcher_error.log

View File

@@ -6,7 +6,6 @@ APScheduler==3.5.1
asn1crypto==0.24.0
automaton==1.14.0
Babel==2.5.3
bandit==1.4.0
beautifulsoup4==4.6.0
cachetools==2.0.1
certifi==2018.1.18
@@ -34,7 +33,7 @@ fixtures==3.0.0
flake8==2.5.5
freezegun==0.3.10
future==0.16.0
futurist==1.6.0
futurist==1.8.0
gitdb2==2.0.3
GitPython==2.1.8
gnocchiclient==7.0.1
@@ -73,14 +72,15 @@ os-client-config==1.29.0
os-service-types==1.2.0
os-testr==1.0.0
osc-lib==1.10.0
os-resource-classes==0.4.0
oslo.cache==1.29.0
oslo.concurrency==3.26.0
oslo.config==5.2.0
oslo.context==2.20.0
oslo.context==2.21.0
oslo.db==4.35.0
oslo.i18n==3.20.0
oslo.log==3.37.0
oslo.messaging==5.36.0
oslo.messaging==8.1.2
oslo.middleware==3.35.0
oslo.policy==1.34.0
oslo.reports==1.27.0
@@ -94,7 +94,7 @@ packaging==17.1
Paste==2.0.3
PasteDeploy==1.5.2
pbr==3.1.1
pecan==1.2.1
pecan==1.3.2
pep8==1.5.7
pika==0.10.0
pika-pool==0.1.3
@@ -113,12 +113,12 @@ python-cinderclient==3.5.0
python-dateutil==2.7.0
python-editor==1.0.3
python-glanceclient==2.9.1
python-ironicclient==2.3.0
python-ironicclient==2.5.0
python-keystoneclient==3.15.0
python-mimeparse==1.6.0
python-monascaclient==1.12.0
python-neutronclient==6.7.0
python-novaclient==10.1.0
python-novaclient==14.1.0
python-openstackclient==3.14.0
python-subunit==1.2.0
pytz==2018.3
@@ -159,7 +159,7 @@ urllib3==1.22
vine==1.1.4
waitress==1.1.0
warlock==1.3.0
WebOb==1.7.4
WebOb==1.8.5
WebTest==2.0.29
wrapt==1.10.11
WSME==0.9.2

View File

@@ -13,12 +13,12 @@
set -x
cat > clonemap.yaml << EOF
clonemap:
- name: openstack-infra/devstack-gate
- name: openstack/devstack-gate
dest: devstack-gate
EOF
/usr/zuul-env/bin/zuul-cloner -m clonemap.yaml --cache-dir /opt/git \
git://git.openstack.org \
openstack-infra/devstack-gate
https://opendev.org \
openstack/devstack-gate
executable: /bin/bash
chdir: '{{ ansible_user_dir }}/workspace'
environment: '{{ zuul | zuul_legacy_vars }}'
@@ -29,13 +29,13 @@
set -x
export PYTHONUNBUFFERED=true
export PROJECTS="openstack-dev/grenade $PROJECTS"
export PROJECTS="openstack/grenade $PROJECTS"
export PROJECTS="openstack/watcher $PROJECTS"
export PROJECTS="openstack/watcher-tempest-plugin $PROJECTS"
export PROJECTS="openstack/python-watcherclient $PROJECTS"
export DEVSTACK_PROJECT_FROM_GIT="python-watcherclient $DEVSTACK_PROJECT_FROM_GIT"
export GRENADE_PLUGINRC="enable_grenade_plugin watcher https://git.openstack.org/openstack/watcher"
export GRENADE_PLUGINRC="enable_grenade_plugin watcher https://opendev.org/openstack/watcher"
export DEVSTACK_LOCAL_CONFIG+=$'\n'"export TEMPEST_PLUGINS='/opt/stack/new/watcher-tempest-plugin'"
export DEVSTACK_GATE_TEMPEST_NOTESTS=1

View File

@@ -0,0 +1,7 @@
---
features:
- |
Add force field to Audit. User can set --force to enable the new option when
launching audit. If force is True, audit will be executed despite of ongoing
actionplan. The new audit may create a wrong actionplan if they use the same
data model.

View File

@@ -0,0 +1,9 @@
---
features:
- |
API calls while building the Compute data model will be retried upon
failure. The amount of failures allowed before giving up and the time before
reattempting are configurable. The `api_call_retries` and
`api_query_timeout` parameters in the `[collector]` group can be used to
adjust these paremeters. 10 retries with a 1 second time in between
reattempts is the default.

View File

@@ -0,0 +1,17 @@
---
features:
- |
All datasources can now be configured to retry retrieving a metric upon
encountering an error. Between each attempt will be a set amount of time
which can be adjusted from the configuration. These configuration
options can be found in the `[watcher_datasources]` group and are named
`query_max_retries` and `query_timeout`.
upgrade:
- |
If Gnocchi was configured to have a custom amount of retries and or a
custom timeout then the configuration needs to moved into the
`[watcher_datasources]` group instead of the `[gnocchi_client]` group.
deprecations:
- |
The configuration options for query retries in `[gnocchi_client]` are
deprecated and the option in `[watcher_datasources]` should now be used.

View File

@@ -0,0 +1,11 @@
---
features:
- |
Allow using file to override metric map. Override the metric map of
each datasource as soon as it is created by the manager. This override
comes from a file whose path is provided by a setting in config file.
The setting is `watcher_decision_engine/metric_map_path`. The file
contains a map per datasource whose keys are the metric names as
recognized by watcher and the value is the real name of the metric
in the datasource. This setting defaults to `/etc/watcher/metric_map.yaml`,
and presence of this file is optional.

View File

@@ -0,0 +1,17 @@
---
features:
- |
Improved interface for datasource baseclass that better defines expected
values and types for parameters and return types of all abstract methods.
This allows all strategies to work with every datasource provided the
metrics are configured for that given datasource.
deprecations:
- |
The new strategy baseclass has significant changes in method parameters
and any out-of-tree strategies will have to be adopted.
- |
Several strategies have changed the `node` parameter to `compute_node` to
be better aligned with terminology. These strategies include
`basic_consolidation` and `workload_stabilzation`. The `node` parameter
will remain supported during Train release and will be removed in the
subsequent release.

View File

@@ -0,0 +1,11 @@
---
features:
- |
Watcher now supports configuring which datasource to use and in which
order. This configuration is done by specifying datasources in the
watcher_datasources section:
- ``[watcher_datasources] datasources = gnocchi,monasca,ceilometer``
Specific strategies can override this order and use datasources which
are not listed in the global preference.

View File

@@ -0,0 +1,10 @@
---
features:
- |
Grafana has been added as datasource that can be used for collecting
metrics. The configuration options allow to specify what metrics and how
they are stored in grafana so that no matter how Grafana is configured it
can still be used. The configuration can be done via the typical
configuration file but it is recommended to configure most options in the
yaml file for metrics. For a complete walkthrough on configuring Grafana
see: https://docs.openstack.org/watcher/latest/datasources/grafana.html

View File

@@ -0,0 +1,23 @@
---
features:
- |
Watcher can get resource information such as total, allocation ratio and
reserved information from Placement API.
Now we add some new fields to the Watcher Data Model:
* vcpu_reserved: The amount of cpu a node has reserved for its own use.
* vcpu_ratio: CPU allocation ratio.
* memory_mb_reserved: The amount of memory a node has reserved for
its own use.
* memory_ratio: Memory allocation ratio.
* disk_gb_reserved: The amount of disk a node has reserved for its own use.
* disk_ratio: Disk allocation ratio.
We also add some new propeties:
* vcpu_capacity: The amount of vcpu, take allocation ratio into account,
but do not include reserved.
* memory_mb_capacity: The amount of memory, take allocation ratio into
account, but do not include reserved.
* disk_gb_capacity: The amount of disk, take allocation ratio into
account, but do not include reserved.

View File

@@ -0,0 +1,8 @@
---
upgrade:
- |
The minimum required version of the ``[nova_client]/api_version`` value
is now enforced to be ``2.56`` which is available since the Queens version
of the nova compute service.
A ``watcher-status upgrade check`` has been added for this.

View File

@@ -0,0 +1,7 @@
---
features:
- |
Added strategy "node resource consolidation". This
strategy is used to centralize VMs to as few nodes
as possible by VM migration. User can set an input
parameter to decide how to select the destination node.

View File

@@ -0,0 +1,12 @@
---
features:
- |
Add show data model api for Watcher. New in version 1.3.
User can use 'openstack optimize datamodel list'
command to view the current data model information in memory.
User can also add '--audit <Audit_UUID>' to view specific data model
in memory filted by the scope in audit.
User can also add '--detail' to view detailed information about current data model.
User can also add '--type <type>' to specify the type of data model.
Default type is 'compute'. In the future, type 'storage' and 'baremetal'
will be supported.

View File

@@ -0,0 +1,5 @@
---
features:
- |
Add keystone_client Group for user to configure 'interface' and 'region_name'
by watcher.conf. The default value of 'interface' is 'admin'.

View File

@@ -0,0 +1,8 @@
---
features:
- |
Added Placement API helper to Watcher. Now Watcher can get information
about resource providers, it can be used for the data model and strategies.
Config group placement_client with options 'api_version', 'interface' and
'region_name' is also added. The default values for 'api_version' and
'interface' are 1.29 and 'public', respectively.

View File

@@ -0,0 +1,12 @@
---
upgrade:
- |
An Watcher API WSGI application script ``watcher-api-wsgi`` is now
available. It is auto-generated by ``pbr`` and allows to run the API
service using WSGI server (for example Nginx and uWSGI).
deprecations:
- |
Using ``watcher/api/app.wsgi`` script is deprecated and it will be removed
in U release.
Please switch to automatically generated ``watcher-api-wsgi`` script
instead.

View File

@@ -0,0 +1,5 @@
---
features:
- Now Watcher strategy can select specific planner
beyond default. Strategy can set planner property
to specify its own planner.

View File

@@ -21,6 +21,7 @@ Contents:
:maxdepth: 1
unreleased
stein
rocky
queens
pike

View File

@@ -0,0 +1,33 @@
# Gérald LONLAS <g.lonlas@gmail.com>, 2016. #zanata
msgid ""
msgstr ""
"Project-Id-Version: python-watcher\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-03-22 02:21+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2016-10-22 06:44+0000\n"
"Last-Translator: Gérald LONLAS <g.lonlas@gmail.com>\n"
"Language-Team: French\n"
"Language: fr\n"
"X-Generator: Zanata 4.3.3\n"
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
msgid "0.29.0"
msgstr "0.29.0"
msgid "Contents:"
msgstr "Contenu :"
msgid "Current Series Release Notes"
msgstr "Note de la release actuelle"
msgid "New Features"
msgstr "Nouvelles fonctionnalités"
msgid "Newton Series Release Notes"
msgstr "Note de release pour Newton"
msgid "Welcome to watcher's Release Notes documentation!"
msgstr "Bienvenue dans la documentation de la note de Release de Watcher"

View File

@@ -0,0 +1,6 @@
===================================
Stein Series Release Notes
===================================
.. release-notes::
:branch: stable/stein

View File

@@ -6,18 +6,19 @@ apscheduler>=3.5.1 # MIT License
enum34>=1.1.6;python_version=='2.7' or python_version=='2.6' or python_version=='3.3' # BSD
jsonpatch>=1.21 # BSD
keystoneauth1>=3.4.0 # Apache-2.0
jsonschema<3.0.0,>=2.6.0 # MIT
jsonschema>=2.6.0 # MIT
keystonemiddleware>=4.21.0 # Apache-2.0
lxml>=4.1.1 # BSD
croniter>=0.3.20 # MIT License
os-resource-classes>=0.4.0
oslo.concurrency>=3.26.0 # Apache-2.0
oslo.cache>=1.29.0 # Apache-2.0
oslo.config>=5.2.0 # Apache-2.0
oslo.context>=2.20.0 # Apache-2.0
oslo.context>=2.21.0 # Apache-2.0
oslo.db>=4.35.0 # Apache-2.0
oslo.i18n>=3.20.0 # Apache-2.0
oslo.log>=3.37.0 # Apache-2.0
oslo.messaging>=5.36.0 # Apache-2.0
oslo.messaging>=8.1.2 # Apache-2.0
oslo.policy>=1.34.0 # Apache-2.0
oslo.reports>=1.27.0 # Apache-2.0
oslo.serialization>=2.25.0 # Apache-2.0
@@ -27,7 +28,7 @@ oslo.utils>=3.36.0 # Apache-2.0
oslo.versionedobjects>=1.32.0 # Apache-2.0
PasteDeploy>=1.5.2 # MIT
pbr>=3.1.1 # Apache-2.0
pecan>=1.2.1 # BSD
pecan>=1.3.2 # BSD
PrettyTable<0.8,>=0.7.2 # BSD
gnocchiclient>=7.0.1 # Apache-2.0
python-ceilometerclient>=2.9.0 # Apache-2.0
@@ -36,14 +37,17 @@ python-glanceclient>=2.9.1 # Apache-2.0
python-keystoneclient>=3.15.0 # Apache-2.0
python-monascaclient>=1.12.0 # Apache-2.0
python-neutronclient>=6.7.0 # Apache-2.0
python-novaclient>=10.1.0 # Apache-2.0
python-novaclient>=14.1.0 # Apache-2.0
python-openstackclient>=3.14.0 # Apache-2.0
python-ironicclient>=2.3.0 # Apache-2.0
python-ironicclient>=2.5.0 # Apache-2.0
six>=1.11.0 # MIT
SQLAlchemy>=1.2.5 # MIT
stevedore>=1.28.0 # Apache-2.0
taskflow>=3.1.0 # Apache-2.0
WebOb>=1.7.4 # MIT
WebOb>=1.8.5 # MIT
WSME>=0.9.2 # MIT
networkx>=1.11 # BSD
# NOTE(fdegir): NetworkX 2.3 dropped support for Python 2
networkx>=1.11,<2.3;python_version<'3.0' # BSD
networkx>=1.11;python_version>='3.4' # BSD
microversion_parse>=0.2.1 # Apache-2.0
futurist>=1.8.0 # Apache-2.0

View File

@@ -16,7 +16,8 @@ classifier =
Programming Language :: Python :: 2
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
[files]
packages =
@@ -46,6 +47,9 @@ console_scripts =
watcher-sync = watcher.cmd.sync:main
watcher-status = watcher.cmd.status:main
wsgi_scripts =
watcher-api-wsgi = watcher.api.wsgi:initialize_wsgi_app
watcher.database.migration_backend =
sqlalchemy = watcher.db.sqlalchemy.migration
@@ -83,6 +87,7 @@ watcher_strategies =
storage_capacity_balance = watcher.decision_engine.strategy.strategies.storage_capacity_balance:StorageCapacityBalance
zone_migration = watcher.decision_engine.strategy.strategies.zone_migration:ZoneMigration
host_maintenance = watcher.decision_engine.strategy.strategies.host_maintenance:HostMaintenance
node_resource_consolidation = watcher.decision_engine.strategy.strategies.node_resource_consolidation:NodeResourceConsolidation
watcher_actions =
migrate = watcher.applier.actions.migration:Migrate
@@ -99,6 +104,7 @@ watcher_workflow_engines =
watcher_planners =
weight = watcher.decision_engine.planner.weight:WeightPlanner
workload_stabilization = watcher.decision_engine.planner.workload_stabilization:WorkloadStabilizationPlanner
node_resource_consolidation = watcher.decision_engine.planner.node_resource_consolidation:NodeResourceConsolidationPlanner
watcher_cluster_data_model_collectors =
compute = watcher.decision_engine.model.collector.nova:NovaClusterDataModelCollector

View File

@@ -13,4 +13,4 @@ testscenarios>=0.5.0 # Apache-2.0/BSD
testtools>=2.3.0 # MIT
stestr>=2.0.0 # Apache-2.0
os-api-ref>=1.4.0 # Apache-2.0
bandit>=1.1.0 # Apache-2.0
bandit>=1.6.0 # Apache-2.0

34
tox.ini
View File

@@ -1,16 +1,19 @@
[tox]
minversion = 2.0
envlist = py35,py27,pep8
envlist = py36,py37,py27,pep8
skipsdist = True
[testenv]
usedevelop = True
whitelist_externals = find
rm
install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
install_command = pip install {opts} {packages}
setenv =
VIRTUAL_ENV={envdir}
deps = -r{toxinidir}/test-requirements.txt
deps =
-c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
-r{toxinidir}/test-requirements.txt
-r{toxinidir}/requirements.txt
commands =
rm -f .testrepository/times.dbm
find . -type f -name "*.py[c|o]" -delete
@@ -22,11 +25,16 @@ basepython = python3
commands =
doc8 doc/source/ CONTRIBUTING.rst HACKING.rst README.rst
flake8
bandit -r watcher -x tests -n5 -ll -s B320
bandit -r watcher -x watcher/tests/* -n5 -ll -s B320
[testenv:venv]
basepython = python3
setenv = PYTHONHASHSEED=0
deps =
-c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
-r{toxinidir}/doc/requirements.txt
-r{toxinidir}/test-requirements.txt
-r{toxinidir}/requirements.txt
commands = {posargs}
[testenv:cover]
@@ -44,7 +52,9 @@ commands =
basepython = python3
setenv = PYTHONHASHSEED=0
deps = -r{toxinidir}/doc/requirements.txt
commands = sphinx-build -W -b html doc/source doc/build/html
commands =
rm -fr doc/build doc/source/api/ .autogenerated
sphinx-build -W -b html doc/source doc/build/html
[testenv:api-ref]
basepython = python3
@@ -90,6 +100,18 @@ extension=.rst
# todo: stop ignoring doc/source/man when https://bugs.launchpad.net/doc8/+bug/1502391 is fixed
ignore-path=doc/source/image_src,doc/source/man,doc/source/api
[testenv:pdf-docs]
basepython = python3
envdir = {toxworkdir}/docs
deps = {[testenv:docs]deps}
whitelist_externals =
rm
make
commands =
rm -rf doc/build/pdf
sphinx-build -W -b latex doc/source doc/build/pdf
make -C doc/build/pdf
[testenv:releasenotes]
basepython = python3
deps = -r{toxinidir}/doc/requirements.txt
@@ -98,7 +120,7 @@ commands = sphinx-build -a -W -E -d releasenotes/build/doctrees -b html releasen
[testenv:bandit]
basepython = python3
deps = -r{toxinidir}/test-requirements.txt
commands = bandit -r watcher -x tests -n5 -ll -s B320
commands = bandit -r watcher -x watcher/tests/* -n5 -ll -s B320
[testenv:lower-constraints]
basepython = python3

View File

@@ -16,24 +16,9 @@
Use this file for deploying the API service under Apache2 mod_wsgi.
"""
import sys
from oslo_config import cfg
import oslo_i18n as i18n
from oslo_log import log
# This script is deprecated and it will be removed in U release.
# Please switch to automatically generated watcher-api-wsgi script instead.
from watcher.api import wsgi
from watcher.api import app
from watcher.common import service
CONF = cfg.CONF
i18n.install('watcher')
service.prepare_service(sys.argv)
LOG = log.getLogger(__name__)
LOG.debug("Configuration:")
CONF.log_opt_values(LOG, log.DEBUG)
application = app.VersionSelectorApplication()
application = wsgi.initialize_wsgi_app(show_deprecated=True)

View File

@@ -25,3 +25,8 @@ was requested.
Added the parameters ``start_time`` and ``end_time`` to
create audit request. Supported for start and end time of continuous
audits.
1.2
---
Added ``force`` into create audit request. If ``force`` is true,
audit will be executed despite of ongoing actionplan.

View File

@@ -35,6 +35,7 @@ from watcher.api.controllers.v1 import action
from watcher.api.controllers.v1 import action_plan
from watcher.api.controllers.v1 import audit
from watcher.api.controllers.v1 import audit_template
from watcher.api.controllers.v1 import data_model
from watcher.api.controllers.v1 import goal
from watcher.api.controllers.v1 import scoring_engine
from watcher.api.controllers.v1 import service
@@ -114,6 +115,9 @@ class V1(APIBase):
audits = [link.Link]
"""Links to the audits resource"""
data_model = [link.Link]
"""Links to the data model resource"""
actions = [link.Link]
"""Links to the actions resource"""
@@ -158,6 +162,13 @@ class V1(APIBase):
'audits', '',
bookmark=True)
]
v1.data_model = [link.Link.make_link('self', pecan.request.host_url,
'data_model', ''),
link.Link.make_link('bookmark',
pecan.request.host_url,
'data_model', '',
bookmark=True)
]
v1.actions = [link.Link.make_link('self', pecan.request.host_url,
'actions', ''),
link.Link.make_link('bookmark',
@@ -202,6 +213,7 @@ class Controller(rest.RestController):
scoring_engines = scoring_engine.ScoringEngineController()
services = service.ServicesController()
strategies = strategy.StrategiesController()
data_model = data_model.DataModelController()
@wsme_pecan.wsexpose(V1)
def get(self):

View File

@@ -117,9 +117,9 @@ class Action(base.APIBase):
uuid = wtypes.wsattr(types.uuid, readonly=True)
"""Unique UUID for this action"""
action_plan_uuid = wsme.wsproperty(types.uuid, _get_action_plan_uuid,
_set_action_plan_uuid,
mandatory=True)
action_plan_uuid = wtypes.wsproperty(types.uuid, _get_action_plan_uuid,
_set_action_plan_uuid,
mandatory=True)
"""The action plan this action belongs to """
state = wtypes.text
@@ -137,7 +137,7 @@ class Action(base.APIBase):
parents = wtypes.wsattr(types.jsontype, readonly=True)
"""UUIDs of parent actions"""
links = wsme.wsattr([link.Link], readonly=True)
links = wtypes.wsattr([link.Link], readonly=True)
"""A list containing a self link and associated action links"""
def __init__(self, **kwargs):

View File

@@ -95,7 +95,7 @@ class ActionPlanPatchType(types.JsonPatchType):
@staticmethod
def _validate_state(patch):
serialized_patch = {'path': patch.path, 'op': patch.op}
if patch.value is not wsme.Unset:
if patch.value is not wtypes.Unset:
serialized_patch['value'] = patch.value
# todo: use state machines to handle state transitions
state_value = patch.value
@@ -214,19 +214,20 @@ class ActionPlan(base.APIBase):
uuid = wtypes.wsattr(types.uuid, readonly=True)
"""Unique UUID for this action plan"""
audit_uuid = wsme.wsproperty(types.uuid, _get_audit_uuid, _set_audit_uuid,
mandatory=True)
audit_uuid = wtypes.wsproperty(types.uuid, _get_audit_uuid,
_set_audit_uuid,
mandatory=True)
"""The UUID of the audit this port belongs to"""
strategy_uuid = wsme.wsproperty(
strategy_uuid = wtypes.wsproperty(
wtypes.text, _get_strategy_uuid, _set_strategy_uuid, mandatory=False)
"""Strategy UUID the action plan refers to"""
strategy_name = wsme.wsproperty(
strategy_name = wtypes.wsproperty(
wtypes.text, _get_strategy_name, _set_strategy_name, mandatory=False)
"""The name of the strategy this action plan refers to"""
efficacy_indicators = wsme.wsproperty(
efficacy_indicators = wtypes.wsproperty(
types.jsontype, _get_efficacy_indicators, _set_efficacy_indicators,
mandatory=True)
"""The list of efficacy indicators associated to this action plan"""
@@ -237,10 +238,10 @@ class ActionPlan(base.APIBase):
state = wtypes.text
"""This action plan state"""
links = wsme.wsattr([link.Link], readonly=True)
links = wtypes.wsattr([link.Link], readonly=True)
"""A list containing a self link and associated action links"""
hostname = wsme.wsattr(wtypes.text, mandatory=False)
hostname = wtypes.wsattr(wtypes.text, mandatory=False)
"""Hostname the actionplan is running on"""
def __init__(self, **kwargs):

View File

@@ -71,8 +71,10 @@ def hide_fields_in_newer_versions(obj):
matches or exceeds the versions when these fields were introduced.
"""
if not api_utils.allow_start_end_audit_time():
obj.start_time = wsme.Unset
obj.end_time = wsme.Unset
obj.start_time = wtypes.Unset
obj.end_time = wtypes.Unset
if not api_utils.allow_force():
obj.force = wtypes.Unset
class AuditPostType(wtypes.Base):
@@ -87,12 +89,12 @@ class AuditPostType(wtypes.Base):
audit_type = wtypes.wsattr(wtypes.text, mandatory=True)
state = wsme.wsattr(wtypes.text, readonly=True,
default=objects.audit.State.PENDING)
state = wtypes.wsattr(wtypes.text, readonly=True,
default=objects.audit.State.PENDING)
parameters = wtypes.wsattr({wtypes.text: types.jsontype}, mandatory=False,
default={})
interval = wsme.wsattr(types.interval_or_cron, mandatory=False)
interval = wtypes.wsattr(types.interval_or_cron, mandatory=False)
scope = wtypes.wsattr(types.jsontype, readonly=True)
@@ -100,9 +102,11 @@ class AuditPostType(wtypes.Base):
hostname = wtypes.wsattr(wtypes.text, readonly=True, mandatory=False)
start_time = wsme.wsattr(datetime.datetime, mandatory=False)
start_time = wtypes.wsattr(datetime.datetime, mandatory=False)
end_time = wsme.wsattr(datetime.datetime, mandatory=False)
end_time = wtypes.wsattr(datetime.datetime, mandatory=False)
force = wtypes.wsattr(bool, mandatory=False)
def as_audit(self, context):
audit_type_values = [val.value for val in objects.audit.AuditType]
@@ -130,7 +134,7 @@ class AuditPostType(wtypes.Base):
if not api_utils.allow_start_end_audit_time():
for field in ('start_time', 'end_time'):
if getattr(self, field) not in (wsme.Unset, None):
if getattr(self, field) not in (wtypes.Unset, None):
raise exception.NotAcceptable()
# If audit_template_uuid was provided, we will provide any
@@ -192,7 +196,8 @@ class AuditPostType(wtypes.Base):
scope=self.scope,
auto_trigger=self.auto_trigger,
start_time=self.start_time,
end_time=self.end_time)
end_time=self.end_time,
force=self.force)
class AuditPatchType(types.JsonPatchType):
@@ -316,49 +321,53 @@ class Audit(base.APIBase):
state = wtypes.text
"""This audit state"""
goal_uuid = wsme.wsproperty(
goal_uuid = wtypes.wsproperty(
wtypes.text, _get_goal_uuid, _set_goal_uuid, mandatory=True)
"""Goal UUID the audit refers to"""
goal_name = wsme.wsproperty(
goal_name = wtypes.wsproperty(
wtypes.text, _get_goal_name, _set_goal_name, mandatory=False)
"""The name of the goal this audit refers to"""
strategy_uuid = wsme.wsproperty(
strategy_uuid = wtypes.wsproperty(
wtypes.text, _get_strategy_uuid, _set_strategy_uuid, mandatory=False)
"""Strategy UUID the audit refers to"""
strategy_name = wsme.wsproperty(
strategy_name = wtypes.wsproperty(
wtypes.text, _get_strategy_name, _set_strategy_name, mandatory=False)
"""The name of the strategy this audit refers to"""
parameters = {wtypes.text: types.jsontype}
"""The strategy parameters for this audit"""
links = wsme.wsattr([link.Link], readonly=True)
links = wtypes.wsattr([link.Link], readonly=True)
"""A list containing a self link and associated audit links"""
interval = wsme.wsattr(wtypes.text, mandatory=False)
interval = wtypes.wsattr(wtypes.text, mandatory=False)
"""Launch audit periodically (in seconds)"""
scope = wsme.wsattr(types.jsontype, mandatory=False)
scope = wtypes.wsattr(types.jsontype, mandatory=False)
"""Audit Scope"""
auto_trigger = wsme.wsattr(bool, mandatory=False, default=False)
auto_trigger = wtypes.wsattr(bool, mandatory=False, default=False)
"""Autoexecute action plan once audit is succeeded"""
next_run_time = wsme.wsattr(datetime.datetime, mandatory=False)
next_run_time = wtypes.wsattr(datetime.datetime, mandatory=False)
"""The next time audit launch"""
hostname = wsme.wsattr(wtypes.text, mandatory=False)
hostname = wtypes.wsattr(wtypes.text, mandatory=False)
"""Hostname the audit is running on"""
start_time = wsme.wsattr(datetime.datetime, mandatory=False)
start_time = wtypes.wsattr(datetime.datetime, mandatory=False)
"""The start time for continuous audit launch"""
end_time = wsme.wsattr(datetime.datetime, mandatory=False)
end_time = wtypes.wsattr(datetime.datetime, mandatory=False)
"""The end time that stopping continuous audit"""
force = wsme.wsattr(bool, mandatory=False, default=False)
"""Allow Action Plan of this Audit be executed in parallel
with other Action Plan"""
def __init__(self, **kwargs):
self.fields = []
fields = list(objects.Audit.fields)

View File

@@ -342,29 +342,29 @@ class AuditTemplate(base.APIBase):
description = wtypes.wsattr(wtypes.text, mandatory=False)
"""Short description of this audit template"""
goal_uuid = wsme.wsproperty(
goal_uuid = wtypes.wsproperty(
wtypes.text, _get_goal_uuid, _set_goal_uuid, mandatory=True)
"""Goal UUID the audit template refers to"""
goal_name = wsme.wsproperty(
goal_name = wtypes.wsproperty(
wtypes.text, _get_goal_name, _set_goal_name, mandatory=False)
"""The name of the goal this audit template refers to"""
strategy_uuid = wsme.wsproperty(
strategy_uuid = wtypes.wsproperty(
wtypes.text, _get_strategy_uuid, _set_strategy_uuid, mandatory=False)
"""Strategy UUID the audit template refers to"""
strategy_name = wsme.wsproperty(
strategy_name = wtypes.wsproperty(
wtypes.text, _get_strategy_name, _set_strategy_name, mandatory=False)
"""The name of the strategy this audit template refers to"""
audits = wsme.wsattr([link.Link], readonly=True)
audits = wtypes.wsattr([link.Link], readonly=True)
"""Links to the collection of audits contained in this audit template"""
links = wsme.wsattr([link.Link], readonly=True)
links = wtypes.wsattr([link.Link], readonly=True)
"""A list containing a self link and associated audit template links"""
scope = wsme.wsattr(types.jsontype, mandatory=False)
scope = wtypes.wsattr(types.jsontype, mandatory=False)
"""Audit Scope"""
def __init__(self, **kwargs):

View File

@@ -0,0 +1,68 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2019 ZTE Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
An Interface for users and admin to List Data Model.
"""
import pecan
from pecan import rest
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from watcher.api.controllers.v1 import types
from watcher.common import exception
from watcher.common import policy
from watcher.decision_engine import rpcapi
class DataModelController(rest.RestController):
"""REST controller for data model"""
def __init__(self):
super(DataModelController, self).__init__()
from_data_model = False
"""A flag to indicate if the requests to this controller are coming
from the top-level resource DataModel."""
@wsme_pecan.wsexpose(wtypes.text, wtypes.text, types.uuid)
def get_all(self, data_model_type='compute', audit_uuid=None):
"""Retrieve information about the given data model.
:param data_model_type: The type of data model user wants to list.
Supported values: compute.
Future support values: storage, baremetal.
The default value is compute.
:param audit_uuid: The UUID of the audit, used to filter data model
by the scope in audit.
"""
if self.from_data_model:
raise exception.OperationNotPermitted
allowed_data_model_type = [
'compute',
]
if data_model_type not in allowed_data_model_type:
raise exception.DataModelTypeNotFound(
data_model_type=data_model_type)
context = pecan.request.context
de_client = rpcapi.DecisionEngineAPI()
policy.enforce(context, 'data_model:get_all',
action='data_model:get_all')
rpc_all_data_model = de_client.get_data_model_info(
context,
data_model_type,
audit_uuid)
return rpc_all_data_model

View File

@@ -34,7 +34,6 @@ Here are some examples of :ref:`Goals <goal_definition>`:
import pecan
from pecan import rest
import wsme
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
@@ -77,7 +76,7 @@ class Goal(base.APIBase):
efficacy_specification = wtypes.wsattr(types.jsontype, readonly=True)
"""Efficacy specification for this goal"""
links = wsme.wsattr([link.Link], readonly=True)
links = wtypes.wsattr([link.Link], readonly=True)
"""A list containing a self link and associated audit template links"""
def __init__(self, **kwargs):

View File

@@ -29,7 +29,6 @@ be needed by the user of a given scoring engine.
import pecan
from pecan import rest
import wsme
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
@@ -73,7 +72,7 @@ class ScoringEngine(base.APIBase):
metainfo = wtypes.text
"""A metadata associated with the scoring engine"""
links = wsme.wsattr([link.Link], readonly=True)
links = wtypes.wsattr([link.Link], readonly=True)
"""A list containing a self link and associated action links"""
def __init__(self, **kwargs):

View File

@@ -26,7 +26,6 @@ from oslo_log import log
from oslo_utils import timeutils
import pecan
from pecan import rest
import wsme
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
@@ -93,7 +92,7 @@ class Service(base.APIBase):
else:
self._status = objects.service.ServiceStatus.ACTIVE
id = wsme.wsattr(int, readonly=True)
id = wtypes.wsattr(int, readonly=True)
"""ID for this service."""
name = wtypes.text
@@ -102,13 +101,13 @@ class Service(base.APIBase):
host = wtypes.text
"""Host where service is placed on."""
last_seen_up = wsme.wsattr(datetime.datetime, readonly=True)
last_seen_up = wtypes.wsattr(datetime.datetime, readonly=True)
"""Time when Watcher service sent latest heartbeat."""
status = wsme.wsproperty(wtypes.text, _get_status, _set_status,
mandatory=True)
status = wtypes.wsproperty(wtypes.text, _get_status, _set_status,
mandatory=True)
links = wsme.wsattr([link.Link], readonly=True)
links = wtypes.wsattr([link.Link], readonly=True)
"""A list containing a self link."""
def __init__(self, **kwargs):

View File

@@ -29,7 +29,6 @@ to find an optimal :ref:`Solution <solution_definition>`.
import pecan
from pecan import rest
import wsme
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
@@ -109,15 +108,15 @@ class Strategy(base.APIBase):
display_name = wtypes.text
"""Localized name of the strategy"""
links = wsme.wsattr([link.Link], readonly=True)
links = wtypes.wsattr([link.Link], readonly=True)
"""A list containing a self link and associated goal links"""
goal_uuid = wsme.wsproperty(wtypes.text, _get_goal_uuid, _set_goal_uuid,
mandatory=True)
goal_uuid = wtypes.wsproperty(wtypes.text, _get_goal_uuid, _set_goal_uuid,
mandatory=True)
"""The UUID of the goal this audit refers to"""
goal_name = wsme.wsproperty(wtypes.text, _get_goal_name, _set_goal_name,
mandatory=False)
goal_name = wtypes.wsproperty(wtypes.text, _get_goal_name, _set_goal_name,
mandatory=False)
"""The name of the goal this audit refers to"""
parameters_spec = {wtypes.text: types.jsontype}

View File

@@ -165,3 +165,12 @@ def allow_start_end_audit_time():
audits.
"""
return pecan.request.version.minor >= versions.MINOR_1_START_END_TIMING
def allow_force():
"""Check if we should support optional force attribute for Audit.
Version 1.2 of the API added support for forced audits that allows to
launch audit when other action plan is ongoing.
"""
return pecan.request.version.minor >= versions.MINOR_2_FORCE

View File

@@ -22,11 +22,13 @@ BASE_VERSION = 1
#
# v1.0: corresponds to Rocky API
# v1.1: Add start/end time for continuous audit
# v1.2: Add force field to audit
MINOR_0_ROCKY = 0
MINOR_1_START_END_TIMING = 1
MINOR_2_FORCE = 2
MINOR_MAX_VERSION = MINOR_1_START_END_TIMING
MINOR_MAX_VERSION = MINOR_2_FORCE
# String representations of the minor and maximum versions
_MIN_VERSION_STRING = '{}.{}'.format(BASE_VERSION, MINOR_0_ROCKY)

View File

@@ -34,9 +34,8 @@ LOG = log.getLogger(__name__)
class APISchedulingService(scheduling.BackgroundSchedulerService):
def __init__(self, gconfig=None, **options):
def __init__(self, gconfig={}, **options):
self.services_status = {}
gconfig = None or {}
super(APISchedulingService, self).__init__(gconfig, **options)
def get_services_status(self, context):

41
watcher/api/wsgi.py Normal file
View File

@@ -0,0 +1,41 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""WSGI script for Watcher API, installed by pbr."""
import sys
from oslo_config import cfg
import oslo_i18n as i18n
from oslo_log import log
from watcher.api import app
from watcher.common import service
CONF = cfg.CONF
LOG = log.getLogger(__name__)
def initialize_wsgi_app(show_deprecated=False):
i18n.install('watcher')
service.prepare_service(sys.argv)
LOG.debug("Configuration:")
CONF.log_opt_values(LOG, log.DEBUG)
if show_deprecated:
LOG.warning("Using watcher/api/app.wsgi is deprecated and it will "
"be removed in U release. Please use automatically "
"generated watcher-api-wsgi instead.")
return app.VersionSelectorApplication()

View File

@@ -131,11 +131,8 @@ class BaseAction(loadable.Loadable):
raise NotImplementedError()
def validate_parameters(self):
try:
jsonschema.validate(self.input_parameters, self.schema)
return True
except jsonschema.ValidationError as e:
raise e
jsonschema.validate(self.input_parameters, self.schema)
return True
@abc.abstractmethod
def get_description(self):

View File

@@ -50,6 +50,7 @@ class ChangeNovaServiceState(base.BaseAction):
STATE = 'state'
REASON = 'disabled_reason'
RESOURCE_NAME = 'resource_name'
@property
def schema(self):
@@ -60,6 +61,10 @@ class ChangeNovaServiceState(base.BaseAction):
'type': 'string',
"minlength": 1
},
'resource_name': {
'type': 'string',
"minlength": 1
},
'state': {
'type': 'string',
'enum': [element.ServiceState.ONLINE.value,
@@ -78,7 +83,7 @@ class ChangeNovaServiceState(base.BaseAction):
@property
def host(self):
return self.resource_id
return self.input_parameters.get(self.RESOURCE_NAME)
@property
def state(self):

View File

@@ -87,6 +87,10 @@ class Migrate(base.BaseAction):
"([a-fA-F0-9]){4}-([a-fA-F0-9]){4}-"
"([a-fA-F0-9]){12}$")
},
'resource_name': {
'type': 'string',
"minlength": 1
},
'source_node': {
'type': 'string',
"minLength": 1
@@ -182,7 +186,7 @@ class Migrate(base.BaseAction):
return self.migrate(destination=self.destination_node)
def revert(self):
return self.migrate(destination=self.source_node)
LOG.info('Migrate action do not revert!')
def abort(self):
nova = nova_helper.NovaHelper(osc=self.osc)

View File

@@ -87,6 +87,10 @@ class VolumeMigrate(base.BaseAction):
"([a-fA-F0-9]){4}-([a-fA-F0-9]){4}-"
"([a-fA-F0-9]){12}$")
},
'resource_name': {
'type': 'string',
"minlength": 1
},
'migration_type': {
'type': 'string',
"enum": ["swap", "retype", "migrate"]
@@ -109,11 +113,8 @@ class VolumeMigrate(base.BaseAction):
}
def validate_parameters(self):
try:
jsonschema.validate(self.input_parameters, self.schema)
return True
except jsonschema.ValidationError as e:
raise e
jsonschema.validate(self.input_parameters, self.schema)
return True
@property
def volume_id(self):

View File

@@ -16,7 +16,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
from concurrent import futures
import futurist
from oslo_config import cfg
from oslo_log import log
@@ -31,7 +31,7 @@ class TriggerActionPlan(object):
def __init__(self, applier_manager):
self.applier_manager = applier_manager
workers = CONF.watcher_applier.workers
self.executor = futures.ThreadPoolExecutor(max_workers=workers)
self.executor = futurist.GreenThreadPoolExecutor(max_workers=workers)
def do_launch_action_plan(self, context, action_plan_uuid):
try:

View File

@@ -91,7 +91,7 @@ class DefaultWorkFlowEngine(base.BaseWorkFlowEngine):
# default although we still want to leave the possibility for
# the users to change it.
# The current implementation uses graph with linked actions.
# todo(jed) add olso conf for retry and name
# todo(jed) add oslo conf for retry and name
self.execution_rule = self.get_execution_rule(actions)
flow = gf.Flow("watcher_flow")
actions_uuid = {}
@@ -106,7 +106,7 @@ class DefaultWorkFlowEngine(base.BaseWorkFlowEngine):
decider=self.decider)
e = engines.load(
flow, engine='parallel',
flow, executor='greenthreaded', engine='parallel',
max_workers=self.config.max_workers)
e.run()

View File

@@ -0,0 +1,20 @@
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# NOTE(licanwei): Do eventlet monkey patching here, instead of in
# common/service.py. This allows the API service to run without monkey
# patching under Apache (which uses its own concurrency model). Mixing
# concurrency models can cause undefined behavior and potentially API timeouts.
import eventlet
eventlet.monkey_patch()

View File

@@ -15,8 +15,10 @@
import sys
from oslo_upgradecheck import upgradecheck
import six
from watcher._i18n import _
from watcher.common import clients
from watcher import conf
CONF = conf.CONF
@@ -30,17 +32,18 @@ class Checks(upgradecheck.UpgradeCommands):
and added to _upgrade_checks tuple.
"""
def _sample_check(self):
"""This is sample check added to test the upgrade check framework
It needs to be removed after adding any real upgrade check
"""
return upgradecheck.Result(upgradecheck.Code.SUCCESS, 'Sample detail')
def _minimum_nova_api_version(self):
"""Checks the minimum required version of nova_client.api_version"""
try:
clients.check_min_nova_api_version(CONF.nova_client.api_version)
except ValueError as e:
return upgradecheck.Result(
upgradecheck.Code.FAILURE, six.text_type(e))
return upgradecheck.Result(upgradecheck.Code.SUCCESS)
_upgrade_checks = (
# Sample check added for now.
# Whereas in future real checks must be added here in tuple
(_('Sample Check'), _sample_check),
# Added in Train.
(_('Minimum Nova API Version'), _minimum_nova_api_version),
)

View File

@@ -10,31 +10,52 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from cinderclient import client as ciclient
from glanceclient import client as glclient
from gnocchiclient import client as gnclient
from ironicclient import client as irclient
from keystoneauth1 import adapter as ka_adapter
from keystoneauth1 import loading as ka_loading
from keystoneclient import client as keyclient
from monascaclient import client as monclient
from neutronclient.neutron import client as netclient
from novaclient import api_versions as nova_api_versions
from novaclient import client as nvclient
from watcher.common import exception
from watcher import conf
try:
from ceilometerclient import client as ceclient
HAS_CEILCLIENT = True
except ImportError:
HAS_CEILCLIENT = False
CONF = conf.CONF
CONF = cfg.CONF
_CLIENTS_AUTH_GROUP = 'watcher_clients_auth'
# NOTE(mriedem): This is the minimum required version of the nova API for
# watcher features to work. If new features are added which require new
# versions, they should perform version discovery and be backward compatible
# for at least one release before raising the minimum required version.
MIN_NOVA_API_VERSION = '2.56'
def check_min_nova_api_version(config_version):
"""Validates the minimum required nova API version.
:param config_version: The configured [nova_client]/api_version value
:raises: ValueError if the configured version is less than the required
minimum
"""
min_required = nova_api_versions.APIVersion(MIN_NOVA_API_VERSION)
if nova_api_versions.APIVersion(config_version) < min_required:
raise ValueError('Invalid nova_client.api_version %s. %s or '
'greater is required.' % (config_version,
MIN_NOVA_API_VERSION))
class OpenStackClients(object):
"""Convenience class to create and cache client instances."""
@@ -53,6 +74,7 @@ class OpenStackClients(object):
self._monasca = None
self._neutron = None
self._ironic = None
self._placement = None
def _get_keystone_session(self):
auth = ka_loading.load_auth_from_conf_options(CONF,
@@ -77,8 +99,16 @@ class OpenStackClients(object):
@exception.wrap_keystone_exception
def keystone(self):
if not self._keystone:
self._keystone = keyclient.Client(session=self.session)
if self._keystone:
return self._keystone
keystone_interface = self._get_client_option('keystone',
'interface')
keystone_region_name = self._get_client_option('keystone',
'region_name')
self._keystone = keyclient.Client(
interface=keystone_interface,
region_name=keystone_region_name,
session=self.session)
return self._keystone
@@ -88,6 +118,9 @@ class OpenStackClients(object):
return self._nova
novaclient_version = self._get_client_option('nova', 'api_version')
check_min_nova_api_version(novaclient_version)
nova_endpoint_type = self._get_client_option('nova', 'endpoint_type')
nova_region_name = self._get_client_option('nova', 'region_name')
self._nova = nvclient.Client(novaclient_version,
@@ -227,7 +260,31 @@ class OpenStackClients(object):
endpoint_type = self._get_client_option('ironic', 'endpoint_type')
ironic_region_name = self._get_client_option('ironic', 'region_name')
self._ironic = irclient.get_client(ironicclient_version,
os_endpoint_type=endpoint_type,
interface=endpoint_type,
region_name=ironic_region_name,
session=self.session)
return self._ironic
@exception.wrap_keystone_exception
def placement(self):
if self._placement:
return self._placement
placement_version = self._get_client_option('placement',
'api_version')
placement_interface = self._get_client_option('placement',
'interface')
placement_region_name = self._get_client_option('placement',
'region_name')
# Set accept header on every request to ensure we notify placement
# service of our response body media type preferences.
headers = {'accept': 'application/json'}
self._placement = ka_adapter.Adapter(
session=self.session,
service_type='placement',
default_microversion=placement_version,
interface=placement_interface,
region_name=placement_region_name,
additional_headers=headers)
return self._placement

View File

@@ -21,12 +21,15 @@ from watcher.common import rpc
from watcher import version
def parse_args(argv, default_config_files=None):
def parse_args(argv, default_config_files=None, default_config_dirs=None):
default_config_files = (default_config_files or
cfg.find_config_files(project='watcher'))
default_config_dirs = (default_config_dirs or
cfg.find_config_dirs(project='watcher'))
rpc.set_defaults(control_exchange='watcher')
cfg.CONF(argv[1:],
project='python-watcher',
project='watcher',
version=version.version_info.release_string(),
default_config_dirs=default_config_dirs,
default_config_files=default_config_files)
rpc.init(cfg.CONF)

View File

@@ -26,16 +26,15 @@ import functools
import sys
from keystoneclient import exceptions as keystone_exceptions
from oslo_config import cfg
from oslo_log import log
import six
from watcher._i18n import _
from watcher import conf
LOG = log.getLogger(__name__)
CONF = conf.CONF
CONF = cfg.CONF
def wrap_keystone_exception(func):
@@ -211,6 +210,10 @@ class InvalidIntervalOrCron(Invalid):
msg_fmt = _("Expected an interval or cron syntax but received %(name)s")
class DataModelTypeNotFound(ResourceNotFound):
msg_fmt = _("The %(data_model_type)s data model could not be found")
class GoalNotFound(ResourceNotFound):
msg_fmt = _("Goal %(goal)s could not be found")
@@ -236,11 +239,6 @@ class AuditTemplateAlreadyExists(Conflict):
"already exists")
class AuditTemplateReferenced(Invalid):
msg_fmt = _("AuditTemplate %(audit_template)s is referenced by one or "
"multiple audits")
class AuditTypeNotFound(Invalid):
msg_fmt = _("Audit type %(audit_type)s could not be found")
@@ -360,26 +358,10 @@ class IllegalArgumentException(WatcherException):
msg_fmt = _('Illegal argument')
class NoSuchMetric(WatcherException):
msg_fmt = _('No such metric')
class NoDataFound(WatcherException):
msg_fmt = _('No rows were returned')
class AuthorizationFailure(WatcherException):
msg_fmt = _('%(client)s connection failed. Reason: %(reason)s')
class KeystoneFailure(WatcherException):
msg_fmt = _("Keystone API endpoint is missing")
class MetricCollectorNotDefined(WatcherException):
msg_fmt = _("The metrics resource collector is not defined")
class ClusterStateStale(WatcherException):
msg_fmt = _("The cluster state is stale")
@@ -392,10 +374,6 @@ class ClusterStateNotDefined(WatcherException):
msg_fmt = _("The cluster state is not defined")
class CapacityNotDefined(WatcherException):
msg_fmt = _("The capacity %(capacity)s is not defined for '%(resource)s'")
class NoAvailableStrategyForGoal(WatcherException):
msg_fmt = _("No strategy could be found to achieve the '%(goal)s' goal.")
@@ -410,10 +388,6 @@ class GlobalEfficacyComputationError(WatcherException):
"goal using the '%(strategy)s' strategy.")
class NoMetricValuesForInstance(WatcherException):
msg_fmt = _("No values returned by %(resource_id)s for %(metric_name)s.")
class UnsupportedDataSource(UnsupportedError):
msg_fmt = _("Datasource %(datasource)s is not supported "
"by strategy %(strategy)s")
@@ -423,6 +397,16 @@ class DataSourceNotAvailable(WatcherException):
msg_fmt = _("Datasource %(datasource)s is not available.")
class MetricNotAvailable(WatcherException):
"""Indicate that a metric is not configured or does not exists"""
msg_fmt = _('Metric: %(metric)s not available')
class NoDatasourceAvailable(WatcherException):
"""No datasources have been configured"""
msg_fmt = _('No datasources available')
class NoSuchMetricForHost(WatcherException):
msg_fmt = _("No %(metric)s metric for %(host)s found.")
@@ -467,6 +451,11 @@ class InstanceNotFound(ComputeResourceNotFound):
msg_fmt = _("The instance '%(name)s' could not be found")
class InstanceNotMapped(ComputeResourceNotFound):
msg_fmt = _("The mapped compute node for instance '%(uuid)s' "
"could not be found.")
class ComputeNodeNotFound(ComputeResourceNotFound):
msg_fmt = _("The compute node %(name)s could not be found")

View File

@@ -27,7 +27,6 @@ import novaclient.exceptions as nvexceptions
from watcher.common import clients
from watcher.common import exception
from watcher.common import utils
from watcher import conf
LOG = log.getLogger(__name__)
@@ -46,39 +45,92 @@ class NovaHelper(object):
self.glance = self.osc.glance()
def get_compute_node_list(self):
return self.nova.hypervisors.list()
hypervisors = self.nova.hypervisors.list()
# filter out baremetal nodes from hypervisors
compute_nodes = [node for node in hypervisors if
node.hypervisor_type != 'ironic']
return compute_nodes
def get_compute_node_by_id(self, node_id):
"""Get compute node by ID (*not* UUID)"""
# We need to pass an object with an 'id' attribute to make it work
return self.nova.hypervisors.get(utils.Struct(id=node_id))
def get_compute_node_by_name(self, node_name, servers=False,
detailed=False):
"""Search for a hypervisor (compute node) by hypervisor_hostname
def get_compute_node_by_name(self, node_name, servers=False):
return self.nova.hypervisors.search(node_name, servers)
:param node_name: The hypervisor_hostname to search
:param servers: If true, include information about servers per
hypervisor
:param detailed: If true, include information about the compute service
per hypervisor (requires microversion 2.53)
"""
return self.nova.hypervisors.search(node_name, servers=servers,
detailed=detailed)
def get_compute_node_by_hostname(self, node_hostname):
"""Get compute node by hostname"""
try:
hypervisors = [hv for hv in self.get_compute_node_list()
if hv.service['host'] == node_hostname]
if len(hypervisors) != 1:
# TODO(hidekazu)
# this may occur if VMware vCenter driver is used
raise exception.ComputeNodeNotFound(name=node_hostname)
else:
compute_nodes = self.nova.hypervisors.search(
hypervisors[0].hypervisor_hostname)
if len(compute_nodes) != 1:
raise exception.ComputeNodeNotFound(name=node_hostname)
"""Get compute node by hostname
return self.get_compute_node_by_id(compute_nodes[0].id)
:param node_hostname: Compute service hostname
:returns: novaclient.v2.hypervisors.Hypervisor object if found
:raises: ComputeNodeNotFound if no hypervisor is found for the compute
service hostname or there was an error communicating with nova
"""
try:
# This is a fuzzy match on hypervisor_hostname so we could get back
# more than one compute node. If so, match on the compute service
# hostname.
compute_nodes = self.get_compute_node_by_name(
node_hostname, detailed=True)
for cn in compute_nodes:
if cn.service['host'] == node_hostname:
return cn
raise exception.ComputeNodeNotFound(name=node_hostname)
except Exception as exc:
LOG.exception(exc)
raise exception.ComputeNodeNotFound(name=node_hostname)
def get_instance_list(self):
return self.nova.servers.list(search_opts={'all_tenants': True},
limit=-1)
def get_compute_node_by_uuid(self, node_uuid):
"""Get compute node by uuid
:param node_uuid: hypervisor id as uuid after microversion 2.53
:returns: novaclient.v2.hypervisors.Hypervisor object if found
"""
return self.nova.hypervisors.get(node_uuid)
def get_instance_list(self, filters=None, marker=None, limit=-1):
"""List servers for all tenants with details.
This always gets servers with the all_tenants=True filter.
:param filters: Dict of additional filters (optional).
:param marker: Get servers that appear later in the server
list than that represented by this server id (optional).
:param limit: Maximum number of servers to return (optional).
If limit == -1, all servers will be returned,
note that limit == -1 will have a performance
penalty. For details, please see:
https://bugs.launchpad.net/watcher/+bug/1834679
:returns: list of novaclient Server objects
"""
search_opts = {'all_tenants': True}
if filters:
search_opts.update(filters)
return self.nova.servers.list(search_opts=search_opts,
marker=marker,
limit=limit)
def get_instance_by_uuid(self, instance_uuid):
return [instance for instance in
self.nova.servers.list(search_opts={"all_tenants": True,
"uuid": instance_uuid})]
def get_instance_by_name(self, instance_name):
return [instance for instance in
self.nova.servers.list(search_opts={"all_tenants": True,
"name": instance_name})]
def get_instances_by_node(self, host):
return [instance for instance in
self.nova.servers.list(search_opts={"all_tenants": True,
"host": host},
limit=-1)]
def get_flavor_list(self):
return self.nova.flavors.list(**{'is_public': None})
@@ -167,13 +219,6 @@ class NovaHelper(object):
{'instance': instance_id, 'host': host_name})
previous_status = getattr(instance, 'status')
if (dest_hostname and
not self._check_nova_api_version(self.nova, "2.56")):
LOG.error("For migrating a given dest_hostname,"
"Nova API version must be 2.56 or higher")
return False
instance.migrate(host=dest_hostname)
instance = self.nova.servers.get(instance_id)
@@ -313,8 +358,8 @@ class NovaHelper(object):
if host_name != new_hostname and instance.status == 'ACTIVE':
LOG.debug(
"Live migration succeeded : "
"instance %s is now on host '%s'.", (
instance_id, new_hostname))
"instance %(instance)s is now on host '%(host)s'.",
{'instance': instance_id, 'host': new_hostname})
return True
else:
return False
@@ -664,22 +709,6 @@ class NovaHelper(object):
return network_id
def get_instance_by_uuid(self, instance_uuid):
return [instance for instance in
self.nova.servers.list(search_opts={"all_tenants": True,
"uuid": instance_uuid})]
def get_instance_by_name(self, instance_name):
return [instance for instance in
self.nova.servers.list(search_opts={"all_tenants": True,
"name": instance_name})]
def get_instances_by_node(self, host):
return [instance for instance in
self.nova.servers.list(search_opts={"all_tenants": True,
"host": host},
limit=-1)]
def get_hostname(self, instance):
return str(getattr(instance, 'OS-EXT-SRV-ATTR:host'))

View File

@@ -0,0 +1,179 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_config import cfg
from oslo_log import log as logging
from watcher.common import clients
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
class PlacementHelper(object):
def __init__(self, osc=None):
""":param osc: an OpenStackClients instance"""
self.osc = osc if osc else clients.OpenStackClients()
self._placement = self.osc.placement()
def get(self, url):
return self._placement.get(url, raise_exc=False)
@staticmethod
def get_error_msg(resp):
json_resp = resp.json()
# https://docs.openstack.org/api-ref/placement/#errors
if 'errors' in json_resp:
error_msg = json_resp['errors'][0].get('detail')
else:
error_msg = resp.text
return error_msg
def get_resource_providers(self, rp_name=None):
"""Calls the placement API for a resource provider record.
:param rp_name: Name of the resource provider, if None,
list all resource providers.
:return: A list of resource providers information
or None if the resource provider doesn't exist.
"""
url = '/resource_providers'
if rp_name:
url += '?name=%s' % rp_name
resp = self.get(url)
if resp.status_code == 200:
json_resp = resp.json()
return json_resp['resource_providers']
if rp_name:
msg = "Failed to get resource provider %(name)s. "
else:
msg = "Failed to get all resource providers. "
msg += "Got %(status_code)d: %(err_text)s."
args = {
'name': rp_name,
'status_code': resp.status_code,
'err_text': self.get_error_msg(resp),
}
LOG.error(msg, args)
def get_inventories(self, rp_uuid):
"""Calls the placement API to get resource inventory information.
:param rp_uuid: UUID of the resource provider to get.
:return: A dictionary of inventories keyed by resource classes.
"""
url = '/resource_providers/%s/inventories' % rp_uuid
resp = self.get(url)
if resp.status_code == 200:
json = resp.json()
return json['inventories']
msg = ("Failed to get resource provider %(rp_uuid)s inventories. "
"Got %(status_code)d: %(err_text)s.")
args = {
'rp_uuid': rp_uuid,
'status_code': resp.status_code,
'err_text': self.get_error_msg(resp),
}
LOG.error(msg, args)
def get_provider_traits(self, rp_uuid):
"""Queries the placement API for a resource provider's traits.
:param rp_uuid: UUID of the resource provider to grab traits for.
:return: A list of traits.
"""
resp = self.get("/resource_providers/%s/traits" % rp_uuid)
if resp.status_code == 200:
json = resp.json()
return json['traits']
msg = ("Failed to get resource provider %(rp_uuid)s traits. "
"Got %(status_code)d: %(err_text)s.")
args = {
'rp_uuid': rp_uuid,
'status_code': resp.status_code,
'err_text': self.get_error_msg(resp),
}
LOG.error(msg, args)
def get_allocations_for_consumer(self, consumer_uuid):
"""Retrieves the allocations for a specific consumer.
:param consumer_uuid: the UUID of the consumer resource.
:return: A dictionary of allocation records keyed by resource
provider uuid.
"""
url = '/allocations/%s' % consumer_uuid
resp = self.get(url)
if resp.status_code == 200:
json = resp.json()
return json['allocations']
msg = ("Failed to get allocations for consumer %(c_uuid). "
"Got %(status_code)d: %(err_text)s.")
args = {
'c_uuid': consumer_uuid,
'status_code': resp.status_code,
'err_text': self.get_error_msg(resp),
}
LOG.error(msg, args)
def get_usages_for_resource_provider(self, rp_uuid):
"""Retrieves the usages for a specific provider.
:param rp_uuid: The UUID of the provider.
:return: A dictionary that describes how much each class of
resource is being consumed on this resource provider.
"""
url = '/resource_providers/%s/usages' % rp_uuid
resp = self.get(url)
if resp.status_code == 200:
json = resp.json()
return json['usages']
msg = ("Failed to get resource provider %(rp_uuid)s usages. "
"Got %(status_code)d: %(err_text)s.")
args = {
'rp_uuid': rp_uuid,
'status_code': resp.status_code,
'err_text': self.get_error_msg(resp),
}
LOG.error(msg, args)
def get_candidate_providers(self, resources):
"""Returns a dictionary of resource provider summaries.
:param resources: A comma-separated list of strings indicating
an amount of resource of a specified class that
providers in each allocation request must collectively
have the capacity and availability to serve:
resources=VCPU:4,DISK_GB:64,MEMORY_MB:2048
:returns: A dict, keyed by resource provider UUID, which can
provide the required resources.
"""
url = "/allocation_candidates?%s" % resources
resp = self.get(url)
if resp.status_code == 200:
data = resp.json()
return data['provider_summaries']
args = {
'resource_request': resources,
'status_code': resp.status_code,
'err_text': self.get_error_msg(resp),
}
msg = ("Failed to get allocation candidates from placement "
"API for resources: %(resource_request)s\n"
"Got %(status_code)d: %(err_text)s.")
LOG.error(msg, args)

View File

@@ -17,6 +17,7 @@ from watcher.common.policies import action_plan
from watcher.common.policies import audit
from watcher.common.policies import audit_template
from watcher.common.policies import base
from watcher.common.policies import data_model
from watcher.common.policies import goal
from watcher.common.policies import scoring_engine
from watcher.common.policies import service
@@ -30,6 +31,7 @@ def list_rules():
action_plan.list_rules(),
audit.list_rules(),
audit_template.list_rules(),
data_model.list_rules(),
goal.list_rules(),
scoring_engine.list_rules(),
service.list_rules(),

View File

@@ -0,0 +1,37 @@
# Copyright 2019 ZTE Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_policy import policy
from watcher.common.policies import base
DATA_MODEL = 'data_model:%s'
rules = [
policy.DocumentedRuleDefault(
name=DATA_MODEL % 'get_all',
check_str=base.RULE_ADMIN_API,
description='List data model.',
operations=[
{
'path': '/v1/data_model',
'method': 'GET'
}
]
),
]
def list_rules():
return rules

View File

@@ -17,14 +17,41 @@
# limitations under the License.
from apscheduler import events
from apscheduler.executors.pool import BasePoolExecutor
from apscheduler.schedulers import background
import futurist
from oslo_service import service
job_events = events
class GreenThreadPoolExecutor(BasePoolExecutor):
"""Green thread pool
An executor that runs jobs in a green thread pool.
Plugin alias: ``threadpool``
:param max_workers: the maximum number of spawned threads.
"""
def __init__(self, max_workers=10):
pool = futurist.GreenThreadPoolExecutor(int(max_workers))
super(GreenThreadPoolExecutor, self).__init__(pool)
executors = {
'default': GreenThreadPoolExecutor(),
}
class BackgroundSchedulerService(service.ServiceBase,
background.BackgroundScheduler):
def __init__(self, gconfig={}, **options):
if options is None:
options = {'executors': executors}
else:
if 'executors' not in options.keys():
options['executors'] = executors
super(BackgroundSchedulerService, self).__init__(
gconfig, **options)
def start(self):
"""Start service."""

Some files were not shown because too many files have changed in this diff Show More