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:
@@ -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.')),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user