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:
Alexander Chadin
2017-11-28 17:28:54 +03:00
parent bf706365ea
commit a907c2d0cd
7 changed files with 106 additions and 3 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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']

View File

@@ -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))

View File

@@ -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."""