Use policy defaults when not specified for attach

This patch enables cluster policy attach operation to use the default
'cooldown', 'level' from the policy object if not specified. For the
'priority' parameter, we introduce a new configuration option and set it
to 100. For 'enabled', we set the default to 'True'.

Change-Id: I3142773c9b4234bcf7dba43958a9d4b3cf9bdcea
Closes-Bug: 1465565
This commit is contained in:
tengqm
2015-07-14 02:15:28 -04:00
parent e3cc428167
commit cf96f8df16
6 changed files with 109 additions and 48 deletions

View File

@@ -65,6 +65,9 @@ engine_opts = [
cfg.IntOpt('default_action_timeout',
default=3600,
help=_('Timeout in seconds for actions.')),
cfg.IntOpt('default_policy_priority',
default=50,
help=_('Default priority for policies attached to a cluster.')),
cfg.IntOpt('lock_retry_times',
default=3,
help=_('Number of times trying to grab a lock.')),

View File

@@ -23,6 +23,7 @@ from senlin.common import scaleutils
from senlin.db import api as db_api
from senlin.engine.actions import base
from senlin.engine import cluster as cluster_mod
from senlin.engine import cluster_policy as cp_mod
from senlin.engine import dispatcher
from senlin.engine import node as node_mod
from senlin.engine import scheduler
@@ -617,18 +618,18 @@ class ClusterAction(base.Action):
# Initialize data field of cluster_policy object with information
# generated during policy attaching
values = {
'cooldown': self.inputs.get('cooldown', policy.cooldown),
'level': self.inputs.get('level', policy.level),
'priority': self.inputs.get('priority', 50),
'enabled': self.inputs.get('enabled', True),
'priority': self.inputs['priority'],
'cooldown': self.inputs['cooldown'],
'level': self.inputs['level'],
'enabled': self.inputs['enabled'],
'data': data,
}
db_api.cluster_policy_attach(self.context, cluster.id, policy_id,
values)
cp = cp_mod.ClusterPolicy(cluster.id, policy_id, **values)
cp.store(self.context)
cluster.add_policy(policy)
return self.RES_OK, 'Policy attached'
return self.RES_OK, _('Policy attached.')
def do_detach_policy(self, cluster):
policy_id = self.inputs.get('policy_id', None)
@@ -638,15 +639,12 @@ class ClusterAction(base.Action):
policy = policy_mod.Policy.load(self.context, policy_id)
res, data = policy.detach(cluster.id, self)
if not res:
return self.RES_ERROR, 'Failed detaching policy'
if res == self.RES_CANCEL:
# Action is canceled during progress, reason is stored in data
return res, data
return self.RES_ERROR, _('Failed detaching policy.')
db_api.cluster_policy_detach(self.context, cluster.id, policy_id)
cluster.remove_policy(policy)
return self.RES_OK, 'Policy detached'
return self.RES_OK, _('Policy detached.')
def do_update_policy(self, cluster):
policy_id = self.inputs.get('policy_id', None)
@@ -670,7 +668,7 @@ class ClusterAction(base.Action):
db_api.cluster_policy_update(self.context, cluster.id, policy_id,
values)
return self.RES_OK, 'Policy updated'
return self.RES_OK, _('Policy updated.')
def _execute(self, cluster):
# do pre-action policy checking
@@ -718,7 +716,7 @@ class ClusterAction(base.Action):
senlin_lock.CLUSTER_SCOPE,
forced)
if not res:
return self.RES_ERROR, _('Failed locking cluster')
return self.RES_ERROR, _('Failed in locking cluster.')
try:
res, reason = self._execute(cluster)

View File

@@ -18,24 +18,21 @@ from senlin.db import api as db_api
LOG = logging.getLogger(__name__)
# TODO(Qiming): expose configuration options for default values for
# policy attachments, i.e. cooldown, priority, level, enabled
class ClusterPolicy(object):
'''Object representing a binding between a cluster and a policy.
This object also records the runtime data of a policy, if any.
'''
def __init__(self, cluster_id, policy_id, context=None, **kwargs):
def __init__(self, cluster_id, policy_id, **kwargs):
self.id = kwargs.get('id', None)
self.cluster_id = cluster_id
self.policy_id = policy_id
self.cooldown = kwargs.get('cooldown', 0)
self.priority = kwargs.get('priority', 50)
self.level = kwargs.get('level', 50)
self.enabled = kwargs.get('enabled', True)
self.priority = kwargs.get('priority')
self.cooldown = kwargs.get('cooldown')
self.level = kwargs.get('level')
self.enabled = kwargs.get('enabled')
self.data = kwargs.get('data', {})
self.last_op = kwargs.get('last_op', None)
@@ -47,8 +44,8 @@ class ClusterPolicy(object):
def store(self, context):
'''Store the binding record into database table.'''
values = {
'cooldown': self.cooldown,
'priority': self.priority,
'cooldown': self.cooldown,
'level': self.level,
'enabled': self.enabled,
'data': self.data,
@@ -61,7 +58,11 @@ class ClusterPolicy(object):
else:
binding = db_api.cluster_policy_attach(context, self.cluster_id,
self.policy_id, values)
self.cluster_name = binding.cluster.name
self.policy_name = binding.policy.name
self.policy_type = binding.policy.type
self.id = binding.id
return self.id
@classmethod
@@ -73,8 +74,8 @@ class ClusterPolicy(object):
'''
kwargs = {
'id': record.id,
'cooldown': record.cooldown,
'priority': record.priority,
'cooldown': record.cooldown,
'level': record.level,
'enabled': record.enabled,
'data': record.data,

View File

@@ -1071,10 +1071,16 @@ class EngineService(service.Service):
inputs = {
'policy_id': db_policy.id,
'priority': utils.parse_int_param('priority', priority) or 50,
'level': utils.parse_int_param('level', level) or 50,
'cooldown': utils.parse_int_param('cooldown', cooldown) or 0,
'enabled': utils.parse_bool_param('enabled', enabled),
'priority':
utils.parse_int_param('priority', priority) or
cfg.CONF.default_policy_priority,
'level':
utils.parse_int_param('level', level) or db_policy.level,
'cooldown':
utils.parse_int_param('cooldown', cooldown) or
db_policy.cooldown,
'enabled':
utils.parse_bool_param('enabled', enabled) or True,
}
action_name = 'cluster_attach_policy_%s' % db_cluster.id[:8]

View File

@@ -11,6 +11,7 @@
# under the License.
import mock
from oslo_config import cfg
from oslo_messaging.rpc import dispatcher as rpc
import six
@@ -46,7 +47,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
self.policy = self.eng.policy_create(
self.ctx, 'policy_1', 'TestPolicy',
spec={'KEY1': 'string'}, cooldown=60, level=50)
spec={'KEY1': 'string'}, cooldown=6, level=5)
self.cluster = self.eng.cluster_create(self.ctx, 'c-1', 0,
self.profile['id'])
@@ -64,8 +65,8 @@ class ClusterPolicyTest(base.SenlinTestCase):
def test_cluster_policy_attach(self, notify):
cluster_id = self.cluster['id']
policy_id = self.policy['id']
action = self.eng.cluster_policy_attach(self.ctx, cluster_id,
policy_id)
action = self.eng.cluster_policy_attach(
self.ctx, cluster_id, policy_id, 50, 50, 40, False)
action_id = action['action']
action = db_api.action_get(self.ctx, action_id)
@@ -74,7 +75,32 @@ class ClusterPolicyTest(base.SenlinTestCase):
'policy_id': policy_id,
'priority': 50,
'level': 50,
'cooldown': 0,
'cooldown': 40,
'enabled': True
}
self._verify_action(action, 'CLUSTER_ATTACH_POLICY',
'cluster_attach_policy_%s' % cluster_id[:8],
cluster_id, cause=action_mod.CAUSE_RPC,
inputs=inputs)
notify.assert_called_with(self.ctx, action_id=action_id)
self.assertEqual(1, notify.call_count)
@mock.patch.object(dispatcher, 'start_action')
def test_cluster_policy_attach_using_default(self, notify):
cluster_id = self.cluster['id']
policy_id = self.policy['id']
action = self.eng.cluster_policy_attach(self.ctx, cluster_id,
policy_id)
action_id = action['action']
action = db_api.action_get(self.ctx, action_id)
self.assertIsNotNone(action)
inputs = {
'policy_id': policy_id,
'priority': cfg.CONF.default_policy_priority,
'level': self.policy['level'],
'cooldown': self.policy['cooldown'],
'enabled': True
}
self._verify_action(action, 'CLUSTER_ATTACH_POLICY',

View File

@@ -27,14 +27,20 @@ class TestClusterPolicy(base.SenlinTestCase):
self.context = utils.dummy_context()
def test_cluster_policy_init(self):
cp = cpm.ClusterPolicy('fake-cluster', 'fake-policy')
values = {
'priority': 12,
'cooldown': 34,
'level': 56,
'enabled': True,
}
cp = cpm.ClusterPolicy('fake-cluster', 'fake-policy', **values)
self.assertIsNone(cp.id)
self.assertEqual('fake-cluster', cp.cluster_id)
self.assertEqual('fake-policy', cp.policy_id)
self.assertEqual(0, cp.cooldown)
self.assertEqual(50, cp.priority)
self.assertEqual(50, cp.level)
self.assertEqual(12, cp.priority)
self.assertEqual(34, cp.cooldown)
self.assertEqual(56, cp.level)
self.assertTrue(True, cp.enabled)
self.assertEqual({}, cp.data)
self.assertIsNone(cp.last_op)
@@ -43,7 +49,15 @@ class TestClusterPolicy(base.SenlinTestCase):
self.assertEqual('', cp.policy_name)
def test_cluster_policy_store(self):
cp = cpm.ClusterPolicy('fake-cluster', 'fake-policy')
cluster = self._create_cluster('fake-cluster')
policy = self._create_policy('fake-policy')
values = {
'priority': 12,
'cooldown': 34,
'level': 56,
'enabled': True,
}
cp = cpm.ClusterPolicy(cluster.id, policy.id, **values)
self.assertIsNone(cp.id)
cp_id = cp.store(self.context)
self.assertIsNotNone(cp_id)
@@ -52,9 +66,9 @@ class TestClusterPolicy(base.SenlinTestCase):
'fake-policy')
self.assertIsNotNone(result)
self.assertEqual(0, result.cooldown)
self.assertEqual(50, result.priority)
self.assertEqual(50, result.level)
self.assertEqual(12, result.priority)
self.assertEqual(34, result.cooldown)
self.assertEqual(56, result.level)
self.assertTrue(result.enabled)
self.assertEqual({}, result.data)
self.assertIsNone(result.last_op)
@@ -110,7 +124,14 @@ class TestClusterPolicy(base.SenlinTestCase):
cluster = self._create_cluster('CLUSTER_ID')
policy = self._create_policy('POLICY_ID')
cp = cpm.ClusterPolicy(cluster.id, policy.id)
values = {
'priority': 12,
'cooldown': 34,
'level': 56,
'enabled': True,
}
cp = cpm.ClusterPolicy(cluster.id, policy.id, **values)
cp_id = cp.store(self.context)
result = cpm.ClusterPolicy.load(self.context, 'CLUSTER_ID',
@@ -119,9 +140,9 @@ class TestClusterPolicy(base.SenlinTestCase):
self.assertEqual(cp_id, result.id)
self.assertEqual(cluster.id, result.cluster_id)
self.assertEqual(policy.id, result.policy_id)
self.assertEqual(0, result.cooldown)
self.assertEqual(50, result.priority)
self.assertEqual(50, result.level)
self.assertEqual(12, result.priority)
self.assertEqual(34, result.cooldown)
self.assertEqual(56, result.level)
self.assertTrue(True, result.enabled)
self.assertEqual({}, result.data)
self.assertIsNone(result.last_op)
@@ -152,15 +173,21 @@ class TestClusterPolicy(base.SenlinTestCase):
self.assertEqual('CLUSTER', result[1].cluster_id)
def test_cluster_policy_to_dict(self):
cp = cpm.ClusterPolicy('fake-cluster', 'fake-policy')
values = {
'priority': 12,
'cooldown': 34,
'level': 56,
'enabled': True,
}
cp = cpm.ClusterPolicy('fake-cluster', 'fake-policy', **values)
self.assertIsNone(cp.id)
expected = {
'id': None,
'cluster_id': 'fake-cluster',
'policy_id': 'fake-policy',
'cooldown': 0,
'priority': 50,
'level': 50,
'priority': 12,
'cooldown': 34,
'level': 56,
'enabled': True,
'data': {},
'last_op': None,