Add CLI error notification in case there is no share type
Currently, when there is no default share type and try to create a manila share without specifying a share type, the creation request is sent and no CLI error notification is received. This patch prevent sending the create request and provide early feedback to CLI users. Closes-Bug: #1960422 Change-Id: I66a8bcebe35e744f9796e3db44d6cedf2ada983f
This commit is contained in:
parent
f7c7c38d5e
commit
ded2303da8
@ -23,6 +23,7 @@ from osc_lib import utils as oscutils
|
|||||||
|
|
||||||
from manilaclient import api_versions
|
from manilaclient import api_versions
|
||||||
from manilaclient.common._i18n import _
|
from manilaclient.common._i18n import _
|
||||||
|
from manilaclient.common.apiclient import exceptions as apiclient_exceptions
|
||||||
from manilaclient.common.apiclient import utils as apiutils
|
from manilaclient.common.apiclient import utils as apiutils
|
||||||
from manilaclient.common import cliutils
|
from manilaclient.common import cliutils
|
||||||
from manilaclient.osc import utils
|
from manilaclient.osc import utils
|
||||||
@ -193,10 +194,17 @@ class CreateShare(command.ShowOne):
|
|||||||
# TODO(s0ru): the table shows 'Field', 'Value'
|
# TODO(s0ru): the table shows 'Field', 'Value'
|
||||||
share_client = self.app.client_manager.share
|
share_client = self.app.client_manager.share
|
||||||
|
|
||||||
share_type = None
|
|
||||||
if parsed_args.share_type:
|
if parsed_args.share_type:
|
||||||
share_type = apiutils.find_resource(share_client.share_types,
|
share_type = apiutils.find_resource(share_client.share_types,
|
||||||
parsed_args.share_type).id
|
parsed_args.share_type).id
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
share_type = apiutils.find_resource(
|
||||||
|
share_client.share_types, 'default').id
|
||||||
|
except apiclient_exceptions.CommandError:
|
||||||
|
msg = ("There is no default share type available. You must "
|
||||||
|
"pick a valid share type to create a share.")
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
share_network = None
|
share_network = None
|
||||||
if parsed_args.share_network:
|
if parsed_args.share_network:
|
||||||
|
@ -82,6 +82,8 @@ class TestShareCreate(TestShare):
|
|||||||
self.share_snapshot = (
|
self.share_snapshot = (
|
||||||
manila_fakes.FakeShareSnapshot.create_one_snapshot())
|
manila_fakes.FakeShareSnapshot.create_one_snapshot())
|
||||||
self.snapshots_mock.get.return_value = self.share_snapshot
|
self.snapshots_mock.get.return_value = self.share_snapshot
|
||||||
|
self.share_type = manila_fakes.FakeShareType.create_one_sharetype()
|
||||||
|
self.share_types_mock.get.return_value = self.share_type
|
||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = osc_shares.CreateShare(self.app, None)
|
self.cmd = osc_shares.CreateShare(self.app, None)
|
||||||
@ -95,10 +97,12 @@ class TestShareCreate(TestShare):
|
|||||||
arglist = [
|
arglist = [
|
||||||
self.new_share.share_proto,
|
self.new_share.share_proto,
|
||||||
str(self.new_share.size),
|
str(self.new_share.size),
|
||||||
|
'--share-type', self.share_type.id,
|
||||||
]
|
]
|
||||||
verifylist = [
|
verifylist = [
|
||||||
('share_proto', self.new_share.share_proto),
|
('share_proto', self.new_share.share_proto),
|
||||||
('size', self.new_share.size)
|
('size', self.new_share.size),
|
||||||
|
('share_type', self.share_type.id)
|
||||||
]
|
]
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
@ -114,7 +118,7 @@ class TestShareCreate(TestShare):
|
|||||||
share_group_id=None,
|
share_group_id=None,
|
||||||
share_network=None,
|
share_network=None,
|
||||||
share_proto=self.new_share.share_proto,
|
share_proto=self.new_share.share_proto,
|
||||||
share_type=None,
|
share_type=self.share_type.id,
|
||||||
size=self.new_share.size,
|
size=self.new_share.size,
|
||||||
snapshot_id=None,
|
snapshot_id=None,
|
||||||
scheduler_hints={}
|
scheduler_hints={}
|
||||||
@ -139,12 +143,14 @@ class TestShareCreate(TestShare):
|
|||||||
arglist = [
|
arglist = [
|
||||||
self.new_share.share_proto,
|
self.new_share.share_proto,
|
||||||
str(self.new_share.size),
|
str(self.new_share.size),
|
||||||
|
'--share-type', self.share_type.id,
|
||||||
'--property', 'Manila=zorilla',
|
'--property', 'Manila=zorilla',
|
||||||
'--property', 'Zorilla=manila'
|
'--property', 'Zorilla=manila'
|
||||||
]
|
]
|
||||||
verifylist = [
|
verifylist = [
|
||||||
('share_proto', self.new_share.share_proto),
|
('share_proto', self.new_share.share_proto),
|
||||||
('size', self.new_share.size),
|
('size', self.new_share.size),
|
||||||
|
('share_type', self.share_type.id),
|
||||||
('property', {'Manila': 'zorilla', 'Zorilla': 'manila'}),
|
('property', {'Manila': 'zorilla', 'Zorilla': 'manila'}),
|
||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
@ -160,7 +166,7 @@ class TestShareCreate(TestShare):
|
|||||||
share_group_id=None,
|
share_group_id=None,
|
||||||
share_network=None,
|
share_network=None,
|
||||||
share_proto=self.new_share.share_proto,
|
share_proto=self.new_share.share_proto,
|
||||||
share_type=None,
|
share_type=self.share_type.id,
|
||||||
size=self.new_share.size,
|
size=self.new_share.size,
|
||||||
snapshot_id=None,
|
snapshot_id=None,
|
||||||
scheduler_hints={}
|
scheduler_hints={}
|
||||||
@ -181,12 +187,14 @@ class TestShareCreate(TestShare):
|
|||||||
arglist = [
|
arglist = [
|
||||||
self.new_share.share_proto,
|
self.new_share.share_proto,
|
||||||
str(self.new_share.size),
|
str(self.new_share.size),
|
||||||
|
'--share-type', self.share_type.id,
|
||||||
'--scheduler-hint', ('same_host=%s' % share1_name),
|
'--scheduler-hint', ('same_host=%s' % share1_name),
|
||||||
'--scheduler-hint', ('different_host=%s' % share2_name),
|
'--scheduler-hint', ('different_host=%s' % share2_name),
|
||||||
]
|
]
|
||||||
verifylist = [
|
verifylist = [
|
||||||
('share_proto', self.new_share.share_proto),
|
('share_proto', self.new_share.share_proto),
|
||||||
('size', self.new_share.size),
|
('size', self.new_share.size),
|
||||||
|
('share_type', self.share_type.id),
|
||||||
('scheduler_hint',
|
('scheduler_hint',
|
||||||
{'same_host': share1_name, 'different_host': share2_name}),
|
{'same_host': share1_name, 'different_host': share2_name}),
|
||||||
]
|
]
|
||||||
@ -203,7 +211,7 @@ class TestShareCreate(TestShare):
|
|||||||
share_group_id=None,
|
share_group_id=None,
|
||||||
share_network=None,
|
share_network=None,
|
||||||
share_proto=self.new_share.share_proto,
|
share_proto=self.new_share.share_proto,
|
||||||
share_type=None,
|
share_type=self.share_type.id,
|
||||||
size=self.new_share.size,
|
size=self.new_share.size,
|
||||||
snapshot_id=None,
|
snapshot_id=None,
|
||||||
scheduler_hints={'same_host': shares[0].id,
|
scheduler_hints={'same_host': shares[0].id,
|
||||||
@ -219,12 +227,14 @@ class TestShareCreate(TestShare):
|
|||||||
arglist = [
|
arglist = [
|
||||||
self.new_share.share_proto,
|
self.new_share.share_proto,
|
||||||
str(self.new_share.size),
|
str(self.new_share.size),
|
||||||
|
'--share-type', self.share_type.id,
|
||||||
'--snapshot-id', self.share_snapshot.id
|
'--snapshot-id', self.share_snapshot.id
|
||||||
|
|
||||||
]
|
]
|
||||||
verifylist = [
|
verifylist = [
|
||||||
('share_proto', self.new_share.share_proto),
|
('share_proto', self.new_share.share_proto),
|
||||||
('size', self.new_share.size),
|
('size', self.new_share.size),
|
||||||
|
('share_type', self.share_type.id),
|
||||||
('snapshot_id', self.share_snapshot.id)
|
('snapshot_id', self.share_snapshot.id)
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -241,7 +251,7 @@ class TestShareCreate(TestShare):
|
|||||||
share_group_id=None,
|
share_group_id=None,
|
||||||
share_network=None,
|
share_network=None,
|
||||||
share_proto=self.new_share.share_proto,
|
share_proto=self.new_share.share_proto,
|
||||||
share_type=None,
|
share_type=self.share_type.id,
|
||||||
size=self.new_share.size,
|
size=self.new_share.size,
|
||||||
snapshot_id=self.share_snapshot.id,
|
snapshot_id=self.share_snapshot.id,
|
||||||
scheduler_hints={}
|
scheduler_hints={}
|
||||||
@ -255,11 +265,13 @@ class TestShareCreate(TestShare):
|
|||||||
arglist = [
|
arglist = [
|
||||||
self.new_share.share_proto,
|
self.new_share.share_proto,
|
||||||
str(self.new_share.size),
|
str(self.new_share.size),
|
||||||
|
'--share-type', self.share_type.id,
|
||||||
'--wait'
|
'--wait'
|
||||||
]
|
]
|
||||||
verifylist = [
|
verifylist = [
|
||||||
('share_proto', self.new_share.share_proto),
|
('share_proto', self.new_share.share_proto),
|
||||||
('size', self.new_share.size),
|
('size', self.new_share.size),
|
||||||
|
('share_type', self.share_type.id),
|
||||||
('wait', True)
|
('wait', True)
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -276,7 +288,7 @@ class TestShareCreate(TestShare):
|
|||||||
share_group_id=None,
|
share_group_id=None,
|
||||||
share_network=None,
|
share_network=None,
|
||||||
share_proto=self.new_share.share_proto,
|
share_proto=self.new_share.share_proto,
|
||||||
share_type=None,
|
share_type=self.share_type.id,
|
||||||
size=self.new_share.size,
|
size=self.new_share.size,
|
||||||
snapshot_id=None,
|
snapshot_id=None,
|
||||||
scheduler_hints={}
|
scheduler_hints={}
|
||||||
@ -292,11 +304,13 @@ class TestShareCreate(TestShare):
|
|||||||
arglist = [
|
arglist = [
|
||||||
self.new_share.share_proto,
|
self.new_share.share_proto,
|
||||||
str(self.new_share.size),
|
str(self.new_share.size),
|
||||||
|
'--share-type', self.share_type.id,
|
||||||
'--wait'
|
'--wait'
|
||||||
]
|
]
|
||||||
verifylist = [
|
verifylist = [
|
||||||
('share_proto', self.new_share.share_proto),
|
('share_proto', self.new_share.share_proto),
|
||||||
('size', self.new_share.size),
|
('size', self.new_share.size),
|
||||||
|
('share_type', self.share_type.id),
|
||||||
('wait', True)
|
('wait', True)
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -314,7 +328,7 @@ class TestShareCreate(TestShare):
|
|||||||
share_group_id=None,
|
share_group_id=None,
|
||||||
share_network=None,
|
share_network=None,
|
||||||
share_proto=self.new_share.share_proto,
|
share_proto=self.new_share.share_proto,
|
||||||
share_type=None,
|
share_type=self.share_type.id,
|
||||||
size=self.new_share.size,
|
size=self.new_share.size,
|
||||||
snapshot_id=None,
|
snapshot_id=None,
|
||||||
scheduler_hints={}
|
scheduler_hints={}
|
||||||
@ -327,6 +341,24 @@ class TestShareCreate(TestShare):
|
|||||||
self.assertCountEqual(self.columns, columns)
|
self.assertCountEqual(self.columns, columns)
|
||||||
self.assertCountEqual(self.datalist, data)
|
self.assertCountEqual(self.datalist, data)
|
||||||
|
|
||||||
|
def test_create_share_with_no_existing_share_type(self):
|
||||||
|
arglist = [
|
||||||
|
self.new_share.share_proto,
|
||||||
|
str(self.new_share.size),
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('share_proto', self.new_share.share_proto),
|
||||||
|
('size', self.new_share.size),
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
self.share_types_mock.get.side_effect = osc_exceptions.CommandError()
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
osc_exceptions.CommandError,
|
||||||
|
self.cmd.take_action,
|
||||||
|
parsed_args)
|
||||||
|
|
||||||
|
|
||||||
class TestShareDelete(TestShare):
|
class TestShareDelete(TestShare):
|
||||||
|
|
||||||
|
@ -2092,13 +2092,16 @@ class ShellTest(test_utils.TestCase):
|
|||||||
|
|
||||||
def test_create_share(self):
|
def test_create_share(self):
|
||||||
# Use only required fields
|
# Use only required fields
|
||||||
self.run_command("create nfs 1")
|
expected = self.create_share_body.copy()
|
||||||
self.assert_called("POST", "/shares", body=self.create_share_body)
|
expected['share']['share_type'] = 'test_type'
|
||||||
|
self.run_command("create nfs 1 --share-type test_type")
|
||||||
|
self.assert_called("POST", "/shares", body=expected)
|
||||||
|
|
||||||
def test_create_public_share(self):
|
def test_create_public_share(self):
|
||||||
expected = self.create_share_body.copy()
|
expected = self.create_share_body.copy()
|
||||||
expected['share']['is_public'] = True
|
expected['share']['is_public'] = True
|
||||||
self.run_command("create --public nfs 1")
|
expected['share']['share_type'] = 'test_type'
|
||||||
|
self.run_command("create --public nfs 1 --share-type test_type")
|
||||||
self.assert_called("POST", "/shares", body=expected)
|
self.assert_called("POST", "/shares", body=expected)
|
||||||
|
|
||||||
def test_create_with_share_network(self):
|
def test_create_with_share_network(self):
|
||||||
@ -2106,26 +2109,35 @@ class ShellTest(test_utils.TestCase):
|
|||||||
sn = "fake-share-network"
|
sn = "fake-share-network"
|
||||||
with mock.patch.object(shell_v2, "_find_share_network",
|
with mock.patch.object(shell_v2, "_find_share_network",
|
||||||
mock.Mock(return_value=sn)):
|
mock.Mock(return_value=sn)):
|
||||||
self.run_command("create nfs 1 --share-network %s" % sn)
|
self.run_command("create nfs 1 --share-type test_type "
|
||||||
|
"--share-network %s" % sn)
|
||||||
expected = self.create_share_body.copy()
|
expected = self.create_share_body.copy()
|
||||||
expected['share']['share_network_id'] = sn
|
expected['share']['share_network_id'] = sn
|
||||||
|
expected['share']['share_type'] = 'test_type'
|
||||||
self.assert_called("POST", "/shares", body=expected)
|
self.assert_called("POST", "/shares", body=expected)
|
||||||
shell_v2._find_share_network.assert_called_once_with(mock.ANY, sn)
|
shell_v2._find_share_network.assert_called_once_with(mock.ANY, sn)
|
||||||
|
|
||||||
def test_create_with_metadata(self):
|
def test_create_with_metadata(self):
|
||||||
# Except required fields added metadata
|
# Except required fields added metadata
|
||||||
self.run_command("create nfs 1 --metadata key1=value1 key2=value2")
|
self.run_command("create nfs 1 --metadata key1=value1 key2=value2 "
|
||||||
|
"--share-type test_type")
|
||||||
expected = self.create_share_body.copy()
|
expected = self.create_share_body.copy()
|
||||||
expected['share']['metadata'] = {"key1": "value1", "key2": "value2"}
|
expected['share']['metadata'] = {"key1": "value1", "key2": "value2"}
|
||||||
|
expected['share']['share_type'] = 'test_type'
|
||||||
self.assert_called("POST", "/shares", body=expected)
|
self.assert_called("POST", "/shares", body=expected)
|
||||||
|
|
||||||
def test_create_with_wait(self):
|
def test_create_with_wait(self):
|
||||||
self.run_command("create nfs 1 --wait")
|
self.run_command("create nfs 1 --wait --share-type test_type")
|
||||||
expected = self.create_share_body.copy()
|
expected = self.create_share_body.copy()
|
||||||
|
expected['share']['share_type'] = 'test_type'
|
||||||
self.assert_called_anytime(
|
self.assert_called_anytime(
|
||||||
"POST", "/shares", body=expected, clear_callstack=False)
|
"POST", "/shares", body=expected, clear_callstack=False)
|
||||||
self.assert_called("GET", "/shares/1234")
|
self.assert_called("GET", "/shares/1234")
|
||||||
|
|
||||||
|
def test_create_share_with_no_existing_share_type(self):
|
||||||
|
self.assertRaises(
|
||||||
|
exceptions.CommandError, self.run_command, "create nfs 1")
|
||||||
|
|
||||||
def test_allow_access_cert(self):
|
def test_allow_access_cert(self):
|
||||||
self.run_command("access-allow 1234 cert client.example.com")
|
self.run_command("access-allow 1234 cert client.example.com")
|
||||||
|
|
||||||
|
@ -972,6 +972,14 @@ def do_create(cs, args):
|
|||||||
raise exceptions.CommandError(
|
raise exceptions.CommandError(
|
||||||
"Share name cannot be with the value 'None'")
|
"Share name cannot be with the value 'None'")
|
||||||
|
|
||||||
|
if not args.share_type:
|
||||||
|
try:
|
||||||
|
_find_share_type(cs, "default")
|
||||||
|
except exceptions.CommandError:
|
||||||
|
msg = ("There is no default share type available. You must pick "
|
||||||
|
"a valid share type to create a share.")
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
scheduler_hints = {}
|
scheduler_hints = {}
|
||||||
if args.scheduler_hints:
|
if args.scheduler_hints:
|
||||||
scheduler_hints = _extract_key_value_options(args, 'scheduler_hints')
|
scheduler_hints = _extract_key_value_options(args, 'scheduler_hints')
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
`Launchpad bug 1960422 <https://bugs.launchpad.net/python-manilaclient/+bug/1960422>`_
|
||||||
|
has been fixed by prevent sending the share creation request and provide
|
||||||
|
early feedback to CLI users.
|
Loading…
Reference in New Issue
Block a user