Add support for node tainted field

- Update supported microversion to 1.13
- Return node tainted field
- Support setting tainted field for node update

Depends-On: https://review.opendev.org/#/c/690755/
Change-Id: I1b36e6e9b8f743308d4a8361ad1f6564a462f4f3
This commit is contained in:
Duc Truong 2019-10-23 22:22:20 +00:00
parent f6453b4f0f
commit 4c39914798
5 changed files with 32 additions and 9 deletions

View File

@ -24,7 +24,7 @@ LOG = logging.getLogger(__name__)
DEFAULT_CLUSTERING_API_VERSION = '1' DEFAULT_CLUSTERING_API_VERSION = '1'
API_VERSION_OPTION = 'os_clustering_api_version' API_VERSION_OPTION = 'os_clustering_api_version'
API_NAME = 'clustering' API_NAME = 'clustering'
CURRENT_API_VERSION = '1.12' CURRENT_API_VERSION = '1.13'
def _make_key(service_type, key): def _make_key(service_type, key):

View File

@ -2,7 +2,7 @@ type: os.nova.server
version: 1.0 version: 1.0
properties: properties:
flavor: 1 flavor: 1
image: "cirros-0.3.5-x86_64-disk.img" image: "cirros-0.4.0-x86_64-disk"
networks: networks:
- network: private - network: private
metadata: metadata:

View File

@ -22,7 +22,7 @@ class NodeTest(base.OpenStackClientTestBase):
self.assertTableStruct(node_list, ['id', 'name', 'index', 'status', self.assertTableStruct(node_list, ['id', 'name', 'index', 'status',
'cluster_id', 'physical_id', 'cluster_id', 'physical_id',
'profile_name', 'created_at', 'profile_name', 'created_at',
'updated_at']) 'updated_at', 'tainted'])
def test_node_create(self): def test_node_create(self):
name = self.name_generate() name = self.name_generate()
@ -39,8 +39,10 @@ class NodeTest(base.OpenStackClientTestBase):
new_name = self.name_generate() new_name = self.name_generate()
pf_new = self.profile_create(new_name) pf_new = self.profile_create(new_name)
role = 'master' role = 'master'
cmd = ('cluster node update --name %s --role %s --profile %s %s' tainted = 'True'
% (new_name, role, pf_new['id'], n1['id'])) cmd = ('cluster node update --name %s --role %s --profile %s '
'--tainted %s %s'
% (new_name, role, pf_new['id'], tainted, n1['id']))
self.openstack(cmd) self.openstack(cmd)
self.wait_for_status(n1['id'], 'ACTIVE', 'node', 120) self.wait_for_status(n1['id'], 'ACTIVE', 'node', 120)
raw_node = self.openstack('cluster node show %s' % n1['id']) raw_node = self.openstack('cluster node show %s' % n1['id'])
@ -48,6 +50,7 @@ class NodeTest(base.OpenStackClientTestBase):
self.assertEqual(node_data['name'], new_name) self.assertEqual(node_data['name'], new_name)
self.assertNotEqual(node_data['name'], old_name) self.assertNotEqual(node_data['name'], old_name)
self.assertEqual(node_data['role'], role) self.assertEqual(node_data['role'], role)
self.assertEqual(node_data['tainted'], tainted)
self.assertEqual(node_data['profile_id'], pf_new['id']) self.assertEqual(node_data['profile_id'], pf_new['id'])
self.node_delete(new_name) self.node_delete(new_name)
self.addCleanup(self.profile_delete, pf['id']) self.addCleanup(self.profile_delete, pf['id'])

View File

@ -30,7 +30,8 @@ class TestNode(fakes.TestClusteringv1):
class TestNodeList(TestNode): class TestNodeList(TestNode):
columns = ['id', 'name', 'index', 'status', 'cluster_id', columns = ['id', 'name', 'index', 'status', 'cluster_id',
'physical_id', 'profile_name', 'created_at', 'updated_at'] 'physical_id', 'profile_name', 'created_at', 'updated_at',
'tainted']
defaults = { defaults = {
'cluster_id': None, 'cluster_id': None,
@ -60,6 +61,7 @@ class TestNodeList(TestNode):
role=None, role=None,
status="ACTIVE", status="ACTIVE",
status_reason="Creation succeeded", status_reason="Creation succeeded",
tainted=True,
updated_at=None, updated_at=None,
user_id="5e5bf8027826429c96af157f68dc9072" user_id="5e5bf8027826429c96af157f68dc9072"
) )
@ -160,6 +162,7 @@ class TestNodeShow(TestNode):
role=None, role=None,
status="ACTIVE", status="ACTIVE",
status_reason="Creation succeeded", status_reason="Creation succeeded",
tainted=True,
updated_at="2015-03-04T04:58:27", updated_at="2015-03-04T04:58:27",
user_id="5e5bf8027826429c96af157f68dc9072" user_id="5e5bf8027826429c96af157f68dc9072"
) )
@ -275,7 +278,8 @@ class TestNodeUpdate(TestNode):
"nk2": "nv2", "nk2": "nv2",
}, },
"profile_id": "new_profile", "profile_id": "new_profile",
"role": "new_role" "role": "new_role",
"tainted": True
} }
def setUp(self): def setUp(self):
@ -298,6 +302,7 @@ class TestNodeUpdate(TestNode):
role="master", role="master",
status="INIT", status="INIT",
status_reason="Initializing", status_reason="Initializing",
tainted=False,
updated_at=None, updated_at=None,
user_id="5e5bf8027826429c96af157f68dc9072" user_id="5e5bf8027826429c96af157f68dc9072"
) )
@ -310,7 +315,7 @@ class TestNodeUpdate(TestNode):
def test_node_update_defaults(self): def test_node_update_defaults(self):
arglist = ['--name', 'new_node', '--metadata', 'nk1=nv1;nk2=nv2', arglist = ['--name', 'new_node', '--metadata', 'nk1=nv1;nk2=nv2',
'--profile', 'new_profile', '--role', 'new_role', '--profile', 'new_profile', '--role', 'new_role',
'0df0931b'] '--tainted', 'True', '0df0931b']
parsed_args = self.check_parser(self.cmd, arglist, []) parsed_args = self.check_parser(self.cmd, arglist, [])
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.mock_client.update_node.assert_called_with( self.mock_client.update_node.assert_called_with(

View File

@ -86,7 +86,8 @@ class ListNode(command.Lister):
senlin_client = self.app.client_manager.clustering senlin_client = self.app.client_manager.clustering
columns = ['id', 'name', 'index', 'status', 'cluster_id', columns = ['id', 'name', 'index', 'status', 'cluster_id',
'physical_id', 'profile_name', 'created_at', 'updated_at'] 'physical_id', 'profile_name', 'created_at', 'updated_at',
'tainted']
queries = { queries = {
'cluster_id': parsed_args.cluster, 'cluster_id': parsed_args.cluster,
'sort': parsed_args.sort, 'sort': parsed_args.sort,
@ -254,6 +255,14 @@ class UpdateNode(command.ShowOne):
"can clean metadata "), "can clean metadata "),
action='append' action='append'
) )
parser.add_argument(
'--tainted',
metavar='<boolean>',
help=_("Whether the node should be marked as tainted. "
"If true, this node will be selected first for the next"
"cluster scale-in operation.")
)
parser.add_argument( parser.add_argument(
'node', 'node',
metavar='<node>', metavar='<node>',
@ -278,6 +287,12 @@ class UpdateNode(command.ShowOne):
'metadata': senlin_utils.format_parameters(parsed_args.metadata), 'metadata': senlin_utils.format_parameters(parsed_args.metadata),
} }
if parsed_args.tainted is not None:
attrs['tainted'] = strutils.bool_from_string(
parsed_args.tainted,
strict=True,
)
senlin_client.update_node(node.id, **attrs) senlin_client.update_node(node.id, **attrs)
return _show_node(senlin_client, node.id) return _show_node(senlin_client, node.id)