Retrieve is_default value to fix empty display in CLI
This bug is from path[1], when we use manila client to create a share type or share group type, the is_default value is always empty, so add the is_default value when we create each share type or share group type. Closes-bug: #1743941 [1] Ib264d8422fe57701f990cbbf7ea5d1e90b8b0008 Change-Id: Ia8bcb632591fc0b5438847b22ec59c2039ecf5f1
This commit is contained in:
parent
2b389ce1e1
commit
cf677f2603
@ -1605,6 +1605,24 @@ is_admin_only:
|
||||
in: body
|
||||
required: true
|
||||
type: boolean
|
||||
is_default_type:
|
||||
description: |
|
||||
Defines the share type created is default or not. If the returning
|
||||
value is true, then it is the default share type, otherwise, it is
|
||||
not default.
|
||||
in: body
|
||||
required: true
|
||||
type: boolean
|
||||
min_version: 2.46
|
||||
is_group_type_default:
|
||||
description: |
|
||||
Defines the share group type created is default or not. If the
|
||||
returning value is true, then it is the default share group type,
|
||||
otherwise, it is not default.
|
||||
in: body
|
||||
required: true
|
||||
type: boolean
|
||||
min_version: 2.46
|
||||
is_public:
|
||||
description: |
|
||||
(Since API v2.8) The level of visibility for the
|
||||
|
@ -4,6 +4,7 @@
|
||||
"group_specs": {},
|
||||
"share_types": ["ecd11f4c-d811-4471-b656-c755c77e02ba"],
|
||||
"id": "89861c2a-10bf-4013-bdd4-3d020466aee4",
|
||||
"name": "test_group_type"
|
||||
"name": "test_group_type",
|
||||
"is_default": false
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
"group_specs": {},
|
||||
"share_types": ["ecd11f4c-d811-4471-b656-c755c77e02ba"],
|
||||
"id": "89861c2a-10bf-4013-bdd4-3d020466aee4",
|
||||
"name": "test_group_type"
|
||||
"name": "test_group_type",
|
||||
"is_default": true
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,8 @@
|
||||
"group_specs": {},
|
||||
"share_types": ["ecd11f4c-d811-4471-b656-c755c77e02ba"],
|
||||
"id": "89861c2a-10bf-4013-bdd4-3d020466aee4",
|
||||
"name": "test_group_type"
|
||||
"name": "test_group_type",
|
||||
"is_default": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
},
|
||||
"id": "7fa1342b-de9d-4d89-bdc8-af67795c0e52",
|
||||
"name": "testing",
|
||||
"is_default": false,
|
||||
"description": "share type description"
|
||||
},
|
||||
"volume_type": {
|
||||
@ -31,6 +32,7 @@
|
||||
},
|
||||
"id": "7fa1342b-de9d-4d89-bdc8-af67795c0e52",
|
||||
"name": "testing",
|
||||
"is_default": false,
|
||||
"description": "share type description"
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
},
|
||||
"id": "2780fc88-526b-464a-a72c-ecb83f0e3929",
|
||||
"name": "default-share-type",
|
||||
"is_default": true,
|
||||
"description": "manila share type"
|
||||
},
|
||||
"volume_type": {
|
||||
@ -21,6 +22,7 @@
|
||||
},
|
||||
"id": "2780fc88-526b-464a-a72c-ecb83f0e3929",
|
||||
"name": "default-share-type",
|
||||
"is_default": true,
|
||||
"description": "manila share type"
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
},
|
||||
"id": "420e6a31-3f3d-4ed7-9d11-59450372182a",
|
||||
"name": "default",
|
||||
"is_default": true,
|
||||
"description": "share type description"
|
||||
},
|
||||
"volume_type": {
|
||||
@ -21,6 +22,7 @@
|
||||
},
|
||||
"id": "420e6a31-3f3d-4ed7-9d11-59450372182a",
|
||||
"name": "default",
|
||||
"is_default": true,
|
||||
"description": "share type description"
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
},
|
||||
"id": "420e6a31-3f3d-4ed7-9d11-59450372182a",
|
||||
"name": "default",
|
||||
"is_default": true,
|
||||
"description": "share type description"
|
||||
},
|
||||
{
|
||||
@ -27,6 +28,7 @@
|
||||
},
|
||||
"id": "7fa1342b-de9d-4d89-bdc8-af67795c0e52",
|
||||
"name": "testing",
|
||||
"is_default": false,
|
||||
"description": "share type description"
|
||||
}
|
||||
],
|
||||
@ -41,6 +43,7 @@
|
||||
},
|
||||
"id": "420e6a31-3f3d-4ed7-9d11-59450372182a",
|
||||
"name": "default",
|
||||
"is_default": true,
|
||||
"description": "share type description"
|
||||
},
|
||||
{
|
||||
@ -58,6 +61,7 @@
|
||||
},
|
||||
"id": "7fa1342b-de9d-4d89-bdc8-af67795c0e52",
|
||||
"name": "testing",
|
||||
"is_default": false,
|
||||
"description": "share type description"
|
||||
}
|
||||
]
|
||||
|
@ -65,6 +65,7 @@ Response parameters
|
||||
- share_types: share_types_1
|
||||
- name: share_group_type_name
|
||||
- group_specs: group_specs_required
|
||||
- is_default: is_group_type_default
|
||||
|
||||
Response example
|
||||
----------------
|
||||
@ -111,6 +112,7 @@ Response parameters
|
||||
- share_types: share_types_1
|
||||
- name: share_group_type_name
|
||||
- group_specs: group_specs_required
|
||||
- is_default: is_group_type_default
|
||||
|
||||
Response example
|
||||
----------------
|
||||
@ -211,6 +213,7 @@ Response parameters
|
||||
- name: share_group_type_name
|
||||
- share_types: share_types_1
|
||||
- is_public: share_group_type_is_public
|
||||
- is_default: is_group_type_default
|
||||
|
||||
Response example
|
||||
----------------
|
||||
|
@ -124,6 +124,7 @@ Response parameters
|
||||
- share_type_access:is_public: share_type_access:is_public
|
||||
- create_share_from_snapshot_support: create_share_from_snapshot_support
|
||||
- description: share_type_description
|
||||
- is_default: is_default_type
|
||||
|
||||
Response example
|
||||
----------------
|
||||
@ -173,6 +174,7 @@ Response parameters
|
||||
- share_type_access:is_public: share_type_access:is_public
|
||||
- name: share_type_name
|
||||
- description: share_type_description
|
||||
- is_default: is_default_type
|
||||
|
||||
Response example
|
||||
----------------
|
||||
@ -227,6 +229,7 @@ Response Parameters
|
||||
- share_type_access:is_public: share_type_access:is_public
|
||||
- name: share_type_name
|
||||
- description: share_type_description
|
||||
- is_default: is_default_type
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
@ -348,6 +351,7 @@ Response parameters
|
||||
- revert_to_snapshot_support: revert_to_snapshot_support
|
||||
- create_share_from_snapshot_support: create_share_from_snapshot_support
|
||||
- description: share_type_description
|
||||
- is_default: is_default_type
|
||||
|
||||
Response example
|
||||
----------------
|
||||
|
@ -119,13 +119,15 @@ REST_API_VERSION_HISTORY = """
|
||||
* 2.45 - Added access metadata for share access and also introduced
|
||||
the GET /share-access-rules API. The prior API to retrieve
|
||||
access rules will not work with API version >=2.45.
|
||||
* 2.46 - Added 'is_default' field to 'share_type' and 'share_group_type'
|
||||
objects.
|
||||
"""
|
||||
|
||||
# The minimum and maximum versions of the API supported
|
||||
# The default api version request is defined to be the
|
||||
# minimum version of the API supported.
|
||||
_MIN_API_VERSION = "2.0"
|
||||
_MAX_API_VERSION = "2.45"
|
||||
_MAX_API_VERSION = "2.46"
|
||||
DEFAULT_API_VERSION = _MIN_API_VERSION
|
||||
|
||||
|
||||
|
@ -248,3 +248,8 @@ user documentation.
|
||||
Added access metadata for share access and also introduced the
|
||||
GET /share-access-rules API. The prior API to retrieve access
|
||||
rules will not work with API version >=2.45.
|
||||
|
||||
2.46
|
||||
----
|
||||
Added 'is_default' field to 'share_type' and 'share_group_type'
|
||||
objects.
|
||||
|
@ -9,13 +9,20 @@
|
||||
# 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 oslo_config import cfg
|
||||
|
||||
from manila.api import common
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class ShareGroupTypeViewBuilder(common.ViewBuilder):
|
||||
_collection_name = 'share_group_types'
|
||||
|
||||
_detail_version_modifiers = [
|
||||
"add_is_default_attr",
|
||||
]
|
||||
|
||||
def show(self, request, share_group_type, brief=False):
|
||||
"""Trim away extraneous share group type attributes."""
|
||||
group_specs = share_group_type.get('group_specs', {})
|
||||
@ -37,3 +44,15 @@ class ShareGroupTypeViewBuilder(common.ViewBuilder):
|
||||
for share_group_type in share_group_types
|
||||
]
|
||||
return {"share_group_types": share_group_types_list}
|
||||
|
||||
@common.ViewBuilder.versioned_method("2.46")
|
||||
def add_is_default_attr(self, context,
|
||||
share_group_type_dict,
|
||||
share_group_type):
|
||||
is_default = False
|
||||
type_name = share_group_type.get('name')
|
||||
default_name = CONF.default_share_group_type
|
||||
|
||||
if default_name is not None:
|
||||
is_default = default_name == type_name
|
||||
share_group_type_dict['is_default'] = is_default
|
||||
|
@ -13,10 +13,14 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from manila.api import common
|
||||
from manila.common import constants
|
||||
from manila.share import share_types
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class ViewBuilder(common.ViewBuilder):
|
||||
|
||||
@ -27,6 +31,7 @@ class ViewBuilder(common.ViewBuilder):
|
||||
"add_is_public_attr_extension_like",
|
||||
"add_inferred_optional_extra_specs",
|
||||
"add_description_attr",
|
||||
"add_is_default_attr"
|
||||
]
|
||||
|
||||
def show(self, request, share_type, brief=False):
|
||||
@ -103,3 +108,13 @@ class ViewBuilder(common.ViewBuilder):
|
||||
@common.ViewBuilder.versioned_method("2.41")
|
||||
def add_description_attr(self, context, share_type_dict, share_type):
|
||||
share_type_dict['description'] = share_type.get('description')
|
||||
|
||||
@common.ViewBuilder.versioned_method("2.46")
|
||||
def add_is_default_attr(self, context, share_type_dict, share_type):
|
||||
is_default = False
|
||||
type_name = share_type.get('name')
|
||||
default_name = CONF.default_share_type
|
||||
|
||||
if default_name is not None:
|
||||
is_default = default_name == type_name
|
||||
share_type_dict['is_default'] = is_default
|
||||
|
@ -15,6 +15,7 @@ import datetime
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
import webob
|
||||
|
||||
from manila.api.v2 import share_group_types as types
|
||||
@ -24,6 +25,8 @@ from manila.share_group import share_group_types
|
||||
from manila import test
|
||||
from manila.tests.api import fakes
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
PROJ1_UUID = '11111111-1111-1111-1111-111111111111'
|
||||
PROJ2_UUID = '22222222-2222-2222-2222-222222222222'
|
||||
PROJ3_UUID = '33333333-3333-3333-3333-333333333333'
|
||||
@ -53,6 +56,18 @@ GROUP_TYPE_2 = {
|
||||
'share_types': [{'share_type_id': SHARE_TYPE_ID}],
|
||||
}
|
||||
|
||||
GROUP_TYPE_3 = {
|
||||
'id': '61fdcbed-db27-4cc0-8938-8b4f74c2ae59',
|
||||
'name': u'group type 3',
|
||||
'deleted': False,
|
||||
'created_at': datetime.datetime(2012, 1, 1, 1, 1, 1, 1),
|
||||
'updated_at': None,
|
||||
'deleted_at': None,
|
||||
'is_public': True,
|
||||
'group_specs': {},
|
||||
'share_types': [],
|
||||
}
|
||||
|
||||
|
||||
def fake_request(url, admin=False, experimental=True, version='2.31',
|
||||
**kwargs):
|
||||
@ -430,6 +445,98 @@ class ShareGroupTypesAPITest(test.TestCase):
|
||||
webob.exc.HTTPNotFound,
|
||||
self.controller._create, req, fake_body)
|
||||
|
||||
@ddt.data(('2.45', True), ('2.45', False),
|
||||
('2.46', True), ('2.46', False))
|
||||
@ddt.unpack
|
||||
def test_share_group_types_create_with_is_default_key(self,
|
||||
version,
|
||||
admin):
|
||||
# is_default is false
|
||||
fake_type = copy.deepcopy(GROUP_TYPE_1)
|
||||
fake_type['share_types'] = [{'share_type_id': SHARE_TYPE_ID}]
|
||||
self.mock_object(share_group_types, 'create')
|
||||
self.mock_object(
|
||||
share_group_types, 'get_by_name',
|
||||
mock.Mock(return_value=fake_type))
|
||||
req = fake_request('/v2/fake/share-group-types',
|
||||
version=version,
|
||||
admin=admin)
|
||||
fake_body = {'share_group_type': {
|
||||
'name': GROUP_TYPE_1['name'],
|
||||
'share_types': [SHARE_TYPE_ID],
|
||||
}}
|
||||
res_dict = self.controller._create(req, fake_body)
|
||||
if self.is_microversion_ge(version, '2.46'):
|
||||
self.assertIn('is_default', res_dict['share_group_type'])
|
||||
self.assertIs(False, res_dict['share_group_type']['is_default'])
|
||||
else:
|
||||
self.assertNotIn('is_default', res_dict['share_group_type'])
|
||||
|
||||
# is_default is true
|
||||
default_type_name = 'group type 3'
|
||||
CONF.set_default('default_share_group_type', default_type_name)
|
||||
|
||||
fake_type = copy.deepcopy(GROUP_TYPE_3)
|
||||
fake_type['share_types'] = [{'share_type_id': SHARE_TYPE_ID}]
|
||||
self.mock_object(share_group_types, 'create')
|
||||
self.mock_object(
|
||||
share_group_types, 'get_by_name',
|
||||
mock.Mock(return_value=fake_type))
|
||||
req = fake_request('/v2/fake/share-group-types',
|
||||
version=version,
|
||||
admin=admin)
|
||||
fake_body = {'share_group_type': {
|
||||
'name': GROUP_TYPE_3['name'],
|
||||
'share_types': [SHARE_TYPE_ID],
|
||||
}}
|
||||
res_dict = self.controller._create(req, fake_body)
|
||||
if self.is_microversion_ge(version, '2.46'):
|
||||
self.assertIn('is_default', res_dict['share_group_type'])
|
||||
self.assertIs(True, res_dict['share_group_type']['is_default'])
|
||||
else:
|
||||
self.assertNotIn('is_default', res_dict['share_group_type'])
|
||||
|
||||
@ddt.data(('2.45', True), ('2.45', False),
|
||||
('2.46', True), ('2.46', False))
|
||||
@ddt.unpack
|
||||
def test_share_group_types_list_with_is_default_key(self, version, admin):
|
||||
fake_types = {
|
||||
GROUP_TYPE_1['name']: GROUP_TYPE_1,
|
||||
GROUP_TYPE_2['name']: GROUP_TYPE_2,
|
||||
}
|
||||
self.mock_object(
|
||||
share_group_types, 'get_all',
|
||||
mock.Mock(return_value=fake_types))
|
||||
req = fake_request(
|
||||
'/v2/fake/share-group-types?is_public=all',
|
||||
version=version,
|
||||
admin=admin)
|
||||
res_dict = self.controller.index(req)
|
||||
for res in res_dict['share_group_types']:
|
||||
if self.is_microversion_ge(version, '2.46'):
|
||||
self.assertIn('is_default', res)
|
||||
self.assertIs(False, res['is_default'])
|
||||
else:
|
||||
self.assertNotIn('is_default', res)
|
||||
self.assertEqual(2, len(res_dict['share_group_types']))
|
||||
|
||||
@ddt.data(('2.45', True), ('2.45', False),
|
||||
('2.46', True), ('2.46', False))
|
||||
@ddt.unpack
|
||||
def test_shares_group_types_show_with_is_default_key(self, version, admin):
|
||||
self.mock_object(
|
||||
share_group_types, 'get',
|
||||
mock.Mock(return_value=GROUP_TYPE_2))
|
||||
req = fake_request('/v2/fake/group-types/%s' % GROUP_TYPE_2['id'],
|
||||
version=version,
|
||||
admin=admin)
|
||||
res_dict = self.controller.show(req, GROUP_TYPE_2['id'])
|
||||
if self.is_microversion_ge(version, '2.46'):
|
||||
self.assertIn('is_default', res_dict['share_group_type'])
|
||||
self.assertIs(False, res_dict['share_group_type']['is_default'])
|
||||
else:
|
||||
self.assertNotIn('is_default', res_dict['share_group_type'])
|
||||
|
||||
|
||||
class ShareGroupTypeAccessTest(test.TestCase):
|
||||
|
||||
|
@ -17,6 +17,7 @@ import datetime
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import timeutils
|
||||
import webob
|
||||
|
||||
@ -32,6 +33,8 @@ from manila import test
|
||||
from manila.tests.api import fakes
|
||||
from manila.tests import fake_notifier
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
def stub_share_type(id):
|
||||
specs = {
|
||||
@ -61,6 +64,34 @@ def return_share_types_get_all_types(context, search_opts=None):
|
||||
)
|
||||
|
||||
|
||||
def stub_default_name():
|
||||
return 'default_share_type'
|
||||
|
||||
|
||||
def stub_default_share_type(id):
|
||||
return dict(
|
||||
id=id,
|
||||
name=stub_default_name(),
|
||||
description='description_%s' % str(id),
|
||||
required_extra_specs={
|
||||
constants.ExtraSpecs.DRIVER_HANDLES_SHARE_SERVERS: "true",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def return_all_share_types(context, search_opts=None):
|
||||
mock_value = dict(
|
||||
share_type_1=stub_share_type(1),
|
||||
share_type_2=stub_share_type(2),
|
||||
share_type_3=stub_default_share_type(3)
|
||||
)
|
||||
return mock_value
|
||||
|
||||
|
||||
def return_default_share_type(context, search_opts=None):
|
||||
return stub_default_share_type(3)
|
||||
|
||||
|
||||
def return_empty_share_types_get_all_types(context, search_opts=None):
|
||||
return {}
|
||||
|
||||
@ -491,6 +522,65 @@ class ShareTypesAPITest(test.TestCase):
|
||||
for d1, d2 in zip(expected, observed):
|
||||
self.assertEqual(d1['id'], d2['id'])
|
||||
|
||||
@ddt.data(('2.45', True), ('2.45', False),
|
||||
('2.46', True), ('2.46', False))
|
||||
@ddt.unpack
|
||||
def test_share_types_create_with_is_default_key(self, version, admin):
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/types',
|
||||
version=version,
|
||||
use_admin_context=admin)
|
||||
|
||||
body = make_create_body()
|
||||
res_dict = self.controller.create(req, body)
|
||||
if self.is_microversion_ge(version, '2.46'):
|
||||
self.assertIn('is_default', res_dict['share_type'])
|
||||
self.assertIs(False, res_dict['share_type']['is_default'])
|
||||
else:
|
||||
self.assertNotIn('is_default', res_dict['share_type'])
|
||||
|
||||
@ddt.data(('2.45', True), ('2.45', False),
|
||||
('2.46', True), ('2.46', False))
|
||||
@ddt.unpack
|
||||
def test_share_types_index_with_is_default_key(self, version, admin):
|
||||
default_type_name = stub_default_name()
|
||||
CONF.set_default("default_share_type", default_type_name)
|
||||
self.mock_object(share_types, 'get_all_types',
|
||||
return_all_share_types)
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/types',
|
||||
version=version,
|
||||
use_admin_context=admin)
|
||||
|
||||
res_dict = self.controller.index(req)
|
||||
self.assertEqual(3, len(res_dict['share_types']))
|
||||
for res in res_dict['share_types']:
|
||||
if self.is_microversion_ge(version, '2.46'):
|
||||
self.assertIn('is_default', res)
|
||||
expected = res['name'] == default_type_name
|
||||
self.assertIs(res['is_default'], expected)
|
||||
else:
|
||||
self.assertNotIn('is_default', res)
|
||||
|
||||
@ddt.data(('2.45', True), ('2.45', False),
|
||||
('2.46', True), ('2.46', False))
|
||||
@ddt.unpack
|
||||
def test_share_types_default_with_is_default_key(self, version, admin):
|
||||
default_type_name = stub_default_name()
|
||||
CONF.set_default("default_share_type", default_type_name)
|
||||
self.mock_object(share_types, 'get_default_share_type',
|
||||
return_default_share_type)
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/types/default_share_type',
|
||||
version=version,
|
||||
use_admin_context=admin)
|
||||
|
||||
res_dict = self.controller.default(req)
|
||||
if self.is_microversion_ge(version, '2.46'):
|
||||
self.assertIn('is_default', res_dict['share_type'])
|
||||
self.assertIs(True, res_dict['share_type']['is_default'])
|
||||
else:
|
||||
self.assertNotIn('is_default', res_dict['share_type'])
|
||||
|
||||
|
||||
def generate_type(type_id, is_public):
|
||||
return {
|
||||
|
6
releasenotes/notes/add-is-default-e49727d276dd9bc3.yaml
Normal file
6
releasenotes/notes/add-is-default-e49727d276dd9bc3.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
|
||||
- The share type and share group type APIs in API version 2.46 return
|
||||
field "is_default" which is set to 'true' if the share type or the
|
||||
share group type is the default as configured by the administrator.
|
Loading…
Reference in New Issue
Block a user