Improve Magnum cluster templates functions

There are two improvements in this patch:

1. Add alias to rename xxx_cluster_template to xxx_coe_cluster_template.
This a pre clean so that we can support xxx_coe_cluster to avoid conflits
with Senlin's functions.

2. Support new Magnum API endpoints, /clustertemplates and /clusters.
Those two endpoints added in Newton.

Change-Id: I78c37f0df8f63a13c534f3dcaca2e27073f0d730
This commit is contained in:
Feilong Wang 2018-06-22 15:33:07 +12:00
parent e1f524233b
commit dcaf63b608
2 changed files with 141 additions and 50 deletions

View File

@ -8772,11 +8772,21 @@ class OpenStackCloud(
the OpenStack API call.
"""
with _utils.shade_exceptions("Error fetching cluster template list"):
data = self._container_infra_client.get(
'/baymodels/detail')
return self._normalize_cluster_templates(
self._get_and_munchify('baymodels', data))
try:
data = self._container_infra_client.get('/clustertemplates')
# NOTE(flwang): Magnum adds /clustertemplates and /cluster
# to deprecate /baymodels and /bay since Newton release. So
# we're using a small tag to indicate if current
# cloud has those two new API endpoints.
self._container_infra_client._has_magnum_after_newton = True
return self._normalize_cluster_templates(
self._get_and_munchify('clustertemplates', data))
except exc.OpenStackCloudURINotFound:
data = self._container_infra_client.get('/baymodels/detail')
return self._normalize_cluster_templates(
self._get_and_munchify('baymodels', data))
list_baymodels = list_cluster_templates
list_coe_cluster_templates = list_cluster_templates
def search_cluster_templates(
self, name_or_id=None, filters=None, detail=False):
@ -8796,6 +8806,7 @@ class OpenStackCloud(
return _utils._filter_list(
cluster_templates, name_or_id, filters)
search_baymodels = search_cluster_templates
search_coe_cluster_templates = search_cluster_templates
def get_cluster_template(self, name_or_id, filters=None, detail=False):
"""Get a cluster template by name or ID.
@ -8822,6 +8833,7 @@ class OpenStackCloud(
return _utils._get_entity(self, 'cluster_template', name_or_id,
filters=filters, detail=detail)
get_baymodel = get_cluster_template
get_coe_cluster_template = get_cluster_template
def create_cluster_template(
self, name, image_id=None, keypair_id=None, coe=None, **kwargs):
@ -8849,12 +8861,18 @@ class OpenStackCloud(
body['keypair_id'] = keypair_id
body['coe'] = coe
cluster_template = self._container_infra_client.post(
'/baymodels', json=body)
try:
cluster_template = self._container_infra_client.post(
'/clustertemplates', json=body)
self._container_infra_client._has_magnum_after_newton = True
except exc.OpenStackCloudURINotFound:
cluster_template = self._container_infra_client.post(
'/baymodels', json=body)
self.list_cluster_templates.invalidate(self)
return cluster_template
create_baymodel = create_cluster_template
create_coe_cluster_template = create_cluster_template
def delete_cluster_template(self, name_or_id):
"""Delete a cluster template.
@ -8876,12 +8894,18 @@ class OpenStackCloud(
return False
with _utils.shade_exceptions("Error in deleting cluster template"):
self._container_infra_client.delete(
'/baymodels/{id}'.format(id=cluster_template['id']))
if getattr(self._container_infra_client,
'_has_magnum_after_newton', False):
self._container_infra_client.delete(
'/clustertemplates/{id}'.format(id=cluster_template['id']))
else:
self._container_infra_client.delete(
'/baymodels/{id}'.format(id=cluster_template['id']))
self.list_cluster_templates.invalidate(self)
return True
delete_baymodel = delete_cluster_template
delete_coe_cluster_template = delete_cluster_template
@_utils.valid_kwargs('name', 'image_id', 'flavor_id', 'master_flavor_id',
'keypair_id', 'external_network_id', 'fixed_network',
@ -8918,13 +8942,20 @@ class OpenStackCloud(
with _utils.shade_exceptions(
"Error updating cluster template {0}".format(name_or_id)):
self._container_infra_client.patch(
'/baymodels/{id}'.format(id=cluster_template['id']),
json=patches)
if getattr(self._container_infra_client,
'_has_magnum_after_newton', False):
self._container_infra_client.patch(
'/clustertemplates/{id}'.format(id=cluster_template['id']),
json=patches)
else:
self._container_infra_client.patch(
'/baymodels/{id}'.format(id=cluster_template['id']),
json=patches)
new_cluster_template = self.get_cluster_template(name_or_id)
return new_cluster_template
update_baymodel = update_cluster_template
update_coe_cluster_template = update_cluster_template
def list_nics(self):
msg = "Error fetching machine port list"

View File

@ -53,10 +53,15 @@ class TestClusterTemplates(base.RequestsMockTestCase):
def test_list_cluster_templates_without_detail(self):
self.register_uris([dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
json=dict(baymodels=[cluster_template_obj.toDict()]))])
self.register_uris([
dict(
method='GET',
uri='https://container-infra.example.com/v1/clustertemplates',
status_code=404),
dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
json=dict(baymodels=[cluster_template_obj.toDict()]))])
cluster_templates_list = self.cloud.list_cluster_templates()
self.assertEqual(
cluster_templates_list[0],
@ -64,10 +69,15 @@ class TestClusterTemplates(base.RequestsMockTestCase):
self.assert_calls()
def test_list_cluster_templates_with_detail(self):
self.register_uris([dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
json=dict(baymodels=[cluster_template_obj.toDict()]))])
self.register_uris([
dict(
method='GET',
uri='https://container-infra.example.com/v1/clustertemplates',
status_code=404),
dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
json=dict(baymodels=[cluster_template_obj.toDict()]))])
cluster_templates_list = self.cloud.list_cluster_templates(detail=True)
self.assertEqual(
cluster_templates_list[0],
@ -75,10 +85,15 @@ class TestClusterTemplates(base.RequestsMockTestCase):
self.assert_calls()
def test_search_cluster_templates_by_name(self):
self.register_uris([dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
json=dict(baymodels=[cluster_template_obj.toDict()]))])
self.register_uris([
dict(
method='GET',
uri='https://container-infra.example.com/v1/clustertemplates',
status_code=404),
dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
json=dict(baymodels=[cluster_template_obj.toDict()]))])
cluster_templates = self.cloud.search_cluster_templates(
name_or_id='fake-cluster-template')
@ -89,10 +104,15 @@ class TestClusterTemplates(base.RequestsMockTestCase):
def test_search_cluster_templates_not_found(self):
self.register_uris([dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
json=dict(baymodels=[cluster_template_obj.toDict()]))])
self.register_uris([
dict(
method='GET',
uri='https://container-infra.example.com/v1/clustertemplates',
status_code=404),
dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
json=dict(baymodels=[cluster_template_obj.toDict()]))])
cluster_templates = self.cloud.search_cluster_templates(
name_or_id='non-existent')
@ -101,10 +121,15 @@ class TestClusterTemplates(base.RequestsMockTestCase):
self.assert_calls()
def test_get_cluster_template(self):
self.register_uris([dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
json=dict(baymodels=[cluster_template_obj.toDict()]))])
self.register_uris([
dict(
method='GET',
uri='https://container-infra.example.com/v1/clustertemplates',
status_code=404),
dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
json=dict(baymodels=[cluster_template_obj.toDict()]))])
r = self.cloud.get_cluster_template('fake-cluster-template')
self.assertIsNotNone(r)
@ -113,25 +138,34 @@ class TestClusterTemplates(base.RequestsMockTestCase):
self.assert_calls()
def test_get_cluster_template_not_found(self):
self.register_uris([dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
json=dict(baymodels=[]))])
self.register_uris([
dict(
method='GET',
uri='https://container-infra.example.com/v1/clustertemplates',
status_code=404),
dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
json=dict(baymodels=[]))])
r = self.cloud.get_cluster_template('doesNotExist')
self.assertIsNone(r)
self.assert_calls()
def test_create_cluster_template(self):
self.register_uris([dict(
method='POST',
uri='https://container-infra.example.com/v1/baymodels',
json=dict(baymodels=[cluster_template_obj.toDict()]),
validate=dict(json={
'coe': 'fake-coe',
'image_id': 'fake-image',
'keypair_id': 'fake-key',
'name': 'fake-cluster-template'}),
)])
self.register_uris([
dict(
method='POST',
uri='https://container-infra.example.com/v1/clustertemplates',
status_code=404),
dict(
method='POST',
uri='https://container-infra.example.com/v1/baymodels',
json=dict(baymodels=[cluster_template_obj.toDict()]),
validate=dict(json={
'coe': 'fake-coe',
'image_id': 'fake-image',
'keypair_id': 'fake-key',
'name': 'fake-cluster-template'}),)])
self.cloud.create_cluster_template(
name=cluster_template_obj.name,
image_id=cluster_template_obj.image_id,
@ -140,10 +174,15 @@ class TestClusterTemplates(base.RequestsMockTestCase):
self.assert_calls()
def test_create_cluster_template_exception(self):
self.register_uris([dict(
method='POST',
uri='https://container-infra.example.com/v1/baymodels',
status_code=403)])
self.register_uris([
dict(
method='POST',
uri='https://container-infra.example.com/v1/clustertemplates',
status_code=404),
dict(
method='POST',
uri='https://container-infra.example.com/v1/baymodels',
status_code=403)])
# TODO(mordred) requests here doens't give us a great story
# for matching the old error message text. Investigate plumbing
# an error message in to the adapter call so that we can give a
@ -158,6 +197,10 @@ class TestClusterTemplates(base.RequestsMockTestCase):
def test_delete_cluster_template(self):
uri = 'https://container-infra.example.com/v1/baymodels/fake-uuid'
self.register_uris([
dict(
method='GET',
uri='https://container-infra.example.com/v1/clustertemplates',
status_code=404),
dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
@ -172,6 +215,10 @@ class TestClusterTemplates(base.RequestsMockTestCase):
def test_update_cluster_template(self):
uri = 'https://container-infra.example.com/v1/baymodels/fake-uuid'
self.register_uris([
dict(
method='GET',
uri='https://container-infra.example.com/v1/clustertemplates',
status_code=404),
dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
@ -189,7 +236,7 @@ class TestClusterTemplates(base.RequestsMockTestCase):
)),
dict(
method='GET',
uri='https://container-infra.example.com/v1/baymodels/detail',
uri='https://container-infra.example.com/v1/clustertemplates',
# This json value is not meaningful to the test - it just has
# to be valid.
json=dict(baymodels=[cluster_template_obj.toDict()])),
@ -198,3 +245,16 @@ class TestClusterTemplates(base.RequestsMockTestCase):
self.cloud.update_cluster_template(
'fake-uuid', 'replace', name=new_name)
self.assert_calls()
def test_get_coe_cluster_template(self):
self.register_uris([
dict(
method='GET',
uri='https://container-infra.example.com/v1/clustertemplates',
json=dict(clustertemplates=[cluster_template_obj.toDict()]))])
r = self.cloud.get_coe_cluster_template('fake-cluster-template')
self.assertIsNotNone(r)
self.assertDictEqual(
r, self.cloud._normalize_cluster_template(cluster_template_obj))
self.assert_calls()