Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db7a5e4bc9 | ||
|
|
825e5cb081 | ||
|
|
a8185c7067 | ||
|
|
4a0b0e76b4 | ||
|
|
1918d3f26b | ||
|
|
2ca6b6b421 | ||
|
|
1086b23454 | ||
|
|
535b9da7d2 | ||
|
|
34a4ad3041 | ||
|
|
39d4c1e944 | ||
|
|
c1fd569b76 | ||
|
|
eed22ea2bb | ||
|
|
47241e0462 | ||
|
|
88d122a21f | ||
|
|
5e928b80be | ||
|
|
723ad12afa | ||
|
|
3926dcc541 | ||
|
|
c557e45ae2 | ||
|
|
0b8dba2cb9 | ||
|
|
496f4c1365 | ||
|
|
6681724daa | ||
|
|
2551ff0934 | ||
|
|
adc812746c | ||
|
|
8d62995cf4 | ||
|
|
d82be4c8c4 | ||
|
|
152804168d | ||
|
|
4a4add3dcc | ||
|
|
db012f1f8f | ||
|
|
a4c020c19f | ||
|
|
8ef72f18c4 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -26,7 +26,7 @@ pip-log.txt
|
||||
.coverage
|
||||
.tox
|
||||
nosetests.xml
|
||||
.testrepository
|
||||
.stestr/
|
||||
.venv
|
||||
|
||||
# Translations
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[DEFAULT]
|
||||
test_path=${OS_TEST_PATH:-./watcherclient/tests/functional}
|
||||
top_dir=./
|
||||
test_path=./watcherclient/tests/functional
|
||||
top_dir=./
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
[DEFAULT]
|
||||
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
|
||||
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
|
||||
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-160} \
|
||||
${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./watcherclient/tests} $LISTOPT $IDOPTION
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
||||
16
.zuul.yaml
16
.zuul.yaml
@@ -1,9 +1,13 @@
|
||||
- project:
|
||||
templates:
|
||||
- openstack-lower-constraints-jobs
|
||||
- openstack-python-jobs
|
||||
- openstack-python35-jobs
|
||||
- openstack-python36-jobs
|
||||
- publish-openstack-docs-pti
|
||||
- check-requirements
|
||||
- openstackclient-plugin-jobs
|
||||
check:
|
||||
jobs:
|
||||
- watcherclient-tempest-functional
|
||||
- openstack-tox-lower-constraints
|
||||
gate:
|
||||
jobs:
|
||||
- watcherclient-tempest-functional
|
||||
- openstack-tox-lower-constraints
|
||||
- watcherclient-tempest-functional:
|
||||
voting: false
|
||||
|
||||
@@ -157,7 +157,7 @@ watcher action list
|
||||
[--quote {all,minimal,none,nonnumeric}]
|
||||
[--action-plan <action-plan>] [--audit <audit>]
|
||||
[--detail] [--limit <limit>] [--sort-key <field>]
|
||||
[--sort-dir <direction>]
|
||||
[--sort-dir <direction>] [--marker <marker>]
|
||||
|
||||
List information on retrieved actions.
|
||||
|
||||
@@ -186,6 +186,10 @@ List information on retrieved actions.
|
||||
``--sort-dir <direction>``
|
||||
Sort direction: "asc" (the default) or "desc".
|
||||
|
||||
``--marker <marker>``
|
||||
UUID of the last action in the previous page; displays
|
||||
list of actions after "marker".
|
||||
|
||||
.. _watcher_action_show:
|
||||
|
||||
watcher action show
|
||||
@@ -295,7 +299,8 @@ watcher actionplan list
|
||||
[--fit-width] [--print-empty] [--noindent]
|
||||
[--quote {all,minimal,none,nonnumeric}]
|
||||
[--audit <audit>] [--detail] [--limit <limit>]
|
||||
[--sort-key <field>] [--sort-dir <direction>]
|
||||
[--marker <actionplan>] [--sort-key <field>]
|
||||
[--sort-dir <direction>]
|
||||
|
||||
List information on retrieved action plans.
|
||||
|
||||
@@ -315,6 +320,10 @@ List information on retrieved action plans.
|
||||
0 for no limit. Default is the maximum number used by
|
||||
the Watcher API Service.
|
||||
|
||||
``--marker <actionplan>``
|
||||
The last actionplan UUID of the previous page;
|
||||
displays list of actionplans after "marker".
|
||||
|
||||
``--sort-key <field>``
|
||||
Action Plan field that will be used for sorting.
|
||||
|
||||
@@ -466,7 +475,7 @@ Delete audit command.
|
||||
**Positional arguments:**
|
||||
|
||||
``<audit>``
|
||||
UUID of the audit
|
||||
UUID or name of the audit
|
||||
|
||||
**Optional arguments:**
|
||||
|
||||
@@ -532,7 +541,7 @@ Show detailed information about a given audit.
|
||||
**Positional arguments:**
|
||||
|
||||
``<audit>``
|
||||
UUID of the audit
|
||||
UUID or name of the audit
|
||||
|
||||
**Optional arguments:**
|
||||
|
||||
@@ -556,7 +565,7 @@ Update audit command.
|
||||
**Positional arguments:**
|
||||
|
||||
``<audit>``
|
||||
UUID of the audit.
|
||||
UUID or name of the audit.
|
||||
|
||||
``<op>``
|
||||
Operation: 'add', 'replace', or 'remove'.
|
||||
@@ -680,7 +689,7 @@ watcher audittemplate list
|
||||
[--detail] [--goal <goal>]
|
||||
[--strategy <strategy>] [--limit <limit>]
|
||||
[--sort-key <field>]
|
||||
[--sort-dir <direction>]
|
||||
[--sort-dir <direction>][--marker <marker>]
|
||||
|
||||
List information on retrieved audit templates.
|
||||
|
||||
@@ -709,6 +718,10 @@ List information on retrieved audit templates.
|
||||
``--sort-dir <direction>``
|
||||
Sort direction: "asc" (the default) or "desc".
|
||||
|
||||
``--marker <marker>``
|
||||
UUID of the last audittemplate in the previous page; displays
|
||||
list of audittemplates after "marker".
|
||||
|
||||
.. _watcher_audittemplate_show:
|
||||
|
||||
watcher audittemplate show
|
||||
@@ -781,7 +794,7 @@ watcher goal list
|
||||
[--print-empty] [--noindent]
|
||||
[--quote {all,minimal,none,nonnumeric}] [--detail]
|
||||
[--limit <limit>] [--sort-key <field>]
|
||||
[--sort-dir <direction>]
|
||||
[--sort-dir <direction>][--marker <marker>]
|
||||
|
||||
List information on retrieved goals.
|
||||
|
||||
@@ -804,6 +817,10 @@ List information on retrieved goals.
|
||||
``--sort-dir <direction>``
|
||||
Sort direction: "asc" (the default) or "desc".
|
||||
|
||||
``--marker <marker>``
|
||||
UUID of the last goal in the previous page; displays
|
||||
list of goals after "marker".
|
||||
|
||||
.. _watcher_goal_show:
|
||||
|
||||
watcher goal show
|
||||
@@ -841,7 +858,7 @@ watcher scoringengine list
|
||||
[--quote {all,minimal,none,nonnumeric}]
|
||||
[--detail] [--limit <limit>]
|
||||
[--sort-key <field>]
|
||||
[--sort-dir <direction>]
|
||||
[--sort-dir <direction>][--marker <marker>]
|
||||
|
||||
List information on retrieved scoring engines.
|
||||
|
||||
@@ -864,6 +881,10 @@ List information on retrieved scoring engines.
|
||||
``--sort-dir <direction>``
|
||||
Sort direction: "asc" (the default) or "desc".
|
||||
|
||||
``--marker <marker>``
|
||||
UUID of the last scoringengine in the previous page; displays
|
||||
list of scoringengines after "marker".
|
||||
|
||||
.. _watcher_scoringengine_show:
|
||||
|
||||
watcher scoringengine show
|
||||
@@ -961,6 +982,7 @@ watcher strategy list
|
||||
[--quote {all,minimal,none,nonnumeric}]
|
||||
[--goal <goal>] [--detail] [--limit <limit>]
|
||||
[--sort-key <field>] [--sort-dir <direction>]
|
||||
[--marker <marker>]
|
||||
|
||||
List information on retrieved strategies.
|
||||
|
||||
@@ -986,6 +1008,10 @@ List information on retrieved strategies.
|
||||
``--sort-dir <direction>``
|
||||
Sort direction: "asc" (the default) or "desc".
|
||||
|
||||
``--marker <marker>``
|
||||
UUID of the last strategy in the previous page; displays
|
||||
list of strategies after "marker".
|
||||
|
||||
.. _watcher_strategy_show:
|
||||
|
||||
watcher strategy show
|
||||
@@ -1010,3 +1036,28 @@ Show detailed information about a given strategy.
|
||||
``-h, --help``
|
||||
show this help message and exit
|
||||
|
||||
.. _watcher_strategy_state:
|
||||
|
||||
watcher strategy state
|
||||
----------------------
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
usage: watcher strategy state [-h] [-f {csv,html,json,table,value,yaml}]
|
||||
[-c COLUMN] [--max-width <integer>]
|
||||
[--fit-width] [--print-empty] [--noindent]
|
||||
[--quote {all,minimal,none,nonnumeric}]
|
||||
[--sort-column SORT_COLUMN]
|
||||
<strategy>
|
||||
|
||||
Retrieve information about strategy requirements.
|
||||
|
||||
**Positional arguments:**
|
||||
|
||||
``<strategy>``
|
||||
Name of the strategy
|
||||
|
||||
**Optional arguments:**
|
||||
|
||||
``-h, --help``
|
||||
show this help message and exit
|
||||
|
||||
@@ -71,8 +71,7 @@ Once you have an watcher `Client`_, you can perform various tasks::
|
||||
>>> watcher.audit.get(audit_uuid_or_name) # information about a particular audit
|
||||
|
||||
When the `Client`_ needs to propagate an exception, it will usually
|
||||
raise an instance subclassed from
|
||||
`watcherclient.exc.BaseException`_ or `watcherclient.exc.ClientException`_.
|
||||
raise an instance listed in `watcherclient.exceptions`_.
|
||||
|
||||
Refer to the modules themselves, for more details.
|
||||
|
||||
@@ -84,5 +83,4 @@ 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.exc.BaseException: api/watcherclient.exc.html#watcherclient.exc.BaseException
|
||||
.. _watcherclient.exc.ClientException: api/watcherclient.exc.html#watcherclient.exc.ClientException
|
||||
.. _watcherclient.exceptions: api/watcherclient.exceptions.html
|
||||
|
||||
@@ -69,7 +69,6 @@ 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
|
||||
@@ -80,10 +79,9 @@ six==1.11.0
|
||||
snowballstemmer==1.2.1
|
||||
Sphinx==1.6.5
|
||||
sphinxcontrib-websupport==1.0.1
|
||||
stestr==1.0.0
|
||||
stestr==2.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
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# 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
|
||||
pbr!=2.1.0,>=2.0.0 # Apache-2.0
|
||||
PrettyTable<0.8,>=0.7.1 # BSD
|
||||
Babel!=2.4.0,>=2.5.3 # BSD
|
||||
cliff!=2.9.0,>=2.11.0 # Apache-2.0
|
||||
osc-lib>=1.10.0 # Apache-2.0
|
||||
oslo.i18n>=3.20.0 # Apache-2.0
|
||||
oslo.utils>=3.36.0 # Apache-2.0
|
||||
pbr!=2.1.0,>=3.1.1 # Apache-2.0
|
||||
PrettyTable<0.8,>=0.7.2 # BSD
|
||||
keystoneauth1>=3.4.0 # Apache-2.0
|
||||
six>=1.10.0 # MIT
|
||||
six>=1.11.0 # MIT
|
||||
PyYAML>=3.12 # MIT
|
||||
|
||||
@@ -54,7 +54,6 @@ 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
|
||||
@@ -91,7 +90,6 @@ 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
|
||||
|
||||
@@ -9,11 +9,8 @@ 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
|
||||
testrepository>=0.0.18 # Apache-2.0/BSD
|
||||
sphinx!=1.6.6,!=1.6.7,>=1.6.5 # BSD
|
||||
stestr>=2.0.0 # Apache-2.0
|
||||
testscenarios>=0.4 # Apache-2.0/BSD
|
||||
testtools>=2.2.0 # MIT
|
||||
tempest>=17.1.0 # Apache-2.0
|
||||
|
||||
# Needed for pypi packaging
|
||||
wheel>=0.24.0 # MIT
|
||||
|
||||
24
tox.ini
24
tox.ini
@@ -10,26 +10,36 @@ install_command =
|
||||
pip install -U {opts} {packages}
|
||||
setenv =
|
||||
VIRTUAL_ENV={envdir}
|
||||
OS_TEST_PATH=./watcherclient/tests/unit
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
commands = rm -f .testrepository/times.dbm
|
||||
python setup.py testr --slowest --testr-args='{posargs}'
|
||||
stestr --test-path=./watcherclient/tests/unit run {posargs}
|
||||
stestr slowest
|
||||
|
||||
[testenv:pep8]
|
||||
basepython = python3
|
||||
commands = flake8
|
||||
|
||||
[testenv:venv]
|
||||
basepython = python3
|
||||
commands = {posargs}
|
||||
|
||||
[testenv:cover]
|
||||
basepython = python3
|
||||
setenv =
|
||||
PYTHON=coverage run --source watcherclient --parallel-mode
|
||||
commands =
|
||||
python setup.py testr --coverage --testr-args='{posargs}'
|
||||
coverage report
|
||||
stestr run {posargs}
|
||||
coverage combine
|
||||
coverage html -d cover
|
||||
coverage xml -o cover/coverage.xml
|
||||
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]
|
||||
@@ -43,9 +53,8 @@ passenv =
|
||||
OS_AUTH_URL
|
||||
OS_IDENTITY_API_VERSION
|
||||
OS_IMAGE_API_VERSION
|
||||
setenv =
|
||||
OS_TEST_PATH = ./watcherclient/tests/functional
|
||||
commands = python setup.py testr --slowest --testr-args='--concurrency=1 {posargs}'
|
||||
commands = stestr --test-path=./watcherclient/tests/functional run --concurrency=1 {posargs}
|
||||
stestr slowest
|
||||
|
||||
[flake8]
|
||||
# E123, E125 skipped as they are invalid PEP-8.
|
||||
@@ -56,6 +65,7 @@ builtins = _
|
||||
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
|
||||
|
||||
[testenv:wheel]
|
||||
basepython = python3
|
||||
commands = python setup.py bdist_wheel
|
||||
|
||||
[hacking]
|
||||
|
||||
@@ -134,6 +134,11 @@ 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).
|
||||
|
||||
@@ -354,7 +354,15 @@ class HTTPClient(VersionNegotiationMixin):
|
||||
# Read body into string if it isn't obviously image data
|
||||
body_str = None
|
||||
if resp.headers.get('Content-Type') != 'application/octet-stream':
|
||||
body_str = ''.join([chunk for chunk in body_iter])
|
||||
# decoding byte to string is necessary for Python 3 compatibility
|
||||
# this issues has not been found with Python 3 unit tests
|
||||
# because the test creates a fake http response of type str
|
||||
# the if statement satisfies test (str) and real (bytes) behavior
|
||||
body_list = [
|
||||
chunk.decode("utf-8") if isinstance(chunk, bytes)
|
||||
else chunk for chunk in body_iter
|
||||
]
|
||||
body_str = ''.join(body_list)
|
||||
self.log_http_response(resp, body_str)
|
||||
body_iter = six.StringIO(body_str)
|
||||
else:
|
||||
|
||||
@@ -47,8 +47,6 @@ _IDENTITY_API_VERSION_3 = ['3']
|
||||
class WatcherShell(app.App):
|
||||
"""Watcher command line interface."""
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.client = None
|
||||
|
||||
@@ -194,12 +192,12 @@ class WatcherShell(app.App):
|
||||
except Exception as e:
|
||||
if not logging.getLogger('').handlers:
|
||||
logging.basicConfig()
|
||||
self.log.error('Exception raised: %s', str(e))
|
||||
LOG.error('Exception raised: %s', str(e))
|
||||
|
||||
return ret_val
|
||||
|
||||
finally:
|
||||
self.log.info("END return value: %s", ret_val)
|
||||
LOG.info("END return value: %s", ret_val)
|
||||
|
||||
|
||||
def main(argv=sys.argv[1:]):
|
||||
|
||||
@@ -28,7 +28,8 @@ 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']
|
||||
'Strategy', 'Efficacy indicators',
|
||||
'Hostname']
|
||||
audit_template_name = 'a' + uuidutils.generate_uuid()
|
||||
audit_uuid = None
|
||||
|
||||
@@ -94,52 +95,3 @@ class ActionPlanTests(base.TestCase):
|
||||
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):
|
||||
self.assertTrue(test_utils.call_until_true(
|
||||
func=functools.partial(
|
||||
self.has_audit_created, self.audit_uuid),
|
||||
duration=600,
|
||||
sleep_for=2
|
||||
))
|
||||
output = self.parse_show(
|
||||
self.watcher('actionplan list --audit %s' % self.audit_uuid))
|
||||
action_plan_uuid = list(output[0])[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()
|
||||
|
||||
@@ -30,7 +30,7 @@ class AuditTests(base.TestCase):
|
||||
detailed_list_fields = list_fields + ['Created At', 'Updated At',
|
||||
'Deleted At', 'Parameters',
|
||||
'Interval', 'Audit Scope',
|
||||
'Next Run Time']
|
||||
'Next Run Time', 'Hostname']
|
||||
audit_template_name = 'a' + uuidutils.generate_uuid()
|
||||
audit_uuid = None
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ 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':
|
||||
@@ -69,6 +71,13 @@ 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': (
|
||||
@@ -220,3 +229,10 @@ 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)
|
||||
|
||||
@@ -44,6 +44,7 @@ ACTION_PLAN_1 = {
|
||||
"description": "Dummy Global Efficacy2"}
|
||||
],
|
||||
'deleted_at': None,
|
||||
'hostname': ''
|
||||
}
|
||||
|
||||
ACTION_PLAN_2 = {
|
||||
@@ -63,6 +64,7 @@ ACTION_PLAN_2 = {
|
||||
"description": "Dummy Global Efficacy",
|
||||
}],
|
||||
'deleted_at': None,
|
||||
'hostname': ''
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ AUDIT_1 = {
|
||||
'auto_trigger': False,
|
||||
'next_run_time': None,
|
||||
'name': 'my_audit1',
|
||||
'hostname': '',
|
||||
}
|
||||
|
||||
AUDIT_2 = {
|
||||
@@ -88,6 +89,7 @@ AUDIT_2 = {
|
||||
'auto_trigger': False,
|
||||
'next_run_time': None,
|
||||
'name': 'my_audit2',
|
||||
'hostname': '',
|
||||
}
|
||||
|
||||
AUDIT_3 = {
|
||||
@@ -107,6 +109,7 @@ AUDIT_3 = {
|
||||
'auto_trigger': True,
|
||||
'next_run_time': None,
|
||||
'name': 'my_audit3',
|
||||
'hostname': '',
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,8 +27,13 @@ class ActionPlanManager(base.Manager):
|
||||
resource_class = ActionPlan
|
||||
|
||||
@staticmethod
|
||||
def _path(id=None):
|
||||
return '/v1/action_plans/%s' % id if id else '/v1/action_plans'
|
||||
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 list(self, audit=None, limit=None, sort_key=None,
|
||||
sort_dir=None, detail=False, marker=None):
|
||||
@@ -90,8 +95,7 @@ class ActionPlanManager(base.Manager):
|
||||
return self._update(self._path(action_plan_id), patch)
|
||||
|
||||
def start(self, action_plan_id):
|
||||
patch = [{'op': 'replace', 'value': 'PENDING', 'path': '/state'}]
|
||||
return self._update(self._path(action_plan_id), patch)
|
||||
return self._start(self._path(action_plan_id, 'start'))
|
||||
|
||||
def cancel(self, action_plan_id):
|
||||
action_plan = self.get(action_plan_id)
|
||||
|
||||
@@ -70,7 +70,7 @@ class ShowActionPlan(command.ShowOne):
|
||||
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()],
|
||||
data=[value for value in formatted_global_efficacy.values()],
|
||||
stdout=out,
|
||||
parsed_args=parsed_args,
|
||||
)
|
||||
@@ -200,47 +200,6 @@ class ListActionPlan(command.Lister):
|
||||
(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."""
|
||||
|
||||
|
||||
@@ -200,19 +200,10 @@ class CreateAudit(command.ShowOne):
|
||||
if k in field_list and v is not None)
|
||||
fields = common_utils.args_array_to_dict(fields, 'parameters')
|
||||
|
||||
if fields.get('goal'):
|
||||
if not uuidutils.is_uuid_like(fields['goal']):
|
||||
fields['goal'] = client.goal.get(fields['goal']).uuid
|
||||
|
||||
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
|
||||
# optional
|
||||
if fields.get('strategy'):
|
||||
if not uuidutils.is_uuid_like(fields['strategy']):
|
||||
fields['strategy'] = client.strategy.get(
|
||||
fields['strategy']).uuid
|
||||
|
||||
audit = client.audit.create(**fields)
|
||||
if audit.strategy_name is None:
|
||||
|
||||
@@ -32,12 +32,13 @@ AUDIT_TEMPLATE_SHORT_LIST_FIELD_LABELS = ['UUID', 'Name', 'Goal', 'Strategy']
|
||||
# Audit
|
||||
AUDIT_FIELDS = ['uuid', 'name', 'created_at', 'updated_at', 'deleted_at',
|
||||
'state', 'audit_type', 'parameters', 'interval', 'goal_name',
|
||||
'strategy_name', 'scope', 'auto_trigger', 'next_run_time']
|
||||
'strategy_name', 'scope', 'auto_trigger', 'next_run_time',
|
||||
'hostname']
|
||||
|
||||
AUDIT_FIELD_LABELS = ['UUID', 'Name', 'Created At', 'Updated At', 'Deleted At',
|
||||
'State', 'Audit Type', 'Parameters', 'Interval', 'Goal',
|
||||
'Strategy', 'Audit Scope', 'Auto Trigger',
|
||||
'Next Run Time']
|
||||
'Next Run Time', 'Hostname']
|
||||
|
||||
AUDIT_SHORT_LIST_FIELDS = ['uuid', 'name', 'audit_type',
|
||||
'state', 'goal_name', 'strategy_name',
|
||||
@@ -49,11 +50,12 @@ AUDIT_SHORT_LIST_FIELD_LABELS = ['UUID', 'Name', 'Audit Type', 'State', 'Goal',
|
||||
# Action Plan
|
||||
ACTION_PLAN_FIELDS = ['uuid', 'created_at', 'updated_at', 'deleted_at',
|
||||
'audit_uuid', 'strategy_name', 'state',
|
||||
'efficacy_indicators', 'global_efficacy']
|
||||
'efficacy_indicators', 'global_efficacy', 'hostname']
|
||||
|
||||
ACTION_PLAN_FIELD_LABELS = ['UUID', 'Created At', 'Updated At', 'Deleted At',
|
||||
'Audit', 'Strategy', 'State',
|
||||
'Efficacy indicators', 'Global efficacy']
|
||||
'Efficacy indicators', 'Global efficacy',
|
||||
'Hostname']
|
||||
|
||||
ACTION_PLAN_SHORT_LIST_FIELDS = ['uuid', 'audit_uuid', 'state',
|
||||
'updated_at', 'global_efficacy']
|
||||
|
||||
Reference in New Issue
Block a user