GBP Client for GBP resources
Partially-implements: blueprint group-based-policy-abstraction Change-Id: I6925ab7e3cdbce741f7c3f73c4e810d7ca8b5c7a
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -14,6 +14,7 @@ gbp/vcsversion.py
 | 
			
		||||
gbpclient/versioninfo
 | 
			
		||||
run_tests.err.log
 | 
			
		||||
run_tests.log
 | 
			
		||||
subunit.log
 | 
			
		||||
.autogenerated
 | 
			
		||||
.coverage
 | 
			
		||||
.testrepository/
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								HACKING.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								HACKING.rst
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
Neutron Style Commandments
 | 
			
		||||
================================
 | 
			
		||||
 | 
			
		||||
- Step 1: Read the OpenStack Style Commandments
 | 
			
		||||
  http://docs.openstack.org/developer/hacking/
 | 
			
		||||
- Step 2: Read on
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Running Tests
 | 
			
		||||
-------------
 | 
			
		||||
The testing system is based on a combination of tox and testr. The canonical
 | 
			
		||||
approach to running tests is to simply run the command `tox`. This will
 | 
			
		||||
create virtual environments, populate them with depenedencies and run all of
 | 
			
		||||
the tests that OpenStack CI systems run. Behind the scenes, tox is running
 | 
			
		||||
`testr run --parallel`, but is set up such that you can supply any additional
 | 
			
		||||
testr arguments that are needed to tox. For example, you can run:
 | 
			
		||||
`tox -- --analyze-isolation` to cause tox to tell testr to add
 | 
			
		||||
--analyze-isolation to its argument list.
 | 
			
		||||
 | 
			
		||||
It is also possible to run the tests inside of a virtual environment
 | 
			
		||||
you have created, or it is possible that you have all of the dependencies
 | 
			
		||||
installed locally already. In this case, you can interact with the testr
 | 
			
		||||
command directly. Running `testr run` will run the entire test suite. `testr
 | 
			
		||||
run --parallel` will run it in parallel (this is the default incantation tox
 | 
			
		||||
uses.) More information about testr can be found at:
 | 
			
		||||
http://wiki.openstack.org/testr
 | 
			
		||||
							
								
								
									
										176
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,176 @@
 | 
			
		||||
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										0
									
								
								gbpclient/gbp/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								gbpclient/gbp/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								gbpclient/gbp/v2_0/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								gbpclient/gbp/v2_0/__init__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
from neutronclient.neutron import v2_0 as neutronV2_0
 | 
			
		||||
 | 
			
		||||
_get_resource_plural = neutronV2_0._get_resource_plural
 | 
			
		||||
							
								
								
									
										861
									
								
								gbpclient/gbp/v2_0/groupbasedpolicy.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										861
									
								
								gbpclient/gbp/v2_0/groupbasedpolicy.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,861 @@
 | 
			
		||||
#    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
 | 
			
		||||
import string
 | 
			
		||||
 | 
			
		||||
from neutronclient.common import utils
 | 
			
		||||
from neutronclient.neutron import v2_0 as neutronV20
 | 
			
		||||
from neutronclient.openstack.common.gettextutils import _
 | 
			
		||||
from oslo.serialization import jsonutils
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _format_network_service_params(net_svc_policy):
 | 
			
		||||
    try:
 | 
			
		||||
        return '\n'.join([jsonutils.dumps(param) for param in
 | 
			
		||||
                          net_svc_policy['network_service_params']])
 | 
			
		||||
    except (TypeError, KeyError):
 | 
			
		||||
        return ''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListEndpoint(neutronV20.ListCommand):
 | 
			
		||||
    """List policy_targets that belong to a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'endpoint'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ListEndpoint')
 | 
			
		||||
    _formatters = {}
 | 
			
		||||
    list_columns = ['id', 'name', 'description', 'endpoint_group_id']
 | 
			
		||||
    pagination_support = True
 | 
			
		||||
    sorting_support = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShowEndpoint(neutronV20.ShowCommand):
 | 
			
		||||
    """Show information of a given policy_target."""
 | 
			
		||||
 | 
			
		||||
    resource = 'endpoint'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ShowEndpoint')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreateEndpoint(neutronV20.CreateCommand):
 | 
			
		||||
    """Create a policy_target for a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'endpoint'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.CreateEndpoint')
 | 
			
		||||
 | 
			
		||||
    def add_known_arguments(self, parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--description',
 | 
			
		||||
            help=_('Description of the policy_target'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--endpoint-group', metavar='EPG',
 | 
			
		||||
            default='',
 | 
			
		||||
            help=_('group uuid'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--port',
 | 
			
		||||
            default='',
 | 
			
		||||
            help=_('Neutron Port'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            'name', metavar='NAME',
 | 
			
		||||
            help=_('Name of policy_target to create'))
 | 
			
		||||
 | 
			
		||||
    def args2body(self, parsed_args):
 | 
			
		||||
        body = {self.resource: {}, }
 | 
			
		||||
 | 
			
		||||
        neutronV20.update_dict(parsed_args, body[self.resource],
 | 
			
		||||
                               ['name', 'tenant_id', 'description'])
 | 
			
		||||
        if parsed_args.endpoint_group:
 | 
			
		||||
            body[self.resource]['endpoint_group_id'] = \
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'endpoint_group',
 | 
			
		||||
                    parsed_args.endpoint_group)
 | 
			
		||||
        if parsed_args.port:
 | 
			
		||||
            body[self.resource]['port_id'] = \
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'port',
 | 
			
		||||
                    parsed_args.port)
 | 
			
		||||
        return body
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeleteEndpoint(neutronV20.DeleteCommand):
 | 
			
		||||
    """Delete a given policy_target."""
 | 
			
		||||
 | 
			
		||||
    resource = 'endpoint'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.DeleteEndpoint')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UpdateEndpoint(neutronV20.UpdateCommand):
 | 
			
		||||
    """Update policy_target's information."""
 | 
			
		||||
 | 
			
		||||
    resource = 'endpoint'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.UpdateEndpoint')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListEndpointGroup(neutronV20.ListCommand):
 | 
			
		||||
    """List groups that belong to a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'endpoint_group'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ListEndpointGroup')
 | 
			
		||||
    list_columns = ['id', 'name', 'description']
 | 
			
		||||
    pagination_support = True
 | 
			
		||||
    sorting_support = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShowEndpointGroup(neutronV20.ShowCommand):
 | 
			
		||||
    """Show information of a given group."""
 | 
			
		||||
 | 
			
		||||
    resource = 'endpoint_group'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ShowEndpointGroup')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreateEndpointGroup(neutronV20.CreateCommand):
 | 
			
		||||
    """Create a group for a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'endpoint_group'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.CreateEndpointGroup')
 | 
			
		||||
 | 
			
		||||
    def add_known_arguments(self, parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--description',
 | 
			
		||||
            help=_('Description of the group'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            'name', metavar='NAME',
 | 
			
		||||
            help=_('Name of group to create'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--l2-policy', metavar='L2_POLICY',
 | 
			
		||||
            default='',
 | 
			
		||||
            help=_('L2 policy uuid'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--provided-contracts', type=utils.str2dict,
 | 
			
		||||
            default={},
 | 
			
		||||
            help=_('Dictionary of provided contract uuids'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--consumed-contracts', type=utils.str2dict,
 | 
			
		||||
            default={},
 | 
			
		||||
            help=_('Dictionary of consumed contract uuids'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--network-service-policy', metavar='NETWORK_SERVICE_POLICY',
 | 
			
		||||
            default='',
 | 
			
		||||
            help=_('Network service policy uuid'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--subnets', type=string.split,
 | 
			
		||||
            help=_('Subnet to map the group'))
 | 
			
		||||
 | 
			
		||||
    def args2body(self, parsed_args):
 | 
			
		||||
        body = {self.resource: {}, }
 | 
			
		||||
 | 
			
		||||
        if parsed_args.l2_policy:
 | 
			
		||||
            body[self.resource]['l2_policy_id'] = \
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'l2_policy',
 | 
			
		||||
                    parsed_args.l2_policy)
 | 
			
		||||
 | 
			
		||||
        if parsed_args.network_service_policy:
 | 
			
		||||
            body[self.resource]['network_service_policy_id'] = \
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'network_service_policy',
 | 
			
		||||
                    parsed_args.network_service_policy)
 | 
			
		||||
 | 
			
		||||
        if parsed_args.provided_contracts:
 | 
			
		||||
            for key in parsed_args.provided_contracts.keys():
 | 
			
		||||
                id_key = neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'contract',
 | 
			
		||||
                    key)
 | 
			
		||||
                parsed_args.provided_contracts[id_key] = \
 | 
			
		||||
                    parsed_args.provided_contracts.pop(key)
 | 
			
		||||
 | 
			
		||||
        if parsed_args.consumed_contracts:
 | 
			
		||||
            for key in parsed_args.consumed_contracts.keys():
 | 
			
		||||
                id_key = neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'contract',
 | 
			
		||||
                    key)
 | 
			
		||||
                parsed_args.consumed_contracts[id_key] = \
 | 
			
		||||
                    parsed_args.consumed_contracts.pop(key)
 | 
			
		||||
 | 
			
		||||
        if parsed_args.subnets:
 | 
			
		||||
            for subnet in parsed_args.subnets:
 | 
			
		||||
                subnet_id = neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'subnet',
 | 
			
		||||
                    subnet)
 | 
			
		||||
                parsed_args.subnets.remove(subnet)
 | 
			
		||||
                parsed_args.subnets.append(subnet_id)
 | 
			
		||||
        neutronV20.update_dict(parsed_args, body[self.resource],
 | 
			
		||||
                               ['name', 'tenant_id', 'description',
 | 
			
		||||
                                'provided_contracts', 'subnets',
 | 
			
		||||
                                'consumed_contracts'])
 | 
			
		||||
 | 
			
		||||
        return body
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeleteEndpointGroup(neutronV20.DeleteCommand):
 | 
			
		||||
    """Delete a given group."""
 | 
			
		||||
 | 
			
		||||
    resource = 'endpoint_group'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.DeleteEndpointGroup')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UpdateEndpointGroup(neutronV20.UpdateCommand):
 | 
			
		||||
    """Update group's information."""
 | 
			
		||||
 | 
			
		||||
    resource = 'endpoint_group'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.UpdateEndpointGroup')
 | 
			
		||||
 | 
			
		||||
    def add_known_arguments(self, parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--description',
 | 
			
		||||
            help=_('Description of the group'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--l2-policy', metavar='L2_POLICY',
 | 
			
		||||
            help=_('L2 policy uuid'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--network-service-policy', metavar='NETWORK_SERVICE_POLICY',
 | 
			
		||||
            help=_('Network Service Policy uuid'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--provided-contracts', type=utils.str2dict,
 | 
			
		||||
            help=_('Dictionary of provided contract uuids'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--consumed-contracts', type=utils.str2dict,
 | 
			
		||||
            help=_('Dictionary of consumed contract uuids'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--subnets', type=string.split,
 | 
			
		||||
            help=_('Subnet to map the group'))
 | 
			
		||||
 | 
			
		||||
    def args2body(self, parsed_args):
 | 
			
		||||
        body = {self.resource: {}, }
 | 
			
		||||
 | 
			
		||||
        if parsed_args.l2_policy:
 | 
			
		||||
            body[self.resource]['l2_policy_id'] = \
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'l2_policy',
 | 
			
		||||
                    parsed_args.l2_policy)
 | 
			
		||||
 | 
			
		||||
        if parsed_args.network_service_policy:
 | 
			
		||||
            body[self.resource]['network_service_policy_id'] = \
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'network_service_policy',
 | 
			
		||||
                    parsed_args.l2_policy)
 | 
			
		||||
 | 
			
		||||
        if parsed_args.provided_contracts:
 | 
			
		||||
            for key in parsed_args.provided_contracts.keys():
 | 
			
		||||
                id_key = neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'contract',
 | 
			
		||||
                    key)
 | 
			
		||||
                parsed_args.provided_contracts[id_key] = \
 | 
			
		||||
                    parsed_args.provided_contracts.pop(key)
 | 
			
		||||
 | 
			
		||||
        if parsed_args.consumed_contracts:
 | 
			
		||||
            for key in parsed_args.consumed_contracts.keys():
 | 
			
		||||
                id_key = neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'contract',
 | 
			
		||||
                    key)
 | 
			
		||||
                parsed_args.consumed_contracts[id_key] = \
 | 
			
		||||
                    parsed_args.consumed_contracts.pop(key)
 | 
			
		||||
 | 
			
		||||
        if parsed_args.subnets:
 | 
			
		||||
            for subnet in parsed_args.subnets:
 | 
			
		||||
                subnet_id = neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'subnet',
 | 
			
		||||
                    subnet)
 | 
			
		||||
                parsed_args.subnets.remove(subnet)
 | 
			
		||||
                parsed_args.subnets.append(subnet_id)
 | 
			
		||||
 | 
			
		||||
        neutronV20.update_dict(parsed_args, body[self.resource],
 | 
			
		||||
                               ['name', 'tenant_id', 'description',
 | 
			
		||||
                                'provided_contracts', 'subnets',
 | 
			
		||||
                                'consumed_contracts'])
 | 
			
		||||
 | 
			
		||||
        return body
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListL2Policy(neutronV20.ListCommand):
 | 
			
		||||
    """List L2 Policies that belong to a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'l2_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ListL2Policy')
 | 
			
		||||
    _formatters = {}
 | 
			
		||||
    list_columns = ['id', 'name', 'description', 'l3_policy_id']
 | 
			
		||||
    pagination_support = True
 | 
			
		||||
    sorting_support = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShowL2Policy(neutronV20.ShowCommand):
 | 
			
		||||
    """Show information of a given l2_policy."""
 | 
			
		||||
 | 
			
		||||
    resource = 'l2_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ShowL2Policy')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreateL2Policy(neutronV20.CreateCommand):
 | 
			
		||||
    """Create a bridge_domain for a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'l2_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.CreateL2Policy')
 | 
			
		||||
 | 
			
		||||
    def add_known_arguments(self, parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--description',
 | 
			
		||||
            help=_('Description of the l2_policy'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--network',
 | 
			
		||||
            help=_('Network to map the l2_policy'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--l3-policy',
 | 
			
		||||
            default='',
 | 
			
		||||
            help=_('l3_policy uuid'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            'name', metavar='NAME',
 | 
			
		||||
            help=_('Name of l2_policy to create'))
 | 
			
		||||
 | 
			
		||||
    def args2body(self, parsed_args):
 | 
			
		||||
        body = {self.resource: {}, }
 | 
			
		||||
 | 
			
		||||
        neutronV20.update_dict(parsed_args, body[self.resource],
 | 
			
		||||
                               ['name', 'tenant_id', 'description'])
 | 
			
		||||
        if parsed_args.l3_policy:
 | 
			
		||||
            body[self.resource]['l3_policy_id'] = \
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'l3_policy',
 | 
			
		||||
                    parsed_args.l3_policy)
 | 
			
		||||
        if parsed_args.network:
 | 
			
		||||
            body[self.resource]['network_id'] = \
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(), 'network',
 | 
			
		||||
                    parsed_args.network)
 | 
			
		||||
        return body
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeleteL2Policy(neutronV20.DeleteCommand):
 | 
			
		||||
    """Delete a given l2_policy."""
 | 
			
		||||
 | 
			
		||||
    resource = 'l2_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.DeleteL2Policy')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UpdateL2Policy(neutronV20.UpdateCommand):
 | 
			
		||||
    """Update l2_policy's information."""
 | 
			
		||||
 | 
			
		||||
    resource = 'l2_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.UpdateL2Policy')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListL3Policy(neutronV20.ListCommand):
 | 
			
		||||
    """List l3_policies that belong to a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'l3_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ListL3Policy')
 | 
			
		||||
    _formatters = {}
 | 
			
		||||
    list_columns = ['id', 'name', 'description', 'ip_pool',
 | 
			
		||||
                    'subnet_prefix_length']
 | 
			
		||||
    pagination_support = True
 | 
			
		||||
    sorting_support = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShowL3Policy(neutronV20.ShowCommand):
 | 
			
		||||
    """Show information of a given l3_policy."""
 | 
			
		||||
 | 
			
		||||
    resource = 'l3_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ShowL3Policy')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreateL3Policy(neutronV20.CreateCommand):
 | 
			
		||||
    """Create a l3_policy for a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'l3_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.CreateL3Policy')
 | 
			
		||||
 | 
			
		||||
    def add_known_arguments(self, parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--description',
 | 
			
		||||
            help=_('Description of the l3_policy'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--ip-version',
 | 
			
		||||
            type=int,
 | 
			
		||||
            default=4, choices=[4, 6],
 | 
			
		||||
            help=_('IP version, default is 4'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--ip-pool',
 | 
			
		||||
            help=_('CIDR of IP pool to create, default is 10.0.0.0/8'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--subnet-prefix-length',
 | 
			
		||||
            type=int,
 | 
			
		||||
            default=24,
 | 
			
		||||
            help=_('Subnet prefix length, default is 24'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            'name', metavar='NAME',
 | 
			
		||||
            help=_('Name of l3_policy to create'))
 | 
			
		||||
 | 
			
		||||
    def args2body(self, parsed_args):
 | 
			
		||||
        body = {self.resource: {}, }
 | 
			
		||||
 | 
			
		||||
        neutronV20.update_dict(parsed_args, body[self.resource],
 | 
			
		||||
                               ['name', 'tenant_id', 'description',
 | 
			
		||||
                                'ip_version', 'ip_pool',
 | 
			
		||||
                                'subnet_prefix_length'])
 | 
			
		||||
 | 
			
		||||
        return body
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeleteL3Policy(neutronV20.DeleteCommand):
 | 
			
		||||
    """Delete a given l3_policy."""
 | 
			
		||||
 | 
			
		||||
    resource = 'l3_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.DeleteL3Policy')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UpdateL3Policy(neutronV20.UpdateCommand):
 | 
			
		||||
    """Update l3_policy's information."""
 | 
			
		||||
 | 
			
		||||
    resource = 'l3_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.UpdateL3Policy')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListNetworkServicePolicy(neutronV20.ListCommand):
 | 
			
		||||
    """List Network Service Policies that belong to a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'network_service_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ListNetworkServicePolicy')
 | 
			
		||||
    _formatters = {'network_servie_params': _format_network_service_params}
 | 
			
		||||
    list_columns = ['id', 'name', 'description', 'network_service_params']
 | 
			
		||||
    pagination_support = True
 | 
			
		||||
    sorting_support = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShowNetworkServicePolicy(neutronV20.ShowCommand):
 | 
			
		||||
    """Show information of a given network_service_policy."""
 | 
			
		||||
 | 
			
		||||
    resource = 'network_service_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ShowNetworkServicePolicy')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreateNetworkServicePolicy(neutronV20.CreateCommand):
 | 
			
		||||
    """Create a Network Service Policy for a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'network_service_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.CreateNetworkServicePolicy')
 | 
			
		||||
 | 
			
		||||
    def add_known_arguments(self, parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--description',
 | 
			
		||||
            help=_('Description of the network_service_policy'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            'name',
 | 
			
		||||
            help=_('Name of network_service_policy to create'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--network-service-params',
 | 
			
		||||
            metavar='type=PARAM_TYPE,name=PARAM_NAME,value=PARAM_VALUE',
 | 
			
		||||
            action='append', dest='network_service_params',
 | 
			
		||||
            type=utils.str2dict,
 | 
			
		||||
            help=_('Network service params for this network service policy'
 | 
			
		||||
                   '(This option can be repeated).'))
 | 
			
		||||
 | 
			
		||||
    def args2body(self, parsed_args):
 | 
			
		||||
        body = {self.resource: {}, }
 | 
			
		||||
 | 
			
		||||
        """
 | 
			
		||||
        if parsed_args.name:
 | 
			
		||||
            body[self.resource].update({'name': parsed_args.name})
 | 
			
		||||
 | 
			
		||||
        if parsed_args.description:
 | 
			
		||||
            body[self.resource].update({'description': parsed_args.name})
 | 
			
		||||
 | 
			
		||||
        if parsed_args.network_service_params:
 | 
			
		||||
            body[self.resource]['network_service_params'] = (
 | 
			
		||||
                parsed_args.network_sercice_params)
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        neutronV20.update_dict(parsed_args, body[self.resource],
 | 
			
		||||
                               ['name', 'tenant_id', 'description',
 | 
			
		||||
                                'network_service_params'])
 | 
			
		||||
        return body
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeleteNetworkServicePolicy(neutronV20.DeleteCommand):
 | 
			
		||||
    """Delete a given network_service_policy."""
 | 
			
		||||
 | 
			
		||||
    resource = 'network_service_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.DeleteNetworkServicePolicy')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UpdateNetworkServicePolicy(neutronV20.UpdateCommand):
 | 
			
		||||
    """Update network_service_policy's information."""
 | 
			
		||||
 | 
			
		||||
    resource = 'network_service_policy'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.UpdateNetworkServicePolicy')
 | 
			
		||||
 | 
			
		||||
    def add_known_arguments(self, parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--description',
 | 
			
		||||
            help=_('Description of the network_service_policy'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--name',
 | 
			
		||||
            help=_('Name of network_service_policy to create'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--network-service-params',
 | 
			
		||||
            metavar='type=PARAM_TYPE,name=PARAM_NAME,value=PARAM_VALUE',
 | 
			
		||||
            action='append', dest='network_service_params',
 | 
			
		||||
            type=utils.str2dict,
 | 
			
		||||
            help=_('Network service params for this network service policy'
 | 
			
		||||
                   '(This option can be repeated).'))
 | 
			
		||||
 | 
			
		||||
    def args2body(self, parsed_args):
 | 
			
		||||
        body = {self.resource: {}, }
 | 
			
		||||
 | 
			
		||||
        neutronV20.update_dict(parsed_args, body[self.resource],
 | 
			
		||||
                               ['name', 'tenant_id', 'description',
 | 
			
		||||
                                'network_service_params'])
 | 
			
		||||
        return body
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListPolicyClassifier(neutronV20.ListCommand):
 | 
			
		||||
    """List classifiers that belong to a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_classifier'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ListPolicyClassifier')
 | 
			
		||||
    _formatters = {}
 | 
			
		||||
    list_columns = ['id', 'name', 'protocol', 'port_range', 'direction']
 | 
			
		||||
    pagination_support = True
 | 
			
		||||
    sorting_support = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShowPolicyClassifier(neutronV20.ShowCommand):
 | 
			
		||||
    """Show information of a given classifier."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_classifier'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ShowPolicyClassifier')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreatePolicyClassifier(neutronV20.CreateCommand):
 | 
			
		||||
    """Create a classifier for a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_classifier'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.CreatePolicyClassifier')
 | 
			
		||||
 | 
			
		||||
    def add_known_arguments(self, parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--description',
 | 
			
		||||
            help=_('Description of the policy classifier'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--protocol',
 | 
			
		||||
            choices=['tcp', 'udp', 'icmp'],
 | 
			
		||||
            help=_('Protocol'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--port-range',
 | 
			
		||||
            help=_('Port range'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--direction',
 | 
			
		||||
            choices=['in', 'out', 'bi', ''],
 | 
			
		||||
            help=_('Direction'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            'name', metavar='NAME',
 | 
			
		||||
            help=_('Name of classifier to create'))
 | 
			
		||||
 | 
			
		||||
    def args2body(self, parsed_args):
 | 
			
		||||
        body = {self.resource: {}, }
 | 
			
		||||
 | 
			
		||||
        neutronV20.update_dict(parsed_args, body[self.resource],
 | 
			
		||||
                               ['name', 'tenant_id', 'description',
 | 
			
		||||
                                'protocol', 'port_range', 'direction'])
 | 
			
		||||
 | 
			
		||||
        return body
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeletePolicyClassifier(neutronV20.DeleteCommand):
 | 
			
		||||
    """Delete a given classifier."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_classifier'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.DeletePolicyClassifier')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UpdatePolicyClassifier(neutronV20.UpdateCommand):
 | 
			
		||||
    """Update classifier's information."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_classifier'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.UpdatePolicyClassifier')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListPolicyAction(neutronV20.ListCommand):
 | 
			
		||||
    """List actions that belong to a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_action'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ListPolicyAction')
 | 
			
		||||
    _formatters = {}
 | 
			
		||||
    list_columns = ['id', 'name', 'action_type', 'action_value']
 | 
			
		||||
    pagination_support = True
 | 
			
		||||
    sorting_support = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShowPolicyAction(neutronV20.ShowCommand):
 | 
			
		||||
    """Show information of a given action."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_action'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ShowPolicyAction')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreatePolicyAction(neutronV20.CreateCommand):
 | 
			
		||||
    """Create a action for a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_action'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.CreatePolicyAction')
 | 
			
		||||
 | 
			
		||||
    def add_known_arguments(self, parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--description',
 | 
			
		||||
            help=_('Description of the policy action'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--action-type',
 | 
			
		||||
            help=_('Type of action'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--action-value',
 | 
			
		||||
            help=_('uuid of service for redirect action'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            'name', metavar='NAME',
 | 
			
		||||
            help=_('Name of action to create'))
 | 
			
		||||
 | 
			
		||||
    def args2body(self, parsed_args):
 | 
			
		||||
        body = {self.resource: {}, }
 | 
			
		||||
 | 
			
		||||
        neutronV20.update_dict(parsed_args, body[self.resource],
 | 
			
		||||
                               ['name', 'tenant_id', 'description',
 | 
			
		||||
                                'action_type', 'action_value'])
 | 
			
		||||
 | 
			
		||||
        return body
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeletePolicyAction(neutronV20.DeleteCommand):
 | 
			
		||||
    """Delete a given action."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_action'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.DeletePolicyAction')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UpdatePolicyAction(neutronV20.UpdateCommand):
 | 
			
		||||
    """Update action's information."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_action'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.UpdatePolicyAction')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListPolicyRule(neutronV20.ListCommand):
 | 
			
		||||
    """List policy_rules that belong to a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_rule'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ListPolicyRule')
 | 
			
		||||
    _formatters = {}
 | 
			
		||||
    list_columns = ['id', 'name', 'enabled', 'classifier_id',
 | 
			
		||||
                    'actions']
 | 
			
		||||
    pagination_support = True
 | 
			
		||||
    sorting_support = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShowPolicyRule(neutronV20.ShowCommand):
 | 
			
		||||
    """Show information of a given policy_rule."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_rule'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ShowPolicyRule')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreatePolicyRule(neutronV20.CreateCommand):
 | 
			
		||||
    """Create a policy_rule for a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_rule'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.CreatePolicyRule')
 | 
			
		||||
 | 
			
		||||
    def add_known_arguments(self, parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--description',
 | 
			
		||||
            help=_('Description of the policy_rule'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--enabled', type=bool,
 | 
			
		||||
            help=_('Enable flag'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--classifier',
 | 
			
		||||
            help=_('uuid of policy classifier'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--actions', type=string.split,
 | 
			
		||||
            help=_('List of policy actions'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            'name', metavar='NAME',
 | 
			
		||||
            help=_('Name of policy_rule to create'))
 | 
			
		||||
 | 
			
		||||
    def args2body(self, parsed_args):
 | 
			
		||||
        body = {self.resource: {}, }
 | 
			
		||||
 | 
			
		||||
        if parsed_args.actions:
 | 
			
		||||
            body[self.resource]['policy_actions'] = [
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(),
 | 
			
		||||
                    'policy_action',
 | 
			
		||||
                    elem) for elem in parsed_args.actions]
 | 
			
		||||
 | 
			
		||||
        if parsed_args.classifier:
 | 
			
		||||
            body[self.resource]['policy_classifier_id'] = \
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(),
 | 
			
		||||
                    'policy_classifier',
 | 
			
		||||
                    parsed_args.classifier)
 | 
			
		||||
 | 
			
		||||
        neutronV20.update_dict(parsed_args, body[self.resource],
 | 
			
		||||
                               ['name', 'tenant_id', 'description',
 | 
			
		||||
                                'enabled'])
 | 
			
		||||
 | 
			
		||||
        return body
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeletePolicyRule(neutronV20.DeleteCommand):
 | 
			
		||||
    """Delete a given policy_rule."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_rule'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.DeletePolicyRule')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UpdatePolicyRule(neutronV20.UpdateCommand):
 | 
			
		||||
    """Update policy_rule's information."""
 | 
			
		||||
 | 
			
		||||
    resource = 'policy_rule'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.UpdatePolicyRule')
 | 
			
		||||
 | 
			
		||||
    def add_known_arguments(self, parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--enabled', type=bool,
 | 
			
		||||
            help=_('Enable flag'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--classifier',
 | 
			
		||||
            help=_('uuid of policy classifier'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--actions', type=string.split,
 | 
			
		||||
            help=_('List of policy actions'))
 | 
			
		||||
 | 
			
		||||
    def args2body(self, parsed_args):
 | 
			
		||||
        body = {self.resource: {}, }
 | 
			
		||||
 | 
			
		||||
        if parsed_args.actions:
 | 
			
		||||
            body[self.resource]['policy_actions'] = [
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(),
 | 
			
		||||
                    'policy_action',
 | 
			
		||||
                    elem) for elem in parsed_args.actions]
 | 
			
		||||
 | 
			
		||||
        if parsed_args.classifier:
 | 
			
		||||
            body[self.resource]['policy_classifier_id'] = \
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(),
 | 
			
		||||
                    'policy_classifier',
 | 
			
		||||
                    parsed_args.classifier)
 | 
			
		||||
 | 
			
		||||
        neutronV20.update_dict(parsed_args, body[self.resource],
 | 
			
		||||
                               ['name', 'description',
 | 
			
		||||
                                'enabled'])
 | 
			
		||||
        return body
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListContract(neutronV20.ListCommand):
 | 
			
		||||
    """List contracts that belong to a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'contract'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ListContract')
 | 
			
		||||
    _formatters = {}
 | 
			
		||||
    list_columns = ['id', 'name', 'ploicy_rules']
 | 
			
		||||
    pagination_support = True
 | 
			
		||||
    sorting_support = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShowContract(neutronV20.ShowCommand):
 | 
			
		||||
    """Show information of a given contract."""
 | 
			
		||||
 | 
			
		||||
    resource = 'contract'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.ShowContract')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreateContract(neutronV20.CreateCommand):
 | 
			
		||||
    """Create a contract for a given tenant."""
 | 
			
		||||
 | 
			
		||||
    resource = 'contract'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.CreateContract')
 | 
			
		||||
 | 
			
		||||
    def add_known_arguments(self, parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--description',
 | 
			
		||||
            help=_('Description of the contract'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--policy-rules', type=string.split,
 | 
			
		||||
            help=_('List of policy rules'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--child-contracts', type=string.split,
 | 
			
		||||
            help=_('List of child contracts'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            'name', metavar='NAME',
 | 
			
		||||
            help=_('Name of contract to create'))
 | 
			
		||||
 | 
			
		||||
    def args2body(self, parsed_args):
 | 
			
		||||
        body = {self.resource: {}, }
 | 
			
		||||
 | 
			
		||||
        if parsed_args.policy_rules:
 | 
			
		||||
            body[self.resource]['policy_rules'] = [
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(),
 | 
			
		||||
                    'policy_rule',
 | 
			
		||||
                    elem) for elem in parsed_args.policy_rules]
 | 
			
		||||
 | 
			
		||||
        if parsed_args.child_contracts:
 | 
			
		||||
            body[self.resource]['child_contracts'] = [
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(),
 | 
			
		||||
                    'contract',
 | 
			
		||||
                    elem) for elem in parsed_args.child_contracts]
 | 
			
		||||
 | 
			
		||||
        neutronV20.update_dict(parsed_args, body[self.resource],
 | 
			
		||||
                               ['name', 'tenant_id', 'description'])
 | 
			
		||||
        return body
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeleteContract(neutronV20.DeleteCommand):
 | 
			
		||||
    """Delete a given contract."""
 | 
			
		||||
 | 
			
		||||
    resource = 'contract'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.DeleteContract')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UpdateContract(neutronV20.UpdateCommand):
 | 
			
		||||
    """Update contract's information."""
 | 
			
		||||
 | 
			
		||||
    resource = 'contract'
 | 
			
		||||
    log = logging.getLogger(__name__ + '.UpdateContract')
 | 
			
		||||
 | 
			
		||||
    def add_known_arguments(self, parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--policy-rules', type=string.split,
 | 
			
		||||
            help=_('List of policy rules'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--child-contracts', type=string.split,
 | 
			
		||||
            help=_('List of child contracts'))
 | 
			
		||||
 | 
			
		||||
    def args2body(self, parsed_args):
 | 
			
		||||
        body = {self.resource: {}, }
 | 
			
		||||
        if parsed_args.policy_rules:
 | 
			
		||||
            body[self.resource]['policy_rules'] = [
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(),
 | 
			
		||||
                    'policy_rule',
 | 
			
		||||
                    elem) for elem in parsed_args.policy_rules]
 | 
			
		||||
            parsed_args.policy_rules = body[self.resource]['policy_rules']
 | 
			
		||||
 | 
			
		||||
        if parsed_args.child_contracts:
 | 
			
		||||
            body[self.resource]['child_contracts'] = [
 | 
			
		||||
                neutronV20.find_resourceid_by_name_or_id(
 | 
			
		||||
                    self.get_client(),
 | 
			
		||||
                    'contract',
 | 
			
		||||
                    elem) for elem in parsed_args.child_contracts]
 | 
			
		||||
            parsed_args.child_contracts = parsed_args.child_contracts
 | 
			
		||||
        neutronV20.update_dict(parsed_args, body[self.resource],
 | 
			
		||||
                               ['name', 'description', 'policy_rules',
 | 
			
		||||
                                'child_contracts'])
 | 
			
		||||
        return body
 | 
			
		||||
							
								
								
									
										793
									
								
								gbpclient/gbpshell.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										793
									
								
								gbpclient/gbpshell.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,793 @@
 | 
			
		||||
#    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.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
Command-line interface to the GBP APIs
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from __future__ import print_function
 | 
			
		||||
 | 
			
		||||
import argparse
 | 
			
		||||
import logging
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
from keystoneclient.auth.identity import v2 as v2_auth
 | 
			
		||||
from keystoneclient.auth.identity import v3 as v3_auth
 | 
			
		||||
from keystoneclient import discover
 | 
			
		||||
from keystoneclient.openstack.common.apiclient import exceptions as ks_exc
 | 
			
		||||
from keystoneclient import session
 | 
			
		||||
import six.moves.urllib.parse as urlparse
 | 
			
		||||
 | 
			
		||||
from cliff import app
 | 
			
		||||
from cliff import commandmanager
 | 
			
		||||
from neutronclient.common import clientmanager
 | 
			
		||||
from neutronclient.common import exceptions as exc
 | 
			
		||||
from neutronclient.common import utils
 | 
			
		||||
from neutronclient.openstack.common.gettextutils import _
 | 
			
		||||
from neutronclient.openstack.common import strutils
 | 
			
		||||
from neutronclient.version import __version__
 | 
			
		||||
 | 
			
		||||
from gbpclient.gbp.v2_0 import groupbasedpolicy as gbp
 | 
			
		||||
 | 
			
		||||
VERSION = '2.0'
 | 
			
		||||
NEUTRON_API_VERSION = '2.0'
 | 
			
		||||
clientmanager.neutron_client.API_VERSIONS = {
 | 
			
		||||
    '2.0': 'gbpclient.v2_0.client.Client',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def run_command(cmd, cmd_parser, sub_argv):
 | 
			
		||||
    _argv = sub_argv
 | 
			
		||||
    index = -1
 | 
			
		||||
    values_specs = []
 | 
			
		||||
    if '--' in sub_argv:
 | 
			
		||||
        index = sub_argv.index('--')
 | 
			
		||||
        _argv = sub_argv[:index]
 | 
			
		||||
        values_specs = sub_argv[index:]
 | 
			
		||||
    known_args, _values_specs = cmd_parser.parse_known_args(_argv)
 | 
			
		||||
    cmd.values_specs = (index == -1 and _values_specs or values_specs)
 | 
			
		||||
    return cmd.run(known_args)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def env(*_vars, **kwargs):
 | 
			
		||||
    """Search for the first defined of possibly many env vars.
 | 
			
		||||
 | 
			
		||||
    Returns the first environment variable defined in vars, or
 | 
			
		||||
    returns the default defined in kwargs.
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    for v in _vars:
 | 
			
		||||
        value = os.environ.get(v, None)
 | 
			
		||||
        if value:
 | 
			
		||||
            return value
 | 
			
		||||
    return kwargs.get('default', '')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def check_non_negative_int(value):
 | 
			
		||||
    try:
 | 
			
		||||
        value = int(value)
 | 
			
		||||
    except ValueError:
 | 
			
		||||
        raise argparse.ArgumentTypeError(_("invalid int value: %r") % value)
 | 
			
		||||
    if value < 0:
 | 
			
		||||
        raise argparse.ArgumentTypeError(_("input value %d is negative") %
 | 
			
		||||
                                         value)
 | 
			
		||||
    return value
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
COMMAND_V2 = {
 | 
			
		||||
    'policy-target-create': gbp.CreateEndpoint,
 | 
			
		||||
    'policy-target-delete': gbp.DeleteEndpoint,
 | 
			
		||||
    'policy-target-update': gbp.UpdateEndpoint,
 | 
			
		||||
    'policy-target-list': gbp.ListEndpoint,
 | 
			
		||||
    'policy-target-show': gbp.ShowEndpoint,
 | 
			
		||||
    'group-create': gbp.CreateEndpointGroup,
 | 
			
		||||
    'group-delete': gbp.DeleteEndpointGroup,
 | 
			
		||||
    'group-update': gbp.UpdateEndpointGroup,
 | 
			
		||||
    'group-list': gbp.ListEndpointGroup,
 | 
			
		||||
    'group-show': gbp.ShowEndpointGroup,
 | 
			
		||||
    'l2policy-create': gbp.CreateL2Policy,
 | 
			
		||||
    'l2policy-delete': gbp.DeleteL2Policy,
 | 
			
		||||
    'l2policy-update': gbp.UpdateL2Policy,
 | 
			
		||||
    'l2policy-list': gbp.ListL2Policy,
 | 
			
		||||
    'l2policy-show': gbp.ShowL2Policy,
 | 
			
		||||
    'l3policy-create': gbp.CreateL3Policy,
 | 
			
		||||
    'l3policy-delete': gbp.DeleteL3Policy,
 | 
			
		||||
    'l3policy-update': gbp.UpdateL3Policy,
 | 
			
		||||
    'l3policy-list': gbp.ListL3Policy,
 | 
			
		||||
    'l3policy-show': gbp.ShowL3Policy,
 | 
			
		||||
    'network-service-policy-create': gbp.CreateNetworkServicePolicy,
 | 
			
		||||
    'network-service-policy-delete': gbp.DeleteNetworkServicePolicy,
 | 
			
		||||
    'network-service-policy-update': gbp.UpdateNetworkServicePolicy,
 | 
			
		||||
    'network-service-policy-list': gbp.ListNetworkServicePolicy,
 | 
			
		||||
    'network-service-policy-show': gbp.ShowNetworkServicePolicy,
 | 
			
		||||
    'policy-classifier-create': gbp.CreatePolicyClassifier,
 | 
			
		||||
    'policy-classifier-delete': gbp.DeletePolicyClassifier,
 | 
			
		||||
    'policy-classifier-update': gbp.UpdatePolicyClassifier,
 | 
			
		||||
    'policy-classifier-list': gbp.ListPolicyClassifier,
 | 
			
		||||
    'policy-classifier-show': gbp.ShowPolicyClassifier,
 | 
			
		||||
    'policy-action-create': gbp.CreatePolicyAction,
 | 
			
		||||
    'policy-action-delete': gbp.DeletePolicyAction,
 | 
			
		||||
    'policy-action-update': gbp.UpdatePolicyAction,
 | 
			
		||||
    'policy-action-list': gbp.ListPolicyAction,
 | 
			
		||||
    'policy-action-show': gbp.ShowPolicyAction,
 | 
			
		||||
    'policy-rule-create': gbp.CreatePolicyRule,
 | 
			
		||||
    'policy-rule-delete': gbp.DeletePolicyRule,
 | 
			
		||||
    'policy-rule-update': gbp.UpdatePolicyRule,
 | 
			
		||||
    'policy-rule-list': gbp.ListPolicyRule,
 | 
			
		||||
    'policy-rule-show': gbp.ShowPolicyRule,
 | 
			
		||||
    'policy-rule-set-create': gbp.CreateContract,
 | 
			
		||||
    'policy-rule-set-delete': gbp.DeleteContract,
 | 
			
		||||
    'policy-rule-set-update': gbp.UpdateContract,
 | 
			
		||||
    'policy-rule-set-list': gbp.ListContract,
 | 
			
		||||
    'policy-rule-set-show': gbp.ShowContract,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
COMMANDS = {'2.0': COMMAND_V2}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HelpAction(argparse.Action):
 | 
			
		||||
    """Provide a custom action so the -h and --help options
 | 
			
		||||
    to the main app will print a list of the commands.
 | 
			
		||||
 | 
			
		||||
    The commands are determined by checking the CommandManager
 | 
			
		||||
    instance, passed in as the "default" value for the action.
 | 
			
		||||
    """
 | 
			
		||||
    def __call__(self, parser, namespace, values, option_string=None):
 | 
			
		||||
        outputs = []
 | 
			
		||||
        max_len = 0
 | 
			
		||||
        app = self.default
 | 
			
		||||
        parser.print_help(app.stdout)
 | 
			
		||||
        app.api_version = '2.0'  # Check this
 | 
			
		||||
        app.stdout.write(_('\nCommands for GBP API v%s:\n') % app.api_version)
 | 
			
		||||
        command_manager = app.command_manager
 | 
			
		||||
        for name, ep in sorted(command_manager):
 | 
			
		||||
            factory = ep.load()
 | 
			
		||||
            cmd = factory(self, None)
 | 
			
		||||
            one_liner = cmd.get_description().split('\n')[0]
 | 
			
		||||
            outputs.append((name, one_liner))
 | 
			
		||||
            max_len = max(len(name), max_len)
 | 
			
		||||
        for (name, one_liner) in outputs:
 | 
			
		||||
            app.stdout.write('  %s  %s\n' % (name.ljust(max_len), one_liner))
 | 
			
		||||
        sys.exit(0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GBPShell(app.App):
 | 
			
		||||
 | 
			
		||||
    # verbose logging levels
 | 
			
		||||
    WARNING_LEVEL = 0
 | 
			
		||||
    INFO_LEVEL = 1
 | 
			
		||||
    DEBUG_LEVEL = 2
 | 
			
		||||
    CONSOLE_MESSAGE_FORMAT = '%(message)s'
 | 
			
		||||
    DEBUG_MESSAGE_FORMAT = '%(levelname)s: %(name)s %(message)s'
 | 
			
		||||
    log = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
    def __init__(self, apiversion):
 | 
			
		||||
        super(GBPShell, self).__init__(
 | 
			
		||||
            description=__doc__.strip(),
 | 
			
		||||
            version=VERSION,
 | 
			
		||||
            command_manager=commandmanager.CommandManager('gbp.cli'), )
 | 
			
		||||
        self.commands = COMMANDS
 | 
			
		||||
        for k, v in self.commands[apiversion].items():
 | 
			
		||||
            self.command_manager.add_command(k, v)
 | 
			
		||||
 | 
			
		||||
        # This is instantiated in initialize_app() only when using
 | 
			
		||||
        # password flow auth
 | 
			
		||||
        self.auth_client = None
 | 
			
		||||
        self.api_version = apiversion
 | 
			
		||||
 | 
			
		||||
    def build_option_parser(self, description, version):
 | 
			
		||||
        """Return an argparse option parser for this application.
 | 
			
		||||
 | 
			
		||||
        Subclasses may override this method to extend
 | 
			
		||||
        the parser with more global options.
 | 
			
		||||
 | 
			
		||||
        :param description: full description of the application
 | 
			
		||||
        :paramtype description: str
 | 
			
		||||
        :param version: version number for the application
 | 
			
		||||
        :paramtype version: str
 | 
			
		||||
        """
 | 
			
		||||
        parser = argparse.ArgumentParser(
 | 
			
		||||
            description=description,
 | 
			
		||||
            add_help=False, )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--version',
 | 
			
		||||
            action='version',
 | 
			
		||||
            version=__version__, )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '-v', '--verbose', '--debug',
 | 
			
		||||
            action='count',
 | 
			
		||||
            dest='verbose_level',
 | 
			
		||||
            default=self.DEFAULT_VERBOSE_LEVEL,
 | 
			
		||||
            help=_('Increase verbosity of output and show tracebacks on'
 | 
			
		||||
                   ' errors. You can repeat this option.'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '-q', '--quiet',
 | 
			
		||||
            action='store_const',
 | 
			
		||||
            dest='verbose_level',
 | 
			
		||||
            const=0,
 | 
			
		||||
            help=_('Suppress output except warnings and errors.'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '-h', '--help',
 | 
			
		||||
            action=HelpAction,
 | 
			
		||||
            nargs=0,
 | 
			
		||||
            default=self,  # tricky
 | 
			
		||||
            help=_("Show this help message and exit."))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '-r', '--retries',
 | 
			
		||||
            metavar="NUM",
 | 
			
		||||
            type=check_non_negative_int,
 | 
			
		||||
            default=0,
 | 
			
		||||
            help=_("How many times the request to the Neutron server should "
 | 
			
		||||
                   "be retried if it fails."))
 | 
			
		||||
        # FIXME(bklei): this method should come from python-keystoneclient
 | 
			
		||||
        self._append_global_identity_args(parser)
 | 
			
		||||
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
    def _append_global_identity_args(self, parser):
 | 
			
		||||
        # FIXME(bklei): these are global identity (Keystone) arguments which
 | 
			
		||||
        # should be consistent and shared by all service clients. Therefore,
 | 
			
		||||
        # they should be provided by python-keystoneclient. We will need to
 | 
			
		||||
        # refactor this code once this functionality is available in
 | 
			
		||||
        # python-keystoneclient.
 | 
			
		||||
        #
 | 
			
		||||
        # Note: At that time we'll need to decide if we can just abandon
 | 
			
		||||
        #       the deprecated args (--service-type and --endpoint-type).
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-service-type', metavar='<os-service-type>',
 | 
			
		||||
            default=env('OS_NETWORK_SERVICE_TYPE', default='network'),
 | 
			
		||||
            help=_('Defaults to env[OS_NETWORK_SERVICE_TYPE] or network.'))
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-endpoint-type', metavar='<os-endpoint-type>',
 | 
			
		||||
            default=env('OS_ENDPOINT_TYPE', default='publicURL'),
 | 
			
		||||
            help=_('Defaults to env[OS_ENDPOINT_TYPE] or publicURL.'))
 | 
			
		||||
 | 
			
		||||
        # FIXME(bklei): --service-type is deprecated but kept in for
 | 
			
		||||
        # backward compatibility.
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--service-type', metavar='<service-type>',
 | 
			
		||||
            default=env('OS_NETWORK_SERVICE_TYPE', default='network'),
 | 
			
		||||
            help=_('DEPRECATED! Use --os-service-type.'))
 | 
			
		||||
 | 
			
		||||
        # FIXME(bklei): --endpoint-type is deprecated but kept in for
 | 
			
		||||
        # backward compatibility.
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--endpoint-type', metavar='<endpoint-type>',
 | 
			
		||||
            default=env('OS_ENDPOINT_TYPE', default='publicURL'),
 | 
			
		||||
            help=_('DEPRECATED! Use --os-endpoint-type.'))
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-auth-strategy', metavar='<auth-strategy>',
 | 
			
		||||
            default=env('OS_AUTH_STRATEGY', default='keystone'),
 | 
			
		||||
            help=_('DEPRECATED! Only keystone is supported.'))
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os_auth_strategy',
 | 
			
		||||
            help=argparse.SUPPRESS)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-auth-url', metavar='<auth-url>',
 | 
			
		||||
            default=env('OS_AUTH_URL'),
 | 
			
		||||
            help=_('Authentication URL, defaults to env[OS_AUTH_URL].'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os_auth_url',
 | 
			
		||||
            help=argparse.SUPPRESS)
 | 
			
		||||
 | 
			
		||||
        project_name_group = parser.add_mutually_exclusive_group()
 | 
			
		||||
        project_name_group.add_argument(
 | 
			
		||||
            '--os-tenant-name', metavar='<auth-tenant-name>',
 | 
			
		||||
            default=env('OS_TENANT_NAME'),
 | 
			
		||||
            help=_('Authentication tenant name, defaults to '
 | 
			
		||||
                   'env[OS_TENANT_NAME].'))
 | 
			
		||||
        project_name_group.add_argument(
 | 
			
		||||
            '--os-project-name',
 | 
			
		||||
            metavar='<auth-project-name>',
 | 
			
		||||
            default=utils.env('OS_PROJECT_NAME'),
 | 
			
		||||
            help='Another way to specify tenant name. '
 | 
			
		||||
                 'This option is mutually exclusive with '
 | 
			
		||||
                 ' --os-tenant-name. '
 | 
			
		||||
                 'Defaults to env[OS_PROJECT_NAME].')
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os_tenant_name',
 | 
			
		||||
            help=argparse.SUPPRESS)
 | 
			
		||||
 | 
			
		||||
        project_id_group = parser.add_mutually_exclusive_group()
 | 
			
		||||
        project_id_group.add_argument(
 | 
			
		||||
            '--os-tenant-id', metavar='<auth-tenant-id>',
 | 
			
		||||
            default=env('OS_TENANT_ID'),
 | 
			
		||||
            help=_('Authentication tenant ID, defaults to '
 | 
			
		||||
                   'env[OS_TENANT_ID].'))
 | 
			
		||||
        project_id_group.add_argument(
 | 
			
		||||
            '--os-project-id',
 | 
			
		||||
            metavar='<auth-project-id>',
 | 
			
		||||
            default=utils.env('OS_PROJECT_ID'),
 | 
			
		||||
            help='Another way to specify tenant ID. '
 | 
			
		||||
            'This option is mutually exclusive with '
 | 
			
		||||
            ' --os-tenant-id. '
 | 
			
		||||
            'Defaults to env[OS_PROJECT_ID].')
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-username', metavar='<auth-username>',
 | 
			
		||||
            default=utils.env('OS_USERNAME'),
 | 
			
		||||
            help=_('Authentication username, defaults to env[OS_USERNAME].'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os_username',
 | 
			
		||||
            help=argparse.SUPPRESS)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-user-id', metavar='<auth-user-id>',
 | 
			
		||||
            default=env('OS_USER_ID'),
 | 
			
		||||
            help=_('Authentication user ID (Env: OS_USER_ID)'))
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os_user_id',
 | 
			
		||||
            help=argparse.SUPPRESS)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-user-domain-id',
 | 
			
		||||
            metavar='<auth-user-domain-id>',
 | 
			
		||||
            default=utils.env('OS_USER_DOMAIN_ID'),
 | 
			
		||||
            help='OpenStack user domain ID. '
 | 
			
		||||
            'Defaults to env[OS_USER_DOMAIN_ID].')
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os_user_domain_id',
 | 
			
		||||
            help=argparse.SUPPRESS)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-user-domain-name',
 | 
			
		||||
            metavar='<auth-user-domain-name>',
 | 
			
		||||
            default=utils.env('OS_USER_DOMAIN_NAME'),
 | 
			
		||||
            help='OpenStack user domain name. '
 | 
			
		||||
                 'Defaults to env[OS_USER_DOMAIN_NAME].')
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os_user_domain_name',
 | 
			
		||||
            help=argparse.SUPPRESS)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os_project_id',
 | 
			
		||||
            help=argparse.SUPPRESS)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os_project_name',
 | 
			
		||||
            help=argparse.SUPPRESS)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-project-domain-id',
 | 
			
		||||
            metavar='<auth-project-domain-id>',
 | 
			
		||||
            default=utils.env('OS_PROJECT_DOMAIN_ID'),
 | 
			
		||||
            help='Defaults to env[OS_PROJECT_DOMAIN_ID].')
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-project-domain-name',
 | 
			
		||||
            metavar='<auth-project-domain-name>',
 | 
			
		||||
            default=utils.env('OS_PROJECT_DOMAIN_NAME'),
 | 
			
		||||
            help='Defaults to env[OS_PROJECT_DOMAIN_NAME].')
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-cert',
 | 
			
		||||
            metavar='<certificate>',
 | 
			
		||||
            default=utils.env('OS_CERT'),
 | 
			
		||||
            help=_("Path of certificate file to use in SSL "
 | 
			
		||||
                   "connection. This file can optionally be "
 | 
			
		||||
                   "prepended with the private key. Defaults "
 | 
			
		||||
                   "to env[OS_CERT]"))
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-cacert',
 | 
			
		||||
            metavar='<ca-certificate>',
 | 
			
		||||
            default=env('OS_CACERT', default=None),
 | 
			
		||||
            help=_("Specify a CA bundle file to use in "
 | 
			
		||||
                   "verifying a TLS (https) server certificate. "
 | 
			
		||||
                   "Defaults to env[OS_CACERT]"))
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-key',
 | 
			
		||||
            metavar='<key>',
 | 
			
		||||
            default=utils.env('OS_KEY'),
 | 
			
		||||
            help=_("Path of client key to use in SSL "
 | 
			
		||||
                   "connection. This option is not necessary "
 | 
			
		||||
                   "if your key is prepended to your certificate "
 | 
			
		||||
                   "file. Defaults to env[OS_KEY]"))
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-password', metavar='<auth-password>',
 | 
			
		||||
            default=utils.env('OS_PASSWORD'),
 | 
			
		||||
            help=_('Authentication password, defaults to env[OS_PASSWORD].'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os_password',
 | 
			
		||||
            help=argparse.SUPPRESS)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-region-name', metavar='<auth-region-name>',
 | 
			
		||||
            default=env('OS_REGION_NAME'),
 | 
			
		||||
            help=_('Authentication region name, defaults to '
 | 
			
		||||
                   'env[OS_REGION_NAME].'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os_region_name',
 | 
			
		||||
            help=argparse.SUPPRESS)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-token', metavar='<token>',
 | 
			
		||||
            default=env('OS_TOKEN'),
 | 
			
		||||
            help=_('Authentication token, defaults to env[OS_TOKEN].'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os_token',
 | 
			
		||||
            help=argparse.SUPPRESS)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--http-timeout', metavar='<seconds>',
 | 
			
		||||
            default=env('OS_NETWORK_TIMEOUT', default=None), type=float,
 | 
			
		||||
            help=_('Timeout in seconds to wait for an HTTP response. Defaults '
 | 
			
		||||
                   'to env[OS_NETWORK_TIMEOUT] or None if not specified.'))
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os-url', metavar='<url>',
 | 
			
		||||
            default=env('OS_URL'),
 | 
			
		||||
            help=_('Defaults to env[OS_URL].'))
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--os_url',
 | 
			
		||||
            help=argparse.SUPPRESS)
 | 
			
		||||
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--insecure',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            default=env('NEUTRONCLIENT_INSECURE', default=False),
 | 
			
		||||
            help=_("Explicitly allow neutronclient to perform \"insecure\" "
 | 
			
		||||
                   "SSL (https) requests. The server's certificate will "
 | 
			
		||||
                   "not be verified against any certificate authorities. "
 | 
			
		||||
                   "This option should be used with caution."))
 | 
			
		||||
 | 
			
		||||
    def _bash_completion(self):
 | 
			
		||||
        """Prints all of the commands and options for bash-completion."""
 | 
			
		||||
        commands = set()
 | 
			
		||||
        options = set()
 | 
			
		||||
        for option, _action in self.parser._option_string_actions.items():
 | 
			
		||||
            options.add(option)
 | 
			
		||||
        for command_name, command in self.command_manager:
 | 
			
		||||
            commands.add(command_name)
 | 
			
		||||
            cmd_factory = command.load()
 | 
			
		||||
            cmd = cmd_factory(self, None)
 | 
			
		||||
            cmd_parser = cmd.get_parser('')
 | 
			
		||||
            for option, _action in cmd_parser._option_string_actions.items():
 | 
			
		||||
                options.add(option)
 | 
			
		||||
        print(' '.join(commands | options))
 | 
			
		||||
 | 
			
		||||
    def run(self, argv):
 | 
			
		||||
        """Equivalent to the main program for the application.
 | 
			
		||||
 | 
			
		||||
        :param argv: input arguments and options
 | 
			
		||||
        :paramtype argv: list of str
 | 
			
		||||
        """
 | 
			
		||||
        try:
 | 
			
		||||
            index = 0
 | 
			
		||||
            command_pos = -1
 | 
			
		||||
            help_pos = -1
 | 
			
		||||
            help_command_pos = -1
 | 
			
		||||
            for arg in argv:
 | 
			
		||||
                if arg == 'bash-completion':
 | 
			
		||||
                    self._bash_completion()
 | 
			
		||||
                    return 0
 | 
			
		||||
                if arg in self.commands[self.api_version]:
 | 
			
		||||
                    if command_pos == -1:
 | 
			
		||||
                        command_pos = index
 | 
			
		||||
                elif arg in ('-h', '--help'):
 | 
			
		||||
                    if help_pos == -1:
 | 
			
		||||
                        help_pos = index
 | 
			
		||||
                elif arg == 'help':
 | 
			
		||||
                    if help_command_pos == -1:
 | 
			
		||||
                        help_command_pos = index
 | 
			
		||||
                index = index + 1
 | 
			
		||||
            if command_pos > -1 and help_pos > command_pos:
 | 
			
		||||
                argv = ['help', argv[command_pos]]
 | 
			
		||||
            if help_command_pos > -1 and command_pos == -1:
 | 
			
		||||
                argv[help_command_pos] = '--help'
 | 
			
		||||
            self.options, remainder = self.parser.parse_known_args(argv)
 | 
			
		||||
            self.configure_logging()
 | 
			
		||||
            self.interactive_mode = not remainder
 | 
			
		||||
            self.initialize_app(remainder)
 | 
			
		||||
        except Exception as err:
 | 
			
		||||
            if self.options.verbose_level >= self.DEBUG_LEVEL:
 | 
			
		||||
                self.log.exception(unicode(err))
 | 
			
		||||
                raise
 | 
			
		||||
            else:
 | 
			
		||||
                self.log.error(unicode(err))
 | 
			
		||||
            return 1
 | 
			
		||||
        result = 1
 | 
			
		||||
        if self.interactive_mode:
 | 
			
		||||
            _argv = [sys.argv[0]]
 | 
			
		||||
            sys.argv = _argv
 | 
			
		||||
            result = self.interact()
 | 
			
		||||
        else:
 | 
			
		||||
            result = self.run_subcommand(remainder)
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    def run_subcommand(self, argv):
 | 
			
		||||
        subcommand = self.command_manager.find_command(argv)
 | 
			
		||||
        cmd_factory, cmd_name, sub_argv = subcommand
 | 
			
		||||
        cmd = cmd_factory(self, self.options)
 | 
			
		||||
        err = None
 | 
			
		||||
        result = 1
 | 
			
		||||
        try:
 | 
			
		||||
            self.prepare_to_run_command(cmd)
 | 
			
		||||
            full_name = (cmd_name
 | 
			
		||||
                         if self.interactive_mode
 | 
			
		||||
                         else ' '.join([self.NAME, cmd_name])
 | 
			
		||||
                         )
 | 
			
		||||
            cmd_parser = cmd.get_parser(full_name)
 | 
			
		||||
            return run_command(cmd, cmd_parser, sub_argv)
 | 
			
		||||
        except Exception as err:
 | 
			
		||||
            if self.options.verbose_level >= self.DEBUG_LEVEL:
 | 
			
		||||
                self.log.exception(unicode(err))
 | 
			
		||||
            else:
 | 
			
		||||
                self.log.error(unicode(err))
 | 
			
		||||
            try:
 | 
			
		||||
                self.clean_up(cmd, result, err)
 | 
			
		||||
            except Exception as err2:
 | 
			
		||||
                if self.options.verbose_level >= self.DEBUG_LEVEL:
 | 
			
		||||
                    self.log.exception(unicode(err2))
 | 
			
		||||
                else:
 | 
			
		||||
                    self.log.error(_('Could not clean up: %s'), unicode(err2))
 | 
			
		||||
            if self.options.verbose_level >= self.DEBUG_LEVEL:
 | 
			
		||||
                raise
 | 
			
		||||
        else:
 | 
			
		||||
            try:
 | 
			
		||||
                self.clean_up(cmd, result, None)
 | 
			
		||||
            except Exception as err3:
 | 
			
		||||
                if self.options.verbose_level >= self.DEBUG_LEVEL:
 | 
			
		||||
                    self.log.exception(unicode(err3))
 | 
			
		||||
                else:
 | 
			
		||||
                    self.log.error(_('Could not clean up: %s'), unicode(err3))
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    def authenticate_user(self):
 | 
			
		||||
        """Make sure the user has provided all of the authentication
 | 
			
		||||
        info we need.
 | 
			
		||||
        """
 | 
			
		||||
        if self.options.os_auth_strategy == 'keystone':
 | 
			
		||||
            if self.options.os_token or self.options.os_url:
 | 
			
		||||
                # Token flow auth takes priority
 | 
			
		||||
                if not self.options.os_token:
 | 
			
		||||
                    raise exc.CommandError(
 | 
			
		||||
                        _("You must provide a token via"
 | 
			
		||||
                          " either --os-token or env[OS_TOKEN]"))
 | 
			
		||||
 | 
			
		||||
                if not self.options.os_url:
 | 
			
		||||
                    raise exc.CommandError(
 | 
			
		||||
                        _("You must provide a service URL via"
 | 
			
		||||
                          " either --os-url or env[OS_URL]"))
 | 
			
		||||
 | 
			
		||||
            else:
 | 
			
		||||
                # Validate password flow auth
 | 
			
		||||
                project_info = (self.options.os_tenant_name or
 | 
			
		||||
                                self.options.os_tenant_id or
 | 
			
		||||
                                (self.options.os_project_name and
 | 
			
		||||
                                    (self.options.project_domain_name or
 | 
			
		||||
                                     self.options.project_domain_id)) or
 | 
			
		||||
                                self.options.os_project_id)
 | 
			
		||||
 | 
			
		||||
                if (not self.options.os_username
 | 
			
		||||
                    and not self.options.os_user_id):
 | 
			
		||||
                    raise exc.CommandError(
 | 
			
		||||
                        _("You must provide a username or user ID via"
 | 
			
		||||
                          "  --os-username, env[OS_USERNAME] or"
 | 
			
		||||
                          "  --os-user_id, env[OS_USER_ID]"))
 | 
			
		||||
 | 
			
		||||
                if not self.options.os_password:
 | 
			
		||||
                    raise exc.CommandError(
 | 
			
		||||
                        _("You must provide a password via"
 | 
			
		||||
                          " either --os-password or env[OS_PASSWORD]"))
 | 
			
		||||
 | 
			
		||||
                if (not project_info):
 | 
			
		||||
                    # tenent is deprecated in Keystone v3. Use the latest
 | 
			
		||||
                    # terminology instead.
 | 
			
		||||
                    raise exc.CommandError(
 | 
			
		||||
                        _("You must provide a project_id or project_name ("
 | 
			
		||||
                          "with project_domain_name or project_domain_id) "
 | 
			
		||||
                          "via "
 | 
			
		||||
                          "  --os-project-id (env[OS_PROJECT_ID])"
 | 
			
		||||
                          "  --os-project-name (env[OS_PROJECT_NAME]),"
 | 
			
		||||
                          "  --os-project-domain-id "
 | 
			
		||||
                          "(env[OS_PROJECT_DOMAIN_ID])"
 | 
			
		||||
                          "  --os-project-domain-name "
 | 
			
		||||
                          "(env[OS_PROJECT_DOMAIN_NAME])"))
 | 
			
		||||
 | 
			
		||||
                if not self.options.os_auth_url:
 | 
			
		||||
                    raise exc.CommandError(
 | 
			
		||||
                        _("You must provide an auth url via"
 | 
			
		||||
                          " either --os-auth-url or via env[OS_AUTH_URL]"))
 | 
			
		||||
        else:   # not keystone
 | 
			
		||||
            if not self.options.os_url:
 | 
			
		||||
                raise exc.CommandError(
 | 
			
		||||
                    _("You must provide a service URL via"
 | 
			
		||||
                      " either --os-url or env[OS_URL]"))
 | 
			
		||||
 | 
			
		||||
        auth_session = self._get_keystone_session()
 | 
			
		||||
 | 
			
		||||
        self.client_manager = clientmanager.ClientManager(
 | 
			
		||||
            token=self.options.os_token,
 | 
			
		||||
            url=self.options.os_url,
 | 
			
		||||
            auth_url=self.options.os_auth_url,
 | 
			
		||||
            tenant_name=self.options.os_tenant_name,
 | 
			
		||||
            tenant_id=self.options.os_tenant_id,
 | 
			
		||||
            username=self.options.os_username,
 | 
			
		||||
            user_id=self.options.os_user_id,
 | 
			
		||||
            password=self.options.os_password,
 | 
			
		||||
            region_name=self.options.os_region_name,
 | 
			
		||||
            api_version=self.api_version,
 | 
			
		||||
            auth_strategy=self.options.os_auth_strategy,
 | 
			
		||||
            # FIXME (bklei) honor deprecated service_type and
 | 
			
		||||
            # endpoint type until they are removed
 | 
			
		||||
            service_type=self.options.os_service_type or
 | 
			
		||||
            self.options.service_type,
 | 
			
		||||
            endpoint_type=self.options.os_endpoint_type or self.endpoint_type,
 | 
			
		||||
            insecure=self.options.insecure,
 | 
			
		||||
            ca_cert=self.options.os_cacert,
 | 
			
		||||
            timeout=self.options.http_timeout,
 | 
			
		||||
            retries=self.options.retries,
 | 
			
		||||
            raise_errors=False,
 | 
			
		||||
            session=auth_session,
 | 
			
		||||
            auth=auth_session.auth,
 | 
			
		||||
            log_credentials=True)
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    def initialize_app(self, argv):
 | 
			
		||||
        """Global app init bits:
 | 
			
		||||
 | 
			
		||||
        * set up API versions
 | 
			
		||||
        * validate authentication info
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        super(GBPShell, self).initialize_app(argv)
 | 
			
		||||
 | 
			
		||||
        self.api_version = {'network': self.api_version}
 | 
			
		||||
 | 
			
		||||
        # If the user is not asking for help, make sure they
 | 
			
		||||
        # have given us auth.
 | 
			
		||||
        cmd_name = None
 | 
			
		||||
        if argv:
 | 
			
		||||
            cmd_info = self.command_manager.find_command(argv)
 | 
			
		||||
            cmd_factory, cmd_name, sub_argv = cmd_info
 | 
			
		||||
        if self.interactive_mode or cmd_name != 'help':
 | 
			
		||||
            self.authenticate_user()
 | 
			
		||||
 | 
			
		||||
    def clean_up(self, cmd, result, err):
 | 
			
		||||
        self.log.debug('clean_up %s', cmd.__class__.__name__)
 | 
			
		||||
        if err:
 | 
			
		||||
            self.log.debug('Got an error: %s', unicode(err))
 | 
			
		||||
 | 
			
		||||
    def configure_logging(self):
 | 
			
		||||
        """Create logging handlers for any log output."""
 | 
			
		||||
        root_logger = logging.getLogger('')
 | 
			
		||||
 | 
			
		||||
        # Set up logging to a file
 | 
			
		||||
        root_logger.setLevel(logging.DEBUG)
 | 
			
		||||
 | 
			
		||||
        # Send higher-level messages to the console via stderr
 | 
			
		||||
        console = logging.StreamHandler(self.stderr)
 | 
			
		||||
        console_level = {self.WARNING_LEVEL: logging.WARNING,
 | 
			
		||||
                         self.INFO_LEVEL: logging.INFO,
 | 
			
		||||
                         self.DEBUG_LEVEL: logging.DEBUG,
 | 
			
		||||
                         }.get(self.options.verbose_level, logging.DEBUG)
 | 
			
		||||
        console.setLevel(console_level)
 | 
			
		||||
        if logging.DEBUG == console_level:
 | 
			
		||||
            formatter = logging.Formatter(self.DEBUG_MESSAGE_FORMAT)
 | 
			
		||||
        else:
 | 
			
		||||
            formatter = logging.Formatter(self.CONSOLE_MESSAGE_FORMAT)
 | 
			
		||||
        logging.getLogger('urllib3.connectionpool').setLevel(logging.WARNING)
 | 
			
		||||
        console.setFormatter(formatter)
 | 
			
		||||
        root_logger.addHandler(console)
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    def get_v2_auth(self, v2_auth_url):
 | 
			
		||||
        return v2_auth.Password(
 | 
			
		||||
            v2_auth_url,
 | 
			
		||||
            username=self.options.os_username,
 | 
			
		||||
            password=self.options.os_password,
 | 
			
		||||
            tenant_id=self.options.os_tenant_id,
 | 
			
		||||
            tenant_name=self.options.os_tenant_name)
 | 
			
		||||
 | 
			
		||||
    def get_v3_auth(self, v3_auth_url):
 | 
			
		||||
        project_id = self.options.os_project_id or self.options.os_tenant_id
 | 
			
		||||
        project_name = (self.options.os_project_name or
 | 
			
		||||
                        self.options.os_tenant_name)
 | 
			
		||||
 | 
			
		||||
        return v3_auth.Password(
 | 
			
		||||
            v3_auth_url,
 | 
			
		||||
            username=self.options.os_username,
 | 
			
		||||
            password=self.options.os_password,
 | 
			
		||||
            user_id=self.options.os_user_id,
 | 
			
		||||
            user_domain_name=self.options.os_user_domain_name,
 | 
			
		||||
            user_domain_id=self.options.os_user_domain_id,
 | 
			
		||||
            project_id=project_id,
 | 
			
		||||
            project_name=project_name,
 | 
			
		||||
            project_domain_name=self.options.os_project_domain_name,
 | 
			
		||||
            project_domain_id=self.options.os_project_domain_id
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def _discover_auth_versions(self, session, auth_url):
 | 
			
		||||
        # discover the API versions the server is supporting base on the
 | 
			
		||||
        # given URL
 | 
			
		||||
        try:
 | 
			
		||||
            ks_discover = discover.Discover(session=session, auth_url=auth_url)
 | 
			
		||||
            return (ks_discover.url_for('2.0'), ks_discover.url_for('3.0'))
 | 
			
		||||
        except ks_exc.ClientException:
 | 
			
		||||
            # Identity service may not support discover API version.
 | 
			
		||||
            # Lets try to figure out the API version from the original URL.
 | 
			
		||||
            url_parts = urlparse.urlparse(auth_url)
 | 
			
		||||
            (scheme, netloc, path, params, query, fragment) = url_parts
 | 
			
		||||
            path = path.lower()
 | 
			
		||||
            if path.startswith('/v3'):
 | 
			
		||||
                return (None, auth_url)
 | 
			
		||||
            elif path.startswith('/v2'):
 | 
			
		||||
                return (auth_url, None)
 | 
			
		||||
            else:
 | 
			
		||||
                # not enough information to determine the auth version
 | 
			
		||||
                msg = _('Unable to determine the Keystone version '
 | 
			
		||||
                        'to authenticate with using the given '
 | 
			
		||||
                        'auth_url. Identity service may not support API '
 | 
			
		||||
                        'version discovery. Please provide a versioned '
 | 
			
		||||
                        'auth_url instead.')
 | 
			
		||||
                raise exc.CommandError(msg)
 | 
			
		||||
 | 
			
		||||
    def _get_keystone_session(self):
 | 
			
		||||
        # first create a Keystone session
 | 
			
		||||
        cacert = self.options.os_cacert or None
 | 
			
		||||
        cert = self.options.os_cert or None
 | 
			
		||||
        key = self.options.os_key or None
 | 
			
		||||
        insecure = self.options.insecure or False
 | 
			
		||||
        ks_session = session.Session.construct(dict(cacert=cacert,
 | 
			
		||||
                                                    cert=cert,
 | 
			
		||||
                                                    key=key,
 | 
			
		||||
                                                    insecure=insecure))
 | 
			
		||||
        # discover the supported keystone versions using the given url
 | 
			
		||||
        (v2_auth_url, v3_auth_url) = self._discover_auth_versions(
 | 
			
		||||
            session=ks_session,
 | 
			
		||||
            auth_url=self.options.os_auth_url)
 | 
			
		||||
 | 
			
		||||
        # Determine which authentication plugin to use. First inspect the
 | 
			
		||||
        # auth_url to see the supported version. If both v3 and v2 are
 | 
			
		||||
        # supported, then use the highest version if possible.
 | 
			
		||||
        user_domain_name = self.options.os_user_domain_name or None
 | 
			
		||||
        user_domain_id = self.options.os_user_domain_id or None
 | 
			
		||||
        project_domain_name = self.options.os_project_domain_name or None
 | 
			
		||||
        project_domain_id = self.options.os_project_domain_id or None
 | 
			
		||||
        domain_info = (user_domain_name or user_domain_id or
 | 
			
		||||
                       project_domain_name or project_domain_id)
 | 
			
		||||
 | 
			
		||||
        if (v2_auth_url and not domain_info) or not v3_auth_url:
 | 
			
		||||
            ks_session.auth = self.get_v2_auth(v2_auth_url)
 | 
			
		||||
        else:
 | 
			
		||||
            ks_session.auth = self.get_v3_auth(v3_auth_url)
 | 
			
		||||
 | 
			
		||||
        return ks_session
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main(argv=sys.argv[1:]):
 | 
			
		||||
    try:
 | 
			
		||||
        return GBPShell(NEUTRON_API_VERSION).run(map(strutils.safe_decode,
 | 
			
		||||
                                                     argv))
 | 
			
		||||
    except exc.NeutronClientException:
 | 
			
		||||
        return 1
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        print(unicode(e))
 | 
			
		||||
        return 1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    sys.exit(main(sys.argv[1:]))
 | 
			
		||||
@@ -30,7 +30,6 @@ from keystoneclient import exceptions as ks_exceptions
 | 
			
		||||
from keystoneclient.fixture import v2 as ks_v2_fixture
 | 
			
		||||
from keystoneclient.fixture import v3 as ks_v3_fixture
 | 
			
		||||
from keystoneclient import session
 | 
			
		||||
 | 
			
		||||
from neutronclient import client
 | 
			
		||||
from neutronclient.common import exceptions
 | 
			
		||||
from neutronclient.common import utils
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,3 @@
 | 
			
		||||
# Copyright 2012 OpenStack Foundation.
 | 
			
		||||
# 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
 | 
			
		||||
@@ -14,198 +11,56 @@
 | 
			
		||||
#    under the License.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
import contextlib
 | 
			
		||||
import itertools
 | 
			
		||||
import sys
 | 
			
		||||
import urllib
 | 
			
		||||
 | 
			
		||||
import fixtures
 | 
			
		||||
from mox3 import mox
 | 
			
		||||
from oslotest import base
 | 
			
		||||
import requests
 | 
			
		||||
import six
 | 
			
		||||
import six.moves.urllib.parse as urlparse
 | 
			
		||||
 | 
			
		||||
from neutronclient.common import constants
 | 
			
		||||
from neutronclient.common import exceptions
 | 
			
		||||
from neutronclient.neutron import v2_0 as neutronV2_0
 | 
			
		||||
from neutronclient import shell
 | 
			
		||||
from neutronclient.v2_0 import client
 | 
			
		||||
from neutronclient.tests.unit import test_cli20 as neutron_test_cli20
 | 
			
		||||
import requests
 | 
			
		||||
 | 
			
		||||
API_VERSION = "2.0"
 | 
			
		||||
FORMAT = 'json'
 | 
			
		||||
TOKEN = 'testtoken'
 | 
			
		||||
ENDURL = 'localurl'
 | 
			
		||||
from gbpclient.gbp import v2_0 as gbpV2_0
 | 
			
		||||
from gbpclient import gbpshell
 | 
			
		||||
from gbpclient.v2_0 import client as gbpclient
 | 
			
		||||
 | 
			
		||||
API_VERSION = neutron_test_cli20.API_VERSION
 | 
			
		||||
FORMAT = neutron_test_cli20.FORMAT
 | 
			
		||||
TOKEN = neutron_test_cli20.TOKEN
 | 
			
		||||
ENDURL = neutron_test_cli20.ENDURL
 | 
			
		||||
capture_std_streams = neutron_test_cli20.capture_std_streams
 | 
			
		||||
end_url = neutron_test_cli20.end_url
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@contextlib.contextmanager
 | 
			
		||||
def capture_std_streams():
 | 
			
		||||
    fake_stdout, fake_stderr = six.StringIO(), six.StringIO()
 | 
			
		||||
    stdout, stderr = sys.stdout, sys.stderr
 | 
			
		||||
    try:
 | 
			
		||||
        sys.stdout, sys.stderr = fake_stdout, fake_stderr
 | 
			
		||||
        yield fake_stdout, fake_stderr
 | 
			
		||||
    finally:
 | 
			
		||||
        sys.stdout, sys.stderr = stdout, stderr
 | 
			
		||||
class FakeStdout(neutron_test_cli20.FakeStdout):
 | 
			
		||||
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FakeStdout:
 | 
			
		||||
class MyResp(neutron_test_cli20.MyResp):
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.content = []
 | 
			
		||||
 | 
			
		||||
    def write(self, text):
 | 
			
		||||
        self.content.append(text)
 | 
			
		||||
 | 
			
		||||
    def make_string(self):
 | 
			
		||||
        result = ''
 | 
			
		||||
        for line in self.content:
 | 
			
		||||
            result = result + line
 | 
			
		||||
        return result
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MyResp(object):
 | 
			
		||||
    def __init__(self, status_code, headers=None, reason=None):
 | 
			
		||||
        self.status_code = status_code
 | 
			
		||||
        self.headers = headers or {}
 | 
			
		||||
        self.reason = reason
 | 
			
		||||
class MyApp(neutron_test_cli20.MyApp):
 | 
			
		||||
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MyApp(object):
 | 
			
		||||
    def __init__(self, _stdout):
 | 
			
		||||
        self.stdout = _stdout
 | 
			
		||||
class MyUrlComparator(neutron_test_cli20.MyUrlComparator):
 | 
			
		||||
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def end_url(path, query=None, format=FORMAT):
 | 
			
		||||
    _url_str = ENDURL + "/v" + API_VERSION + path + "." + format
 | 
			
		||||
    return query and _url_str + "?" + query or _url_str
 | 
			
		||||
class MyComparator(neutron_test_cli20.MyComparator):
 | 
			
		||||
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MyUrlComparator(mox.Comparator):
 | 
			
		||||
    def __init__(self, lhs, client):
 | 
			
		||||
        self.lhs = lhs
 | 
			
		||||
        self.client = client
 | 
			
		||||
class CLITestV20Base(neutron_test_cli20.CLITestV20Base):
 | 
			
		||||
 | 
			
		||||
    def equals(self, rhs):
 | 
			
		||||
        lhsp = urlparse.urlparse(self.lhs)
 | 
			
		||||
        rhsp = urlparse.urlparse(rhs)
 | 
			
		||||
 | 
			
		||||
        return (lhsp.scheme == rhsp.scheme and
 | 
			
		||||
                lhsp.netloc == rhsp.netloc and
 | 
			
		||||
                lhsp.path == rhsp.path and
 | 
			
		||||
                urlparse.parse_qs(lhsp.query) == urlparse.parse_qs(rhsp.query))
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        if self.client and self.client.format != FORMAT:
 | 
			
		||||
            lhs_parts = self.lhs.split("?", 1)
 | 
			
		||||
            if len(lhs_parts) == 2:
 | 
			
		||||
                lhs = ("%s.%s?%s" % (lhs_parts[0][:-4],
 | 
			
		||||
                                     self.client.format,
 | 
			
		||||
                                     lhs_parts[1]))
 | 
			
		||||
            else:
 | 
			
		||||
                lhs = ("%s.%s" % (lhs_parts[0][:-4],
 | 
			
		||||
                                  self.client.format))
 | 
			
		||||
            return lhs
 | 
			
		||||
        return self.lhs
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return str(self)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MyComparator(mox.Comparator):
 | 
			
		||||
    def __init__(self, lhs, client):
 | 
			
		||||
        self.lhs = lhs
 | 
			
		||||
        self.client = client
 | 
			
		||||
 | 
			
		||||
    def _com_dict(self, lhs, rhs):
 | 
			
		||||
        if len(lhs) != len(rhs):
 | 
			
		||||
            return False
 | 
			
		||||
        for key, value in six.iteritems(lhs):
 | 
			
		||||
            if key not in rhs:
 | 
			
		||||
                return False
 | 
			
		||||
            rhs_value = rhs[key]
 | 
			
		||||
            if not self._com(value, rhs_value):
 | 
			
		||||
                return False
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    def _com_list(self, lhs, rhs):
 | 
			
		||||
        if len(lhs) != len(rhs):
 | 
			
		||||
            return False
 | 
			
		||||
        for lhs_value in lhs:
 | 
			
		||||
            if lhs_value not in rhs:
 | 
			
		||||
                return False
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    def _com(self, lhs, rhs):
 | 
			
		||||
        if lhs is None:
 | 
			
		||||
            return rhs is None
 | 
			
		||||
        if isinstance(lhs, dict):
 | 
			
		||||
            if not isinstance(rhs, dict):
 | 
			
		||||
                return False
 | 
			
		||||
            return self._com_dict(lhs, rhs)
 | 
			
		||||
        if isinstance(lhs, list):
 | 
			
		||||
            if not isinstance(rhs, list):
 | 
			
		||||
                return False
 | 
			
		||||
            return self._com_list(lhs, rhs)
 | 
			
		||||
        if isinstance(lhs, tuple):
 | 
			
		||||
            if not isinstance(rhs, tuple):
 | 
			
		||||
                return False
 | 
			
		||||
            return self._com_list(lhs, rhs)
 | 
			
		||||
        return lhs == rhs
 | 
			
		||||
 | 
			
		||||
    def equals(self, rhs):
 | 
			
		||||
        if self.client:
 | 
			
		||||
            rhs = self.client.deserialize(rhs, 200)
 | 
			
		||||
        return self._com(self.lhs, rhs)
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        if self.client:
 | 
			
		||||
            return self.client.serialize(self.lhs)
 | 
			
		||||
        return str(self.lhs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CLITestV20Base(base.BaseTestCase):
 | 
			
		||||
 | 
			
		||||
    format = 'json'
 | 
			
		||||
    test_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
 | 
			
		||||
    id_field = 'id'
 | 
			
		||||
 | 
			
		||||
    def _find_resourceid(self, client, resource, name_or_id,
 | 
			
		||||
                         cmd_resource=None, parent_id=None):
 | 
			
		||||
        return name_or_id
 | 
			
		||||
 | 
			
		||||
    def _get_attr_metadata(self):
 | 
			
		||||
        return self.metadata
 | 
			
		||||
        client.Client.EXTED_PLURALS.update(constants.PLURALS)
 | 
			
		||||
        client.Client.EXTED_PLURALS.update({'tags': 'tag'})
 | 
			
		||||
        return {'plurals': client.Client.EXTED_PLURALS,
 | 
			
		||||
                'xmlns': constants.XML_NS_V20,
 | 
			
		||||
                constants.EXT_NS: {'prefix': 'http://xxxx.yy.com'}}
 | 
			
		||||
    shell = gbpshell
 | 
			
		||||
    client = gbpclient
 | 
			
		||||
 | 
			
		||||
    def setUp(self, plurals=None):
 | 
			
		||||
        """Prepare the test environment."""
 | 
			
		||||
        super(CLITestV20Base, self).setUp()
 | 
			
		||||
        client.Client.EXTED_PLURALS.update(constants.PLURALS)
 | 
			
		||||
        if plurals is not None:
 | 
			
		||||
            client.Client.EXTED_PLURALS.update(plurals)
 | 
			
		||||
        self.metadata = {'plurals': client.Client.EXTED_PLURALS,
 | 
			
		||||
                         'xmlns': constants.XML_NS_V20,
 | 
			
		||||
                         constants.EXT_NS: {'prefix':
 | 
			
		||||
                                            'http://xxxx.yy.com'}}
 | 
			
		||||
        self.mox = mox.Mox()
 | 
			
		||||
        self.endurl = ENDURL
 | 
			
		||||
        self.fake_stdout = FakeStdout()
 | 
			
		||||
        self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.fake_stdout))
 | 
			
		||||
        self.useFixture(fixtures.MonkeyPatch(
 | 
			
		||||
            'neutronclient.neutron.v2_0.find_resourceid_by_name_or_id',
 | 
			
		||||
            self._find_resourceid))
 | 
			
		||||
        self.useFixture(fixtures.MonkeyPatch(
 | 
			
		||||
            'neutronclient.neutron.v2_0.find_resourceid_by_id',
 | 
			
		||||
            self._find_resourceid))
 | 
			
		||||
        self.useFixture(fixtures.MonkeyPatch(
 | 
			
		||||
            'neutronclient.v2_0.client.Client.get_attr_metadata',
 | 
			
		||||
            self._get_attr_metadata))
 | 
			
		||||
        self.client = client.Client(token=TOKEN, endpoint_url=self.endurl)
 | 
			
		||||
        self.client = gbpclient.Client(token=TOKEN, endpoint_url=self.endurl)
 | 
			
		||||
 | 
			
		||||
    def _test_create_resource(self, resource, cmd, name, myid, args,
 | 
			
		||||
                              position_names, position_values,
 | 
			
		||||
@@ -215,19 +70,9 @@ class CLITestV20Base(base.BaseTestCase):
 | 
			
		||||
        self.mox.StubOutWithMock(cmd, "get_client")
 | 
			
		||||
        self.mox.StubOutWithMock(self.client.httpclient, "request")
 | 
			
		||||
        cmd.get_client().MultipleTimes().AndReturn(self.client)
 | 
			
		||||
        non_admin_status_resources = ['subnet', 'floatingip', 'security_group',
 | 
			
		||||
                                      'security_group_rule', 'qos_queue',
 | 
			
		||||
                                      'network_gateway', 'gateway_device',
 | 
			
		||||
                                      'credential', 'network_profile',
 | 
			
		||||
                                      'policy_profile', 'ikepolicy',
 | 
			
		||||
                                      'ipsecpolicy', 'metering_label',
 | 
			
		||||
                                      'metering_label_rule', 'net_partition']
 | 
			
		||||
        if not cmd_resource:
 | 
			
		||||
            cmd_resource = resource
 | 
			
		||||
        if (resource in non_admin_status_resources):
 | 
			
		||||
            body = {resource: {}, }
 | 
			
		||||
        else:
 | 
			
		||||
            body = {resource: {'admin_state_up': admin_state_up, }, }
 | 
			
		||||
        body = {resource: {}, }
 | 
			
		||||
        if tenant_id:
 | 
			
		||||
            body[resource].update({'tenant_id': tenant_id})
 | 
			
		||||
        if tags:
 | 
			
		||||
@@ -245,8 +90,8 @@ class CLITestV20Base(base.BaseTestCase):
 | 
			
		||||
        self.client.format = self.format
 | 
			
		||||
        resstr = self.client.serialize(ress)
 | 
			
		||||
        # url method body
 | 
			
		||||
        resource_plural = neutronV2_0._get_resource_plural(cmd_resource,
 | 
			
		||||
                                                           self.client)
 | 
			
		||||
        resource_plural = gbpV2_0._get_resource_plural(cmd_resource,
 | 
			
		||||
                                                       self.client)
 | 
			
		||||
        path = getattr(self.client, resource_plural + "_path")
 | 
			
		||||
        if parent_id:
 | 
			
		||||
            path = path % parent_id
 | 
			
		||||
@@ -264,7 +109,7 @@ class CLITestV20Base(base.BaseTestCase):
 | 
			
		||||
        args.extend(['--request-format', self.format])
 | 
			
		||||
        self.mox.ReplayAll()
 | 
			
		||||
        cmd_parser = cmd.get_parser('create_' + resource)
 | 
			
		||||
        shell.run_command(cmd, cmd_parser, args)
 | 
			
		||||
        gbpshell.run_command(cmd, cmd_parser, args)
 | 
			
		||||
        self.mox.VerifyAll()
 | 
			
		||||
        self.mox.UnsetStubs()
 | 
			
		||||
        _str = self.fake_stdout.make_string()
 | 
			
		||||
@@ -272,354 +117,10 @@ class CLITestV20Base(base.BaseTestCase):
 | 
			
		||||
        if name:
 | 
			
		||||
            self.assertIn(name, _str)
 | 
			
		||||
 | 
			
		||||
    def _test_list_columns(self, cmd, resources,
 | 
			
		||||
                           resources_out, args=('-f', 'json'),
 | 
			
		||||
                           cmd_resources=None, parent_id=None):
 | 
			
		||||
        self.mox.StubOutWithMock(cmd, "get_client")
 | 
			
		||||
        self.mox.StubOutWithMock(self.client.httpclient, "request")
 | 
			
		||||
        cmd.get_client().MultipleTimes().AndReturn(self.client)
 | 
			
		||||
        self.client.format = self.format
 | 
			
		||||
        if not cmd_resources:
 | 
			
		||||
            cmd_resources = resources
 | 
			
		||||
 | 
			
		||||
        resstr = self.client.serialize(resources_out)
 | 
			
		||||
 | 
			
		||||
        path = getattr(self.client, cmd_resources + "_path")
 | 
			
		||||
        if parent_id:
 | 
			
		||||
            path = path % parent_id
 | 
			
		||||
        self.client.httpclient.request(
 | 
			
		||||
            end_url(path, format=self.format), 'GET',
 | 
			
		||||
            body=None,
 | 
			
		||||
            headers=mox.ContainsKeyValue(
 | 
			
		||||
                'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr))
 | 
			
		||||
        args = tuple(args) + ('--request-format', self.format)
 | 
			
		||||
        self.mox.ReplayAll()
 | 
			
		||||
        cmd_parser = cmd.get_parser("list_" + cmd_resources)
 | 
			
		||||
        shell.run_command(cmd, cmd_parser, args)
 | 
			
		||||
        self.mox.VerifyAll()
 | 
			
		||||
        self.mox.UnsetStubs()
 | 
			
		||||
 | 
			
		||||
    def _test_list_resources(self, resources, cmd, detail=False, tags=(),
 | 
			
		||||
                             fields_1=(), fields_2=(), page_size=None,
 | 
			
		||||
                             sort_key=(), sort_dir=(), response_contents=None,
 | 
			
		||||
                             base_args=None, path=None, cmd_resources=None,
 | 
			
		||||
                             parent_id=None):
 | 
			
		||||
        self.mox.StubOutWithMock(cmd, "get_client")
 | 
			
		||||
        self.mox.StubOutWithMock(self.client.httpclient, "request")
 | 
			
		||||
        cmd.get_client().MultipleTimes().AndReturn(self.client)
 | 
			
		||||
        if not cmd_resources:
 | 
			
		||||
            cmd_resources = resources
 | 
			
		||||
        if response_contents is None:
 | 
			
		||||
            contents = [{self.id_field: 'myid1', },
 | 
			
		||||
                        {self.id_field: 'myid2', }, ]
 | 
			
		||||
        else:
 | 
			
		||||
            contents = response_contents
 | 
			
		||||
        reses = {resources: contents}
 | 
			
		||||
        self.client.format = self.format
 | 
			
		||||
        resstr = self.client.serialize(reses)
 | 
			
		||||
        # url method body
 | 
			
		||||
        query = ""
 | 
			
		||||
        args = base_args if base_args is not None else []
 | 
			
		||||
        if detail:
 | 
			
		||||
            args.append('-D')
 | 
			
		||||
        args.extend(['--request-format', self.format])
 | 
			
		||||
        if fields_1:
 | 
			
		||||
            for field in fields_1:
 | 
			
		||||
                args.append('--fields')
 | 
			
		||||
                args.append(field)
 | 
			
		||||
 | 
			
		||||
        if tags:
 | 
			
		||||
            args.append('--')
 | 
			
		||||
            args.append("--tag")
 | 
			
		||||
        for tag in tags:
 | 
			
		||||
            args.append(tag)
 | 
			
		||||
            if isinstance(tag, unicode):
 | 
			
		||||
                tag = urllib.quote(tag.encode('utf-8'))
 | 
			
		||||
            if query:
 | 
			
		||||
                query += "&tag=" + tag
 | 
			
		||||
            else:
 | 
			
		||||
                query = "tag=" + tag
 | 
			
		||||
        if (not tags) and fields_2:
 | 
			
		||||
            args.append('--')
 | 
			
		||||
        if fields_2:
 | 
			
		||||
            args.append("--fields")
 | 
			
		||||
            for field in fields_2:
 | 
			
		||||
                args.append(field)
 | 
			
		||||
        if detail:
 | 
			
		||||
            query = query and query + '&verbose=True' or 'verbose=True'
 | 
			
		||||
        for field in itertools.chain(fields_1, fields_2):
 | 
			
		||||
            if query:
 | 
			
		||||
                query += "&fields=" + field
 | 
			
		||||
            else:
 | 
			
		||||
                query = "fields=" + field
 | 
			
		||||
        if page_size:
 | 
			
		||||
            args.append("--page-size")
 | 
			
		||||
            args.append(str(page_size))
 | 
			
		||||
            if query:
 | 
			
		||||
                query += "&limit=%s" % page_size
 | 
			
		||||
            else:
 | 
			
		||||
                query = "limit=%s" % page_size
 | 
			
		||||
        if sort_key:
 | 
			
		||||
            for key in sort_key:
 | 
			
		||||
                args.append('--sort-key')
 | 
			
		||||
                args.append(key)
 | 
			
		||||
                if query:
 | 
			
		||||
                    query += '&'
 | 
			
		||||
                query += 'sort_key=%s' % key
 | 
			
		||||
        if sort_dir:
 | 
			
		||||
            len_diff = len(sort_key) - len(sort_dir)
 | 
			
		||||
            if len_diff > 0:
 | 
			
		||||
                sort_dir = tuple(sort_dir) + ('asc',) * len_diff
 | 
			
		||||
            elif len_diff < 0:
 | 
			
		||||
                sort_dir = sort_dir[:len(sort_key)]
 | 
			
		||||
            for dir in sort_dir:
 | 
			
		||||
                args.append('--sort-dir')
 | 
			
		||||
                args.append(dir)
 | 
			
		||||
                if query:
 | 
			
		||||
                    query += '&'
 | 
			
		||||
                query += 'sort_dir=%s' % dir
 | 
			
		||||
        if path is None:
 | 
			
		||||
            path = getattr(self.client, cmd_resources + "_path")
 | 
			
		||||
            if parent_id:
 | 
			
		||||
                path = path % parent_id
 | 
			
		||||
        self.client.httpclient.request(
 | 
			
		||||
            MyUrlComparator(end_url(path, query, format=self.format),
 | 
			
		||||
                            self.client),
 | 
			
		||||
            'GET',
 | 
			
		||||
            body=None,
 | 
			
		||||
            headers=mox.ContainsKeyValue(
 | 
			
		||||
                'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr))
 | 
			
		||||
        self.mox.ReplayAll()
 | 
			
		||||
        cmd_parser = cmd.get_parser("list_" + cmd_resources)
 | 
			
		||||
        shell.run_command(cmd, cmd_parser, args)
 | 
			
		||||
        self.mox.VerifyAll()
 | 
			
		||||
        self.mox.UnsetStubs()
 | 
			
		||||
        _str = self.fake_stdout.make_string()
 | 
			
		||||
        if response_contents is None:
 | 
			
		||||
            self.assertIn('myid1', _str)
 | 
			
		||||
        return _str
 | 
			
		||||
 | 
			
		||||
    def _test_list_resources_with_pagination(self, resources, cmd,
 | 
			
		||||
                                             cmd_resources=None,
 | 
			
		||||
                                             parent_id=None):
 | 
			
		||||
        self.mox.StubOutWithMock(cmd, "get_client")
 | 
			
		||||
        self.mox.StubOutWithMock(self.client.httpclient, "request")
 | 
			
		||||
        cmd.get_client().MultipleTimes().AndReturn(self.client)
 | 
			
		||||
        if not cmd_resources:
 | 
			
		||||
            cmd_resources = resources
 | 
			
		||||
 | 
			
		||||
        path = getattr(self.client, cmd_resources + "_path")
 | 
			
		||||
        if parent_id:
 | 
			
		||||
            path = path % parent_id
 | 
			
		||||
        fake_query = "marker=myid2&limit=2"
 | 
			
		||||
        reses1 = {resources: [{'id': 'myid1', },
 | 
			
		||||
                              {'id': 'myid2', }],
 | 
			
		||||
                  '%s_links' % resources: [{'href': end_url(path, fake_query),
 | 
			
		||||
                                            'rel': 'next'}]}
 | 
			
		||||
        reses2 = {resources: [{'id': 'myid3', },
 | 
			
		||||
                              {'id': 'myid4', }]}
 | 
			
		||||
        self.client.format = self.format
 | 
			
		||||
        resstr1 = self.client.serialize(reses1)
 | 
			
		||||
        resstr2 = self.client.serialize(reses2)
 | 
			
		||||
        self.client.httpclient.request(
 | 
			
		||||
            end_url(path, "", format=self.format), 'GET',
 | 
			
		||||
            body=None,
 | 
			
		||||
            headers=mox.ContainsKeyValue(
 | 
			
		||||
                'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr1))
 | 
			
		||||
        self.client.httpclient.request(
 | 
			
		||||
            MyUrlComparator(end_url(path, fake_query, format=self.format),
 | 
			
		||||
                            self.client), 'GET',
 | 
			
		||||
            body=None,
 | 
			
		||||
            headers=mox.ContainsKeyValue(
 | 
			
		||||
                'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr2))
 | 
			
		||||
        self.mox.ReplayAll()
 | 
			
		||||
        cmd_parser = cmd.get_parser("list_" + cmd_resources)
 | 
			
		||||
        args = ['--request-format', self.format]
 | 
			
		||||
        shell.run_command(cmd, cmd_parser, args)
 | 
			
		||||
        self.mox.VerifyAll()
 | 
			
		||||
        self.mox.UnsetStubs()
 | 
			
		||||
 | 
			
		||||
    def _test_update_resource(self, resource, cmd, myid, args, extrafields,
 | 
			
		||||
                              cmd_resource=None, parent_id=None):
 | 
			
		||||
        self.mox.StubOutWithMock(cmd, "get_client")
 | 
			
		||||
        self.mox.StubOutWithMock(self.client.httpclient, "request")
 | 
			
		||||
        cmd.get_client().MultipleTimes().AndReturn(self.client)
 | 
			
		||||
        if not cmd_resource:
 | 
			
		||||
            cmd_resource = resource
 | 
			
		||||
 | 
			
		||||
        body = {resource: extrafields}
 | 
			
		||||
        path = getattr(self.client, cmd_resource + "_path")
 | 
			
		||||
        if parent_id:
 | 
			
		||||
            path = path % (parent_id, myid)
 | 
			
		||||
        else:
 | 
			
		||||
            path = path % myid
 | 
			
		||||
        self.client.format = self.format
 | 
			
		||||
        # Work around for LP #1217791. XML deserializer called from
 | 
			
		||||
        # MyComparator does not decodes XML string correctly.
 | 
			
		||||
        if self.format == 'json':
 | 
			
		||||
            mox_body = MyComparator(body, self.client)
 | 
			
		||||
        else:
 | 
			
		||||
            mox_body = self.client.serialize(body)
 | 
			
		||||
        self.client.httpclient.request(
 | 
			
		||||
            MyUrlComparator(end_url(path, format=self.format),
 | 
			
		||||
                            self.client),
 | 
			
		||||
            'PUT',
 | 
			
		||||
            body=mox_body,
 | 
			
		||||
            headers=mox.ContainsKeyValue(
 | 
			
		||||
                'X-Auth-Token', TOKEN)).AndReturn((MyResp(204), None))
 | 
			
		||||
        args.extend(['--request-format', self.format])
 | 
			
		||||
        self.mox.ReplayAll()
 | 
			
		||||
        cmd_parser = cmd.get_parser("update_" + cmd_resource)
 | 
			
		||||
        shell.run_command(cmd, cmd_parser, args)
 | 
			
		||||
        self.mox.VerifyAll()
 | 
			
		||||
        self.mox.UnsetStubs()
 | 
			
		||||
        _str = self.fake_stdout.make_string()
 | 
			
		||||
        self.assertIn(myid, _str)
 | 
			
		||||
 | 
			
		||||
    def _test_show_resource(self, resource, cmd, myid, args, fields=(),
 | 
			
		||||
                            cmd_resource=None, parent_id=None):
 | 
			
		||||
        self.mox.StubOutWithMock(cmd, "get_client")
 | 
			
		||||
        self.mox.StubOutWithMock(self.client.httpclient, "request")
 | 
			
		||||
        cmd.get_client().MultipleTimes().AndReturn(self.client)
 | 
			
		||||
        if not cmd_resource:
 | 
			
		||||
            cmd_resource = resource
 | 
			
		||||
 | 
			
		||||
        query = "&".join(["fields=%s" % field for field in fields])
 | 
			
		||||
        expected_res = {resource:
 | 
			
		||||
                        {self.id_field: myid,
 | 
			
		||||
                         'name': 'myname', }, }
 | 
			
		||||
        self.client.format = self.format
 | 
			
		||||
        resstr = self.client.serialize(expected_res)
 | 
			
		||||
        path = getattr(self.client, cmd_resource + "_path")
 | 
			
		||||
        if parent_id:
 | 
			
		||||
            path = path % (parent_id, myid)
 | 
			
		||||
        else:
 | 
			
		||||
            path = path % myid
 | 
			
		||||
        self.client.httpclient.request(
 | 
			
		||||
            end_url(path, query, format=self.format), 'GET',
 | 
			
		||||
            body=None,
 | 
			
		||||
            headers=mox.ContainsKeyValue(
 | 
			
		||||
                'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr))
 | 
			
		||||
        args.extend(['--request-format', self.format])
 | 
			
		||||
        self.mox.ReplayAll()
 | 
			
		||||
        cmd_parser = cmd.get_parser("show_" + cmd_resource)
 | 
			
		||||
        shell.run_command(cmd, cmd_parser, args)
 | 
			
		||||
        self.mox.VerifyAll()
 | 
			
		||||
        self.mox.UnsetStubs()
 | 
			
		||||
        _str = self.fake_stdout.make_string()
 | 
			
		||||
        self.assertIn(myid, _str)
 | 
			
		||||
        self.assertIn('myname', _str)
 | 
			
		||||
 | 
			
		||||
    def _test_delete_resource(self, resource, cmd, myid, args,
 | 
			
		||||
                              cmd_resource=None, parent_id=None):
 | 
			
		||||
        self.mox.StubOutWithMock(cmd, "get_client")
 | 
			
		||||
        self.mox.StubOutWithMock(self.client.httpclient, "request")
 | 
			
		||||
        cmd.get_client().MultipleTimes().AndReturn(self.client)
 | 
			
		||||
        if not cmd_resource:
 | 
			
		||||
            cmd_resource = resource
 | 
			
		||||
        path = getattr(self.client, cmd_resource + "_path")
 | 
			
		||||
        if parent_id:
 | 
			
		||||
            path = path % (parent_id, myid)
 | 
			
		||||
        else:
 | 
			
		||||
            path = path % (myid)
 | 
			
		||||
        self.client.httpclient.request(
 | 
			
		||||
            end_url(path, format=self.format), 'DELETE',
 | 
			
		||||
            body=None,
 | 
			
		||||
            headers=mox.ContainsKeyValue(
 | 
			
		||||
                'X-Auth-Token', TOKEN)).AndReturn((MyResp(204), None))
 | 
			
		||||
        args.extend(['--request-format', self.format])
 | 
			
		||||
        self.mox.ReplayAll()
 | 
			
		||||
        cmd_parser = cmd.get_parser("delete_" + cmd_resource)
 | 
			
		||||
        shell.run_command(cmd, cmd_parser, args)
 | 
			
		||||
        self.mox.VerifyAll()
 | 
			
		||||
        self.mox.UnsetStubs()
 | 
			
		||||
        _str = self.fake_stdout.make_string()
 | 
			
		||||
        self.assertIn(myid, _str)
 | 
			
		||||
 | 
			
		||||
    def _test_update_resource_action(self, resource, cmd, myid, action, args,
 | 
			
		||||
                                     body, retval=None, cmd_resource=None):
 | 
			
		||||
        self.mox.StubOutWithMock(cmd, "get_client")
 | 
			
		||||
        self.mox.StubOutWithMock(self.client.httpclient, "request")
 | 
			
		||||
        cmd.get_client().MultipleTimes().AndReturn(self.client)
 | 
			
		||||
        if not cmd_resource:
 | 
			
		||||
            cmd_resource = resource
 | 
			
		||||
        path = getattr(self.client, cmd_resource + "_path")
 | 
			
		||||
        path_action = '%s/%s' % (myid, action)
 | 
			
		||||
        self.client.httpclient.request(
 | 
			
		||||
            end_url(path % path_action, format=self.format), 'PUT',
 | 
			
		||||
            body=MyComparator(body, self.client),
 | 
			
		||||
            headers=mox.ContainsKeyValue(
 | 
			
		||||
                'X-Auth-Token', TOKEN)).AndReturn((MyResp(204), retval))
 | 
			
		||||
        args.extend(['--request-format', self.format])
 | 
			
		||||
        self.mox.ReplayAll()
 | 
			
		||||
        cmd_parser = cmd.get_parser("delete_" + cmd_resource)
 | 
			
		||||
        shell.run_command(cmd, cmd_parser, args)
 | 
			
		||||
        self.mox.VerifyAll()
 | 
			
		||||
        self.mox.UnsetStubs()
 | 
			
		||||
        _str = self.fake_stdout.make_string()
 | 
			
		||||
        self.assertIn(myid, _str)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ClientV2TestJson(CLITestV20Base):
 | 
			
		||||
    def test_do_request_unicode(self):
 | 
			
		||||
        self.client.format = self.format
 | 
			
		||||
        self.mox.StubOutWithMock(self.client.httpclient, "request")
 | 
			
		||||
        unicode_text = u'\u7f51\u7edc'
 | 
			
		||||
        # url with unicode
 | 
			
		||||
        action = u'/test'
 | 
			
		||||
        expected_action = action.encode('utf-8')
 | 
			
		||||
        # query string with unicode
 | 
			
		||||
        params = {'test': unicode_text}
 | 
			
		||||
        expect_query = urllib.urlencode({'test':
 | 
			
		||||
                                         unicode_text.encode('utf-8')})
 | 
			
		||||
        # request body with unicode
 | 
			
		||||
        body = params
 | 
			
		||||
        expect_body = self.client.serialize(body)
 | 
			
		||||
        # headers with unicode
 | 
			
		||||
        self.client.httpclient.auth_token = unicode_text
 | 
			
		||||
        expected_auth_token = unicode_text.encode('utf-8')
 | 
			
		||||
 | 
			
		||||
        self.client.httpclient.request(
 | 
			
		||||
            end_url(expected_action, query=expect_query, format=self.format),
 | 
			
		||||
            'PUT', body=expect_body,
 | 
			
		||||
            headers=mox.ContainsKeyValue(
 | 
			
		||||
                'X-Auth-Token',
 | 
			
		||||
                expected_auth_token)).AndReturn((MyResp(200), expect_body))
 | 
			
		||||
 | 
			
		||||
        self.mox.ReplayAll()
 | 
			
		||||
        res_body = self.client.do_request('PUT', action, body=body,
 | 
			
		||||
                                          params=params)
 | 
			
		||||
        self.mox.VerifyAll()
 | 
			
		||||
        self.mox.UnsetStubs()
 | 
			
		||||
 | 
			
		||||
        # test response with unicode
 | 
			
		||||
        self.assertEqual(res_body, body)
 | 
			
		||||
 | 
			
		||||
    def test_do_request_error_without_response_body(self):
 | 
			
		||||
        self.client.format = self.format
 | 
			
		||||
        self.mox.StubOutWithMock(self.client.httpclient, "request")
 | 
			
		||||
        params = {'test': 'value'}
 | 
			
		||||
        expect_query = six.moves.urllib.parse.urlencode(params)
 | 
			
		||||
        self.client.httpclient.auth_token = 'token'
 | 
			
		||||
 | 
			
		||||
        self.client.httpclient.request(
 | 
			
		||||
            MyUrlComparator(end_url(
 | 
			
		||||
                '/test', query=expect_query, format=self.format), self.client),
 | 
			
		||||
            'PUT', body='',
 | 
			
		||||
            headers=mox.ContainsKeyValue('X-Auth-Token', 'token')
 | 
			
		||||
        ).AndReturn((MyResp(400, reason='An error'), ''))
 | 
			
		||||
 | 
			
		||||
        self.mox.ReplayAll()
 | 
			
		||||
        error = self.assertRaises(exceptions.NeutronClientException,
 | 
			
		||||
                                  self.client.do_request, 'PUT', '/test',
 | 
			
		||||
                                  body='', params=params)
 | 
			
		||||
        self.assertEqual("An error", str(error))
 | 
			
		||||
        self.mox.VerifyAll()
 | 
			
		||||
        self.mox.UnsetStubs()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ClientV2UnicodeTestXML(ClientV2TestJson):
 | 
			
		||||
    format = 'xml'
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CLITestV20ExceptionHandler(CLITestV20Base):
 | 
			
		||||
@@ -634,7 +135,7 @@ class CLITestV20ExceptionHandler(CLITestV20Base):
 | 
			
		||||
                                              'detail': error_detail}}
 | 
			
		||||
 | 
			
		||||
        e = self.assertRaises(expected_exception,
 | 
			
		||||
                              client.exception_handler_v20,
 | 
			
		||||
                              gbpclient.exception_handler_v20,
 | 
			
		||||
                              status_code, error_content)
 | 
			
		||||
        self.assertEqual(status_code, e.status_code)
 | 
			
		||||
 | 
			
		||||
@@ -645,44 +146,13 @@ class CLITestV20ExceptionHandler(CLITestV20Base):
 | 
			
		||||
                expected_msg = error_msg
 | 
			
		||||
        self.assertEqual(expected_msg, e.message)
 | 
			
		||||
 | 
			
		||||
    def test_exception_handler_v20_ip_address_in_use(self):
 | 
			
		||||
        err_msg = ('Unable to complete operation for network '
 | 
			
		||||
                   'fake-network-uuid. The IP address fake-ip is in use.')
 | 
			
		||||
        self._test_exception_handler_v20(
 | 
			
		||||
            exceptions.IpAddressInUseClient, 409, err_msg,
 | 
			
		||||
            'IpAddressInUse', err_msg, '')
 | 
			
		||||
 | 
			
		||||
    def test_exception_handler_v20_neutron_known_error(self):
 | 
			
		||||
        known_error_map = [
 | 
			
		||||
            ('NetworkNotFound', exceptions.NetworkNotFoundClient, 404),
 | 
			
		||||
            ('PortNotFound', exceptions.PortNotFoundClient, 404),
 | 
			
		||||
            ('NetworkInUse', exceptions.NetworkInUseClient, 409),
 | 
			
		||||
            ('PortInUse', exceptions.PortInUseClient, 409),
 | 
			
		||||
            ('StateInvalid', exceptions.StateInvalidClient, 400),
 | 
			
		||||
            ('IpAddressInUse', exceptions.IpAddressInUseClient, 409),
 | 
			
		||||
            ('IpAddressGenerationFailure',
 | 
			
		||||
             exceptions.IpAddressGenerationFailureClient, 409),
 | 
			
		||||
            ('MacAddressInUse', exceptions.MacAddressInUseClient, 409),
 | 
			
		||||
            ('ExternalIpAddressExhausted',
 | 
			
		||||
             exceptions.ExternalIpAddressExhaustedClient, 400),
 | 
			
		||||
            ('OverQuota', exceptions.OverQuotaClient, 409),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        error_msg = 'dummy exception message'
 | 
			
		||||
        error_detail = 'sample detail'
 | 
			
		||||
        for server_exc, client_exc, status_code in known_error_map:
 | 
			
		||||
            self._test_exception_handler_v20(
 | 
			
		||||
                client_exc, status_code,
 | 
			
		||||
                error_msg + '\n' + error_detail,
 | 
			
		||||
                server_exc, error_msg, error_detail)
 | 
			
		||||
        # TODO(Sumit): This needs to be adapted for GBP
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def test_exception_handler_v20_neutron_known_error_without_detail(self):
 | 
			
		||||
        error_msg = 'Network not found'
 | 
			
		||||
        error_detail = ''
 | 
			
		||||
        self._test_exception_handler_v20(
 | 
			
		||||
            exceptions.NetworkNotFoundClient, 404,
 | 
			
		||||
            error_msg,
 | 
			
		||||
            'NetworkNotFound', error_msg, error_detail)
 | 
			
		||||
        # TODO(Sumit): This needs to be adapted for GBP
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def test_exception_handler_v20_unknown_error_to_per_code_exception(self):
 | 
			
		||||
        for status_code, client_exc in exceptions.HTTP_EXCEPTION_MAP.items():
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										137
									
								
								gbpclient/tests/unit/test_cli20_networkservicepolicy.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								gbpclient/tests/unit/test_cli20_networkservicepolicy.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,137 @@
 | 
			
		||||
#    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 gbpclient.gbp.v2_0 import groupbasedpolicy as gbp
 | 
			
		||||
from gbpclient.tests.unit import test_cli20
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CLITestV20NetworkServicePolicyJSON(test_cli20.CLITestV20Base):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(CLITestV20NetworkServicePolicyJSON, self).setUp()
 | 
			
		||||
 | 
			
		||||
    def test_create_nsp_with_mandatory_params(self):
 | 
			
		||||
        """network-service-policy-create with mandatory params."""
 | 
			
		||||
        resource = 'network_service_policy'
 | 
			
		||||
        cmd = gbp.CreateNetworkServicePolicy(test_cli20.MyApp(sys.stdout),
 | 
			
		||||
                                             None)
 | 
			
		||||
        name = 'my-name'
 | 
			
		||||
        tenant_id = 'my-tenant'
 | 
			
		||||
        my_id = 'my-id'
 | 
			
		||||
        args = ['--tenant-id', tenant_id,
 | 
			
		||||
                name]
 | 
			
		||||
        position_names = ['name', ]
 | 
			
		||||
        position_values = [name, ]
 | 
			
		||||
        self._test_create_resource(resource, cmd, name, my_id, args,
 | 
			
		||||
                                   position_names, position_values,
 | 
			
		||||
                                   tenant_id=tenant_id)
 | 
			
		||||
 | 
			
		||||
    def test_create_network_service_policy_with_all_params(self):
 | 
			
		||||
        """network-service-policy-create with all params."""
 | 
			
		||||
        resource = 'network_service_policy'
 | 
			
		||||
        cmd = gbp.CreateNetworkServicePolicy(test_cli20.MyApp(sys.stdout),
 | 
			
		||||
                                             None)
 | 
			
		||||
        name = 'myname'
 | 
			
		||||
        tenant_id = 'mytenant'
 | 
			
		||||
        description = 'Mynsp'
 | 
			
		||||
        my_id = 'someid'
 | 
			
		||||
        network_svc_params = "type=ip_single,name=vip,value=self_subnet"
 | 
			
		||||
        args = ['--tenant_id', tenant_id,
 | 
			
		||||
                '--description', description,
 | 
			
		||||
                '--network-service-params', network_svc_params,
 | 
			
		||||
                name]
 | 
			
		||||
        position_names = ['name', 'description', 'network_service_params']
 | 
			
		||||
        net_params = [{"type": "ip_single", "name": "vip",
 | 
			
		||||
                       "value": "self_subnet"}]
 | 
			
		||||
        position_values = [name, description, net_params]
 | 
			
		||||
        self._test_create_resource(resource, cmd, name, my_id, args,
 | 
			
		||||
                                   position_names, position_values,
 | 
			
		||||
                                   tenant_id=tenant_id)
 | 
			
		||||
 | 
			
		||||
    def test_list_network_service_policies(self):
 | 
			
		||||
        """network-sercvice-policy-list."""
 | 
			
		||||
        resources = 'network_service_policies'
 | 
			
		||||
        cmd = gbp.ListNetworkServicePolicy(test_cli20.MyApp(sys.stdout),
 | 
			
		||||
                                           None)
 | 
			
		||||
        self._test_list_resources(resources, cmd, True)
 | 
			
		||||
 | 
			
		||||
    def test_list_network_service_policies_with_pagination(self):
 | 
			
		||||
        """network-sercvice-policy-list."""
 | 
			
		||||
        resources = 'network_service_policies'
 | 
			
		||||
        cmd = gbp.ListNetworkServicePolicy(test_cli20.MyApp(sys.stdout),
 | 
			
		||||
                                           None)
 | 
			
		||||
        self._test_list_resources_with_pagination(resources, cmd)
 | 
			
		||||
 | 
			
		||||
    def test_list_network_sercice_policies_sort(self):
 | 
			
		||||
        """network-service-policy-list --sort-key name --sort-key id
 | 
			
		||||
        --sort-key asc --sort-key desc
 | 
			
		||||
        """
 | 
			
		||||
        resources = 'network_service_policies'
 | 
			
		||||
        cmd = gbp.ListNetworkServicePolicy(test_cli20.MyApp(sys.stdout),
 | 
			
		||||
                                           None)
 | 
			
		||||
        self._test_list_resources(resources, cmd,
 | 
			
		||||
                                  sort_key=["name", "id"],
 | 
			
		||||
                                  sort_dir=["asc", "desc"])
 | 
			
		||||
 | 
			
		||||
    def test_list_network_service_polices_limit(self):
 | 
			
		||||
        """network-service-policy-list -P."""
 | 
			
		||||
        resources = 'network_service_policies'
 | 
			
		||||
        cmd = gbp.ListNetworkServicePolicy(test_cli20.MyApp(sys.stdout),
 | 
			
		||||
                                           None)
 | 
			
		||||
        self._test_list_resources(resources, cmd, page_size=1000)
 | 
			
		||||
 | 
			
		||||
    def test_show_network_service_policy_id(self):
 | 
			
		||||
        """network-service-policy-show test_id."""
 | 
			
		||||
        resource = 'network_service_policy'
 | 
			
		||||
        cmd = gbp.ShowNetworkServicePolicy(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        args = ['--fields', 'id', self.test_id]
 | 
			
		||||
        self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
 | 
			
		||||
 | 
			
		||||
    def test_show_network_service_policy_id_name(self):
 | 
			
		||||
        """network-service-policy-show."""
 | 
			
		||||
        resource = 'network_service_policy'
 | 
			
		||||
        cmd = gbp.ShowNetworkServicePolicy(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_network_service_policy(self):
 | 
			
		||||
        """network-service-policy-update  myid --name myname --tags a b."""
 | 
			
		||||
        resource = 'network_service_policy'
 | 
			
		||||
        cmd = gbp.UpdateNetworkServicePolicy(test_cli20.MyApp(sys.stdout),
 | 
			
		||||
                                             None)
 | 
			
		||||
        self._test_update_resource(resource, cmd, 'myid',
 | 
			
		||||
                                   ['myid', '--name', 'myname',
 | 
			
		||||
                                    '--tags', 'a', 'b'],
 | 
			
		||||
                                   {'name': 'myname', 'tags': ['a', 'b'], })
 | 
			
		||||
 | 
			
		||||
    def test_update_network_service_policy_with_allparams(self):
 | 
			
		||||
        resource = 'network_service_policy'
 | 
			
		||||
        new_name = "new_name"
 | 
			
		||||
        cmd = gbp.UpdateNetworkServicePolicy(test_cli20.MyApp(sys.stdout),
 | 
			
		||||
                                             None)
 | 
			
		||||
        body = {
 | 
			
		||||
            'name': new_name
 | 
			
		||||
        }
 | 
			
		||||
        args = ['myid', '--name', new_name, '--request-format', 'json']
 | 
			
		||||
        self._test_update_resource(resource, cmd, 'myid', args, body)
 | 
			
		||||
 | 
			
		||||
    def test_delete_network_service_policy(self):
 | 
			
		||||
        """network-service-policy-delete my-id."""
 | 
			
		||||
        resource = 'network_service_policy'
 | 
			
		||||
        cmd = gbp.DeleteNetworkServicePolicy(test_cli20.MyApp(sys.stdout),
 | 
			
		||||
                                             None)
 | 
			
		||||
        my_id = 'my-id'
 | 
			
		||||
        args = [my_id]
 | 
			
		||||
        self._test_delete_resource(resource, cmd, my_id, args)
 | 
			
		||||
							
								
								
									
										135
									
								
								gbpclient/tests/unit/test_cli20_policyaction.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								gbpclient/tests/unit/test_cli20_policyaction.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
#    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 gbpclient.gbp.v2_0 import groupbasedpolicy as gbp
 | 
			
		||||
from gbpclient.tests.unit import test_cli20
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CLITestV20PolicyActionJSON(test_cli20.CLITestV20Base):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(CLITestV20PolicyActionJSON, self).setUp()
 | 
			
		||||
 | 
			
		||||
    def test_create_policy_action_with_mandatory_params(self):
 | 
			
		||||
        """grouppolicy-policy-action-create with all mandatory params."""
 | 
			
		||||
        resource = 'policy_action'
 | 
			
		||||
        cmd = gbp.CreatePolicyAction(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        name = 'my-name'
 | 
			
		||||
        tenant_id = 'my-tenant'
 | 
			
		||||
        my_id = 'my-id'
 | 
			
		||||
        args = ['--tenant-id', tenant_id,
 | 
			
		||||
                name]
 | 
			
		||||
        position_names = ['name', ]
 | 
			
		||||
        position_values = [name, ]
 | 
			
		||||
        self._test_create_resource(resource, cmd, name, my_id, args,
 | 
			
		||||
                                   position_names, position_values,
 | 
			
		||||
                                   tenant_id=tenant_id)
 | 
			
		||||
 | 
			
		||||
    def test_create_policy_action_with_all_params(self):
 | 
			
		||||
        """grouppolicy-policy-action-create with all params."""
 | 
			
		||||
        resource = 'policy_action'
 | 
			
		||||
        cmd = gbp.CreatePolicyAction(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        name = 'my-name'
 | 
			
		||||
        tenant_id = 'my-tenant'
 | 
			
		||||
        description = 'My PolicyAction'
 | 
			
		||||
        my_id = 'my-id'
 | 
			
		||||
        action_type = "allow"
 | 
			
		||||
        action_value = "1234"
 | 
			
		||||
        args = ['--tenant-id', tenant_id,
 | 
			
		||||
                '--description', description,
 | 
			
		||||
                '--action-type', action_type,
 | 
			
		||||
                '--action-value', action_value,
 | 
			
		||||
                name]
 | 
			
		||||
        position_names = ['name', ]
 | 
			
		||||
        position_values = [name, ]
 | 
			
		||||
        self._test_create_resource(resource, cmd, name, my_id, args,
 | 
			
		||||
                                   position_names, position_values,
 | 
			
		||||
                                   tenant_id=tenant_id,
 | 
			
		||||
                                   description=description,
 | 
			
		||||
                                   action_type=action_type,
 | 
			
		||||
                                   action_value=action_value)
 | 
			
		||||
 | 
			
		||||
    def test_list_policy_actions(self):
 | 
			
		||||
        """grouppolicy-policy-action-list."""
 | 
			
		||||
        resources = 'policy_actions'
 | 
			
		||||
        cmd = gbp.ListPolicyAction(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_list_resources(resources, cmd, True)
 | 
			
		||||
 | 
			
		||||
    def test_list_policy_actions_pagination(self):
 | 
			
		||||
        """grouppolicy-policy-action-list."""
 | 
			
		||||
        resources = 'policy_actions'
 | 
			
		||||
        cmd = gbp.ListPolicyAction(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_list_resources_with_pagination(resources, cmd)
 | 
			
		||||
 | 
			
		||||
    def test_list_policy_actions_sort(self):
 | 
			
		||||
        """grouppolicy-policy-action-list --sort-key name --sort-key id
 | 
			
		||||
        --sort-key asc --sort-key desc
 | 
			
		||||
        """
 | 
			
		||||
        resources = 'policy_actions'
 | 
			
		||||
        cmd = gbp.ListPolicyAction(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_list_resources(resources, cmd,
 | 
			
		||||
                                  sort_key=["name", "id"],
 | 
			
		||||
                                  sort_dir=["asc", "desc"])
 | 
			
		||||
 | 
			
		||||
    def test_list_policy_actions_limit(self):
 | 
			
		||||
        """grouppolicy-policy-action-list -P."""
 | 
			
		||||
        resources = 'policy_actions'
 | 
			
		||||
        cmd = gbp.ListPolicyAction(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_list_resources(resources, cmd, page_size=1000)
 | 
			
		||||
 | 
			
		||||
    def test_show_policy_action_id(self):
 | 
			
		||||
        """grouppolicy-policy-action-show test_id."""
 | 
			
		||||
        resource = 'policy_action'
 | 
			
		||||
        cmd = gbp.ShowPolicyAction(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        args = ['--fields', 'id', self.test_id]
 | 
			
		||||
        self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
 | 
			
		||||
 | 
			
		||||
    def test_show_policy_action_id_name(self):
 | 
			
		||||
        """grouppolicy-policy-action-show."""
 | 
			
		||||
        resource = 'policy_action'
 | 
			
		||||
        cmd = gbp.ShowPolicyAction(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_policy_action(self):
 | 
			
		||||
        """grouppolicy-policy-action-update  myid --name myname --tags a b."""
 | 
			
		||||
        resource = 'policy_action'
 | 
			
		||||
        cmd = gbp.UpdatePolicyAction(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_update_resource(resource, cmd, 'myid',
 | 
			
		||||
                                   ['myid', '--name', 'myname',
 | 
			
		||||
                                    '--tags', 'a', 'b'],
 | 
			
		||||
                                   {'name': 'myname', 'tags': ['a', 'b'], })
 | 
			
		||||
 | 
			
		||||
    def test_update_policy_action_with_allparams(self):
 | 
			
		||||
        resource = 'policy_action'
 | 
			
		||||
        action_type = "allow"
 | 
			
		||||
        action_value = "1234"
 | 
			
		||||
        cmd = gbp.UpdatePolicyAction(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        body = {
 | 
			
		||||
            'action_type': action_type,
 | 
			
		||||
            'action_value': action_value
 | 
			
		||||
        }
 | 
			
		||||
        args = ['myid',
 | 
			
		||||
                '--action-type', action_type,
 | 
			
		||||
                '--action-value', action_value, ]
 | 
			
		||||
        self._test_update_resource(resource, cmd, 'myid', args, body)
 | 
			
		||||
 | 
			
		||||
    def test_delete_policy_action(self):
 | 
			
		||||
        """grouppolicy-policy-action-delete my-id."""
 | 
			
		||||
        resource = 'policy_action'
 | 
			
		||||
        cmd = gbp.DeletePolicyAction(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        my_id = 'my-id'
 | 
			
		||||
        args = [my_id]
 | 
			
		||||
        self._test_delete_resource(resource, cmd, my_id, args)
 | 
			
		||||
							
								
								
									
										141
									
								
								gbpclient/tests/unit/test_cli20_policyclassifier.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								gbpclient/tests/unit/test_cli20_policyclassifier.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
			
		||||
#    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 gbpclient.gbp.v2_0 import groupbasedpolicy as gbp
 | 
			
		||||
from gbpclient.tests.unit import test_cli20
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CLITestV20PolicyClassifierJSON(test_cli20.CLITestV20Base):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(CLITestV20PolicyClassifierJSON, self).setUp()
 | 
			
		||||
 | 
			
		||||
    def test_create_policy_classifier_with_mandatory_params(self):
 | 
			
		||||
        """grouppolicy-policy-classifier-create with all mandatory params."""
 | 
			
		||||
        resource = 'policy_classifier'
 | 
			
		||||
        cmd = gbp.CreatePolicyClassifier(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        name = 'my-name'
 | 
			
		||||
        tenant_id = 'my-tenant'
 | 
			
		||||
        my_id = 'my-id'
 | 
			
		||||
        args = ['--tenant-id', tenant_id,
 | 
			
		||||
                name]
 | 
			
		||||
        position_names = ['name', ]
 | 
			
		||||
        position_values = [name, ]
 | 
			
		||||
        self._test_create_resource(resource, cmd, name, my_id, args,
 | 
			
		||||
                                   position_names, position_values,
 | 
			
		||||
                                   tenant_id=tenant_id)
 | 
			
		||||
 | 
			
		||||
    def test_create_policy_classifier_with_all_params(self):
 | 
			
		||||
        """grouppolicy-policy-classifier-create with all params."""
 | 
			
		||||
        resource = 'policy_classifier'
 | 
			
		||||
        cmd = gbp.CreatePolicyClassifier(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        name = 'my-name'
 | 
			
		||||
        tenant_id = 'my-tenant'
 | 
			
		||||
        description = 'My PolicyClassifier'
 | 
			
		||||
        my_id = 'my-id'
 | 
			
		||||
        protocol = 'tcp'
 | 
			
		||||
        port_range = '10-80'
 | 
			
		||||
        direction = 'in'
 | 
			
		||||
        args = ['--tenant-id', tenant_id,
 | 
			
		||||
                '--description', description,
 | 
			
		||||
                '--protocol', protocol,
 | 
			
		||||
                '--port-range', port_range,
 | 
			
		||||
                '--direction', direction,
 | 
			
		||||
                name]
 | 
			
		||||
        position_names = ['name', ]
 | 
			
		||||
        position_values = [name, ]
 | 
			
		||||
        self._test_create_resource(resource, cmd, name, my_id, args,
 | 
			
		||||
                                   position_names, position_values,
 | 
			
		||||
                                   tenant_id=tenant_id,
 | 
			
		||||
                                   description=description,
 | 
			
		||||
                                   protocol=protocol,
 | 
			
		||||
                                   port_range=port_range,
 | 
			
		||||
                                   direction=direction)
 | 
			
		||||
 | 
			
		||||
    def test_list_policy_classifiers(self):
 | 
			
		||||
        """grouppolicy-policy-classifier-list."""
 | 
			
		||||
        resources = 'policy_classifiers'
 | 
			
		||||
        cmd = gbp.ListPolicyClassifier(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_list_resources(resources, cmd, True)
 | 
			
		||||
 | 
			
		||||
    def test_list_policy_classifiers_pagination(self):
 | 
			
		||||
        """grouppolicy-policy-classifier-list."""
 | 
			
		||||
        resources = 'policy_classifiers'
 | 
			
		||||
        cmd = gbp.ListPolicyClassifier(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_list_resources_with_pagination(resources, cmd)
 | 
			
		||||
 | 
			
		||||
    def test_list_policy_classifiers_sort(self):
 | 
			
		||||
        """grouppolicy-policy-classifier-list --sort-key name --sort-key id
 | 
			
		||||
        --sort-key asc --sort-key desc
 | 
			
		||||
        """
 | 
			
		||||
        resources = 'policy_classifiers'
 | 
			
		||||
        cmd = gbp.ListPolicyClassifier(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_list_resources(resources, cmd,
 | 
			
		||||
                                  sort_key=["name", "id"],
 | 
			
		||||
                                  sort_dir=["asc", "desc"])
 | 
			
		||||
 | 
			
		||||
    def test_list_policy_classifiers_limit(self):
 | 
			
		||||
        """grouppolicy-policy-classifier-list -P."""
 | 
			
		||||
        resources = 'policy_classifiers'
 | 
			
		||||
        cmd = gbp.ListPolicyClassifier(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_list_resources(resources, cmd, page_size=1000)
 | 
			
		||||
 | 
			
		||||
    def test_show_policy_classifier_id(self):
 | 
			
		||||
        """grouppolicy-policy-classifier-show test_id."""
 | 
			
		||||
        resource = 'policy_classifier'
 | 
			
		||||
        cmd = gbp.ShowPolicyClassifier(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        args = ['--fields', 'id', self.test_id]
 | 
			
		||||
        self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
 | 
			
		||||
 | 
			
		||||
    def test_show_policy_classifier_id_name(self):
 | 
			
		||||
        """grouppolicy-policy-classifier-show."""
 | 
			
		||||
        resource = 'policy_classifier'
 | 
			
		||||
        cmd = gbp.ShowPolicyClassifier(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_policy_classifier(self):
 | 
			
		||||
        """grouppolicy-policy-classifier-update  myid --name myname --tags a b.
 | 
			
		||||
        """
 | 
			
		||||
        resource = 'policy_classifier'
 | 
			
		||||
        cmd = gbp.UpdatePolicyClassifier(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_update_resource(resource, cmd, 'myid',
 | 
			
		||||
                                   ['myid', '--name', 'myname',
 | 
			
		||||
                                    '--tags', 'a', 'b'],
 | 
			
		||||
                                   {'name': 'myname', 'tags': ['a', 'b'], })
 | 
			
		||||
 | 
			
		||||
    def test_update_policy_classifier_with_allparams(self):
 | 
			
		||||
        resource = 'policy_classifier'
 | 
			
		||||
        protocol = 'tcp'
 | 
			
		||||
        port_range = '10-80'
 | 
			
		||||
        direction = 'in'
 | 
			
		||||
        cmd = gbp.UpdatePolicyClassifier(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        body = {
 | 
			
		||||
            'protocol': protocol,
 | 
			
		||||
            'port_range': port_range,
 | 
			
		||||
            'direction': direction
 | 
			
		||||
        }
 | 
			
		||||
        args = ['myid', '--protocol', protocol,
 | 
			
		||||
                '--port-range', port_range,
 | 
			
		||||
                '--direction', direction, ]
 | 
			
		||||
        self._test_update_resource(resource, cmd, 'myid', args, body)
 | 
			
		||||
 | 
			
		||||
    def test_delete_policy_classifier(self):
 | 
			
		||||
        """grouppolicy-policy-classifier-delete my-id."""
 | 
			
		||||
        resource = 'policy_classifier'
 | 
			
		||||
        cmd = gbp.DeletePolicyClassifier(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        my_id = 'my-id'
 | 
			
		||||
        args = [my_id]
 | 
			
		||||
        self._test_delete_resource(resource, cmd, my_id, args)
 | 
			
		||||
							
								
								
									
										142
									
								
								gbpclient/tests/unit/test_cli20_policyrule.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								gbpclient/tests/unit/test_cli20_policyrule.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,142 @@
 | 
			
		||||
#    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 gbpclient.gbp.v2_0 import groupbasedpolicy as gbp
 | 
			
		||||
from gbpclient.tests.unit import test_cli20
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CLITestV20PolicyRuleJSON(test_cli20.CLITestV20Base):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(CLITestV20PolicyRuleJSON, self).setUp()
 | 
			
		||||
 | 
			
		||||
    def test_create_policy_rule_with_mandatory_params(self):
 | 
			
		||||
        """grouppolicy-policy-rule-create with all mandatory params."""
 | 
			
		||||
        resource = 'policy_rule'
 | 
			
		||||
        cmd = gbp.CreatePolicyRule(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        name = 'my-name'
 | 
			
		||||
        tenant_id = 'my-tenant'
 | 
			
		||||
        my_id = 'my-id'
 | 
			
		||||
        args = ['--tenant-id', tenant_id,
 | 
			
		||||
                name]
 | 
			
		||||
        position_names = ['name', ]
 | 
			
		||||
        position_values = [name, ]
 | 
			
		||||
        self._test_create_resource(resource, cmd, name, my_id, args,
 | 
			
		||||
                                   position_names, position_values,
 | 
			
		||||
                                   tenant_id=tenant_id)
 | 
			
		||||
 | 
			
		||||
    def test_create_policy_rule_with_all_params(self):
 | 
			
		||||
        """grouppolicy-policy-rule-create with all params."""
 | 
			
		||||
        resource = 'policy_rule'
 | 
			
		||||
        cmd = gbp.CreatePolicyRule(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        name = 'my-name'
 | 
			
		||||
        tenant_id = 'my-tenant'
 | 
			
		||||
        description = 'My PolicyRule'
 | 
			
		||||
        my_id = 'my-id'
 | 
			
		||||
        enabled = True
 | 
			
		||||
        policy_classifier_id = 'pc-id'
 | 
			
		||||
        policy_actions_res = ["pa1", "pa2"]
 | 
			
		||||
        policy_actions_arg = "pa1 pa2"
 | 
			
		||||
        args = ['--tenant-id', tenant_id,
 | 
			
		||||
                '--description', description,
 | 
			
		||||
                '--enabled', "True",
 | 
			
		||||
                '--classifier', policy_classifier_id,
 | 
			
		||||
                '--actions', policy_actions_arg,
 | 
			
		||||
                name]
 | 
			
		||||
        position_names = ['name', ]
 | 
			
		||||
        position_values = [name, ]
 | 
			
		||||
        self._test_create_resource(resource, cmd, name, my_id, args,
 | 
			
		||||
                                   position_names, position_values,
 | 
			
		||||
                                   tenant_id=tenant_id,
 | 
			
		||||
                                   description=description,
 | 
			
		||||
                                   enabled=enabled,
 | 
			
		||||
                                   policy_classifier_id=policy_classifier_id,
 | 
			
		||||
                                   policy_actions=policy_actions_res)
 | 
			
		||||
 | 
			
		||||
    def test_list_policy_rules(self):
 | 
			
		||||
        """grouppolicy-policy-rule-list."""
 | 
			
		||||
        resources = 'policy_rules'
 | 
			
		||||
        cmd = gbp.ListPolicyRule(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_list_resources(resources, cmd, True)
 | 
			
		||||
 | 
			
		||||
    def test_list_policy_rules_pagination(self):
 | 
			
		||||
        """grouppolicy-policy-rule-list."""
 | 
			
		||||
        resources = 'policy_rules'
 | 
			
		||||
        cmd = gbp.ListPolicyRule(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_list_resources_with_pagination(resources, cmd)
 | 
			
		||||
 | 
			
		||||
    def test_list_policy_rules_sort(self):
 | 
			
		||||
        """grouppolicy-policy-rule-list --sort-key name --sort-key id
 | 
			
		||||
        --sort-key asc --sort-key desc
 | 
			
		||||
        """
 | 
			
		||||
        resources = 'policy_rules'
 | 
			
		||||
        cmd = gbp.ListPolicyRule(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_list_resources(resources, cmd,
 | 
			
		||||
                                  sort_key=["name", "id"],
 | 
			
		||||
                                  sort_dir=["asc", "desc"])
 | 
			
		||||
 | 
			
		||||
    def test_list_policy_rules_limit(self):
 | 
			
		||||
        """grouppolicy-policy-rule-list -P."""
 | 
			
		||||
        resources = 'policy_rules'
 | 
			
		||||
        cmd = gbp.ListPolicyRule(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_list_resources(resources, cmd, page_size=1000)
 | 
			
		||||
 | 
			
		||||
    def test_show_policy_classifier_id(self):
 | 
			
		||||
        """grouppolicy-policy-rule-show test_id."""
 | 
			
		||||
        resource = 'policy_rule'
 | 
			
		||||
        cmd = gbp.ShowPolicyRule(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        args = ['--fields', 'id', self.test_id]
 | 
			
		||||
        self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
 | 
			
		||||
 | 
			
		||||
    def test_show_policy_classifier_id_name(self):
 | 
			
		||||
        """grouppolicy-policy-rule-show."""
 | 
			
		||||
        resource = 'policy_rule'
 | 
			
		||||
        cmd = gbp.ShowPolicyRule(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_policy_rule(self):
 | 
			
		||||
        """grouppolicy-policy-rule-update  myid --name myname --tags a b."""
 | 
			
		||||
        resource = 'policy_rule'
 | 
			
		||||
        cmd = gbp.UpdatePolicyRule(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self._test_update_resource(resource, cmd, 'myid',
 | 
			
		||||
                                   ['myid', '--name', 'myname',
 | 
			
		||||
                                    '--tags', 'a', 'b'],
 | 
			
		||||
                                   {'name': 'myname', 'tags': ['a', 'b'], })
 | 
			
		||||
 | 
			
		||||
    def test_update_policy_rule_with_allparams(self):
 | 
			
		||||
        resource = 'policy_rule'
 | 
			
		||||
        enabled = True
 | 
			
		||||
        policy_classifier_id = 'pc-id'
 | 
			
		||||
        policy_actions_res = ["pa1", "pa2"]
 | 
			
		||||
        policy_actions_arg = "pa1 pa2"
 | 
			
		||||
        cmd = gbp.UpdatePolicyRule(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        body = {
 | 
			
		||||
            'policy_classifier_id': policy_classifier_id,
 | 
			
		||||
            'enabled': enabled,
 | 
			
		||||
            'policy_actions': policy_actions_res
 | 
			
		||||
        }
 | 
			
		||||
        args = ['myid', '--enabled', "True",
 | 
			
		||||
                '--classifier', policy_classifier_id,
 | 
			
		||||
                '--actions', policy_actions_arg, ]
 | 
			
		||||
        self._test_update_resource(resource, cmd, 'myid', args, body)
 | 
			
		||||
 | 
			
		||||
    def test_delete_policy_classifier(self):
 | 
			
		||||
        """grouppolicy-policy-rule-delete my-id."""
 | 
			
		||||
        resource = 'policy_rule'
 | 
			
		||||
        cmd = gbp.DeletePolicyRule(test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        my_id = 'my-id'
 | 
			
		||||
        args = [my_id]
 | 
			
		||||
        self._test_delete_resource(resource, cmd, my_id, args)
 | 
			
		||||
							
								
								
									
										0
									
								
								gbpclient/v2_0/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								gbpclient/v2_0/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										624
									
								
								gbpclient/v2_0/client.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										624
									
								
								gbpclient/v2_0/client.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,624 @@
 | 
			
		||||
#    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
 | 
			
		||||
import time
 | 
			
		||||
import urllib
 | 
			
		||||
 | 
			
		||||
from neutronclient import client
 | 
			
		||||
from neutronclient.common import _
 | 
			
		||||
from neutronclient.common import constants
 | 
			
		||||
from neutronclient.common import exceptions
 | 
			
		||||
from neutronclient.common import serializer
 | 
			
		||||
from neutronclient.common import utils
 | 
			
		||||
import requests
 | 
			
		||||
import six.moves.urllib.parse as urlparse
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_logger = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def exception_handler_v20(status_code, error_content):
 | 
			
		||||
    """Exception handler for API v2.0 client
 | 
			
		||||
 | 
			
		||||
        This routine generates the appropriate
 | 
			
		||||
        Neutron exception according to the contents of the
 | 
			
		||||
        response body
 | 
			
		||||
 | 
			
		||||
        :param status_code: HTTP error status code
 | 
			
		||||
        :param error_content: deserialized body of error response
 | 
			
		||||
    """
 | 
			
		||||
    error_dict = None
 | 
			
		||||
    if isinstance(error_content, dict):
 | 
			
		||||
        error_dict = error_content.get('NeutronError')
 | 
			
		||||
    # Find real error type
 | 
			
		||||
    bad_neutron_error_flag = False
 | 
			
		||||
    if error_dict:
 | 
			
		||||
        # If Neutron key is found, it will definitely contain
 | 
			
		||||
        # a 'message' and 'type' keys?
 | 
			
		||||
        try:
 | 
			
		||||
            error_type = error_dict['type']
 | 
			
		||||
            error_message = error_dict['message']
 | 
			
		||||
            if error_dict['detail']:
 | 
			
		||||
                error_message += "\n" + error_dict['detail']
 | 
			
		||||
        except Exception:
 | 
			
		||||
            bad_neutron_error_flag = True
 | 
			
		||||
        if not bad_neutron_error_flag:
 | 
			
		||||
            # If corresponding exception is defined, use it.
 | 
			
		||||
            client_exc = getattr(exceptions, '%sClient' % error_type, None)
 | 
			
		||||
            # Otherwise look up per status-code client exception
 | 
			
		||||
            if not client_exc:
 | 
			
		||||
                client_exc = exceptions.HTTP_EXCEPTION_MAP.get(status_code)
 | 
			
		||||
            if client_exc:
 | 
			
		||||
                raise client_exc(message=error_message,
 | 
			
		||||
                                 status_code=status_code)
 | 
			
		||||
            else:
 | 
			
		||||
                raise exceptions.NeutronClientException(
 | 
			
		||||
                    status_code=status_code, message=error_message)
 | 
			
		||||
        else:
 | 
			
		||||
            raise exceptions.NeutronClientException(status_code=status_code,
 | 
			
		||||
                                                    message=error_dict)
 | 
			
		||||
    else:
 | 
			
		||||
        message = None
 | 
			
		||||
        if isinstance(error_content, dict):
 | 
			
		||||
            message = error_content.get('message')
 | 
			
		||||
        if message:
 | 
			
		||||
            raise exceptions.NeutronClientException(status_code=status_code,
 | 
			
		||||
                                                    message=message)
 | 
			
		||||
 | 
			
		||||
    # If we end up here the exception was not a neutron error
 | 
			
		||||
    msg = "%s-%s" % (status_code, error_content)
 | 
			
		||||
    raise exceptions.NeutronClientException(status_code=status_code,
 | 
			
		||||
                                            message=msg)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class APIParamsCall(object):
 | 
			
		||||
    """A Decorator to add support for format and tenant overriding
 | 
			
		||||
       and filters
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, function):
 | 
			
		||||
        self.function = function
 | 
			
		||||
 | 
			
		||||
    def __get__(self, instance, owner):
 | 
			
		||||
        def with_params(*args, **kwargs):
 | 
			
		||||
            _format = instance.format
 | 
			
		||||
            if 'format' in kwargs:
 | 
			
		||||
                instance.format = kwargs['format']
 | 
			
		||||
            ret = self.function(instance, *args, **kwargs)
 | 
			
		||||
            instance.format = _format
 | 
			
		||||
            return ret
 | 
			
		||||
        return with_params
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Client(object):
 | 
			
		||||
    """Client for the GBP API.
 | 
			
		||||
 | 
			
		||||
    :param string username: Username for authentication. (optional)
 | 
			
		||||
    :param string user_id: User ID for authentication. (optional)
 | 
			
		||||
    :param string password: Password for authentication. (optional)
 | 
			
		||||
    :param string token: Token for authentication. (optional)
 | 
			
		||||
    :param string tenant_name: Tenant name. (optional)
 | 
			
		||||
    :param string tenant_id: Tenant id. (optional)
 | 
			
		||||
    :param string auth_url: Keystone service endpoint for authorization.
 | 
			
		||||
    :param string service_type: Network service type to pull from the
 | 
			
		||||
                                keystone catalog (e.g. 'network') (optional)
 | 
			
		||||
    :param string endpoint_type: Network service endpoint type to pull from the
 | 
			
		||||
                                 keystone catalog (e.g. 'publicURL',
 | 
			
		||||
                                 'internalURL', or 'adminURL') (optional)
 | 
			
		||||
    :param string region_name: Name of a region to select when choosing an
 | 
			
		||||
                               endpoint from the service catalog.
 | 
			
		||||
    :param string endpoint_url: A user-supplied endpoint URL for the neutron
 | 
			
		||||
                            service.  Lazy-authentication is possible for API
 | 
			
		||||
                            service calls if endpoint is set at
 | 
			
		||||
                            instantiation.(optional)
 | 
			
		||||
    :param integer timeout: Allows customization of the timeout for client
 | 
			
		||||
                            http requests. (optional)
 | 
			
		||||
    :param bool insecure: SSL certificate validation. (optional)
 | 
			
		||||
    :param string ca_cert: SSL CA bundle file to use. (optional)
 | 
			
		||||
    :param integer retries: How many times idempotent (GET, PUT, DELETE)
 | 
			
		||||
                            requests to Neutron server should be retried if
 | 
			
		||||
                            they fail (default: 0).
 | 
			
		||||
    :param bool raise_errors: If True then exceptions caused by connection
 | 
			
		||||
                              failure are propagated to the caller.
 | 
			
		||||
                              (default: True)
 | 
			
		||||
    :param session: Keystone client auth session to use. (optional)
 | 
			
		||||
    :param auth: Keystone auth plugin to use. (optional)
 | 
			
		||||
 | 
			
		||||
    Example::
 | 
			
		||||
 | 
			
		||||
        from gbpclient.v2_0 import client
 | 
			
		||||
        gbp = client.Client(username=USER,
 | 
			
		||||
                            password=PASS,
 | 
			
		||||
                            tenant_name=TENANT_NAME,
 | 
			
		||||
                            auth_url=KEYSTONE_URL)
 | 
			
		||||
 | 
			
		||||
        ptgs = gbp.list_policy_target_groups()
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    endpoints_path = "/grouppolicy/endpoints"
 | 
			
		||||
    endpoint_path = "/grouppolicy/endpoints/%s"
 | 
			
		||||
    endpoint_groups_path = "/grouppolicy/endpoint_groups"
 | 
			
		||||
    endpoint_group_path = "/grouppolicy/endpoint_groups/%s"
 | 
			
		||||
    l2_policies_path = "/grouppolicy/l2_policies"
 | 
			
		||||
    l2_policy_path = "/grouppolicy/l2_policies/%s"
 | 
			
		||||
    l3_policies_path = "/grouppolicy/l3_policies"
 | 
			
		||||
    l3_policy_path = "/grouppolicy/l3_policies/%s"
 | 
			
		||||
    network_service_policies_path = "/grouppolicy/network_service_policies"
 | 
			
		||||
    network_service_policy_path = "/grouppolicy/network_service_policies/%s"
 | 
			
		||||
    policy_classifiers_path = "/grouppolicy/policy_classifiers"
 | 
			
		||||
    policy_classifier_path = "/grouppolicy/policy_classifiers/%s"
 | 
			
		||||
    policy_actions_path = "/grouppolicy/policy_actions"
 | 
			
		||||
    policy_action_path = "/grouppolicy/policy_actions/%s"
 | 
			
		||||
    policy_rules_path = "/grouppolicy/policy_rules"
 | 
			
		||||
    policy_rule_path = "/grouppolicy/policy_rules/%s"
 | 
			
		||||
    contracts_path = "/grouppolicy/contracts"
 | 
			
		||||
    contract_path = "/grouppolicy/contracts/%s"
 | 
			
		||||
 | 
			
		||||
    # API has no way to report plurals, so we have to hard code them
 | 
			
		||||
    EXTED_PLURALS = {'endpoints': 'endpoint',
 | 
			
		||||
                     'endpoint_groups': 'endpoint_group',
 | 
			
		||||
                     'l2_policies': 'l2_policy',
 | 
			
		||||
                     'l3_policies': 'l3_policy',
 | 
			
		||||
                     'network_service_policies': 'network_service_policy',
 | 
			
		||||
                     'policy_classifiers': 'policy_classifier',
 | 
			
		||||
                     'policy_actions': 'policy_action',
 | 
			
		||||
                     'policy_rules': 'policy_rule',
 | 
			
		||||
                     'contracts': 'contract',
 | 
			
		||||
                     }
 | 
			
		||||
    # 8192 Is the default max URI len for eventlet.wsgi.server
 | 
			
		||||
    MAX_URI_LEN = 8192
 | 
			
		||||
 | 
			
		||||
    def get_attr_metadata(self):
 | 
			
		||||
        if self.format == 'json':
 | 
			
		||||
            return {}
 | 
			
		||||
        old_request_format = self.format
 | 
			
		||||
        self.format = 'json'
 | 
			
		||||
        exts = self.list_extensions()['extensions']
 | 
			
		||||
        self.format = old_request_format
 | 
			
		||||
        ns = dict([(ext['alias'], ext['namespace']) for ext in exts])
 | 
			
		||||
        self.EXTED_PLURALS.update(constants.PLURALS)
 | 
			
		||||
        return {'plurals': self.EXTED_PLURALS,
 | 
			
		||||
                'xmlns': constants.XML_NS_V20,
 | 
			
		||||
                constants.EXT_NS: ns}
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def list_extensions(self, **_params):
 | 
			
		||||
        """Fetch a list of all exts on server side."""
 | 
			
		||||
        return self.get(self.extensions_path, params=_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def show_extension(self, ext_alias, **_params):
 | 
			
		||||
        """Fetch a list of all exts on server side."""
 | 
			
		||||
        return self.get(self.extension_path % ext_alias, params=_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def list_endpoints(self, retrieve_all=True, **_params):
 | 
			
		||||
        """Fetches a list of all endpoints for a tenant."""
 | 
			
		||||
        # Pass filters in "params" argument to do_request
 | 
			
		||||
        return self.list('endpoints', self.endpoints_path, retrieve_all,
 | 
			
		||||
                         **_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def show_endpoint(self, endpoint, **_params):
 | 
			
		||||
        """Fetches information of a certain endpoint."""
 | 
			
		||||
        return self.get(self.endpoint_path % (endpoint), params=_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def create_endpoint(self, body=None):
 | 
			
		||||
        """Creates a new endpoint."""
 | 
			
		||||
        return self.post(self.endpoints_path, body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def update_endpoint(self, endpoint, body=None):
 | 
			
		||||
        """Updates a endpoint."""
 | 
			
		||||
        return self.put(self.endpoint_path % (endpoint), body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def delete_endpoint(self, endpoint):
 | 
			
		||||
        """Deletes the specified endpoint."""
 | 
			
		||||
        return self.delete(self.endpoint_path % (endpoint))
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def list_endpoint_groups(self, retrieve_all=True, **_params):
 | 
			
		||||
        """Fetches a list of all endpoint_groups for a tenant."""
 | 
			
		||||
        # Pass filters in "params" argument to do_request
 | 
			
		||||
        return self.list('endpoint_groups', self.endpoint_groups_path,
 | 
			
		||||
                         retrieve_all, **_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def show_endpoint_group(self, endpoint_group, **_params):
 | 
			
		||||
        """Fetches information of a certain endpoint_group."""
 | 
			
		||||
        return self.get(self.endpoint_group_path % (endpoint_group),
 | 
			
		||||
                        params=_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def create_endpoint_group(self, body=None):
 | 
			
		||||
        """Creates a new endpoint_group."""
 | 
			
		||||
        return self.post(self.endpoint_groups_path, body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def update_endpoint_group(self, endpoint_group, body=None):
 | 
			
		||||
        """Updates a endpoint_group."""
 | 
			
		||||
        return self.put(self.endpoint_group_path % (endpoint_group),
 | 
			
		||||
                        body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def delete_endpoint_group(self, endpoint_group):
 | 
			
		||||
        """Deletes the specified endpoint_group."""
 | 
			
		||||
        return self.delete(self.endpoint_group_path % (endpoint_group))
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def list_l2_policies(self, retrieve_all=True, **_params):
 | 
			
		||||
        """Fetches a list of all l2_policies for a tenant."""
 | 
			
		||||
        # Pass filters in "params" argument to do_request
 | 
			
		||||
        return self.list('l2_policies', self.l2_policies_path,
 | 
			
		||||
                         retrieve_all, **_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def show_l2_policy(self, l2_policy, **_params):
 | 
			
		||||
        """Fetches information of a certain l2_policy."""
 | 
			
		||||
        return self.get(self.l2_policy_path % (l2_policy),
 | 
			
		||||
                        params=_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def create_l2_policy(self, body=None):
 | 
			
		||||
        """Creates a new l2_policy."""
 | 
			
		||||
        return self.post(self.l2_policies_path, body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def update_l2_policy(self, l2_policy, body=None):
 | 
			
		||||
        """Updates a l2_policy."""
 | 
			
		||||
        return self.put(self.l2_policy_path % (l2_policy), body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def delete_l2_policy(self, l2_policy):
 | 
			
		||||
        """Deletes the specified l2_policy."""
 | 
			
		||||
        return self.delete(self.l2_policy_path % (l2_policy))
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def list_network_service_policies(self, retrieve_all=True, **_params):
 | 
			
		||||
        """Fetches a list of all network_service_policies for a tenant."""
 | 
			
		||||
        # Pass filters in "params" argument to do_request
 | 
			
		||||
        return self.list('network_service_policies',
 | 
			
		||||
                         self.network_service_policies_path,
 | 
			
		||||
                         retrieve_all, **_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def show_network_service_policy(self, network_service_policy, **_params):
 | 
			
		||||
        """Fetches information of a certain network_service_policy."""
 | 
			
		||||
        return self.get(
 | 
			
		||||
            self.network_service_policy_path % (network_service_policy),
 | 
			
		||||
            params=_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def create_network_service_policy(self, body=None):
 | 
			
		||||
        """Creates a new network_service_policy."""
 | 
			
		||||
        return self.post(self.network_service_policies_path, body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def update_network_service_policy(self, network_service_policy, body=None):
 | 
			
		||||
        """Updates a network_service_policy."""
 | 
			
		||||
        return self.put(
 | 
			
		||||
            self.network_service_policy_path % (network_service_policy),
 | 
			
		||||
            body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def delete_network_service_policy(self, network_service_policy):
 | 
			
		||||
        """Deletes the specified network_service_policy."""
 | 
			
		||||
        return self.delete(
 | 
			
		||||
            self.network_service_policy_path % (network_service_policy))
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def list_l3_policies(self, retrieve_all=True, **_params):
 | 
			
		||||
        """Fetches a list of all l3_policies for a tenant."""
 | 
			
		||||
        # Pass filters in "params" argument to do_request
 | 
			
		||||
        return self.list('l3_policies', self.l3_policies_path,
 | 
			
		||||
                         retrieve_all, **_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def show_l3_policy(self, l3_policy, **_params):
 | 
			
		||||
        """Fetches information of a certain l3_policy."""
 | 
			
		||||
        return self.get(self.l3_policy_path % (l3_policy),
 | 
			
		||||
                        params=_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def create_l3_policy(self, body=None):
 | 
			
		||||
        """Creates a new l3_policy."""
 | 
			
		||||
        return self.post(self.l3_policies_path, body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def update_l3_policy(self, l3_policy, body=None):
 | 
			
		||||
        """Updates a l3_policy."""
 | 
			
		||||
        return self.put(self.l3_policy_path % (l3_policy),
 | 
			
		||||
                        body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def delete_l3_policy(self, l3_policy):
 | 
			
		||||
        """Deletes the specified l3_policy."""
 | 
			
		||||
        return self.delete(self.l3_policy_path % (l3_policy))
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def list_policy_classifiers(self, retrieve_all=True, **_params):
 | 
			
		||||
        """Fetches a list of all policy_classifiers for a tenant."""
 | 
			
		||||
        # Pass filters in "params" argument to do_request
 | 
			
		||||
        return self.list('policy_classifiers', self.policy_classifiers_path,
 | 
			
		||||
                         retrieve_all, **_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def show_policy_classifier(self, policy_classifier, **_params):
 | 
			
		||||
        """Fetches information of a certain policy_classifier."""
 | 
			
		||||
        return self.get(self.policy_classifier_path % (policy_classifier),
 | 
			
		||||
                        params=_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def create_policy_classifier(self, body=None):
 | 
			
		||||
        """Creates a new policy_classifier."""
 | 
			
		||||
        return self.post(self.policy_classifiers_path, body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def update_policy_classifier(self, policy_classifier, body=None):
 | 
			
		||||
        """Updates a policy_classifier."""
 | 
			
		||||
        return self.put(self.policy_classifier_path % (policy_classifier),
 | 
			
		||||
                        body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def delete_policy_classifier(self, policy_classifier):
 | 
			
		||||
        """Deletes the specified policy_classifier."""
 | 
			
		||||
        return self.delete(self.policy_classifier_path % (policy_classifier))
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def list_policy_actions(self, retrieve_all=True, **_params):
 | 
			
		||||
        """Fetches a list of all policy_actions for a tenant."""
 | 
			
		||||
        # Pass filters in "params" argument to do_request
 | 
			
		||||
        return self.list('policy_actions', self.policy_actions_path,
 | 
			
		||||
                         retrieve_all, **_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def show_policy_action(self, policy_action, **_params):
 | 
			
		||||
        """Fetches information of a certain policy_action."""
 | 
			
		||||
        return self.get(self.policy_action_path % (policy_action),
 | 
			
		||||
                        params=_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def create_policy_action(self, body=None):
 | 
			
		||||
        """Creates a new policy_action."""
 | 
			
		||||
        return self.post(self.policy_actions_path, body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def update_policy_action(self, policy_action, body=None):
 | 
			
		||||
        """Updates a policy_action."""
 | 
			
		||||
        return self.put(self.policy_action_path % (policy_action), body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def delete_policy_action(self, policy_action):
 | 
			
		||||
        """Deletes the specified policy_action."""
 | 
			
		||||
        return self.delete(self.policy_action_path % (policy_action))
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def list_policy_rules(self, retrieve_all=True, **_params):
 | 
			
		||||
        """Fetches a list of all policy_rules for a tenant."""
 | 
			
		||||
        # Pass filters in "params" argument to do_request
 | 
			
		||||
        return self.list('policy_rules', self.policy_rules_path, retrieve_all,
 | 
			
		||||
                         **_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def show_policy_rule(self, policy_rule, **_params):
 | 
			
		||||
        """Fetches information of a certain policy_rule."""
 | 
			
		||||
        return self.get(self.policy_rule_path % (policy_rule), params=_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def create_policy_rule(self, body=None):
 | 
			
		||||
        """Creates a new policy_rule."""
 | 
			
		||||
        return self.post(self.policy_rules_path, body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def update_policy_rule(self, policy_rule, body=None):
 | 
			
		||||
        """Updates a policy_rule."""
 | 
			
		||||
        return self.put(self.policy_rule_path % (policy_rule), body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def delete_policy_rule(self, policy_rule):
 | 
			
		||||
        """Deletes the specified policy_rule."""
 | 
			
		||||
        return self.delete(self.policy_rule_path % (policy_rule))
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def list_contracts(self, retrieve_all=True, **_params):
 | 
			
		||||
        """Fetches a list of all contracts for a tenant."""
 | 
			
		||||
        # Pass filters in "params" argument to do_request
 | 
			
		||||
        return self.list('contracts', self.contracts_path, retrieve_all,
 | 
			
		||||
                         **_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def show_contract(self, contract, **_params):
 | 
			
		||||
        """Fetches information of a certain contract."""
 | 
			
		||||
        return self.get(self.contract_path % (contract), params=_params)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def create_contract(self, body=None):
 | 
			
		||||
        """Creates a new contract."""
 | 
			
		||||
        return self.post(self.contracts_path, body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def update_contract(self, contract, body=None):
 | 
			
		||||
        """Updates a contract."""
 | 
			
		||||
        return self.put(self.contract_path % (contract), body=body)
 | 
			
		||||
 | 
			
		||||
    @APIParamsCall
 | 
			
		||||
    def delete_contract(self, contract):
 | 
			
		||||
        """Deletes the specified contract."""
 | 
			
		||||
        return self.delete(self.contract_path % (contract))
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
        """Initialize a new client for the GBP v2.0 API."""
 | 
			
		||||
        super(Client, self).__init__()
 | 
			
		||||
        self.retries = kwargs.pop('retries', 0)
 | 
			
		||||
        self.raise_errors = kwargs.pop('raise_errors', True)
 | 
			
		||||
        self.httpclient = client.construct_http_client(**kwargs)
 | 
			
		||||
        self.version = '2.0'
 | 
			
		||||
        self.format = 'json'
 | 
			
		||||
        self.action_prefix = "/v%s" % (self.version)
 | 
			
		||||
        self.retry_interval = 1
 | 
			
		||||
 | 
			
		||||
    def _handle_fault_response(self, status_code, response_body):
 | 
			
		||||
        # Create exception with HTTP status code and message
 | 
			
		||||
        _logger.debug("Error message: %s", response_body)
 | 
			
		||||
        # Add deserialized error message to exception arguments
 | 
			
		||||
        try:
 | 
			
		||||
            des_error_body = self.deserialize(response_body, status_code)
 | 
			
		||||
        except Exception:
 | 
			
		||||
            # If unable to deserialized body it is probably not a
 | 
			
		||||
            # Neutron error
 | 
			
		||||
            des_error_body = {'message': response_body}
 | 
			
		||||
        # Raise the appropriate exception
 | 
			
		||||
        exception_handler_v20(status_code, des_error_body)
 | 
			
		||||
 | 
			
		||||
    def _check_uri_length(self, action):
 | 
			
		||||
        uri_len = len(self.httpclient.endpoint_url) + len(action)
 | 
			
		||||
        if uri_len > self.MAX_URI_LEN:
 | 
			
		||||
            raise exceptions.RequestURITooLong(
 | 
			
		||||
                excess=uri_len - self.MAX_URI_LEN)
 | 
			
		||||
 | 
			
		||||
    def do_request(self, method, action, body=None, headers=None, params=None):
 | 
			
		||||
        # Add format and tenant_id
 | 
			
		||||
        action += ".%s" % self.format
 | 
			
		||||
        action = self.action_prefix + action
 | 
			
		||||
        if type(params) is dict and params:
 | 
			
		||||
            params = utils.safe_encode_dict(params)
 | 
			
		||||
            action += '?' + urllib.urlencode(params, doseq=1)
 | 
			
		||||
        # Ensure client always has correct uri - do not guesstimate anything
 | 
			
		||||
        self.httpclient.authenticate_and_fetch_endpoint_url()
 | 
			
		||||
        self._check_uri_length(action)
 | 
			
		||||
 | 
			
		||||
        if body:
 | 
			
		||||
            body = self.serialize(body)
 | 
			
		||||
        self.httpclient.content_type = self.content_type()
 | 
			
		||||
        resp, replybody = self.httpclient.do_request(action, method, body=body)
 | 
			
		||||
        status_code = resp.status_code
 | 
			
		||||
        if status_code in (requests.codes.ok,
 | 
			
		||||
                           requests.codes.created,
 | 
			
		||||
                           requests.codes.accepted,
 | 
			
		||||
                           requests.codes.no_content):
 | 
			
		||||
            return self.deserialize(replybody, status_code)
 | 
			
		||||
        else:
 | 
			
		||||
            if not replybody:
 | 
			
		||||
                replybody = resp.reason
 | 
			
		||||
            self._handle_fault_response(status_code, replybody)
 | 
			
		||||
 | 
			
		||||
    def get_auth_info(self):
 | 
			
		||||
        return self.httpclient.get_auth_info()
 | 
			
		||||
 | 
			
		||||
    def serialize(self, data):
 | 
			
		||||
        """Serializes a dictionary into either XML or JSON.
 | 
			
		||||
 | 
			
		||||
        A dictionary with a single key can be passed and
 | 
			
		||||
        it can contain any structure.
 | 
			
		||||
        """
 | 
			
		||||
        if data is None:
 | 
			
		||||
            return None
 | 
			
		||||
        elif type(data) is dict:
 | 
			
		||||
            return serializer.Serializer(
 | 
			
		||||
                self.get_attr_metadata()).serialize(data, self.content_type())
 | 
			
		||||
        else:
 | 
			
		||||
            raise Exception(_("Unable to serialize object of type = '%s'") %
 | 
			
		||||
                            type(data))
 | 
			
		||||
 | 
			
		||||
    def deserialize(self, data, status_code):
 | 
			
		||||
        """Deserializes an XML or JSON string into a dictionary."""
 | 
			
		||||
        if status_code == 204:
 | 
			
		||||
            return data
 | 
			
		||||
        return serializer.Serializer(self.get_attr_metadata()).deserialize(
 | 
			
		||||
            data, self.content_type())['body']
 | 
			
		||||
 | 
			
		||||
    def content_type(self, _format=None):
 | 
			
		||||
        """Returns the mime-type for either 'xml' or 'json'.
 | 
			
		||||
 | 
			
		||||
        Defaults to the currently set format.
 | 
			
		||||
        """
 | 
			
		||||
        _format = _format or self.format
 | 
			
		||||
        return "application/%s" % (_format)
 | 
			
		||||
 | 
			
		||||
    def retry_request(self, method, action, body=None,
 | 
			
		||||
                      headers=None, params=None):
 | 
			
		||||
        """Call do_request with the default retry configuration.
 | 
			
		||||
 | 
			
		||||
        Only idempotent requests should retry failed connection attempts.
 | 
			
		||||
        :raises: ConnectionFailed if the maximum # of retries is exceeded
 | 
			
		||||
        """
 | 
			
		||||
        max_attempts = self.retries + 1
 | 
			
		||||
        for i in range(max_attempts):
 | 
			
		||||
            try:
 | 
			
		||||
                return self.do_request(method, action, body=body,
 | 
			
		||||
                                       headers=headers, params=params)
 | 
			
		||||
            except exceptions.ConnectionFailed:
 | 
			
		||||
                # Exception has already been logged by do_request()
 | 
			
		||||
                if i < self.retries:
 | 
			
		||||
                    _logger.debug('Retrying connection to Neutron service')
 | 
			
		||||
                    time.sleep(self.retry_interval)
 | 
			
		||||
                elif self.raise_errors:
 | 
			
		||||
                    raise
 | 
			
		||||
 | 
			
		||||
        if self.retries:
 | 
			
		||||
            msg = (_("Failed to connect to Neutron server after %d attempts")
 | 
			
		||||
                   % max_attempts)
 | 
			
		||||
        else:
 | 
			
		||||
            msg = _("Failed to connect Neutron server")
 | 
			
		||||
 | 
			
		||||
        raise exceptions.ConnectionFailed(reason=msg)
 | 
			
		||||
 | 
			
		||||
    def delete(self, action, body=None, headers=None, params=None):
 | 
			
		||||
        return self.retry_request("DELETE", action, body=body,
 | 
			
		||||
                                  headers=headers, params=params)
 | 
			
		||||
 | 
			
		||||
    def get(self, action, body=None, headers=None, params=None):
 | 
			
		||||
        return self.retry_request("GET", action, body=body,
 | 
			
		||||
                                  headers=headers, params=params)
 | 
			
		||||
 | 
			
		||||
    def post(self, action, body=None, headers=None, params=None):
 | 
			
		||||
        # Do not retry POST requests to avoid the orphan objects problem.
 | 
			
		||||
        return self.do_request("POST", action, body=body,
 | 
			
		||||
                               headers=headers, params=params)
 | 
			
		||||
 | 
			
		||||
    def put(self, action, body=None, headers=None, params=None):
 | 
			
		||||
        return self.retry_request("PUT", action, body=body,
 | 
			
		||||
                                  headers=headers, params=params)
 | 
			
		||||
 | 
			
		||||
    def list(self, collection, path, retrieve_all=True, **params):
 | 
			
		||||
        if retrieve_all:
 | 
			
		||||
            res = []
 | 
			
		||||
            for r in self._pagination(collection, path, **params):
 | 
			
		||||
                res.extend(r[collection])
 | 
			
		||||
            return {collection: res}
 | 
			
		||||
        else:
 | 
			
		||||
            return self._pagination(collection, path, **params)
 | 
			
		||||
 | 
			
		||||
    def _pagination(self, collection, path, **params):
 | 
			
		||||
        if params.get('page_reverse', False):
 | 
			
		||||
            linkrel = 'previous'
 | 
			
		||||
        else:
 | 
			
		||||
            linkrel = 'next'
 | 
			
		||||
        next = True
 | 
			
		||||
        while next:
 | 
			
		||||
            res = self.get(path, params=params)
 | 
			
		||||
            yield res
 | 
			
		||||
            next = False
 | 
			
		||||
            try:
 | 
			
		||||
                for link in res['%s_links' % collection]:
 | 
			
		||||
                    if link['rel'] == linkrel:
 | 
			
		||||
                        query_str = urlparse.urlparse(link['href']).query
 | 
			
		||||
                        params = urlparse.parse_qs(query_str)
 | 
			
		||||
                        next = True
 | 
			
		||||
                        break
 | 
			
		||||
            except KeyError:
 | 
			
		||||
                break
 | 
			
		||||
							
								
								
									
										227
									
								
								run_tests.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										227
									
								
								run_tests.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,227 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
set -eu
 | 
			
		||||
 | 
			
		||||
function usage {
 | 
			
		||||
  echo "Usage: $0 [OPTION]..."
 | 
			
		||||
  echo "Run Group Based Policy's test suite(s)"
 | 
			
		||||
  echo ""
 | 
			
		||||
  echo "  -V, --virtual-env           Always use virtualenv.  Install automatically if not present"
 | 
			
		||||
  echo "  -N, --no-virtual-env        Don't use virtualenv.  Run tests in local environment"
 | 
			
		||||
  echo "  -s, --no-site-packages      Isolate the virtualenv from the global Python environment"
 | 
			
		||||
  echo "  -r, --recreate-db           Recreate the test database (deprecated, as this is now the default)."
 | 
			
		||||
  echo "  -n, --no-recreate-db        Don't recreate the test database."
 | 
			
		||||
  echo "  -f, --force                 Force a clean re-build of the virtual environment. Useful when dependencies have been added."
 | 
			
		||||
  echo "  -u, --update                Update the virtual environment with any newer package versions"
 | 
			
		||||
  echo "  -p, --pep8                  Just run PEP8 and HACKING compliance check"
 | 
			
		||||
  echo "  -P, --no-pep8               Don't run static code checks"
 | 
			
		||||
  echo "  -c, --coverage              Generate coverage report"
 | 
			
		||||
  echo "  -d, --debug                 Run tests with testtools instead of testr. This allows you to use the debugger."
 | 
			
		||||
  echo "  -h, --help                  Print this usage message"
 | 
			
		||||
  echo "  --virtual-env-path <path>   Location of the virtualenv directory"
 | 
			
		||||
  echo "                               Default: \$(pwd)"
 | 
			
		||||
  echo "  --virtual-env-name <name>   Name of the virtualenv directory"
 | 
			
		||||
  echo "                               Default: .venv"
 | 
			
		||||
  echo "  --tools-path <dir>          Location of the tools directory"
 | 
			
		||||
  echo "                               Default: \$(pwd)"
 | 
			
		||||
  echo ""
 | 
			
		||||
  echo "Note: with no options specified, the script will try to run the tests in a virtual environment,"
 | 
			
		||||
  echo "      If no virtualenv is found, the script will ask if you would like to create one.  If you "
 | 
			
		||||
  echo "      prefer to run tests NOT in a virtual environment, simply pass the -N option."
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function process_options {
 | 
			
		||||
  i=1
 | 
			
		||||
  while [ $i -le $# ]; do
 | 
			
		||||
    case "${!i}" in
 | 
			
		||||
      -h|--help) usage;;
 | 
			
		||||
      -V|--virtual-env) always_venv=1; never_venv=0;;
 | 
			
		||||
      -N|--no-virtual-env) always_venv=0; never_venv=1;;
 | 
			
		||||
      -s|--no-site-packages) no_site_packages=1;;
 | 
			
		||||
      -r|--recreate-db) recreate_db=1;;
 | 
			
		||||
      -n|--no-recreate-db) recreate_db=0;;
 | 
			
		||||
      -f|--force) force=1;;
 | 
			
		||||
      -u|--update) update=1;;
 | 
			
		||||
      -p|--pep8) just_pep8=1;;
 | 
			
		||||
      -P|--no-pep8) no_pep8=1;;
 | 
			
		||||
      -c|--coverage) coverage=1;;
 | 
			
		||||
      -d|--debug) debug=1;;
 | 
			
		||||
      --virtual-env-path)
 | 
			
		||||
        (( i++ ))
 | 
			
		||||
        venv_path=${!i}
 | 
			
		||||
        ;;
 | 
			
		||||
      --virtual-env-name)
 | 
			
		||||
        (( i++ ))
 | 
			
		||||
        venv_dir=${!i}
 | 
			
		||||
        ;;
 | 
			
		||||
      --tools-path)
 | 
			
		||||
        (( i++ ))
 | 
			
		||||
        tools_path=${!i}
 | 
			
		||||
        ;;
 | 
			
		||||
      -*) testropts="$testropts ${!i}";;
 | 
			
		||||
      *) testrargs="$testrargs ${!i}"
 | 
			
		||||
    esac
 | 
			
		||||
    (( i++ ))
 | 
			
		||||
  done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tool_path=${tools_path:-$(pwd)}
 | 
			
		||||
venv_path=${venv_path:-$(pwd)}
 | 
			
		||||
venv_dir=${venv_name:-.venv}
 | 
			
		||||
with_venv=tools/with_venv.sh
 | 
			
		||||
always_venv=0
 | 
			
		||||
never_venv=0
 | 
			
		||||
force=0
 | 
			
		||||
no_site_packages=0
 | 
			
		||||
installvenvopts=
 | 
			
		||||
testrargs=
 | 
			
		||||
testropts=
 | 
			
		||||
wrapper=""
 | 
			
		||||
just_pep8=0
 | 
			
		||||
no_pep8=0
 | 
			
		||||
coverage=0
 | 
			
		||||
debug=0
 | 
			
		||||
recreate_db=1
 | 
			
		||||
update=0
 | 
			
		||||
 | 
			
		||||
LANG=en_US.UTF-8
 | 
			
		||||
LANGUAGE=en_US:en
 | 
			
		||||
LC_ALL=C
 | 
			
		||||
 | 
			
		||||
process_options $@
 | 
			
		||||
# Make our paths available to other scripts we call
 | 
			
		||||
export venv_path
 | 
			
		||||
export venv_dir
 | 
			
		||||
export venv_name
 | 
			
		||||
export tools_dir
 | 
			
		||||
export venv=${venv_path}/${venv_dir}
 | 
			
		||||
 | 
			
		||||
if [ $no_site_packages -eq 1 ]; then
 | 
			
		||||
  installvenvopts="--no-site-packages"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function run_tests {
 | 
			
		||||
  # Cleanup *pyc
 | 
			
		||||
  ${wrapper} find . -type f -name "*.pyc" -delete
 | 
			
		||||
 | 
			
		||||
  if [ $debug -eq 1 ]; then
 | 
			
		||||
    if [ "$testropts" = "" ] && [ "$testrargs" = "" ]; then
 | 
			
		||||
      # Default to running all tests if specific test is not
 | 
			
		||||
      # provided.
 | 
			
		||||
      testrargs="discover ./gbp/"
 | 
			
		||||
    fi
 | 
			
		||||
    ${wrapper} python -m testtools.run $testropts $testrargs
 | 
			
		||||
 | 
			
		||||
    # Short circuit because all of the testr and coverage stuff
 | 
			
		||||
    # below does not make sense when running testtools.run for
 | 
			
		||||
    # debugging purposes.
 | 
			
		||||
    return $?
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ $coverage -eq 1 ]; then
 | 
			
		||||
    TESTRTESTS="$TESTRTESTS --coverage"
 | 
			
		||||
  else
 | 
			
		||||
    TESTRTESTS="$TESTRTESTS --slowest"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Just run the test suites in current environment
 | 
			
		||||
  set +e
 | 
			
		||||
  testrargs=`echo "$testrargs" | sed -e's/^\s*\(.*\)\s*$/\1/'`
 | 
			
		||||
  TESTRTESTS="$TESTRTESTS --testr-args='--subunit $testropts $testrargs'"
 | 
			
		||||
  OS_TEST_PATH=`echo $testrargs|grep -o 'gbp\.tests[^[:space:]:]*\+'|tr . /`
 | 
			
		||||
  if [ -d "$OS_TEST_PATH" ]; then
 | 
			
		||||
      wrapper="OS_TEST_PATH=$OS_TEST_PATH $wrapper"
 | 
			
		||||
  elif [ -d "$(dirname $OS_TEST_PATH)" ]; then
 | 
			
		||||
      wrapper="OS_TEST_PATH=$(dirname $OS_TEST_PATH) $wrapper"
 | 
			
		||||
  fi
 | 
			
		||||
  echo "Running \`${wrapper} $TESTRTESTS\`"
 | 
			
		||||
  bash -c "${wrapper} $TESTRTESTS | ${wrapper} subunit2pyunit"
 | 
			
		||||
  RESULT=$?
 | 
			
		||||
  set -e
 | 
			
		||||
 | 
			
		||||
  copy_subunit_log
 | 
			
		||||
 | 
			
		||||
  if [ $coverage -eq 1 ]; then
 | 
			
		||||
    echo "Generating coverage report in covhtml/"
 | 
			
		||||
    # Don't compute coverage for common code, which is tested elsewhere
 | 
			
		||||
    ${wrapper} coverage combine
 | 
			
		||||
    ${wrapper} coverage html --include='gbp/*' --omit='gbp/openstack/common/*' -d covhtml -i
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  return $RESULT
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function copy_subunit_log {
 | 
			
		||||
  LOGNAME=`cat .testrepository/next-stream`
 | 
			
		||||
  LOGNAME=$(($LOGNAME - 1))
 | 
			
		||||
  LOGNAME=".testrepository/${LOGNAME}"
 | 
			
		||||
  cp $LOGNAME subunit.log
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function run_pep8 {
 | 
			
		||||
  echo "Running flake8 ..."
 | 
			
		||||
 | 
			
		||||
  ${wrapper} flake8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TESTRTESTS="python setup.py testr"
 | 
			
		||||
 | 
			
		||||
if [ $never_venv -eq 0 ]
 | 
			
		||||
then
 | 
			
		||||
  # Remove the virtual environment if --force used
 | 
			
		||||
  if [ $force -eq 1 ]; then
 | 
			
		||||
    echo "Cleaning virtualenv..."
 | 
			
		||||
    rm -rf ${venv}
 | 
			
		||||
  fi
 | 
			
		||||
  if [ $update -eq 1 ]; then
 | 
			
		||||
      echo "Updating virtualenv..."
 | 
			
		||||
      python tools/install_venv.py $installvenvopts
 | 
			
		||||
  fi
 | 
			
		||||
  if [ -e ${venv} ]; then
 | 
			
		||||
    wrapper="${with_venv}"
 | 
			
		||||
  else
 | 
			
		||||
    if [ $always_venv -eq 1 ]; then
 | 
			
		||||
      # Automatically install the virtualenv
 | 
			
		||||
      python tools/install_venv.py $installvenvopts
 | 
			
		||||
      wrapper="${with_venv}"
 | 
			
		||||
    else
 | 
			
		||||
      echo -e "No virtual environment found...create one? (Y/n) \c"
 | 
			
		||||
      read use_ve
 | 
			
		||||
      if [ "x$use_ve" = "xY" -o "x$use_ve" = "x" -o "x$use_ve" = "xy" ]; then
 | 
			
		||||
        # Install the virtualenv and run the test suite in it
 | 
			
		||||
        python tools/install_venv.py $installvenvopts
 | 
			
		||||
        wrapper=${with_venv}
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Delete old coverage data from previous runs
 | 
			
		||||
if [ $coverage -eq 1 ]; then
 | 
			
		||||
    ${wrapper} coverage erase
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [ $just_pep8 -eq 1 ]; then
 | 
			
		||||
    run_pep8
 | 
			
		||||
    exit
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [ $recreate_db -eq 1 ]; then
 | 
			
		||||
    rm -f tests.sqlite
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
run_tests
 | 
			
		||||
 | 
			
		||||
# NOTE(sirp): we only want to run pep8 when we're running the full-test suite,
 | 
			
		||||
# not when we're running tests individually. To handle this, we need to
 | 
			
		||||
# distinguish between options (testropts), which begin with a '-', and
 | 
			
		||||
# arguments (testrargs).
 | 
			
		||||
if [ -z "$testrargs" ]; then
 | 
			
		||||
  if [ $no_pep8 -eq 0 ]; then
 | 
			
		||||
    run_pep8
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
@@ -28,7 +28,7 @@ setup-hooks =
 | 
			
		||||
 | 
			
		||||
[entry_points]
 | 
			
		||||
console_scripts =
 | 
			
		||||
    gbp = gbpclient.shell:main
 | 
			
		||||
    gbp = gbpclient.gbpshell:main
 | 
			
		||||
 | 
			
		||||
[build_sphinx]
 | 
			
		||||
all_files = 1
 | 
			
		||||
 
 | 
			
		||||
@@ -15,4 +15,5 @@ oslotest>=1.1.0.0a2
 | 
			
		||||
python-subunit>=0.0.18
 | 
			
		||||
sphinx>=1.1.2,!=1.2.0,<1.3
 | 
			
		||||
testrepository>=0.0.18
 | 
			
		||||
testscenarios>=0.4
 | 
			
		||||
testtools>=0.9.34
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										74
									
								
								tools/install_venv.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								tools/install_venv.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
# Copyright 2010 United States Government as represented by the
 | 
			
		||||
# Administrator of the National Aeronautics and Space Administration.
 | 
			
		||||
# All Rights Reserved.
 | 
			
		||||
#
 | 
			
		||||
# Copyright 2010 OpenStack Foundation
 | 
			
		||||
# Copyright 2013 IBM Corp.
 | 
			
		||||
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
 | 
			
		||||
#
 | 
			
		||||
# 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 ConfigParser
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
import install_venv_common as install_venv  # flake8: noqa
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def print_help(project, venv, root):
 | 
			
		||||
    help = """
 | 
			
		||||
    %(project)s development environment setup is complete.
 | 
			
		||||
 | 
			
		||||
    %(project)s development uses virtualenv to track and manage Python
 | 
			
		||||
    dependencies while in development and testing.
 | 
			
		||||
 | 
			
		||||
    To activate the %(project)s virtualenv for the extent of your current
 | 
			
		||||
    shell session you can run:
 | 
			
		||||
 | 
			
		||||
    $ source %(venv)s/bin/activate
 | 
			
		||||
 | 
			
		||||
    Or, if you prefer, you can run commands in the virtualenv on a case by
 | 
			
		||||
    case basis by running:
 | 
			
		||||
 | 
			
		||||
    $ %(root)s/tools/with_venv.sh <your command>
 | 
			
		||||
    """
 | 
			
		||||
    print help % dict(project=project, venv=venv, root=root)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main(argv):
 | 
			
		||||
    root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
 | 
			
		||||
 | 
			
		||||
    if os.environ.get('tools_path'):
 | 
			
		||||
        root = os.environ['tools_path']
 | 
			
		||||
    venv = os.path.join(root, '.venv')
 | 
			
		||||
    if os.environ.get('venv'):
 | 
			
		||||
        venv = os.environ['venv']
 | 
			
		||||
 | 
			
		||||
    pip_requires = os.path.join(root, 'requirements.txt')
 | 
			
		||||
    test_requires = os.path.join(root, 'test-requirements.txt')
 | 
			
		||||
    py_version = "python%s.%s" % (sys.version_info[0], sys.version_info[1])
 | 
			
		||||
    setup_cfg = ConfigParser.ConfigParser()
 | 
			
		||||
    setup_cfg.read('setup.cfg')
 | 
			
		||||
    project = setup_cfg.get('metadata', 'name')
 | 
			
		||||
 | 
			
		||||
    install = install_venv.InstallVenv(
 | 
			
		||||
        root, venv, pip_requires, test_requires, py_version, project)
 | 
			
		||||
    options = install.parse_args(argv)
 | 
			
		||||
    install.check_python_version()
 | 
			
		||||
    install.check_dependencies()
 | 
			
		||||
    install.create_virtualenv(no_site_packages=options.no_site_packages)
 | 
			
		||||
    install.install_dependencies()
 | 
			
		||||
    print_help(project, venv, root)
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    main(sys.argv)
 | 
			
		||||
							
								
								
									
										172
									
								
								tools/install_venv_common.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								tools/install_venv_common.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,172 @@
 | 
			
		||||
# Copyright 2013 OpenStack Foundation
 | 
			
		||||
# Copyright 2013 IBM Corp.
 | 
			
		||||
#
 | 
			
		||||
#    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.
 | 
			
		||||
 | 
			
		||||
"""Provides methods needed by installation script for OpenStack development
 | 
			
		||||
virtual environments.
 | 
			
		||||
 | 
			
		||||
Since this script is used to bootstrap a virtualenv from the system's Python
 | 
			
		||||
environment, it should be kept strictly compatible with Python 2.6.
 | 
			
		||||
 | 
			
		||||
Synced in from openstack-common
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from __future__ import print_function
 | 
			
		||||
 | 
			
		||||
import optparse
 | 
			
		||||
import os
 | 
			
		||||
import subprocess
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class InstallVenv(object):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, root, venv, requirements,
 | 
			
		||||
                 test_requirements, py_version,
 | 
			
		||||
                 project):
 | 
			
		||||
        self.root = root
 | 
			
		||||
        self.venv = venv
 | 
			
		||||
        self.requirements = requirements
 | 
			
		||||
        self.test_requirements = test_requirements
 | 
			
		||||
        self.py_version = py_version
 | 
			
		||||
        self.project = project
 | 
			
		||||
 | 
			
		||||
    def die(self, message, *args):
 | 
			
		||||
        print(message % args, file=sys.stderr)
 | 
			
		||||
        sys.exit(1)
 | 
			
		||||
 | 
			
		||||
    def check_python_version(self):
 | 
			
		||||
        if sys.version_info < (2, 6):
 | 
			
		||||
            self.die("Need Python Version >= 2.6")
 | 
			
		||||
 | 
			
		||||
    def run_command_with_code(self, cmd, redirect_output=True,
 | 
			
		||||
                              check_exit_code=True):
 | 
			
		||||
        """Runs a command in an out-of-process shell.
 | 
			
		||||
 | 
			
		||||
        Returns the output of that command. Working directory is self.root.
 | 
			
		||||
        """
 | 
			
		||||
        if redirect_output:
 | 
			
		||||
            stdout = subprocess.PIPE
 | 
			
		||||
        else:
 | 
			
		||||
            stdout = None
 | 
			
		||||
 | 
			
		||||
        proc = subprocess.Popen(cmd, cwd=self.root, stdout=stdout)
 | 
			
		||||
        output = proc.communicate()[0]
 | 
			
		||||
        if check_exit_code and proc.returncode != 0:
 | 
			
		||||
            self.die('Command "%s" failed.\n%s', ' '.join(cmd), output)
 | 
			
		||||
        return (output, proc.returncode)
 | 
			
		||||
 | 
			
		||||
    def run_command(self, cmd, redirect_output=True, check_exit_code=True):
 | 
			
		||||
        return self.run_command_with_code(cmd, redirect_output,
 | 
			
		||||
                                          check_exit_code)[0]
 | 
			
		||||
 | 
			
		||||
    def get_distro(self):
 | 
			
		||||
        if (os.path.exists('/etc/fedora-release') or
 | 
			
		||||
                os.path.exists('/etc/redhat-release')):
 | 
			
		||||
            return Fedora(
 | 
			
		||||
                self.root, self.venv, self.requirements,
 | 
			
		||||
                self.test_requirements, self.py_version, self.project)
 | 
			
		||||
        else:
 | 
			
		||||
            return Distro(
 | 
			
		||||
                self.root, self.venv, self.requirements,
 | 
			
		||||
                self.test_requirements, self.py_version, self.project)
 | 
			
		||||
 | 
			
		||||
    def check_dependencies(self):
 | 
			
		||||
        self.get_distro().install_virtualenv()
 | 
			
		||||
 | 
			
		||||
    def create_virtualenv(self, no_site_packages=True):
 | 
			
		||||
        """Creates the virtual environment and installs PIP.
 | 
			
		||||
 | 
			
		||||
        Creates the virtual environment and installs PIP only into the
 | 
			
		||||
        virtual environment.
 | 
			
		||||
        """
 | 
			
		||||
        if not os.path.isdir(self.venv):
 | 
			
		||||
            print('Creating venv...', end=' ')
 | 
			
		||||
            if no_site_packages:
 | 
			
		||||
                self.run_command(['virtualenv', '-q', '--no-site-packages',
 | 
			
		||||
                                 self.venv])
 | 
			
		||||
            else:
 | 
			
		||||
                self.run_command(['virtualenv', '-q', self.venv])
 | 
			
		||||
            print('done.')
 | 
			
		||||
        else:
 | 
			
		||||
            print("venv already exists...")
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
    def pip_install(self, *args):
 | 
			
		||||
        self.run_command(['tools/with_venv.sh',
 | 
			
		||||
                         'pip', 'install', '--upgrade'] + list(args),
 | 
			
		||||
                         redirect_output=False)
 | 
			
		||||
 | 
			
		||||
    def install_dependencies(self):
 | 
			
		||||
        print('Installing dependencies with pip (this can take a while)...')
 | 
			
		||||
 | 
			
		||||
        # First things first, make sure our venv has the latest pip and
 | 
			
		||||
        # setuptools and pbr
 | 
			
		||||
        self.pip_install('pip>=1.4')
 | 
			
		||||
        self.pip_install('setuptools')
 | 
			
		||||
        self.pip_install('pbr')
 | 
			
		||||
 | 
			
		||||
        self.pip_install('-r', self.requirements, '-r', self.test_requirements)
 | 
			
		||||
 | 
			
		||||
    def parse_args(self, argv):
 | 
			
		||||
        """Parses command-line arguments."""
 | 
			
		||||
        parser = optparse.OptionParser()
 | 
			
		||||
        parser.add_option('-n', '--no-site-packages',
 | 
			
		||||
                          action='store_true',
 | 
			
		||||
                          help="Do not inherit packages from global Python "
 | 
			
		||||
                               "install.")
 | 
			
		||||
        return parser.parse_args(argv[1:])[0]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Distro(InstallVenv):
 | 
			
		||||
 | 
			
		||||
    def check_cmd(self, cmd):
 | 
			
		||||
        return bool(self.run_command(['which', cmd],
 | 
			
		||||
                    check_exit_code=False).strip())
 | 
			
		||||
 | 
			
		||||
    def install_virtualenv(self):
 | 
			
		||||
        if self.check_cmd('virtualenv'):
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        if self.check_cmd('easy_install'):
 | 
			
		||||
            print('Installing virtualenv via easy_install...', end=' ')
 | 
			
		||||
            if self.run_command(['easy_install', 'virtualenv']):
 | 
			
		||||
                print('Succeeded')
 | 
			
		||||
                return
 | 
			
		||||
            else:
 | 
			
		||||
                print('Failed')
 | 
			
		||||
 | 
			
		||||
        self.die('ERROR: virtualenv not found.\n\n%s development'
 | 
			
		||||
                 ' requires virtualenv, please install it using your'
 | 
			
		||||
                 ' favorite package management tool' % self.project)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Fedora(Distro):
 | 
			
		||||
    """This covers all Fedora-based distributions.
 | 
			
		||||
 | 
			
		||||
    Includes: Fedora, RHEL, CentOS, Scientific Linux
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def check_pkg(self, pkg):
 | 
			
		||||
        return self.run_command_with_code(['rpm', '-q', pkg],
 | 
			
		||||
                                          check_exit_code=False)[1] == 0
 | 
			
		||||
 | 
			
		||||
    def install_virtualenv(self):
 | 
			
		||||
        if self.check_cmd('virtualenv'):
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        if not self.check_pkg('python-virtualenv'):
 | 
			
		||||
            self.die("Please install 'python-virtualenv'.")
 | 
			
		||||
 | 
			
		||||
        super(Fedora, self).install_virtualenv()
 | 
			
		||||
@@ -1,27 +0,0 @@
 | 
			
		||||
_policy_opts="" # lazy init
 | 
			
		||||
_policy_flags="" # lazy init
 | 
			
		||||
_policy_opts_exp="" # lazy init
 | 
			
		||||
_policy()
 | 
			
		||||
{
 | 
			
		||||
	local cur prev nbc cflags
 | 
			
		||||
	COMPREPLY=()
 | 
			
		||||
	cur="${COMP_WORDS[COMP_CWORD]}"
 | 
			
		||||
	prev="${COMP_WORDS[COMP_CWORD-1]}"
 | 
			
		||||
 | 
			
		||||
	if [ "x$_policy_opts" == "x" ] ; then
 | 
			
		||||
		nbc="`policy bash-completion`"
 | 
			
		||||
		_policy_opts="`echo "$nbc" | sed -e "s/--[a-z0-9_-]*//g" -e "s/\s\s*/ /g"`"
 | 
			
		||||
		_policy_flags="`echo " $nbc" | sed -e "s/ [^-][^-][a-z0-9_-]*//g" -e "s/\s\s*/ /g"`"
 | 
			
		||||
		_policy_opts_exp="`echo "$_policy_opts" | sed -e "s/\s/|/g"`"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if [[ " ${COMP_WORDS[@]} " =~ " "($_policy_opts_exp)" " && "$prev" != "help" ]] ; then
 | 
			
		||||
		COMPLETION_CACHE=~/.policyclient/*/*-cache
 | 
			
		||||
		cflags="$_policy_flags "$(cat $COMPLETION_CACHE 2> /dev/null | tr '\n' ' ')
 | 
			
		||||
		COMPREPLY=($(compgen -W "${cflags}" -- ${cur}))
 | 
			
		||||
	else
 | 
			
		||||
		COMPREPLY=($(compgen -W "${_policy_opts}" -- ${cur}))
 | 
			
		||||
	fi
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
complete -F _policy policy
 | 
			
		||||
							
								
								
									
										4
									
								
								tools/with_venv.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								tools/with_venv.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
TOOLS=`dirname $0`
 | 
			
		||||
VENV=$TOOLS/../.venv
 | 
			
		||||
source $VENV/bin/activate && $@
 | 
			
		||||
		Reference in New Issue
	
	Block a user