diff --git a/doc/source/command-objects/network.rst b/doc/source/command-objects/network.rst index 7c791840fc..bb36667253 100644 --- a/doc/source/command-objects/network.rst +++ b/doc/source/command-objects/network.rst @@ -16,6 +16,7 @@ Create new network [--project [--project-domain ]] [--enable | --disable] [--share | --no-share] + [--availability-zone-hint ] .. option:: --project @@ -43,6 +44,11 @@ Create new network Do not share the network between projects +.. option:: --availability-zone-hint + + Availability Zone in which to create this network (requires the Network + Availability Zone extension, this option can be repeated). + .. _network_create-name: .. describe:: diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py index 38dff8d92a..7d9324f085 100644 --- a/openstackclient/network/v2/network.py +++ b/openstackclient/network/v2/network.py @@ -36,6 +36,8 @@ _formatters = { 'subnets': utils.format_list, 'admin_state_up': _format_admin_state, 'router_external': _format_router_external, + 'availability_zones': utils.format_list, + 'availability_zone_hints': utils.format_list, } @@ -93,8 +95,19 @@ class CreateNetwork(show.ShowOne): parser.add_argument( '--project', metavar='', - help="Owner's project (name or ID)") + help="Owner's project (name or ID)" + ) identity_common.add_project_domain_option_to_parser(parser) + + parser.add_argument( + '--availability-zone-hint', + action='append', + dest='availability_zone_hints', + metavar='', + help='Availability Zone in which to create this network ' + '(requires the Network Availability Zone extension, ' + 'this option can be repeated).', + ) return parser def take_action(self, parsed_args): @@ -119,6 +132,10 @@ class CreateNetwork(show.ShowOne): parsed_args.project_domain, ).id body['tenant_id'] = project_id + if parsed_args.availability_zone_hints is not None: + body['availability_zone_hints'] = \ + parsed_args.availability_zone_hints + return body @@ -181,6 +198,7 @@ class ListNetwork(lister.Lister): 'subnets', 'provider_network_type', 'router_external', + 'availability_zones', ) column_headers = ( 'ID', @@ -192,6 +210,7 @@ class ListNetwork(lister.Lister): 'Subnets', 'Network Type', 'Router Type', + 'Availability Zones', ) else: columns = ( diff --git a/openstackclient/tests/network/v2/fakes.py b/openstackclient/tests/network/v2/fakes.py index de885c62ab..146ba61649 100644 --- a/openstackclient/tests/network/v2/fakes.py +++ b/openstackclient/tests/network/v2/fakes.py @@ -85,6 +85,8 @@ class FakeNetwork(object): 'provider_network_type': 'vlan', 'router_external': True, 'is_dirty': True, + 'availability_zones': [], + 'availability_zone_hints': [], } # Overwrite default attributes. @@ -93,7 +95,8 @@ class FakeNetwork(object): # Set default methods. network_methods = { 'keys': ['id', 'name', 'admin_state_up', 'router_external', - 'status', 'subnets', 'tenant_id'], + 'status', 'subnets', 'tenant_id', 'availability_zones', + 'availability_zone_hints'], } # Overwrite default methods. diff --git a/openstackclient/tests/network/v2/test_network.py b/openstackclient/tests/network/v2/test_network.py index 12ac802c82..37cc66742a 100644 --- a/openstackclient/tests/network/v2/test_network.py +++ b/openstackclient/tests/network/v2/test_network.py @@ -37,11 +37,16 @@ class TestCreateNetworkIdentityV3(TestNetwork): # The new network created. _network = network_fakes.FakeNetwork.create_one_network( - attrs={'tenant_id': identity_fakes_v3.project_id} + attrs={ + 'tenant_id': identity_fakes_v3.project_id, + 'availability_zone_hints': ["nova"], + } ) columns = ( 'admin_state_up', + 'availability_zone_hints', + 'availability_zones', 'id', 'name', 'project_id', @@ -52,6 +57,8 @@ class TestCreateNetworkIdentityV3(TestNetwork): data = ( network._format_admin_state(_network.admin_state_up), + utils.format_list(_network.availability_zone_hints), + utils.format_list(_network.availability_zones), _network.id, _network.name, _network.project_id, @@ -129,6 +136,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): "--share", "--project", identity_fakes_v3.project_name, "--project-domain", identity_fakes_v3.domain_name, + "--availability-zone-hint", "nova", self._network.name, ] verifylist = [ @@ -136,6 +144,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): ('shared', True), ('project', identity_fakes_v3.project_name), ('project_domain', identity_fakes_v3.domain_name), + ('availability_zone_hints', ["nova"]), ('name', self._network.name), ] @@ -144,6 +153,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): self.network.create_network.assert_called_with(**{ 'admin_state_up': False, + 'availability_zone_hints': ["nova"], 'name': self._network.name, 'shared': True, 'tenant_id': identity_fakes_v3.project_id, @@ -184,6 +194,8 @@ class TestCreateNetworkIdentityV2(TestNetwork): columns = ( 'admin_state_up', + 'availability_zone_hints', + 'availability_zones', 'id', 'name', 'project_id', @@ -194,6 +206,8 @@ class TestCreateNetworkIdentityV2(TestNetwork): data = ( network._format_admin_state(_network.admin_state_up), + utils.format_list(_network.availability_zone_hints), + utils.format_list(_network.availability_zones), _network.id, _network.name, _network.project_id, @@ -324,6 +338,7 @@ class TestListNetwork(TestNetwork): 'Subnets', 'Network Type', 'Router Type', + 'Availability Zones', ) data = [] @@ -346,6 +361,7 @@ class TestListNetwork(TestNetwork): utils.format_list(net.subnets), net.provider_network_type, network._format_router_external(net.router_external), + utils.format_list(net.availability_zones), )) def setUp(self): @@ -483,6 +499,8 @@ class TestShowNetwork(TestNetwork): columns = ( 'admin_state_up', + 'availability_zone_hints', + 'availability_zones', 'id', 'name', 'project_id', @@ -493,6 +511,8 @@ class TestShowNetwork(TestNetwork): data = ( network._format_admin_state(_network.admin_state_up), + utils.format_list(_network.availability_zone_hints), + utils.format_list(_network.availability_zones), _network.id, _network.name, _network.project_id,