Compare commits

..

7 Commits

Author SHA1 Message Date
OpenDev Sysadmins
3dc382f9cd 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:45:01 +00:00
Nguyen Hai
4a8cf8445e import zuul job settings from project-config
This is a mechanically generated patch to complete step 1 of moving
the zuul job settings out of project-config and into each project
repository.

Because there will be a separate patch on each branch, the branch
specifiers for branch-specific jobs have been removed.

Because this patch is generated by a script, there may be some
cosmetic changes to the layout of the YAML file(s) as the contents are
normalized.

See the python3-first goal document for details:
https://governance.openstack.org/tc/goals/stein/python3-first.html

Change-Id: I6e15638497fc016dca98189dc15397d61d268433
Story: #2002586
Task: #24344
2018-08-19 00:58:47 +09:00
OpenStack Proposal Bot
e28f0e7ee2 Updated from global requirements
Change-Id: I7236e4ba660824d4ae8b72f0c2f79a49ae36861b
2017-09-15 07:45:58 +00:00
zte-hanrong
b45c813d9a Add the filed of description to shell command for action.
blueprint dynamic-action-description

Change-Id: I927cf966530059d9c7af1e6e60a8d75dd3e6b812
(cherry picked from commit 08fbccc684)
2017-08-24 08:45:20 +00:00
Alexander Chadin
4a47b7886d Fix Audit Update functional test
Change-Id: Iffd70302d0b1d7a919db3e6e44bd3bbebcb1e7ce
(cherry picked from commit d6b68dc819)
2017-08-24 07:49:35 +00:00
f5eae02253 Update UPPER_CONSTRAINTS_FILE for stable/pike
Change-Id: I933e0a2cc99083aefae75648578800af7047c343
2017-07-28 21:08:25 +00:00
b6fe5c9261 Update .gitreview for stable/pike
Change-Id: I0ef7e43614425d4f88a2f3b5c2d90dfe3bb7f6c2
2017-07-28 21:08:24 +00:00
51 changed files with 345 additions and 1925 deletions

View File

@@ -1,4 +1,5 @@
[gerrit]
host=review.openstack.org
host=review.opendev.org
port=29418
project=openstack/python-watcherclient.git
defaultbranch=stable/pike

View File

@@ -1,3 +0,0 @@
[DEFAULT]
test_path=${OS_TEST_PATH:-./watcherclient/tests/functional}
top_dir=./

View File

@@ -1,9 +1,12 @@
- project:
templates:
- openstack-python-jobs
- openstack-python35-jobs
- publish-openstack-sphinx-docs
- check-requirements
- openstackclient-plugin-jobs
check:
jobs:
- watcherclient-tempest-functional:
- openstack-tox-cover:
voting: false
- openstack-tox-lower-constraints
gate:
jobs:
- openstack-tox-lower-constraints

View File

@@ -1,13 +1,13 @@
If you would like to contribute to the development of OpenStack,
you must follow the steps in this page:
https://docs.openstack.org/infra/manual/developers.html
http://docs.openstack.org/infra/manual/developers.html
Once those steps have been completed, changes to OpenStack
should be submitted for review via the Gerrit tool, following
the workflow documented at:
https://docs.openstack.org/infra/manual/developers.html#development-workflow
http://docs.openstack.org/infra/manual/developers.html#development-workflow
Pull requests submitted through GitHub will be ignored.

View File

@@ -1,4 +1,4 @@
python-watcherclient Style Commandments
=======================================
Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/
Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/

View File

@@ -2,8 +2,8 @@
Team and repository tags
========================
.. image:: https://governance.openstack.org/tc/badges/python-watcherclient.svg
:target: https://governance.openstack.org/tc/reference/tags/index.html
.. image:: https://governance.openstack.org/badges/python-watcherclient.svg
:target: https://governance.openstack.org/reference/tags/index.html
.. Change things from this point on
@@ -20,12 +20,12 @@ metrics receiver, complex event processor and profiler, optimization processor
and an action plan applier. This provides a robust framework to realize a wide
range of cloud optimization goals, including the reduction of data center
operating costs, increased system performance via intelligent virtual machine
migration, increased energy efficiency and more!
migration, increased energy efficiency-and more!
* Free software: Apache license
* Wiki: https://wiki.openstack.org/wiki/Watcher
* Source: https://git.openstack.org/cgit/openstack/python-watcher
* Bugs: https://bugs.launchpad.net/watcher
* Wiki: http://wiki.openstack.org/wiki/Watcher
* Source: http://git.openstack.org/cgit/openstack/python-watcher
* Bugs: http://bugs.launchpad.net/watcher
Installation
============
@@ -61,7 +61,7 @@ You can install the Watcher CLI with the following command:
sudo pip install python-watcherclient
You can also use the `OpenStack client <https://docs.openstack.org/python-openstackclient/latest/>`_
You can also use the `OpenStack client <http://docs.openstack.org/cli-reference/overview.html>`_
with Watcher (our watcher plugin for OpenStack client is included in the
python-watcherclient package). To install it, you have just to run this command:

File diff suppressed because it is too large Load Diff

View File

@@ -29,4 +29,3 @@ Once you've configured your authentication parameters, you can run
watcher
openstack_cli
details

View File

@@ -55,7 +55,7 @@ fill partially typed commands. To use this feature, source the below file
https://git.openstack.org/cgit/openstack/python-watcherclient/tree/tools/watcher.bash_completion)
to your terminal and then bash completion should work::
$ . watcher.bash_completion
$ source watcher.bash_completion
To avoid doing this every time, add this to your ``.bashrc`` or copy the
watcher.bash_completion file to the default bash completion scripts directory

View File

@@ -19,8 +19,8 @@ signed OpenStack's contributor's agreement.
.. seealso::
* https://docs.openstack.org/infra/manual/developers.html
* https://wiki.openstack.org/CLA
* http://docs.openstack.org/infra/manual/developers.html
* http://wiki.openstack.org/CLA
LaunchPad Project
-----------------
@@ -41,7 +41,7 @@ Project Hosting Details
-------------------------
Bug tracker
https://launchpad.net/python-watcherclient
http://launchpad.net/python-watcherclient
Mailing list (prefix subjects with ``[watcher]`` for faster responses)
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev

View File

@@ -68,10 +68,11 @@ Once you have an watcher `Client`_, you can perform various tasks::
>>> watcher.action.list() # list of actions
>>> watcher.action_plan.list() # list of action_plan
>>> watcher.audit.get(audit_uuid_or_name) # information about a particular audit
>>> watcher.audit.get(audit_uuid) # information about a particular audit
When the `Client`_ needs to propagate an exception, it will usually
raise an instance listed in `watcherclient.exceptions`_.
raise an instance subclassed from
`watcherclient.exc.BaseException`_ or `watcherclient.exc.ClientException`_.
Refer to the modules themselves, for more details.
@@ -83,4 +84,5 @@ watcherclient Modules
.. _watcherclient.v1.client.Client: api/watcherclient.v1.client.html#watcherclient.v1.client.Client
.. _Client: api/watcherclient.v1.client.html#watcherclient.v1.client.Client
.. _watcherclient.client.get_client(): api/watcherclient.client.html#watcherclient.client.get_client
.. _watcherclient.exceptions: api/watcherclient.exceptions.html
.. _watcherclient.exc.BaseException: api/watcherclient.exc.html#watcherclient.exc.BaseException
.. _watcherclient.exc.ClientException: api/watcherclient.exc.html#watcherclient.exc.ClientException

View File

@@ -1,92 +0,0 @@
alabaster==0.7.10
appdirs==1.4.3
asn1crypto==0.23.0
Babel==2.5.3
certifi==2018.1.18
cffi==1.7.0
chardet==3.0.4
cliff==2.11.0
cmd2==0.8.2
coverage==4.0
cryptography==2.1
debtcollector==1.19.0
decorator==4.2.1
deprecation==2.0
docutils==0.11
dogpile.cache==0.6.5
dulwich==0.15.0
extras==1.0.0
fasteners==0.7.0
fixtures==3.0.0
flake8==2.5.5
future==0.16.0
hacking==0.12.0
idna==2.6
imagesize==0.7.1
iso8601==0.1.12
Jinja2==2.10
jmespath==0.9.3
jsonpatch==1.21
jsonpointer==2.0
jsonschema==2.6.0
keystoneauth1==3.4.0
linecache2==1.0.0
MarkupSafe==1.0
mccabe==0.2.1
mock==2.0.0
monotonic==1.4
mox3==0.20.0
msgpack-python==0.4.0
munch==2.2.0
netaddr==0.7.19
netifaces==0.10.6
openstackdocstheme==1.18.1
openstacksdk==0.12.0
os-client-config==1.29.0
os-service-types==1.2.0
os-testr==1.0.0
osc-lib==1.10.0
oslo.concurrency==3.25.0
oslo.config==5.2.0
oslo.context==2.19.2
oslo.i18n==3.20.0
oslo.log==3.36.0
oslo.serialization==2.18.0
oslo.utils==3.36.0
oslotest==3.2.0
packaging==17.1
paramiko==2.0.0
pbr==3.1.1
pep8==1.5.7
prettytable==0.7.2
pyasn1==0.1.8
pycparser==2.18
pyflakes==0.8.1
Pygments==2.2.0
pyinotify==0.9.6
pyparsing==2.2.0
pyperclip==1.6.0
python-dateutil==2.5.3
python-mimeparse==1.6.0
python-subunit==1.0.0
-e git://git.openstack.org/openstack/python-watcherclient@104894958882a4877dad6f469361d2adb41d0b59#egg=python_watcherclient
pytz==2018.3
PyYAML==3.12
requests==2.18.4
requestsexceptions==1.4.0
rfc3986==0.3.1
simplejson==3.13.2
six==1.11.0
snowballstemmer==1.2.1
Sphinx==1.6.5
sphinxcontrib-websupport==1.0.1
stestr==1.0.0
stevedore==1.28.0
tempest==17.1.0
testrepository==0.0.18
testscenarios==0.4
testtools==2.2.0
traceback2==1.4.0
unittest2==1.1.0
urllib3==1.22
wrapt==1.10.11

View File

@@ -3,12 +3,12 @@
# process, which may cause wedges in the gate later.
Babel!=2.4.0,>=2.3.4 # BSD
cliff!=2.9.0,>=2.8.0 # Apache-2.0
osc-lib>=1.8.0 # Apache-2.0
oslo.i18n>=3.15.3 # Apache-2.0
oslo.utils>=3.33.0 # Apache-2.0
cliff>=2.8.0 # Apache-2.0
osc-lib>=1.7.0 # Apache-2.0
oslo.i18n!=3.15.2,>=2.1.0 # Apache-2.0
oslo.utils>=3.20.0 # Apache-2.0
pbr!=2.1.0,>=2.0.0 # Apache-2.0
PrettyTable<0.8,>=0.7.1 # BSD
keystoneauth1>=3.4.0 # Apache-2.0
six>=1.10.0 # MIT
PyYAML>=3.12 # MIT
keystoneauth1>=3.1.0 # Apache-2.0
six>=1.9.0 # MIT
PyYAML>=3.10.0 # MIT

View File

@@ -5,7 +5,7 @@ description-file =
README.rst
author = OpenStack
author-email = openstack-dev@lists.openstack.org
home-page = https://docs.openstack.org/python-watcherclient/latest/
home-page = http://docs.openstack.org/developer/python-watcherclient
classifier =
Environment :: OpenStack
Intended Audience :: Information Technology
@@ -25,8 +25,6 @@ packages =
[entry_points]
console_scripts =
watcher = watcherclient.shell:main
tempest.test_plugins =
watcherclient_tests = watcherclient.plugin:WatcherClientTempestPlugin
openstack.cli.extension =
infra_optim = watcherclient.osc.plugin
@@ -38,7 +36,6 @@ openstack.infra_optim.v1 =
optimize_strategy_show = watcherclient.v1.strategy_shell:ShowStrategy
optimize_strategy_list = watcherclient.v1.strategy_shell:ListStrategy
optimize_strategy_state = watcherclient.v1.strategy_shell:StateStrategy
optimize_audittemplate_show = watcherclient.v1.audit_template_shell:ShowAuditTemplate
optimize_audittemplate_list = watcherclient.v1.audit_template_shell:ListAuditTemplate
@@ -54,6 +51,7 @@ openstack.infra_optim.v1 =
optimize_actionplan_show = watcherclient.v1.action_plan_shell:ShowActionPlan
optimize_actionplan_list = watcherclient.v1.action_plan_shell:ListActionPlan
optimize_actionplan_create = watcherclient.v1.action_plan_shell:CreateActionPlan
optimize_actionplan_update = watcherclient.v1.action_plan_shell:UpdateActionPlan
optimize_actionplan_start = watcherclient.v1.action_plan_shell:StartActionPlan
optimize_actionplan_cancel = watcherclient.v1.action_plan_shell:CancelActionPlan
@@ -74,7 +72,6 @@ watcherclient.v1 =
strategy_show = watcherclient.v1.strategy_shell:ShowStrategy
strategy_list = watcherclient.v1.strategy_shell:ListStrategy
strategy_state = watcherclient.v1.strategy_shell:StateStrategy
audittemplate_show = watcherclient.v1.audit_template_shell:ShowAuditTemplate
audittemplate_list = watcherclient.v1.audit_template_shell:ListAuditTemplate
@@ -90,6 +87,7 @@ watcherclient.v1 =
actionplan_show = watcherclient.v1.action_plan_shell:ShowActionPlan
actionplan_list = watcherclient.v1.action_plan_shell:ListActionPlan
actionplan_create = watcherclient.v1.action_plan_shell:CreateActionPlan
actionplan_update = watcherclient.v1.action_plan_shell:UpdateActionPlan
actionplan_start = watcherclient.v1.action_plan_shell:StartActionPlan
actionplan_delete = watcherclient.v1.action_plan_shell:DeleteActionPlan

View File

@@ -5,15 +5,15 @@
coverage!=4.4,>=4.0 # Apache-2.0
fixtures>=3.0.0 # Apache-2.0/BSD
hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
mock>=2.0.0 # BSD
openstackdocstheme>=1.18.1 # Apache-2.0
oslotest>=3.2.0 # Apache-2.0
python-subunit>=1.0.0 # Apache-2.0/BSD
sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
mock>=2.0 # BSD
openstackdocstheme>=1.16.0 # Apache-2.0
oslotest>=1.10.0 # Apache-2.0
python-subunit>=0.0.18 # Apache-2.0/BSD
sphinx>=1.6.2 # BSD
testrepository>=0.0.18 # Apache-2.0/BSD
testscenarios>=0.4 # Apache-2.0/BSD
testtools>=2.2.0 # MIT
tempest>=17.1.0 # Apache-2.0
testtools>=1.4.0 # MIT
tempest>=16.1.0 # Apache-2.0
# Needed for pypi packaging
wheel>=0.24.0 # MIT
wheel # MIT

16
tox.ini
View File

@@ -6,7 +6,7 @@ skipsdist = True
[testenv]
usedevelop = True
install_command =
constraints: pip install -U --force-reinstall -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
constraints: pip install -U --force-reinstall -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/pike} {opts} {packages}
pip install -U {opts} {packages}
setenv =
VIRTUAL_ENV={envdir}
@@ -16,25 +16,20 @@ commands = rm -f .testrepository/times.dbm
python setup.py testr --slowest --testr-args='{posargs}'
[testenv:pep8]
basepython = python3
commands = flake8
[testenv:venv]
basepython = python3
commands = {posargs}
[testenv:cover]
basepython = python3
commands =
python setup.py testr --coverage --testr-args='{posargs}'
coverage report
[testenv:docs]
basepython = python3
commands = python setup.py build_sphinx
[testenv:debug]
basepython = python3
commands = oslo_debug_helper -t watcherclient/tests/unit {posargs}
[testenv:functional]
@@ -61,16 +56,7 @@ builtins = _
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
[testenv:wheel]
basepython = python3
commands = python setup.py bdist_wheel
[hacking]
import_exceptions = watcherclient._i18n
[testenv:lower-constraints]
basepython = python3
install_command = pip install -U {opts} {packages}
deps =
-c{toxinidir}/lower-constraints.txt
-r{toxinidir}/test-requirements.txt
-r{toxinidir}/requirements.txt

View File

@@ -134,11 +134,6 @@ class Manager(object):
def _delete(self, url):
self.api.raw_request('DELETE', url)
def _start(self, url, body=None, method='POST'):
resp, body = self.api.json_request(method, url, body={})
if body:
return self.resource_class(self, body)
class Resource(base.Resource):
"""Represents a particular instance of an object (tenant, user, etc).

View File

@@ -165,7 +165,8 @@ class VersionNegotiationMixin(object):
raise NotImplementedError()
_RETRY_EXCEPTIONS = (exceptions.ServiceUnavailable,
_RETRY_EXCEPTIONS = (exceptions.Conflict,
exceptions.ServiceUnavailable,
exceptions.ConnectionRefused,
kexceptions.RetriableConnectionFailure)

View File

@@ -161,21 +161,17 @@ def common_params_for_list(args, fields, field_labels):
args.sort_dir)
params['sort_dir'] = args.sort_dir
marker = getattr(args, 'marker', None)
if marker is not None:
params['marker'] = marker
params['detail'] = args.detail
return params
def common_filters(limit=None, sort_key=None, sort_dir=None, marker=None):
def common_filters(limit=None, sort_key=None, sort_dir=None):
"""Generate common filters for any list request.
:param limit: maximum number of entities to return.
:param sort_key: field to use for sorting.
:param sort_dir: direction of sorting: 'asc' or 'desc'.
:param marker: The last actionplan UUID of the previous page.
:returns: list of string filters.
"""
filters = []
@@ -185,8 +181,6 @@ def common_filters(limit=None, sort_key=None, sort_dir=None, marker=None):
filters.append('sort_key=%s' % sort_key)
if sort_dir is not None:
filters.append('sort_dir=%s' % sort_dir)
if marker is not None:
filters.append('marker=%s' % marker)
return filters

View File

@@ -1,23 +0,0 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2018 Servionica
#
# 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
service_option = cfg.BoolOpt("watcher_client",
default=True,
help="Whether or not watcher_client is expected"
"to be available")

View File

@@ -1,34 +0,0 @@
# 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.
import os
from tempest.test_discover import plugins
from watcherclient import config as watcher_config
class WatcherClientTempestPlugin(plugins.TempestPlugin):
def load_tests(self):
base_path = os.path.split(os.path.dirname(
os.path.abspath(__file__)))[0]
test_dir = "watcherclient/tests/functional/v1"
full_test_dir = os.path.join(base_path, test_dir)
return full_test_dir, base_path
def register_opts(self, conf):
conf.register_opt(watcher_config.service_option,
group='service_available')
def get_opt_lists(self):
return [('service_available', [watcher_config.service_option])]

View File

@@ -26,7 +26,7 @@ You need to install virtualenv, create a virtual environment and activate it::
$ pip install virtualenv
$ virtualenv watcher-env
$ . watcher-env/bin/activate
$ source watcher-env/bin/activate
Then, to install Tempest you can issue the following commands::

View File

@@ -0,0 +1,53 @@
#!/bin/bash -xe
# 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.
# This script is executed inside post_test_hook function in devstack gate.
# Default gate uses /opt/stack/new... but some of us may install differently
STACK_DIR=$BASE/new/devstack
function generate_testr_results {
if [ -f .testrepository/0 ]; then
sudo .tox/functional/bin/testr last --subunit > $WORKSPACE/testrepository.subunit
sudo mv $WORKSPACE/testrepository.subunit $BASE/logs/testrepository.subunit
sudo /usr/os-testr-env/bin/subunit2html $BASE/logs/testrepository.subunit $BASE/logs/testr_results.html
sudo gzip -9 $BASE/logs/testrepository.subunit
sudo gzip -9 $BASE/logs/testr_results.html
sudo chown jenkins:jenkins $BASE/logs/testrepository.subunit.gz $BASE/logs/testr_results.html.gz
sudo chmod a+r $BASE/logs/testrepository.subunit.gz $BASE/logs/testr_results.html.gz
fi
}
export WATCHERCLIENT_DIR="$BASE/new/python-watcherclient"
sudo chown -R jenkins:stack $WATCHERCLIENT_DIR
# Get admin credentials
cd $STACK_DIR
source openrc admin admin
# Go to the watcherclient dir
cd $WATCHERCLIENT_DIR
# Run tests
echo "Running watcherclient functional test suite"
set +e
# Preserve env for OS_ credentials
sudo -E -H -u jenkins tox -efunctional
EXIT_CODE=$?
set -e
# Collect and parse result
generate_testr_results
exit $EXIT_CODE

View File

@@ -10,45 +10,19 @@
# License for the specific language governing permissions and limitations
# under the License.
import os
import re
import shlex
import subprocess
import testtools
import six
from tempest import clients
from tempest.common import credentials_factory as creds_factory
from tempest.lib.cli import output_parser
from tempest.lib import exceptions
def credentials():
# You can get credentials either from tempest.conf file or
# from OS environment.
tempest_creds = clients.get_auth_provider(
creds_factory.get_configured_admin_credentials())
creds = tempest_creds.credentials
creds_dict = {
'--os-username': os.environ.get('OS_USERNAME', creds.username),
'--os-password': os.environ.get('OS_PASSWORD', creds.password),
'--os-project-name': os.environ.get('OS_PROJECT_NAME',
creds.project_name),
'--os-auth-url': os.environ.get('OS_AUTH_URL',
tempest_creds.auth_url),
'--os-project-domain-name': os.environ.get('OS_PROJECT_DOMAIN_ID',
creds.project_domain_name),
'--os-user-domain-name': os.environ.get('OS_USER_DOMAIN_ID',
creds.user_domain_name),
}
return [x for sub in creds_dict.items() for x in sub]
def execute(cmd, fail_ok=False, merge_stderr=False):
"""Executes specified command for the given action."""
cmdlist = shlex.split(cmd)
cmdlist.extend(credentials())
stdout = subprocess.PIPE
stderr = subprocess.STDOUT if merge_stderr else subprocess.PIPE
proc = subprocess.Popen(cmdlist, stdout=stdout, stderr=stderr)
@@ -132,13 +106,3 @@ class TestCase(testtools.TestCase):
def parse_listing(self, raw_output):
"""Return list of dicts with basic item parsed from cli output."""
return output_parser.listing(raw_output)
def has_actionplan_succeeded(self, ap_uuid):
return self.parse_show_as_object(
self.watcher('actionplan show %s' % ap_uuid)
)['State'] == 'SUCCEEDED'
@classmethod
def has_audit_created(cls, audit_uuid):
return cls.parse_show_as_object(
cls.watcher('audit show %s' % audit_uuid))['State'] == 'SUCCEEDED'

View File

@@ -15,10 +15,6 @@
from oslo_utils import uuidutils
import functools
from tempest.lib.common.utils import test_utils
from watcherclient.tests.functional.v1 import base
@@ -37,22 +33,17 @@ class ActionTests(base.TestCase):
template_raw_output = cls.watcher(
'audittemplate create %s dummy -s dummy' % cls.audit_template_name)
template_output = cls.parse_show_as_object(template_raw_output)
audit_output = cls.parse_show_as_object(cls.watcher(
'audit create -a %s' % template_output['Name']))
audit_raw_output = cls.watcher(
'audit create -a %s' % template_output['Name'])
audit_output = cls.parse_show_as_object(audit_raw_output)
cls.audit_uuid = audit_output['UUID']
audit_created = test_utils.call_until_true(
func=functools.partial(cls.has_audit_created, cls.audit_uuid),
duration=600,
sleep_for=2)
if not audit_created:
raise Exception('Audit has not been succeeded')
@classmethod
def tearDownClass(cls):
# Delete Action Plan and all related actions.
output = cls.parse_show(
cls.watcher('actionplan list --audit %s' % cls.audit_uuid))
action_plan_uuid = list(output[0])[0]
action_plan_uuid = output[0].keys()[0]
raw_output = cls.watcher('actionplan delete %s' % action_plan_uuid)
cls.assertOutput('', raw_output)
# Delete audit
@@ -72,10 +63,9 @@ class ActionTests(base.TestCase):
self.assert_table_structure([raw_output], self.detailed_list_fields)
def test_action_show(self):
action_list = self.parse_show(self.watcher('action list --audit %s'
% self.audit_uuid))
action_uuid = list(action_list[0])[0]
action = self.watcher('action show %s' % action_uuid)
action_list = self.parse_show(self.watcher('action list'))
action_uuid = action_list[0].keys()[0]
action = self.watcher('action show ' + action_uuid)
self.assertIn(action_uuid, action)
self.assert_table_structure([action],
self.detailed_list_fields)

View File

@@ -15,10 +15,6 @@
from oslo_utils import uuidutils
import functools
from tempest.lib.common.utils import test_utils
from watcherclient.tests.functional.v1 import base
@@ -28,8 +24,7 @@ class ActionPlanTests(base.TestCase):
dummy_name = 'dummy'
list_fields = ['UUID', 'Audit', 'State', 'Updated At', 'Global efficacy']
detailed_list_fields = list_fields + ['Created At', 'Deleted At',
'Strategy', 'Efficacy indicators',
'Hostname']
'Strategy', 'Efficacy indicators']
audit_template_name = 'a' + uuidutils.generate_uuid()
audit_uuid = None
@@ -42,19 +37,13 @@ class ActionPlanTests(base.TestCase):
% template_output['Name'])
audit_output = cls.parse_show_as_object(audit_raw_output)
cls.audit_uuid = audit_output['UUID']
audit_created = test_utils.call_until_true(
func=functools.partial(cls.has_audit_created, cls.audit_uuid),
duration=600,
sleep_for=2)
if not audit_created:
raise Exception('Audit has not been succeeded')
@classmethod
def tearDownClass(cls):
# Delete action plan
output = cls.parse_show(
cls.watcher('actionplan list --audit %s' % cls.audit_uuid))
action_plan_uuid = list(output[0])[0]
action_plan_uuid = output[0].keys()[0]
raw_output = cls.watcher('actionplan delete %s' % action_plan_uuid)
cls.assertOutput('', raw_output)
# Delete audit
@@ -75,7 +64,7 @@ class ActionPlanTests(base.TestCase):
def test_action_plan_show(self):
action_plan_list = self.parse_show(self.watcher('actionplan list'))
action_plan_uuid = list(action_plan_list[0])[0]
action_plan_uuid = action_plan_list[0].keys()[0]
actionplan = self.watcher('actionplan show %s' % action_plan_uuid)
self.assertIn(action_plan_uuid, actionplan)
self.assert_table_structure([actionplan],
@@ -84,14 +73,50 @@ class ActionPlanTests(base.TestCase):
def test_action_plan_start(self):
output = self.parse_show(self.watcher('actionplan list --audit %s'
% self.audit_uuid))
action_plan_uuid = list(output[0])[0]
action_plan_uuid = output[0].keys()[0]
self.watcher('actionplan start %s' % action_plan_uuid)
raw_output = self.watcher('actionplan show %s' % action_plan_uuid)
self.assert_table_structure([raw_output], self.detailed_list_fields)
self.assertTrue(test_utils.call_until_true(
func=functools.partial(
self.has_actionplan_succeeded, action_plan_uuid),
duration=600,
sleep_for=2
))
class ActionPlanActiveTests(base.TestCase):
audit_uuid = None
audit_template_name = 'b' + uuidutils.generate_uuid()
list_fields = ['UUID', 'Audit', 'State', 'Updated At', 'Global efficacy']
detailed_list_fields = list_fields + ['Created At', 'Deleted At',
'Strategy', 'Efficacy indicators']
def _delete_action_plan(self):
output = self.parse_show(
self.watcher('actionplan list --audit %s' % self.audit_uuid))
action_plan_uuid = output[0].keys()[0]
raw_output = self.watcher('actionplan delete %s' % action_plan_uuid)
self.assertOutput('', raw_output)
def _delete_audit(self):
raw_output = self.watcher('audit delete %s' % self.audit_uuid)
self.assertOutput('', raw_output)
def _delete_audit_template(self):
raw_output = self.watcher(
'audittemplate delete %s' % self.audit_template_name)
self.assertOutput('', raw_output)
def _create_audit_template(self):
template_raw_output = self.watcher(
'audittemplate create %s dummy -s dummy'
% self.audit_template_name)
template_output = self.parse_show_as_object(template_raw_output)
return template_output
def test_action_plan_create(self):
template_output = self._create_audit_template()
action_plan = self.watcher(
'actionplan create -a %s' % template_output['Name'])
self.audit_uuid = self.parse_show_as_object(action_plan)['UUID']
self.assert_table_structure([action_plan], self.detailed_list_fields)
self._delete_action_plan()
self._delete_audit()
self._delete_audit_template()

View File

@@ -15,10 +15,6 @@
from oslo_utils import uuidutils
import functools
from tempest.lib.common.utils import test_utils
from watcherclient.tests.functional.v1 import base
@@ -26,11 +22,11 @@ class AuditTests(base.TestCase):
"""Functional tests for audit."""
dummy_name = 'dummy'
list_fields = ['UUID', 'Name', 'Audit Type', 'State', 'Goal', 'Strategy']
list_fields = ['UUID', 'Audit Type', 'State', 'Goal', 'Strategy']
detailed_list_fields = list_fields + ['Created At', 'Updated At',
'Deleted At', 'Parameters',
'Interval', 'Audit Scope',
'Next Run Time', 'Hostname']
'Next Run Time']
audit_template_name = 'a' + uuidutils.generate_uuid()
audit_uuid = None
@@ -43,18 +39,12 @@ class AuditTests(base.TestCase):
'audit create -a %s' % template_output['Name'])
audit_output = cls.parse_show_as_object(audit_raw_output)
cls.audit_uuid = audit_output['UUID']
audit_created = test_utils.call_until_true(
func=functools.partial(cls.has_audit_created, cls.audit_uuid),
duration=600,
sleep_for=2)
if not audit_created:
raise Exception('Audit has not been succeeded')
@classmethod
def tearDownClass(cls):
output = cls.parse_show(
cls.watcher('actionplan list --audit %s' % cls.audit_uuid))
action_plan_uuid = list(output[0])[0]
action_plan_uuid = output[0].keys()[0]
cls.watcher('actionplan delete %s' % action_plan_uuid)
cls.watcher('audit delete %s' % cls.audit_uuid)
cls.watcher('audittemplate delete %s' % cls.audit_template_name)
@@ -81,56 +71,44 @@ class AuditTests(base.TestCase):
class AuditActiveTests(base.TestCase):
list_fields = ['UUID', 'Name', 'Audit Type', 'State', 'Goal', 'Strategy']
list_fields = ['UUID', 'Audit Type', 'State', 'Goal', 'Strategy']
detailed_list_fields = list_fields + ['Created At', 'Updated At',
'Deleted At', 'Parameters',
'Interval', 'Audit Scope']
audit_template_name = 'a' + uuidutils.generate_uuid()
@classmethod
def setUpClass(cls):
cls.watcher('audittemplate create %s dummy -s dummy'
% cls.audit_template_name)
@classmethod
def tearDownClass(cls):
cls.watcher('audittemplate delete %s' % cls.audit_template_name)
audit_uuid = None
def _create_audit(self):
return self.parse_show_as_object(
raw_output = self.watcher('audittemplate create %s dummy -s dummy'
% self.audit_template_name)
template_output = self.parse_show_as_object(raw_output)
self.audit_uuid = self.parse_show_as_object(
self.watcher('audit create -a %s'
% self.audit_template_name))['UUID']
% template_output['Name']))['UUID']
def _delete_audit(self, audit_uuid):
self.assertTrue(test_utils.call_until_true(
func=functools.partial(
self.has_audit_created, audit_uuid),
duration=600,
sleep_for=2
))
def _delete_audit(self):
output = self.parse_show(
self.watcher('actionplan list --audit %s' % audit_uuid))
action_plan_uuid = list(output[0])[0]
self.watcher('actionplan list --audit %s' % self.audit_uuid))
action_plan_uuid = output[0].keys()[0]
self.watcher('actionplan delete %s' % action_plan_uuid)
self.watcher('audit delete %s' % audit_uuid)
self.watcher('audit delete %s' % self.audit_uuid)
self.watcher('audittemplate delete %s' % self.audit_template_name)
def test_create_audit(self):
audit = self.watcher('audit create -a %s' % self.audit_template_name)
audit_uuid = self.parse_show_as_object(audit)['UUID']
raw_output = self.watcher('audittemplate create %s dummy -s dummy'
% self.audit_template_name)
template_output = self.parse_show_as_object(raw_output)
audit = self.watcher('audit create -a %s' % template_output['Name'])
self.audit_uuid = self.parse_show_as_object(audit)['UUID']
self.assert_table_structure([audit], self.detailed_list_fields)
self._delete_audit(audit_uuid)
self._delete_audit()
def test_delete_audit(self):
audit_uuid = self._create_audit()
self.assertTrue(test_utils.call_until_true(
func=functools.partial(
self.has_audit_created, audit_uuid),
duration=600,
sleep_for=2
))
raw_output = self.watcher('audit delete %s' % audit_uuid)
self._create_audit()
raw_output = self.watcher('audit delete %s' % self.audit_uuid)
self.assertOutput('', raw_output)
output = self.parse_show(
self.watcher('actionplan list --audit %s' % audit_uuid))
action_plan_uuid = list(output[0])[0]
self.watcher('actionplan list --audit %s' % self.audit_uuid))
action_plan_uuid = output[0].keys()[0]
self.watcher('actionplan delete %s' % action_plan_uuid)
self.watcher('audittemplate delete %s' % self.audit_template_name)

View File

@@ -37,8 +37,6 @@ class ServiceTests(base.TestCase):
self.list_fields + ['Last seen up'])
def test_service_show(self):
# TODO(alexchadin): this method should be refactored since Watcher will
# get HA support soon.
raw_output = self.watcher('service show %s'
% self.decision_engine_name)
self.assertIn(self.decision_engine_name, raw_output)

View File

@@ -20,9 +20,7 @@ class StrategyTests(base.TestCase):
"""Functional tests for strategy."""
dummy_name = 'dummy'
basic_strategy = 'basic'
list_fields = ['UUID', 'Name', 'Display name', 'Goal']
state_fields = ['Datasource', 'Metrics', 'CDM', 'Name']
def test_strategy_list(self):
raw_output = self.watcher('strategy list')
@@ -41,8 +39,3 @@ class StrategyTests(base.TestCase):
self.assert_table_structure([raw_output],
self.list_fields + ['Parameters spec'])
self.assertNotIn('basic', raw_output)
def test_strategy_state(self):
raw_output = self.watcher('strategy state %s' % self.basic_strategy)
self.assertIn(self.basic_strategy, raw_output)
self.assert_table_structure([raw_output], self.state_fields)

View File

@@ -97,8 +97,7 @@ class UtilsTest(test_utils.BaseTestCase):
class CommonParamsForListTest(test_utils.BaseTestCase):
def setUp(self):
super(CommonParamsForListTest, self).setUp()
self.args = mock.Mock(limit=None, marker=None,
sort_key=None, sort_dir=None)
self.args = mock.Mock(limit=None, sort_key=None, sort_dir=None)
self.args.detail = False
self.expected_params = {'detail': False}
@@ -118,13 +117,6 @@ class CommonParamsForListTest(test_utils.BaseTestCase):
utils.common_params_for_list,
self.args, [], [])
def test_marker(self):
self.args.marker = 'e420a881-d7df-4de2-bbf3-378cc13d9b3a'
self.expected_params.update(
{'marker': 'e420a881-d7df-4de2-bbf3-378cc13d9b3a'})
self.assertEqual(self.expected_params,
utils.common_params_for_list(self.args, [], []))
def test_sort_key_and_sort_dir(self):
self.args.sort_key = 'field'
self.args.sort_dir = 'desc'

View File

@@ -144,16 +144,6 @@ fake_responses_sorting = {
},
}
fake_responses_marker = {
'/v1/actions/?marker=770ef053-ecb3-48b0-85b5-d55a2dbc6588':
{
'GET': (
{},
{"actions": [ACTION2, ACTION3]}
),
},
}
class ActionManagerTest(testtools.TestCase):
@@ -241,20 +231,6 @@ class ActionManagerTest(testtools.TestCase):
self.assertEqual(expect, self.api.calls)
self.assertEqual(3, len(actions))
def test_actions_list_marker(self):
self.api = utils.FakeAPI(fake_responses_marker)
self.mgr = watcherclient.v1.action.ActionManager(self.api)
actions = self.mgr.list(
marker='770ef053-ecb3-48b0-85b5-d55a2dbc6588')
expect = [
('GET',
'/v1/actions/?marker=770ef053-ecb3-48b0-85b5-d55a2dbc6588',
{},
None)
]
self.assertEqual(expect, self.api.calls)
self.assertEqual(2, len(actions))
def test_actions_show(self):
action = self.mgr.get(ACTION1['uuid'])
expect = [

View File

@@ -38,8 +38,6 @@ ACTION_PLAN2 = {
UPDATED_ACTION_PLAN = copy.deepcopy(ACTION_PLAN1)
NEW_STATE = 'PENDING'
UPDATED_ACTION_PLAN['state'] = NEW_STATE
START_ACTION_PLAN = copy.deepcopy(ACTION_PLAN1)
START_ACTION_PLAN['state'] = NEW_STATE
fake_responses = {
'/v1/action_plans':
@@ -71,13 +69,6 @@ fake_responses = {
UPDATED_ACTION_PLAN,
),
},
'/v1/action_plans/%s/start' % ACTION_PLAN1['uuid']:
{
'POST': (
{},
START_ACTION_PLAN,
),
},
'/v1/action_plans/detail?uuid=%s' % ACTION_PLAN1['uuid']:
{
'GET': (
@@ -103,13 +94,6 @@ fake_responses_pagination = {
{"action_plans": [ACTION_PLAN2]}
),
},
'/v1/action_plans/?marker=f8e47706-efcf-49a4-a5c4-af604eb492f2':
{
'GET': (
{},
{"action_plans": [ACTION_PLAN2]}
),
},
}
fake_responses_sorting = {
@@ -174,19 +158,6 @@ class ActionPlanManagerTest(testtools.TestCase):
self.assertEqual(expect, self.api.calls)
self.assertThat(action_plans, matchers.HasLength(2))
def test_action_plans_list_marker(self):
self.api = utils.FakeAPI(fake_responses_pagination)
self.mgr = watcherclient.v1.action_plan.ActionPlanManager(self.api)
action_plans = self.mgr.list(
marker='f8e47706-efcf-49a4-a5c4-af604eb492f2')
expect = [
('GET', '/v1/action_plans/?'
'marker=f8e47706-efcf-49a4-a5c4-af604eb492f2',
{}, None),
]
self.assertEqual(expect, self.api.calls)
self.assertThat(action_plans, matchers.HasLength(1))
def test_action_plans_list_sort_key(self):
self.api = utils.FakeAPI(fake_responses_sorting)
self.mgr = watcherclient.v1.action_plan.ActionPlanManager(self.api)
@@ -229,10 +200,3 @@ class ActionPlanManagerTest(testtools.TestCase):
]
self.assertEqual(expect, self.api.calls)
self.assertEqual(NEW_STATE, action_plan.state)
def test_action_plan_start(self):
action_plan = self.mgr.start(ACTION_PLAN1['uuid'])
expect = [('POST', '/v1/action_plans/%s/start'
% ACTION_PLAN1['uuid'], {}, {})]
self.assertEqual(expect, self.api.calls)
self.assertEqual(NEW_STATE, action_plan.state)

View File

@@ -33,18 +33,13 @@ ACTION_PLAN_1 = {
'unit': '%'}],
'created_at': datetime.datetime.now().isoformat(),
'updated_at': None,
'global_efficacy': [
{"value": 99,
"unit": "%",
"name": "dummy_global_efficacy",
"description": "Dummy Global Efficacy"},
{"value": 75,
"unit": "%",
"name": "dummy_global_efficacy2",
"description": "Dummy Global Efficacy2"}
],
'global_efficacy': {
"value": 99,
"unit": "%",
"name": "dummy_global_efficacy",
"description": "Dummy Global Efficacy",
},
'deleted_at': None,
'hostname': ''
}
ACTION_PLAN_2 = {
@@ -57,14 +52,13 @@ ACTION_PLAN_2 = {
'name': 'indicator2',
'unit': '%'}],
'updated_at': None,
'global_efficacy': [{
'global_efficacy': {
"value": 87,
"unit": "%",
"name": "dummy_global_efficacy",
"description": "Dummy Global Efficacy",
}],
},
'deleted_at': None,
'hostname': ''
}
@@ -75,7 +69,6 @@ class ActionPlanShellTest(base.CommandTestCase):
resource_fields.ACTION_PLAN_SHORT_LIST_FIELD_LABELS)
FIELDS = resource_fields.ACTION_PLAN_FIELDS
FIELD_LABELS = resource_fields.ACTION_PLAN_FIELD_LABELS
GLOBAL_EFFICACY_FIELDS = resource_fields.GLOBAL_EFFICACY_FIELDS
def setUp(self):
super(self.__class__, self).setUp()
@@ -121,11 +114,6 @@ class ActionPlanShellTest(base.CommandTestCase):
self.SHORT_LIST_FIELD_LABELS)],
results)
self.assertEqual(action_plan1.global_efficacy,
results[0]['Global efficacy'])
self.assertEqual(action_plan2.global_efficacy,
results[1]['Global efficacy'])
self.m_action_plan_mgr.list.assert_called_once_with(detail=False)
def test_do_action_plan_list_detail(self):
@@ -143,10 +131,6 @@ class ActionPlanShellTest(base.CommandTestCase):
self.resource_as_dict(action_plan2, self.FIELDS,
self.FIELD_LABELS)],
results)
self.assertEqual(action_plan1.global_efficacy,
results[0]['Global efficacy'])
self.assertEqual(action_plan2.global_efficacy,
results[1]['Global efficacy'])
self.m_action_plan_mgr.list.assert_called_once_with(detail=True)
@@ -181,8 +165,6 @@ class ActionPlanShellTest(base.CommandTestCase):
self.resource_as_dict(
action_plan, self.FIELDS, self.FIELD_LABELS),
result)
self.assertEqual(action_plan.global_efficacy,
result['Global efficacy'])
self.m_action_plan_mgr.get.assert_called_once_with(
'd9d9978e-6db5-4a05-8eab-1531795d7004')

21
watcherclient/tests/unit/v1/test_action_shell.py Normal file → Executable file
View File

@@ -132,27 +132,6 @@ class ActionShellTest(base.CommandTestCase):
self.m_action_mgr.list.assert_called_once_with(detail=True)
def test_do_action_list_marker(self):
action2 = resource.Action(mock.Mock(), ACTION_2)
action3 = resource.Action(mock.Mock(), ACTION_3)
self.m_action_mgr.list.return_value = [
action2, action3]
exit_code, results = self.run_cmd(
'action list --marker 770ef053-ecb3-48b0-85b5-d55a2dbc6588')
self.assertEqual(0, exit_code)
self.assertEqual(
[self.resource_as_dict(action2, self.SHORT_LIST_FIELDS,
self.SHORT_LIST_FIELD_LABELS),
self.resource_as_dict(action3, self.SHORT_LIST_FIELDS,
self.SHORT_LIST_FIELD_LABELS)],
results)
self.m_action_mgr.list.assert_called_once_with(
detail=False,
marker='770ef053-ecb3-48b0-85b5-d55a2dbc6588')
def test_do_action_show_by_uuid(self):
action = resource.Action(mock.Mock(), ACTION_1)
self.m_action_mgr.get.return_value = action

View File

@@ -145,16 +145,6 @@ fake_responses_strategy = {
},
}
fake_responses_marker = {
'/v1/audits/?marker=5869da81-4876-4687-a1ed-12cd64cf53d9':
{
'GET': (
{},
{"audits": [AUDIT2]}
),
},
}
class AuditManagerTest(testtools.TestCase):
def setUp(self):
@@ -239,17 +229,6 @@ class AuditManagerTest(testtools.TestCase):
self.assertEqual(expect, self.api.calls)
self.assertEqual(1, len(audits))
def test_audits_list_marker(self):
self.api = utils.FakeAPI(fake_responses_marker)
self.mgr = watcherclient.v1.audit.AuditManager(self.api)
audits = self.mgr.list(marker=AUDIT1['uuid'])
expect = [
('GET', '/v1/audits/?marker=5869da81-4876-4687-a1ed-12cd64cf53d9',
{}, None),
]
self.assertEqual(expect, self.api.calls)
self.assertEqual(1, len(audits))
def test_audits_show(self):
audit = self.mgr.get(AUDIT1['uuid'])
expect = [

114
watcherclient/tests/unit/v1/test_audit_shell.py Executable file → Normal file
View File

@@ -17,6 +17,7 @@ import datetime
import mock
import six
from watcherclient import exceptions
from watcherclient import shell
from watcherclient.tests.unit.v1 import base
from watcherclient import v1 as resource
@@ -68,8 +69,6 @@ AUDIT_1 = {
'scope': '',
'auto_trigger': False,
'next_run_time': None,
'name': 'my_audit1',
'hostname': '',
}
AUDIT_2 = {
@@ -88,8 +87,6 @@ AUDIT_2 = {
'scope': '',
'auto_trigger': False,
'next_run_time': None,
'name': 'my_audit2',
'hostname': '',
}
AUDIT_3 = {
@@ -108,8 +105,6 @@ AUDIT_3 = {
'scope': '',
'auto_trigger': True,
'next_run_time': None,
'name': 'my_audit3',
'hostname': '',
}
@@ -175,23 +170,6 @@ class AuditShellTest(base.CommandTestCase):
self.m_audit_mgr.list.assert_called_once_with(detail=False)
def test_do_audit_list_marker(self):
audit2 = resource.Audit(mock.Mock(), AUDIT_2)
self.m_audit_mgr.list.return_value = [audit2]
exit_code, results = self.run_cmd(
'audit list --marker 5869da81-4876-4687-a1ed-12cd64cf53d9')
self.assertEqual(0, exit_code)
self.assertEqual(
[self.resource_as_dict(audit2, self.SHORT_LIST_FIELDS,
self.SHORT_LIST_FIELD_LABELS)],
results)
self.m_audit_mgr.list.assert_called_once_with(
detail=False,
marker='5869da81-4876-4687-a1ed-12cd64cf53d9')
def test_do_audit_list_detail(self):
audit1 = resource.Audit(mock.Mock(), AUDIT_1)
audit2 = resource.Audit(mock.Mock(), AUDIT_2)
@@ -224,19 +202,14 @@ class AuditShellTest(base.CommandTestCase):
self.m_audit_mgr.get.assert_called_once_with(
'5869da81-4876-4687-a1ed-12cd64cf53d9')
def test_do_audit_show_by_name(self):
audit = resource.Audit(mock.Mock(), AUDIT_1)
self.m_audit_mgr.get.return_value = audit
def test_do_audit_show_by_not_uuid(self):
self.m_audit_mgr.get.side_effect = exceptions.HTTPNotFound
exit_code, result = self.run_cmd(
'audit show my_audit')
'audit show not_uuid', formatting=None)
self.assertEqual(0, exit_code)
self.assertEqual(
self.resource_as_dict(audit, self.FIELDS, self.FIELD_LABELS),
result)
self.m_audit_mgr.get.assert_called_once_with(
'my_audit')
self.assertEqual(1, exit_code)
self.assertEqual('', result)
def test_do_audit_delete(self):
self.m_audit_mgr.delete.return_value = ''
@@ -250,18 +223,6 @@ class AuditShellTest(base.CommandTestCase):
self.m_audit_mgr.delete.assert_called_once_with(
'5869da81-4876-4687-a1ed-12cd64cf53d9')
def test_do_audit_delete_by_name(self):
self.m_audit_mgr.delete.return_value = ''
exit_code, result = self.run_cmd(
'audit delete my_audit',
formatting=None)
self.assertEqual(0, exit_code)
self.assertEqual('', result)
self.m_audit_mgr.delete.assert_called_once_with(
'my_audit')
def test_do_audit_delete_multiple(self):
self.m_audit_mgr.delete.return_value = ''
@@ -277,6 +238,16 @@ class AuditShellTest(base.CommandTestCase):
self.m_audit_mgr.delete.assert_any_call(
'5b157edd-5a7e-4aaa-b511-f7b33ec86e9f')
def test_do_audit_delete_with_not_uuid(self):
self.m_audit_mgr.delete.return_value = ''
exit_code, result = self.run_cmd(
'audit delete not_uuid',
formatting=None)
self.assertEqual(1, exit_code)
self.assertEqual('', result)
def test_do_audit_update(self):
audit = resource.Audit(mock.Mock(), AUDIT_1)
self.m_audit_mgr.update.return_value = audit
@@ -293,20 +264,14 @@ class AuditShellTest(base.CommandTestCase):
'5869da81-4876-4687-a1ed-12cd64cf53d9',
[{'op': 'replace', 'path': '/state', 'value': 'PENDING'}])
def test_do_audit_update_by_name(self):
audit = resource.Audit(mock.Mock(), AUDIT_1)
self.m_audit_mgr.update.return_value = audit
def test_do_audit_update_with_not_uuid(self):
self.m_audit_mgr.update.return_value = ''
exit_code, result = self.run_cmd(
'audit update my_audit replace state=PENDING')
'audit update not_uuid replace state=PENDING', formatting=None)
self.assertEqual(0, exit_code)
self.assertEqual(
self.resource_as_dict(audit, self.FIELDS, self.FIELD_LABELS),
result)
self.m_audit_mgr.update.assert_called_once_with(
'my_audit',
[{'op': 'replace', 'path': '/state', 'value': 'PENDING'}])
self.assertEqual(1, exit_code)
self.assertEqual('', result)
def test_do_audit_create_with_audit_template_uuid(self):
audit = resource.Audit(mock.Mock(), AUDIT_3)
@@ -323,9 +288,7 @@ class AuditShellTest(base.CommandTestCase):
result)
self.m_audit_mgr.create.assert_called_once_with(
audit_template_uuid='f8e47706-efcf-49a4-a5c4-af604eb492f2',
audit_type='ONESHOT',
auto_trigger=False
)
audit_type='ONESHOT', auto_trigger=False)
def test_do_audit_create_with_audit_template_name(self):
audit = resource.Audit(mock.Mock(), AUDIT_3)
@@ -342,8 +305,7 @@ class AuditShellTest(base.CommandTestCase):
self.m_audit_mgr.create.assert_called_once_with(
audit_template_uuid='f8e47706-efcf-49a4-a5c4-af604eb492f2',
auto_trigger=False,
audit_type='ONESHOT'
)
audit_type='ONESHOT')
def test_do_audit_create_with_goal(self):
audit = resource.Audit(mock.Mock(), AUDIT_1)
@@ -394,9 +356,7 @@ class AuditShellTest(base.CommandTestCase):
result)
self.m_audit_mgr.create.assert_called_once_with(
goal='fc087747-61be-4aad-8126-b701731ae836',
auto_trigger=False,
audit_type='ONESHOT'
)
auto_trigger=False, audit_type='ONESHOT')
def test_do_audit_create_with_parameter(self):
audit = resource.Audit(mock.Mock(), AUDIT_1)
@@ -414,8 +374,7 @@ class AuditShellTest(base.CommandTestCase):
goal='fc087747-61be-4aad-8126-b701731ae836',
audit_type='ONESHOT',
auto_trigger=False,
parameters={'para1': 10, 'para2': 20}
)
parameters={'para1': 10, 'para2': 20})
def test_do_audit_create_with_type_continuous(self):
audit = resource.Audit(mock.Mock(), AUDIT_1)
@@ -433,25 +392,4 @@ class AuditShellTest(base.CommandTestCase):
goal='fc087747-61be-4aad-8126-b701731ae836',
audit_type='CONTINUOUS',
auto_trigger=False,
interval='3600'
)
def test_do_audit_create_with_name(self):
audit = resource.Audit(mock.Mock(), AUDIT_1)
self.m_audit_mgr.create.return_value = audit
exit_code, result = self.run_cmd(
'audit create -g fc087747-61be-4aad-8126-b701731ae836 '
'-t CONTINUOUS -i 3600 --name my_audit')
self.assertEqual(0, exit_code)
self.assertEqual(
self.resource_as_dict(audit, self.FIELDS, self.FIELD_LABELS),
result)
self.m_audit_mgr.create.assert_called_once_with(
goal='fc087747-61be-4aad-8126-b701731ae836',
audit_type='CONTINUOUS',
auto_trigger=False,
interval='3600',
name='my_audit'
)
interval='3600')

View File

@@ -178,16 +178,6 @@ fake_responses_sorting = {
},
}
fake_responses_marker = {
'/v1/audit_templates/?marker=f8e47706-efcf-49a4-a5c4-af604eb492f2':
{
'GET': (
{},
{"audit_templates": [AUDIT_TMPL2, AUDIT_TMPL3]}
),
},
}
fake_responses_filter_by_goal_uuid = {
'/v1/audit_templates/?goal=e75ee410-b32b-465f-88b5-4397705f9473':
{
@@ -399,18 +389,6 @@ class AuditTemplateManagerTest(utils.BaseTestCase):
self.assertEqual(expect, self.api.calls)
self.assertEqual(3, len(audit_templates))
def test_audit_templates_list_marker(self):
self.api = utils.FakeAPI(fake_responses_marker)
self.mgr = watcherclient.v1.audit_template.AuditTemplateManager(
self.api)
audit_templates = self.mgr.list(marker=AUDIT_TMPL1['uuid'])
expect_url = '/v1/audit_templates/?marker=%s' % AUDIT_TMPL1['uuid']
expect = [
('GET', expect_url, {}, None)
]
self.assertEqual(expect, self.api.calls)
self.assertEqual(2, len(audit_templates))
def test_audit_templates_show(self):
audit_template = self.mgr.get(AUDIT_TMPL1['uuid'])
expect = [

View File

@@ -128,24 +128,6 @@ class AuditTemplateShellTest(base.CommandTestCase):
self.m_audit_template_mgr.list.assert_called_once_with(detail=False)
def test_do_audit_template_list_marker(self):
audit_template2 = resource.AuditTemplate(mock.Mock(), AUDIT_TEMPLATE_2)
self.m_audit_template_mgr.list.return_value = [audit_template2]
exit_code, results = self.run_cmd(
'audittemplate list --marker '
'f8e47706-efcf-49a4-a5c4-af604eb492f2')
self.assertEqual(0, exit_code)
self.assertEqual(
[self.resource_as_dict(audit_template2, self.SHORT_LIST_FIELDS,
self.SHORT_LIST_FIELD_LABELS)],
results)
self.m_audit_template_mgr.list.assert_called_once_with(
detail=False,
marker='f8e47706-efcf-49a4-a5c4-af604eb492f2')
def test_do_audit_template_list_detail(self):
audit_template1 = resource.AuditTemplate(mock.Mock(), AUDIT_TEMPLATE_1)
audit_template2 = resource.AuditTemplate(mock.Mock(), AUDIT_TEMPLATE_2)

View File

@@ -63,13 +63,6 @@ fake_responses = {
STRATEGY1,
),
},
'/v1/strategies/%s/state' % STRATEGY1['name']:
{
'GET': (
{},
STRATEGY1,
),
},
}
fake_responses_pagination = {
@@ -187,10 +180,3 @@ class StrategyManagerTest(testtools.TestCase):
]
self.assertEqual(expect, self.api.calls)
self.assertEqual(STRATEGY1['name'], strategy.name)
def test_strategies_state(self):
self.mgr.state(STRATEGY1['name'])
expect = [
('GET', '/v1/strategies/%s/state' % STRATEGY1['name'], {}, None),
]
self.assertEqual(expect, self.api.calls)

View File

@@ -17,8 +17,6 @@ import datetime
import mock
import six
from oslo_serialization import jsonutils
from watcherclient import shell
from watcherclient.tests.unit.v1 import base
from watcherclient import v1 as resource
@@ -56,8 +54,6 @@ class StrategyShellTest(base.CommandTestCase):
resource_fields.STRATEGY_SHORT_LIST_FIELD_LABELS)
FIELDS = resource_fields.STRATEGY_FIELDS
FIELD_LABELS = resource_fields.STRATEGY_FIELD_LABELS
STATE_FIELDS = resource_fields.STRATEGY_STATE_FIELDS
STATE_FIELD_LABELS = resource_fields.STRATEGY_STATE_FIELD_LABELS
def setUp(self):
super(self.__class__, self).setUp()
@@ -159,33 +155,3 @@ class StrategyShellTest(base.CommandTestCase):
result)
self.m_strategy_mgr.get.assert_called_once_with(
'f8e47706-efcf-49a4-a5c4-af604eb492f2')
def test_do_strategy_state(self):
strategy1 = resource.Strategy(mock.Mock(), STRATEGY_1)
strategy_req = [
{'type': 'Datasource', 'mandatory': True,
'comment': '', 'state': 'gnocchi: True'},
{'type': 'Metrics', 'mandatory': False,
'comment': '', 'state': jsonutils.dumps([
{'compute.node.cpu.percent': 'available'},
{'cpu_util': 'available'},
{'memory.resident': 'available'},
{'hardware.memory.used': 'not available'}])},
{'type': 'CDM', 'mandatory': True,
'comment': '',
'state': jsonutils.dumps([{'compute_model': 'available'},
{'storage_model': 'not available'}])},
{'type': 'Name', 'mandatory': '', 'comment': '',
'state': strategy1.name}]
requirements = [resource.Strategy(mock.Mock(), req)
for req in strategy_req]
self.m_strategy_mgr.state.return_value = requirements
exit_code, results = self.run_cmd('strategy state basic')
self.assertEqual(0, exit_code)
self.assertEqual(
[self.resource_as_dict(req, self.STATE_FIELDS,
self.STATE_FIELD_LABELS)
for req in requirements],
results)

View File

@@ -30,7 +30,7 @@ class ActionManager(base.Manager):
return '/v1/actions/%s' % id if id else '/v1/actions'
def list(self, action_plan=None, audit=None, limit=None, sort_key=None,
sort_dir=None, detail=False, marker=None):
sort_dir=None, detail=False):
"""Retrieve a list of action.
:param action_plan: UUID of the action plan
@@ -52,15 +52,13 @@ class ActionManager(base.Manager):
:param detail: Optional, boolean whether to return detailed information
about actions.
:param marker: Optional, UUID of the last action in the previous page.
:returns: A list of actions.
"""
if limit is not None:
limit = int(limit)
filters = utils.common_filters(limit, sort_key, sort_dir, marker)
filters = utils.common_filters(limit, sort_key, sort_dir)
if action_plan is not None:
filters.append('action_plan_uuid=%s' % action_plan)
if audit is not None:

View File

@@ -27,16 +27,11 @@ class ActionPlanManager(base.Manager):
resource_class = ActionPlan
@staticmethod
def _path(id=None, q_param=None):
if id and q_param:
return '/v1/action_plans/%s/%s' % (id, q_param)
elif id:
return '/v1/action_plans/%s' % id
else:
return '/v1/action_plans'
def _path(id=None):
return '/v1/action_plans/%s' % id if id else '/v1/action_plans'
def list(self, audit=None, limit=None, sort_key=None,
sort_dir=None, detail=False, marker=None):
sort_dir=None, detail=False):
"""Retrieve a list of action plan.
:param audit: Name of the audit
@@ -57,16 +52,13 @@ class ActionPlanManager(base.Manager):
:param detail: Optional, boolean whether to return detailed information
about action plans.
:param marker: The last actionplan UUID of the previous page;
displays list of actionplans after "marker".
:returns: A list of action plans.
"""
if limit is not None:
limit = int(limit)
filters = utils.common_filters(limit, sort_key, sort_dir, marker)
filters = utils.common_filters(limit, sort_key, sort_dir)
if audit is not None:
filters.append('audit_uuid=%s' % audit)
@@ -95,7 +87,8 @@ class ActionPlanManager(base.Manager):
return self._update(self._path(action_plan_id), patch)
def start(self, action_plan_id):
return self._start(self._path(action_plan_id, 'start'))
patch = [{'op': 'replace', 'value': 'PENDING', 'path': '/state'}]
return self._update(self._path(action_plan_id), patch)
def cancel(self, action_plan_id):
action_plan = self.get(action_plan_id)

View File

@@ -26,16 +26,16 @@ from watcherclient.v1 import resource_fields as res_fields
def format_global_efficacy(global_efficacy):
formatted_global_eff = {}
for eff in global_efficacy:
eff_name = eff.get('name')
if (eff.get('value') is not None and eff.get('unit')):
formatted_global_eff[eff_name] = "%(value).2f %(unit)s" % dict(
unit=eff.get('unit'),
value=eff.get('value'))
elif eff.get('value') is not None:
formatted_global_eff[eff_name] = eff.get('value')
return formatted_global_eff
formatted_global_efficacy = None
if (global_efficacy.get('value') is not None and
global_efficacy.get('unit')):
formatted_global_efficacy = "%(value).2f %(unit)s" % dict(
unit=global_efficacy.get('unit'),
value=global_efficacy.get('value'))
elif global_efficacy.get('value') is not None:
formatted_global_efficacy = global_efficacy.get('value')
return formatted_global_efficacy
class ShowActionPlan(command.ShowOne):
@@ -64,18 +64,6 @@ class ShowActionPlan(command.ShowOne):
)
return out.getvalue() or ''
def _format_global_efficacy(self, global_efficacy, parsed_args):
formatted_global_efficacy = format_global_efficacy(global_efficacy)
out = six.StringIO()
yaml_format.YAMLFormatter().emit_one(
column_names=list(resource.capitalize()
for resource in formatted_global_efficacy),
data=[value for value in formatted_global_efficacy.itervalues()],
stdout=out,
parsed_args=parsed_args,
)
return out.getvalue() or ''
def take_action(self, parsed_args):
client = getattr(self.app.client_manager, "infra-optim")
@@ -95,8 +83,8 @@ class ShowActionPlan(command.ShowOne):
self._format_indicators(action_plan, parsed_args))
# Update the raw global efficacy with the formatted one
action_plan.global_efficacy = self._format_global_efficacy(
action_plan.global_efficacy, parsed_args)
action_plan.global_efficacy = format_global_efficacy(
action_plan.global_efficacy)
columns = res_fields.ACTION_PLAN_FIELDS
column_headers = res_fields.ACTION_PLAN_FIELD_LABELS
@@ -125,11 +113,6 @@ class ListActionPlan(command.Lister):
help=_('Maximum number of action plans to return per request, '
'0 for no limit. Default is the maximum number used '
'by the Watcher API Service.'))
parser.add_argument(
'--marker',
metavar='<actionplan>',
help=_('The last actionplan UUID of the previous page; '
'displays list of actionplans after "marker".'))
parser.add_argument(
'--sort-key',
metavar='<field>',
@@ -156,18 +139,6 @@ class ListActionPlan(command.Lister):
)
return out.getvalue() or ''
def _format_global_efficacy(self, global_efficacy, parsed_args):
formatted_global_efficacy = format_global_efficacy(global_efficacy)
out = six.StringIO()
yaml_format.YAMLFormatter().emit_one(
column_names=list(resource.capitalize()
for resource in formatted_global_efficacy),
data=[value for value in formatted_global_efficacy.values()],
stdout=out,
parsed_args=parsed_args,
)
return out.getvalue() or ''
def take_action(self, parsed_args):
client = getattr(self.app.client_manager, "infra-optim")
@@ -193,13 +164,54 @@ class ListActionPlan(command.Lister):
self._format_indicators(action_plan, parsed_args))
# Update the raw global efficacy with the formatted one
action_plan.global_efficacy = self._format_global_efficacy(
action_plan.global_efficacy, parsed_args)
action_plan.global_efficacy = format_global_efficacy(
action_plan.global_efficacy)
return (field_labels,
(utils.get_item_properties(item, fields) for item in data))
class CreateActionPlan(command.ShowOne):
"""Create new audit."""
def get_parser(self, prog_name):
parser = super(CreateActionPlan, self).get_parser(prog_name)
parser.add_argument(
'-a', '--audit-template',
required=True,
dest='audit_template_uuid',
metavar='<audit_template>',
help=_('Audit template used for this audit (name or uuid).'))
parser.add_argument(
'-t', '--audit_type',
dest='audit_type',
metavar='<audit_type>',
default='ONESHOT',
choices=['ONESHOT', 'CONTINUOUS'],
help=_("Audit type. It must be ONESHOT or CONTINUOUS. "
"Default is ONESHOT."))
return parser
def take_action(self, parsed_args):
client = getattr(self.app.client_manager, "infra-optim")
field_list = ['audit_template_uuid', 'audit_type']
fields = dict((k, v) for (k, v) in vars(parsed_args).items()
if k in field_list and v is not None)
if fields.get('audit_template_uuid'):
if not uuidutils.is_uuid_like(fields['audit_template_uuid']):
fields['audit_template_uuid'] = client.audit_template.get(
fields['audit_template_uuid']).uuid
audit = client.audit.create(**fields)
columns = res_fields.ACTION_PLAN_FIELDS
column_headers = res_fields.ACTION_PLAN_FIELD_LABELS
return column_headers, utils.get_item_properties(audit, columns)
class UpdateActionPlan(command.ShowOne):
"""Update action plan command."""

View File

@@ -83,13 +83,6 @@ class ListAction(command.Lister):
metavar='<direction>',
choices=['asc', 'desc'],
help=_('Sort direction: "asc" (the default) or "desc".'))
parser.add_argument(
'--marker',
dest='marker',
metavar='<marker>',
default=None,
help=_('UUID of the last action in the previous page; '
'displays list of actions after "marker".'))
return parser

View File

@@ -19,8 +19,7 @@ from watcherclient import exceptions as exc
CREATION_ATTRIBUTES = ['audit_template_uuid', 'audit_type', 'interval',
'parameters', 'goal', 'strategy', 'auto_trigger',
'name']
'parameters', 'goal', 'strategy', 'auto_trigger']
class Audit(base.Resource):
@@ -36,11 +35,11 @@ class AuditManager(base.Manager):
return '/v1/audits/%s' % id if id else '/v1/audits'
def list(self, audit_template=None, limit=None, sort_key=None,
sort_dir=None, detail=False, goal=None, strategy=None,
marker=None):
sort_dir=None, detail=False, goal=None, strategy=None):
"""Retrieve a list of audit.
:param audit_template: Name of the audit template
:param audit_template: Name of the audit
:param name: Name of the audit
:param limit: The maximum number of results to return per
request, if:
@@ -58,15 +57,13 @@ class AuditManager(base.Manager):
:param detail: Optional, boolean whether to return detailed information
about audits.
:param marker: Optional, UUID of the last audit in the previous page.
:returns: A list of audits.
"""
if limit is not None:
limit = int(limit)
filters = utils.common_filters(limit, sort_key, sort_dir, marker)
filters = utils.common_filters(limit, sort_key, sort_dir)
if audit_template is not None:
filters.append('audit_template=%s' % audit_template)
if goal is not None:
@@ -95,14 +92,14 @@ class AuditManager(base.Manager):
raise exc.InvalidAttribute()
return self._create(self._path(), new)
def get(self, audit):
def get(self, audit_id):
try:
return self._list(self._path(audit))[0]
return self._list(self._path(audit_id))[0]
except IndexError:
return None
def delete(self, audit):
return self._delete(self._path(audit))
def delete(self, audit_id):
return self._delete(self._path(audit_id))
def update(self, audit, patch):
return self._update(self._path(audit), patch)
def update(self, audit_id, patch):
return self._update(self._path(audit_id), patch)

View File

@@ -31,7 +31,7 @@ class ShowAudit(command.ShowOne):
parser.add_argument(
'audit',
metavar='<audit>',
help=_('UUID or name of the audit'),
help=_('UUID of the audit'),
)
return parser
@@ -88,13 +88,6 @@ class ListAudit(command.Lister):
metavar='<direction>',
choices=['asc', 'desc'],
help=_('Sort direction: "asc" (the default) or "desc".'))
parser.add_argument(
'--marker',
dest='marker',
metavar='<marker>',
default=None,
help=_('UUID of the last audit in the previous page; '
'displays list of audits after "marker".'))
return parser
@@ -182,19 +175,13 @@ class CreateAudit(command.ShowOne):
default=False,
help=_('Trigger automatically action plan '
'once audit is succeeded.'))
parser.add_argument(
'--name',
dest='name',
metavar='<name>',
help=_('Name for this audit.'))
return parser
def take_action(self, parsed_args):
client = getattr(self.app.client_manager, "infra-optim")
field_list = ['audit_template_uuid', 'audit_type', 'parameters',
'interval', 'goal', 'strategy', 'auto_trigger', 'name']
'interval', 'goal', 'strategy', 'auto_trigger']
fields = dict((k, v) for (k, v) in vars(parsed_args).items()
if k in field_list and v is not None)
@@ -232,7 +219,7 @@ class UpdateAudit(command.ShowOne):
parser.add_argument(
'audit',
metavar='<audit>',
help=_("UUID or name of the audit."))
help=_("UUID of the audit."))
parser.add_argument(
'op',
metavar='<op>',
@@ -252,6 +239,9 @@ class UpdateAudit(command.ShowOne):
def take_action(self, parsed_args):
client = getattr(self.app.client_manager, "infra-optim")
if not uuidutils.is_uuid_like(parsed_args.audit):
raise exceptions.ValidationError()
patch = common_utils.args_array_to_patch(
parsed_args.op, parsed_args.attributes[0],
exclude_fields=['/interval'])
@@ -273,7 +263,7 @@ class DeleteAudit(command.Command):
'audits',
metavar='<audit>',
nargs='+',
help=_('UUID or name of the audit'),
help=_('UUID of the audit'),
)
return parser
@@ -281,4 +271,7 @@ class DeleteAudit(command.Command):
client = getattr(self.app.client_manager, "infra-optim")
for audit in parsed_args.audits:
if not uuidutils.is_uuid_like(audit):
raise exceptions.ValidationError()
client.audit.delete(audit)

View File

@@ -33,7 +33,7 @@ class AuditTemplateManager(base.Manager):
return '/v1/audit_templates/%s' % id_ if id_ else '/v1/audit_templates'
def list(self, name=None, goal=None, strategy=None, limit=None,
sort_key=None, sort_dir=None, detail=False, marker=None):
sort_key=None, sort_dir=None, detail=False):
"""Retrieve a list of audit template.
:param name: Name of the audit template
@@ -54,16 +54,13 @@ class AuditTemplateManager(base.Manager):
:param detail: Optional, boolean whether to return detailed information
about audit_templates.
:param marker: Optional, UUID of the last audit template of
the previous page.
:returns: A list of audit templates.
"""
if limit is not None:
limit = int(limit)
filters = utils.common_filters(limit, sort_key, sort_dir, marker)
filters = utils.common_filters(limit, sort_key, sort_dir)
if name is not None:
filters.append('name=%s' % name)
if goal is not None:

View File

@@ -91,13 +91,6 @@ class ListAuditTemplate(command.Lister):
metavar='<direction>',
choices=['asc', 'desc'],
help=_('Sort direction: "asc" (the default) or "desc".'))
parser.add_argument(
'--marker',
dest='marker',
metavar='<marker>',
default=None,
help=_('UUID of the last audit template of the previous page; '
'displays list of audit templates after "marker".'))
return parser
@@ -169,81 +162,37 @@ class CreateAuditTemplate(command.ShowOne):
"Can be provided either in yaml or json file.\n"
"YAML example:\n"
"---\n"
" - compute:\n"
" - host_aggregates:\n"
" - id: 1\n"
" - id: 2\n"
" - id: 3\n"
" - availability_zones:\n"
" - name: AZ1\n"
" - name: AZ2\n"
" - exclude:\n"
" - instances:\n"
" - uuid: UUID1\n"
" - uuid: UUID2\n"
" - compute_nodes:\n"
" - name: compute1\n"
" - storage: \n"
" - availability_zones:\n"
" - name: AZ1\n"
" - name: AZ2\n"
" - volume_types:\n"
" - name: lvm1\n"
" - name: lvm2\n"
" - exclude:\n"
" - storage_pools:\n"
" - name: host0@backend0#pool0\n"
" - name: host1@backend1#pool1\n"
" - volumes:\n"
" - uuid: UUID1\n"
" - uuid: UUID2\n"
" - projects:\n"
" - uuid: UUID1\n"
" - uuid: UUID2\n"
" - host_aggregates:\n"
" - id: 1\n"
" - id: 2\n"
" - id: 3\n"
" - availability_zones:\n"
" - name: AZ1\n"
" - name: AZ2\n"
" - exclude:\n"
" - instances:\n"
" - uuid: UUID1\n"
" - uuid: UUID2\n"
" - compute_nodes:\n"
" - name: compute1\n"
"\n"
"JSON example:\n"
"[\n"
" {\"compute\":\n"
" [{\"host_aggregates\": [\n"
" {\"id\": 1},\n"
" {\"id\": 2},\n"
" {\"id\": 3}]},\n"
" {\"availability_zones\": [\n"
" {\"name\": \"AZ1\"},\n"
" {\"name\": \"AZ2\"}]},\n"
" {\"exclude\": [\n"
" {\"instances\": [\n"
" {\"uuid\": \"UUID1\"},\n"
" {\"uuid\": \"UUID2\"}\n"
" ]},\n"
" {\"compute_nodes\": [\n"
" {\"name\": \"compute1\"}\n"
" ]}\n"
" ]}]\n"
" },\n"
" {\"storage\":\n"
" [{\"availability_zones\": [\n"
" {\"name\": \"AZ1\"},\n"
" {\"name\": \"AZ2\"}]},\n"
" {\"volume_types\": [\n"
" {\"name\": \"lvm1\"},\n"
" {\"name\": \"lvm2\"}]},\n"
" {\"exclude\": [\n"
" {\"storage_pools\": [\n"
" {\"name\": \"host0@backend0#pool0\"},\n"
" {\"name\": \"host1@backend1#pool1\"}\n"
" ]},\n"
" {\"volumes\": [\n"
" {\"uuid\": \"UUID1\"},\n"
" {\"uuid\": \"UUID2\"}\n"
" ]},\n"
" {\"projects\": [\n"
" {\"uuid\": \"UUID1\"},\n"
" {\"uuid\": \"UUID2\"}\n"
" ]},\n"
" ]}]\n"
" }\n"
" ]\n"
"[{'host_aggregates': [\n"
" {'id': 1},\n"
" {'id': 2},\n"
" {'id': 3}]},\n"
" {'availability_zones': [\n"
" {'name': 'AZ1'},\n"
" {'name': 'AZ2'}]},\n"
" {'exclude': [\n"
" {'instances': [\n"
" {'uuid': 'UUID1'},\n"
" {'uuid': 'UUID2'}\n"
" ]},\n"
" {'compute_nodes': [\n"
" {'name': 'compute1'}\n"
" ]}\n"
"]}]\n"
)
)

View File

@@ -30,32 +30,30 @@ AUDIT_TEMPLATE_SHORT_LIST_FIELDS = [
AUDIT_TEMPLATE_SHORT_LIST_FIELD_LABELS = ['UUID', 'Name', 'Goal', 'Strategy']
# Audit
AUDIT_FIELDS = ['uuid', 'name', 'created_at', 'updated_at', 'deleted_at',
AUDIT_FIELDS = ['uuid', 'created_at', 'updated_at', 'deleted_at',
'state', 'audit_type', 'parameters', 'interval', 'goal_name',
'strategy_name', 'scope', 'auto_trigger', 'next_run_time',
'hostname']
'strategy_name', 'scope', 'auto_trigger', 'next_run_time']
AUDIT_FIELD_LABELS = ['UUID', 'Name', 'Created At', 'Updated At', 'Deleted At',
AUDIT_FIELD_LABELS = ['UUID', 'Created At', 'Updated At', 'Deleted At',
'State', 'Audit Type', 'Parameters', 'Interval', 'Goal',
'Strategy', 'Audit Scope', 'Auto Trigger',
'Next Run Time', 'Hostname']
'Next Run Time']
AUDIT_SHORT_LIST_FIELDS = ['uuid', 'name', 'audit_type',
AUDIT_SHORT_LIST_FIELDS = ['uuid', 'audit_type',
'state', 'goal_name', 'strategy_name',
'auto_trigger']
AUDIT_SHORT_LIST_FIELD_LABELS = ['UUID', 'Name', 'Audit Type', 'State', 'Goal',
AUDIT_SHORT_LIST_FIELD_LABELS = ['UUID', 'Audit Type', 'State', 'Goal',
'Strategy', 'Auto Trigger']
# Action Plan
ACTION_PLAN_FIELDS = ['uuid', 'created_at', 'updated_at', 'deleted_at',
'audit_uuid', 'strategy_name', 'state',
'efficacy_indicators', 'global_efficacy', 'hostname']
'efficacy_indicators', 'global_efficacy']
ACTION_PLAN_FIELD_LABELS = ['UUID', 'Created At', 'Updated At', 'Deleted At',
'Audit', 'Strategy', 'State',
'Efficacy indicators', 'Global efficacy',
'Hostname']
'Efficacy indicators', 'Global efficacy']
ACTION_PLAN_SHORT_LIST_FIELDS = ['uuid', 'audit_uuid', 'state',
'updated_at', 'global_efficacy']
@@ -63,8 +61,6 @@ ACTION_PLAN_SHORT_LIST_FIELDS = ['uuid', 'audit_uuid', 'state',
ACTION_PLAN_SHORT_LIST_FIELD_LABELS = ['UUID', 'Audit', 'State',
'Updated At', 'Global efficacy']
GLOBAL_EFFICACY_FIELDS = ['value', 'unit', 'name', 'description']
# Action
ACTION_FIELDS = ['uuid', 'created_at', 'updated_at', 'deleted_at', 'parents',
'state', 'action_plan_uuid', 'action_type',
@@ -101,10 +97,6 @@ STRATEGY_SHORT_LIST_FIELDS = ['uuid', 'name', 'display_name', 'goal_name']
STRATEGY_SHORT_LIST_FIELD_LABELS = ['UUID', 'Name', 'Display name', 'Goal']
STRATEGY_STATE_FIELDS = ['type', 'state', 'mandatory', 'comment']
STRATEGY_STATE_FIELD_LABELS = ['Type', 'State', 'Mandatory', 'Comment']
# Metric Collector
METRIC_COLLECTOR_FIELDS = ['uuid', 'created_at', 'updated_at', 'deleted_at',
'endpoint', 'category']

View File

@@ -28,14 +28,9 @@ class StrategyManager(base.Manager):
resource_class = Strategy
@staticmethod
def _path(strategy=None, state=False):
if strategy:
path = '/v1/strategies/%s' % strategy
if state:
path = '/v1/strategies/%s/state' % strategy
else:
path = '/v1/strategies'
return path
def _path(strategy=None):
return ('/v1/strategies/%s' % strategy
if strategy else '/v1/strategies')
def list(self, goal=None, limit=None, sort_key=None,
sort_dir=None, detail=False):
@@ -87,6 +82,3 @@ class StrategyManager(base.Manager):
return self._list(self._path(strategy))[0]
except IndexError:
return None
def state(self, strategy):
return self._list(self._path(strategy, state=True))

View File

@@ -57,40 +57,6 @@ class ShowStrategy(command.ShowOne):
return column_headers, utils.get_item_properties(strategy, columns)
class StateStrategy(command.Lister):
"""Retrieve information about strategy requirements."""
def get_parser(self, prog_name):
parser = super(StateStrategy, self).get_parser(prog_name)
parser.add_argument(
'strategy',
metavar='<strategy>',
help=_('Name of the strategy'),
)
return parser
def _format_spec(self, requirements):
for req in requirements:
if type(req.state) == list:
req.state = jsonutils.dumps(req.state, indent=2)
return requirements
def take_action(self, parsed_args):
client = getattr(self.app.client_manager, "infra-optim")
try:
requirements = client.strategy.state(parsed_args.strategy)
except exceptions.HTTPNotFound as exc:
raise exceptions.CommandError(str(exc))
requirements = self._format_spec(requirements)
columns = res_fields.STRATEGY_STATE_FIELDS
column_headers = res_fields.STRATEGY_STATE_FIELD_LABELS
return (column_headers,
(utils.get_item_properties(item, columns)
for item in requirements))
class ListStrategy(command.Lister):
"""List information on retrieved strategies."""