diff --git a/doc/source/model.rst b/doc/source/model.rst index 37aa5d1db..93ae95cff 100644 --- a/doc/source/model.rst +++ b/doc/source/model.rst @@ -395,3 +395,41 @@ A volume type access from cinder. volume_type_id=str(), project_id=str(), properties=dict()) + + +ClusterTemplate +--------------- + +A Cluster Template from magnum. + +.. code-block:: python + + ClusterTemplate = dict( + location=Location(), + apiserver_port=int(), + cluster_distro=str(), + coe=str(), + created_at=str(), + dns_nameserver=str(), + docker_volume_size=int(), + external_network_id=str(), + fixed_network=str() or None, + flavor_id=str(), + http_proxy=str() or None, + https_proxy=str() or None, + id=str(), + image_id=str(), + insecure_registry=str(), + is_public=bool(), + is_registry_enabled=bool(), + is_tls_disabled=bool(), + keypair_id=str(), + labels=dict(), + master_flavor_id=str() or None, + name=str(), + network_driver=str(), + no_proxy=str() or None, + server_type=str(), + updated_at=str() or None, + volume_driver=str(), + properties=dict()) diff --git a/releasenotes/notes/always-detail-cluster-templates-3eb4b5744ba327ac.yaml b/releasenotes/notes/always-detail-cluster-templates-3eb4b5744ba327ac.yaml new file mode 100644 index 000000000..cc98f8c9f --- /dev/null +++ b/releasenotes/notes/always-detail-cluster-templates-3eb4b5744ba327ac.yaml @@ -0,0 +1,5 @@ +--- +upgrade: + - Cluster Templates have data model and normalization + now. As a result, the detail parameter is now ignored + and detailed records are always returned. diff --git a/shade/_normalize.py b/shade/_normalize.py index 3621e7805..79fa3f518 100644 --- a/shade/_normalize.py +++ b/shade/_normalize.py @@ -836,3 +836,72 @@ class Normalizer(object): for server_usage in server_usages: ret.append(self._normalize_server_usage(server_usage)) return ret + + def _normalize_cluster_templates(self, cluster_templates): + ret = [] + for cluster_template in cluster_templates: + ret.append(self._normalize_cluster_template(cluster_template)) + return ret + + def _normalize_cluster_template(self, cluster_template): + """Normalize Magnum cluster_templates.""" + cluster_template = cluster_template.copy() + + # Discard noise + cluster_template.pop('links', None) + cluster_template.pop('human_id', None) + # model_name is a magnumclient-ism + cluster_template.pop('model_name', None) + + ct_id = cluster_template.pop('uuid') + + ret = munch.Munch( + id=ct_id, + location=self._get_current_location(), + ) + ret['is_public'] = cluster_template.pop('public') + ret['is_registry_enabled'] = cluster_template.pop('registry_enabled') + ret['is_tls_disabled'] = cluster_template.pop('tls_disabled') + # pop floating_ip_enabled since we want to hide it in a future patch + fip_enabled = cluster_template.pop('floating_ip_enabled', None) + if not self.strict_mode: + ret['uuid'] = ct_id + if fip_enabled is not None: + ret['floating_ip_enabled'] = fip_enabled + ret['public'] = ret['is_public'] + ret['registry_enabled'] = ret['is_registry_enabled'] + ret['tls_disabled'] = ret['is_tls_disabled'] + + # Optional keys + for (key, default) in ( + ('fixed_network', None), + ('fixed_subnet', None), + ('http_proxy', None), + ('https_proxy', None), + ('labels', {}), + ('master_flavor_id', None), + ('no_proxy', None)): + if key in cluster_template: + ret[key] = cluster_template.pop(key, default) + + for key in ( + 'apiserver_port', + 'cluster_distro', + 'coe', + 'created_at', + 'dns_nameserver', + 'docker_volume_size', + 'external_network_id', + 'flavor_id', + 'image_id', + 'insecure_registry', + 'keypair_id', + 'name', + 'network_driver', + 'server_type', + 'updated_at', + 'volume_driver'): + ret[key] = cluster_template.pop(key) + + ret['properties'] = cluster_template + return ret diff --git a/shade/_utils.py b/shade/_utils.py index 6500556fd..bf2153cff 100644 --- a/shade/_utils.py +++ b/shade/_utils.py @@ -376,14 +376,6 @@ def normalize_stacks(stacks): return stacks -def normalize_cluster_templates(cluster_templates): - """Normalize Magnum cluster_templates.""" - for cluster_template in cluster_templates: - cluster_template.pop('model_name', None) - cluster_template['id'] = cluster_template['uuid'] - return cluster_templates - - def valid_kwargs(*valid_args): # This decorator checks if argument passed as **kwargs to a function are # present in valid_args. diff --git a/shade/openstackcloud.py b/shade/openstackcloud.py index cbe580356..f7dc0be25 100644 --- a/shade/openstackcloud.py +++ b/shade/openstackcloud.py @@ -7117,8 +7117,8 @@ class OpenStackCloud(_normalize.Normalizer): def list_cluster_templates(self, detail=False): """List cluster templates. - :param bool detail. Flag to control if we need summarized or - detailed output. + :param bool detail. Ignored. Included for backwards compat. + ClusterTemplates are always returned with full details. :returns: a list of dicts containing the cluster template details. @@ -7127,8 +7127,8 @@ class OpenStackCloud(_normalize.Normalizer): """ with _utils.shade_exceptions("Error fetching cluster template list"): cluster_templates = self.manager.submit_task( - _tasks.ClusterTemplateList(detail=detail)) - return _utils.normalize_cluster_templates(cluster_templates) + _tasks.ClusterTemplateList(detail=True)) + return self._normalize_cluster_templates(cluster_templates) list_baymodels = list_cluster_templates def search_cluster_templates( diff --git a/shade/tests/unit/test_cluster_templates.py b/shade/tests/unit/test_cluster_templates.py index 0ab8cdd60..fff08ef49 100644 --- a/shade/tests/unit/test_cluster_templates.py +++ b/shade/tests/unit/test_cluster_templates.py @@ -15,52 +15,38 @@ import mock import munch import shade -from shade import _utils import testtools from shade.tests.unit import base cluster_template_obj = munch.Munch( - apiserver_port=None, - uuid='fake-uuid', - human_id=None, - name='fake-cluster-template', - server_type='vm', - public=False, - image_id='fake-image', - tls_disabled=False, - registry_enabled=False, - coe='fake-coe', - keypair_id='fake-key', -) - -cluster_template_detail_obj = munch.Munch( - links={}, - labels={}, - apiserver_port=None, - uuid='fake-uuid', - human_id=None, - name='fake-cluster-template', - server_type='vm', - public=False, - image_id='fake-image', - tls_disabled=False, - registry_enabled=False, + apiserver_port=12345, + cluster_distro='fake-distro', coe='fake-coe', created_at='fake-date', - updated_at=None, - master_flavor_id=None, - no_proxy=None, - https_proxy=None, - keypair_id='fake-key', + dns_nameserver='8.8.8.8', docker_volume_size=1, external_network_id='public', - cluster_distro='fake-distro', - volume_driver=None, - network_driver='fake-driver', fixed_network=None, flavor_id='fake-flavor', - dns_nameserver='8.8.8.8', + https_proxy=None, + human_id=None, + image_id='fake-image', + insecure_registry='https://192.168.0.10', + keypair_id='fake-key', + labels={}, + links={}, + master_flavor_id=None, + name='fake-cluster-template', + network_driver='fake-driver', + no_proxy=None, + public=False, + registry_enabled=False, + server_type='vm', + tls_disabled=False, + updated_at=None, + uuid='fake-uuid', + volume_driver=None, ) @@ -70,24 +56,24 @@ class TestClusterTemplates(base.RequestsMockTestCase): self.register_uris([dict( method='GET', - uri='https://container-infra.example.com/v1/baymodels', + 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], - _utils.normalize_cluster_templates([cluster_template_obj])[0]) + self.cloud._normalize_cluster_template(cluster_template_obj)) 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_detail_obj.toDict()]))]) + json=dict(baymodels=[cluster_template_obj.toDict()]))]) cluster_templates_list = self.cloud.list_cluster_templates(detail=True) self.assertEqual( cluster_templates_list[0], - _utils.normalize_cluster_templates( - [cluster_template_detail_obj])[0]) + self.cloud._normalize_cluster_template( + cluster_template_obj)) self.assert_calls() @mock.patch.object(shade.OpenStackCloud, 'magnum_client') @@ -97,7 +83,7 @@ class TestClusterTemplates(base.RequestsMockTestCase): cluster_templates = self.cloud.search_cluster_templates( name_or_id='fake-cluster-template') - mock_magnum.baymodels.list.assert_called_with(detail=False) + mock_magnum.baymodels.list.assert_called_with(detail=True) self.assertEqual(1, len(cluster_templates)) self.assertEqual('fake-uuid', cluster_templates[0]['uuid']) @@ -110,7 +96,7 @@ class TestClusterTemplates(base.RequestsMockTestCase): cluster_templates = self.cloud.search_cluster_templates( name_or_id='non-existent') - mock_magnum.baymodels.list.assert_called_with(detail=False) + mock_magnum.baymodels.list.assert_called_with(detail=True) self.assertEqual(0, len(cluster_templates)) @mock.patch.object(shade.OpenStackCloud, 'search_cluster_templates')