summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Gessau <gessau@cisco.com>2015-09-21 14:44:04 +0000
committerHenry Gessau <gessau@cisco.com>2015-09-21 14:44:04 +0000
commit716eb017d35829c18745c4c0279b895784c297f1 (patch)
tree47e0266b47cb7b622f4c8edbe627664902776a41
parent8292cb85f8830e65284736ea1f9bae2f344c084a (diff)
downloadpython-neutronclient-716eb017d35829c18745c4c0279b895784c297f1.tar.gz
Revert "Remove Cisco-specific neutron client commands"
This reverts commit 8292cb85f8830e65284736ea1f9bae2f344c084a. This cannot go in 3.x since it requires a version bump. Will repropose for Mitaka (4.x client). Change-Id: Ia89d3e3c9c4a27ffbe3089354b4eaeca527de8ae
-rw-r--r--neutronclient/neutron/v2_0/credential.py73
-rw-r--r--neutronclient/neutron/v2_0/networkprofile.py148
-rw-r--r--neutronclient/neutron/v2_0/policyprofile.py72
-rw-r--r--neutronclient/shell.py15
-rw-r--r--neutronclient/tests/unit/test_cli20.py3
-rw-r--r--neutronclient/tests/unit/test_cli20_credential.py77
-rw-r--r--neutronclient/tests/unit/test_cli20_networkprofile.py133
-rw-r--r--neutronclient/tests/unit/test_cli20_policyprofile.py71
-rw-r--r--neutronclient/v2_0/client.py81
9 files changed, 672 insertions, 1 deletions
diff --git a/neutronclient/neutron/v2_0/credential.py b/neutronclient/neutron/v2_0/credential.py
new file mode 100644
index 0000000..c397627
--- /dev/null
+++ b/neutronclient/neutron/v2_0/credential.py
@@ -0,0 +1,73 @@
+# 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.
+#
+
+from neutronclient.i18n import _
+from neutronclient.neutron import v2_0 as neutronV20
+
+
+class ListCredential(neutronV20.ListCommand):
+ """List credentials that belong to a given tenant."""
+
+ resource = 'credential'
+ _formatters = {}
+ list_columns = ['credential_id', 'credential_name', 'user_name',
+ 'password', 'type']
+
+
+class ShowCredential(neutronV20.ShowCommand):
+ """Show information of a given credential."""
+
+ resource = 'credential'
+ allow_names = False
+
+
+class CreateCredential(neutronV20.CreateCommand):
+ """Create a credential."""
+
+ resource = 'credential'
+
+ def add_known_arguments(self, parser):
+ parser.add_argument(
+ 'credential_name',
+ help=_('Name/IP address for credential.'))
+ parser.add_argument(
+ 'credential_type',
+ help=_('Type of the credential.'))
+ parser.add_argument(
+ '--username',
+ help=_('Username for the credential.'))
+ parser.add_argument(
+ '--password',
+ help=_('Password for the credential.'))
+
+ def args2body(self, parsed_args):
+ body = {'credential': {
+ 'credential_name': parsed_args.credential_name}}
+
+ if parsed_args.credential_type:
+ body['credential'].update({'type':
+ parsed_args.credential_type})
+ if parsed_args.username:
+ body['credential'].update({'user_name':
+ parsed_args.username})
+ if parsed_args.password:
+ body['credential'].update({'password':
+ parsed_args.password})
+ return body
+
+
+class DeleteCredential(neutronV20.DeleteCommand):
+ """Delete a given credential."""
+
+ resource = 'credential'
+ allow_names = False
diff --git a/neutronclient/neutron/v2_0/networkprofile.py b/neutronclient/neutron/v2_0/networkprofile.py
new file mode 100644
index 0000000..ed85875
--- /dev/null
+++ b/neutronclient/neutron/v2_0/networkprofile.py
@@ -0,0 +1,148 @@
+# 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.
+#
+
+from __future__ import print_function
+
+from neutronclient.i18n import _
+from neutronclient.neutron import v2_0 as neutronV20
+from neutronclient.neutron.v2_0 import parse_args_to_dict
+
+RESOURCE = 'network_profile'
+SEGMENT_TYPE_CHOICES = ['vlan', 'overlay', 'multi-segment', 'trunk']
+
+
+class ListNetworkProfile(neutronV20.ListCommand):
+ """List network profiles that belong to a given tenant."""
+
+ resource = RESOURCE
+ _formatters = {}
+ list_columns = ['id', 'name', 'segment_type', 'sub_type', 'segment_range',
+ 'physical_network', 'multicast_ip_index',
+ 'multicast_ip_range']
+
+
+class ShowNetworkProfile(neutronV20.ShowCommand):
+ """Show information of a given network profile."""
+
+ resource = RESOURCE
+ allow_names = True
+
+
+class CreateNetworkProfile(neutronV20.CreateCommand):
+ """Create a network profile."""
+
+ resource = RESOURCE
+
+ def add_known_arguments(self, parser):
+ parser.add_argument('name',
+ help=_('Name for network profile.'))
+ parser.add_argument('segment_type',
+ choices=SEGMENT_TYPE_CHOICES,
+ help='Segment type.')
+ # TODO(Abhishek): Check on sub-type choices depending on segment_type
+ parser.add_argument('--sub_type',
+ help=_('Sub-type for the segment. Available '
+ 'sub-types for overlay segments: '
+ 'native, enhanced; For trunk segments: '
+ 'vlan, overlay.'))
+ parser.add_argument('--segment_range',
+ help=_('Range for the segment.'))
+ parser.add_argument('--physical_network',
+ help=_('Name for the physical network.'))
+ parser.add_argument('--multicast_ip_range',
+ help=_('Multicast IPv4 range.'))
+ parser.add_argument("--add-tenant",
+ action='append', dest='add_tenants',
+ help=_("Add tenant to the network profile. "
+ "You can repeat this option."))
+
+ def args2body(self, parsed_args):
+ body = {'network_profile': {'name': parsed_args.name}}
+ if parsed_args.segment_type:
+ body['network_profile'].update({'segment_type':
+ parsed_args.segment_type})
+ if parsed_args.sub_type:
+ body['network_profile'].update({'sub_type':
+ parsed_args.sub_type})
+ if parsed_args.segment_range:
+ body['network_profile'].update({'segment_range':
+ parsed_args.segment_range})
+ if parsed_args.physical_network:
+ body['network_profile'].update({'physical_network':
+ parsed_args.physical_network})
+ if parsed_args.multicast_ip_range:
+ body['network_profile'].update({'multicast_ip_range':
+ parsed_args.multicast_ip_range})
+ if parsed_args.add_tenants:
+ body['network_profile'].update({'add_tenants':
+ parsed_args.add_tenants})
+ return body
+
+
+class DeleteNetworkProfile(neutronV20.DeleteCommand):
+ """Delete a given network profile."""
+
+ resource = RESOURCE
+ allow_names = True
+
+
+class UpdateNetworkProfile(neutronV20.UpdateCommand):
+ """Update network profile's information."""
+
+ resource = RESOURCE
+
+ def add_known_arguments(self, parser):
+ parser.add_argument("--remove-tenant",
+ action='append', dest='remove_tenants',
+ help=_("Remove tenant from the network profile. "
+ "You can repeat this option."))
+ parser.add_argument("--add-tenant",
+ action='append', dest='add_tenants',
+ help=_("Add tenant to the network profile. "
+ "You can repeat this option."))
+
+ def args2body(self, parsed_args):
+ body = {'network_profile': {}}
+ if parsed_args.remove_tenants:
+ body['network_profile']['remove_tenants'] = (parsed_args.
+ remove_tenants)
+ if parsed_args.add_tenants:
+ body['network_profile']['add_tenants'] = parsed_args.add_tenants
+ return body
+
+
+# Aaron: This function is deprecated
+class UpdateNetworkProfileV2(neutronV20.NeutronCommand):
+
+ api = 'network'
+ resource = RESOURCE
+
+ def get_parser(self, prog_name):
+ parser = super(UpdateNetworkProfileV2, self).get_parser(prog_name)
+ parser.add_argument("--remove-tenant",
+ help="Remove tenant from the network profile.")
+ return parser
+
+ def run(self, parsed_args):
+ self.log.debug('run(%s)' % parsed_args)
+ neutron_client = self.get_client()
+ neutron_client.format = parsed_args.request_format
+ data = {self.resource: parse_args_to_dict(parsed_args)}
+ if parsed_args.remove_tenant:
+ data[self.resource]['remove_tenant'] = parsed_args.remove_tenant
+ neutron_client.update_network_profile(parsed_args.id,
+ {self.resource: data})
+ print((_('Updated %(resource)s: %(id)s') %
+ {'id': parsed_args.id, 'resource': self.resource}),
+ file=self.app.stdout)
+ return
diff --git a/neutronclient/neutron/v2_0/policyprofile.py b/neutronclient/neutron/v2_0/policyprofile.py
new file mode 100644
index 0000000..7ff00db
--- /dev/null
+++ b/neutronclient/neutron/v2_0/policyprofile.py
@@ -0,0 +1,72 @@
+# 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.
+#
+
+from __future__ import print_function
+
+from neutronclient.i18n import _
+from neutronclient.neutron import v2_0 as neutronV20
+from neutronclient.neutron.v2_0 import parse_args_to_dict
+
+RESOURCE = 'policy_profile'
+
+
+class ListPolicyProfile(neutronV20.ListCommand):
+ """List policy profiles that belong to a given tenant."""
+
+ resource = RESOURCE
+ _formatters = {}
+ list_columns = ['id', 'name']
+
+
+class ShowPolicyProfile(neutronV20.ShowCommand):
+ """Show information of a given policy profile."""
+
+ resource = RESOURCE
+ allow_names = True
+
+
+class UpdatePolicyProfile(neutronV20.UpdateCommand):
+ """Update policy profile's information."""
+
+ resource = RESOURCE
+
+
+class UpdatePolicyProfileV2(neutronV20.UpdateCommand):
+ """Update policy profile's information."""
+
+ api = 'network'
+ resource = RESOURCE
+
+ def get_parser(self, prog_name):
+ parser = super(UpdatePolicyProfileV2, self).get_parser(prog_name)
+ parser.add_argument("--add-tenant",
+ help=_("Add tenant to the policy profile."))
+ parser.add_argument("--remove-tenant",
+ help=_("Remove tenant from the policy profile."))
+ return parser
+
+ def run(self, parsed_args):
+ self.log.debug('run(%s)' % parsed_args)
+ neutron_client = self.get_client()
+ neutron_client.format = parsed_args.request_format
+ data = {self.resource: parse_args_to_dict(parsed_args)}
+ if parsed_args.add_tenant:
+ data[self.resource]['add_tenant'] = parsed_args.add_tenant
+ if parsed_args.remove_tenant:
+ data[self.resource]['remove_tenant'] = parsed_args.remove_tenant
+ neutron_client.update_policy_profile(parsed_args.id,
+ {self.resource: data})
+ print((_('Updated %(resource)s: %(id)s') %
+ {'id': parsed_args.id, 'resource': self.resource}),
+ file=self.app.stdout)
+ return
diff --git a/neutronclient/shell.py b/neutronclient/shell.py
index fae2a21..cc50a95 100644
--- a/neutronclient/shell.py
+++ b/neutronclient/shell.py
@@ -48,6 +48,7 @@ from neutronclient.i18n import _
from neutronclient.neutron.v2_0 import address_scope
from neutronclient.neutron.v2_0 import agent
from neutronclient.neutron.v2_0 import agentscheduler
+from neutronclient.neutron.v2_0 import credential
from neutronclient.neutron.v2_0 import extension
from neutronclient.neutron.v2_0 import floatingip
from neutronclient.neutron.v2_0.fw import firewall
@@ -66,8 +67,10 @@ from neutronclient.neutron.v2_0 import metering
from neutronclient.neutron.v2_0.nec import packetfilter
from neutronclient.neutron.v2_0 import netpartition
from neutronclient.neutron.v2_0 import network
+from neutronclient.neutron.v2_0 import networkprofile
from neutronclient.neutron.v2_0.nsx import networkgateway
from neutronclient.neutron.v2_0.nsx import qos_queue
+from neutronclient.neutron.v2_0 import policyprofile
from neutronclient.neutron.v2_0 import port
from neutronclient.neutron.v2_0.qos import bandwidth_limit_rule
from neutronclient.neutron.v2_0.qos import policy as qos_policy
@@ -303,6 +306,18 @@ COMMAND_V2 = {
'firewall-create': firewall.CreateFirewall,
'firewall-update': firewall.UpdateFirewall,
'firewall-delete': firewall.DeleteFirewall,
+ 'cisco-credential-list': credential.ListCredential,
+ 'cisco-credential-show': credential.ShowCredential,
+ 'cisco-credential-create': credential.CreateCredential,
+ 'cisco-credential-delete': credential.DeleteCredential,
+ 'cisco-network-profile-list': networkprofile.ListNetworkProfile,
+ 'cisco-network-profile-show': networkprofile.ShowNetworkProfile,
+ 'cisco-network-profile-create': networkprofile.CreateNetworkProfile,
+ 'cisco-network-profile-delete': networkprofile.DeleteNetworkProfile,
+ 'cisco-network-profile-update': networkprofile.UpdateNetworkProfile,
+ 'cisco-policy-profile-list': policyprofile.ListPolicyProfile,
+ 'cisco-policy-profile-show': policyprofile.ShowPolicyProfile,
+ 'cisco-policy-profile-update': policyprofile.UpdatePolicyProfile,
'ipsec-site-connection-list': (
ipsec_site_connection.ListIPsecSiteConnection
),
diff --git a/neutronclient/tests/unit/test_cli20.py b/neutronclient/tests/unit/test_cli20.py
index 7790223..94d979c 100644
--- a/neutronclient/tests/unit/test_cli20.py
+++ b/neutronclient/tests/unit/test_cli20.py
@@ -42,7 +42,8 @@ ENDURL = 'localurl'
non_admin_status_resources = ['subnet', 'floatingip', 'security_group',
'security_group_rule', 'qos_queue',
'network_gateway', 'gateway_device',
- 'ikepolicy',
+ 'credential', 'network_profile',
+ 'policy_profile', 'ikepolicy',
'ipsecpolicy', 'metering_label',
'metering_label_rule', 'net_partition',
'fox_socket', 'subnetpool',
diff --git a/neutronclient/tests/unit/test_cli20_credential.py b/neutronclient/tests/unit/test_cli20_credential.py
new file mode 100644
index 0000000..4f4a1d3
--- /dev/null
+++ b/neutronclient/tests/unit/test_cli20_credential.py
@@ -0,0 +1,77 @@
+# Copyright 2013 Cisco Systems Inc.
+# All Rights Reserved
+#
+# 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 sys
+
+from neutronclient.neutron.v2_0 import credential
+from neutronclient.tests.unit import test_cli20
+
+
+class CLITestV20Credential(test_cli20.CLITestV20Base):
+
+ def test_create_credential(self):
+ """Create credential: myid."""
+ resource = 'credential'
+ cmd = credential.CreateCredential(test_cli20.MyApp(sys.stdout), None)
+ name = 'myname'
+ myid = 'myid'
+ type = 'mytype'
+ args = [name, type]
+ position_names = ['credential_name', 'type']
+ position_values = [name, type]
+ self._test_create_resource(resource, cmd, name, myid, args,
+ position_names, position_values)
+
+ def test_list_credentials_detail(self):
+ """List credentials: -D."""
+ resources = 'credentials'
+ cmd = credential.ListCredential(test_cli20.MyApp(sys.stdout), None)
+ contents = [{'credential_name': 'myname', 'type': 'mytype'}]
+ self._test_list_resources(resources, cmd, True,
+ response_contents=contents)
+
+ def test_list_credential_known_option_after_unknown(self):
+ """List credential: -- --tags a b --request-format xml."""
+ resources = 'credentials'
+ cmd = credential.ListCredential(test_cli20.MyApp(sys.stdout), None)
+ contents = [{'credential_name': 'myname', 'type': 'mytype'}]
+ self._test_list_resources(resources, cmd, tags=['a', 'b'],
+ response_contents=contents)
+
+ def test_list_credential_fields(self):
+ """List credential: --fields a --fields b -- --fields c d."""
+ resources = 'credentials'
+ cmd = credential.ListCredential(test_cli20.MyApp(sys.stdout), None)
+ contents = [{'credential_name': 'myname', 'type': 'mytype'}]
+ self._test_list_resources(resources, cmd,
+ fields_1=['a', 'b'], fields_2=['c', 'd'],
+ response_contents=contents)
+
+ def test_show_credential(self):
+ """Show credential: --fields id --fields name myid."""
+ resource = 'credential'
+ cmd = credential.ShowCredential(test_cli20.MyApp(sys.stdout), None)
+ args = ['--fields', 'id', '--fields', 'name', self.test_id]
+ self._test_show_resource(resource, cmd, self.test_id, args,
+ ['id', 'name'])
+
+ def test_delete_credential(self):
+ """Delete credential: myid."""
+ resource = 'credential'
+ cmd = credential.DeleteCredential(test_cli20.MyApp(sys.stdout), None)
+ myid = 'myid'
+ args = [myid]
+ self._test_delete_resource(resource, cmd, myid, args)
diff --git a/neutronclient/tests/unit/test_cli20_networkprofile.py b/neutronclient/tests/unit/test_cli20_networkprofile.py
new file mode 100644
index 0000000..c5a7353
--- /dev/null
+++ b/neutronclient/tests/unit/test_cli20_networkprofile.py
@@ -0,0 +1,133 @@
+# Copyright 2013 Cisco Systems Inc.
+# All Rights Reserved
+#
+# 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 sys
+
+from neutronclient.neutron.v2_0 import networkprofile
+from neutronclient.tests.unit import test_cli20
+
+
+class CLITestV20NetworkProfile(test_cli20.CLITestV20Base):
+
+ def test_create_networkprofile(self):
+ """Create networkprofile: myid."""
+ resource = 'network_profile'
+ cmd = networkprofile.CreateNetworkProfile(test_cli20.
+ MyApp(sys.stdout), None)
+ name = 'myname'
+ myid = 'myid'
+ segment_type = 'vlan'
+ args = [name, segment_type]
+ position_names = ['name', 'segment_type']
+ position_values = [name, segment_type]
+ self._test_create_resource(resource, cmd, name, myid, args,
+ position_names, position_values)
+
+ def test_list_networkprofile_detail(self):
+ """List networkprofile: -D."""
+ resources = 'network_profiles'
+ cmd = networkprofile.ListNetworkProfile(test_cli20.MyApp(sys.stdout),
+ None)
+ contents = [{'name': 'myname', 'segment_type': 'vlan'}]
+ self._test_list_resources(resources, cmd, True,
+ response_contents=contents)
+
+ def test_list_networkprofile_known_option_after_unknown(self):
+ """List networkprofile: -- --tags a b --request-format xml."""
+ resources = 'network_profiles'
+ cmd = networkprofile.ListNetworkProfile(test_cli20.MyApp(sys.stdout),
+ None)
+ contents = [{'name': 'myname', 'segment_type': 'vlan'}]
+ self._test_list_resources(resources, cmd, tags=['a', 'b'],
+ response_contents=contents)
+
+ def test_list_networkprofile_fields(self):
+ """List networkprofile: --fields a --fields b -- --fields c d."""
+ resources = 'network_profiles'
+ cmd = networkprofile.ListNetworkProfile(test_cli20.MyApp(sys.stdout),
+ None)
+ contents = [{'name': 'myname', 'segment_type': 'vlan'}]
+ self._test_list_resources(resources, cmd,
+ fields_1=['a', 'b'], fields_2=['c', 'd'],
+ response_contents=contents)
+
+ def test_show_networkprofile(self):
+ """Show networkprofile: --fields id --fields name myid."""
+ resource = 'network_profile'
+ cmd = networkprofile.ShowNetworkProfile(test_cli20.MyApp(sys.stdout),
+ None)
+ args = ['--fields', 'id', '--fields', 'name', self.test_id]
+ self._test_show_resource(resource, cmd, self.test_id, args,
+ ['id', 'name'])
+
+ def test_delete_networkprofile(self):
+ """Delete networkprofile: myid."""
+ resource = 'network_profile'
+ cmd = networkprofile.DeleteNetworkProfile(test_cli20.
+ MyApp(sys.stdout), None)
+ myid = 'myid'
+ args = [myid]
+ self._test_delete_resource(resource, cmd, myid, args)
+
+ def test_create_networkprofile_trunk(self):
+ """Create networkprofile: myid."""
+ resource = 'network_profile'
+ cmd = networkprofile.CreateNetworkProfile(test_cli20.
+ MyApp(sys.stdout), None)
+ name = 'myname'
+ myid = 'myid'
+ segment_type = 'trunk'
+ args = [name, segment_type, '--sub_type', 'vlan']
+ position_names = ['name', 'segment_type', ]
+ position_values = [name, segment_type, ]
+ self._test_create_resource(resource, cmd, name, myid, args,
+ position_names, position_values,
+ sub_type='vlan')
+
+ def test_list_networkprofile_trunk_detail(self):
+ """List networkprofile: -D."""
+ resources = 'network_profiles'
+ cmd = networkprofile.ListNetworkProfile(test_cli20.MyApp(sys.stdout),
+ None)
+ contents = [{'name': 'myname', 'segment_type': 'trunk',
+ '--sub_type': 'vlan'}]
+ self._test_list_resources(resources, cmd, True,
+ response_contents=contents)
+
+ def test_create_networkprofile_multi_tenants(self):
+ """Create networkprofile with mulitple tenants: myid."""
+ resource = 'network_profile'
+ cmd = networkprofile.CreateNetworkProfile(test_cli20.
+ MyApp(sys.stdout), None)
+ name = 'myname'
+ myid = 'myid'
+ segment_type = 'vlan'
+ args = [name, segment_type, '--add-tenant', 'demo',
+ '--add-tenant', 'admin']
+ position_names = ['name', 'segment_type', 'add_tenants']
+ position_values = [name, segment_type, ['demo', 'admin']]
+ self._test_create_resource(resource, cmd, name, myid, args,
+ position_names, position_values)
+
+ def test_update_networkprofile_multi_tenants(self):
+ resource = 'network_profile'
+ cmd = networkprofile.UpdateNetworkProfile(test_cli20.
+ MyApp(sys.stdout), None)
+ args = ['myid', '--add-tenant', 'service', '--add-tenant', 'demo',
+ '--remove-tenant', 'demo']
+ extrafields = {'add_tenants': ['service', 'demo'],
+ 'remove_tenants': ['demo']}
+ self._test_update_resource(resource, cmd, 'myid', args, extrafields)
diff --git a/neutronclient/tests/unit/test_cli20_policyprofile.py b/neutronclient/tests/unit/test_cli20_policyprofile.py
new file mode 100644
index 0000000..94cbf2c
--- /dev/null
+++ b/neutronclient/tests/unit/test_cli20_policyprofile.py
@@ -0,0 +1,71 @@
+# Copyright 2013 Cisco Systems Inc.
+# All Rights Reserved
+#
+# 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 sys
+
+from neutronclient.neutron.v2_0 import policyprofile
+from neutronclient.tests.unit import test_cli20
+
+
+class CLITestV20PolicyProfile(test_cli20.CLITestV20Base):
+
+ def test_list_policyprofile_detail(self):
+ """List policyprofile: -D."""
+ resources = 'policy_profiles'
+ cmd = policyprofile.ListPolicyProfile(test_cli20.MyApp(sys.stdout),
+ None)
+ contents = [{'name': 'myname', 'segment_type': 'vlan'}]
+ self._test_list_resources(resources, cmd, True,
+ response_contents=contents)
+
+ def test_list_policyprofile_known_option_after_unknown(self):
+ """List policyprofile: -- --tags a b --request-format xml."""
+ resources = 'policy_profiles'
+ cmd = policyprofile.ListPolicyProfile(test_cli20.MyApp(sys.stdout),
+ None)
+ contents = [{'name': 'myname', 'segment_type': 'vlan'}]
+ self._test_list_resources(resources, cmd, tags=['a', 'b'],
+ response_contents=contents)
+
+ def test_list_policyprofile_fields(self):
+ """List policyprofile: --fields a --fields b -- --fields c d."""
+ resources = 'policy_profiles'
+ cmd = policyprofile.ListPolicyProfile(test_cli20.MyApp(sys.stdout),
+ None)
+ contents = [{'name': 'myname', 'segment_type': 'vlan'}]
+ self._test_list_resources(resources, cmd,
+ fields_1=['a', 'b'], fields_2=['c', 'd'],
+ response_contents=contents)
+
+ def test_show_policyprofile(self):
+ """Show policyprofile: --fields id --fields name myid."""
+ resource = 'policy_profile'
+ cmd = policyprofile.ShowPolicyProfile(test_cli20.MyApp(sys.stdout),
+ None)
+ args = ['--fields', 'id', '--fields', 'name', self.test_id]
+ self._test_show_resource(resource, cmd, self.test_id, args,
+ ['id', 'name'])
+
+ def test_update_policyprofile(self):
+ """Update policyprofile: myid --name myname --tags a b."""
+ resource = 'policy_profile'
+ cmd = policyprofile.UpdatePolicyProfile(test_cli20.MyApp(sys.stdout),
+ None)
+ self._test_update_resource(resource, cmd, 'myid',
+ ['myid', '--name', 'myname',
+ '--tags', 'a', 'b'],
+ {'name': 'myname', 'tags': ['a', 'b'], }
+ )
diff --git a/neutronclient/v2_0/client.py b/neutronclient/v2_0/client.py
index c53f00d..facc6d1 100644
--- a/neutronclient/v2_0/client.py
+++ b/neutronclient/v2_0/client.py
@@ -396,6 +396,14 @@ class Client(ClientBase):
gateway_devices_path = "/gateway-devices"
gateway_device_path = "/gateway-devices/%s"
service_providers_path = "/service-providers"
+ credentials_path = "/credentials"
+ credential_path = "/credentials/%s"
+ network_profiles_path = "/network_profiles"
+ network_profile_path = "/network_profiles/%s"
+ network_profile_bindings_path = "/network_profile_bindings"
+ policy_profiles_path = "/policy_profiles"
+ policy_profile_path = "/policy_profiles/%s"
+ policy_profile_bindings_path = "/policy_profile_bindings"
metering_labels_path = "/metering/metering-labels"
metering_label_path = "/metering/metering-labels/%s"
metering_label_rules_path = "/metering/metering-label-rules"
@@ -1469,6 +1477,79 @@ class Client(ClientBase):
return self.list('service_providers', self.service_providers_path,
retrieve_all, **_params)
+ def list_credentials(self, **_params):
+ """Fetch a list of all credentials for a tenant."""
+ return self.get(self.credentials_path, params=_params)
+
+ @APIParamsCall
+ def show_credential(self, credential, **_params):
+ """Fetch a credential."""
+ return self.get(self.credential_path % (credential), params=_params)
+
+ @APIParamsCall
+ def create_credential(self, body=None):
+ """Create a new credential."""
+ return self.post(self.credentials_path, body=body)
+
+ @APIParamsCall
+ def update_credential(self, credential, body=None):
+ """Update a credential."""
+ return self.put(self.credential_path % (credential), body=body)
+
+ @APIParamsCall
+ def delete_credential(self, credential):
+ """Delete the specified credential."""
+ return self.delete(self.credential_path % (credential))
+
+ def list_network_profile_bindings(self, **params):
+ """Fetch a list of all tenants associated for a network profile."""
+ return self.get(self.network_profile_bindings_path, params=params)
+
+ @APIParamsCall
+ def list_network_profiles(self, **params):
+ """Fetch a list of all network profiles for a tenant."""
+ return self.get(self.network_profiles_path, params=params)
+
+ @APIParamsCall
+ def show_network_profile(self, profile, **params):
+ """Fetch a network profile."""
+ return self.get(self.network_profile_path % (profile), params=params)
+
+ @APIParamsCall
+ def create_network_profile(self, body=None):
+ """Create a network profile."""
+ return self.post(self.network_profiles_path, body=body)
+
+ @APIParamsCall
+ def update_network_profile(self, profile, body=None):
+ """Update a network profile."""
+ return self.put(self.network_profile_path % (profile), body=body)
+
+ @APIParamsCall
+ def delete_network_profile(self, profile):
+ """Delete the network profile."""
+ return self.delete(self.network_profile_path % profile)
+
+ @APIParamsCall
+ def list_policy_profile_bindings(self, **params):
+ """Fetch a list of all tenants associated for a policy profile."""
+ return self.get(self.policy_profile_bindings_path, params=params)
+
+ @APIParamsCall
+ def list_policy_profiles(self, **params):
+ """Fetch a list of all network profiles for a tenant."""
+ return self.get(self.policy_profiles_path, params=params)
+
+ @APIParamsCall
+ def show_policy_profile(self, profile, **params):
+ """Fetch a network profile."""
+ return self.get(self.policy_profile_path % (profile), params=params)
+
+ @APIParamsCall
+ def update_policy_profile(self, profile, body=None):
+ """Update a policy profile."""
+ return self.put(self.policy_profile_path % (profile), body=body)
+
@APIParamsCall
def create_metering_label(self, body=None):
"""Creates a metering label."""