[OSC] Implement share network subnet commands
This patch adds the following openstack share commands: share network subnet create share network subnet delete share network subnet show Partially-implements: bp openstack-client-support Change-Id: I4e066a982fa40b079f969e7c3ca3276d3a842074
This commit is contained in:
parent
0f9ba9a7d3
commit
b095429783
|
@ -66,7 +66,20 @@ share networks
|
|||
==============
|
||||
|
||||
.. autoprogram-cliff:: openstack.share.v2
|
||||
:command: share network *
|
||||
:command: share network [!s]*
|
||||
|
||||
.. autoprogram-cliff:: openstack.share.v2
|
||||
:command: share network show
|
||||
|
||||
.. autoprogram-cliff:: openstack.share.v2
|
||||
:command: share network set
|
||||
|
||||
=====================
|
||||
share network subnets
|
||||
=====================
|
||||
|
||||
.. autoprogram-cliff:: openstack.share.v2
|
||||
:command: share network subnet *
|
||||
|
||||
===========
|
||||
share types
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
# 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 logging
|
||||
from operator import xor
|
||||
|
||||
from osc_lib.command import command
|
||||
from osc_lib import exceptions
|
||||
from osc_lib import utils as oscutils
|
||||
|
||||
from manilaclient.common._i18n import _
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CreateShareNetworkSubnet(command.ShowOne):
|
||||
"""Create a share network subnet."""
|
||||
_description = _("Create a share network subnet")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateShareNetworkSubnet, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"share_network",
|
||||
metavar="<share-network>",
|
||||
help=_("Share network name or ID.")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--neutron-net-id",
|
||||
metavar="<neutron-net-id>",
|
||||
default=None,
|
||||
help=_("Neutron network ID. Used to set up network for share "
|
||||
"servers (optional). Should be defined together with "
|
||||
"'--neutron-subnet-id'.")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--neutron-subnet-id",
|
||||
metavar="<neutron-subnet-id>",
|
||||
default=None,
|
||||
help=_("Neutron subnet ID. Used to set up network for share "
|
||||
"servers (optional). Should be defined together with "
|
||||
"'--neutron-net-id' to which this subnet belongs to. ")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--availability-zone",
|
||||
metavar="<availability-zone>",
|
||||
default=None,
|
||||
help=_("Optional availability zone that the subnet is available "
|
||||
"within (Default=None). If None, the subnet will be "
|
||||
"considered as being available across all availability "
|
||||
"zones.")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
share_client = self.app.client_manager.share
|
||||
|
||||
if xor(bool(parsed_args.neutron_net_id),
|
||||
bool(parsed_args.neutron_subnet_id)):
|
||||
raise exceptions.CommandError(
|
||||
"Both neutron_net_id and neutron_subnet_id should be "
|
||||
"specified. Alternatively, neither of them should be "
|
||||
"specified.")
|
||||
|
||||
share_network_id = oscutils.find_resource(
|
||||
share_client.share_networks,
|
||||
parsed_args.share_network).id
|
||||
|
||||
share_network_subnet = share_client.share_network_subnets.create(
|
||||
neutron_net_id=parsed_args.neutron_net_id,
|
||||
neutron_subnet_id=parsed_args.neutron_subnet_id,
|
||||
availability_zone=parsed_args.availability_zone,
|
||||
share_network_id=share_network_id
|
||||
)
|
||||
subnet_data = share_network_subnet._info
|
||||
|
||||
return self.dict2columns(subnet_data)
|
||||
|
||||
|
||||
class DeleteShareNetworkSubnet(command.Command):
|
||||
"""Create a share network subnet."""
|
||||
_description = _("Create a share network subnet")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteShareNetworkSubnet, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"share_network",
|
||||
metavar="<share-network>",
|
||||
help=_("Share network name or ID.")
|
||||
)
|
||||
parser.add_argument(
|
||||
"share_network_subnet",
|
||||
metavar="<share-network-subnet>",
|
||||
nargs="+",
|
||||
help=_("ID(s) of share network subnet(s) to be deleted.")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
share_client = self.app.client_manager.share
|
||||
result = 0
|
||||
|
||||
share_network_id = oscutils.find_resource(
|
||||
share_client.share_networks,
|
||||
parsed_args.share_network).id
|
||||
|
||||
for subnet in parsed_args.share_network_subnet:
|
||||
try:
|
||||
share_client.share_network_subnets.delete(
|
||||
share_network_id,
|
||||
subnet)
|
||||
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error(f"Failed to delete share network subnet with "
|
||||
f"ID {subnet}: {e}")
|
||||
if result > 0:
|
||||
total = len(parsed_args.share_network_subnet)
|
||||
raise exceptions.CommandError(
|
||||
f"{result} of {total} share network subnets failed to be "
|
||||
f"deleted.")
|
||||
|
||||
|
||||
class ShowShareNetworkSubnet(command.ShowOne):
|
||||
"""Show share network subnet."""
|
||||
_description = _("Show share network subnet")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowShareNetworkSubnet, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"share_network",
|
||||
metavar="<share-network>",
|
||||
help=_("Share network name or ID.")
|
||||
)
|
||||
parser.add_argument(
|
||||
"share_network_subnet",
|
||||
metavar="<share-network-subnet>",
|
||||
help=_("ID of share network subnet to show.")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
share_client = self.app.client_manager.share
|
||||
|
||||
share_network_id = oscutils.find_resource(
|
||||
share_client.share_networks,
|
||||
parsed_args.share_network).id
|
||||
|
||||
share_network_subnet = share_client.share_network_subnets.get(
|
||||
share_network_id,
|
||||
parsed_args.share_network_subnet)
|
||||
|
||||
return self.dict2columns(share_network_subnet._info)
|
|
@ -41,6 +41,7 @@ class FakeShareClient(object):
|
|||
self.share_replicas = mock.Mock()
|
||||
self.share_replica_export_locations = mock.Mock()
|
||||
self.share_networks = mock.Mock()
|
||||
self.share_network_subnets = mock.Mock()
|
||||
self.security_services = mock.Mock()
|
||||
self.shares.resource_class = osc_fakes.FakeResource(None, {})
|
||||
self.share_instance_export_locations = mock.Mock()
|
||||
|
@ -1095,6 +1096,64 @@ class FakeShareNetwork(object):
|
|||
return share_networks
|
||||
|
||||
|
||||
class FakeShareNetworkSubnet(object):
|
||||
"""Fake a share network subnet"""
|
||||
|
||||
@staticmethod
|
||||
def create_one_share_subnet(attrs=None):
|
||||
"""Create a fake share network subnet
|
||||
|
||||
:param Dictionary attrs:
|
||||
A dictionary with all attributes
|
||||
:return:
|
||||
A FakeResource object, with project_id, resource and so on
|
||||
"""
|
||||
|
||||
attrs = attrs or {}
|
||||
|
||||
share_network_subnet = {
|
||||
"availability_zone": None,
|
||||
"cidr": "10.0.0.0/24",
|
||||
"created_at": datetime.datetime.now().isoformat(),
|
||||
"gateway": "10.0.0.1",
|
||||
'id': str(uuid.uuid4()),
|
||||
"ip_version": 4,
|
||||
"mtu": "1500",
|
||||
"network_type": "vlan",
|
||||
"neutron_net_id": str(uuid.uuid4()),
|
||||
"neutron_subnet_id": str(uuid.uuid4()),
|
||||
"segmentation_id": 1010,
|
||||
"share_network_id": str(uuid.uuid4()),
|
||||
"share_network_name": str(uuid.uuid4()),
|
||||
"updated_at": datetime.datetime.now().isoformat(),
|
||||
}
|
||||
|
||||
share_network_subnet.update(attrs)
|
||||
share_network_subnet = osc_fakes.FakeResource(info=copy.deepcopy(
|
||||
share_network_subnet),
|
||||
loaded=True)
|
||||
return share_network_subnet
|
||||
|
||||
@staticmethod
|
||||
def create_share_network_subnets(attrs=None, count=2):
|
||||
"""Create multiple fake share network subnets.
|
||||
|
||||
:param Dictionary attrs:
|
||||
A dictionary with all attributes
|
||||
:param Integer count:
|
||||
The number of share network subnets to be faked
|
||||
:return:
|
||||
A list of FakeResource objects
|
||||
"""
|
||||
|
||||
share_network_subnets = []
|
||||
for n in range(count):
|
||||
share_network_subnets.append(
|
||||
FakeShareNetworkSubnet.create_one_share_subnet(attrs))
|
||||
|
||||
return share_network_subnets
|
||||
|
||||
|
||||
class FakeShareGroup(object):
|
||||
"""Fake a share group"""
|
||||
|
||||
|
|
|
@ -0,0 +1,213 @@
|
|||
# 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 uuid
|
||||
|
||||
from osc_lib import exceptions
|
||||
|
||||
from manilaclient.osc.v2 import share_network_subnets as osc_share_subnets
|
||||
from manilaclient.tests.unit.osc import osc_utils
|
||||
from manilaclient.tests.unit.osc.v2 import fakes as manila_fakes
|
||||
|
||||
|
||||
class TestShareNetworkSubnet(manila_fakes.TestShare):
|
||||
|
||||
def setUp(self):
|
||||
super(TestShareNetworkSubnet, self).setUp()
|
||||
|
||||
self.share_networks_mock = self.app.client_manager.share.share_networks
|
||||
self.share_networks_mock.reset_mock()
|
||||
|
||||
self.share_subnets_mock = (
|
||||
self.app.client_manager.share.share_network_subnets)
|
||||
self.share_subnets_mock.reset_mock()
|
||||
|
||||
|
||||
class TestShareNetworkSubnetCreate(TestShareNetworkSubnet):
|
||||
|
||||
def setUp(self):
|
||||
super(TestShareNetworkSubnetCreate, self).setUp()
|
||||
|
||||
self.share_network = (
|
||||
manila_fakes.FakeShareNetwork.create_one_share_network())
|
||||
self.share_networks_mock.get.return_value = self.share_network
|
||||
|
||||
self.share_network_subnet = (
|
||||
manila_fakes.FakeShareNetworkSubnet.create_one_share_subnet())
|
||||
self.share_subnets_mock.create.return_value = self.share_network_subnet
|
||||
|
||||
self.cmd = osc_share_subnets.CreateShareNetworkSubnet(
|
||||
self.app, None)
|
||||
|
||||
self.data = self.share_network_subnet._info.values()
|
||||
self.columns = self.share_network_subnet._info.keys()
|
||||
|
||||
def test_share_network_subnet_create_missing_args(self):
|
||||
arglist = []
|
||||
verifylist = []
|
||||
|
||||
self.assertRaises(osc_utils.ParserException,
|
||||
self.check_parser, self.cmd, arglist, verifylist)
|
||||
|
||||
def test_share_network_subnet_create(self):
|
||||
fake_neutron_net_id = str(uuid.uuid4())
|
||||
fake_neutron_subnet_id = str(uuid.uuid4())
|
||||
|
||||
arglist = [
|
||||
self.share_network.id,
|
||||
'--neutron-net-id', fake_neutron_net_id,
|
||||
'--neutron-subnet-id', fake_neutron_subnet_id,
|
||||
'--availability-zone', 'nova',
|
||||
]
|
||||
verifylist = [
|
||||
('share_network', self.share_network.id),
|
||||
('neutron_net_id', fake_neutron_net_id),
|
||||
('neutron_subnet_id', fake_neutron_subnet_id),
|
||||
('availability_zone', 'nova'),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.share_subnets_mock.create.assert_called_once_with(
|
||||
neutron_net_id=fake_neutron_net_id,
|
||||
neutron_subnet_id=fake_neutron_subnet_id,
|
||||
availability_zone='nova',
|
||||
share_network_id=self.share_network.id
|
||||
)
|
||||
|
||||
self.assertCountEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
||||
|
||||
def test_share_network_subnet_create_arg_group_exception(self):
|
||||
fake_neutron_net_id = str(uuid.uuid4())
|
||||
|
||||
arglist = [
|
||||
self.share_network.id,
|
||||
'--neutron-net-id', fake_neutron_net_id
|
||||
]
|
||||
verifylist = [
|
||||
('share_network', self.share_network.id),
|
||||
('neutron_net_id', fake_neutron_net_id)
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestShareNetworkSubnetDelete(TestShareNetworkSubnet):
|
||||
|
||||
def setUp(self):
|
||||
super(TestShareNetworkSubnetDelete, self).setUp()
|
||||
|
||||
self.share_network = (
|
||||
manila_fakes.FakeShareNetwork.create_one_share_network())
|
||||
self.share_networks_mock.get.return_value = self.share_network
|
||||
|
||||
self.share_network_subnets = (
|
||||
manila_fakes.FakeShareNetworkSubnet.create_share_network_subnets())
|
||||
|
||||
self.cmd = osc_share_subnets.DeleteShareNetworkSubnet(
|
||||
self.app, None)
|
||||
|
||||
def test_share_network_subnet_delete_missing_args(self):
|
||||
arglist = []
|
||||
verifylist = []
|
||||
|
||||
self.assertRaises(osc_utils.ParserException,
|
||||
self.check_parser, self.cmd, arglist, verifylist)
|
||||
|
||||
def test_share_network_subnets_delete(self):
|
||||
arglist = [
|
||||
self.share_network.id,
|
||||
self.share_network_subnets[0].id,
|
||||
self.share_network_subnets[1].id,
|
||||
]
|
||||
verifylist = [
|
||||
('share_network', self.share_network.id),
|
||||
('share_network_subnet', [self.share_network_subnets[0].id,
|
||||
self.share_network_subnets[1].id]),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.assertEqual(self.share_subnets_mock.delete.call_count,
|
||||
len(self.share_network_subnets))
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_share_network_subnet_delete_exception(self):
|
||||
arglist = [
|
||||
self.share_network.id,
|
||||
self.share_network_subnets[0].id,
|
||||
]
|
||||
verifylist = [
|
||||
('share_network', self.share_network.id),
|
||||
('share_network_subnet', [self.share_network_subnets[0].id]),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.share_subnets_mock.delete.side_effect = exceptions.CommandError()
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestShareNetworkSubnetShow(TestShareNetworkSubnet):
|
||||
|
||||
def setUp(self):
|
||||
super(TestShareNetworkSubnetShow, self).setUp()
|
||||
|
||||
self.share_network = (
|
||||
manila_fakes.FakeShareNetwork.create_one_share_network())
|
||||
self.share_networks_mock.get.return_value = self.share_network
|
||||
|
||||
self.share_network_subnet = (
|
||||
manila_fakes.FakeShareNetworkSubnet.create_one_share_subnet())
|
||||
self.share_subnets_mock.get.return_value = self.share_network_subnet
|
||||
|
||||
self.cmd = osc_share_subnets.ShowShareNetworkSubnet(
|
||||
self.app, None)
|
||||
|
||||
self.data = self.share_network_subnet._info.values()
|
||||
self.columns = self.share_network_subnet._info.keys()
|
||||
|
||||
def test_share_network_subnet_show_missing_args(self):
|
||||
arglist = []
|
||||
verifylist = []
|
||||
|
||||
self.assertRaises(osc_utils.ParserException,
|
||||
self.check_parser, self.cmd, arglist, verifylist)
|
||||
|
||||
def test_share_network_subnet_show(self):
|
||||
arglist = [
|
||||
self.share_network.id,
|
||||
self.share_network_subnet.id,
|
||||
]
|
||||
verifylist = [
|
||||
('share_network', self.share_network.id),
|
||||
('share_network_subnet', self.share_network_subnet.id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.share_subnets_mock.get.assert_called_once_with(
|
||||
self.share_network.id,
|
||||
self.share_network_subnet.id
|
||||
)
|
||||
|
||||
self.assertCountEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.data, data)
|
|
@ -113,6 +113,9 @@ openstack.share.v2 =
|
|||
share_network_delete = manilaclient.osc.v2.share_networks:DeleteShareNetwork
|
||||
share_network_set = manilaclient.osc.v2.share_networks:SetShareNetwork
|
||||
share_network_unset = manilaclient.osc.v2.share_networks:UnsetShareNetwork
|
||||
share_network_subnet_create = manilaclient.osc.v2.share_network_subnets:CreateShareNetworkSubnet
|
||||
share_network_subnet_delete = manilaclient.osc.v2.share_network_subnets:DeleteShareNetworkSubnet
|
||||
share_network_subnet_show = manilaclient.osc.v2.share_network_subnets:ShowShareNetworkSubnet
|
||||
share_group_create = manilaclient.osc.v2.share_groups:CreateShareGroup
|
||||
share_group_delete = manilaclient.osc.v2.share_groups:DeleteShareGroup
|
||||
share_group_list = manilaclient.osc.v2.share_groups:ListShareGroup
|
||||
|
|
Loading…
Reference in New Issue