Browse Source

Merge "Only allow zero node count from microversion 1.10"

changes/42/767242/7
Zuul 1 month ago
committed by Gerrit Code Review
parent
commit
3f40b9a1b7
5 changed files with 155 additions and 20 deletions
  1. +38
    -1
      magnum/api/controllers/v1/cluster.py
  2. +22
    -2
      magnum/api/controllers/v1/cluster_actions.py
  3. +10
    -0
      magnum/common/exception.py
  4. +38
    -3
      magnum/tests/unit/api/controllers/v1/test_cluster.py
  5. +47
    -14
      magnum/tests/unit/api/controllers/v1/test_cluster_actions.py

+ 38
- 1
magnum/api/controllers/v1/cluster.py View File

@ -490,10 +490,23 @@ class ClustersController(base.Controller):
"one.") % cluster_limit
raise exception.ResourceLimitExceeded(msg=msg)
@base.Controller.api_version("1.1", "1.9")
@expose.expose(ClusterID, body=Cluster, status_code=202)
@validation.enforce_cluster_type_supported()
@validation.enforce_cluster_volume_storage_size()
def post(self, cluster):
if cluster.node_count == 0:
raise exception.ZeroNodeCountNotSupported()
return self._post(cluster)
@base.Controller.api_version("1.10") # noqa
@expose.expose(ClusterID, body=Cluster, status_code=202)
@validation.enforce_cluster_type_supported()
@validation.enforce_cluster_volume_storage_size()
def post(self, cluster): # noqa
return self._post(cluster)
def _post(self, cluster):
"""Create a new cluster.
:param cluster: a cluster within the request body.
@ -585,12 +598,36 @@ class ClustersController(base.Controller):
(cluster, node_count,
health_status,
health_status_reason) = self._patch(cluster_ident, patch)
if node_count == 0:
raise exception.ZeroNodeCountNotSupported()
pecan.request.rpcapi.cluster_update_async(cluster, node_count,
health_status,
health_status_reason)
return ClusterID(cluster.uuid)
@base.Controller.api_version("1.3") # noqa
@base.Controller.api_version("1.3", "1.9") # noqa
@wsme.validate(types.uuid, bool, [ClusterPatchType])
@expose.expose(ClusterID, types.uuid_or_name, types.boolean,
body=[ClusterPatchType], status_code=202)
def patch(self, cluster_ident, rollback=False, patch=None): # noqa
"""Update an existing Cluster.
:param cluster_ident: UUID or logical name of a cluster.
:param rollback: whether to rollback cluster on update failure.
:param patch: a json PATCH document to apply to this cluster.
"""
(cluster, node_count,
health_status,
health_status_reason) = self._patch(cluster_ident, patch)
if node_count == 0:
raise exception.ZeroNodeCountNotSupported()
pecan.request.rpcapi.cluster_update_async(cluster, node_count,
health_status,
health_status_reason,
rollback)
return ClusterID(cluster.uuid)
@base.Controller.api_version("1.10") # noqa
@wsme.validate(types.uuid, bool, [ClusterPatchType])
@expose.expose(ClusterID, types.uuid_or_name, types.boolean,
body=[ClusterPatchType], status_code=202)


+ 22
- 2
magnum/api/controllers/v1/cluster_actions.py View File

@ -81,10 +81,21 @@ class ActionsController(base.Controller):
'upgrade': ['POST']
}
@base.Controller.api_version("1.7")
@base.Controller.api_version("1.7", "1.9")
@expose.expose(ClusterID, types.uuid_or_name,
body=ClusterResizeRequest, status_code=202)
def resize(self, cluster_ident, cluster_resize_req):
if cluster_resize_req.node_count == 0:
raise exception.ZeroNodeCountNotSupported()
return self._resize(cluster_ident, cluster_resize_req)
@base.Controller.api_version("1.10") # noqa
@expose.expose(ClusterID, types.uuid_or_name,
body=ClusterResizeRequest, status_code=202)
def resize(self, cluster_ident, cluster_resize_req): # noqa
return self._resize(cluster_ident, cluster_resize_req)
def _resize(self, cluster_ident, cluster_resize_req):
"""Resize a cluster.
:param cluster_ident: UUID of a cluster or logical name of the cluster.
@ -126,10 +137,19 @@ class ActionsController(base.Controller):
nodegroup)
return ClusterID(cluster.uuid)
@base.Controller.api_version("1.8")
@base.Controller.api_version("1.7", "1.7")
@expose.expose(ClusterID, types.uuid_or_name,
body=ClusterUpgradeRequest, status_code=202)
def upgrade(self, cluster_ident, cluster_upgrade_req):
raise exception.ClusterUpgradeNotSupported()
@base.Controller.api_version("1.8") # noqa
@expose.expose(ClusterID, types.uuid_or_name,
body=ClusterUpgradeRequest, status_code=202)
def upgrade(self, cluster_ident, cluster_upgrade_req): # noqa
return self._upgrade(cluster_ident, cluster_upgrade_req)
def _upgrade(self, cluster_ident, cluster_upgrade_req):
"""Upgrade a cluster.
:param cluster_ident: UUID of a cluster or logical name of the cluster.


+ 10
- 0
magnum/common/exception.py View File

@ -441,6 +441,16 @@ class MasterNGResizeNotSupported(NotSupported):
message = _("Resizing a master nodegroup is not supported.")
class ZeroNodeCountNotSupported(NotSupported):
message = _("Resizing a nodegroup to zero is not supported in the "
"provided microversion.")
class ClusterUpgradeNotSupported(NotSupported):
message = _("Cluster upgrade is not supported in the "
"provided microversion.")
class NGResizeOutBounds(Invalid):
message = _("Resizing %(nodegroup)s outside the allowed range: "
"min_node_count = %(min_nc)s, "


+ 38
- 3
magnum/tests/unit/api/controllers/v1/test_cluster.py View File

@ -511,6 +511,30 @@ class TestPatch(api_base.FunctionalTest):
self.cluster_obj.health_status_reason, False)
self.assertEqual(202, response.status_code)
def test_update_cluster_with_zero_node_count_fail(self):
node_count = 0
response = self.patch_json(
'/clusters/%s' % self.cluster_obj.uuid,
[{'path': '/node_count', 'value': node_count,
'op': 'replace'}],
headers={'OpenStack-API-Version': 'container-infra 1.9'},
expect_errors=True)
self.assertEqual(400, response.status_code)
def test_update_cluster_with_zero_node_count(self):
node_count = 0
response = self.patch_json(
'/clusters/%s' % self.cluster_obj.uuid,
[{'path': '/node_count', 'value': node_count,
'op': 'replace'}],
headers={'OpenStack-API-Version': 'container-infra 1.10'})
self.mock_cluster_update.assert_called_once_with(
mock.ANY, node_count, self.cluster_obj.health_status,
self.cluster_obj.health_status_reason, False)
self.assertEqual(202, response.status_code)
def test_remove_ok(self):
response = self.get_json('/clusters/%s' % self.cluster_obj.uuid)
self.assertIsNotNone(response['name'])
@ -678,10 +702,21 @@ class TestPost(api_base.FunctionalTest):
self.assertEqual('application/json', response.content_type)
self.assertEqual(202, response.status_int)
def test_create_cluster_with_node_count_zero(self):
def test_create_cluster_with_zero_node_count_fail(self):
bdict = apiutils.cluster_post_data()
bdict['node_count'] = 0
response = self.post_json('/clusters', bdict, expect_errors=True)
response = self.post_json('/clusters', bdict, expect_errors=True,
headers={"Openstack-Api-Version":
"container-infra 1.9"})
self.assertEqual('application/json', response.content_type)
self.assertEqual(400, response.status_int)
def test_create_cluster_with_zero_node_count(self):
bdict = apiutils.cluster_post_data()
bdict['node_count'] = 0
response = self.post_json('/clusters', bdict,
headers={"Openstack-Api-Version":
"container-infra 1.10"})
self.assertEqual('application/json', response.content_type)
self.assertEqual(202, response.status_int)
@ -696,7 +731,7 @@ class TestPost(api_base.FunctionalTest):
def test_create_cluster_with_no_node_count(self):
bdict = apiutils.cluster_post_data()
del bdict['node_count']
response = self.post_json('/clusters', bdict, expect_errors=True)
response = self.post_json('/clusters', bdict)
self.assertEqual('application/json', response.content_type)
self.assertEqual(202, response.status_int)


+ 47
- 14
magnum/tests/unit/api/controllers/v1/test_cluster_actions.py View File

@ -46,7 +46,7 @@ class TestClusterResize(api_base.FunctionalTest):
self.cluster_obj.uuid,
{"node_count": new_node_count},
headers={"Openstack-Api-Version":
"container-infra latest"})
"container-infra 1.7"})
self.assertEqual(202, response.status_code)
response = self.get_json('/clusters/%s' % self.cluster_obj.uuid)
@ -69,7 +69,7 @@ class TestClusterResize(api_base.FunctionalTest):
self.cluster_obj.uuid,
cluster_resize_req,
headers={"Openstack-Api-Version":
"container-infra latest"})
"container-infra 1.9"})
self.assertEqual(202, response.status_code)
response = self.get_json('/clusters/%s' % self.cluster_obj.uuid)
@ -89,7 +89,7 @@ class TestClusterResize(api_base.FunctionalTest):
self.cluster_obj.uuid,
cluster_resize_req,
headers={"Openstack-Api-Version":
"container-infra latest"},
"container-infra 1.9"},
expect_errors=True)
self.assertEqual(400, response.status_code)
@ -106,7 +106,7 @@ class TestClusterResize(api_base.FunctionalTest):
self.cluster_obj.uuid,
cluster_resize_req,
headers={"Openstack-Api-Version":
"container-infra latest"},
"container-infra 1.9"},
expect_errors=True)
self.assertEqual(400, response.status_code)
@ -123,10 +123,43 @@ class TestClusterResize(api_base.FunctionalTest):
self.cluster_obj.uuid,
cluster_resize_req,
headers={"Openstack-Api-Version":
"container-infra latest"},
"container-infra 1.9"},
expect_errors=True)
self.assertEqual(400, response.status_code)
def test_resize_with_zero_node_count_fail(self):
new_node_count = 0
nodegroup = self.cluster_obj.default_ng_worker
nodegroup.min_node_count = 0
nodegroup.save()
cluster_resize_req = {
"node_count": new_node_count,
"nodegroup": nodegroup.uuid
}
response = self.post_json('/clusters/%s/actions/resize' %
self.cluster_obj.uuid,
cluster_resize_req,
headers={"Openstack-Api-Version":
"container-infra 1.9"},
expect_errors=True)
self.assertEqual(400, response.status_code)
def test_resize_with_zero_node_count(self):
new_node_count = 0
nodegroup = self.cluster_obj.default_ng_worker
nodegroup.min_node_count = 0
nodegroup.save()
cluster_resize_req = {
"node_count": new_node_count,
"nodegroup": nodegroup.uuid
}
response = self.post_json('/clusters/%s/actions/resize' %
self.cluster_obj.uuid,
cluster_resize_req,
headers={"Openstack-Api-Version":
"container-infra 1.10"})
self.assertEqual(202, response.status_code)
class TestClusterUpgrade(api_base.FunctionalTest):
def setUp(self):
@ -162,7 +195,7 @@ class TestClusterUpgrade(api_base.FunctionalTest):
self.cluster_obj.uuid,
cluster_upgrade_req,
headers={"Openstack-Api-Version":
"container-infra latest"})
"container-infra 1.8"})
self.assertEqual(202, response.status_code)
def test_upgrade_cluster_as_admin(self):
@ -193,7 +226,7 @@ class TestClusterUpgrade(api_base.FunctionalTest):
'/clusters/%s/actions/upgrade' %
cluster_uuid,
cluster_upgrade_req,
headers={"Openstack-Api-Version": "container-infra latest"})
headers={"Openstack-Api-Version": "container-infra 1.8"})
self.assertEqual(202, response.status_int)
@ -206,7 +239,7 @@ class TestClusterUpgrade(api_base.FunctionalTest):
self.cluster_obj.uuid,
cluster_upgrade_req,
headers={"Openstack-Api-Version":
"container-infra latest"})
"container-infra 1.9"})
self.assertEqual(202, response.status_code)
def test_upgrade_default_master(self):
@ -218,7 +251,7 @@ class TestClusterUpgrade(api_base.FunctionalTest):
self.cluster_obj.uuid,
cluster_upgrade_req,
headers={"Openstack-Api-Version":
"container-infra latest"})
"container-infra 1.9"})
self.assertEqual(202, response.status_code)
def test_upgrade_non_default_ng(self):
@ -230,7 +263,7 @@ class TestClusterUpgrade(api_base.FunctionalTest):
self.cluster_obj.uuid,
cluster_upgrade_req,
headers={"Openstack-Api-Version":
"container-infra latest"})
"container-infra 1.9"})
self.assertEqual(202, response.status_code)
def test_upgrade_cluster_not_found(self):
@ -240,7 +273,7 @@ class TestClusterUpgrade(api_base.FunctionalTest):
response = self.post_json('/clusters/not_there/actions/upgrade',
cluster_upgrade_req,
headers={"Openstack-Api-Version":
"container-infra latest"},
"container-infra 1.8"},
expect_errors=True)
self.assertEqual(404, response.status_code)
@ -252,7 +285,7 @@ class TestClusterUpgrade(api_base.FunctionalTest):
self.cluster_obj.uuid,
cluster_upgrade_req,
headers={"Openstack-Api-Version":
"container-infra latest"},
"container-infra 1.8"},
expect_errors=True)
self.assertEqual(404, response.status_code)
@ -265,7 +298,7 @@ class TestClusterUpgrade(api_base.FunctionalTest):
self.cluster_obj.uuid,
cluster_upgrade_req,
headers={"Openstack-Api-Version":
"container-infra latest"},
"container-infra 1.9"},
expect_errors=True)
self.assertEqual(404, response.status_code)
@ -278,6 +311,6 @@ class TestClusterUpgrade(api_base.FunctionalTest):
self.cluster_obj.uuid,
cluster_upgrade_req,
headers={"Openstack-Api-Version":
"container-infra latest"},
"container-infra 1.9"},
expect_errors=True)
self.assertEqual(409, response.status_code)

Loading…
Cancel
Save