Add strategy state command
This patch set adds command "strategy state" that allows to request strategy requirements to run. Partially-Implements: blueprint check-strategy-requirements Change-Id: I327cc4f5a887f62af700bd646576caa036faaf75
This commit is contained in:
@@ -36,6 +36,7 @@ openstack.infra_optim.v1 =
|
|||||||
|
|
||||||
optimize_strategy_show = watcherclient.v1.strategy_shell:ShowStrategy
|
optimize_strategy_show = watcherclient.v1.strategy_shell:ShowStrategy
|
||||||
optimize_strategy_list = watcherclient.v1.strategy_shell:ListStrategy
|
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_show = watcherclient.v1.audit_template_shell:ShowAuditTemplate
|
||||||
optimize_audittemplate_list = watcherclient.v1.audit_template_shell:ListAuditTemplate
|
optimize_audittemplate_list = watcherclient.v1.audit_template_shell:ListAuditTemplate
|
||||||
@@ -72,6 +73,7 @@ watcherclient.v1 =
|
|||||||
|
|
||||||
strategy_show = watcherclient.v1.strategy_shell:ShowStrategy
|
strategy_show = watcherclient.v1.strategy_shell:ShowStrategy
|
||||||
strategy_list = watcherclient.v1.strategy_shell:ListStrategy
|
strategy_list = watcherclient.v1.strategy_shell:ListStrategy
|
||||||
|
strategy_state = watcherclient.v1.strategy_shell:StateStrategy
|
||||||
|
|
||||||
audittemplate_show = watcherclient.v1.audit_template_shell:ShowAuditTemplate
|
audittemplate_show = watcherclient.v1.audit_template_shell:ShowAuditTemplate
|
||||||
audittemplate_list = watcherclient.v1.audit_template_shell:ListAuditTemplate
|
audittemplate_list = watcherclient.v1.audit_template_shell:ListAuditTemplate
|
||||||
|
@@ -20,7 +20,9 @@ class StrategyTests(base.TestCase):
|
|||||||
"""Functional tests for strategy."""
|
"""Functional tests for strategy."""
|
||||||
|
|
||||||
dummy_name = 'dummy'
|
dummy_name = 'dummy'
|
||||||
|
basic_strategy = 'basic'
|
||||||
list_fields = ['UUID', 'Name', 'Display name', 'Goal']
|
list_fields = ['UUID', 'Name', 'Display name', 'Goal']
|
||||||
|
state_fields = ['Datasource', 'Metrics', 'CDM', 'Name']
|
||||||
|
|
||||||
def test_strategy_list(self):
|
def test_strategy_list(self):
|
||||||
raw_output = self.watcher('strategy list')
|
raw_output = self.watcher('strategy list')
|
||||||
@@ -39,3 +41,8 @@ class StrategyTests(base.TestCase):
|
|||||||
self.assert_table_structure([raw_output],
|
self.assert_table_structure([raw_output],
|
||||||
self.list_fields + ['Parameters spec'])
|
self.list_fields + ['Parameters spec'])
|
||||||
self.assertNotIn('basic', raw_output)
|
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)
|
||||||
|
@@ -63,6 +63,13 @@ fake_responses = {
|
|||||||
STRATEGY1,
|
STRATEGY1,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
'/v1/strategies/%s/state' % STRATEGY1['name']:
|
||||||
|
{
|
||||||
|
'GET': (
|
||||||
|
{},
|
||||||
|
STRATEGY1,
|
||||||
|
),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fake_responses_pagination = {
|
fake_responses_pagination = {
|
||||||
@@ -180,3 +187,10 @@ class StrategyManagerTest(testtools.TestCase):
|
|||||||
]
|
]
|
||||||
self.assertEqual(expect, self.api.calls)
|
self.assertEqual(expect, self.api.calls)
|
||||||
self.assertEqual(STRATEGY1['name'], strategy.name)
|
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)
|
||||||
|
@@ -17,6 +17,8 @@ import datetime
|
|||||||
import mock
|
import mock
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
from oslo_serialization import jsonutils
|
||||||
|
|
||||||
from watcherclient import shell
|
from watcherclient import shell
|
||||||
from watcherclient.tests.unit.v1 import base
|
from watcherclient.tests.unit.v1 import base
|
||||||
from watcherclient import v1 as resource
|
from watcherclient import v1 as resource
|
||||||
@@ -54,6 +56,8 @@ class StrategyShellTest(base.CommandTestCase):
|
|||||||
resource_fields.STRATEGY_SHORT_LIST_FIELD_LABELS)
|
resource_fields.STRATEGY_SHORT_LIST_FIELD_LABELS)
|
||||||
FIELDS = resource_fields.STRATEGY_FIELDS
|
FIELDS = resource_fields.STRATEGY_FIELDS
|
||||||
FIELD_LABELS = resource_fields.STRATEGY_FIELD_LABELS
|
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):
|
def setUp(self):
|
||||||
super(self.__class__, self).setUp()
|
super(self.__class__, self).setUp()
|
||||||
@@ -155,3 +159,33 @@ class StrategyShellTest(base.CommandTestCase):
|
|||||||
result)
|
result)
|
||||||
self.m_strategy_mgr.get.assert_called_once_with(
|
self.m_strategy_mgr.get.assert_called_once_with(
|
||||||
'f8e47706-efcf-49a4-a5c4-af604eb492f2')
|
'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)
|
||||||
|
@@ -99,6 +99,10 @@ STRATEGY_SHORT_LIST_FIELDS = ['uuid', 'name', 'display_name', 'goal_name']
|
|||||||
|
|
||||||
STRATEGY_SHORT_LIST_FIELD_LABELS = ['UUID', 'Name', 'Display name', 'Goal']
|
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
|
||||||
METRIC_COLLECTOR_FIELDS = ['uuid', 'created_at', 'updated_at', 'deleted_at',
|
METRIC_COLLECTOR_FIELDS = ['uuid', 'created_at', 'updated_at', 'deleted_at',
|
||||||
'endpoint', 'category']
|
'endpoint', 'category']
|
||||||
|
@@ -28,9 +28,14 @@ class StrategyManager(base.Manager):
|
|||||||
resource_class = Strategy
|
resource_class = Strategy
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _path(strategy=None):
|
def _path(strategy=None, state=False):
|
||||||
return ('/v1/strategies/%s' % strategy
|
if strategy:
|
||||||
if strategy else '/v1/strategies')
|
path = '/v1/strategies/%s' % strategy
|
||||||
|
if state:
|
||||||
|
path = '/v1/strategies/%s/state' % strategy
|
||||||
|
else:
|
||||||
|
path = '/v1/strategies'
|
||||||
|
return path
|
||||||
|
|
||||||
def list(self, goal=None, limit=None, sort_key=None,
|
def list(self, goal=None, limit=None, sort_key=None,
|
||||||
sort_dir=None, detail=False):
|
sort_dir=None, detail=False):
|
||||||
@@ -82,3 +87,6 @@ class StrategyManager(base.Manager):
|
|||||||
return self._list(self._path(strategy))[0]
|
return self._list(self._path(strategy))[0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def state(self, strategy):
|
||||||
|
return self._list(self._path(strategy, state=True))
|
||||||
|
@@ -57,6 +57,40 @@ class ShowStrategy(command.ShowOne):
|
|||||||
return column_headers, utils.get_item_properties(strategy, columns)
|
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):
|
class ListStrategy(command.Lister):
|
||||||
"""List information on retrieved strategies."""
|
"""List information on retrieved strategies."""
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user