From 9aedaa6d8ab2a799f140fd7c01ad30342d0cc2aa Mon Sep 17 00:00:00 2001 From: rabi Date: Fri, 8 Oct 2021 11:04:00 +0530 Subject: [PATCH] Fix ServerGroup create Nova api has a different signature from microversion 2.64 onwards[1]. Also adds support_status for 'rules' property missed earlier in I8e77f54303298da00cbe719afccb449f10fe387c. [1] https://github.com/openstack/python-novaclient/blob/master/novaclient/v2/server_groups.py#L103-L104 Task: 43168 Change-Id: If7138c71044adadaf7de255a2fac463b57ff3c47 --- .../resources/openstack/nova/server_group.py | 39 ++++++++++--------- .../tests/openstack/nova/test_server_group.py | 10 +++-- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/heat/engine/resources/openstack/nova/server_group.py b/heat/engine/resources/openstack/nova/server_group.py index afc417bd0c..90a6ff171d 100644 --- a/heat/engine/resources/openstack/nova/server_group.py +++ b/heat/engine/resources/openstack/nova/server_group.py @@ -35,11 +35,13 @@ class ServerGroup(resource.Resource): entity = 'server_groups' PROPERTIES = ( - NAME, POLICIES, RULE + NAME, POLICIES, RULES ) = ( - 'name', 'policies', 'rule' + 'name', 'policies', 'rules' ) + _RULES = (MAX_SERVER_PER_HOST) = ('max_server_per_host') + properties_schema = { NAME: properties.Schema( properties.Schema.STRING, @@ -47,7 +49,7 @@ class ServerGroup(resource.Resource): ), POLICIES: properties.Schema( properties.Schema.LIST, - _('A list of string policies to apply. ' + _('A list of exactly one policy to apply. ' 'Defaults to anti-affinity.'), default=['anti-affinity'], constraints=[ @@ -59,11 +61,17 @@ class ServerGroup(resource.Resource): properties.Schema.STRING, ), ), - RULE: properties.Schema( + RULES: properties.Schema( properties.Schema.MAP, - _('A rule for the policy. Currently, only the ' - '"max_server_per_host" rule is supported for the ' - '"anti-affinity" policy.'), + _('Rules for a policy.'), + schema={ + MAX_SERVER_PER_HOST: properties.Schema( + properties.Schema.NUMBER, + _('Maximum servers in a group on a given host. ' + 'Rule for anti-affinity policy.') + ) + }, + support_status=support.SupportStatus(version='17.0.0'), ), } @@ -77,26 +85,19 @@ class ServerGroup(resource.Resource): msg = _('Required microversion for soft policies not supported.') raise exception.StackValidationFailed(message=msg) - if self.properties[self.RULE]: + if self.properties[self.RULES]: is_supported = self.client_plugin().is_version_supported( MICROVERSION_RULE) if not is_supported: - msg = _('Required microversion for rule not supported.') + msg = _('Required microversion for rules not supported.') raise exception.StackValidationFailed(message=msg) def handle_create(self): name = self.physical_resource_name() policies = self.properties[self.POLICIES] - if self.properties[self.RULE] and 'soft-affinity' in policies: - rule = self.properties[self.RULE] - client = self.client() - server_group = client.server_groups.create(name=name, - policies=policies, - rule=rule) - else: - client = self.client() - server_group = client.server_groups.create(name=name, - policies=policies) + rules = self.properties[self.RULES] + server_group = self.client().server_groups.create( + name=name, policy=policies[0], rules=rules) self.resource_id_set(server_group.id) def physical_resource_name(self): diff --git a/heat/tests/openstack/nova/test_server_group.py b/heat/tests/openstack/nova/test_server_group.py index 0a1e682e0f..4059e37c23 100644 --- a/heat/tests/openstack/nova/test_server_group.py +++ b/heat/tests/openstack/nova/test_server_group.py @@ -26,7 +26,9 @@ sg_template = { "type": "OS::Nova::ServerGroup", "properties": { "name": "test", - "policies": ["anti-affinity"] + "policies": ["anti-affinity"], + "rules": { + "max_server_per_host": 8} } } } @@ -68,7 +70,7 @@ class NovaServerGroupTest(common.HeatTestCase): name = 'test' n = name - def fake_create(name, policies): + def fake_create(name, policy, rules): self.assertGreater(len(name), 1) return FakeGroup(n) self.sg_mgr.create = fake_create @@ -81,7 +83,9 @@ class NovaServerGroupTest(common.HeatTestCase): self._create_sg('test') expected_args = () expected_kwargs = {'name': 'test', - 'policies': ["anti-affinity"], + 'policy': "anti-affinity", + 'rules': { + 'max_server_per_host': 8} } self.sg_mgr.create.assert_called_once_with(*expected_args, **expected_kwargs)