From 70cb628278642e0e275c3e8d294bb73c17a97f5e Mon Sep 17 00:00:00 2001 From: Richard Theis Date: Mon, 3 Oct 2016 16:24:39 -0500 Subject: SDK Refactor: Prepare address scope commands Prepare the OSC "address scope" commands for the SDK refactor. See [1] for details. [1] https://etherpad.openstack.org/p/osc-network-command-sdk-support Change-Id: I4e253e01f9b0b10452354f4e4152468090c76958 Partially-Implements: blueprint network-command-sdk-support --- openstackclient/network/sdk_utils.py | 40 +++++++++++++++ openstackclient/network/v2/address_scope.py | 28 +++++----- .../tests/unit/network/test_sdk_utils.py | 59 ++++++++++++++++++++++ openstackclient/tests/unit/network/v2/fakes.py | 1 + 4 files changed, 116 insertions(+), 12 deletions(-) create mode 100644 openstackclient/network/sdk_utils.py create mode 100644 openstackclient/tests/unit/network/test_sdk_utils.py diff --git a/openstackclient/network/sdk_utils.py b/openstackclient/network/sdk_utils.py new file mode 100644 index 00000000..7bd54e46 --- /dev/null +++ b/openstackclient/network/sdk_utils.py @@ -0,0 +1,40 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import six + + +# Get the OSC show command display and attribute columns for an SDK resource. +def get_osc_show_columns_for_sdk_resource(sdk_resource, osc_column_map): + if getattr(sdk_resource, 'allow_get', None) is not None: + resource_dict = sdk_resource.to_dict( + body=True, headers=False, ignore_none=False) + else: + resource_dict = sdk_resource + + # Build the OSC column names to display for the SDK resource. + attr_map = {} + display_columns = list(resource_dict.keys()) + for sdk_attr, osc_attr in six.iteritems(osc_column_map): + if sdk_attr in display_columns: + attr_map[osc_attr] = sdk_attr + display_columns.remove(sdk_attr) + if osc_attr not in display_columns: + display_columns.append(osc_attr) + sorted_display_columns = sorted(display_columns) + + # Build the SDK attribute names for the OSC column names. + attr_columns = [] + for column in sorted_display_columns: + new_column = attr_map[column] if column in attr_map else column + attr_columns.append(new_column) + return tuple(sorted_display_columns), tuple(attr_columns) diff --git a/openstackclient/network/v2/address_scope.py b/openstackclient/network/v2/address_scope.py index 6cd13f8c..95f6c947 100644 --- a/openstackclient/network/v2/address_scope.py +++ b/openstackclient/network/v2/address_scope.py @@ -21,18 +21,18 @@ from osc_lib import utils from openstackclient.i18n import _ from openstackclient.identity import common as identity_common +from openstackclient.network import sdk_utils LOG = logging.getLogger(__name__) def _get_columns(item): - columns = list(item.keys()) - if 'tenant_id' in columns: - columns.remove('tenant_id') - columns.append('project_id') - - return tuple(sorted(columns)) + column_map = { + 'is_shared': 'shared', + 'tenant_id': 'project_id', + } + return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map) def _get_attrs(client_manager, parsed_args): @@ -55,6 +55,8 @@ def _get_attrs(client_manager, parsed_args): return attrs +# TODO(rtheis): Use the SDK resource mapped attribute names once the +# OSC minimum requirements include SDK 1.0. class CreateAddressScope(command.ShowOne): """Create a new Address Scope""" @@ -97,10 +99,10 @@ class CreateAddressScope(command.ShowOne): client = self.app.client_manager.network attrs = _get_attrs(self.app.client_manager, parsed_args) obj = client.create_address_scope(**attrs) - columns = _get_columns(obj) + display_columns, columns = _get_columns(obj) data = utils.get_item_properties(obj, columns, formatters={}) - return (columns, data) + return (display_columns, data) class DeleteAddressScope(command.Command): @@ -147,8 +149,8 @@ class ListAddressScope(command.Lister): 'id', 'name', 'ip_version', - 'shared', - 'tenant_id', + 'is_shared', + 'project_id', ) column_headers = ( 'ID', @@ -165,6 +167,8 @@ class ListAddressScope(command.Lister): ) for s in data)) +# TODO(rtheis): Use the SDK resource mapped attribute names once the +# OSC minimum requirements include SDK 1.0. class SetAddressScope(command.Command): """Set address scope properties""" @@ -227,7 +231,7 @@ class ShowAddressScope(command.ShowOne): obj = client.find_address_scope( parsed_args.address_scope, ignore_missing=False) - columns = _get_columns(obj) + display_columns, columns = _get_columns(obj) data = utils.get_item_properties(obj, columns, formatters={}) - return (columns, data) + return (display_columns, data) diff --git a/openstackclient/tests/unit/network/test_sdk_utils.py b/openstackclient/tests/unit/network/test_sdk_utils.py new file mode 100644 index 00000000..d1efa7e4 --- /dev/null +++ b/openstackclient/tests/unit/network/test_sdk_utils.py @@ -0,0 +1,59 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from openstackclient.network import sdk_utils +from openstackclient.tests.unit import utils as tests_utils + + +class TestSDKUtils(tests_utils.TestCase): + + def setUp(self): + super(TestSDKUtils, self).setUp() + + def _test_get_osc_show_columns_for_sdk_resource( + self, sdk_resource, column_map, + expected_display_columns, expected_attr_columns): + display_columns, attr_columns = \ + sdk_utils.get_osc_show_columns_for_sdk_resource( + sdk_resource, column_map) + self.assertEqual(expected_display_columns, display_columns) + self.assertEqual(expected_attr_columns, attr_columns) + + def test_get_osc_show_columns_for_sdk_resource_empty(self): + self._test_get_osc_show_columns_for_sdk_resource( + {}, {}, tuple(), tuple()) + + def test_get_osc_show_columns_for_sdk_resource_empty_map(self): + self._test_get_osc_show_columns_for_sdk_resource( + {'foo': 'foo1'}, {}, + ('foo',), ('foo',)) + + def test_get_osc_show_columns_for_sdk_resource_empty_data(self): + self._test_get_osc_show_columns_for_sdk_resource( + {}, {'foo': 'foo_map'}, + ('foo_map',), ('foo_map',)) + + def test_get_osc_show_columns_for_sdk_resource_map(self): + self._test_get_osc_show_columns_for_sdk_resource( + {'foo': 'foo1'}, {'foo': 'foo_map'}, + ('foo_map',), ('foo',)) + + def test_get_osc_show_columns_for_sdk_resource_map_dup(self): + self._test_get_osc_show_columns_for_sdk_resource( + {'foo': 'foo1', 'foo_map': 'foo1'}, {'foo': 'foo_map'}, + ('foo_map',), ('foo',)) + + def test_get_osc_show_columns_for_sdk_resource_map_full(self): + self._test_get_osc_show_columns_for_sdk_resource( + {'foo': 'foo1', 'bar': 'bar1'}, + {'foo': 'foo_map', 'new': 'bar'}, + ('bar', 'foo_map'), ('bar', 'foo')) diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py index cea00282..ed3579b7 100644 --- a/openstackclient/tests/unit/network/v2/fakes.py +++ b/openstackclient/tests/unit/network/v2/fakes.py @@ -98,6 +98,7 @@ class FakeAddressScope(object): loaded=True) # Set attributes with special mapping in OpenStack SDK. + address_scope.is_shared = address_scope_attrs['shared'] address_scope.project_id = address_scope_attrs['tenant_id'] return address_scope -- cgit v1.2.1