summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/command-objects/network.rst10
-rw-r--r--openstackclient/network/v2/network.py21
-rw-r--r--openstackclient/tests/identity/v2_0/fakes.py7
-rw-r--r--openstackclient/tests/network/v2/test_network.py100
4 files changed, 138 insertions, 0 deletions
diff --git a/doc/source/command-objects/network.rst b/doc/source/command-objects/network.rst
index 0edd2980..dcba9f82 100644
--- a/doc/source/command-objects/network.rst
+++ b/doc/source/command-objects/network.rst
@@ -13,10 +13,20 @@ Create new network
.. code:: bash
os network create
+ [--domain <domain>]
[--enable | --disable]
+ [--project <project>]
[--share | --no-share]
<name>
+.. option:: --domain <domain>
+
+ Owner's domain (name or ID)"
+
+.. option:: --project <project>
+
+ Owner's project (name or ID)
+
.. option:: --enable
Enable network (default)
diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py
index 1a79c80a..9b246642 100644
--- a/openstackclient/network/v2/network.py
+++ b/openstackclient/network/v2/network.py
@@ -22,6 +22,7 @@ from cliff import show
from openstackclient.common import exceptions
from openstackclient.common import utils
+from openstackclient.identity import common as identity_common
from openstackclient.network import common
@@ -82,6 +83,14 @@ class CreateNetwork(show.ShowOne):
action='store_false',
help='Do not share the network between projects',
)
+ parser.add_argument(
+ '--project',
+ metavar='<project>',
+ help="Owner's project (name or ID)")
+ parser.add_argument(
+ '--domain',
+ metavar='<domain>',
+ help="Owner's domain (name or ID)")
return parser
def take_action(self, parsed_args):
@@ -101,6 +110,18 @@ class CreateNetwork(show.ShowOne):
'admin_state_up': parsed_args.admin_state}
if parsed_args.shared is not None:
body['shared'] = parsed_args.shared
+ if parsed_args.project is not None:
+ identity_client = self.app.client_manager.identity
+ if parsed_args.domain is not None:
+ domain = identity_common.find_domain(identity_client,
+ parsed_args.domain)
+ project_id = utils.find_resource(identity_client.projects,
+ parsed_args.project,
+ domain_id=domain.id).id
+ else:
+ project_id = utils.find_resource(identity_client.projects,
+ parsed_args.project).id
+ body['tenant_id'] = project_id
return {'network': body}
diff --git a/openstackclient/tests/identity/v2_0/fakes.py b/openstackclient/tests/identity/v2_0/fakes.py
index b136f841..6688606a 100644
--- a/openstackclient/tests/identity/v2_0/fakes.py
+++ b/openstackclient/tests/identity/v2_0/fakes.py
@@ -142,6 +142,13 @@ class FakeIdentityv2Client(object):
self.auth_token = kwargs['token']
self.management_url = kwargs['endpoint']
+ def __getattr__(self, name):
+ # Map v3 'projects' back to v2 'tenants'
+ if name == "projects":
+ return self.tenants
+ else:
+ raise AttributeError(name)
+
class TestIdentityv2(utils.TestCommand):
def setUp(self):
diff --git a/openstackclient/tests/network/v2/test_network.py b/openstackclient/tests/network/v2/test_network.py
index e14dd88b..90085f28 100644
--- a/openstackclient/tests/network/v2/test_network.py
+++ b/openstackclient/tests/network/v2/test_network.py
@@ -16,6 +16,9 @@ import mock
from openstackclient.common import exceptions
from openstackclient.network.v2 import network
+from openstackclient.tests import fakes
+from openstackclient.tests.identity.v2_0 import fakes as identity_fakes_v2
+from openstackclient.tests.identity.v3 import fakes as identity_fakes_v3
from openstackclient.tests.network import common
RESOURCE = 'network'
@@ -65,6 +68,7 @@ class TestCreateNetwork(common.TestNetworkBase):
('name', FAKE_NAME),
('admin_state', True),
('shared', None),
+ ('project', None),
]
mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
self.app.client_manager.network.create_network = mocker
@@ -85,15 +89,36 @@ class TestCreateNetwork(common.TestNetworkBase):
arglist = [
"--disable",
"--share",
+ "--project", identity_fakes_v3.project_name,
+ "--domain", identity_fakes_v3.domain_name,
FAKE_NAME,
] + self.given_show_options
verifylist = [
('admin_state', False),
('shared', True),
+ ('project', identity_fakes_v3.project_name),
+ ('domain', identity_fakes_v3.domain_name),
('name', FAKE_NAME),
] + self.then_show_options
mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
self.app.client_manager.network.create_network = mocker
+ identity_client = identity_fakes_v3.FakeIdentityv3Client(
+ endpoint=fakes.AUTH_URL,
+ token=fakes.AUTH_TOKEN,
+ )
+ self.app.client_manager.identity = identity_client
+ self.projects_mock = self.app.client_manager.identity.projects
+ self.projects_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes_v3.PROJECT),
+ loaded=True,
+ )
+ self.domains_mock = self.app.client_manager.identity.domains
+ self.domains_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes_v3.DOMAIN),
+ loaded=True,
+ )
cmd = network.CreateNetwork(self.app, self.namespace)
parsed_args = self.check_parser(cmd, arglist, verifylist)
@@ -104,6 +129,7 @@ class TestCreateNetwork(common.TestNetworkBase):
'admin_state_up': False,
'name': FAKE_NAME,
'shared': True,
+ 'tenant_id': identity_fakes_v3.project_id,
}
})
self.assertEqual(FILTERED, result)
@@ -135,6 +161,80 @@ class TestCreateNetwork(common.TestNetworkBase):
})
self.assertEqual(FILTERED, result)
+ def test_create_with_project_identityv2(self):
+ arglist = [
+ "--project", identity_fakes_v2.project_name,
+ FAKE_NAME,
+
+ ]
+ verifylist = [
+ ('admin_state', True),
+ ('shared', None),
+ ('name', FAKE_NAME),
+ ('project', identity_fakes_v2.project_name),
+ ]
+ mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
+ self.app.client_manager.network.create_network = mocker
+ identity_client = identity_fakes_v2.FakeIdentityv2Client(
+ endpoint=fakes.AUTH_URL,
+ token=fakes.AUTH_TOKEN,
+ )
+ self.app.client_manager.identity = identity_client
+ self.projects_mock = self.app.client_manager.identity.tenants
+ self.projects_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes_v2.PROJECT),
+ loaded=True,
+ )
+ cmd = network.CreateNetwork(self.app, self.namespace)
+
+ parsed_args = self.check_parser(cmd, arglist, verifylist)
+ result = list(cmd.take_action(parsed_args))
+
+ mocker.assert_called_with({
+ RESOURCE: {
+ 'admin_state_up': True,
+ 'name': FAKE_NAME,
+ 'tenant_id': identity_fakes_v2.project_id,
+ }
+ })
+ self.assertEqual(FILTERED, result)
+
+ def test_create_with_domain_identityv2(self):
+ arglist = [
+ "--project", identity_fakes_v3.project_name,
+ "--domain", identity_fakes_v3.domain_name,
+ FAKE_NAME,
+ ]
+ verifylist = [
+ ('admin_state', True),
+ ('shared', None),
+ ('project', identity_fakes_v3.project_name),
+ ('domain', identity_fakes_v3.domain_name),
+ ('name', FAKE_NAME),
+ ]
+ mocker = mock.Mock(return_value=copy.deepcopy(RESPONSE))
+ self.app.client_manager.network.create_network = mocker
+ identity_client = identity_fakes_v2.FakeIdentityv2Client(
+ endpoint=fakes.AUTH_URL,
+ token=fakes.AUTH_TOKEN,
+ )
+ self.app.client_manager.identity = identity_client
+ self.projects_mock = self.app.client_manager.identity.tenants
+ self.projects_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes_v2.PROJECT),
+ loaded=True,
+ )
+ cmd = network.CreateNetwork(self.app, self.namespace)
+ parsed_args = self.check_parser(cmd, arglist, verifylist)
+
+ self.assertRaises(
+ AttributeError,
+ cmd.take_action,
+ parsed_args,
+ )
+
class TestDeleteNetwork(common.TestNetworkBase):
def test_delete(self):