python-neutronclient-6.7.0/0000775000175100017510000000000013232473710015762 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/.coveragerc0000666000175100017510000000014713232473350020107 0ustar zuulzuul00000000000000[run] branch = True source = neutronclient omit = neutronclient/tests/* [report] ignore_errors = True python-neutronclient-6.7.0/HACKING.rst0000666000175100017510000000227013232473350017563 0ustar zuulzuul00000000000000Neutron Style Commandments ================================ - Step 1: Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/ - 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 python-neutronclient-6.7.0/PKG-INFO0000664000175100017510000000530613232473710017063 0ustar zuulzuul00000000000000Metadata-Version: 1.1 Name: python-neutronclient Version: 6.7.0 Summary: CLI and Client Library for OpenStack Networking Home-page: https://docs.openstack.org/python-neutronclient/latest/ Author: OpenStack Networking Project Author-email: openstack-dev@lists.openstack.org License: UNKNOWN Description-Content-Type: UNKNOWN Description: ======================== Team and repository tags ======================== .. image:: http://governance.openstack.org/badges/python-neutronclient.svg :target: http://governance.openstack.org/reference/tags/index.html .. Change things from this point on Python bindings to the Neutron API ================================== .. image:: https://img.shields.io/pypi/v/python-neutronclient.svg :target: https://pypi.python.org/pypi/python-neutronclient/ :alt: Latest Version .. image:: https://img.shields.io/pypi/dm/python-neutronclient.svg :target: https://pypi.python.org/pypi/python-neutronclient/ :alt: Downloads This is a client library for Neutron built on the Neutron API. It provides a Python API (the ``neutronclient`` module) and a command-line tool (``neutron``). * License: Apache License, Version 2.0 * `PyPi`_ - package installation * `Online Documentation`_ * `Launchpad project`_ - release management * `Blueprints`_ - feature specifications * `Bugs`_ - issue tracking * `Source`_ * `Developer's Guide`_ .. _PyPi: https://pypi.python.org/pypi/python-neutronclient .. _Online Documentation: https://docs.openstack.org/python-neutronclient/latest/ .. _Launchpad project: https://launchpad.net/python-neutronclient .. _Blueprints: https://blueprints.launchpad.net/python-neutronclient .. _Bugs: https://bugs.launchpad.net/python-neutronclient .. _Source: https://git.openstack.org/cgit/openstack/python-neutronclient .. _Developer's Guide: http://docs.openstack.org/infra/manual/developers.html Platform: UNKNOWN Classifier: Environment :: OpenStack Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.5 python-neutronclient-6.7.0/neutronclient/0000775000175100017510000000000013232473710020653 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/version.py0000666000175100017510000000142613232473350022717 0ustar zuulzuul00000000000000# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import pbr.version version_info = pbr.version.VersionInfo('python-neutronclient') __version__ = version_info.version_string() python-neutronclient-6.7.0/neutronclient/v2_0/0000775000175100017510000000000013232473710021421 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/v2_0/client.py0000666000175100017510000032344513232473407023271 0ustar zuulzuul00000000000000# Copyright 2012 OpenStack Foundation. # Copyright 2015 Hewlett-Packard Development Company, L.P. # Copyright 2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import inspect import itertools import logging import re import time import debtcollector.renames from keystoneauth1 import exceptions as ksa_exc import requests import six.moves.urllib.parse as urlparse from six import string_types from neutronclient._i18n import _ from neutronclient import client from neutronclient.common import exceptions from neutronclient.common import extension as client_extension from neutronclient.common import serializer from neutronclient.common import utils _logger = logging.getLogger(__name__) HEX_ELEM = '[0-9A-Fa-f]' UUID_PATTERN = '-'.join([HEX_ELEM + '{8}', HEX_ELEM + '{4}', HEX_ELEM + '{4}', HEX_ELEM + '{4}', HEX_ELEM + '{12}']) 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 request_ids = error_content.request_ids if isinstance(error_content, dict): error_dict = error_content.get('NeutronError') # Find real error type client_exc = None 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'] # If corresponding exception is defined, use it. client_exc = getattr(exceptions, '%sClient' % error_type, None) except Exception: error_message = "%s" % error_dict else: error_message = None if isinstance(error_content, dict): error_message = error_content.get('message') if not error_message: # If we end up here the exception was not a neutron error error_message = "%s-%s" % (status_code, error_content) # If an exception corresponding to the error type is not found, # look up per status-code client exception. if not client_exc: client_exc = exceptions.HTTP_EXCEPTION_MAP.get(status_code) # If there is no exception per status-code, # Use NeutronClientException as fallback. if not client_exc: client_exc = exceptions.NeutronClientException raise client_exc(message=error_message, status_code=status_code, request_ids=request_ids) class _RequestIdMixin(object): """Wrapper class to expose x-openstack-request-id to the caller.""" def _request_ids_setup(self): self._request_ids = [] @property def request_ids(self): return self._request_ids def _append_request_ids(self, resp): """Add request_ids as an attribute to the object :param resp: Response object or list of Response objects """ if isinstance(resp, list): # Add list of request_ids if response is of type list. for resp_obj in resp: self._append_request_id(resp_obj) elif resp is not None: # Add request_ids if response contains single object. self._append_request_id(resp) def _append_request_id(self, resp): if isinstance(resp, requests.Response): # Extract 'x-openstack-request-id' from headers if # response is a Response object. request_id = resp.headers.get('x-openstack-request-id') else: # If resp is of type string. request_id = resp if request_id: self._request_ids.append(request_id) class _DictWithMeta(dict, _RequestIdMixin): def __init__(self, values, resp): super(_DictWithMeta, self).__init__(values) self._request_ids_setup() self._append_request_ids(resp) class _TupleWithMeta(tuple, _RequestIdMixin): def __new__(cls, values, resp): return super(_TupleWithMeta, cls).__new__(cls, values) def __init__(self, values, resp): self._request_ids_setup() self._append_request_ids(resp) class _StrWithMeta(str, _RequestIdMixin): def __new__(cls, value, resp): return super(_StrWithMeta, cls).__new__(cls, value) def __init__(self, values, resp): self._request_ids_setup() self._append_request_ids(resp) class _GeneratorWithMeta(_RequestIdMixin): def __init__(self, paginate_func, collection, path, **params): self.paginate_func = paginate_func self.collection = collection self.path = path self.params = params self.generator = None self._request_ids_setup() def _paginate(self): for r in self.paginate_func( self.collection, self.path, **self.params): yield r, r.request_ids def __iter__(self): return self # Python 3 compatibility def __next__(self): return self.next() def next(self): if not self.generator: self.generator = self._paginate() try: obj, req_id = next(self.generator) self._append_request_ids(req_id) except StopIteration: raise StopIteration() return obj class ClientBase(object): """Client for the OpenStack Neutron v2.0 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: DEPRECATED! Use project_name instead. :param string project_name: Project name. (optional) :param string tenant_id: DEPRECATED! Use project_id instead. :param string project_id: Project id. (optional) :param string auth_strategy: 'keystone' by default, 'noauth' for no authentication against keystone. (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 bool log_credentials: Allow for logging of passwords or not. Defaults to False. (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 neutronclient.v2_0 import client neutron = client.Client(username=USER, password=PASS, project_name=PROJECT_NAME, auth_url=KEYSTONE_URL) nets = neutron.list_networks() ... """ # API has no way to report plurals, so we have to hard code them # This variable should be overridden by a child class. EXTED_PLURALS = {} @debtcollector.renames.renamed_kwarg( 'tenant_id', 'project_id', replace=True) def __init__(self, **kwargs): """Initialize a new client for the Neutron v2.0 API.""" super(ClientBase, 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.action_prefix = "/v%s" % (self.version) self.retry_interval = 1 def _handle_fault_response(self, status_code, response_body, resp): # 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} error_body = self._convert_into_with_meta(des_error_body, resp) # Raise the appropriate exception exception_handler_v20(status_code, error_body) def do_request(self, method, action, body=None, headers=None, params=None): # Add format and project_id action = self.action_prefix + action if isinstance(params, dict) and params: params = utils.safe_encode_dict(params) action += '?' + urlparse.urlencode(params, doseq=1) if body: body = self.serialize(body) resp, replybody = self.httpclient.do_request(action, method, body=body, headers=headers) status_code = resp.status_code if status_code in (requests.codes.ok, requests.codes.created, requests.codes.accepted, requests.codes.no_content): data = self.deserialize(replybody, status_code) return self._convert_into_with_meta(data, resp) else: if not replybody: replybody = resp.reason self._handle_fault_response(status_code, replybody, resp) def get_auth_info(self): return self.httpclient.get_auth_info() def serialize(self, data): """Serializes a dictionary into JSON. A dictionary with a single key can be passed and it can contain any structure. """ if data is None: return None elif isinstance(data, dict): return serializer.Serializer().serialize(data) else: raise Exception(_("Unable to serialize object of type = '%s'") % type(data)) def deserialize(self, data, status_code): """Deserializes a JSON string into a dictionary.""" if not data: return data return serializer.Serializer().deserialize( data)['body'] 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, ksa_exc.ConnectionError): # 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 = [] request_ids = [] for r in self._pagination(collection, path, **params): res.extend(r[collection]) request_ids.extend(r.request_ids) return _DictWithMeta({collection: res}, request_ids) else: return _GeneratorWithMeta(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 def _convert_into_with_meta(self, item, resp): if item: if isinstance(item, dict): return _DictWithMeta(item, resp) elif isinstance(item, string_types): return _StrWithMeta(item, resp) else: return _TupleWithMeta((), resp) def get_resource_plural(self, resource): for k in self.EXTED_PLURALS: if self.EXTED_PLURALS[k] == resource: return k return resource + 's' def find_resource_by_id(self, resource, resource_id, cmd_resource=None, parent_id=None, fields=None): if not cmd_resource: cmd_resource = resource cmd_resource_plural = self.get_resource_plural(cmd_resource) resource_plural = self.get_resource_plural(resource) # TODO(amotoki): Use show_%s instead of list_%s obj_lister = getattr(self, "list_%s" % cmd_resource_plural) # perform search by id only if we are passing a valid UUID match = re.match(UUID_PATTERN, resource_id) collection = resource_plural if match: params = {'id': resource_id} if fields: params['fields'] = fields if parent_id: data = obj_lister(parent_id, **params) else: data = obj_lister(**params) if data and data[collection]: return data[collection][0] not_found_message = (_("Unable to find %(resource)s with id " "'%(id)s'") % {'resource': resource, 'id': resource_id}) # 404 is raised by exceptions.NotFound to simulate serverside behavior raise exceptions.NotFound(message=not_found_message) def _find_resource_by_name(self, resource, name, project_id=None, cmd_resource=None, parent_id=None, fields=None): if not cmd_resource: cmd_resource = resource cmd_resource_plural = self.get_resource_plural(cmd_resource) resource_plural = self.get_resource_plural(resource) obj_lister = getattr(self, "list_%s" % cmd_resource_plural) params = {'name': name} if fields: params['fields'] = fields if project_id: params['tenant_id'] = project_id if parent_id: data = obj_lister(parent_id, **params) else: data = obj_lister(**params) collection = resource_plural info = data[collection] if len(info) > 1: raise exceptions.NeutronClientNoUniqueMatch(resource=resource, name=name) elif len(info) == 0: not_found_message = (_("Unable to find %(resource)s with name " "'%(name)s'") % {'resource': resource, 'name': name}) # 404 is raised by exceptions.NotFound # to simulate serverside behavior raise exceptions.NotFound(message=not_found_message) else: return info[0] def find_resource(self, resource, name_or_id, project_id=None, cmd_resource=None, parent_id=None, fields=None): try: return self.find_resource_by_id(resource, name_or_id, cmd_resource, parent_id, fields) except exceptions.NotFound: try: return self._find_resource_by_name( resource, name_or_id, project_id, cmd_resource, parent_id, fields) except exceptions.NotFound: not_found_message = (_("Unable to find %(resource)s with name " "or id '%(name_or_id)s'") % {'resource': resource, 'name_or_id': name_or_id}) raise exceptions.NotFound( message=not_found_message) class Client(ClientBase): networks_path = "/networks" network_path = "/networks/%s" ports_path = "/ports" port_path = "/ports/%s" subnets_path = "/subnets" subnet_path = "/subnets/%s" subnetpools_path = "/subnetpools" subnetpool_path = "/subnetpools/%s" address_scopes_path = "/address-scopes" address_scope_path = "/address-scopes/%s" quotas_path = "/quotas" quota_path = "/quotas/%s" quota_default_path = "/quotas/%s/default" extensions_path = "/extensions" extension_path = "/extensions/%s" routers_path = "/routers" router_path = "/routers/%s" floatingips_path = "/floatingips" floatingip_path = "/floatingips/%s" security_groups_path = "/security-groups" security_group_path = "/security-groups/%s" security_group_rules_path = "/security-group-rules" security_group_rule_path = "/security-group-rules/%s" sfc_flow_classifiers_path = "/sfc/flow_classifiers" sfc_flow_classifier_path = "/sfc/flow_classifiers/%s" sfc_port_pairs_path = "/sfc/port_pairs" sfc_port_pair_path = "/sfc/port_pairs/%s" sfc_port_pair_groups_path = "/sfc/port_pair_groups" sfc_port_pair_group_path = "/sfc/port_pair_groups/%s" sfc_port_chains_path = "/sfc/port_chains" sfc_port_chain_path = "/sfc/port_chains/%s" sfc_service_graphs_path = "/sfc/service_graphs" sfc_service_graph_path = "/sfc/service_graphs/%s" endpoint_groups_path = "/vpn/endpoint-groups" endpoint_group_path = "/vpn/endpoint-groups/%s" vpnservices_path = "/vpn/vpnservices" vpnservice_path = "/vpn/vpnservices/%s" ipsecpolicies_path = "/vpn/ipsecpolicies" ipsecpolicy_path = "/vpn/ipsecpolicies/%s" ikepolicies_path = "/vpn/ikepolicies" ikepolicy_path = "/vpn/ikepolicies/%s" ipsec_site_connections_path = "/vpn/ipsec-site-connections" ipsec_site_connection_path = "/vpn/ipsec-site-connections/%s" lbaas_loadbalancers_path = "/lbaas/loadbalancers" lbaas_loadbalancer_path = "/lbaas/loadbalancers/%s" lbaas_loadbalancer_path_stats = "/lbaas/loadbalancers/%s/stats" lbaas_loadbalancer_path_status = "/lbaas/loadbalancers/%s/statuses" lbaas_listeners_path = "/lbaas/listeners" lbaas_listener_path = "/lbaas/listeners/%s" lbaas_l7policies_path = "/lbaas/l7policies" lbaas_l7policy_path = lbaas_l7policies_path + "/%s" lbaas_l7rules_path = lbaas_l7policy_path + "/rules" lbaas_l7rule_path = lbaas_l7rules_path + "/%s" lbaas_pools_path = "/lbaas/pools" lbaas_pool_path = "/lbaas/pools/%s" lbaas_healthmonitors_path = "/lbaas/healthmonitors" lbaas_healthmonitor_path = "/lbaas/healthmonitors/%s" lbaas_members_path = lbaas_pool_path + "/members" lbaas_member_path = lbaas_pool_path + "/members/%s" vips_path = "/lb/vips" vip_path = "/lb/vips/%s" pools_path = "/lb/pools" pool_path = "/lb/pools/%s" pool_path_stats = "/lb/pools/%s/stats" members_path = "/lb/members" member_path = "/lb/members/%s" health_monitors_path = "/lb/health_monitors" health_monitor_path = "/lb/health_monitors/%s" associate_pool_health_monitors_path = "/lb/pools/%s/health_monitors" disassociate_pool_health_monitors_path = ( "/lb/pools/%(pool)s/health_monitors/%(health_monitor)s") qos_queues_path = "/qos-queues" qos_queue_path = "/qos-queues/%s" agents_path = "/agents" agent_path = "/agents/%s" network_gateways_path = "/network-gateways" network_gateway_path = "/network-gateways/%s" gateway_devices_path = "/gateway-devices" gateway_device_path = "/gateway-devices/%s" service_providers_path = "/service-providers" metering_labels_path = "/metering/metering-labels" metering_label_path = "/metering/metering-labels/%s" metering_label_rules_path = "/metering/metering-label-rules" metering_label_rule_path = "/metering/metering-label-rules/%s" DHCP_NETS = '/dhcp-networks' DHCP_AGENTS = '/dhcp-agents' L3_ROUTERS = '/l3-routers' L3_AGENTS = '/l3-agents' LOADBALANCER_POOLS = '/loadbalancer-pools' LOADBALANCER_AGENT = '/loadbalancer-agent' AGENT_LOADBALANCERS = '/agent-loadbalancers' LOADBALANCER_HOSTING_AGENT = '/loadbalancer-hosting-agent' firewall_rules_path = "/fw/firewall_rules" firewall_rule_path = "/fw/firewall_rules/%s" firewall_policies_path = "/fw/firewall_policies" firewall_policy_path = "/fw/firewall_policies/%s" firewall_policy_insert_path = "/fw/firewall_policies/%s/insert_rule" firewall_policy_remove_path = "/fw/firewall_policies/%s/remove_rule" firewalls_path = "/fw/firewalls" firewall_path = "/fw/firewalls/%s" fwaas_firewall_groups_path = "/fwaas/firewall_groups" fwaas_firewall_group_path = "/fwaas/firewall_groups/%s" fwaas_firewall_rules_path = "/fwaas/firewall_rules" fwaas_firewall_rule_path = "/fwaas/firewall_rules/%s" fwaas_firewall_policies_path = "/fwaas/firewall_policies" fwaas_firewall_policy_path = "/fwaas/firewall_policies/%s" fwaas_firewall_policy_insert_path = \ "/fwaas/firewall_policies/%s/insert_rule" fwaas_firewall_policy_remove_path = \ "/fwaas/firewall_policies/%s/remove_rule" rbac_policies_path = "/rbac-policies" rbac_policy_path = "/rbac-policies/%s" qos_policies_path = "/qos/policies" qos_policy_path = "/qos/policies/%s" qos_bandwidth_limit_rules_path = "/qos/policies/%s/bandwidth_limit_rules" qos_bandwidth_limit_rule_path = "/qos/policies/%s/bandwidth_limit_rules/%s" qos_dscp_marking_rules_path = "/qos/policies/%s/dscp_marking_rules" qos_dscp_marking_rule_path = "/qos/policies/%s/dscp_marking_rules/%s" qos_minimum_bandwidth_rules_path = \ "/qos/policies/%s/minimum_bandwidth_rules" qos_minimum_bandwidth_rule_path = \ "/qos/policies/%s/minimum_bandwidth_rules/%s" qos_rule_types_path = "/qos/rule-types" qos_rule_type_path = "/qos/rule-types/%s" flavors_path = "/flavors" flavor_path = "/flavors/%s" service_profiles_path = "/service_profiles" service_profile_path = "/service_profiles/%s" flavor_profile_bindings_path = flavor_path + service_profiles_path flavor_profile_binding_path = flavor_path + service_profile_path availability_zones_path = "/availability_zones" auto_allocated_topology_path = "/auto-allocated-topology/%s" BGP_DRINSTANCES = "/bgp-drinstances" BGP_DRINSTANCE = "/bgp-drinstance/%s" BGP_DRAGENTS = "/bgp-dragents" BGP_DRAGENT = "/bgp-dragents/%s" bgp_speakers_path = "/bgp-speakers" bgp_speaker_path = "/bgp-speakers/%s" bgp_peers_path = "/bgp-peers" bgp_peer_path = "/bgp-peers/%s" network_ip_availabilities_path = '/network-ip-availabilities' network_ip_availability_path = '/network-ip-availabilities/%s' tags_path = "/%s/%s/tags" tag_path = "/%s/%s/tags/%s" trunks_path = "/trunks" trunk_path = "/trunks/%s" subports_path = "/trunks/%s/get_subports" subports_add_path = "/trunks/%s/add_subports" subports_remove_path = "/trunks/%s/remove_subports" bgpvpns_path = "/bgpvpn/bgpvpns" bgpvpn_path = "/bgpvpn/bgpvpns/%s" bgpvpn_network_associations_path =\ "/bgpvpn/bgpvpns/%s/network_associations" bgpvpn_network_association_path =\ "/bgpvpn/bgpvpns/%s/network_associations/%s" bgpvpn_router_associations_path = "/bgpvpn/bgpvpns/%s/router_associations" bgpvpn_router_association_path =\ "/bgpvpn/bgpvpns/%s/router_associations/%s" bgpvpn_port_associations_path = "/bgpvpn/bgpvpns/%s/port_associations" bgpvpn_port_association_path = "/bgpvpn/bgpvpns/%s/port_associations/%s" network_logs_path = "/log/logs" network_log_path = "/log/logs/%s" network_loggables_path = "/log/loggable-resources" # API has no way to report plurals, so we have to hard code them EXTED_PLURALS = {'routers': 'router', 'floatingips': 'floatingip', 'service_types': 'service_type', 'service_definitions': 'service_definition', 'security_groups': 'security_group', 'security_group_rules': 'security_group_rule', 'ipsecpolicies': 'ipsecpolicy', 'ikepolicies': 'ikepolicy', 'ipsec_site_connections': 'ipsec_site_connection', 'vpnservices': 'vpnservice', 'endpoint_groups': 'endpoint_group', 'vips': 'vip', 'pools': 'pool', 'members': 'member', 'health_monitors': 'health_monitor', 'quotas': 'quota', 'service_providers': 'service_provider', 'firewall_rules': 'firewall_rule', 'firewall_policies': 'firewall_policy', 'firewalls': 'firewall', 'fwaas_firewall_rules': 'fwaas_firewall_rule', 'fwaas_firewall_policies': 'fwaas_firewall_policy', 'fwaas_firewall_groups': 'fwaas_firewall_group', 'metering_labels': 'metering_label', 'metering_label_rules': 'metering_label_rule', 'loadbalancers': 'loadbalancer', 'listeners': 'listener', 'l7rules': 'l7rule', 'l7policies': 'l7policy', 'lbaas_l7policies': 'lbaas_l7policy', 'lbaas_pools': 'lbaas_pool', 'lbaas_healthmonitors': 'lbaas_healthmonitor', 'lbaas_members': 'lbaas_member', 'healthmonitors': 'healthmonitor', 'rbac_policies': 'rbac_policy', 'address_scopes': 'address_scope', 'qos_policies': 'qos_policy', 'policies': 'policy', 'bandwidth_limit_rules': 'bandwidth_limit_rule', 'minimum_bandwidth_rules': 'minimum_bandwidth_rule', 'rules': 'rule', 'dscp_marking_rules': 'dscp_marking_rule', 'rule_types': 'rule_type', 'flavors': 'flavor', 'bgp_speakers': 'bgp_speaker', 'bgp_peers': 'bgp_peer', 'network_ip_availabilities': 'network_ip_availability', 'trunks': 'trunk', 'bgpvpns': 'bgpvpn', 'network_associations': 'network_association', 'router_associations': 'router_association', 'port_associations': 'port_association', 'flow_classifiers': 'flow_classifier', 'port_pairs': 'port_pair', 'port_pair_groups': 'port_pair_group', 'port_chains': 'port_chain', 'service_graphs': 'service_graph', 'logs': 'log', 'loggable_resources': 'loggable_resource', } def list_ext(self, collection, path, retrieve_all, **_params): """Client extension hook for list.""" return self.list(collection, path, retrieve_all, **_params) def show_ext(self, path, id, **_params): """Client extension hook for show.""" return self.get(path % id, params=_params) def create_ext(self, path, body=None): """Client extension hook for create.""" return self.post(path, body=body) def update_ext(self, path, id, body=None): """Client extension hook for update.""" return self.put(path % id, body=body) def delete_ext(self, path, id): """Client extension hook for delete.""" return self.delete(path % id) def get_quotas_tenant(self, **_params): """Fetch project info for following quota operation.""" return self.get(self.quota_path % 'tenant', params=_params) def list_quotas(self, **_params): """Fetch all projects' quotas.""" return self.get(self.quotas_path, params=_params) @debtcollector.renames.renamed_kwarg( 'tenant_id', 'project_id', replace=True) def show_quota(self, project_id, **_params): """Fetch information of a certain project's quotas.""" return self.get(self.quota_path % (project_id), params=_params) @debtcollector.renames.renamed_kwarg( 'tenant_id', 'project_id', replace=True) def show_quota_default(self, project_id, **_params): """Fetch information of a certain project's default quotas.""" return self.get(self.quota_default_path % (project_id), params=_params) @debtcollector.renames.renamed_kwarg( 'tenant_id', 'project_id', replace=True) def update_quota(self, project_id, body=None): """Update a project's quotas.""" return self.put(self.quota_path % (project_id), body=body) @debtcollector.renames.renamed_kwarg( 'tenant_id', 'project_id', replace=True) def delete_quota(self, project_id): """Delete the specified project's quota values.""" return self.delete(self.quota_path % (project_id)) def list_extensions(self, **_params): """Fetch a list of all extensions on server side.""" return self.get(self.extensions_path, params=_params) def show_extension(self, ext_alias, **_params): """Fetches information of a certain extension.""" return self.get(self.extension_path % ext_alias, params=_params) def list_ports(self, retrieve_all=True, **_params): """Fetches a list of all ports for a project.""" # Pass filters in "params" argument to do_request return self.list('ports', self.ports_path, retrieve_all, **_params) def show_port(self, port, **_params): """Fetches information of a certain port.""" return self.get(self.port_path % (port), params=_params) def create_port(self, body=None): """Creates a new port.""" return self.post(self.ports_path, body=body) def update_port(self, port, body=None, revision_number=None): """Updates a port.""" return self._update_resource(self.port_path % (port), body=body, revision_number=revision_number) def delete_port(self, port): """Deletes the specified port.""" return self.delete(self.port_path % (port)) def list_networks(self, retrieve_all=True, **_params): """Fetches a list of all networks for a project.""" # Pass filters in "params" argument to do_request return self.list('networks', self.networks_path, retrieve_all, **_params) def show_network(self, network, **_params): """Fetches information of a certain network.""" return self.get(self.network_path % (network), params=_params) def create_network(self, body=None): """Creates a new network.""" return self.post(self.networks_path, body=body) def update_network(self, network, body=None, revision_number=None): """Updates a network.""" return self._update_resource(self.network_path % (network), body=body, revision_number=revision_number) def delete_network(self, network): """Deletes the specified network.""" return self.delete(self.network_path % (network)) def list_subnets(self, retrieve_all=True, **_params): """Fetches a list of all subnets for a project.""" return self.list('subnets', self.subnets_path, retrieve_all, **_params) def show_subnet(self, subnet, **_params): """Fetches information of a certain subnet.""" return self.get(self.subnet_path % (subnet), params=_params) def create_subnet(self, body=None): """Creates a new subnet.""" return self.post(self.subnets_path, body=body) def update_subnet(self, subnet, body=None, revision_number=None): """Updates a subnet.""" return self._update_resource(self.subnet_path % (subnet), body=body, revision_number=revision_number) def delete_subnet(self, subnet): """Deletes the specified subnet.""" return self.delete(self.subnet_path % (subnet)) def list_subnetpools(self, retrieve_all=True, **_params): """Fetches a list of all subnetpools for a project.""" return self.list('subnetpools', self.subnetpools_path, retrieve_all, **_params) def show_subnetpool(self, subnetpool, **_params): """Fetches information of a certain subnetpool.""" return self.get(self.subnetpool_path % (subnetpool), params=_params) def create_subnetpool(self, body=None): """Creates a new subnetpool.""" return self.post(self.subnetpools_path, body=body) def update_subnetpool(self, subnetpool, body=None, revision_number=None): """Updates a subnetpool.""" return self._update_resource(self.subnetpool_path % (subnetpool), body=body, revision_number=revision_number) def delete_subnetpool(self, subnetpool): """Deletes the specified subnetpool.""" return self.delete(self.subnetpool_path % (subnetpool)) def list_routers(self, retrieve_all=True, **_params): """Fetches a list of all routers for a project.""" # Pass filters in "params" argument to do_request return self.list('routers', self.routers_path, retrieve_all, **_params) def show_router(self, router, **_params): """Fetches information of a certain router.""" return self.get(self.router_path % (router), params=_params) def create_router(self, body=None): """Creates a new router.""" return self.post(self.routers_path, body=body) def update_router(self, router, body=None, revision_number=None): """Updates a router.""" return self._update_resource(self.router_path % (router), body=body, revision_number=revision_number) def delete_router(self, router): """Deletes the specified router.""" return self.delete(self.router_path % (router)) def list_address_scopes(self, retrieve_all=True, **_params): """Fetches a list of all address scopes for a project.""" return self.list('address_scopes', self.address_scopes_path, retrieve_all, **_params) def show_address_scope(self, address_scope, **_params): """Fetches information of a certain address scope.""" return self.get(self.address_scope_path % (address_scope), params=_params) def create_address_scope(self, body=None): """Creates a new address scope.""" return self.post(self.address_scopes_path, body=body) def update_address_scope(self, address_scope, body=None): """Updates a address scope.""" return self.put(self.address_scope_path % (address_scope), body=body) def delete_address_scope(self, address_scope): """Deletes the specified address scope.""" return self.delete(self.address_scope_path % (address_scope)) def add_interface_router(self, router, body=None): """Adds an internal network interface to the specified router.""" return self.put((self.router_path % router) + "/add_router_interface", body=body) def remove_interface_router(self, router, body=None): """Removes an internal network interface from the specified router.""" return self.put((self.router_path % router) + "/remove_router_interface", body=body) def add_gateway_router(self, router, body=None): """Adds an external network gateway to the specified router.""" return self.put((self.router_path % router), body={'router': {'external_gateway_info': body}}) def remove_gateway_router(self, router): """Removes an external network gateway from the specified router.""" return self.put((self.router_path % router), body={'router': {'external_gateway_info': {}}}) def list_floatingips(self, retrieve_all=True, **_params): """Fetches a list of all floatingips for a project.""" # Pass filters in "params" argument to do_request return self.list('floatingips', self.floatingips_path, retrieve_all, **_params) def show_floatingip(self, floatingip, **_params): """Fetches information of a certain floatingip.""" return self.get(self.floatingip_path % (floatingip), params=_params) def create_floatingip(self, body=None): """Creates a new floatingip.""" return self.post(self.floatingips_path, body=body) def update_floatingip(self, floatingip, body=None, revision_number=None): """Updates a floatingip.""" return self._update_resource(self.floatingip_path % (floatingip), body=body, revision_number=revision_number) def delete_floatingip(self, floatingip): """Deletes the specified floatingip.""" return self.delete(self.floatingip_path % (floatingip)) def create_security_group(self, body=None): """Creates a new security group.""" return self.post(self.security_groups_path, body=body) def update_security_group(self, security_group, body=None, revision_number=None): """Updates a security group.""" return self._update_resource(self.security_group_path % security_group, body=body, revision_number=revision_number) def list_security_groups(self, retrieve_all=True, **_params): """Fetches a list of all security groups for a project.""" return self.list('security_groups', self.security_groups_path, retrieve_all, **_params) def show_security_group(self, security_group, **_params): """Fetches information of a certain security group.""" return self.get(self.security_group_path % (security_group), params=_params) def delete_security_group(self, security_group): """Deletes the specified security group.""" return self.delete(self.security_group_path % (security_group)) def create_security_group_rule(self, body=None): """Creates a new security group rule.""" return self.post(self.security_group_rules_path, body=body) def delete_security_group_rule(self, security_group_rule): """Deletes the specified security group rule.""" return self.delete(self.security_group_rule_path % (security_group_rule)) def list_security_group_rules(self, retrieve_all=True, **_params): """Fetches a list of all security group rules for a project.""" return self.list('security_group_rules', self.security_group_rules_path, retrieve_all, **_params) def show_security_group_rule(self, security_group_rule, **_params): """Fetches information of a certain security group rule.""" return self.get(self.security_group_rule_path % (security_group_rule), params=_params) def list_endpoint_groups(self, retrieve_all=True, **_params): """Fetches a list of all VPN endpoint groups for a project.""" return self.list('endpoint_groups', self.endpoint_groups_path, retrieve_all, **_params) def show_endpoint_group(self, endpointgroup, **_params): """Fetches information for a specific VPN endpoint group.""" return self.get(self.endpoint_group_path % endpointgroup, params=_params) def create_endpoint_group(self, body=None): """Creates a new VPN endpoint group.""" return self.post(self.endpoint_groups_path, body=body) def update_endpoint_group(self, endpoint_group, body=None): """Updates a VPN endpoint group.""" return self.put(self.endpoint_group_path % endpoint_group, body=body) def delete_endpoint_group(self, endpoint_group): """Deletes the specified VPN endpoint group.""" return self.delete(self.endpoint_group_path % endpoint_group) def list_vpnservices(self, retrieve_all=True, **_params): """Fetches a list of all configured VPN services for a project.""" return self.list('vpnservices', self.vpnservices_path, retrieve_all, **_params) def show_vpnservice(self, vpnservice, **_params): """Fetches information of a specific VPN service.""" return self.get(self.vpnservice_path % (vpnservice), params=_params) def create_vpnservice(self, body=None): """Creates a new VPN service.""" return self.post(self.vpnservices_path, body=body) def update_vpnservice(self, vpnservice, body=None): """Updates a VPN service.""" return self.put(self.vpnservice_path % (vpnservice), body=body) def delete_vpnservice(self, vpnservice): """Deletes the specified VPN service.""" return self.delete(self.vpnservice_path % (vpnservice)) def list_ipsec_site_connections(self, retrieve_all=True, **_params): """Fetches all configured IPsecSiteConnections for a project.""" return self.list('ipsec_site_connections', self.ipsec_site_connections_path, retrieve_all, **_params) def show_ipsec_site_connection(self, ipsecsite_conn, **_params): """Fetches information of a specific IPsecSiteConnection.""" return self.get( self.ipsec_site_connection_path % (ipsecsite_conn), params=_params ) def create_ipsec_site_connection(self, body=None): """Creates a new IPsecSiteConnection.""" return self.post(self.ipsec_site_connections_path, body=body) def update_ipsec_site_connection(self, ipsecsite_conn, body=None): """Updates an IPsecSiteConnection.""" return self.put( self.ipsec_site_connection_path % (ipsecsite_conn), body=body ) def delete_ipsec_site_connection(self, ipsecsite_conn): """Deletes the specified IPsecSiteConnection.""" return self.delete(self.ipsec_site_connection_path % (ipsecsite_conn)) def list_ikepolicies(self, retrieve_all=True, **_params): """Fetches a list of all configured IKEPolicies for a project.""" return self.list('ikepolicies', self.ikepolicies_path, retrieve_all, **_params) def show_ikepolicy(self, ikepolicy, **_params): """Fetches information of a specific IKEPolicy.""" return self.get(self.ikepolicy_path % (ikepolicy), params=_params) def create_ikepolicy(self, body=None): """Creates a new IKEPolicy.""" return self.post(self.ikepolicies_path, body=body) def update_ikepolicy(self, ikepolicy, body=None): """Updates an IKEPolicy.""" return self.put(self.ikepolicy_path % (ikepolicy), body=body) def delete_ikepolicy(self, ikepolicy): """Deletes the specified IKEPolicy.""" return self.delete(self.ikepolicy_path % (ikepolicy)) def list_ipsecpolicies(self, retrieve_all=True, **_params): """Fetches a list of all configured IPsecPolicies for a project.""" return self.list('ipsecpolicies', self.ipsecpolicies_path, retrieve_all, **_params) def show_ipsecpolicy(self, ipsecpolicy, **_params): """Fetches information of a specific IPsecPolicy.""" return self.get(self.ipsecpolicy_path % (ipsecpolicy), params=_params) def create_ipsecpolicy(self, body=None): """Creates a new IPsecPolicy.""" return self.post(self.ipsecpolicies_path, body=body) def update_ipsecpolicy(self, ipsecpolicy, body=None): """Updates an IPsecPolicy.""" return self.put(self.ipsecpolicy_path % (ipsecpolicy), body=body) def delete_ipsecpolicy(self, ipsecpolicy): """Deletes the specified IPsecPolicy.""" return self.delete(self.ipsecpolicy_path % (ipsecpolicy)) def list_loadbalancers(self, retrieve_all=True, **_params): """Fetches a list of all loadbalancers for a project.""" return self.list('loadbalancers', self.lbaas_loadbalancers_path, retrieve_all, **_params) def show_loadbalancer(self, lbaas_loadbalancer, **_params): """Fetches information for a load balancer.""" return self.get(self.lbaas_loadbalancer_path % (lbaas_loadbalancer), params=_params) def create_loadbalancer(self, body=None): """Creates a new load balancer.""" return self.post(self.lbaas_loadbalancers_path, body=body) def update_loadbalancer(self, lbaas_loadbalancer, body=None): """Updates a load balancer.""" return self.put(self.lbaas_loadbalancer_path % (lbaas_loadbalancer), body=body) def delete_loadbalancer(self, lbaas_loadbalancer): """Deletes the specified load balancer.""" return self.delete(self.lbaas_loadbalancer_path % (lbaas_loadbalancer)) def retrieve_loadbalancer_stats(self, loadbalancer, **_params): """Retrieves stats for a certain load balancer.""" return self.get(self.lbaas_loadbalancer_path_stats % (loadbalancer), params=_params) def retrieve_loadbalancer_status(self, loadbalancer, **_params): """Retrieves status for a certain load balancer.""" return self.get(self.lbaas_loadbalancer_path_status % (loadbalancer), params=_params) def list_listeners(self, retrieve_all=True, **_params): """Fetches a list of all lbaas_listeners for a project.""" return self.list('listeners', self.lbaas_listeners_path, retrieve_all, **_params) def show_listener(self, lbaas_listener, **_params): """Fetches information for a lbaas_listener.""" return self.get(self.lbaas_listener_path % (lbaas_listener), params=_params) def create_listener(self, body=None): """Creates a new lbaas_listener.""" return self.post(self.lbaas_listeners_path, body=body) def update_listener(self, lbaas_listener, body=None): """Updates a lbaas_listener.""" return self.put(self.lbaas_listener_path % (lbaas_listener), body=body) def delete_listener(self, lbaas_listener): """Deletes the specified lbaas_listener.""" return self.delete(self.lbaas_listener_path % (lbaas_listener)) def list_lbaas_l7policies(self, retrieve_all=True, **_params): """Fetches a list of all L7 policies for a listener.""" return self.list('l7policies', self.lbaas_l7policies_path, retrieve_all, **_params) def show_lbaas_l7policy(self, l7policy, **_params): """Fetches information of a certain listener's L7 policy.""" return self.get(self.lbaas_l7policy_path % l7policy, params=_params) def create_lbaas_l7policy(self, body=None): """Creates L7 policy for a certain listener.""" return self.post(self.lbaas_l7policies_path, body=body) def update_lbaas_l7policy(self, l7policy, body=None): """Updates L7 policy.""" return self.put(self.lbaas_l7policy_path % l7policy, body=body) def delete_lbaas_l7policy(self, l7policy): """Deletes the specified L7 policy.""" return self.delete(self.lbaas_l7policy_path % l7policy) def list_lbaas_l7rules(self, l7policy, retrieve_all=True, **_params): """Fetches a list of all rules for L7 policy.""" return self.list('rules', self.lbaas_l7rules_path % l7policy, retrieve_all, **_params) def show_lbaas_l7rule(self, l7rule, l7policy, **_params): """Fetches information of a certain L7 policy's rule.""" return self.get(self.lbaas_l7rule_path % (l7policy, l7rule), params=_params) def create_lbaas_l7rule(self, l7policy, body=None): """Creates rule for a certain L7 policy.""" return self.post(self.lbaas_l7rules_path % l7policy, body=body) def update_lbaas_l7rule(self, l7rule, l7policy, body=None): """Updates L7 rule.""" return self.put(self.lbaas_l7rule_path % (l7policy, l7rule), body=body) def delete_lbaas_l7rule(self, l7rule, l7policy): """Deletes the specified L7 rule.""" return self.delete(self.lbaas_l7rule_path % (l7policy, l7rule)) def list_lbaas_pools(self, retrieve_all=True, **_params): """Fetches a list of all lbaas_pools for a project.""" return self.list('pools', self.lbaas_pools_path, retrieve_all, **_params) def show_lbaas_pool(self, lbaas_pool, **_params): """Fetches information for a lbaas_pool.""" return self.get(self.lbaas_pool_path % (lbaas_pool), params=_params) def create_lbaas_pool(self, body=None): """Creates a new lbaas_pool.""" return self.post(self.lbaas_pools_path, body=body) def update_lbaas_pool(self, lbaas_pool, body=None): """Updates a lbaas_pool.""" return self.put(self.lbaas_pool_path % (lbaas_pool), body=body) def delete_lbaas_pool(self, lbaas_pool): """Deletes the specified lbaas_pool.""" return self.delete(self.lbaas_pool_path % (lbaas_pool)) def list_lbaas_healthmonitors(self, retrieve_all=True, **_params): """Fetches a list of all lbaas_healthmonitors for a project.""" return self.list('healthmonitors', self.lbaas_healthmonitors_path, retrieve_all, **_params) def show_lbaas_healthmonitor(self, lbaas_healthmonitor, **_params): """Fetches information for a lbaas_healthmonitor.""" return self.get(self.lbaas_healthmonitor_path % (lbaas_healthmonitor), params=_params) def create_lbaas_healthmonitor(self, body=None): """Creates a new lbaas_healthmonitor.""" return self.post(self.lbaas_healthmonitors_path, body=body) def update_lbaas_healthmonitor(self, lbaas_healthmonitor, body=None): """Updates a lbaas_healthmonitor.""" return self.put(self.lbaas_healthmonitor_path % (lbaas_healthmonitor), body=body) def delete_lbaas_healthmonitor(self, lbaas_healthmonitor): """Deletes the specified lbaas_healthmonitor.""" return self.delete(self.lbaas_healthmonitor_path % (lbaas_healthmonitor)) def list_lbaas_loadbalancers(self, retrieve_all=True, **_params): """Fetches a list of all lbaas_loadbalancers for a project.""" return self.list('loadbalancers', self.lbaas_loadbalancers_path, retrieve_all, **_params) def list_lbaas_members(self, lbaas_pool, retrieve_all=True, **_params): """Fetches a list of all lbaas_members for a project.""" return self.list('members', self.lbaas_members_path % lbaas_pool, retrieve_all, **_params) def show_lbaas_member(self, lbaas_member, lbaas_pool, **_params): """Fetches information of a certain lbaas_member.""" return self.get(self.lbaas_member_path % (lbaas_pool, lbaas_member), params=_params) def create_lbaas_member(self, lbaas_pool, body=None): """Creates a lbaas_member.""" return self.post(self.lbaas_members_path % lbaas_pool, body=body) def update_lbaas_member(self, lbaas_member, lbaas_pool, body=None): """Updates a lbaas_member.""" return self.put(self.lbaas_member_path % (lbaas_pool, lbaas_member), body=body) def delete_lbaas_member(self, lbaas_member, lbaas_pool): """Deletes the specified lbaas_member.""" return self.delete(self.lbaas_member_path % (lbaas_pool, lbaas_member)) def list_vips(self, retrieve_all=True, **_params): """Fetches a list of all load balancer vips for a project.""" # Pass filters in "params" argument to do_request return self.list('vips', self.vips_path, retrieve_all, **_params) def show_vip(self, vip, **_params): """Fetches information of a certain load balancer vip.""" return self.get(self.vip_path % (vip), params=_params) def create_vip(self, body=None): """Creates a new load balancer vip.""" return self.post(self.vips_path, body=body) def update_vip(self, vip, body=None): """Updates a load balancer vip.""" return self.put(self.vip_path % (vip), body=body) def delete_vip(self, vip): """Deletes the specified load balancer vip.""" return self.delete(self.vip_path % (vip)) def list_pools(self, retrieve_all=True, **_params): """Fetches a list of all load balancer pools for a project.""" # Pass filters in "params" argument to do_request return self.list('pools', self.pools_path, retrieve_all, **_params) def show_pool(self, pool, **_params): """Fetches information of a certain load balancer pool.""" return self.get(self.pool_path % (pool), params=_params) def create_pool(self, body=None): """Creates a new load balancer pool.""" return self.post(self.pools_path, body=body) def update_pool(self, pool, body=None): """Updates a load balancer pool.""" return self.put(self.pool_path % (pool), body=body) def delete_pool(self, pool): """Deletes the specified load balancer pool.""" return self.delete(self.pool_path % (pool)) def retrieve_pool_stats(self, pool, **_params): """Retrieves stats for a certain load balancer pool.""" return self.get(self.pool_path_stats % (pool), params=_params) def list_members(self, retrieve_all=True, **_params): """Fetches a list of all load balancer members for a project.""" # Pass filters in "params" argument to do_request return self.list('members', self.members_path, retrieve_all, **_params) def show_member(self, member, **_params): """Fetches information of a certain load balancer member.""" return self.get(self.member_path % (member), params=_params) def create_member(self, body=None): """Creates a new load balancer member.""" return self.post(self.members_path, body=body) def update_member(self, member, body=None): """Updates a load balancer member.""" return self.put(self.member_path % (member), body=body) def delete_member(self, member): """Deletes the specified load balancer member.""" return self.delete(self.member_path % (member)) def list_health_monitors(self, retrieve_all=True, **_params): """Fetches a list of all load balancer health monitors for a project. """ # Pass filters in "params" argument to do_request return self.list('health_monitors', self.health_monitors_path, retrieve_all, **_params) def show_health_monitor(self, health_monitor, **_params): """Fetches information of a certain load balancer health monitor.""" return self.get(self.health_monitor_path % (health_monitor), params=_params) def create_health_monitor(self, body=None): """Creates a new load balancer health monitor.""" return self.post(self.health_monitors_path, body=body) def update_health_monitor(self, health_monitor, body=None): """Updates a load balancer health monitor.""" return self.put(self.health_monitor_path % (health_monitor), body=body) def delete_health_monitor(self, health_monitor): """Deletes the specified load balancer health monitor.""" return self.delete(self.health_monitor_path % (health_monitor)) def associate_health_monitor(self, pool, body): """Associate specified load balancer health monitor and pool.""" return self.post(self.associate_pool_health_monitors_path % (pool), body=body) def disassociate_health_monitor(self, pool, health_monitor): """Disassociate specified load balancer health monitor and pool.""" path = (self.disassociate_pool_health_monitors_path % {'pool': pool, 'health_monitor': health_monitor}) return self.delete(path) def create_qos_queue(self, body=None): """Creates a new queue.""" return self.post(self.qos_queues_path, body=body) def list_qos_queues(self, **_params): """Fetches a list of all queues for a project.""" return self.get(self.qos_queues_path, params=_params) def show_qos_queue(self, queue, **_params): """Fetches information of a certain queue.""" return self.get(self.qos_queue_path % (queue), params=_params) def delete_qos_queue(self, queue): """Deletes the specified queue.""" return self.delete(self.qos_queue_path % (queue)) def list_agents(self, **_params): """Fetches agents.""" # Pass filters in "params" argument to do_request return self.get(self.agents_path, params=_params) def show_agent(self, agent, **_params): """Fetches information of a certain agent.""" return self.get(self.agent_path % (agent), params=_params) def update_agent(self, agent, body=None): """Updates an agent.""" return self.put(self.agent_path % (agent), body=body) def delete_agent(self, agent): """Deletes the specified agent.""" return self.delete(self.agent_path % (agent)) def list_network_gateways(self, **_params): """Retrieve network gateways.""" return self.get(self.network_gateways_path, params=_params) def show_network_gateway(self, gateway_id, **_params): """Fetch a network gateway.""" return self.get(self.network_gateway_path % gateway_id, params=_params) def create_network_gateway(self, body=None): """Create a new network gateway.""" return self.post(self.network_gateways_path, body=body) def update_network_gateway(self, gateway_id, body=None): """Update a network gateway.""" return self.put(self.network_gateway_path % gateway_id, body=body) def delete_network_gateway(self, gateway_id): """Delete the specified network gateway.""" return self.delete(self.network_gateway_path % gateway_id) def connect_network_gateway(self, gateway_id, body=None): """Connect a network gateway to the specified network.""" base_uri = self.network_gateway_path % gateway_id return self.put("%s/connect_network" % base_uri, body=body) def disconnect_network_gateway(self, gateway_id, body=None): """Disconnect a network from the specified gateway.""" base_uri = self.network_gateway_path % gateway_id return self.put("%s/disconnect_network" % base_uri, body=body) def list_gateway_devices(self, **_params): """Retrieve gateway devices.""" return self.get(self.gateway_devices_path, params=_params) def show_gateway_device(self, gateway_device_id, **_params): """Fetch a gateway device.""" return self.get(self.gateway_device_path % gateway_device_id, params=_params) def create_gateway_device(self, body=None): """Create a new gateway device.""" return self.post(self.gateway_devices_path, body=body) def update_gateway_device(self, gateway_device_id, body=None): """Updates a new gateway device.""" return self.put(self.gateway_device_path % gateway_device_id, body=body) def delete_gateway_device(self, gateway_device_id): """Delete the specified gateway device.""" return self.delete(self.gateway_device_path % gateway_device_id) def list_dhcp_agent_hosting_networks(self, network, **_params): """Fetches a list of dhcp agents hosting a network.""" return self.get((self.network_path + self.DHCP_AGENTS) % network, params=_params) def list_networks_on_dhcp_agent(self, dhcp_agent, **_params): """Fetches a list of dhcp agents hosting a network.""" return self.get((self.agent_path + self.DHCP_NETS) % dhcp_agent, params=_params) def add_network_to_dhcp_agent(self, dhcp_agent, body=None): """Adds a network to dhcp agent.""" return self.post((self.agent_path + self.DHCP_NETS) % dhcp_agent, body=body) def remove_network_from_dhcp_agent(self, dhcp_agent, network_id): """Remove a network from dhcp agent.""" return self.delete((self.agent_path + self.DHCP_NETS + "/%s") % ( dhcp_agent, network_id)) def list_l3_agent_hosting_routers(self, router, **_params): """Fetches a list of L3 agents hosting a router.""" return self.get((self.router_path + self.L3_AGENTS) % router, params=_params) def list_routers_on_l3_agent(self, l3_agent, **_params): """Fetches a list of L3 agents hosting a router.""" return self.get((self.agent_path + self.L3_ROUTERS) % l3_agent, params=_params) def add_router_to_l3_agent(self, l3_agent, body): """Adds a router to L3 agent.""" return self.post((self.agent_path + self.L3_ROUTERS) % l3_agent, body=body) def list_dragents_hosting_bgp_speaker(self, bgp_speaker, **_params): """Fetches a list of Dynamic Routing agents hosting a BGP speaker.""" return self.get((self.bgp_speaker_path + self.BGP_DRAGENTS) % bgp_speaker, params=_params) def add_bgp_speaker_to_dragent(self, bgp_dragent, body): """Adds a BGP speaker to Dynamic Routing agent.""" return self.post((self.agent_path + self.BGP_DRINSTANCES) % bgp_dragent, body=body) def remove_bgp_speaker_from_dragent(self, bgp_dragent, bgpspeaker_id): """Removes a BGP speaker from Dynamic Routing agent.""" return self.delete((self.agent_path + self.BGP_DRINSTANCES + "/%s") % (bgp_dragent, bgpspeaker_id)) def list_bgp_speaker_on_dragent(self, bgp_dragent, **_params): """Fetches a list of BGP speakers hosted by Dynamic Routing agent.""" return self.get((self.agent_path + self.BGP_DRINSTANCES) % bgp_dragent, params=_params) def list_firewall_rules(self, retrieve_all=True, **_params): """Fetches a list of all firewall rules for a project.""" # Pass filters in "params" argument to do_request return self.list('firewall_rules', self.firewall_rules_path, retrieve_all, **_params) def show_firewall_rule(self, firewall_rule, **_params): """Fetches information of a certain firewall rule.""" return self.get(self.firewall_rule_path % (firewall_rule), params=_params) def create_firewall_rule(self, body=None): """Creates a new firewall rule.""" return self.post(self.firewall_rules_path, body=body) def update_firewall_rule(self, firewall_rule, body=None): """Updates a firewall rule.""" return self.put(self.firewall_rule_path % (firewall_rule), body=body) def delete_firewall_rule(self, firewall_rule): """Deletes the specified firewall rule.""" return self.delete(self.firewall_rule_path % (firewall_rule)) def list_firewall_policies(self, retrieve_all=True, **_params): """Fetches a list of all firewall policies for a project.""" # Pass filters in "params" argument to do_request return self.list('firewall_policies', self.firewall_policies_path, retrieve_all, **_params) def show_firewall_policy(self, firewall_policy, **_params): """Fetches information of a certain firewall policy.""" return self.get(self.firewall_policy_path % (firewall_policy), params=_params) def create_firewall_policy(self, body=None): """Creates a new firewall policy.""" return self.post(self.firewall_policies_path, body=body) def update_firewall_policy(self, firewall_policy, body=None): """Updates a firewall policy.""" return self.put(self.firewall_policy_path % (firewall_policy), body=body) def delete_firewall_policy(self, firewall_policy): """Deletes the specified firewall policy.""" return self.delete(self.firewall_policy_path % (firewall_policy)) def firewall_policy_insert_rule(self, firewall_policy, body=None): """Inserts specified rule into firewall policy.""" return self.put(self.firewall_policy_insert_path % (firewall_policy), body=body) def firewall_policy_remove_rule(self, firewall_policy, body=None): """Removes specified rule from firewall policy.""" return self.put(self.firewall_policy_remove_path % (firewall_policy), body=body) def list_firewalls(self, retrieve_all=True, **_params): """Fetches a list of all firewalls for a project.""" # Pass filters in "params" argument to do_request return self.list('firewalls', self.firewalls_path, retrieve_all, **_params) def show_firewall(self, firewall, **_params): """Fetches information of a certain firewall.""" return self.get(self.firewall_path % (firewall), params=_params) def create_firewall(self, body=None): """Creates a new firewall.""" return self.post(self.firewalls_path, body=body) def update_firewall(self, firewall, body=None): """Updates a firewall.""" return self.put(self.firewall_path % (firewall), body=body) def delete_firewall(self, firewall): """Deletes the specified firewall.""" return self.delete(self.firewall_path % (firewall)) def list_fwaas_firewall_groups(self, retrieve_all=True, **_params): """Fetches a list of all firewall groups for a project""" return self.list('firewall_groups', self.fwaas_firewall_groups_path, retrieve_all, **_params) def show_fwaas_firewall_group(self, fwg, **_params): """Fetches information of a certain firewall group""" return self.get(self.fwaas_firewall_group_path % (fwg), params=_params) def create_fwaas_firewall_group(self, body=None): """Creates a new firewall group""" return self.post(self.fwaas_firewall_groups_path, body=body) def update_fwaas_firewall_group(self, fwg, body=None): """Updates a firewall group""" return self.put(self.fwaas_firewall_group_path % (fwg), body=body) def delete_fwaas_firewall_group(self, fwg): """Deletes the specified firewall group""" return self.delete(self.fwaas_firewall_group_path % (fwg)) def list_fwaas_firewall_rules(self, retrieve_all=True, **_params): """Fetches a list of all firewall rules for a project""" # Pass filters in "params" argument to do_request return self.list('firewall_rules', self.fwaas_firewall_rules_path, retrieve_all, **_params) def show_fwaas_firewall_rule(self, firewall_rule, **_params): """Fetches information of a certain firewall rule""" return self.get(self.fwaas_firewall_rule_path % (firewall_rule), params=_params) def create_fwaas_firewall_rule(self, body=None): """Creates a new firewall rule""" return self.post(self.fwaas_firewall_rules_path, body=body) def update_fwaas_firewall_rule(self, firewall_rule, body=None): """Updates a firewall rule""" return self.put(self.fwaas_firewall_rule_path % (firewall_rule), body=body) def delete_fwaas_firewall_rule(self, firewall_rule): """Deletes the specified firewall rule""" return self.delete(self.fwaas_firewall_rule_path % (firewall_rule)) def list_fwaas_firewall_policies(self, retrieve_all=True, **_params): """Fetches a list of all firewall policies for a project""" # Pass filters in "params" argument to do_request return self.list('firewall_policies', self.fwaas_firewall_policies_path, retrieve_all, **_params) def show_fwaas_firewall_policy(self, firewall_policy, **_params): """Fetches information of a certain firewall policy""" return self.get(self.fwaas_firewall_policy_path % (firewall_policy), params=_params) def create_fwaas_firewall_policy(self, body=None): """Creates a new firewall policy""" return self.post(self.fwaas_firewall_policies_path, body=body) def update_fwaas_firewall_policy(self, firewall_policy, body=None): """Updates a firewall policy""" return self.put(self.fwaas_firewall_policy_path % (firewall_policy), body=body) def delete_fwaas_firewall_policy(self, firewall_policy): """Deletes the specified firewall policy""" return self.delete(self.fwaas_firewall_policy_path % (firewall_policy)) def insert_rule_fwaas_firewall_policy(self, firewall_policy, body=None): """Inserts specified rule into firewall policy""" return self.put((self.fwaas_firewall_policy_insert_path % (firewall_policy)), body=body) def remove_rule_fwaas_firewall_policy(self, firewall_policy, body=None): """Removes specified rule from firewall policy""" return self.put((self.fwaas_firewall_policy_remove_path % (firewall_policy)), body=body) def remove_router_from_l3_agent(self, l3_agent, router_id): """Remove a router from l3 agent.""" return self.delete((self.agent_path + self.L3_ROUTERS + "/%s") % ( l3_agent, router_id)) def get_lbaas_agent_hosting_pool(self, pool, **_params): """Fetches a loadbalancer agent hosting a pool.""" return self.get((self.pool_path + self.LOADBALANCER_AGENT) % pool, params=_params) def list_pools_on_lbaas_agent(self, lbaas_agent, **_params): """Fetches a list of pools hosted by the loadbalancer agent.""" return self.get((self.agent_path + self.LOADBALANCER_POOLS) % lbaas_agent, params=_params) def get_lbaas_agent_hosting_loadbalancer(self, loadbalancer, **_params): """Fetches a loadbalancer agent hosting a loadbalancer.""" return self.get((self.lbaas_loadbalancer_path + self.LOADBALANCER_HOSTING_AGENT) % loadbalancer, params=_params) def list_loadbalancers_on_lbaas_agent(self, lbaas_agent, **_params): """Fetches a list of loadbalancers hosted by the loadbalancer agent.""" return self.get((self.agent_path + self.AGENT_LOADBALANCERS) % lbaas_agent, params=_params) def list_service_providers(self, retrieve_all=True, **_params): """Fetches service providers.""" # Pass filters in "params" argument to do_request return self.list('service_providers', self.service_providers_path, retrieve_all, **_params) def create_metering_label(self, body=None): """Creates a metering label.""" return self.post(self.metering_labels_path, body=body) def delete_metering_label(self, label): """Deletes the specified metering label.""" return self.delete(self.metering_label_path % (label)) def list_metering_labels(self, retrieve_all=True, **_params): """Fetches a list of all metering labels for a project.""" return self.list('metering_labels', self.metering_labels_path, retrieve_all, **_params) def show_metering_label(self, metering_label, **_params): """Fetches information of a certain metering label.""" return self.get(self.metering_label_path % (metering_label), params=_params) def create_metering_label_rule(self, body=None): """Creates a metering label rule.""" return self.post(self.metering_label_rules_path, body=body) def delete_metering_label_rule(self, rule): """Deletes the specified metering label rule.""" return self.delete(self.metering_label_rule_path % (rule)) def list_metering_label_rules(self, retrieve_all=True, **_params): """Fetches a list of all metering label rules for a label.""" return self.list('metering_label_rules', self.metering_label_rules_path, retrieve_all, **_params) def show_metering_label_rule(self, metering_label_rule, **_params): """Fetches information of a certain metering label rule.""" return self.get(self.metering_label_rule_path % (metering_label_rule), params=_params) def create_rbac_policy(self, body=None): """Create a new RBAC policy.""" return self.post(self.rbac_policies_path, body=body) def update_rbac_policy(self, rbac_policy_id, body=None): """Update a RBAC policy.""" return self.put(self.rbac_policy_path % rbac_policy_id, body=body) def list_rbac_policies(self, retrieve_all=True, **_params): """Fetch a list of all RBAC policies for a project.""" return self.list('rbac_policies', self.rbac_policies_path, retrieve_all, **_params) def show_rbac_policy(self, rbac_policy_id, **_params): """Fetch information of a certain RBAC policy.""" return self.get(self.rbac_policy_path % rbac_policy_id, params=_params) def delete_rbac_policy(self, rbac_policy_id): """Delete the specified RBAC policy.""" return self.delete(self.rbac_policy_path % rbac_policy_id) def list_qos_policies(self, retrieve_all=True, **_params): """Fetches a list of all qos policies for a project.""" # Pass filters in "params" argument to do_request return self.list('policies', self.qos_policies_path, retrieve_all, **_params) def show_qos_policy(self, qos_policy, **_params): """Fetches information of a certain qos policy.""" return self.get(self.qos_policy_path % qos_policy, params=_params) def create_qos_policy(self, body=None): """Creates a new qos policy.""" return self.post(self.qos_policies_path, body=body) def update_qos_policy(self, qos_policy, body=None, revision_number=None): """Updates a qos policy.""" return self._update_resource(self.qos_policy_path % qos_policy, body=body, revision_number=revision_number) def delete_qos_policy(self, qos_policy): """Deletes the specified qos policy.""" return self.delete(self.qos_policy_path % qos_policy) def list_qos_rule_types(self, retrieve_all=True, **_params): """List available qos rule types.""" return self.list('rule_types', self.qos_rule_types_path, retrieve_all, **_params) def list_bandwidth_limit_rules(self, policy_id, retrieve_all=True, **_params): """Fetches a list of all bandwidth limit rules for the given policy.""" return self.list('bandwidth_limit_rules', self.qos_bandwidth_limit_rules_path % policy_id, retrieve_all, **_params) def show_bandwidth_limit_rule(self, rule, policy, **_params): """Fetches information of a certain bandwidth limit rule.""" return self.get(self.qos_bandwidth_limit_rule_path % (policy, rule), params=_params) def create_bandwidth_limit_rule(self, policy, body=None): """Creates a new bandwidth limit rule.""" return self.post(self.qos_bandwidth_limit_rules_path % policy, body=body) def update_bandwidth_limit_rule(self, rule, policy, body=None): """Updates a bandwidth limit rule.""" return self.put(self.qos_bandwidth_limit_rule_path % (policy, rule), body=body) def delete_bandwidth_limit_rule(self, rule, policy): """Deletes a bandwidth limit rule.""" return self.delete(self.qos_bandwidth_limit_rule_path % (policy, rule)) def list_dscp_marking_rules(self, policy_id, retrieve_all=True, **_params): """Fetches a list of all DSCP marking rules for the given policy.""" return self.list('dscp_marking_rules', self.qos_dscp_marking_rules_path % policy_id, retrieve_all, **_params) def show_dscp_marking_rule(self, rule, policy, **_params): """Shows information of a certain DSCP marking rule.""" return self.get(self.qos_dscp_marking_rule_path % (policy, rule), params=_params) def create_dscp_marking_rule(self, policy, body=None): """Creates a new DSCP marking rule.""" return self.post(self.qos_dscp_marking_rules_path % policy, body=body) def update_dscp_marking_rule(self, rule, policy, body=None): """Updates a DSCP marking rule.""" return self.put(self.qos_dscp_marking_rule_path % (policy, rule), body=body) def delete_dscp_marking_rule(self, rule, policy): """Deletes a DSCP marking rule.""" return self.delete(self.qos_dscp_marking_rule_path % (policy, rule)) def list_minimum_bandwidth_rules(self, policy_id, retrieve_all=True, **_params): """Fetches a list of all minimum bandwidth rules for the given policy. """ return self.list('minimum_bandwidth_rules', self.qos_minimum_bandwidth_rules_path % policy_id, retrieve_all, **_params) def show_minimum_bandwidth_rule(self, rule, policy, body=None): """Fetches information of a certain minimum bandwidth rule.""" return self.get(self.qos_minimum_bandwidth_rule_path % (policy, rule), body=body) def create_minimum_bandwidth_rule(self, policy, body=None): """Creates a new minimum bandwidth rule.""" return self.post(self.qos_minimum_bandwidth_rules_path % policy, body=body) def update_minimum_bandwidth_rule(self, rule, policy, body=None): """Updates a minimum bandwidth rule.""" return self.put(self.qos_minimum_bandwidth_rule_path % (policy, rule), body=body) def delete_minimum_bandwidth_rule(self, rule, policy): """Deletes a minimum bandwidth rule.""" return self.delete(self.qos_minimum_bandwidth_rule_path % (policy, rule)) def create_flavor(self, body=None): """Creates a new Neutron service flavor.""" return self.post(self.flavors_path, body=body) def delete_flavor(self, flavor): """Deletes the specified Neutron service flavor.""" return self.delete(self.flavor_path % (flavor)) def list_flavors(self, retrieve_all=True, **_params): """Fetches a list of all Neutron service flavors for a project.""" return self.list('flavors', self.flavors_path, retrieve_all, **_params) def show_flavor(self, flavor, **_params): """Fetches information for a certain Neutron service flavor.""" return self.get(self.flavor_path % (flavor), params=_params) def update_flavor(self, flavor, body): """Update a Neutron service flavor.""" return self.put(self.flavor_path % (flavor), body=body) def associate_flavor(self, flavor, body): """Associate a Neutron service flavor with a profile.""" return self.post(self.flavor_profile_bindings_path % (flavor), body=body) def disassociate_flavor(self, flavor, flavor_profile): """Disassociate a Neutron service flavor with a profile.""" return self.delete(self.flavor_profile_binding_path % (flavor, flavor_profile)) def create_service_profile(self, body=None): """Creates a new Neutron service flavor profile.""" return self.post(self.service_profiles_path, body=body) def delete_service_profile(self, flavor_profile): """Deletes the specified Neutron service flavor profile.""" return self.delete(self.service_profile_path % (flavor_profile)) def list_service_profiles(self, retrieve_all=True, **_params): """Fetches a list of all Neutron service flavor profiles.""" return self.list('service_profiles', self.service_profiles_path, retrieve_all, **_params) def show_service_profile(self, flavor_profile, **_params): """Fetches information for a certain Neutron service flavor profile.""" return self.get(self.service_profile_path % (flavor_profile), params=_params) def update_service_profile(self, service_profile, body): """Update a Neutron service profile.""" return self.put(self.service_profile_path % (service_profile), body=body) def list_availability_zones(self, retrieve_all=True, **_params): """Fetches a list of all availability zones.""" return self.list('availability_zones', self.availability_zones_path, retrieve_all, **_params) @debtcollector.renames.renamed_kwarg( 'tenant_id', 'project_id', replace=True) def get_auto_allocated_topology(self, project_id, **_params): """Fetch information about a project's auto-allocated topology.""" return self.get( self.auto_allocated_topology_path % project_id, params=_params) @debtcollector.renames.renamed_kwarg( 'tenant_id', 'project_id', replace=True) def delete_auto_allocated_topology(self, project_id, **_params): """Delete a project's auto-allocated topology.""" return self.delete( self.auto_allocated_topology_path % project_id, params=_params) @debtcollector.renames.renamed_kwarg( 'tenant_id', 'project_id', replace=True) def validate_auto_allocated_topology_requirements(self, project_id): """Validate requirements for getting an auto-allocated topology.""" return self.get_auto_allocated_topology(project_id, fields=['dry-run']) def list_bgp_speakers(self, retrieve_all=True, **_params): """Fetches a list of all BGP speakers for a project.""" return self.list('bgp_speakers', self.bgp_speakers_path, retrieve_all, **_params) def show_bgp_speaker(self, bgp_speaker_id, **_params): """Fetches information of a certain BGP speaker.""" return self.get(self.bgp_speaker_path % (bgp_speaker_id), params=_params) def create_bgp_speaker(self, body=None): """Creates a new BGP speaker.""" return self.post(self.bgp_speakers_path, body=body) def update_bgp_speaker(self, bgp_speaker_id, body=None): """Update a BGP speaker.""" return self.put(self.bgp_speaker_path % bgp_speaker_id, body=body) def delete_bgp_speaker(self, speaker_id): """Deletes the specified BGP speaker.""" return self.delete(self.bgp_speaker_path % (speaker_id)) def add_peer_to_bgp_speaker(self, speaker_id, body=None): """Adds a peer to BGP speaker.""" return self.put((self.bgp_speaker_path % speaker_id) + "/add_bgp_peer", body=body) def remove_peer_from_bgp_speaker(self, speaker_id, body=None): """Removes a peer from BGP speaker.""" return self.put((self.bgp_speaker_path % speaker_id) + "/remove_bgp_peer", body=body) def add_network_to_bgp_speaker(self, speaker_id, body=None): """Adds a network to BGP speaker.""" return self.put((self.bgp_speaker_path % speaker_id) + "/add_gateway_network", body=body) def remove_network_from_bgp_speaker(self, speaker_id, body=None): """Removes a network from BGP speaker.""" return self.put((self.bgp_speaker_path % speaker_id) + "/remove_gateway_network", body=body) def list_route_advertised_from_bgp_speaker(self, speaker_id, **_params): """Fetches a list of all routes advertised by BGP speaker.""" return self.get((self.bgp_speaker_path % speaker_id) + "/get_advertised_routes", params=_params) def list_bgp_peers(self, **_params): """Fetches a list of all BGP peers.""" return self.get(self.bgp_peers_path, params=_params) def show_bgp_peer(self, peer_id, **_params): """Fetches information of a certain BGP peer.""" return self.get(self.bgp_peer_path % peer_id, params=_params) def create_bgp_peer(self, body=None): """Create a new BGP peer.""" return self.post(self.bgp_peers_path, body=body) def update_bgp_peer(self, bgp_peer_id, body=None): """Update a BGP peer.""" return self.put(self.bgp_peer_path % bgp_peer_id, body=body) def delete_bgp_peer(self, peer_id): """Deletes the specified BGP peer.""" return self.delete(self.bgp_peer_path % peer_id) def list_network_ip_availabilities(self, retrieve_all=True, **_params): """Fetches IP availability information for all networks""" return self.list('network_ip_availabilities', self.network_ip_availabilities_path, retrieve_all, **_params) def show_network_ip_availability(self, network, **_params): """Fetches IP availability information for a specified network""" return self.get(self.network_ip_availability_path % (network), params=_params) def add_tag(self, resource_type, resource_id, tag, **_params): """Add a tag on the resource.""" return self.put(self.tag_path % (resource_type, resource_id, tag)) def replace_tag(self, resource_type, resource_id, body, **_params): """Replace tags on the resource.""" return self.put(self.tags_path % (resource_type, resource_id), body) def remove_tag(self, resource_type, resource_id, tag, **_params): """Remove a tag on the resource.""" return self.delete(self.tag_path % (resource_type, resource_id, tag)) def remove_tag_all(self, resource_type, resource_id, **_params): """Remove all tags on the resource.""" return self.delete(self.tags_path % (resource_type, resource_id)) def create_trunk(self, body=None): """Create a trunk port.""" return self.post(self.trunks_path, body=body) def update_trunk(self, trunk, body=None, revision_number=None): """Update a trunk port.""" return self._update_resource(self.trunk_path % trunk, body=body, revision_number=revision_number) def delete_trunk(self, trunk): """Delete a trunk port.""" return self.delete(self.trunk_path % (trunk)) def list_trunks(self, retrieve_all=True, **_params): """Fetch a list of all trunk ports.""" return self.list('trunks', self.trunks_path, retrieve_all, **_params) def show_trunk(self, trunk, **_params): """Fetch information for a certain trunk port.""" return self.get(self.trunk_path % (trunk), params=_params) def trunk_add_subports(self, trunk, body=None): """Add specified subports to the trunk.""" return self.put(self.subports_add_path % (trunk), body=body) def trunk_remove_subports(self, trunk, body=None): """Removes specified subports from the trunk.""" return self.put(self.subports_remove_path % (trunk), body=body) def trunk_get_subports(self, trunk, **_params): """Fetch a list of all subports attached to given trunk.""" return self.get(self.subports_path % (trunk), params=_params) def list_bgpvpns(self, retrieve_all=True, **_params): """Fetches a list of all BGP VPNs for a project""" return self.list('bgpvpns', self.bgpvpns_path, retrieve_all, **_params) def show_bgpvpn(self, bgpvpn, **_params): """Fetches information of a certain BGP VPN""" return self.get(self.bgpvpn_path % bgpvpn, params=_params) def create_bgpvpn(self, body=None): """Creates a new BGP VPN""" return self.post(self.bgpvpns_path, body=body) def update_bgpvpn(self, bgpvpn, body=None): """Updates a BGP VPN""" return self.put(self.bgpvpn_path % bgpvpn, body=body) def delete_bgpvpn(self, bgpvpn): """Deletes the specified BGP VPN""" return self.delete(self.bgpvpn_path % bgpvpn) def list_bgpvpn_network_assocs(self, bgpvpn, retrieve_all=True, **_params): """Fetches a list of network associations for a given BGP VPN.""" return self.list('network_associations', self.bgpvpn_network_associations_path % bgpvpn, retrieve_all, **_params) def show_bgpvpn_network_assoc(self, bgpvpn, net_assoc, **_params): """Fetches information of a certain BGP VPN's network association""" return self.get( self.bgpvpn_network_association_path % (bgpvpn, net_assoc), params=_params) def create_bgpvpn_network_assoc(self, bgpvpn, body=None): """Creates a new BGP VPN network association""" return self.post(self.bgpvpn_network_associations_path % bgpvpn, body=body) def update_bgpvpn_network_assoc(self, bgpvpn, net_assoc, body=None): """Updates a BGP VPN network association""" return self.put( self.bgpvpn_network_association_path % (bgpvpn, net_assoc), body=body) def delete_bgpvpn_network_assoc(self, bgpvpn, net_assoc): """Deletes the specified BGP VPN network association""" return self.delete( self.bgpvpn_network_association_path % (bgpvpn, net_assoc)) def list_bgpvpn_router_assocs(self, bgpvpn, retrieve_all=True, **_params): """Fetches a list of router associations for a given BGP VPN.""" return self.list('router_associations', self.bgpvpn_router_associations_path % bgpvpn, retrieve_all, **_params) def show_bgpvpn_router_assoc(self, bgpvpn, router_assoc, **_params): """Fetches information of a certain BGP VPN's router association""" return self.get( self.bgpvpn_router_association_path % (bgpvpn, router_assoc), params=_params) def create_bgpvpn_router_assoc(self, bgpvpn, body=None): """Creates a new BGP VPN router association""" return self.post(self.bgpvpn_router_associations_path % bgpvpn, body=body) def update_bgpvpn_router_assoc(self, bgpvpn, router_assoc, body=None): """Updates a BGP VPN router association""" return self.put( self.bgpvpn_router_association_path % (bgpvpn, router_assoc), body=body) def delete_bgpvpn_router_assoc(self, bgpvpn, router_assoc): """Deletes the specified BGP VPN router association""" return self.delete( self.bgpvpn_router_association_path % (bgpvpn, router_assoc)) def list_bgpvpn_port_assocs(self, bgpvpn, retrieve_all=True, **_params): """Fetches a list of port associations for a given BGP VPN.""" return self.list('port_associations', self.bgpvpn_port_associations_path % bgpvpn, retrieve_all, **_params) def show_bgpvpn_port_assoc(self, bgpvpn, port_assoc, **_params): """Fetches information of a certain BGP VPN's port association""" return self.get( self.bgpvpn_port_association_path % (bgpvpn, port_assoc), params=_params) def create_bgpvpn_port_assoc(self, bgpvpn, body=None): """Creates a new BGP VPN port association""" return self.post(self.bgpvpn_port_associations_path % bgpvpn, body=body) def update_bgpvpn_port_assoc(self, bgpvpn, port_assoc, body=None): """Updates a BGP VPN port association""" return self.put( self.bgpvpn_port_association_path % (bgpvpn, port_assoc), body=body) def delete_bgpvpn_port_assoc(self, bgpvpn, port_assoc): """Deletes the specified BGP VPN port association""" return self.delete( self.bgpvpn_port_association_path % (bgpvpn, port_assoc)) def create_sfc_port_pair(self, body=None): """Creates a new Port Pair.""" return self.post(self.sfc_port_pairs_path, body=body) def update_sfc_port_pair(self, port_pair, body=None): """Update a Port Pair.""" return self.put(self.sfc_port_pair_path % port_pair, body=body) def delete_sfc_port_pair(self, port_pair): """Deletes the specified Port Pair.""" return self.delete(self.sfc_port_pair_path % (port_pair)) def list_sfc_port_pairs(self, retrieve_all=True, **_params): """Fetches a list of all Port Pairs.""" return self.list('port_pairs', self.sfc_port_pairs_path, retrieve_all, **_params) def show_sfc_port_pair(self, port_pair, **_params): """Fetches information of a certain Port Pair.""" return self.get(self.sfc_port_pair_path % (port_pair), params=_params) def create_sfc_port_pair_group(self, body=None): """Creates a new Port Pair Group.""" return self.post(self.sfc_port_pair_groups_path, body=body) def update_sfc_port_pair_group(self, port_pair_group, body=None): """Update a Port Pair Group.""" return self.put(self.sfc_port_pair_group_path % port_pair_group, body=body) def delete_sfc_port_pair_group(self, port_pair_group): """Deletes the specified Port Pair Group.""" return self.delete(self.sfc_port_pair_group_path % (port_pair_group)) def list_sfc_port_pair_groups(self, retrieve_all=True, **_params): """Fetches a list of all Port Pair Groups.""" return self.list('port_pair_groups', self.sfc_port_pair_groups_path, retrieve_all, **_params) def show_sfc_port_pair_group(self, port_pair_group, **_params): """Fetches information of a certain Port Pair Group.""" return self.get(self.sfc_port_pair_group_path % (port_pair_group), params=_params) def create_sfc_port_chain(self, body=None): """Creates a new Port Chain.""" return self.post(self.sfc_port_chains_path, body=body) def update_sfc_port_chain(self, port_chain, body=None): """Update a Port Chain.""" return self.put(self.sfc_port_chain_path % port_chain, body=body) def delete_sfc_port_chain(self, port_chain): """Deletes the specified Port Chain.""" return self.delete(self.sfc_port_chain_path % (port_chain)) def list_sfc_port_chains(self, retrieve_all=True, **_params): """Fetches a list of all Port Chains.""" return self.list('port_chains', self.sfc_port_chains_path, retrieve_all, **_params) def show_sfc_port_chain(self, port_chain, **_params): """Fetches information of a certain Port Chain.""" return self.get(self.sfc_port_chain_path % (port_chain), params=_params) def create_sfc_flow_classifier(self, body=None): """Creates a new Flow Classifier.""" return self.post(self.sfc_flow_classifiers_path, body=body) def update_sfc_flow_classifier(self, flow_classifier, body=None): """Update a Flow Classifier.""" return self.put(self.sfc_flow_classifier_path % flow_classifier, body=body) def delete_sfc_flow_classifier(self, flow_classifier): """Deletes the specified Flow Classifier.""" return self.delete(self.sfc_flow_classifier_path % (flow_classifier)) def list_sfc_flow_classifiers(self, retrieve_all=True, **_params): """Fetches a list of all Flow Classifiers.""" return self.list('flow_classifiers', self.sfc_flow_classifiers_path, retrieve_all, **_params) def show_sfc_flow_classifier(self, flow_classifier, **_params): """Fetches information of a certain Flow Classifier.""" return self.get(self.sfc_flow_classifier_path % (flow_classifier), params=_params) def create_sfc_service_graph(self, body=None): """Create the specified Service Graph.""" return self.post(self.sfc_service_graphs_path, body=body) def update_sfc_service_graph(self, service_graph, body=None): """Update a Service Graph.""" return self.put(self.sfc_service_graph_path % service_graph, body=body) def delete_sfc_service_graph(self, service_graph): """Deletes the specified Service Graph.""" return self.delete(self.sfc_service_graph_path % service_graph) def list_sfc_service_graphs(self, retrieve_all=True, **_params): """Fetches a list of all Service Graphs.""" return self.list('service_graphs', self.sfc_service_graphs_path, retrieve_all, **_params) def show_sfc_service_graph(self, service_graph, **_params): """Fetches information of a certain Service Graph.""" return self.get(self.sfc_service_graph_path % service_graph, params=_params) def create_network_log(self, body=None): """Create a network log.""" return self.post(self.network_logs_path, body=body) def delete_network_log(self, net_log): """Delete a network log.""" return self.delete(self.network_log_path % net_log) def list_network_logs(self, retrieve_all=True, **_params): """Fetch a list of all network logs.""" return self.list( 'logs', self.network_logs_path, retrieve_all, **_params) def show_network_log(self, net_log, **_params): """Fetch information for a certain network log.""" return self.get(self.network_log_path % net_log, params=_params) def update_network_log(self, net_log, body=None): """Update a network log.""" return self.put(self.network_log_path % net_log, body=body) def list_network_loggable_resources(self, retrieve_all=True, **_params): """Fetch a list of supported resource types for network log.""" return self.list('loggable_resources', self.network_loggables_path, retrieve_all, **_params) def __init__(self, **kwargs): """Initialize a new client for the Neutron v2.0 API.""" super(Client, self).__init__(**kwargs) self._register_extensions(self.version) def _update_resource(self, path, **kwargs): revision_number = kwargs.pop('revision_number', None) if revision_number: headers = kwargs.setdefault('headers', {}) headers['If-Match'] = 'revision_number=%s' % revision_number return self.put(path, **kwargs) def extend_show(self, resource_singular, path, parent_resource): def _fx(obj, **_params): return self.show_ext(path, obj, **_params) def _parent_fx(obj, parent_id, **_params): return self.show_ext(path % parent_id, obj, **_params) fn = _fx if not parent_resource else _parent_fx setattr(self, "show_%s" % resource_singular, fn) def extend_list(self, resource_plural, path, parent_resource): def _fx(retrieve_all=True, **_params): return self.list_ext(resource_plural, path, retrieve_all, **_params) def _parent_fx(parent_id, retrieve_all=True, **_params): return self.list_ext(resource_plural, path % parent_id, retrieve_all, **_params) fn = _fx if not parent_resource else _parent_fx setattr(self, "list_%s" % resource_plural, fn) def extend_create(self, resource_singular, path, parent_resource): def _fx(body=None): return self.create_ext(path, body) def _parent_fx(parent_id, body=None): return self.create_ext(path % parent_id, body) fn = _fx if not parent_resource else _parent_fx setattr(self, "create_%s" % resource_singular, fn) def extend_delete(self, resource_singular, path, parent_resource): def _fx(obj): return self.delete_ext(path, obj) def _parent_fx(obj, parent_id): return self.delete_ext(path % parent_id, obj) fn = _fx if not parent_resource else _parent_fx setattr(self, "delete_%s" % resource_singular, fn) def extend_update(self, resource_singular, path, parent_resource): def _fx(obj, body=None): return self.update_ext(path, obj, body) def _parent_fx(obj, parent_id, body=None): return self.update_ext(path % parent_id, obj, body) fn = _fx if not parent_resource else _parent_fx setattr(self, "update_%s" % resource_singular, fn) def _extend_client_with_module(self, module, version): classes = inspect.getmembers(module, inspect.isclass) for cls_name, cls in classes: if hasattr(cls, 'versions'): if version not in cls.versions: continue parent_resource = getattr(cls, 'parent_resource', None) if issubclass(cls, client_extension.ClientExtensionList): self.extend_list(cls.resource_plural, cls.object_path, parent_resource) elif issubclass(cls, client_extension.ClientExtensionCreate): self.extend_create(cls.resource, cls.object_path, parent_resource) elif issubclass(cls, client_extension.ClientExtensionUpdate): self.extend_update(cls.resource, cls.resource_path, parent_resource) elif issubclass(cls, client_extension.ClientExtensionDelete): self.extend_delete(cls.resource, cls.resource_path, parent_resource) elif issubclass(cls, client_extension.ClientExtensionShow): self.extend_show(cls.resource, cls.resource_path, parent_resource) elif issubclass(cls, client_extension.NeutronClientExtension): setattr(self, "%s_path" % cls.resource_plural, cls.object_path) setattr(self, "%s_path" % cls.resource, cls.resource_path) self.EXTED_PLURALS.update({cls.resource_plural: cls.resource}) def _register_extensions(self, version): for name, module in itertools.chain( client_extension._discover_via_entry_points()): self._extend_client_with_module(module, version) python-neutronclient-6.7.0/neutronclient/v2_0/__init__.py0000666000175100017510000000000013232473350023522 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/0000775000175100017510000000000013232473710021437 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/utils.py0000666000175100017510000001647713232473350023172 0ustar zuulzuul00000000000000# Copyright 2016 NEC Corporation # # 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. """This module should contain OSC plugin generic methods. Methods in this module are candidates adopted to osc-lib. Stuffs specific to neutronclient OSC plugin should not be added to this module. They should go to neutronclient.osc.v2.utils. """ import operator from keystoneclient import exceptions as identity_exc from keystoneclient.v3 import domains from keystoneclient.v3 import projects from osc_lib import utils from neutronclient._i18n import _ LIST_BOTH = 'both' LIST_SHORT_ONLY = 'short_only' LIST_LONG_ONLY = 'long_only' def get_column_definitions(attr_map, long_listing): """Return table headers and column names for a listing table. :param attr_map: a list of table entry definitions. Each entry should be a tuple consisting of (API attribute name, header name, listing mode). For example: (('id', 'ID', LIST_BOTH), ('name', 'Name', LIST_BOTH), ('tenant_id', 'Project', LIST_LONG_ONLY)) The third field of each tuple must be one of LIST_BOTH, LIST_LONG_ONLY (a corresponding column is shown only in a long mode), or LIST_SHORT_ONLY (a corresponding column is shown only in a short mode). :param long_listing: A boolean value which indicates a long listing or not. In most cases, parsed_args.long is passed to this argument. :return: A tuple of a list of table headers and a list of column names. """ if long_listing: headers = [hdr for col, hdr, listing_mode in attr_map if listing_mode in (LIST_BOTH, LIST_LONG_ONLY)] columns = [col for col, hdr, listing_mode in attr_map if listing_mode in (LIST_BOTH, LIST_LONG_ONLY)] else: headers = [hdr for col, hdr, listing_mode in attr_map if listing_mode if listing_mode in (LIST_BOTH, LIST_SHORT_ONLY)] columns = [col for col, hdr, listing_mode in attr_map if listing_mode if listing_mode in (LIST_BOTH, LIST_SHORT_ONLY)] return headers, columns def get_columns(item, attr_map=None): """Return pair of resource attributes and corresponding display names. Assume the following item and attr_map are passed. item: {'id': 'myid', 'name': 'myname', 'foo': 'bar', 'tenant_id': 'mytenan'} attr_map: (('id', 'ID', LIST_BOTH), ('name', 'Name', LIST_BOTH), ('tenant_id', 'Project', LIST_LONG_ONLY)) This method returns: (('id', 'name', 'tenant_id', 'foo'), # attributes ('ID', 'Name', 'Project', 'foo') # display names Both tuples of attributes and display names are sorted by display names in the alphabetical order. Attributes not found in a given attr_map are kept as-is. :param item: a dictionary which represents a resource. Keys of the dictionary are expected to be attributes of the resource. Values are not referred to by this method. :param attr_map: a list of mapping from attribute to display name. The same format is used as for get_column_definitions attr_map. :return: A pair of tuple of attributes and tuple of display names. """ attr_map = attr_map or tuple([]) _attr_map_dict = dict((col, hdr) for col, hdr, listing_mode in attr_map) columns = [(column, _attr_map_dict.get(column, column)) for column in item.keys()] columns = sorted(columns, key=operator.itemgetter(1)) return (tuple(col[0] for col in columns), tuple(col[1] for col in columns)) # TODO(amotoki): Use osc-lib version once osc-lib provides this. def add_project_owner_option_to_parser(parser): """Register project and project domain options. :param parser: argparse.Argument parser object. """ parser.add_argument( '--project', metavar='', help=_("Owner's project (name or ID)") ) # Borrowed from openstackclient.identity.common # as it is not exposed officially. parser.add_argument( '--project-domain', metavar='', help=_('Domain the project belongs to (name or ID). ' 'This can be used in case collisions between project names ' 'exist.'), ) # The following methods are borrowed from openstackclient.identity.common # as it is not exposed officially. # TODO(amotoki): Use osc-lib version once osc-lib provides this. def find_domain(identity_client, name_or_id): return _find_identity_resource(identity_client.domains, name_or_id, domains.Domain) def find_project(identity_client, name_or_id, domain_name_or_id=None): domain_id = _get_domain_id_if_requested(identity_client, domain_name_or_id) if not domain_id: return _find_identity_resource(identity_client.projects, name_or_id, projects.Project) else: return _find_identity_resource(identity_client.projects, name_or_id, projects.Project, domain_id=domain_id) def _get_domain_id_if_requested(identity_client, domain_name_or_id): if not domain_name_or_id: return None domain = find_domain(identity_client, domain_name_or_id) return domain.id def _find_identity_resource(identity_client_manager, name_or_id, resource_type, **kwargs): """Find a specific identity resource. Using keystoneclient's manager, attempt to find a specific resource by its name or ID. If Forbidden to find the resource (a common case if the user does not have permission), then return the resource by creating a local instance of keystoneclient's Resource. The parameter identity_client_manager is a keystoneclient manager, for example: keystoneclient.v3.users or keystoneclient.v3.projects. The parameter resource_type is a keystoneclient resource, for example: keystoneclient.v3.users.User or keystoneclient.v3.projects.Project. :param identity_client_manager: the manager that contains the resource :type identity_client_manager: `keystoneclient.base.CrudManager` :param name_or_id: the resources's name or ID :type name_or_id: string :param resource_type: class that represents the resource type :type resource_type: `keystoneclient.base.Resource` :returns: the resource in question :rtype: `keystoneclient.base.Resource` """ try: identity_resource = utils.find_resource(identity_client_manager, name_or_id, **kwargs) if identity_resource is not None: return identity_resource except identity_exc.Forbidden: pass return resource_type(None, {'id': name_or_id, 'name': name_or_id}) # The above are borrowed from openstackclient.identity.common. # DO NOT ADD original methods in neutronclient repo to the above area. python-neutronclient-6.7.0/neutronclient/osc/plugin.py0000666000175100017510000000427213232473350023316 0ustar zuulzuul00000000000000# 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. # """OpenStackClient plugin for advanced Networking service.""" import logging # TODO(rtheis/amotoki): Add functional test infrastructure for OSC # plugin commands. # TODO(amotoki): Add and update document on OSC plugin. from osc_lib import utils LOG = logging.getLogger(__name__) DEFAULT_API_VERSION = '2.0' API_VERSION_OPTION = 'os_network_api_version' # NOTE(rtheis): API_NAME must NOT be set to 'network' since # 'network' is owned by OSC! The OSC 'network' client uses # the OpenStack SDK. API_NAME = 'neutronclient' API_VERSIONS = { '2.0': 'neutronclient.v2_0.client.Client', '2': 'neutronclient.v2_0.client.Client', } def make_client(instance): """Returns an neutron client.""" neutron_client = utils.get_client_class( API_NAME, instance._api_version[API_NAME], API_VERSIONS) LOG.debug('Instantiating neutron client: %s', neutron_client) # TODO(amotoki): Check the following arguments need to be passed # to neutronclient class. Check keystoneauth code. # - endpoint_type (do we need to specify it explicitly?) # - auth (session object contains auth. Is it required?) client = neutron_client(session=instance.session, region_name=instance.region_name, endpoint_type=instance.interface, insecure=not instance.verify, ca_cert=instance.cacert) return client def build_option_parser(parser): """Hook to add global options""" # NOTE(amotoki): At now we register no option. # OSC itself has an option for Network API version # and we refer to it. return parser python-neutronclient-6.7.0/neutronclient/osc/v2/0000775000175100017510000000000013232473710021766 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/utils.py0000666000175100017510000000157013232473350023505 0ustar zuulzuul00000000000000# Copyright 2016 NEC Corporation # # 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. """This module is intended to contain methods specific to Networking v2 API and its extensions. """ from cliff import columns as cliff_columns class AdminStateColumn(cliff_columns.FormattableColumn): def human_readable(self): return 'UP' if self._value else 'DOWN' python-neutronclient-6.7.0/neutronclient/osc/v2/logging/0000775000175100017510000000000013232473710023414 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/logging/network_log.py0000666000175100017510000002522313232473350026326 0ustar zuulzuul00000000000000# Copyright 2017 FUJTISU LIMITED. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from oslo_log import log as logging from neutronclient._i18n import _ from neutronclient.common import utils as nc_utils from neutronclient.osc import utils as osc_utils LOG = logging.getLogger(__name__) _attr_map = ( ('id', 'ID', osc_utils.LIST_BOTH), ('description', 'Description', osc_utils.LIST_LONG_ONLY), ('enabled', 'Enabled', osc_utils.LIST_BOTH), ('name', 'Name', osc_utils.LIST_BOTH), ('target_id', 'Target', osc_utils.LIST_LONG_ONLY), ('project_id', 'Project', osc_utils.LIST_LONG_ONLY), ('resource_id', 'Resource', osc_utils.LIST_LONG_ONLY), ('resource_type', 'Type', osc_utils.LIST_BOTH), ('event', 'Event', osc_utils.LIST_LONG_ONLY), ('summary', 'Summary', osc_utils.LIST_SHORT_ONLY), ) _attr_map_for_loggable = ( ('type', 'Supported types', osc_utils.LIST_BOTH), ) NET_LOG = 'network_log' def _get_common_parser(parser): parser.add_argument( '--description', metavar='', help=_('Description of the network log')) enable_group = parser.add_mutually_exclusive_group() enable_group.add_argument( '--enable', action='store_true', help=_('Enable this log (default is disabled)')) enable_group.add_argument( '--disable', action='store_true', help=_('Disable this log')) return parser def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} client = client_manager.neutronclient if is_create: if 'project' in parsed_args and parsed_args.project is not None: attrs['project_id'] = osc_utils.find_project( client_manager.identity, parsed_args.project, parsed_args.project_domain, ).id if parsed_args.resource: attrs['resource_id'] = client.find_resource( 'security_group', parsed_args.resource)['id'] if parsed_args.target: # NOTE(yushiro) Currently, we're supporting only port attrs['target_id'] = client.find_resource( 'port', parsed_args.target)['id'] if parsed_args.event: attrs['event'] = parsed_args.event if parsed_args.resource_type: attrs['resource_type'] = parsed_args.resource_type if parsed_args.enable: attrs['enabled'] = True if parsed_args.disable: attrs['enabled'] = False if parsed_args.name: attrs['name'] = parsed_args.name if parsed_args.description: attrs['description'] = parsed_args.description return attrs class CreateNetworkLog(command.ShowOne): _description = _("Create a new network log") def get_parser(self, prog_name): parser = super(CreateNetworkLog, self).get_parser(prog_name) _get_common_parser(parser) osc_utils.add_project_owner_option_to_parser(parser) parser.add_argument( 'name', metavar='', help=_('Name for the network log')) parser.add_argument( '--event', metavar='', choices=['ALL', 'ACCEPT', 'DROP'], type=nc_utils.convert_to_uppercase, help=_('An event to store with log')) # NOTE(yushiro) '--resource-type' is managed by following command: # "openstack network loggable resource list". Therefore, this option # shouldn't have "choices" like ['security_group'] parser.add_argument( '--resource-type', metavar='', required=True, type=nc_utils.convert_to_lowercase, help=_('Network log type(s). ' 'You can see supported type(s) with following command:\n' '$ openstack network loggable resource list')) parser.add_argument( '--resource', metavar='', help=_('Security group (name or ID) for logging. You can control ' 'for logging target combination with --target option.')) parser.add_argument( '--target', metavar='', help=_('Port (name or ID) for logging. You can control ' 'for logging target combination with --resource option.')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) obj = client.create_network_log({'log': attrs})['log'] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return (display_columns, data) class DeleteNetworkLog(command.Command): _description = _("Delete network log(s)") def get_parser(self, prog_name): parser = super(DeleteNetworkLog, self).get_parser(prog_name) parser.add_argument( 'network_log', metavar='', nargs='+', help=_('Network log(s) to delete (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient result = 0 for log_res in parsed_args.network_log: try: log_id = client.find_resource( 'log', log_res, cmd_resource=NET_LOG)['id'] client.delete_network_log(log_id) except Exception as e: result += 1 LOG.error(_("Failed to delete network log with " "name or ID '%(network_log)s': %(e)s"), {'network_log': log_res, 'e': e}) if result > 0: total = len(parsed_args.network_log) msg = (_("%(result)s of %(total)s network log(s) " "failed to delete") % {'result': result, 'total': total}) raise exceptions.CommandError(msg) class ListLoggableResource(command.Lister): _description = _("List supported loggable resources") def get_parser(self, prog_name): parser = super(ListLoggableResource, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', help=_("List additional fields in output") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient obj = client.list_network_loggable_resources()['loggable_resources'] headers, columns = osc_utils.get_column_definitions( _attr_map_for_loggable, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties(s, columns) for s in obj)) class ListNetworkLog(command.Lister): _description = _("List network logs") def get_parser(self, prog_name): parser = super(ListNetworkLog, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', help=_("List additional fields in output") ) # TODO(yushiro): We'll support filtering in the future. return parser def _extend_list(self, data, parsed_args): ext_data = copy.deepcopy(data) for d in ext_data: e_prefix = 'Event: ' if d['event']: event = e_prefix + d['event'].upper() port = '(port) ' + d['target_id'] if d['target_id'] else '' sg = ('(security_group) ' + d['resource_id'] if d['resource_id'] else '') t_prefix = 'Logged: ' t = sg + ' on ' + port if port and sg else sg + port target = t_prefix + t if t else t_prefix + '(None specified)' d['summary'] = ',\n'.join([event, target]) return ext_data def take_action(self, parsed_args): client = self.app.client_manager.neutronclient obj = client.list_network_logs()['logs'] obj_extend = self._extend_list(obj, parsed_args) headers, columns = osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, ( utils.get_dict_properties(s, columns) for s in obj_extend)) class SetNetworkLog(command.Command): _description = _("Set network log properties") def get_parser(self, prog_name): parser = super(SetNetworkLog, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( 'network_log', metavar='', help=_('Network log to set (name or ID)')) parser.add_argument( '--name', metavar='', help=_('Name of the network log')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient log_id = client.find_resource( 'log', parsed_args.network_log, cmd_resource=NET_LOG)['id'] attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) try: client.update_network_log(log_id, {'log': attrs}) except Exception as e: msg = (_("Failed to set network log '%(logging)s': %(e)s") % {'logging': parsed_args.network_log, 'e': e}) raise exceptions.CommandError(msg) class ShowNetworkLog(command.ShowOne): _description = _("Display network log details") def get_parser(self, prog_name): parser = super(ShowNetworkLog, self).get_parser(prog_name) parser.add_argument( 'network_log', metavar='', help=_('Network log to show (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient log_id = client.find_resource( 'log', parsed_args.network_log, cmd_resource=NET_LOG)['id'] obj = client.show_network_log(log_id)['log'] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return (display_columns, data) python-neutronclient-6.7.0/neutronclient/osc/v2/logging/__init__.py0000666000175100017510000000000013232473350025515 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/sfc/0000775000175100017510000000000013232473710022541 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/sfc/sfc_port_pair.py0000777000175100017510000002052413232473350025755 0ustar zuulzuul00000000000000# Copyright (c) 2017 Huawei Technologies India Pvt.Limited. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import logging from osc_lib.cli import parseractions from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from neutronclient._i18n import _ from neutronclient.osc import utils as nc_osc_utils LOG = logging.getLogger(__name__) resource = 'port_pair' _attr_map = ( ('id', 'ID', nc_osc_utils.LIST_BOTH), ('name', 'Name', nc_osc_utils.LIST_BOTH), ('ingress', 'Ingress Logical Port', nc_osc_utils.LIST_BOTH), ('egress', 'Egress Logical Port', nc_osc_utils.LIST_BOTH), ('service_function_parameters', 'Service Function Parameters', nc_osc_utils.LIST_LONG_ONLY), ('description', 'Description', nc_osc_utils.LIST_LONG_ONLY), ('project_id', 'Project', nc_osc_utils.LIST_LONG_ONLY), ) class CreateSfcPortPair(command.ShowOne): _description = _("Create a port pair") def get_parser(self, prog_name): parser = super(CreateSfcPortPair, self).get_parser(prog_name) parser.add_argument( 'name', metavar='', help=_('Name of the port pair')) parser.add_argument( '--description', metavar='', help=_('Description for the port pair')) parser.add_argument( '--service-function-parameters', metavar='correlation=,weight=', action=parseractions.MultiKeyValueAction, optional_keys=['correlation', 'weight'], help=_('Dictionary of service function parameters. ' 'Currently, correlation=(None|mpls|nsh) and weight ' 'are supported. Weight is an integer that influences ' 'the selection of a port pair within a port pair group ' 'for a flow. The higher the weight, the more flows will ' 'hash to the port pair. The default weight is 1.')) parser.add_argument( '--ingress', metavar='', required=True, help=_('Ingress neutron port (name or ID)')) parser.add_argument( '--egress', metavar='', required=True, help=_('Egress neutron port (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) body = {resource: attrs} obj = client.create_sfc_port_pair(body)[resource] columns, display_columns = nc_osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data class DeleteSfcPortPair(command.Command): _description = _("Delete a given port pair") def get_parser(self, prog_name): parser = super(DeleteSfcPortPair, self).get_parser(prog_name) parser.add_argument( 'port_pair', metavar="", help=_("Port pair to delete (name or ID)") ) return parser def take_action(self, parsed_args): # TODO(mohan): Add support for deleting multiple resources. client = self.app.client_manager.neutronclient port_pair_id = _get_id(client, parsed_args.port_pair, resource) try: client.delete_sfc_port_pair(port_pair_id) except Exception as e: msg = (_("Failed to delete port pair with name " "or ID '%(port_pair)s': %(e)s") % {'port_pair': parsed_args.port_pair, 'e': e}) raise exceptions.CommandError(msg) class ListSfcPortPair(command.Lister): _description = _("List port pairs") def get_parser(self, prog_name): parser = super(ListSfcPortPair, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', help=_("List additional fields in output") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient data = client.list_sfc_port_pairs() headers, columns = nc_osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties( s, columns, ) for s in data['port_pairs'])) class SetSfcPortPair(command.Command): _description = _("Set port pair properties") def get_parser(self, prog_name): parser = super(SetSfcPortPair, self).get_parser(prog_name) parser.add_argument( '--name', metavar='', help=_('Name of the port pair')) parser.add_argument( '--description', metavar='', help=_('Description for the port pair')) parser.add_argument( 'port_pair', metavar='', help=_("Port pair to modify (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient port_pair_id = _get_id(client, parsed_args.port_pair, resource) attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) body = {resource: attrs} try: client.update_sfc_port_pair(port_pair_id, body) except Exception as e: msg = (_("Failed to update port pair '%(port_pair)s': %(e)s") % {'port_pair': parsed_args.port_pair, 'e': e}) raise exceptions.CommandError(msg) class ShowSfcPortPair(command.ShowOne): _description = _("Display port pair details") def get_parser(self, prog_name): parser = super(ShowSfcPortPair, self).get_parser(prog_name) parser.add_argument( 'port_pair', metavar='', help=_("Port pair to display (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient port_pair_id = _get_id(client, parsed_args.port_pair, resource) obj = client.show_sfc_port_pair(port_pair_id)[resource] columns, display_columns = nc_osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} if parsed_args.name is not None: attrs['name'] = parsed_args.name if parsed_args.description is not None: attrs['description'] = parsed_args.description if is_create: _get_attrs(client_manager, attrs, parsed_args) return attrs def _get_attrs(client_manager, attrs, parsed_args): if parsed_args.ingress is not None: attrs['ingress'] = _get_id(client_manager.neutronclient, parsed_args.ingress, 'port') if parsed_args.egress is not None: attrs['egress'] = _get_id(client_manager.neutronclient, parsed_args.egress, 'port') if parsed_args.service_function_parameters is not None: attrs['service_function_parameters'] = _get_service_function_params( parsed_args.service_function_parameters) def _get_service_function_params(sf_params): attrs = {} for sf_param in sf_params: if 'correlation' in sf_param: if sf_param['correlation'] == 'None': attrs['correlation'] = None else: attrs['correlation'] = sf_param['correlation'] if 'weight' in sf_param: attrs['weight'] = sf_param['weight'] return attrs def _get_id(client, id_or_name, resource): return client.find_resource(resource, id_or_name)['id'] python-neutronclient-6.7.0/neutronclient/osc/v2/sfc/sfc_service_graph.py0000666000175100017510000002201113232473350026565 0ustar zuulzuul00000000000000# Copyright 2017 Intel Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import logging from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from neutronclient._i18n import _ from neutronclient.osc import utils as nc_osc_utils LOG = logging.getLogger(__name__) resource = 'service_graph' _attr_map = ( ('id', 'ID', nc_osc_utils.LIST_BOTH), ('name', 'Name', nc_osc_utils.LIST_BOTH), ('port_chains', 'Branching Points', nc_osc_utils.LIST_BOTH), ('description', 'Description', nc_osc_utils.LIST_LONG_ONLY), ('project_id', 'Project', nc_osc_utils.LIST_LONG_ONLY), ) class CreateSfcServiceGraph(command.ShowOne): """Create a service graph.""" def get_parser(self, prog_name): parser = super(CreateSfcServiceGraph, self).get_parser(prog_name) parser.add_argument( 'name', metavar='', help=_('Name of the service graph.')) parser.add_argument( '--description', help=_('Description for the service graph.')) parser.add_argument( '--branching-point', metavar='SRC_CHAIN:DST_CHAIN_1,DST_CHAIN_2,DST_CHAIN_N', dest='branching_points', action='append', default=[], required=True, help=_('Service graph branching point: the key is the source ' 'Port Chain while the value is a list of destination ' 'Port Chains. This option can be repeated.')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) try: body = {resource: attrs} obj = client.create_sfc_service_graph(body)[resource] columns, display_columns = nc_osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data except Exception as e: msg = (_("Failed to create service graph using '%(pcs)s': %(e)s") % {'pcs': parsed_args.branching_points, 'e': e}) raise exceptions.CommandError(msg) class SetSfcServiceGraph(command.Command): _description = _("Set service graph properties") def get_parser(self, prog_name): parser = super(SetSfcServiceGraph, self).get_parser(prog_name) parser.add_argument( '--name', metavar='', help=_('Name of the service graph')) parser.add_argument( '--description', metavar='', help=_('Description for the service graph')) parser.add_argument( 'service_graph', metavar='', help=_("Service graph to modify (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient service_graph_id = _get_id(client, parsed_args.service_graph, resource) attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) body = {resource: attrs} try: client.update_sfc_service_graph(service_graph_id, body) except Exception as e: msg = (_("Failed to update service graph " "'%(service_graph)s': %(e)s") % {'service_graph': parsed_args.service_graph, 'e': e}) raise exceptions.CommandError(msg) class DeleteSfcServiceGraph(command.Command): """Delete a given service graph.""" def get_parser(self, prog_name): parser = super(DeleteSfcServiceGraph, self).get_parser(prog_name) parser.add_argument( 'service_graph', metavar="", help=_("ID or name of the service graph to delete.") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient id = _get_id(client, parsed_args.service_graph, resource) client.delete_sfc_service_graph(id) class ListSfcServiceGraph(command.Lister): _description = _("List service graphs") def get_parser(self, prog_name): parser = super(ListSfcServiceGraph, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', default=False, help=_("List additional fields in output") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient data = client.list_sfc_service_graphs() headers, columns = nc_osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties(s, columns) for s in data['service_graphs'])) class ShowSfcServiceGraph(command.ShowOne): """Show information of a given service graph.""" def get_parser(self, prog_name): parser = super(ShowSfcServiceGraph, self).get_parser(prog_name) parser.add_argument( 'service_graph', metavar="", help=_("ID or name of the service graph to display.") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient sg_id = _get_id(client, parsed_args.service_graph, resource) obj = client.show_sfc_service_graph(sg_id)[resource] columns, display_columns = nc_osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} if parsed_args.name is not None: attrs['name'] = str(parsed_args.name) if parsed_args.description is not None: attrs['description'] = str(parsed_args.description) if is_create: _get_attrs_for_create(client_manager, attrs, parsed_args) return attrs def _validate_destination_chains(comma_split, attrs, client_manager, sc_): for e in comma_split: if e != "": dc_ = _get_id(client_manager.neutronclient, e, 'port_chain') attrs['port_chains'][sc_].append(dc_) if _check_cycle(attrs['port_chains'], sc_, dc_): raise(exceptions.CommandError( "Error: Service graph contains a cycle")) else: raise exceptions.CommandError( "Error: you must specify at least one " "destination chain for each source chain") return attrs def _check_cycle(graph, new_src, new_dest): for src in graph: if src == new_dest: if _visit(graph, src, new_dest, new_src): return True return False def _visit(graph, src, new_dest, new_src): if src in graph: found_cycle = False for dest in graph[src]: if new_src == dest or found_cycle: return True else: found_cycle = _visit(graph, dest, new_dest, new_src) return False def _get_attrs_for_create(client_manager, attrs, parsed_args): if parsed_args.branching_points: attrs['port_chains'] = {} src_chain = None for c in parsed_args.branching_points: if ':' not in c: raise exceptions.CommandError( "Error: You must specify at least one " "destination chain for each source chain.") colon_split = c.split(':') src_chain = colon_split.pop(0) sc_ = _get_id(client_manager.neutronclient, src_chain, 'port_chain') for i in colon_split: comma_split = i.split(',') unique = set(comma_split) if len(unique) != len(comma_split): raise exceptions.CommandError( "Error: Duplicate " "destination chains from " "source chain {}".format(src_chain)) if sc_ in attrs['port_chains']: raise exceptions.CommandError( "Error: Source chain {} is in " "use already ".format(src_chain)) attrs['port_chains'][sc_] = [] _validate_destination_chains( comma_split, attrs, client_manager, sc_) def _get_id(client, id_or_name, resource): return client.find_resource(resource, id_or_name)['id'] python-neutronclient-6.7.0/neutronclient/osc/v2/sfc/sfc_port_pair_group.py0000777000175100017510000002730113232473350027171 0ustar zuulzuul00000000000000# Copyright (c) 2017 Huawei Technologies India Pvt.Limited. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import logging from osc_lib.cli import parseractions from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from neutronclient._i18n import _ from neutronclient.osc import utils as nc_osc_utils LOG = logging.getLogger(__name__) resource = 'port_pair_group' _attr_map = ( ('id', 'ID', nc_osc_utils.LIST_BOTH), ('name', 'Name', nc_osc_utils.LIST_BOTH), ('port_pairs', 'Port Pair', nc_osc_utils.LIST_BOTH), ('port_pair_group_parameters', 'Port Pair Group Parameters', nc_osc_utils.LIST_BOTH), ('description', 'Description', nc_osc_utils.LIST_LONG_ONLY), ('group_id', 'Loadbalance ID', nc_osc_utils.LIST_LONG_ONLY), ('project_id', 'Project', nc_osc_utils.LIST_LONG_ONLY), ('tap_enabled', 'Tap Enabled', nc_osc_utils.LIST_BOTH) ) class CreateSfcPortPairGroup(command.ShowOne): _description = _("Create a port pair group") def get_parser(self, prog_name): parser = super(CreateSfcPortPairGroup, self).get_parser(prog_name) parser.add_argument( 'name', metavar='', help=_('Name of the port pair group')) parser.add_argument( '--description', metavar='', help=_('Description for the port pair group')) parser.add_argument( '--port-pair', metavar='', dest='port_pairs', default=[], action='append', help=_('Port pair (name or ID). ' 'This option can be repeated.')) tap_enable = parser.add_mutually_exclusive_group() tap_enable.add_argument( '--enable-tap', action='store_true', help=_('Port pairs of this port pair group are deployed as ' 'passive tap service function') ) tap_enable.add_argument( '--disable-tap', action='store_true', help=_('Port pairs of this port pair group are deployed as l3 ' 'service function (default)') ) parser.add_argument( '--port-pair-group-parameters', metavar='lb-fields=', action=parseractions.KeyValueAction, help=_('Dictionary of port pair group parameters. ' 'Currently only one parameter lb-fields is supported. ' ' is a & separated list of load-balancing ' 'fields.')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) body = {resource: attrs} obj = client.create_sfc_port_pair_group(body)[resource] columns, display_columns = nc_osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data class DeleteSfcPortPairGroup(command.Command): _description = _("Delete a given port pair group") def get_parser(self, prog_name): parser = super(DeleteSfcPortPairGroup, self).get_parser(prog_name) parser.add_argument( 'port_pair_group', metavar='', help=_("Port pair group to delete (name or ID)") ) return parser def take_action(self, parsed_args): # TODO(mohan): Add support for deleting multiple resources. client = self.app.client_manager.neutronclient ppg_id = _get_id(client, parsed_args.port_pair_group, resource) try: client.delete_sfc_port_pair_group(ppg_id) except Exception as e: msg = (_("Failed to delete port pair group with name " "or ID '%(ppg)s': %(e)s") % {'ppg': parsed_args.port_pair_group, 'e': e}) raise exceptions.CommandError(msg) class ListSfcPortPairGroup(command.Lister): _description = _("List port pair group") def get_parser(self, prog_name): parser = super(ListSfcPortPairGroup, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', default=False, help=_("List additional fields in output") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient data = client.list_sfc_port_pair_groups() headers, columns = nc_osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties( s, columns, ) for s in data['port_pair_groups'])) class SetSfcPortPairGroup(command.Command): _description = _("Set port pair group properties") def get_parser(self, prog_name): parser = super(SetSfcPortPairGroup, self).get_parser(prog_name) parser.add_argument( 'port_pair_group', metavar='', help=_("Port pair group to modify (name or ID)")) parser.add_argument( '--name', metavar='', help=_('Name of the port pair group')) parser.add_argument( '--description', metavar='', help=_('Description for the port pair group')) parser.add_argument( '--port-pair', metavar='', dest='port_pairs', default=[], action='append', help=_('Port pair (name or ID). ' 'This option can be repeated.')) parser.add_argument( '--no-port-pair', action='store_true', help=_('Remove all port pair from port pair group')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient ppg_id = _get_id(client, parsed_args.port_pair_group, resource) attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) if parsed_args.no_port_pair: attrs['port_pairs'] = [] if parsed_args.port_pairs: added = [client.find_resource('port_pair', pp, cmd_resource='sfc_port_pair')['id'] for pp in parsed_args.port_pairs] if parsed_args.no_port_pair: existing = [] else: existing = [client.find_resource( resource, parsed_args.port_pair_group, cmd_resource='sfc_port_pair_group')['port_pairs']] attrs['port_pairs'] = sorted(list(set(existing) | set(added))) body = {resource: attrs} try: client.update_sfc_port_pair_group(ppg_id, body) except Exception as e: msg = (_("Failed to update port pair group '%(ppg)s': %(e)s") % {'ppg': parsed_args.port_pair_group, 'e': e}) raise exceptions.CommandError(msg) class ShowSfcPortPairGroup(command.ShowOne): _description = _("Display port pair group details") def get_parser(self, prog_name): parser = super(ShowSfcPortPairGroup, self).get_parser(prog_name) parser.add_argument( 'port_pair_group', metavar='', help=_("Port pair group to display (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient ppg_id = _get_id(client, parsed_args.port_pair_group, resource) obj = client.show_sfc_port_pair_group(ppg_id)[resource] columns, display_columns = nc_osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data class UnsetSfcPortPairGroup(command.Command): _description = _("Unset port pairs from port pair group") def get_parser(self, prog_name): parser = super(UnsetSfcPortPairGroup, self).get_parser(prog_name) parser.add_argument( 'port_pair_group', metavar='', help=_("Port pair group to unset (name or ID)")) port_pair_group = parser.add_mutually_exclusive_group() port_pair_group.add_argument( '--port-pair', action='append', metavar='', dest='port_pairs', help=_('Remove port pair(s) from the port pair group ' '(name or ID). This option can be repeated.')) port_pair_group.add_argument( '--all-port-pair', action='store_true', help=_('Remove all port pairs from the port pair group')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient ppg_id = _get_id(client, parsed_args.port_pair_group, resource) attrs = {} if parsed_args.port_pairs: existing = [client.find_resource( resource, parsed_args.port_pair_group, cmd_resource='sfc_port_pair_group')['port_pairs']] for pp in parsed_args.port_pairs: removed = [client.find_resource( 'port_pair', pp, cmd_resource='sfc_port_pair')['id']] attrs['port_pairs'] = list(set(existing) - set(removed)) if parsed_args.all_port_pair: attrs['port_pairs'] = [] body = {resource: attrs} try: client.update_sfc_port_pair_group(ppg_id, body) except Exception as e: msg = (_("Failed to unset port pair group '%(ppg)s': %(e)s") % {'ppg': parsed_args.port_pair_group, 'e': e}) raise exceptions.CommandError(msg) def _get_ppg_param(attrs, ppg): attrs['port_pair_group_parameters'] = {} for key, value in ppg.items(): if key == 'lb-fields': attrs['port_pair_group_parameters']['lb_fields'] = ([ field for field in value.split('&') if field]) else: attrs['port_pair_group_parameters'][key] = value return attrs['port_pair_group_parameters'] def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} if parsed_args.name is not None: attrs['name'] = parsed_args.name if parsed_args.description is not None: attrs['description'] = parsed_args.description if parsed_args.port_pairs: attrs['port_pairs'] = [(_get_id(client_manager.neutronclient, pp, 'port_pair')) for pp in parsed_args.port_pairs] if is_create: _get_attrs(attrs, parsed_args) return attrs def _get_attrs(attrs, parsed_args): if parsed_args.port_pair_group_parameters is not None: attrs['port_pair_group_parameters'] = ( _get_ppg_param(attrs, parsed_args.port_pair_group_parameters)) if parsed_args.enable_tap: attrs['tap_enabled'] = True if parsed_args.disable_tap: attrs['tap_enabled'] = False def _get_id(client, id_or_name, resource): return client.find_resource(resource, id_or_name)['id'] python-neutronclient-6.7.0/neutronclient/osc/v2/sfc/sfc_flow_classifier.py0000777000175100017510000003106513232473350027133 0ustar zuulzuul00000000000000# Copyright (c) 2017 Huawei Technologies India Pvt.Limited. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import argparse import logging from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from neutronclient._i18n import _ from neutronclient.common import exceptions as nc_exc from neutronclient.osc import utils as nc_osc_utils LOG = logging.getLogger(__name__) resource = 'flow_classifier' _attr_map = ( ('id', 'ID', nc_osc_utils.LIST_BOTH), ('name', 'Name', nc_osc_utils.LIST_BOTH), ('summary', 'Summary', nc_osc_utils.LIST_SHORT_ONLY), ('protocol', 'Protocol', nc_osc_utils.LIST_LONG_ONLY), ('ethertype', 'Ethertype', nc_osc_utils.LIST_LONG_ONLY), ('source_ip_prefix', 'Source IP', nc_osc_utils.LIST_LONG_ONLY), ('destination_ip_prefix', 'Destination IP', nc_osc_utils.LIST_LONG_ONLY), ('logical_source_port', 'Logical Source Port', nc_osc_utils.LIST_LONG_ONLY), ('logical_destination_port', 'Logical Destination Port', nc_osc_utils.LIST_LONG_ONLY), ('source_port_range_min', 'Source Port Range Min', nc_osc_utils.LIST_LONG_ONLY), ('source_port_range_max', 'Source Port Range Max', nc_osc_utils.LIST_LONG_ONLY), ('destination_port_range_min', 'Destination Port Range Min', nc_osc_utils.LIST_LONG_ONLY), ('destination_port_range_max', 'Destination Port Range Max', nc_osc_utils.LIST_LONG_ONLY), ('l7_parameters', 'L7 Parameters', nc_osc_utils.LIST_LONG_ONLY), ('description', 'Description', nc_osc_utils.LIST_LONG_ONLY), ('project_id', 'Project', nc_osc_utils.LIST_LONG_ONLY), ) class CreateSfcFlowClassifier(command.ShowOne): _description = _("Create a flow classifier") def get_parser(self, prog_name): parser = super(CreateSfcFlowClassifier, self).get_parser(prog_name) parser.add_argument( 'name', metavar='', help=_('Name of the flow classifier')) parser.add_argument( '--description', metavar='', help=_('Description for the flow classifier')) parser.add_argument( '--protocol', metavar='', help=_('IP protocol name. Protocol name should be as per ' 'IANA standard.')) parser.add_argument( '--ethertype', metavar='{IPv4,IPv6}', default='IPv4', choices=['IPv4', 'IPv6'], help=_('L2 ethertype, default is IPv4')) parser.add_argument( '--source-port', metavar=':', help=_('Source protocol port (allowed range [1,65535]. Must be ' 'specified as a:b, where a=min-port and b=max-port) ' 'in the allowed range.')) parser.add_argument( '--destination-port', metavar=':', help=_('Destination protocol port (allowed range [1,65535]. Must ' 'be specified as a:b, where a=min-port and b=max-port) ' 'in the allowed range.')) parser.add_argument( '--source-ip-prefix', metavar='', help=_('Source IP address in CIDR notation')) parser.add_argument( '--destination-ip-prefix', metavar='', help=_('Destination IP address in CIDR notation')) parser.add_argument( '--logical-source-port', metavar='', help=_('Neutron source port (name or ID)')) parser.add_argument( '--logical-destination-port', metavar='', help=_('Neutron destination port (name or ID)')) parser.add_argument( '--l7-parameters', help=_('Dictionary of L7 parameters. Currently, no value is ' 'supported for this option.')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) body = {resource: attrs} obj = client.create_sfc_flow_classifier(body)[resource] columns, display_columns = nc_osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data class DeleteSfcFlowClassifier(command.Command): _description = _("Delete a given flow classifier") def get_parser(self, prog_name): parser = super(DeleteSfcFlowClassifier, self).get_parser(prog_name) parser.add_argument( 'flow_classifier', metavar='', help=_("Flow classifier to delete (name or ID)") ) return parser def take_action(self, parsed_args): # TODO(mohan): Add support for deleting multiple resources. client = self.app.client_manager.neutronclient fc_id = _get_id(client, parsed_args.flow_classifier, resource) try: client.delete_sfc_flow_classifier(fc_id) except Exception as e: msg = (_("Failed to delete flow classifier with name " "or ID '%(fc)s': %(e)s") % {'fc': parsed_args.flow_classifier, 'e': e}) raise exceptions.CommandError(msg) class ListSfcFlowClassifier(command.Lister): _description = _("List flow classifiers") def get_parser(self, prog_name): parser = super(ListSfcFlowClassifier, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', help=_("List additional fields in output") ) return parser def extend_list(self, data, parsed_args): ext_data = data['flow_classifiers'] for d in ext_data: val = [] protocol = d['protocol'].upper() if d['protocol'] else 'any' val.append('protocol: ' + protocol) val.append(self._get_protocol_port_details(d, 'source')) val.append(self._get_protocol_port_details(d, 'destination')) if 'logical_source_port' in d: val.append('neutron_source_port: ' + str(d['logical_source_port'])) if 'logical_destination_port' in d: val.append('neutron_destination_port: ' + str(d['logical_destination_port'])) if 'l7_parameters' in d: l7_param = 'l7_parameters: {%s}' % ','.join(d['l7_parameters']) val.append(l7_param) d['summary'] = ',\n'.join(val) return ext_data def _get_protocol_port_details(self, data, val): type_ip_prefix = val + '_ip_prefix' ip_prefix = data.get(type_ip_prefix) if not ip_prefix: ip_prefix = 'any' min_port = data.get(val + '_port_range_min') if min_port is None: min_port = 'any' max_port = data.get(val + '_port_range_max') if max_port is None: max_port = 'any' return '%s[port]: %s[%s:%s]' % ( val, ip_prefix, min_port, max_port) def take_action(self, parsed_args): client = self.app.client_manager.neutronclient obj = client.list_sfc_flow_classifiers() obj_extend = self.extend_list(obj, parsed_args) headers, columns = nc_osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties( s, columns) for s in obj_extend)) class SetSfcFlowClassifier(command.Command): _description = _("Set flow classifier properties") def get_parser(self, prog_name): parser = super(SetSfcFlowClassifier, self).get_parser(prog_name) parser.add_argument( '--name', metavar='', help=_('Name of the flow classifier')) parser.add_argument( '--description', metavar='', help=_('Description for the flow classifier')) parser.add_argument( 'flow_classifier', metavar='', help=_("Flow classifier to modify (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient fc_id = _get_id(client, parsed_args.flow_classifier, resource) attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) body = {resource: attrs} try: client.update_sfc_flow_classifier(fc_id, body) except Exception as e: msg = (_("Failed to update flow classifier '%(fc)s': %(e)s") % {'fc': parsed_args.flow_classifier, 'e': e}) raise exceptions.CommandError(msg) class ShowSfcFlowClassifier(command.ShowOne): _description = _("Display flow classifier details") def get_parser(self, prog_name): parser = super(ShowSfcFlowClassifier, self).get_parser(prog_name) parser.add_argument( 'flow_classifier', metavar='', help=_("Flow classifier to display (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient fc_id = _get_id(client, parsed_args.flow_classifier, resource) obj = client.show_sfc_flow_classifier(fc_id)[resource] columns, display_columns = nc_osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} if parsed_args.name is not None: attrs['name'] = parsed_args.name if parsed_args.description is not None: attrs['description'] = parsed_args.description if is_create: _get_attrs(client_manager, attrs, parsed_args) return attrs def _get_attrs(client_manager, attrs, parsed_args): if parsed_args.protocol is not None: attrs['protocol'] = parsed_args.protocol if parsed_args.ethertype: attrs['ethertype'] = parsed_args.ethertype if parsed_args.source_ip_prefix is not None: attrs['source_ip_prefix'] = parsed_args.source_ip_prefix if parsed_args.destination_ip_prefix is not None: attrs['destination_ip_prefix'] = parsed_args.destination_ip_prefix if parsed_args.logical_source_port is not None: attrs['logical_source_port'] = _get_id( client_manager.neutronclient, parsed_args.logical_source_port, 'port') if parsed_args.logical_destination_port is not None: attrs['logical_destination_port'] = _get_id( client_manager.neutronclient, parsed_args.logical_destination_port, 'port') if parsed_args.source_port is not None: _fill_protocol_port_info(attrs, 'source', parsed_args.source_port) if parsed_args.destination_port is not None: _fill_protocol_port_info(attrs, 'destination', parsed_args.destination_port) if parsed_args.l7_parameters is not None: attrs['l7_parameters'] = parsed_args.l7_parameters def _fill_protocol_port_info(attrs, port_type, port_val): min_port, sep, max_port = port_val.partition(":") if not min_port: msg = ("Invalid port value '%s', expected format is " "min-port:max-port or min-port.") raise argparse.ArgumentTypeError(msg % port_val) if not max_port: max_port = min_port try: attrs[port_type + '_port_range_min'] = int(min_port) attrs[port_type + '_port_range_max'] = int(max_port) except ValueError: message = (_("Protocol port value %s must be an integer " "or integer:integer.") % port_val) raise nc_exc.CommandError(message=message) def _get_id(client, id_or_name, resource): return client.find_resource(resource, id_or_name)['id'] python-neutronclient-6.7.0/neutronclient/osc/v2/sfc/__init__.py0000666000175100017510000000000013232473350024642 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/sfc/sfc_port_chain.py0000777000175100017510000003463113232473350026110 0ustar zuulzuul00000000000000# Copyright (c) 2017 Huawei Technologies India Pvt.Limited. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import logging from osc_lib.cli import parseractions from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from neutronclient._i18n import _ from neutronclient.osc import utils as nc_osc_utils LOG = logging.getLogger(__name__) resource = 'port_chain' _attr_map = ( ('id', 'ID', nc_osc_utils.LIST_BOTH), ('name', 'Name', nc_osc_utils.LIST_BOTH), ('port_pair_groups', 'Port Pair Groups', nc_osc_utils.LIST_BOTH), ('flow_classifiers', 'Flow Classifiers', nc_osc_utils.LIST_BOTH), ('chain_parameters', 'Chain Parameters', nc_osc_utils.LIST_BOTH), ('description', 'Description', nc_osc_utils.LIST_LONG_ONLY), ('chain_id', 'Chain ID', nc_osc_utils.LIST_BOTH), ('project_id', 'Project', nc_osc_utils.LIST_LONG_ONLY), ) class CreateSfcPortChain(command.ShowOne): _description = _("Create a port chain") def get_parser(self, prog_name): parser = super(CreateSfcPortChain, self).get_parser(prog_name) parser.add_argument( 'name', metavar='', help=_('Name of the port chain')) parser.add_argument( '--description', metavar='', help=_('Description for the port chain')) parser.add_argument( '--flow-classifier', default=[], metavar='', dest='flow_classifiers', action='append', help=_('Add flow classifier (name or ID). ' 'This option can be repeated.')) parser.add_argument( '--chain-parameters', metavar='correlation=,symmetric=', action=parseractions.MultiKeyValueAction, optional_keys=['correlation', 'symmetric'], help=_('Dictionary of chain parameters. Supports ' 'correlation=(mpls|nsh) (default is mpls) ' 'and symmetric=(true|false).')) parser.add_argument( '--port-pair-group', metavar='', dest='port_pair_groups', required=True, action='append', help=_('Add port pair group (name or ID). ' 'This option can be repeated.')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) body = {resource: attrs} obj = client.create_sfc_port_chain(body)[resource] columns, display_columns = nc_osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data class DeleteSfcPortChain(command.Command): _description = _("Delete a given port chain") def get_parser(self, prog_name): parser = super(DeleteSfcPortChain, self).get_parser(prog_name) parser.add_argument( 'port_chain', metavar="", help=_("Port chain to delete (name or ID)") ) return parser def take_action(self, parsed_args): # TODO(mohan): Add support for deleting multiple resources. client = self.app.client_manager.neutronclient pc_id = _get_id(client, parsed_args.port_chain, resource) try: client.delete_sfc_port_chain(pc_id) except Exception as e: msg = (_("Failed to delete port chain with name " "or ID '%(pc)s': %(e)s") % {'pc': parsed_args.port_chain, 'e': e}) raise exceptions.CommandError(msg) class ListSfcPortChain(command.Lister): _description = _("List port chains") def get_parser(self, prog_name): parser = super(ListSfcPortChain, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', default=False, help=_("List additional fields in output") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient data = client.list_sfc_port_chains() headers, columns = nc_osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties(s, columns) for s in data['port_chains'])) class SetSfcPortChain(command.Command): _description = _("Set port chain properties") def get_parser(self, prog_name): parser = super(SetSfcPortChain, self).get_parser(prog_name) parser.add_argument( '--name', metavar='', help=_('Name of the port chain')) parser.add_argument( '--description', metavar='', help=_('Description for the port chain')) parser.add_argument( '--flow-classifier', metavar='', dest='flow_classifiers', action='append', help=_('Add flow classifier (name or ID). ' 'This option can be repeated.')) parser.add_argument( '--no-flow-classifier', action='store_true', help=_('Remove associated flow classifiers from the port chain')) parser.add_argument( '--port-pair-group', metavar='', dest='port_pair_groups', action='append', help=_('Add port pair group (name or ID). ' 'Current port pair groups order is kept, the added port ' 'pair group will be placed at the end of the port chain. ' 'This option can be repeated.')) parser.add_argument( '--no-port-pair-group', action='store_true', help=_('Remove associated port pair groups from the port chain. ' 'At least one --port-pair-group must be specified ' 'together.')) parser.add_argument( 'port_chain', metavar='', help=_("Port chain to modify (name or ID)")) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient pc_id = _get_id(client, parsed_args.port_chain, resource) attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) if parsed_args.no_flow_classifier: attrs['flow_classifiers'] = [] if parsed_args.flow_classifiers: if parsed_args.no_flow_classifier: fc_list = [] else: fc_list = client.find_resource( resource, parsed_args.port_chain, cmd_resource='sfc_port_chain')['flow_classifiers'] for fc in parsed_args.flow_classifiers: fc_id = client.find_resource( 'flow_classifier', fc, cmd_resource='sfc_flow_classifier')['id'] if fc_id not in fc_list: fc_list.append(fc_id) attrs['flow_classifiers'] = fc_list if (parsed_args.no_port_pair_group and not parsed_args.port_pair_groups): message = _('At least one --port-pair-group must be specified.') raise exceptions.CommandError(message) if parsed_args.no_port_pair_group and parsed_args.port_pair_groups: ppg_list = [] for ppg in parsed_args.port_pair_groups: ppg_id = client.find_resource( 'port_pair_group', ppg, cmd_resource='sfc_port_pair_group')['id'] if ppg_id not in ppg_list: ppg_list.append(ppg_id) attrs['port_pair_groups'] = ppg_list if (parsed_args.port_pair_groups and not parsed_args.no_port_pair_group): ppg_list = client.find_resource( resource, parsed_args.port_chain, cmd_resource='sfc_port_chain')['port_pair_groups'] for ppg in parsed_args.port_pair_groups: ppg_id = client.find_resource( 'port_pair_group', ppg, cmd_resource='sfc_port_pair_group')['id'] if ppg_id not in ppg_list: ppg_list.append(ppg_id) attrs['port_pair_groups'] = ppg_list body = {resource: attrs} try: client.update_sfc_port_chain(pc_id, body) except Exception as e: msg = (_("Failed to update port chain '%(pc)s': %(e)s") % {'pc': parsed_args.port_chain, 'e': e}) raise exceptions.CommandError(msg) class ShowSfcPortChain(command.ShowOne): _description = _("Display port chain details") def get_parser(self, prog_name): parser = super(ShowSfcPortChain, self).get_parser(prog_name) parser.add_argument( 'port_chain', metavar="", help=_("Port chain to display (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient pc_id = _get_id(client, parsed_args.port_chain, resource) obj = client.show_sfc_port_chain(pc_id)[resource] columns, display_columns = nc_osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data class UnsetSfcPortChain(command.Command): _description = _("Unset port chain properties") def get_parser(self, prog_name): parser = super(UnsetSfcPortChain, self).get_parser(prog_name) parser.add_argument( 'port_chain', metavar='', help=_("Port chain to unset (name or ID)")) port_chain = parser.add_mutually_exclusive_group() port_chain.add_argument( '--flow-classifier', action='append', metavar='', dest='flow_classifiers', help=_('Remove flow classifier(s) from the port chain ' '(name or ID). This option can be repeated.')) port_chain.add_argument( '--all-flow-classifier', action='store_true', help=_('Remove all flow classifiers from the port chain')) parser.add_argument( '--port-pair-group', metavar='', dest='port_pair_groups', action='append', help=_('Remove port pair group(s) from the port chain ' '(name or ID). This option can be repeated.')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient pc_id = _get_id(client, parsed_args.port_chain, resource) attrs = {} if parsed_args.flow_classifiers: fc_list = client.find_resource( resource, parsed_args.port_chain, cmd_resource='sfc_port_chain')['flow_classifiers'] for fc in parsed_args.flow_classifiers: fc_id = client.find_resource( 'flow_classifier', fc, cmd_resource='sfc_flow_classifier')['id'] if fc_id in fc_list: fc_list.remove(fc_id) attrs['flow_classifiers'] = fc_list if parsed_args.all_flow_classifier: attrs['flow_classifiers'] = [] if parsed_args.port_pair_groups: ppg_list = client.find_resource( resource, parsed_args.port_chain, cmd_resource='sfc_port_chain')['port_pair_groups'] for ppg in parsed_args.port_pair_groups: ppg_id = client.find_resource( 'port_pair_group', ppg, cmd_resource='sfc_port_pair_group')['id'] if ppg_id in ppg_list: ppg_list.remove(ppg_id) if ppg_list == []: message = _('At least one port pair group must be' ' specified.') raise exceptions.CommandError(message) attrs['port_pair_groups'] = ppg_list body = {resource: attrs} try: client.update_sfc_port_chain(pc_id, body) except Exception as e: msg = (_("Failed to unset port chain '%(pc)s': %(e)s") % {'pc': parsed_args.port_chain, 'e': e}) raise exceptions.CommandError(msg) def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} if parsed_args.name is not None: attrs['name'] = parsed_args.name if parsed_args.description is not None: attrs['description'] = parsed_args.description if parsed_args.port_pair_groups: attrs['port_pair_groups'] = [(_get_id(client_manager.neutronclient, ppg, 'port_pair_group')) for ppg in parsed_args.port_pair_groups] if parsed_args.flow_classifiers: attrs['flow_classifiers'] = [(_get_id(client_manager.neutronclient, fc, 'flow_classifier')) for fc in parsed_args.flow_classifiers] if is_create is True: _get_attrs(attrs, parsed_args) return attrs def _get_attrs(attrs, parsed_args): if parsed_args.chain_parameters is not None: chain_params = {} for chain_param in parsed_args.chain_parameters: if 'correlation' in chain_param: chain_params['correlation'] = chain_param['correlation'] if 'symmetric' in chain_param: chain_params['symmetric'] = chain_param['symmetric'] attrs['chain_parameters'] = chain_params def _get_id(client, id_or_name, resource): return client.find_resource(resource, id_or_name)['id'] python-neutronclient-6.7.0/neutronclient/osc/v2/dynamic_routing/0000775000175100017510000000000013232473710025161 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/dynamic_routing/bgp_peer.py0000666000175100017510000001541513232473350027326 0ustar zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from osc_lib.command import command from osc_lib import utils from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils as nc_utils from neutronclient.osc import utils as nc_osc_utils from neutronclient.osc.v2.dynamic_routing import constants def _get_attrs(client_manager, parsed_args): attrs = {} # Validate password if 'auth_type' in parsed_args: if parsed_args.auth_type != 'none': if 'password' not in parsed_args or parsed_args.password is None: raise exceptions.CommandError(_('Must provide password if ' 'auth-type is specified.')) if ( parsed_args.auth_type == 'none' and parsed_args.password is not None ): raise exceptions.CommandError(_('Must provide auth-type if ' 'password is specified.')) attrs['auth_type'] = parsed_args.auth_type if parsed_args.name is not None: attrs['name'] = parsed_args.name if 'remote_as' in parsed_args: attrs['remote_as'] = parsed_args.remote_as if 'peer_ip' in parsed_args: attrs['peer_ip'] = parsed_args.peer_ip if 'password' in parsed_args: attrs['password'] = parsed_args.password if 'project' in parsed_args and parsed_args.project is not None: identity_client = client_manager.identity project_id = nc_osc_utils.find_project( identity_client, parsed_args.project, parsed_args.project_domain, ).id attrs['tenant_id'] = project_id return attrs class CreateBgpPeer(command.ShowOne): _description = _("Create a BGP peer") def get_parser(self, prog_name): parser = super(CreateBgpPeer, self).get_parser(prog_name) parser.add_argument( 'name', metavar='', help=_("Name of the BGP peer to create")) parser.add_argument( '--peer-ip', metavar='', required=True, help=_("Peer IP address")) parser.add_argument( '--remote-as', required=True, metavar='', help=_("Peer AS number. (Integer in [%(min_val)s, %(max_val)s] " "is allowed)") % {'min_val': constants.MIN_AS_NUM, 'max_val': constants.MAX_AS_NUM}) parser.add_argument( '--auth-type', metavar='', choices=['none', 'md5'], type=nc_utils.convert_to_lowercase, default='none', help=_("Authentication algorithm. Supported algorithms: " "none (default), md5")) parser.add_argument( '--password', metavar='', help=_("Authentication password")) nc_osc_utils.add_project_owner_option_to_parser(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_attrs(self.app.client_manager, parsed_args) body = {constants.BGP_PEER: attrs} obj = client.create_bgp_peer(body)[constants.BGP_PEER] columns, display_columns = nc_osc_utils.get_columns(obj) data = utils.get_dict_properties(obj, columns) return display_columns, data class DeleteBgpPeer(command.Command): _description = _("Delete a BGP peer") def get_parser(self, prog_name): parser = super(DeleteBgpPeer, self).get_parser(prog_name) parser.add_argument( 'bgp_peer', metavar="", help=_("BGP peer to delete (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient id = client.find_resource(constants.BGP_PEER, parsed_args.bgp_peer)['id'] client.delete_bgp_peer(id) class ListBgpPeer(command.Lister): _description = _("List BGP peers") def take_action(self, parsed_args): data = self.app.client_manager.neutronclient.list_bgp_peers() headers = ('ID', 'Name', 'Peer IP', 'Remote AS') columns = ('id', 'name', 'peer_ip', 'remote_as') return (headers, (utils.get_dict_properties( s, columns, ) for s in data[constants.BGP_PEERS])) class SetBgpPeer(command.Command): _description = _("Update a BGP peer") resource = constants.BGP_PEER def get_parser(self, prog_name): parser = super(SetBgpPeer, self).get_parser(prog_name) parser.add_argument( '--name', help=_("Updated name of the BGP peer")) parser.add_argument( '--password', metavar='', help=_("Updated authentication password")) parser.add_argument( 'bgp_peer', metavar="", help=_("BGP peer to update (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient id = client.find_resource(constants.BGP_PEER, parsed_args.bgp_peer)['id'] attrs = _get_attrs(self.app.client_manager, parsed_args) body = {} body[constants.BGP_PEER] = attrs client.update_bgp_peer(id, body) class ShowBgpPeer(command.ShowOne): _description = _("Show information for a BGP peer") def get_parser(self, prog_name): parser = super(ShowBgpPeer, self).get_parser(prog_name) parser.add_argument( 'bgp_peer', metavar="", help=_("BGP peer to display (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient id = client.find_resource(constants.BGP_PEER, parsed_args.bgp_peer)['id'] obj = client.show_bgp_peer(id)[constants.BGP_PEER] columns, display_columns = nc_osc_utils.get_columns(obj) data = utils.get_dict_properties(obj, columns) return display_columns, data python-neutronclient-6.7.0/neutronclient/osc/v2/dynamic_routing/bgp_speaker.py0000666000175100017510000003000513232473350030015 0ustar zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from osc_lib.command import command from osc_lib import utils from neutronclient._i18n import _ from neutronclient.osc import utils as nc_osc_utils from neutronclient.osc.v2.dynamic_routing import constants def _get_attrs(client_manager, parsed_args): attrs = {} if parsed_args.name is not None: attrs['name'] = str(parsed_args.name) if 'local_as' in parsed_args: attrs['local_as'] = parsed_args.local_as if 'ip_version' in parsed_args: attrs['ip_version'] = parsed_args.ip_version if parsed_args.advertise_tenant_networks: attrs['advertise_tenant_networks'] = True if parsed_args.no_advertise_tenant_networks: attrs['advertise_tenant_networks'] = False if parsed_args.advertise_floating_ip_host_routes: attrs['advertise_floating_ip_host_routes'] = True if parsed_args.no_advertise_floating_ip_host_routes: attrs['advertise_floating_ip_host_routes'] = False if 'project' in parsed_args and parsed_args.project is not None: identity_client = client_manager.identity project_id = nc_osc_utils.find_project( identity_client, parsed_args.project, parsed_args.project_domain, ).id attrs['tenant_id'] = project_id return attrs def add_common_arguments(parser): parser.add_argument( '--advertise-floating-ip-host-routes', action='store_true', help=_("Enable the advertisement of floating IP host routes " "by the BGP speaker. (default)")) parser.add_argument( '--no-advertise-floating-ip-host-routes', action='store_true', help=_("Disable the advertisement of floating IP host routes " "by the BGP speaker.")) parser.add_argument( '--advertise-tenant-networks', action='store_true', help=_("Enable the advertisement of tenant network routes " "by the BGP speaker. (default)")) parser.add_argument( '--no-advertise-tenant-networks', action='store_true', help=_("Disable the advertisement of tenant network routes " "by the BGP speaker.")) class AddNetworkToSpeaker(command.Command): _description = _("Add a network to a BGP speaker") def get_parser(self, prog_name): parser = super(AddNetworkToSpeaker, self).get_parser(prog_name) parser.add_argument( 'bgp_speaker', metavar='', help=_("BGP speaker (name or ID)")) parser.add_argument( 'network', metavar='', help=_("Network to add (name or ID)")) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient speaker_id = client.find_resource(constants.BGP_SPEAKER, parsed_args.bgp_speaker)['id'] net_id = client.find_resource('network', parsed_args.network)['id'] client.add_network_to_bgp_speaker(speaker_id, {'network_id': net_id}) class AddPeerToSpeaker(command.Command): _description = _("Add a peer to a BGP speaker") def get_parser(self, prog_name): parser = super(AddPeerToSpeaker, self).get_parser(prog_name) parser.add_argument( 'bgp_speaker', metavar='', help=_("BGP speaker (name or ID)")) parser.add_argument( 'bgp_peer', metavar='', help=_("BGP Peer to add (name or ID)")) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient speaker_id = client.find_resource(constants.BGP_SPEAKER, parsed_args.bgp_speaker)['id'] peer_id = client.find_resource(constants.BGP_PEER, parsed_args.bgp_peer)['id'] client.add_peer_to_bgp_speaker(speaker_id, {'bgp_peer_id': peer_id}) class CreateBgpSpeaker(command.ShowOne): _description = _("Create a BGP speaker") def get_parser(self, prog_name): parser = super(CreateBgpSpeaker, self).get_parser(prog_name) parser.add_argument( 'name', metavar='', help=_("Name of the BGP speaker to create")) parser.add_argument( '--local-as', metavar='', required=True, help=_("Local AS number. (Integer in [%(min_val)s, %(max_val)s] " "is allowed.)") % {'min_val': constants.MIN_AS_NUM, 'max_val': constants.MAX_AS_NUM}) parser.add_argument( '--ip-version', type=int, choices=[4, 6], default=4, help=_("IP version for the BGP speaker (default is 4)")) add_common_arguments(parser) nc_osc_utils.add_project_owner_option_to_parser(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_attrs(self.app.client_manager, parsed_args) body = {} body[constants.BGP_SPEAKER] = attrs obj = client.create_bgp_speaker(body)[constants.BGP_SPEAKER] columns, display_columns = nc_osc_utils.get_columns(obj) data = utils.get_dict_properties(obj, columns) return display_columns, data class DeleteBgpSpeaker(command.Command): _description = _("Delete a BGP speaker") def get_parser(self, prog_name): parser = super(DeleteBgpSpeaker, self).get_parser(prog_name) parser.add_argument( 'bgp_speaker', metavar="", help=_("BGP speaker to delete (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient id = client.find_resource(constants.BGP_SPEAKER, parsed_args.bgp_speaker)['id'] client.delete_bgp_speaker(id) class ListBgpSpeaker(command.Lister): _description = _("List BGP speakers") def get_parser(self, prog_name): parser = super(ListBgpSpeaker, self).get_parser(prog_name) parser.add_argument( '--agent', metavar='', help=_("List BGP speakers hosted by an agent (ID only)")) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient if parsed_args.agent is not None: data = client.list_bgp_speaker_on_dragent(parsed_args.agent_id) else: data = client.list_bgp_speakers() headers = ('ID', 'Name', 'Local AS', 'IP Version') columns = ('id', 'name', 'local_as', 'ip_version') return (headers, (utils.get_dict_properties(s, columns) for s in data[constants.BGP_SPEAKERS])) class ListRoutesAdvertisedBySpeaker(command.Lister): _description = _("List routes advertised") def get_parser(self, prog_name): parser = super(ListRoutesAdvertisedBySpeaker, self).get_parser(prog_name) parser.add_argument( 'bgp_speaker', metavar='', help=_("BGP speaker (name or ID)")) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient speaker_id = client.find_resource(constants.BGP_SPEAKER, parsed_args.bgp_speaker)['id'] data = client.list_route_advertised_from_bgp_speaker(speaker_id) headers = ('ID', 'Destination', 'Nexthop') columns = ('id', 'destination', 'next_hop') return (headers, (utils.get_dict_properties(s, columns) for s in data['advertised_routes'])) class RemoveNetworkFromSpeaker(command.Command): _description = _("Remove a network from a BGP speaker") def get_parser(self, prog_name): parser = super(RemoveNetworkFromSpeaker, self).get_parser(prog_name) parser.add_argument( 'bgp_speaker', metavar='', help=_("BGP speaker (name or ID)")) parser.add_argument( 'network', metavar='', help=_("Network to remove (name or ID)")) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient speaker_id = client.find_resource(constants.BGP_SPEAKER, parsed_args.bgp_speaker)['id'] net_id = client.find_resource('network', parsed_args.network)['id'] client.remove_network_from_bgp_speaker(speaker_id, {'network_id': net_id}) class RemovePeerFromSpeaker(command.Command): _description = _("Remove a peer from a BGP speaker") def get_parser(self, prog_name): parser = super(RemovePeerFromSpeaker, self).get_parser(prog_name) parser.add_argument( 'bgp_speaker', metavar='', help=_("BGP speaker (name or ID)")) parser.add_argument( 'bgp_peer', metavar='', help=_("BGP Peer to remove (name or ID)")) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient speaker_id = client.find_resource(constants.BGP_SPEAKER, parsed_args.bgp_speaker)['id'] peer_id = client.find_resource(constants.BGP_PEER, parsed_args.bgp_peer)['id'] client.remove_peer_from_bgp_speaker(speaker_id, {'bgp_peer_id': peer_id}) class SetBgpSpeaker(command.Command): _description = _("Set BGP speaker properties") resource = constants.BGP_SPEAKER def get_parser(self, prog_name): parser = super(SetBgpSpeaker, self).get_parser(prog_name) parser.add_argument( 'bgp_speaker', metavar="", help=_("BGP speaker to update (name or ID)") ) parser.add_argument( '--name', help=_("Name of the BGP speaker to update")) add_common_arguments(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient id = client.find_resource(constants.BGP_SPEAKER, parsed_args.bgp_speaker)['id'] attrs = _get_attrs(self.app.client_manager, parsed_args) body = {} body[constants.BGP_SPEAKER] = attrs client.update_bgp_speaker(id, body) class ShowBgpSpeaker(command.ShowOne): _description = _("Show a BGP speaker") def get_parser(self, prog_name): parser = super(ShowBgpSpeaker, self).get_parser(prog_name) parser.add_argument( 'bgp_speaker', metavar="", help=_("BGP speaker to display (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient id = client.find_resource(constants.BGP_SPEAKER, parsed_args.bgp_speaker)['id'] obj = client.show_bgp_speaker(id)[constants.BGP_SPEAKER] columns, display_columns = nc_osc_utils.get_columns(obj) data = utils.get_dict_properties(obj, columns) return display_columns, data python-neutronclient-6.7.0/neutronclient/osc/v2/dynamic_routing/constants.py0000666000175100017510000000130713232473350027552 0ustar zuulzuul00000000000000# 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. BGP_SPEAKERS = 'bgp_speakers' BGP_SPEAKER = 'bgp_speaker' BGP_PEERS = 'bgp_peers' BGP_PEER = 'bgp_peer' MIN_AS_NUM = 1 MAX_AS_NUM = 65535 python-neutronclient-6.7.0/neutronclient/osc/v2/dynamic_routing/bgp_dragent.py0000666000175100017510000000714713232473350030022 0ustar zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from osc_lib.command import command from osc_lib import utils from neutronclient._i18n import _ from neutronclient.osc.v2.dynamic_routing import constants def _format_alive_state(item): return ':-)' if item else 'XXX' _formatters = { 'alive': _format_alive_state } def add_common_args(parser): parser.add_argument('dragent_id', metavar='', help=_("ID of the dynamic routing agent")) parser.add_argument('bgp_speaker', metavar='', help=_("ID or name of the BGP speaker")) class AddBgpSpeakerToDRAgent(command.Command): """Add a BGP speaker to a dynamic routing agent""" def get_parser(self, prog_name): parser = super(AddBgpSpeakerToDRAgent, self).get_parser(prog_name) add_common_args(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient speaker_id = client.find_resource(constants.BGP_SPEAKER, parsed_args.bgp_speaker)['id'] client.add_bgp_speaker_to_dragent( parsed_args.dragent_id, {'bgp_speaker_id': speaker_id}) class RemoveBgpSpeakerFromDRAgent(command.Command): """Removes a BGP speaker from a dynamic routing agent""" def get_parser(self, prog_name): parser = super(RemoveBgpSpeakerFromDRAgent, self).get_parser( prog_name) add_common_args(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient speaker_id = client.find_resource(constants.BGP_SPEAKER, parsed_args.bgp_speaker)['id'] client.remove_bgp_speaker_from_dragent(parsed_args.dragent_id, speaker_id) class ListDRAgentsHostingBgpSpeaker(command.Lister): """List dynamic routing agents hosting a BGP speaker""" resource = 'agent' list_columns = ['id', 'host', 'admin_state_up', 'alive'] unknown_parts_flag = False def get_parser(self, prog_name): parser = super(ListDRAgentsHostingBgpSpeaker, self).get_parser(prog_name) parser.add_argument('bgp_speaker', metavar='', help=_("ID or name of the BGP speaker")) return parser def take_action(self, parsed_args): search_opts = {} client = self.app.client_manager.neutronclient speaker_id = client.find_resource(constants.BGP_SPEAKER, parsed_args.bgp_speaker)['id'] search_opts['bgp_speaker'] = speaker_id data = client.list_dragents_hosting_bgp_speaker(**search_opts) headers = ('ID', 'Host', 'State', 'Alive') columns = ('id', 'host', 'admin_state_up', 'alive') return (headers, (utils.get_dict_properties( s, columns, formatters=_formatters, ) for s in data['agents'])) python-neutronclient-6.7.0/neutronclient/osc/v2/dynamic_routing/__init__.py0000666000175100017510000000000013232473350027262 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/fwaas/0000775000175100017510000000000013232473710023067 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/fwaas/firewallrule.py0000666000175100017510000004037513232473350026151 0ustar zuulzuul00000000000000# Copyright 2016-2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy import logging from cliff import columns as cliff_columns from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from neutronclient._i18n import _ from neutronclient.common import utils as nc_utils from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.fwaas import constants as const LOG = logging.getLogger(__name__) _attr_map = ( ('id', 'ID', osc_utils.LIST_BOTH), ('name', 'Name', osc_utils.LIST_BOTH), ('enabled', 'Enabled', osc_utils.LIST_BOTH), ('summary', 'Summary', osc_utils.LIST_SHORT_ONLY), ('description', 'Description', osc_utils.LIST_LONG_ONLY), ('ip_version', 'IP Version', osc_utils.LIST_LONG_ONLY), ('action', 'Action', osc_utils.LIST_LONG_ONLY), ('protocol', 'Protocol', osc_utils.LIST_LONG_ONLY), ('source_ip_address', 'Source IP Address', osc_utils.LIST_LONG_ONLY), ('source_port', 'Source Port', osc_utils.LIST_LONG_ONLY), ('destination_ip_address', 'Destination IP Address', osc_utils.LIST_LONG_ONLY), ('destination_port', 'Destination Port', osc_utils.LIST_LONG_ONLY), ('shared', 'Shared', osc_utils.LIST_LONG_ONLY), ('tenant_id', 'Project', osc_utils.LIST_LONG_ONLY), ) def _get_common_parser(parser): parser.add_argument( '--name', metavar='', help=_('Name of the firewall rule')) parser.add_argument( '--description', metavar='', help=_('Description of the firewall rule')) parser.add_argument( '--protocol', choices=['tcp', 'udp', 'icmp', 'any'], type=nc_utils.convert_to_lowercase, help=_('Protocol for the firewall rule')) parser.add_argument( '--action', choices=['allow', 'deny', 'reject'], type=nc_utils.convert_to_lowercase, help=_('Action for the firewall rule')) parser.add_argument( '--ip-version', metavar='', choices=['4', '6'], help=_('Set IP version 4 or 6 (default is 4)')) src_ip_group = parser.add_mutually_exclusive_group() src_ip_group.add_argument( '--source-ip-address', metavar='', help=_('Source IP address or subnet')) src_ip_group.add_argument( '--no-source-ip-address', action='store_true', help=_('Detach source IP address')) dst_ip_group = parser.add_mutually_exclusive_group() dst_ip_group.add_argument( '--destination-ip-address', metavar='', help=_('Destination IP address or subnet')) dst_ip_group.add_argument( '--no-destination-ip-address', action='store_true', help=_('Detach destination IP address')) src_port_group = parser.add_mutually_exclusive_group() src_port_group.add_argument( '--source-port', metavar='', help=_('Source port number or range' '(integer in [1, 65535] or range like 123:456)')) src_port_group.add_argument( '--no-source-port', action='store_true', help=_('Detach source port number or range')) dst_port_group = parser.add_mutually_exclusive_group() dst_port_group.add_argument( '--destination-port', metavar='', help=_('Destination port number or range' '(integer in [1, 65535] or range like 123:456)')) dst_port_group.add_argument( '--no-destination-port', action='store_true', help=_('Detach destination port number or range')) shared_group = parser.add_mutually_exclusive_group() shared_group.add_argument( '--public', action='store_true', help=_('Make the firewall policy public, which allows it to be ' 'used in all projects (as opposed to the default, ' 'which is to restrict its use to the current project). ' 'This option is deprecated and would be removed in R Release')) shared_group.add_argument( '--private', action='store_true', help=_( 'Restrict use of the firewall rule to the current project.' 'This option is deprecated and would be removed in R release.')) shared_group.add_argument( '--share', action='store_true', help=_('Share the firewall rule to be used in all projects ' '(by default, it is restricted to be used by the ' 'current project).')) shared_group.add_argument( '--no-share', action='store_true', help=_('Restrict use of the firewall rule to the current project')) enable_group = parser.add_mutually_exclusive_group() enable_group.add_argument( '--enable-rule', action='store_true', help=_('Enable this rule (default is enabled)')) enable_group.add_argument( '--disable-rule', action='store_true', help=_('Disable this rule')) return parser def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} if is_create: if 'project' in parsed_args and parsed_args.project is not None: attrs['tenant_id'] = osc_utils.find_project( client_manager.identity, parsed_args.project, parsed_args.project_domain, ).id if parsed_args.name: attrs['name'] = str(parsed_args.name) if parsed_args.description: attrs['description'] = str(parsed_args.description) if parsed_args.protocol: protocol = parsed_args.protocol attrs['protocol'] = None if protocol == 'any' else protocol if parsed_args.action: attrs['action'] = parsed_args.action if parsed_args.ip_version: attrs['ip_version'] = str(parsed_args.ip_version) if parsed_args.source_port: attrs['source_port'] = parsed_args.source_port if parsed_args.no_source_port: attrs['source_port'] = None if parsed_args.source_ip_address: attrs['source_ip_address'] = parsed_args.source_ip_address if parsed_args.no_source_ip_address: attrs['source_ip_address'] = None if parsed_args.destination_port: attrs['destination_port'] = str(parsed_args.destination_port) if parsed_args.no_destination_port: attrs['destination_port'] = None if parsed_args.destination_ip_address: attrs['destination_ip_address'] = str( parsed_args.destination_ip_address) if parsed_args.no_destination_ip_address: attrs['destination_ip_address'] = None if parsed_args.enable_rule: attrs['enabled'] = True if parsed_args.disable_rule: attrs['enabled'] = False if parsed_args.share or parsed_args.public: attrs['shared'] = True if parsed_args.no_share or parsed_args.private: attrs['shared'] = False return attrs class ProtocolColumn(cliff_columns.FormattableColumn): def human_readable(self): return self._value if self._value else 'any' _formatters = {'protocol': ProtocolColumn} class CreateFirewallRule(command.ShowOne): _description = _("Create a new firewall rule") def get_parser(self, prog_name): parser = super(CreateFirewallRule, self).get_parser(prog_name) _get_common_parser(parser) osc_utils.add_project_owner_option_to_parser(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) obj = client.create_fwaas_firewall_rule( {const.FWR: attrs})[const.FWR] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns, formatters=_formatters) return display_columns, data class DeleteFirewallRule(command.Command): _description = _("Delete firewall rule(s)") def get_parser(self, prog_name): parser = super(DeleteFirewallRule, self).get_parser(prog_name) parser.add_argument( const.FWR, metavar='', nargs='+', help=_('Firewall rule(s) to delete (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient result = 0 for fwr in parsed_args.firewall_rule: try: fwr_id = client.find_resource( const.FWR, fwr, cmd_resource=const.CMD_FWR)['id'] client.delete_fwaas_firewall_rule(fwr_id) except Exception as e: result += 1 LOG.error(_("Failed to delete Firewall rule with " "name or ID '%(firewall_rule)s': %(e)s"), {const.FWR: fwr, 'e': e}) if result > 0: total = len(parsed_args.firewall_rule) msg = (_("%(result)s of %(total)s firewall rule(s) failed " "to delete.") % {'result': result, 'total': total}) raise exceptions.CommandError(msg) class ListFirewallRule(command.Lister): _description = _("List firewall rules that belong to a given tenant") def get_parser(self, prog_name): parser = super(ListFirewallRule, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', default=False, help=_("List additional fields in output") ) return parser def extend_list(self, data, parsed_args): ext_data = copy.deepcopy(data) for d in ext_data: protocol = d['protocol'].upper() if d['protocol'] else 'ANY' src_ip = 'none specified' dst_ip = 'none specified' src_port = '(none specified)' dst_port = '(none specified)' if 'source_ip_address' in d and d['source_ip_address']: src_ip = str(d['source_ip_address']).lower() if 'source_port' in d and d['source_port']: src_port = '(' + str(d['source_port']).lower() + ')' if 'destination_ip_address' in d and d['destination_ip_address']: dst_ip = str(d['destination_ip_address']).lower() if 'destination_port' in d and d['destination_port']: dst_port = '(' + str(d['destination_port']).lower() + ')' action = d['action'] if d.get('action') else 'no-action' src = 'source(port): ' + src_ip + src_port dst = 'dest(port): ' + dst_ip + dst_port d['summary'] = ',\n '.join([protocol, src, dst, action]) return ext_data def take_action(self, parsed_args): client = self.app.client_manager.neutronclient obj = client.list_fwaas_firewall_rules()[const.FWRS] obj_extend = self.extend_list(obj, parsed_args) headers, columns = osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties( s, columns, formatters=_formatters) for s in obj_extend)) class SetFirewallRule(command.Command): _description = _("Set firewall rule properties") def get_parser(self, prog_name): parser = super(SetFirewallRule, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( const.FWR, metavar='', help=_('Firewall rule to set (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) fwr_id = client.find_resource( const.FWR, parsed_args.firewall_rule, cmd_resource=const.CMD_FWR)['id'] try: client.update_fwaas_firewall_rule(fwr_id, {const.FWR: attrs}) except Exception as e: msg = (_("Failed to set firewall rule '%(rule)s': %(e)s") % {'rule': parsed_args.firewall_rule, 'e': e}) raise exceptions.CommandError(msg) class ShowFirewallRule(command.ShowOne): _description = _("Display firewall rule details") def get_parser(self, prog_name): parser = super(ShowFirewallRule, self).get_parser(prog_name) parser.add_argument( const.FWR, metavar='', help=_('Firewall rule to display (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient fwr_id = client.find_resource( const.FWR, parsed_args.firewall_rule, cmd_resource=const.CMD_FWR)['id'] obj = client.show_fwaas_firewall_rule(fwr_id)[const.FWR] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns, formatters=_formatters) return (display_columns, data) class UnsetFirewallRule(command.Command): _description = _("Unset firewall rule properties") def get_parser(self, prog_name): parser = super(UnsetFirewallRule, self).get_parser(prog_name) parser.add_argument( const.FWR, metavar='', help=_('Firewall rule to unset (name or ID)')) parser.add_argument( '--source-ip-address', action='store_true', help=_('Source IP address or subnet')) parser.add_argument( '--destination-ip-address', action='store_true', help=_('Destination IP address or subnet')) parser.add_argument( '--source-port', action='store_true', help=_('Source port number or range' '(integer in [1, 65535] or range like 123:456)')) parser.add_argument( '--destination-port', action='store_true', help=_('Destination port number or range' '(integer in [1, 65535] or range like 123:456)')) parser.add_argument( '--share', action='store_true', help=_('Restrict use of the firewall rule to the current project')) parser.add_argument( '--public', action='store_true', help=_('Restrict use of the firewall rule to the current project. ' 'This option is deprecated and would be removed in ' 'R Release.')) parser.add_argument( '--enable-rule', action='store_true', help=_('Disable this rule')) return parser def _get_attrs(self, client_manager, parsed_args): attrs = {} if parsed_args.source_ip_address: attrs['source_ip_address'] = None if parsed_args.source_port: attrs['source_port'] = None if parsed_args.destination_ip_address: attrs['destination_ip_address'] = None if parsed_args.destination_port: attrs['destination_port'] = None if parsed_args.share or parsed_args.public: attrs['shared'] = False if parsed_args.enable_rule: attrs['enabled'] = False return attrs def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = self._get_attrs(self.app.client_manager, parsed_args) fwr_id = client.find_resource( const.FWR, parsed_args.firewall_rule, cmd_resource=const.CMD_FWR)['id'] try: client.update_fwaas_firewall_rule(fwr_id, {const.FWR: attrs}) except Exception as e: msg = (_("Failed to unset firewall rule '%(rule)s': %(e)s") % {'rule': parsed_args.firewall_rule, 'e': e}) raise exceptions.CommandError(msg) python-neutronclient-6.7.0/neutronclient/osc/v2/fwaas/firewallpolicy.py0000666000175100017510000004217713232473350026503 0ustar zuulzuul00000000000000# Copyright 2016-2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from __future__ import print_function import logging from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from neutronclient._i18n import _ from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.fwaas import constants as const LOG = logging.getLogger(__name__) _formatters = {} _attr_map = ( ('id', 'ID', osc_utils.LIST_BOTH), ('name', 'Name', osc_utils.LIST_BOTH), ('firewall_rules', 'Firewall Rules', osc_utils.LIST_BOTH), ('description', 'Description', osc_utils.LIST_LONG_ONLY), ('audited', 'Audited', osc_utils.LIST_LONG_ONLY), ('shared', 'Shared', osc_utils.LIST_LONG_ONLY), ('tenant_id', 'Project', osc_utils.LIST_LONG_ONLY), ) def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} client = client_manager.neutronclient if is_create: if 'project' in parsed_args and parsed_args.project is not None: attrs['tenant_id'] = osc_utils.find_project( client_manager.identity, parsed_args.project, parsed_args.project_domain, ).id if parsed_args.firewall_rule and parsed_args.no_firewall_rule: _firewall_rules = [] for f in parsed_args.firewall_rule: _firewall_rules.append(client.find_resource( const.FWR, f, cmd_resource=const.CMD_FWR)['id']) attrs[const.FWRS] = _firewall_rules elif parsed_args.firewall_rule: rules = [] if not is_create: rules += client.find_resource( const.FWP, parsed_args.firewall_policy, cmd_resource=const.CMD_FWP)[const.FWRS] for f in parsed_args.firewall_rule: rules.append(client.find_resource( const.FWR, f, cmd_resource=const.CMD_FWR)['id']) attrs[const.FWRS] = rules elif parsed_args.no_firewall_rule: attrs[const.FWRS] = [] if parsed_args.audited: attrs['audited'] = True if parsed_args.no_audited: attrs['audited'] = False if parsed_args.name: attrs['name'] = str(parsed_args.name) if parsed_args.description: attrs['description'] = str(parsed_args.description) if parsed_args.share or parsed_args.public: attrs['shared'] = True if parsed_args.no_share or parsed_args.private: attrs['shared'] = False return attrs def _get_common_parser(parser): parser.add_argument( '--description', help=_('Description of the firewall policy')) audited_group = parser.add_mutually_exclusive_group() audited_group.add_argument( '--audited', action='store_true', help=_('Enable auditing for the policy')) audited_group.add_argument( '--no-audited', action='store_true', help=_('Disable auditing for the policy')) shared_group = parser.add_mutually_exclusive_group() shared_group.add_argument( '--share', action='store_true', help=_('Share the firewall policy to be used in all projects ' '(by default, it is restricted to be used by the ' 'current project).')) shared_group.add_argument( '--public', action='store_true', help=_('Make the firewall policy public, which allows it to be ' 'used in all projects (as opposed to the default, which ' 'is to restrict its use to the current project.) This ' 'option is deprecated and would be removed in R release.')) shared_group.add_argument( '--private', action='store_true', help=_( 'Restrict use of the firewall policy to the current project.' 'This option is deprecated and would be removed in R release.')) shared_group.add_argument( '--no-share', action='store_true', help=_('Restrict use of the firewall policy to the ' 'current project')) return parser class CreateFirewallPolicy(command.ShowOne): _description = _("Create a new firewall policy") def get_parser(self, prog_name): parser = super(CreateFirewallPolicy, self).get_parser(prog_name) _get_common_parser(parser) osc_utils.add_project_owner_option_to_parser(parser) parser.add_argument( 'name', metavar='', help=_('Name for the firewall policy')) fwr_group = parser.add_mutually_exclusive_group() fwr_group.add_argument( '--firewall-rule', action='append', metavar='', help=_('Firewall rule(s) to apply (name or ID)')) fwr_group.add_argument( '--no-firewall-rule', action='store_true', help=_('Unset all firewall rules from firewall policy')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) obj = client.create_fwaas_firewall_policy( {const.FWP: attrs})[const.FWP] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns, formatters=_formatters) return (display_columns, data) class DeleteFirewallPolicy(command.Command): _description = _("Delete firewall policy(s)") def get_parser(self, prog_name): parser = super(DeleteFirewallPolicy, self).get_parser(prog_name) parser.add_argument( const.FWP, metavar='', nargs='+', help=_('Firewall policy(s) to delete (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient result = 0 for fwp in parsed_args.firewall_policy: try: fwp_id = client.find_resource( const.FWP, fwp, cmd_resource='fwaas_' + const.FWP)['id'] client.delete_fwaas_firewall_policy(fwp_id) except Exception as e: result += 1 LOG.error(_("Failed to delete Firewall policy with " "name or ID '%(firewall_policy)s': %(e)s"), {const.FWP: fwp, 'e': e}) if result > 0: total = len(parsed_args.firewall_policy) msg = (_("%(result)s of %(total)s firewall policy(s) " "failed to delete.") % {'result': result, 'total': total}) raise exceptions.CommandError(msg) class FirewallPolicyInsertRule(command.Command): _description = _("Insert a rule into a given firewall policy") def get_parser(self, prog_name): parser = super(FirewallPolicyInsertRule, self).get_parser(prog_name) parser.add_argument( const.FWP, metavar='', help=_('Firewall policy to insert rule (name or ID)')) parser.add_argument( '--insert-before', metavar='', help=_('Insert the new rule before this existing rule ' '(name or ID)')) parser.add_argument( '--insert-after', metavar='', help=_('Insert the new rule after this existing rule ' '(name or ID)')) parser.add_argument( const.FWR, metavar='', help=_('Firewall rule to be inserted (name or ID)')) return parser def args2body(self, parsed_args): client = self.app.client_manager.neutronclient _rule_id = _get_required_firewall_rule(client, parsed_args) _insert_before = '' if 'insert_before' in parsed_args: if parsed_args.insert_before: _insert_before = client.find_resource( const.FWR, parsed_args.insert_before, cmd_resource=const.CMD_FWR)['id'] _insert_after = '' if 'insert_after' in parsed_args: if parsed_args.insert_after: _insert_after = client.find_resource( const.FWR, parsed_args.insert_after, cmd_resource=const.CMD_FWR)['id'] return {'firewall_rule_id': _rule_id, 'insert_before': _insert_before, 'insert_after': _insert_after} def take_action(self, parsed_args): client = self.app.client_manager.neutronclient policy_id = client.find_resource( const.FWP, parsed_args.firewall_policy, cmd_resource=const.CMD_FWP)['id'] body = self.args2body(parsed_args) client.insert_rule_fwaas_firewall_policy(policy_id, body) rule_id = body['firewall_rule_id'] policy = parsed_args.firewall_policy print((_('Inserted firewall rule %(rule)s in firewall policy ' '%(policy)s') % {'rule': rule_id, 'policy': policy}), file=self.app.stdout) class FirewallPolicyRemoveRule(command.Command): _description = _("Remove a rule from a given firewall policy") def get_parser(self, prog_name): parser = super(FirewallPolicyRemoveRule, self).get_parser(prog_name) parser.add_argument( const.FWP, metavar='', help=_('Firewall policy to remove rule (name or ID)')) parser.add_argument( const.FWR, metavar='', help=_('Firewall rule to remove from policy (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient policy_id = client.find_resource( const.FWP, parsed_args.firewall_policy, cmd_resource=const.CMD_FWP)['id'] fwr_id = _get_required_firewall_rule(client, parsed_args) body = {'firewall_rule_id': fwr_id} client.remove_rule_fwaas_firewall_policy(policy_id, body) rule_id = body['firewall_rule_id'] policy = parsed_args.firewall_policy print((_('Removed firewall rule %(rule)s from firewall policy ' '%(policy)s') % {'rule': rule_id, 'policy': policy}), file=self.app.stdout) class ListFirewallPolicy(command.Lister): _description = _("List firewall policies") def get_parser(self, prog_name): parser = super(ListFirewallPolicy, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', default=False, help=_("List additional fields in output") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient obj = client.list_fwaas_firewall_policies()[const.FWPS] headers, columns = osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties( s, columns, formatters=_formatters) for s in obj)) class SetFirewallPolicy(command.Command): _description = _("Set firewall policy properties") def get_parser(self, prog_name): parser = super(SetFirewallPolicy, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( const.FWP, metavar='', help=_('Firewall policy to update (name or ID)')) parser.add_argument( '--name', metavar='', help=_('Name for the firewall policy')) parser.add_argument( '--firewall-rule', action='append', metavar='', help=_('Firewall rule(s) to apply (name or ID)')) parser.add_argument( '--no-firewall-rule', action='store_true', help=_('Remove all firewall rules from firewall policy')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient fwp_id = client.find_resource( const.FWP, parsed_args.firewall_policy, cmd_resource=const.CMD_FWP)['id'] attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) try: client.update_fwaas_firewall_policy(fwp_id, {const.FWP: attrs}) except Exception as e: msg = (_("Failed to set firewall policy '%(policy)s': %(e)s") % {'policy': parsed_args.firewall_policy, 'e': e}) raise exceptions.CommandError(msg) class ShowFirewallPolicy(command.ShowOne): _description = _("Display firewall policy details") def get_parser(self, prog_name): parser = super(ShowFirewallPolicy, self).get_parser(prog_name) parser.add_argument( const.FWP, metavar='', help=_('Firewall policy to show (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient fwp_id = client.find_resource(const.FWP, parsed_args.firewall_policy, cmd_resource=const.CMD_FWP)['id'] obj = client.show_fwaas_firewall_policy(fwp_id)[const.FWP] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns, formatters=_formatters) return (display_columns, data) def _get_required_firewall_rule(client, parsed_args): if not parsed_args.firewall_rule: msg = (_("Firewall rule (name or ID) is required.")) raise exceptions.CommandError(msg) return client.find_resource( const.FWR, parsed_args.firewall_rule, cmd_resource=const.CMD_FWR)['id'] class UnsetFirewallPolicy(command.Command): _description = _("Unset firewall policy properties") def get_parser(self, prog_name): parser = super(UnsetFirewallPolicy, self).get_parser(prog_name) parser.add_argument( const.FWP, metavar='', help=_('Firewall policy to unset (name or ID)')) firewall_rule_group = parser.add_mutually_exclusive_group() firewall_rule_group.add_argument( '--firewall-rule', action='append', metavar='', help=_('Remove firewall rule(s) from the firewall policy ' '(name or ID)')) firewall_rule_group.add_argument( '--all-firewall-rule', action='store_true', help=_('Remove all firewall rules from the firewall policy')) parser.add_argument( '--audited', action='store_true', help=_('Disable auditing for the policy')) parser.add_argument( '--share', action='store_true', help=_('Restrict use of the firewall policy to the ' 'current project')) parser.add_argument( '--public', action='store_true', help=_('Restrict use of the firewall policy to the ' 'current project. This option is deprecated ' 'and would be removed in R release.')) return parser def _get_attrs(self, client_manager, parsed_args): attrs = {} client = client_manager.neutronclient if parsed_args.firewall_rule: current = client.find_resource( const.FWP, parsed_args.firewall_policy, cmd_resource=const.CMD_FWP)[const.FWRS] removed = [] for f in set(parsed_args.firewall_rule): removed.append(client.find_resource( const.FWR, f, cmd_resource=const.CMD_FWR)['id']) attrs[const.FWRS] = [r for r in current if r not in removed] if parsed_args.all_firewall_rule: attrs[const.FWRS] = [] if parsed_args.audited: attrs['audited'] = False if parsed_args.share or parsed_args.public: attrs['shared'] = False return attrs def take_action(self, parsed_args): client = self.app.client_manager.neutronclient fwp_id = client.find_resource( const.FWP, parsed_args.firewall_policy, cmd_resource=const.CMD_FWP)['id'] attrs = self._get_attrs(self.app.client_manager, parsed_args) try: client.update_fwaas_firewall_policy(fwp_id, {const.FWP: attrs}) except Exception as e: msg = (_("Failed to unset firewall policy '%(policy)s': %(e)s") % {'policy': parsed_args.firewall_policy, 'e': e}) raise exceptions.CommandError(msg) python-neutronclient-6.7.0/neutronclient/osc/v2/fwaas/constants.py0000666000175100017510000000153113232473350025457 0ustar zuulzuul00000000000000# Copyright 2016-2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # FWG = 'firewall_group' FWGS = 'firewall_groups' FWP = 'firewall_policy' FWPS = 'firewall_policies' FWR = 'firewall_rule' FWRS = 'firewall_rules' CMD_FWG = 'fwaas_' + FWG CMD_FWP = 'fwaas_' + FWP CMD_FWR = 'fwaas_' + FWR python-neutronclient-6.7.0/neutronclient/osc/v2/fwaas/firewallgroup.py0000666000175100017510000003746613232473350026345 0ustar zuulzuul00000000000000# Copyright 2016-2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import logging from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from neutronclient._i18n import _ from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.fwaas import constants as const from neutronclient.osc.v2 import utils as v2_utils LOG = logging.getLogger(__name__) _formatters = { 'admin_state_up': v2_utils.AdminStateColumn, } _attr_map = ( ('id', 'ID', osc_utils.LIST_BOTH), ('name', 'Name', osc_utils.LIST_BOTH), ('ingress_firewall_policy_id', 'Ingress Policy ID', osc_utils.LIST_BOTH), ('egress_firewall_policy_id', 'Egress Policy ID', osc_utils.LIST_BOTH), ('description', 'Description', osc_utils.LIST_LONG_ONLY), ('status', 'Status', osc_utils.LIST_LONG_ONLY), ('ports', 'Ports', osc_utils.LIST_LONG_ONLY), ('admin_state_up', 'State', osc_utils.LIST_LONG_ONLY), ('shared', 'Shared', osc_utils.LIST_LONG_ONLY), ('tenant_id', 'Project', osc_utils.LIST_LONG_ONLY), ) def _get_common_parser(parser): parser.add_argument( '--name', help=_('Name for the firewall group')) parser.add_argument( '--description', metavar='', help=_('Description of the firewall group')) ingress_group = parser.add_mutually_exclusive_group() ingress_group.add_argument( '--ingress-firewall-policy', metavar='', dest='ingress_firewall_policy', help=_('Ingress firewall policy (name or ID)')) ingress_group.add_argument( '--no-ingress-firewall-policy', dest='no_ingress_firewall_policy', action='store_true', help=_('Detach ingress firewall policy from the firewall group')) egress_group = parser.add_mutually_exclusive_group() egress_group.add_argument( '--egress-firewall-policy', metavar='', dest='egress_firewall_policy', help=_('Egress firewall policy (name or ID)')) egress_group.add_argument( '--no-egress-firewall-policy', dest='no_egress_firewall_policy', action='store_true', help=_('Detach egress firewall policy from the firewall group')) shared_group = parser.add_mutually_exclusive_group() shared_group.add_argument( '--public', action='store_true', help=_('Make the firewall group public, which allows it to be ' 'used in all projects (as opposed to the default, ' 'which is to restrict its use to the current project). ' 'This option is deprecated and would be removed in R release.')) shared_group.add_argument( '--private', action='store_true', help=_('Restrict use of the firewall group to the ' 'current project. This option is deprecated ' 'and would be removed in R release.')) shared_group.add_argument( '--share', action='store_true', help=_('Share the firewall group to be used in all projects ' '(by default, it is restricted to be used by the ' 'current project).')) shared_group.add_argument( '--no-share', action='store_true', help=_('Restrict use of the firewall group to the ' 'current project')) admin_group = parser.add_mutually_exclusive_group() admin_group.add_argument( '--enable', action='store_true', help=_('Enable firewall group')) admin_group.add_argument( '--disable', action='store_true', help=_('Disable firewall group')) return parser def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} client = client_manager.neutronclient if is_create: if 'project' in parsed_args and parsed_args.project is not None: attrs['tenant_id'] = osc_utils.find_project( client_manager.identity, parsed_args.project, parsed_args.project_domain, ).id if (parsed_args.ingress_firewall_policy and parsed_args.no_ingress_firewall_policy): attrs['ingress_firewall_policy_id'] = client.find_resource( const.FWP, parsed_args.ingress_firewall_policy, cmd_resource=const.CMD_FWP)['id'] elif parsed_args.ingress_firewall_policy: attrs['ingress_firewall_policy_id'] = client.find_resource( const.FWP, parsed_args.ingress_firewall_policy, cmd_resource=const.CMD_FWP)['id'] elif parsed_args.no_ingress_firewall_policy: attrs['ingress_firewall_policy_id'] = None if (parsed_args.egress_firewall_policy and parsed_args.no_egress_firewall_policy): attrs['egress_firewall_policy_id'] = client.find_resource( const.FWP, parsed_args.egress_firewall_policy, cmd_resource=const.CMD_FWP)['id'] elif parsed_args.egress_firewall_policy: attrs['egress_firewall_policy_id'] = client.find_resource( const.FWP, parsed_args.egress_firewall_policy, cmd_resource=const.CMD_FWP)['id'] elif parsed_args.no_egress_firewall_policy: attrs['egress_firewall_policy_id'] = None if parsed_args.share or parsed_args.public: attrs['shared'] = True if parsed_args.no_share or parsed_args.private: attrs['shared'] = False if parsed_args.enable: attrs['admin_state_up'] = True if parsed_args.disable: attrs['admin_state_up'] = False if parsed_args.name: attrs['name'] = str(parsed_args.name) if parsed_args.description: attrs['description'] = str(parsed_args.description) if parsed_args.port and parsed_args.no_port: attrs['ports'] = sorted([client.find_resource( 'port', p)['id'] for p in set(parsed_args.port)]) elif parsed_args.port: ports = [] for p in set(parsed_args.port): ports.append(client.find_resource('port', p)['id']) if not is_create: ports += client.find_resource( const.FWG, parsed_args.firewall_group, cmd_resource=const.CMD_FWG)['ports'] attrs['ports'] = sorted(set(ports)) elif parsed_args.no_port: attrs['ports'] = [] return attrs class CreateFirewallGroup(command.ShowOne): _description = _("Create a new firewall group") def get_parser(self, prog_name): parser = super(CreateFirewallGroup, self).get_parser(prog_name) _get_common_parser(parser) osc_utils.add_project_owner_option_to_parser(parser) port_group = parser.add_mutually_exclusive_group() port_group.add_argument( '--port', metavar='', action='append', help=_('Port(s) (name or ID) to apply firewall group. This ' 'option can be repeated')) port_group.add_argument( '--no-port', dest='no_port', action='store_true', help=_('Detach all port from the firewall group')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) obj = client.create_fwaas_firewall_group( {const.FWG: attrs})[const.FWG] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns, formatters=_formatters) return (display_columns, data) class DeleteFirewallGroup(command.Command): _description = _("Delete firewall group(s)") def get_parser(self, prog_name): parser = super(DeleteFirewallGroup, self).get_parser(prog_name) parser.add_argument( const.FWG, metavar='', nargs='+', help=_('Firewall group(s) to delete (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient result = 0 for fwg in parsed_args.firewall_group: try: fwg_id = client.find_resource( const.FWG, fwg, cmd_resource=const.CMD_FWG)['id'] client.delete_fwaas_firewall_group(fwg_id) except Exception as e: result += 1 LOG.error(_("Failed to delete firewall group with " "name or ID '%(firewall_group)s': %(e)s"), {const.FWG: fwg, 'e': e}) if result > 0: total = len(parsed_args.firewall_group) msg = (_("%(result)s of %(total)s firewall group(s) " "failed to delete.") % {'result': result, 'total': total}) raise exceptions.CommandError(msg) class ListFirewallGroup(command.Lister): _description = _("List firewall groups") def get_parser(self, prog_name): parser = super(ListFirewallGroup, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', help=_("List additional fields in output") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient obj = client.list_fwaas_firewall_groups()[const.FWGS] headers, columns = osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties( s, columns, formatters=_formatters) for s in obj)) class SetFirewallGroup(command.Command): _description = _("Set firewall group properties") def get_parser(self, prog_name): parser = super(SetFirewallGroup, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( const.FWG, metavar='', help=_('Firewall group to update (name or ID)')) parser.add_argument( '--port', metavar='', action='append', help=_('Port(s) (name or ID) to apply firewall group. This ' 'option can be repeated')) parser.add_argument( '--no-port', dest='no_port', action='store_true', help=_('Detach all port from the firewall group')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient fwg_id = client.find_resource(const.FWG, parsed_args.firewall_group, cmd_resource=const.CMD_FWG)['id'] attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) try: client.update_fwaas_firewall_group(fwg_id, {const.FWG: attrs}) except Exception as e: msg = (_("Failed to set firewall group '%(group)s': %(e)s") % {'group': parsed_args.firewall_group, 'e': e}) raise exceptions.CommandError(msg) class ShowFirewallGroup(command.ShowOne): _description = _("Display firewall group details") def get_parser(self, prog_name): parser = super(ShowFirewallGroup, self).get_parser(prog_name) parser.add_argument( const.FWG, metavar='', help=_('Firewall group to show (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient fwg_id = client.find_resource(const.FWG, parsed_args.firewall_group, cmd_resource=const.CMD_FWG)['id'] obj = client.show_fwaas_firewall_group(fwg_id)[const.FWG] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns, formatters=_formatters) return (display_columns, data) class UnsetFirewallGroup(command.Command): _description = _("Unset firewall group properties") def get_parser(self, prog_name): parser = super(UnsetFirewallGroup, self).get_parser(prog_name) parser.add_argument( const.FWG, metavar='', help=_('Firewall group to unset (name or ID)')) port_group = parser.add_mutually_exclusive_group() port_group.add_argument( '--port', metavar='', action='append', help=_('Port(s) (name or ID) to apply firewall group. This ' 'option can be repeated')) port_group.add_argument( '--all-port', action='store_true', help=_('Remove all ports for this firewall group')) parser.add_argument( '--ingress-firewall-policy', action='store_true', help=_('Ingress firewall policy (name or ID) to delete')) parser.add_argument( '--egress-firewall-policy', action='store_true', dest='egress_firewall_policy', help=_('Egress firewall policy (name or ID) to delete')) shared_group = parser.add_mutually_exclusive_group() shared_group.add_argument( '--public', action='store_true', help=_('Make the firewall group public, which allows it to be ' 'used in all projects (as opposed to the default, ' 'which is to restrict its use to the current project). ' 'This option is deprecated and would be removed in R' ' release.')) shared_group.add_argument( '--share', action='store_true', help=_('Restrict use of the firewall group to the ' 'current project')) parser.add_argument( '--enable', action='store_true', help=_('Disable firewall group')) return parser def _get_attrs(self, client_manager, parsed_args): attrs = {} client = client_manager.neutronclient if parsed_args.ingress_firewall_policy: attrs['ingress_firewall_policy_id'] = None if parsed_args.egress_firewall_policy: attrs['egress_firewall_policy_id'] = None if parsed_args.share or parsed_args.public: attrs['shared'] = False if parsed_args.enable: attrs['admin_state_up'] = False if parsed_args.port: old = client.find_resource( const.FWG, parsed_args.firewall_group, cmd_resource=const.CMD_FWG)['ports'] new = [client.find_resource( 'port', r)['id'] for r in parsed_args.port] attrs['ports'] = sorted(list(set(old) - set(new))) if parsed_args.all_port: attrs['ports'] = [] return attrs def take_action(self, parsed_args): client = self.app.client_manager.neutronclient fwg_id = client.find_resource(const.FWG, parsed_args.firewall_group, cmd_resource=const.CMD_FWG)['id'] attrs = self._get_attrs(self.app.client_manager, parsed_args) try: client.update_fwaas_firewall_group(fwg_id, {const.FWG: attrs}) except Exception as e: msg = (_("Failed to unset firewall group '%(group)s': %(e)s") % {'group': parsed_args.firewall_group, 'e': e}) raise exceptions.CommandError(msg) python-neutronclient-6.7.0/neutronclient/osc/v2/fwaas/__init__.py0000666000175100017510000000000013232473350025170 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/trunk/0000775000175100017510000000000013232473710023131 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/trunk/network_trunk.py0000666000175100017510000003306413232473350026427 0ustar zuulzuul00000000000000# Copyright 2016 ZTE Corporation. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # """Network trunk and subports action implementations""" import logging from osc_lib.cli import format_columns from osc_lib.cli import parseractions from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils as osc_utils from neutronclient._i18n import _ from neutronclient.osc import utils as nc_osc_utils from neutronclient.osc.v2 import utils as v2_utils LOG = logging.getLogger(__name__) TRUNK = 'trunk' TRUNKS = 'trunks' SUB_PORTS = 'sub_ports' class CreateNetworkTrunk(command.ShowOne): """Create a network trunk for a given project""" def get_parser(self, prog_name): parser = super(CreateNetworkTrunk, self).get_parser(prog_name) parser.add_argument( 'name', metavar='', help=_("Name of the trunk to create") ) parser.add_argument( '--description', metavar='', help=_("A description of the trunk") ) parser.add_argument( '--parent-port', metavar='', required=True, help=_("Parent port belonging to this trunk (name or ID)") ) parser.add_argument( '--subport', metavar='', action=parseractions.MultiKeyValueAction, dest='add_subports', optional_keys=['segmentation-id', 'segmentation-type'], required_keys=['port'], help=_("Subport to add. Subport is of form " "\'port=,segmentation-type=,segmentation-ID=\' " "(--subport) option can be repeated") ) admin_group = parser.add_mutually_exclusive_group() admin_group.add_argument( '--enable', action='store_true', default=True, help=_("Enable trunk (default)") ) admin_group.add_argument( '--disable', action='store_true', help=_("Disable trunk") ) nc_osc_utils.add_project_owner_option_to_parser(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_attrs_for_trunk(self.app.client_manager, parsed_args) body = {TRUNK: attrs} obj = client.create_trunk(body) columns = _get_columns(obj[TRUNK]) data = osc_utils.get_dict_properties(obj[TRUNK], columns, formatters=_formatters) return columns, data class DeleteNetworkTrunk(command.Command): """Delete a given network trunk""" def get_parser(self, prog_name): parser = super(DeleteNetworkTrunk, self).get_parser(prog_name) parser.add_argument( 'trunk', metavar="", nargs="+", help=_("Trunk(s) to delete (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient result = 0 for trunk in parsed_args.trunk: try: trunk_id = _get_id(client, trunk, TRUNK) client.delete_trunk(trunk_id) except Exception as e: result += 1 LOG.error(_("Failed to delete trunk with name " "or ID '%(trunk)s': %(e)s"), {'trunk': trunk, 'e': e}) if result > 0: total = len(parsed_args.trunk) msg = (_("%(result)s of %(total)s trunks failed " "to delete.") % {'result': result, 'total': total}) raise exceptions.CommandError(msg) class ListNetworkTrunk(command.Lister): """List all network trunks""" def get_parser(self, prog_name): parser = super(ListNetworkTrunk, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', default=False, help=_("List additional fields in output") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient data = client.list_trunks() headers = ( 'ID', 'Name', 'Parent Port', 'Description' ) columns = ( 'id', 'name', 'port_id', 'description' ) if parsed_args.long: headers += ( 'Status', 'State', 'Created At', 'Updated At', ) columns += ( 'status', 'admin_state_up', 'created_at', 'updated_at' ) return (headers, (osc_utils.get_dict_properties( s, columns, formatters=_formatters, ) for s in data[TRUNKS])) class SetNetworkTrunk(command.Command): """Set network trunk properties""" def get_parser(self, prog_name): parser = super(SetNetworkTrunk, self).get_parser(prog_name) parser.add_argument( 'trunk', metavar="", help=_("Trunk to modify (name or ID)") ) parser.add_argument( '--name', metavar="", help=_("Set trunk name") ) parser.add_argument( '--description', metavar='', help=_("A description of the trunk") ) parser.add_argument( '--subport', metavar='', action=parseractions.MultiKeyValueAction, dest='set_subports', optional_keys=['segmentation-id', 'segmentation-type'], required_keys=['port'], help=_("Subport to add. Subport is of form " "\'port=,segmentation-type=,segmentation-ID=\'" "(--subport) option can be repeated") ) admin_group = parser.add_mutually_exclusive_group() admin_group.add_argument( '--enable', action='store_true', help=_("Enable trunk") ) admin_group.add_argument( '--disable', action='store_true', help=_("Disable trunk") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient trunk_id = _get_id(client, parsed_args.trunk, TRUNK) attrs = _get_attrs_for_trunk(self.app.client_manager, parsed_args) body = {TRUNK: attrs} try: client.update_trunk(trunk_id, body) except Exception as e: msg = (_("Failed to set trunk '%(t)s': %(e)s") % {'t': parsed_args.trunk, 'e': e}) raise exceptions.CommandError(msg) if parsed_args.set_subports: subport_attrs = _get_attrs_for_subports(self.app.client_manager, parsed_args) try: client.trunk_add_subports(trunk_id, subport_attrs) except Exception as e: msg = (_("Failed to add subports to trunk '%(t)s': %(e)s") % {'t': parsed_args.trunk, 'e': e}) raise exceptions.CommandError(msg) class ShowNetworkTrunk(command.ShowOne): """Show information of a given network trunk""" def get_parser(self, prog_name): parser = super(ShowNetworkTrunk, self).get_parser(prog_name) parser.add_argument( 'trunk', metavar="", help=_("Trunk to display (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient trunk_id = _get_id(client, parsed_args.trunk, TRUNK) obj = client.show_trunk(trunk_id) columns = _get_columns(obj[TRUNK]) data = osc_utils.get_dict_properties(obj[TRUNK], columns, formatters=_formatters) return columns, data class ListNetworkSubport(command.Lister): """List all subports for a given network trunk""" def get_parser(self, prog_name): parser = super(ListNetworkSubport, self).get_parser(prog_name) parser.add_argument( '--trunk', required=True, metavar="", help=_("List subports belonging to this trunk (name or ID)") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient trunk_id = _get_id(client, parsed_args.trunk, TRUNK) data = client.trunk_get_subports(trunk_id) headers = ('Port', 'Segmentation Type', 'Segmentation ID') columns = ('port_id', 'segmentation_type', 'segmentation_id') return (headers, (osc_utils.get_dict_properties( s, columns, ) for s in data[SUB_PORTS])) class UnsetNetworkTrunk(command.Command): """Unset subports from a given network trunk""" def get_parser(self, prog_name): parser = super(UnsetNetworkTrunk, self).get_parser(prog_name) parser.add_argument( 'trunk', metavar="", help=_("Unset subports from this trunk (name or ID)") ) parser.add_argument( '--subport', metavar="", required=True, action='append', dest='unset_subports', help=_("Subport to delete (name or ID of the port) " "(--subport) option can be repeated") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_attrs_for_subports(self.app.client_manager, parsed_args) trunk_id = _get_id(client, parsed_args.trunk, TRUNK) client.trunk_remove_subports(trunk_id, attrs) _formatters = { 'admin_state_up': v2_utils.AdminStateColumn, 'sub_ports': format_columns.ListDictColumn, } def _get_columns(item): return tuple(sorted(list(item.keys()))) def _get_attrs_for_trunk(client_manager, parsed_args): attrs = {} if parsed_args.name is not None: attrs['name'] = str(parsed_args.name) if parsed_args.description is not None: attrs['description'] = str(parsed_args.description) if parsed_args.enable: attrs['admin_state_up'] = True if parsed_args.disable: attrs['admin_state_up'] = False if 'parent_port' in parsed_args and parsed_args.parent_port is not None: port_id = _get_id(client_manager.neutronclient, parsed_args.parent_port, 'port') attrs['port_id'] = port_id if 'add_subports' in parsed_args and parsed_args.add_subports is not None: attrs[SUB_PORTS] = _format_subports(client_manager, parsed_args.add_subports) # "trunk set" command doesn't support setting project. if 'project' in parsed_args and parsed_args.project is not None: identity_client = client_manager.identity project_id = nc_osc_utils.find_project( identity_client, parsed_args.project, parsed_args.project_domain, ).id attrs['tenant_id'] = project_id return attrs def _format_subports(client_manager, subports): attrs = [] for subport in subports: subport_attrs = {} if subport.get('port'): port_id = _get_id(client_manager.neutronclient, subport['port'], 'port') subport_attrs['port_id'] = port_id if subport.get('segmentation-id'): try: subport_attrs['segmentation_id'] = int( subport['segmentation-id']) except ValueError: msg = (_("Segmentation-id '%s' is not an integer") % subport['segmentation-id']) raise exceptions.CommandError(msg) if subport.get('segmentation-type'): subport_attrs['segmentation_type'] = subport['segmentation-type'] attrs.append(subport_attrs) return attrs def _get_attrs_for_subports(client_manager, parsed_args): attrs = {} if 'set_subports' in parsed_args and parsed_args.set_subports is not None: attrs[SUB_PORTS] = _format_subports(client_manager, parsed_args.set_subports) if ('unset_subports' in parsed_args and parsed_args.unset_subports is not None): subports_list = [] for subport in parsed_args.unset_subports: port_id = _get_id(client_manager.neutronclient, subport, 'port') subports_list.append({'port_id': port_id}) attrs[SUB_PORTS] = subports_list return attrs def _get_id(client, id_or_name, resource): return client.find_resource(resource, str(id_or_name))['id'] python-neutronclient-6.7.0/neutronclient/osc/v2/trunk/__init__.py0000666000175100017510000000000013232473350025232 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/networking_bgpvpn/0000775000175100017510000000000013232473710025531 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/networking_bgpvpn/router_association.py0000666000175100017510000000432013232473407032023 0ustar zuulzuul00000000000000# Copyright (c) 2016 Juniper networks Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.osc import utils as nc_osc_utils from neutronclient.osc.v2.networking_bgpvpn import constants from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ CreateBgpvpnResAssoc from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ DeleteBgpvpnResAssoc from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ ListBgpvpnResAssoc from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ ShowBgpvpnResAssoc class BgpvpnRouterAssoc(object): _assoc_res_name = constants.ROUTER_RESOURCE_NAME _resource = constants.ROUTER_ASSOC _resource_plural = constants.ROUTER_ASSOCS _attr_map = ( ('id', 'ID', nc_osc_utils.LIST_BOTH), ('tenant_id', 'Project', nc_osc_utils.LIST_LONG_ONLY), ('%s_id' % _assoc_res_name, '%s ID' % _assoc_res_name.capitalize(), nc_osc_utils.LIST_BOTH), ) _formatters = {} class CreateBgpvpnRouterAssoc(BgpvpnRouterAssoc, CreateBgpvpnResAssoc): _description = _("Create a BGP VPN router association") pass class DeleteBgpvpnRouterAssoc(BgpvpnRouterAssoc, DeleteBgpvpnResAssoc): _description = _("Delete a BGP VPN router association(s) for a given BGP " "VPN") pass class ListBgpvpnRouterAssoc(BgpvpnRouterAssoc, ListBgpvpnResAssoc): _description = _("List BGP VPN router associations for a given BGP VPN") pass class ShowBgpvpnRouterAssoc(BgpvpnRouterAssoc, ShowBgpvpnResAssoc): _description = _("Show information of a given BGP VPN router association") pass python-neutronclient-6.7.0/neutronclient/osc/v2/networking_bgpvpn/port_association.py0000666000175100017510000002771313232473407031502 0ustar zuulzuul00000000000000# Copyright (c) 2017 Juniper networks Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import logging from osc_lib.cli import format_columns from osc_lib.cli import parseractions from neutronclient._i18n import _ from neutronclient.osc import utils as nc_osc_utils from neutronclient.osc.v2.networking_bgpvpn import constants from neutronclient.osc.v2.networking_bgpvpn import resource_association LOG = logging.getLogger(__name__) class BgpvpnPortAssoc(object): _assoc_res_name = constants.PORT_RESOURCE_NAME _resource = constants.PORT_ASSOC _resource_plural = constants.PORT_ASSOCS _attr_map = ( ('id', 'ID', nc_osc_utils.LIST_BOTH), ('tenant_id', 'Project', nc_osc_utils.LIST_LONG_ONLY), ('%s_id' % _assoc_res_name, '%s ID' % _assoc_res_name.capitalize(), nc_osc_utils.LIST_BOTH), ('prefix_routes', 'Prefix Routes (BGP LOCAL_PREF)', nc_osc_utils.LIST_LONG_ONLY), ('bgpvpn_routes', 'BGP VPN Routes (BGP LOCAL_PREF)', nc_osc_utils.LIST_LONG_ONLY), ('advertise_fixed_ips', "Advertise Port's Fixed IPs", nc_osc_utils.LIST_LONG_ONLY), ) _formatters = { 'prefix_routes': format_columns.ListColumn, 'bgpvpn_routes': format_columns.ListColumn, } def _transform_resource(self, data): """Transforms BGP VPN port association routes property That permits to easily format the command output with ListColumn formater and separate the two route types. {'routes': [ { 'type': 'prefix', 'local_pref': 100, 'prefix': '8.8.8.0/27', }, { 'type': 'prefix', 'local_pref': 42, 'prefix': '80.50.30.0/28', }, { 'type': 'bgpvpn', 'local_pref': 50, 'bgpvpn': '157d72a9-9968-48e7-8087-6c9a9bc7a181', }, { 'type': 'bgpvpn', 'bgpvpn': 'd5c7aaab-c7e8-48b3-85ca-a115c00d3603', }, ], } to { 'prefix_routes': [ '8.8.8.0/27 (100)', '80.50.30.0/28 (42)', ], 'bgpvpn_routes': [ '157d72a9-9968-48e7-8087-6c9a9bc7a181 (50)', 'd5c7aaab-c7e8-48b3-85ca-a115c00d3603', ], } """ for route in data.get('routes', []): local_pref = '' if route.get('local_pref'): local_pref = ' (%d)' % route.get('local_pref') if route['type'] == 'prefix': data.setdefault('prefix_routes', []).append( '%s%s' % (route['prefix'], local_pref) ) elif route['type'] == 'bgpvpn': data.setdefault('bgpvpn_routes', []).append( '%s%s' % (route['bgpvpn_id'], local_pref) ) else: LOG.warning("Unknown route type %s (%s).", route['type'], route) data.pop('routes', None) def _get_common_parser(self, parser): """Adds to parser arguments common to create, set and unset commands. :params ArgumentParser parser: argparse object contains all command's arguments """ ADVERTISE_ROUTE = _("Fixed IPs of the port will be advertised to the " "BGP VPN%s") % ( _(' (default)') if self._action == 'create' else "") NOT_ADVERTISE_ROUTE = _("Fixed IPs of the port will not be advertised " "to the BGP VPN") LOCAL_PREF_VALUE = _(". Optionally, can control the value of the BGP " "LOCAL_PREF of the routes that will be " "advertised") ADD_PREFIX_ROUTE = _("Add prefix route in CIDR notation%s") %\ LOCAL_PREF_VALUE REMOVE_PREFIX_ROUTE = _("Remove prefix route in CIDR notation") REPEAT_PREFIX_ROUTE = _("repeat option for multiple prefix routes") ADD_BGVPVPN_ROUTE = _("Add BGP VPN route for route leaking%s") %\ LOCAL_PREF_VALUE REMOVE_BGPVPN_ROUTE = _("Remove BGP VPN route") REPEAT_BGPVPN_ROUTE = _("repeat option for multiple BGP VPN routes") group_advertise_fixed_ips = parser.add_mutually_exclusive_group() group_advertise_fixed_ips.add_argument( '--advertise-fixed-ips', action='store_true', help=NOT_ADVERTISE_ROUTE if self._action == 'unset' else ADVERTISE_ROUTE, ) group_advertise_fixed_ips.add_argument( '--no-advertise-fixed-ips', action='store_true', help=ADVERTISE_ROUTE if self._action == 'unset' else NOT_ADVERTISE_ROUTE, ) if self._action in ['create', 'set']: parser.add_argument( '--prefix-route', metavar="prefix=[,local_pref=]", dest='prefix_routes', action=parseractions.MultiKeyValueAction, required_keys=['prefix'], optional_keys=['local_pref'], help="%s (%s)" % (ADD_PREFIX_ROUTE, REPEAT_PREFIX_ROUTE), ) parser.add_argument( '--bgpvpn-route', metavar="bgpvpn=[,local_pref=]", dest='bgpvpn_routes', action=parseractions.MultiKeyValueAction, required_keys=['bgpvpn'], optional_keys=['local_pref'], help="%s (%s)" % (ADD_BGVPVPN_ROUTE, REPEAT_BGPVPN_ROUTE), ) else: parser.add_argument( '--prefix-route', metavar="", dest='prefix_routes', action='append', help="%s (%s)" % (REMOVE_PREFIX_ROUTE, REPEAT_PREFIX_ROUTE), ) parser.add_argument( '--bgpvpn-route', metavar="", dest='bgpvpn_routes', action='append', help="%s (%s)" % (REMOVE_BGPVPN_ROUTE, REPEAT_BGPVPN_ROUTE), ) if self._action != 'create': parser.add_argument( '--no-prefix-route' if self._action == 'set' else '--all-prefix-routes', dest='purge_prefix_route', action='store_true', help=_('Empty prefix route list'), ) parser.add_argument( '--no-bgpvpn-route' if self._action == 'set' else '--all-bgpvpn-routes', dest='purge_bgpvpn_route', action='store_true', help=_('Empty BGP VPN route list'), ) def _args2body(self, bgpvpn_id, args): client = self.app.client_manager.neutronclient attrs = {} if self._action != 'create': assoc = client.find_resource_by_id( self._resource, args.resource_association_id, cmd_resource='bgpvpn_%s_assoc' % self._assoc_res_name, parent_id=bgpvpn_id) else: assoc = {'routes': []} if args.advertise_fixed_ips: attrs['advertise_fixed_ips'] = self._action != 'unset' elif args.no_advertise_fixed_ips: attrs['advertise_fixed_ips'] = self._action == 'unset' prefix_routes = None if 'purge_prefix_route' in args and args.purge_prefix_route: prefix_routes = [] else: prefix_routes = {r['prefix']: r.get('local_pref') for r in assoc['routes'] if r['type'] == 'prefix'} if args.prefix_routes: if self._action in ['create', 'set']: prefix_routes.update({r['prefix']: r.get('local_pref') for r in args.prefix_routes}) elif self._action == 'unset': for prefix in args.prefix_routes: prefix_routes.pop(prefix, None) bgpvpn_routes = None if 'purge_bgpvpn_route' in args and args.purge_bgpvpn_route: bgpvpn_routes = [] else: bgpvpn_routes = {r['bgpvpn_id']: r.get('local_pref') for r in assoc['routes'] if r['type'] == 'bgpvpn'} if args.bgpvpn_routes: if self._action == 'unset': routes = [ {'bgpvpn': bgpvpn} for bgpvpn in args.bgpvpn_routes ] else: routes = args.bgpvpn_routes args_bgpvpn_routes = { client.find_resource(constants.BGPVPN, r['bgpvpn'])['id']: r.get('local_pref') for r in routes } if self._action in ['create', 'set']: bgpvpn_routes.update(args_bgpvpn_routes) elif self._action == 'unset': for bgpvpn_id in args_bgpvpn_routes: bgpvpn_routes.pop(bgpvpn_id, None) if prefix_routes is not None and not prefix_routes: attrs.setdefault('routes', []) elif prefix_routes is not None: for prefix, local_pref in prefix_routes.items(): route = { 'type': 'prefix', 'prefix': prefix, } if local_pref: route['local_pref'] = int(local_pref) attrs.setdefault('routes', []).append(route) if bgpvpn_routes is not None and not bgpvpn_routes: attrs.setdefault('routes', []) elif bgpvpn_routes is not None: for bgpvpn_id, local_pref in bgpvpn_routes.items(): route = { 'type': 'bgpvpn', 'bgpvpn_id': bgpvpn_id, } if local_pref: route['local_pref'] = int(local_pref) attrs.setdefault('routes', []).append(route) return {self._resource: attrs} class CreateBgpvpnPortAssoc(BgpvpnPortAssoc, resource_association.CreateBgpvpnResAssoc): _description = _("Create a BGP VPN port association") class SetBgpvpnPortAssoc(BgpvpnPortAssoc, resource_association.SetBgpvpnResAssoc): _description = _("Set BGP VPN port association properties") class UnsetBgpvpnPortAssoc(BgpvpnPortAssoc, resource_association.UnsetBgpvpnResAssoc): _description = _("Unset BGP VPN port association properties") class DeleteBgpvpnPortAssoc(BgpvpnPortAssoc, resource_association.DeleteBgpvpnResAssoc): _description = _("Delete a BGP VPN port association(s) for a given BGP " "VPN") class ListBgpvpnPortAssoc(BgpvpnPortAssoc, resource_association.ListBgpvpnResAssoc): _description = _("List BGP VPN port associations for a given BGP VPN") class ShowBgpvpnPortAssoc(BgpvpnPortAssoc, resource_association.ShowBgpvpnResAssoc): _description = _("Show information of a given BGP VPN port association") python-neutronclient-6.7.0/neutronclient/osc/v2/networking_bgpvpn/bgpvpn.py0000666000175100017510000003614613232473407027416 0ustar zuulzuul00000000000000# Copyright (c) 2016 Juniper Networks Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import logging from osc_lib.cli import format_columns from osc_lib.cli.parseractions import KeyValueAction from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils as osc_utils from neutronclient._i18n import _ from neutronclient.osc import utils as nc_osc_utils from neutronclient.osc.v2.networking_bgpvpn import constants LOG = logging.getLogger(__name__) _attr_map = ( ('id', 'ID', nc_osc_utils.LIST_BOTH), ('tenant_id', 'Project', nc_osc_utils.LIST_LONG_ONLY), ('name', 'Name', nc_osc_utils.LIST_BOTH), ('type', 'Type', nc_osc_utils.LIST_BOTH), ('route_targets', 'Route Targets', nc_osc_utils.LIST_LONG_ONLY), ('import_targets', 'Import Targets', nc_osc_utils.LIST_LONG_ONLY), ('export_targets', 'Export Targets', nc_osc_utils.LIST_LONG_ONLY), ('route_distinguishers', 'Route Distinguishers', nc_osc_utils.LIST_LONG_ONLY), ('networks', 'Associated Networks', nc_osc_utils.LIST_LONG_ONLY), ('routers', 'Associated Routers', nc_osc_utils.LIST_LONG_ONLY), ('ports', 'Associated Ports', nc_osc_utils.LIST_LONG_ONLY), ('vni', 'VNI', nc_osc_utils.LIST_LONG_ONLY), ) _formatters = { 'route_targets': format_columns.ListColumn, 'import_targets': format_columns.ListColumn, 'export_targets': format_columns.ListColumn, 'route_distinguishers': format_columns.ListColumn, 'networks': format_columns.ListColumn, 'routers': format_columns.ListColumn, 'ports': format_columns.ListColumn, } def _get_common_parser(parser, update=None): """Adds to parser arguments common to create, set and unset commands. :params ArgumentParser parser: argparse object contains all command's arguments :params string update: Determines if it is a create command (value: None), it is a set command (value: 'set') or if it is an unset command (value: 'unset') """ ADD_RT = _("Add Route Target to import/export list") REMOVE_RT = _("Remove Route Target from import/export list") ADD_IMPORT_RT = _("Add Route Target to import list") REMOVE_IMPORT_RT = _("Remove Route Target from import list") ADD_EXPORT_RT = _("Add Route Target to export list") REMOVE_EXPORT_RT = _("Remove Route Target from export list") ADD_RD = _("Add Route Distinguisher to the list of Route Distinguishers " "from which a Route Distinguishers will be picked from to " "advertise a VPN route") REMOVE_RD = _("Remove Route Distinguisher from the list of Route " "Distinguishers from which a Route Distinguishers will be " "picked from to advertise a VPN route") REPEAT_RT = _("repeat option for multiple Route Targets") REPEAT_RD = _("repeat option for multiple Route Distinguishers") def is_appended(): return update is None or update == 'set' if update is None or update == 'set': parser.add_argument( '--name', metavar="", help=_("Name of the BGP VPN"), ) parser.add_argument( '--route-target', dest='route_targets', action='append', metavar="", help="%s (%s)" % ((ADD_RT if is_appended() else REMOVE_RT), REPEAT_RT), ) if update: parser.add_argument( '--no-route-target' if update == 'set' else '--all-route-target', dest='purge_route_target', action='store_true', help=_('Empty route target list'), ) parser.add_argument( '--import-target', dest='import_targets', action='append', metavar="", help="%s (%s)" % ((ADD_IMPORT_RT if is_appended() else REMOVE_IMPORT_RT), REPEAT_RT), ) if update: parser.add_argument( '--no-import-target' if update == 'set' else '--all-import-target', dest='purge_import_target', action='store_true', help=_('Empty import route target list'), ) parser.add_argument( '--export-target', dest='export_targets', action='append', metavar="", help="%s (%s)" % ((ADD_EXPORT_RT if is_appended() else REMOVE_EXPORT_RT), REPEAT_RT), ) if update: parser.add_argument( '--no-export-target' if update == 'set' else '--all-export-target', dest='purge_export_target', action='store_true', help=_('Empty export route target list'), ) parser.add_argument( '--route-distinguisher', dest='route_distinguishers', action='append', metavar="", help="%s (%s)" % ((ADD_RD if is_appended() else REMOVE_RD), REPEAT_RD), ) if update: parser.add_argument( '--no-route-distinguisher' if update == 'set' else '--all-route-distinguisher', dest='purge_route_distinguisher', action='store_true', help=_('Empty route distinguisher list'), ) parser.add_argument( '--vni', type=int, help=_('VXLAN Network Identifier to be used for this BGPVPN ' 'when a VXLAN encapsulation is used')) def _args2body(client_manager, id, action, args): if (not (args.purge_route_target and args.purge_import_target and args.purge_export_target and args.purge_route_distinguisher) and (args.route_targets or args.import_targets or args.export_targets or args.route_distinguishers)): bgpvpn = client_manager.neutronclient.show_bgpvpn(id)['bgpvpn'] attrs = {} if 'name' in args and args.name is not None: attrs['name'] = str(args.name) if 'vni' in args and args.vni is not None: attrs['vni'] = args.vni if args.purge_route_target: attrs['route_targets'] = [] elif args.route_targets: if action == 'set': attrs['route_targets'] = list(set(bgpvpn['route_targets']) | set(args.route_targets)) elif action == 'unset': attrs['route_targets'] = list(set(bgpvpn['route_targets']) - set(args.route_targets)) if args.purge_import_target: attrs['import_targets'] = [] elif args.import_targets: if action == 'set': attrs['import_targets'] = list(set(bgpvpn['import_targets']) | set(args.import_targets)) elif action == 'unset': attrs['import_targets'] = list(set(bgpvpn['import_targets']) - set(args.import_targets)) if args.purge_export_target: attrs['export_targets'] = [] elif args.export_targets: if action == 'set': attrs['export_targets'] = list(set(bgpvpn['export_targets']) | set(args.export_targets)) elif action == 'unset': attrs['export_targets'] = list(set(bgpvpn['export_targets']) - set(args.export_targets)) if args.purge_route_distinguisher: attrs['route_distinguishers'] = [] elif args.route_distinguishers: if action == 'set': attrs['route_distinguishers'] = list( set(bgpvpn['route_distinguishers']) | set(args.route_distinguishers)) elif action == 'unset': attrs['route_distinguishers'] = list( set(bgpvpn['route_distinguishers']) - set(args.route_distinguishers)) return {constants.BGPVPN: attrs} class CreateBgpvpn(command.ShowOne): _description = _("Create BGP VPN resource") def get_parser(self, prog_name): parser = super(CreateBgpvpn, self).get_parser(prog_name) nc_osc_utils.add_project_owner_option_to_parser(parser) _get_common_parser(parser) parser.add_argument( '--type', default='l3', choices=['l2', 'l3'], help=_("BGP VPN type selection between IP VPN (l3) and Ethernet " "VPN (l2) (default: l3)"), ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = {} if parsed_args.name is not None: attrs['name'] = str(parsed_args.name) if parsed_args.type is not None: attrs['type'] = parsed_args.type if parsed_args.route_targets is not None: attrs['route_targets'] = parsed_args.route_targets if parsed_args.import_targets is not None: attrs['import_targets'] = parsed_args.import_targets if parsed_args.export_targets is not None: attrs['export_targets'] = parsed_args.export_targets if parsed_args.route_distinguishers is not None: attrs['route_distinguishers'] = parsed_args.route_distinguishers if parsed_args.vni is not None: attrs['vni'] = parsed_args.vni if 'project' in parsed_args and parsed_args.project is not None: project_id = nc_osc_utils.find_project( self.app.client_manager.identity, parsed_args.project, parsed_args.project_domain, ).id attrs['tenant_id'] = project_id body = {constants.BGPVPN: attrs} obj = client.create_bgpvpn(body)[constants.BGPVPN] columns, display_columns = nc_osc_utils.get_columns(obj, _attr_map) data = osc_utils.get_dict_properties(obj, columns, formatters=_formatters) return display_columns, data class SetBgpvpn(command.Command): _description = _("Set BGP VPN properties") def get_parser(self, prog_name): parser = super(SetBgpvpn, self).get_parser(prog_name) parser.add_argument( 'bgpvpn', metavar="", help=_("BGP VPN to update (name or ID)"), ) _get_common_parser(parser, update='set') return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient id = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn)['id'] body = _args2body(self.app.client_manager, id, 'set', parsed_args) client.update_bgpvpn(id, body) class UnsetBgpvpn(command.Command): _description = _("Unset BGP VPN properties") def get_parser(self, prog_name): parser = super(UnsetBgpvpn, self).get_parser(prog_name) parser.add_argument( 'bgpvpn', metavar="", help=_("BGP VPN to update (name or ID)"), ) _get_common_parser(parser, update='unset') return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient id = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn)['id'] body = _args2body(self.app.client_manager, id, 'unset', parsed_args) client.update_bgpvpn(id, body) class DeleteBgpvpn(command.Command): _description = _("Delete BGP VPN resource(s)") def get_parser(self, prog_name): parser = super(DeleteBgpvpn, self).get_parser(prog_name) parser.add_argument( 'bgpvpns', metavar="", nargs="+", help=_("BGP VPN(s) to delete (name or ID)"), ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient fails = 0 for id_or_name in parsed_args.bgpvpns: try: id = client.find_resource(constants.BGPVPN, id_or_name)['id'] client.delete_bgpvpn(id) LOG.warning("BGP VPN %(id)s deleted", {'id': id}) except Exception as e: fails += 1 LOG.error("Failed to delete BGP VPN with name or ID " "'%(id_or_name)s': %(e)s", {'id_or_name': id_or_name, 'e': e}) if fails > 0: msg = (_("Failed to delete %(fails)s of %(total)s BGP VPN.") % {'fails': fails, 'total': len(parsed_args.bgpvpns)}) raise exceptions.CommandError(msg) class ListBgpvpn(command.Lister): _description = _("List BGP VPN resources") def get_parser(self, prog_name): parser = super(ListBgpvpn, self).get_parser(prog_name) nc_osc_utils.add_project_owner_option_to_parser(parser) parser.add_argument( '--long', action='store_true', help=_("List additional fields in output"), ) parser.add_argument( '--property', metavar="", default=dict(), help=_("Filter property to apply on returned BGP VPNs (repeat to " "filter on multiple properties)"), action=KeyValueAction, ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient params = {} if parsed_args.project is not None: project_id = nc_osc_utils.find_project( self.app.client_manager.identity, parsed_args.project, parsed_args.project_domain, ).id params['tenant_id'] = project_id if parsed_args.property: params.update(parsed_args.property) objs = client.list_bgpvpns(**params)[constants.BGPVPNS] headers, columns = nc_osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (osc_utils.get_dict_properties( s, columns, formatters=_formatters) for s in objs)) class ShowBgpvpn(command.ShowOne): _description = _("Show information of a given BGP VPN") def get_parser(self, prog_name): parser = super(ShowBgpvpn, self).get_parser(prog_name) parser.add_argument( 'bgpvpn', metavar="", help=_("BGP VPN to display (name or ID)"), ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient id = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn)['id'] obj = client.show_bgpvpn(id)[constants.BGPVPN] columns, display_columns = nc_osc_utils.get_columns(obj, _attr_map) data = osc_utils.get_dict_properties(obj, columns, formatters=_formatters) return display_columns, data python-neutronclient-6.7.0/neutronclient/osc/v2/networking_bgpvpn/network_association.py0000666000175100017510000000427413232473350032201 0ustar zuulzuul00000000000000# Copyright (c) 2016 Juniper Networks Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.osc import utils as nc_osc_utils from neutronclient.osc.v2.networking_bgpvpn import constants from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ CreateBgpvpnResAssoc from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ DeleteBgpvpnResAssoc from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ ListBgpvpnResAssoc from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ ShowBgpvpnResAssoc class BgpvpnNetAssoc(object): _assoc_res_name = constants.NETWORK_RESOURCE_NAME _resource = constants.NETWORK_ASSOC _resource_plural = constants.NETWORK_ASSOCS _attr_map = ( ('id', 'ID', nc_osc_utils.LIST_BOTH), ('tenant_id', 'Project', nc_osc_utils.LIST_LONG_ONLY), ('%s_id' % _assoc_res_name, '%s ID' % _assoc_res_name.capitalize(), nc_osc_utils.LIST_BOTH), ) _formatters = {} class CreateBgpvpnNetAssoc(BgpvpnNetAssoc, CreateBgpvpnResAssoc): _description = _("Create a BGP VPN network association") pass class DeleteBgpvpnNetAssoc(BgpvpnNetAssoc, DeleteBgpvpnResAssoc): _description = _("Delete a BGP VPN network association(s) for a given BGP " "VPN") pass class ListBgpvpnNetAssoc(BgpvpnNetAssoc, ListBgpvpnResAssoc): _description = _("List BGP VPN network associations for a given BGP VPN") pass class ShowBgpvpnNetAssoc(BgpvpnNetAssoc, ShowBgpvpnResAssoc): _description = _("Show information of a given BGP VPN network association") pass python-neutronclient-6.7.0/neutronclient/osc/v2/networking_bgpvpn/constants.py0000666000175100017510000000202613232473407030124 0ustar zuulzuul00000000000000# Copyright (c) 2016 Juniper Networks Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # BGPVPN = 'bgpvpn' BGPVPNS = '%ss' % BGPVPN NETWORK_RESOURCE_NAME = 'network' NETWORK_ASSOC = '%s_association' % NETWORK_RESOURCE_NAME NETWORK_ASSOCS = '%ss' % NETWORK_ASSOC ROUTER_RESOURCE_NAME = 'router' ROUTER_ASSOC = '%s_association' % ROUTER_RESOURCE_NAME ROUTER_ASSOCS = '%ss' % ROUTER_ASSOC PORT_RESOURCE_NAME = 'port' PORT_ASSOC = '%s_association' % PORT_RESOURCE_NAME PORT_ASSOCS = '%ss' % PORT_ASSOC python-neutronclient-6.7.0/neutronclient/osc/v2/networking_bgpvpn/resource_association.py0000666000175100017510000002426513232473407032344 0ustar zuulzuul00000000000000# Copyright (c) 2016 Juniper Networks Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import logging from osc_lib.cli import parseractions from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils as osc_utils from neutronclient._i18n import _ from neutronclient.osc import utils as nc_osc_utils from neutronclient.osc.v2.networking_bgpvpn import constants LOG = logging.getLogger(__name__) class CreateBgpvpnResAssoc(command.ShowOne): """Create a BGP VPN resource association""" _action = 'create' def get_parser(self, prog_name): parser = super(CreateBgpvpnResAssoc, self).get_parser(prog_name) nc_osc_utils.add_project_owner_option_to_parser(parser) parser.add_argument( 'bgpvpn', metavar="", help=(_("BGP VPN to apply the %s association (name or ID)") % self._assoc_res_name), ) parser.add_argument( 'resource', metavar="<%s>" % self._assoc_res_name, help=(_("%s to associate the BGP VPN (name or ID)") % self._assoc_res_name.capitalize()), ) get_common_parser = getattr(self, '_get_common_parser', None) if callable(get_common_parser): get_common_parser(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient create_method = getattr( client, 'create_bgpvpn_%s_assoc' % self._assoc_res_name) bgpvpn = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn) assoc_res = client.find_resource(self._assoc_res_name, parsed_args.resource) body = { self._resource: { '%s_id' % self._assoc_res_name: assoc_res['id'], }, } if 'project' in parsed_args and parsed_args.project is not None: project_id = nc_osc_utils.find_project( self.app.client_manager.identity, parsed_args.project, parsed_args.project_domain, ).id body[self._resource]['tenant_id'] = project_id arg2body = getattr(self, '_args2body', None) if callable(arg2body): body[self._resource].update( arg2body(bgpvpn['id'], parsed_args)[self._resource]) obj = create_method(bgpvpn['id'], body)[self._resource] transform = getattr(self, '_transform_resource', None) if callable(transform): transform(obj) columns, display_columns = nc_osc_utils.get_columns(obj, self._attr_map) data = osc_utils.get_dict_properties(obj, columns, formatters=self._formatters) return display_columns, data class SetBgpvpnResAssoc(command.Command): """Set BGP VPN resource association properties""" _action = 'set' def get_parser(self, prog_name): parser = super(SetBgpvpnResAssoc, self).get_parser(prog_name) parser.add_argument( 'resource_association_id', metavar="<%s association ID>" % self._assoc_res_name, help=(_("%s association ID to update") % self._assoc_res_name.capitalize()), ) parser.add_argument( 'bgpvpn', metavar="", help=(_("BGP VPN the %s association belongs to (name or ID)") % self._assoc_res_name), ) get_common_parser = getattr(self, '_get_common_parser', None) if callable(get_common_parser): get_common_parser(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient update_method = getattr( client, 'update_bgpvpn_%s_assoc' % self._assoc_res_name) bgpvpn = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn) arg2body = getattr(self, '_args2body', None) if callable(arg2body): body = arg2body(bgpvpn['id'], parsed_args) update_method(bgpvpn['id'], parsed_args.resource_association_id, body) class UnsetBgpvpnResAssoc(SetBgpvpnResAssoc): """Unset BGP VPN resource association properties""" _action = 'unset' class DeleteBgpvpnResAssoc(command.Command): """Remove a BGP VPN resource association(s) for a given BGP VPN""" def get_parser(self, prog_name): parser = super(DeleteBgpvpnResAssoc, self).get_parser(prog_name) parser.add_argument( 'resource_association_ids', metavar="<%s association ID>" % self._assoc_res_name, nargs="+", help=(_("%s association ID(s) to remove") % self._assoc_res_name.capitalize()), ) parser.add_argument( 'bgpvpn', metavar="", help=(_("BGP VPN the %s association belongs to (name or ID)") % self._assoc_res_name), ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient delete_method = getattr( client, 'delete_bgpvpn_%s_assoc' % self._assoc_res_name) bgpvpn = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn) fails = 0 for id in parsed_args.resource_association_ids: try: delete_method(bgpvpn['id'], id) LOG.warning( "%(assoc_res_name)s association %(id)s deleted", {'assoc_res_name': self._assoc_res_name.capitalize(), 'id': id}) except Exception as e: fails += 1 LOG.error("Failed to delete %(assoc_res_name)s " "association with ID '%(id)s': %(e)s", {'assoc_res_name': self._assoc_res_name, 'id': id, 'e': e}) if fails > 0: msg = (_("Failed to delete %(fails)s of %(total)s " "%(assoc_res_name)s BGP VPN association(s).") % {'fails': fails, 'total': len(parsed_args.resource_association_ids), 'assoc_res_name': self._assoc_res_name}) raise exceptions.CommandError(msg) class ListBgpvpnResAssoc(command.Lister): """List BGP VPN resource associations for a given BGP VPN""" def get_parser(self, prog_name): parser = super(ListBgpvpnResAssoc, self).get_parser(prog_name) parser.add_argument( 'bgpvpn', metavar="", help=_("BGP VPN listed associations belong to (name or ID)"), ) parser.add_argument( '--long', action='store_true', help=_("List additional fields in output"), ) parser.add_argument( '--property', metavar="", help=_("Filter property to apply on returned BGP VPNs (repeat to " "filter on multiple properties)"), action=parseractions.KeyValueAction, ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient list_method = getattr(client, 'list_bgpvpn_%s_assocs' % self._assoc_res_name) bgpvpn = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn) params = {} if parsed_args.property: params.update(parsed_args.property) objs = list_method(bgpvpn['id'], retrieve_all=True, **params)[self._resource_plural] transform = getattr(self, '_transform_resource', None) if callable(transform): [transform(obj) for obj in objs] headers, columns = nc_osc_utils.get_column_definitions( self._attr_map, long_listing=parsed_args.long) return (headers, (osc_utils.get_dict_properties( s, columns, formatters=self._formatters) for s in objs)) class ShowBgpvpnResAssoc(command.ShowOne): """Show information of a given BGP VPN resource association""" def get_parser(self, prog_name): parser = super(ShowBgpvpnResAssoc, self).get_parser(prog_name) parser.add_argument( 'resource_association_id', metavar="<%s association ID>" % self._assoc_res_name, help=(_("%s association ID to look up") % self._assoc_res_name.capitalize()), ) parser.add_argument( 'bgpvpn', metavar="", help=_("BGP VPN the association belongs to (name or ID)"), ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient show_method = getattr(client, 'show_bgpvpn_%s_assoc' % self._assoc_res_name) bgpvpn = client.find_resource(constants.BGPVPN, parsed_args.bgpvpn) assoc = client.find_resource_by_id( self._resource, parsed_args.resource_association_id, cmd_resource='bgpvpn_%s_assoc' % self._assoc_res_name, parent_id=bgpvpn['id']) obj = show_method(bgpvpn['id'], assoc['id'])[self._resource] transform = getattr(self, '_transform_resource', None) if callable(transform): transform(obj) columns, display_columns = nc_osc_utils.get_columns(obj, self._attr_map) data = osc_utils.get_dict_properties(obj, columns, formatters=self._formatters) return display_columns, data python-neutronclient-6.7.0/neutronclient/osc/v2/networking_bgpvpn/__init__.py0000666000175100017510000000000013232473350027632 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/vpnaas/0000775000175100017510000000000013232473710023256 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/vpnaas/endpoint_group.py0000666000175100017510000001754513232473350026702 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from oslo_log import log as logging from neutronclient._i18n import _ from neutronclient.osc import utils as osc_utils LOG = logging.getLogger(__name__) _attr_map = ( ('id', 'ID', osc_utils.LIST_BOTH), ('name', 'Name', osc_utils.LIST_BOTH), ('type', 'Type', osc_utils.LIST_BOTH), ('endpoints', 'Endpoints', osc_utils.LIST_BOTH), ('description', 'Description', osc_utils.LIST_LONG_ONLY), ('tenant_id', 'Project', osc_utils.LIST_LONG_ONLY), ) def _get_common_parser(parser): parser.add_argument( '--description', metavar='', help=_('Description for the endpoint group')) return parser def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} if is_create: if parsed_args.project is not None: attrs['tenant_id'] = osc_utils.find_project( client_manager.identity, parsed_args.project, parsed_args.project_domain, ).id if parsed_args.description: attrs['description'] = parsed_args.description return attrs class CreateEndpointGroup(command.ShowOne): _description = _("Create an endpoint group") def get_parser(self, prog_name): parser = super(CreateEndpointGroup, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( 'name', metavar='', help=_('Name for the endpoint group')) parser.add_argument( '--type', required=True, help=_('Type of endpoints in group (e.g. subnet, cidr)')) parser.add_argument( '--value', action='append', dest='endpoints', required=True, help=_('Endpoint(s) for the group. Must all be of the same type. ' '(--value) option can be repeated')) osc_utils.add_project_owner_option_to_parser(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) if parsed_args.name: attrs['name'] = str(parsed_args.name) attrs['type'] = parsed_args.type if parsed_args.type == 'subnet': _subnet_ids = [client.find_resource( 'subnet', endpoint, cmd_resource='subnet')['id'] for endpoint in parsed_args.endpoints] attrs['endpoints'] = _subnet_ids else: attrs['endpoints'] = parsed_args.endpoints obj = client.create_endpoint_group( {'endpoint_group': attrs})['endpoint_group'] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data class DeleteEndpointGroup(command.Command): _description = _("Delete endpoint group(s)") def get_parser(self, prog_name): parser = super(DeleteEndpointGroup, self).get_parser(prog_name) parser.add_argument( 'endpoint_group', metavar='', nargs='+', help=_('Endpoint group(s) to delete (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient result = 0 for endpoint in parsed_args.endpoint_group: try: endpoint_id = client.find_resource( 'endpoint_group', endpoint, cmd_resource='endpoint_group')['id'] client.delete_endpoint_group(endpoint_id) except Exception as e: result += 1 LOG.error(_("Failed to delete endpoint group with " "name or ID '%(endpoint_group)s': %(e)s"), {'endpoint_group': endpoint, 'e': e}) if result > 0: total = len(parsed_args.endpoint_group) msg = (_("%(result)s of %(total)s endpoint group failed " "to delete.") % {'result': result, 'total': total}) raise exceptions.CommandError(msg) class ListEndpointGroup(command.Lister): _description = _("List endpoint groups that belong to a given project") def get_parser(self, prog_name): parser = super(ListEndpointGroup, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', default=False, help=_("List additional fields in output") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient obj = client.list_endpoint_groups()['endpoint_groups'] headers, columns = osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties(s, columns) for s in obj)) class SetEndpointGroup(command.Command): _description = _("Set endpoint group properties") def get_parser(self, prog_name): parser = super(SetEndpointGroup, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( '--name', metavar='', help=_('Set a name for the endpoint group')) parser.add_argument( 'endpoint_group', metavar='', help=_('Endpoint group to set (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) if parsed_args.name: attrs['name'] = str(parsed_args.name) endpoint_id = client.find_resource( 'endpoint_group', parsed_args.endpoint_group, cmd_resource='endpoint_group')['id'] try: client.update_endpoint_group(endpoint_id, {'endpoint_group': attrs}) except Exception as e: msg = (_("Failed to set endpoint group " "%(endpoint_group)s: %(e)s") % {'endpoint_group': parsed_args.endpoint_group, 'e': e}) raise exceptions.CommandError(msg) class ShowEndpointGroup(command.ShowOne): _description = _("Display endpoint group details") def get_parser(self, prog_name): parser = super(ShowEndpointGroup, self).get_parser(prog_name) parser.add_argument( 'endpoint_group', metavar='', help=_('Endpoint group to display (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient endpoint_id = client.find_resource( 'endpoint_group', parsed_args.endpoint_group, cmd_resource='endpoint_group')['id'] obj = client.show_endpoint_group(endpoint_id)['endpoint_group'] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return (display_columns, data) python-neutronclient-6.7.0/neutronclient/osc/v2/vpnaas/utils.py0000666000175100017510000001033013232473350024767 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # """VPN Utilities and helper functions.""" from neutronclient._i18n import _ from neutronclient.common import exceptions DPD_SUPPORTED_ACTIONS = ['hold', 'clear', 'restart', 'restart-by-peer', 'disabled'] DPD_SUPPORTED_KEYS = ['action', 'interval', 'timeout'] lifetime_keys = ['units', 'value'] lifetime_units = ['seconds'] def validate_dpd_dict(dpd_dict): for key, value in dpd_dict.items(): if key not in DPD_SUPPORTED_KEYS: message = _( "DPD Dictionary KeyError: " "Reason-Invalid DPD key : " "'%(key)s' not in %(supported_key)s") % { 'key': key, 'supported_key': DPD_SUPPORTED_KEYS} raise exceptions.CommandError(message) if key == 'action' and value not in DPD_SUPPORTED_ACTIONS: message = _( "DPD Dictionary ValueError: " "Reason-Invalid DPD action : " "'%(key_value)s' not in %(supported_action)s") % { 'key_value': value, 'supported_action': DPD_SUPPORTED_ACTIONS} raise exceptions.CommandError(message) if key in ('interval', 'timeout'): try: if int(value) <= 0: raise ValueError() except ValueError: message = _( "DPD Dictionary ValueError: " "Reason-Invalid positive integer value: " "'%(key)s' = %(value)s") % { 'key': key, 'value': value} raise exceptions.CommandError(message) else: dpd_dict[key] = int(value) return def validate_lifetime_dict(lifetime_dict): for key, value in lifetime_dict.items(): if key not in lifetime_keys: message = _( "Lifetime Dictionary KeyError: " "Reason-Invalid unit key : " "'%(key)s' not in %(supported_key)s") % { 'key': key, 'supported_key': lifetime_keys} raise exceptions.CommandError(message) if key == 'units' and value not in lifetime_units: message = _( "Lifetime Dictionary ValueError: " "Reason-Invalid units : " "'%(key_value)s' not in %(supported_units)s") % { 'key_value': key, 'supported_units': lifetime_units} raise exceptions.CommandError(message) if key == 'value': try: if int(value) < 60: raise ValueError() except ValueError: message = _( "Lifetime Dictionary ValueError: " "Reason-Invalid value should be at least 60:" "'%(key_value)s' = %(value)s") % { 'key_value': key, 'value': value} raise exceptions.CommandError(message) else: lifetime_dict['value'] = int(value) return def lifetime_help(policy): lifetime = _("%s lifetime attributes. " "'units'-seconds, default:seconds. " "'value'-non negative integer, default:3600.") % policy return lifetime def dpd_help(policy): dpd = _(" %s Dead Peer Detection attributes." " 'action'-hold,clear,disabled,restart,restart-by-peer." " 'interval' and 'timeout' are non negative integers. " " 'interval' should be less than 'timeout' value. " " 'action', default:hold 'interval', default:30, " " 'timeout', default:120.") % policy.capitalize() return dpd python-neutronclient-6.7.0/neutronclient/osc/v2/vpnaas/ipsec_site_connection.py0000666000175100017510000003473513232473350030214 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from osc_lib.cli import format_columns from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from oslo_log import log as logging from neutronclient._i18n import _ from neutronclient.common import utils as nc_utils from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.vpnaas import utils as vpn_utils LOG = logging.getLogger(__name__) _formatters = { 'peer_cidrs': format_columns.ListColumn } _attr_map = ( ('id', 'ID', osc_utils.LIST_BOTH), ('name', 'Name', osc_utils.LIST_BOTH), ('peer_address', 'Peer Address', osc_utils.LIST_BOTH), ('auth_mode', 'Authentication Algorithm', osc_utils.LIST_BOTH), ('status', 'Status', osc_utils.LIST_BOTH), ('tenant_id', 'Project', osc_utils.LIST_LONG_ONLY), ('peer_cidrs', 'Peer CIDRs', osc_utils.LIST_LONG_ONLY), ('vpnservice_id', 'VPN Service', osc_utils.LIST_LONG_ONLY), ('ipsecpolicy_id', 'IPSec Policy', osc_utils.LIST_LONG_ONLY), ('ikepolicy_id', 'IKE Policy', osc_utils.LIST_LONG_ONLY), ('mtu', 'MTU', osc_utils.LIST_LONG_ONLY), ('initiator', 'Initiator', osc_utils.LIST_LONG_ONLY), ('admin_state_up', 'State', osc_utils.LIST_LONG_ONLY), ('description', 'Description', osc_utils.LIST_LONG_ONLY), ('psk', 'Pre-shared Key', osc_utils.LIST_LONG_ONLY), ('route_mode', 'Route Mode', osc_utils.LIST_LONG_ONLY), ('local_id', 'Local ID', osc_utils.LIST_LONG_ONLY), ('peer_id', 'Peer ID', osc_utils.LIST_LONG_ONLY), ('local_ep_group_id', 'Local Endpoint Group ID', osc_utils.LIST_LONG_ONLY), ('peer_ep_group_id', 'Peer Endpoint Group ID', osc_utils.LIST_LONG_ONLY), ) def _convert_to_lowercase(string): return string.lower() def _get_common_parser(parser, is_create=True): parser.add_argument( '--description', metavar='', help=_('Description for the connection')) parser.add_argument( '--dpd', metavar="action=ACTION,interval=INTERVAL,timeout=TIMEOUT", type=nc_utils.str2dict_type( optional_keys=['action', 'interval', 'timeout']), help=vpn_utils.dpd_help("IPsec connection")) parser.add_argument( '--mtu', help=_('MTU size for the connection')) parser.add_argument( '--initiator', choices=['bi-directional', 'response-only'], type=_convert_to_lowercase, help=_('Initiator state')) peer_group = parser.add_mutually_exclusive_group() peer_group.add_argument( '--peer-cidr', dest='peer_cidrs', help=_('Remote subnet(s) in CIDR format. ' 'Cannot be specified when using endpoint groups. Only ' 'applicable, if subnet provided for VPN service.') ) peer_group.add_argument( '--local-endpoint-group', help=_('Local endpoint group (name or ID) with subnet(s) ' 'for IPsec connection') ) parser.add_argument( '--peer-endpoint-group', help=_('Peer endpoint group (name or ID) with CIDR(s) for ' 'IPSec connection')) admin_group = parser.add_mutually_exclusive_group() admin_group.add_argument( '--enable', action='store_true', help=_("Enable IPSec site connection") ) admin_group.add_argument( '--disable', action='store_true', help=_("Disable IPSec site connection") ) parser.add_argument( '--local-id', help=_('An ID to be used instead of the external IP ' 'address for a virtual router')) return parser def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} if is_create: if 'project' in parsed_args and parsed_args.project is not None: attrs['tenant_id'] = osc_utils.find_project( client_manager.identity, parsed_args.project, parsed_args.project_domain, ).id if parsed_args.description: attrs['description'] = str(parsed_args.description) if parsed_args.mtu: attrs['mtu'] = parsed_args.mtu if parsed_args.enable: attrs['admin_state_up'] = True if parsed_args.disable: attrs['admin_state_up'] = False if parsed_args.initiator: attrs['initiator'] = parsed_args.initiator if parsed_args.dpd: vpn_utils.validate_dpd_dict(parsed_args.dpd) attrs['dpd'] = parsed_args.dpd if parsed_args.local_endpoint_group: _local_epg = client_manager.neutronclient.find_resource( 'endpoint_group', parsed_args.local_endpoint_group, cmd_resource='endpoint_group')['id'] attrs['local_ep_group_id'] = _local_epg if parsed_args.peer_endpoint_group: _peer_epg = client_manager.neutronclient.find_resource( 'endpoint_group', parsed_args.peer_endpoint_group, cmd_resource='endpoint_group')['id'] attrs['peer_ep_group_id'] = _peer_epg if parsed_args.peer_cidrs: attrs['peer_cidrs'] = parsed_args.peer_cidrs if parsed_args.local_id: attrs['local_id'] = parsed_args.local_id return attrs class CreateIPsecSiteConnection(command.ShowOne): _description = _("Create an IPsec site connection") def get_parser(self, prog_name): parser = super(CreateIPsecSiteConnection, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( '--peer-id', required=True, help=_('Peer router identity for authentication. Can be ' 'IPv4/IPv6 address, e-mail address, key id, or FQDN')) parser.add_argument( '--peer-address', required=True, help=_('Peer gateway public IPv4/IPv6 address or FQDN')) parser.add_argument( '--psk', required=True, help=_('Pre-shared key string.')) parser.add_argument( '--vpnservice', metavar='VPNSERVICE', required=True, help=_('VPN service instance associated with this ' 'connection (name or ID)')) parser.add_argument( '--ikepolicy', metavar='IKEPOLICY', required=True, help=_('IKE policy associated with this connection (name or ID)')) parser.add_argument( '--ipsecpolicy', metavar='IPSECPOLICY', required=True, help=_('IPsec policy associated with this connection ' '(name or ID)')) parser.add_argument( 'name', metavar='', help=_('Set friendly name for the connection')) osc_utils.add_project_owner_option_to_parser(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) if parsed_args.vpnservice: _vpnservice_id = client.find_resource( 'vpnservice', parsed_args.vpnservice, cmd_resource='vpnservice')['id'] attrs['vpnservice_id'] = _vpnservice_id if parsed_args.ikepolicy: _ikepolicy_id = client.find_resource( 'ikepolicy', parsed_args.ikepolicy, cmd_resource='ikepolicy')['id'] attrs['ikepolicy_id'] = _ikepolicy_id if parsed_args.ipsecpolicy: _ipsecpolicy_id = client.find_resource( 'ipsecpolicy', parsed_args.ipsecpolicy, cmd_resource='ipsecpolicy')['id'] attrs['ipsecpolicy_id'] = _ipsecpolicy_id if parsed_args.peer_id: attrs['peer_id'] = parsed_args.peer_id if parsed_args.peer_address: attrs['peer_address'] = parsed_args.peer_address if parsed_args.psk: attrs['psk'] = parsed_args.psk if parsed_args.name: attrs['name'] = parsed_args.name if (bool(parsed_args.local_endpoint_group) != bool(parsed_args.peer_endpoint_group)): message = _("You must specify both local and peer endpoint " "groups") raise exceptions.CommandError(message) if not parsed_args.peer_cidrs and not parsed_args.local_endpoint_group: message = _("You must specify endpoint groups or peer CIDR(s)") raise exceptions.CommandError(message) obj = client.create_ipsec_site_connection( {'ipsec_site_connection': attrs})['ipsec_site_connection'] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns, formatters=_formatters) return display_columns, data class DeleteIPsecSiteConnection(command.Command): _description = _("Delete IPsec site connection(s)") def get_parser(self, prog_name): parser = super(DeleteIPsecSiteConnection, self).get_parser(prog_name) parser.add_argument( 'ipsec_site_connection', metavar='', nargs='+', help=_('IPsec site connection to delete (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient result = 0 for ipsec_conn in parsed_args.ipsec_site_connection: try: ipsec_con_id = client.find_resource( 'ipsec_site_connection', ipsec_conn, cmd_resource='ipsec_site_connection')['id'] client.delete_ipsec_site_connection(ipsec_con_id) except Exception as e: result += 1 LOG.error(_("Failed to delete IPsec site connection with " "name or ID '%(ipsec_site_conn)s': %(e)s"), {'ipsec_site_conn': ipsec_conn, 'e': e}) if result > 0: total = len(parsed_args.ipsec_site_connection) msg = (_("%(result)s of %(total)s IPsec site connection failed " "to delete.") % {'result': result, 'total': total}) raise exceptions.CommandError(msg) class ListIPsecSiteConnection(command.Lister): _description = _("List IPsec site connections " "that belong to a given project") def get_parser(self, prog_name): parser = super(ListIPsecSiteConnection, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', default=False, help=_("List additional fields in output") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient obj = client.list_ipsec_site_connections()['ipsec_site_connections'] headers, columns = osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties( s, columns, formatters=_formatters) for s in obj)) class SetIPsecSiteConnection(command.Command): _description = _("Set IPsec site connection properties") def get_parser(self, prog_name): parser = super(SetIPsecSiteConnection, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( '--peer-id', help=_('Peer router identity for authentication. Can be ' 'IPv4/IPv6 address, e-mail address, key id, or FQDN')) parser.add_argument( '--peer-address', help=_('Peer gateway public IPv4/IPv6 address or FQDN')) parser.add_argument( '--name', metavar='', help=_('Set friendly name for the connection')) parser.add_argument( 'ipsec_site_connection', metavar='', help=_('IPsec site connection to set (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) if parsed_args.peer_id: attrs['peer_id'] = parsed_args.peer_id if parsed_args.peer_address: attrs['peer_address'] = parsed_args.peer_address if parsed_args.name: attrs['name'] = parsed_args.name ipsec_conn_id = client.find_resource( 'ipsec_site_connection', parsed_args.ipsec_site_connection, cmd_resource='ipsec_site_connection')['id'] try: client.update_ipsec_site_connection( ipsec_conn_id, {'ipsec_site_connection': attrs}) except Exception as e: msg = (_("Failed to set IPsec site " "connection '%(ipsec_conn)s': %(e)s") % {'ipsec_conn': parsed_args.ipsec_site_connection, 'e': e}) raise exceptions.CommandError(msg) class ShowIPsecSiteConnection(command.ShowOne): _description = _("Show information of a given IPsec site connection") def get_parser(self, prog_name): parser = super(ShowIPsecSiteConnection, self).get_parser(prog_name) parser.add_argument( 'ipsec_site_connection', metavar='', help=_('IPsec site connection to display (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient ipsec_site_id = client.find_resource( 'ipsec_site_connection', parsed_args.ipsec_site_connection, cmd_resource='ipsec_site_connection')['id'] obj = client.show_ipsec_site_connection( ipsec_site_id)['ipsec_site_connection'] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns, formatters=_formatters) return (display_columns, data) python-neutronclient-6.7.0/neutronclient/osc/v2/vpnaas/vpnservice.py0000666000175100017510000002037613232473350026026 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from oslo_log import log as logging from neutronclient._i18n import _ from neutronclient.osc import utils as osc_utils LOG = logging.getLogger(__name__) _attr_map = ( ('id', 'ID', osc_utils.LIST_BOTH), ('name', 'Name', osc_utils.LIST_BOTH), ('router_id', 'Router', osc_utils.LIST_BOTH), ('subnet_id', 'Subnet', osc_utils.LIST_BOTH), ('flavor_id', 'Flavor', osc_utils.LIST_BOTH), ('admin_state_up', 'State', osc_utils.LIST_BOTH), ('status', 'Status', osc_utils.LIST_BOTH), ('description', 'Description', osc_utils.LIST_LONG_ONLY), ('tenant_id', 'Project', osc_utils.LIST_LONG_ONLY), ) def _get_common_parser(parser): parser.add_argument( '--description', metavar='', help=_('Description for the VPN service')) parser.add_argument( '--subnet', metavar='', help=_('Local private subnet (name or ID)')) parser.add_argument( '--flavor', metavar='', help=_('Flavor for the VPN service (name or ID)')) admin_group = parser.add_mutually_exclusive_group() admin_group.add_argument( '--enable', action='store_true', help=_("Enable VPN service") ) admin_group.add_argument( '--disable', action='store_true', help=_("Disable VPN service") ) return parser def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} if is_create: if 'project' in parsed_args and parsed_args.project is not None: attrs['tenant_id'] = osc_utils.find_project( client_manager.identity, parsed_args.project, parsed_args.project_domain, ).id if parsed_args.description: attrs['description'] = str(parsed_args.description) if parsed_args.subnet: _subnet_id = client_manager.network.find_subnet( parsed_args.subnet).id attrs['subnet_id'] = _subnet_id if parsed_args.flavor: _flavor_id = client_manager.network.find_flavor( parsed_args.flavor, ignore_missing=False ).id attrs['flavor_id'] = _flavor_id if parsed_args.enable: attrs['admin_state_up'] = True if parsed_args.disable: attrs['admin_state_up'] = False return attrs class CreateVPNService(command.ShowOne): _description = _("Create an VPN service") def get_parser(self, prog_name): parser = super(CreateVPNService, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( 'name', metavar='', help=_('Name for the VPN service')) parser.add_argument( '--router', metavar='ROUTER', required=True, help=_('Router for the VPN service (name or ID)')) osc_utils.add_project_owner_option_to_parser(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) if parsed_args.name: attrs['name'] = str(parsed_args.name) if parsed_args.router: _router_id = self.app.client_manager.network.find_router( parsed_args.router).id attrs['router_id'] = _router_id obj = client.create_vpnservice({'vpnservice': attrs})['vpnservice'] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data class DeleteVPNService(command.Command): _description = _("Delete VPN service(s)") def get_parser(self, prog_name): parser = super(DeleteVPNService, self).get_parser(prog_name) parser.add_argument( 'vpnservice', metavar='', nargs='+', help=_('VPN service to delete (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient result = 0 for vpn in parsed_args.vpnservice: try: vpn_id = client.find_resource( 'vpnservice', vpn, cmd_resource='vpnservice')['id'] client.delete_vpnservice(vpn_id) except Exception as e: result += 1 LOG.error(_("Failed to delete VPN service with " "name or ID '%(vpnservice)s': %(e)s"), {'vpnservice': vpn, 'e': e}) if result > 0: total = len(parsed_args.vpnservice) msg = (_("%(result)s of %(total)s vpn service failed " "to delete.") % {'result': result, 'total': total}) raise exceptions.CommandError(msg) class ListVPNService(command.Lister): _description = _("List VPN services that belong to a given project") def get_parser(self, prog_name): parser = super(ListVPNService, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', default=False, help=_("List additional fields in output") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient obj = client.list_vpnservices()['vpnservices'] headers, columns = osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties(s, columns) for s in obj)) class SetVPNSercice(command.Command): _description = _("Set VPN service properties") def get_parser(self, prog_name): parser = super(SetVPNSercice, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( '--name', metavar='', help=_('Name for the VPN service')) parser.add_argument( 'vpnservice', metavar='', help=_('VPN service to modify (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) if parsed_args.name: attrs['name'] = str(parsed_args.name) vpn_id = client.find_resource( 'vpnservice', parsed_args.vpnservice, cmd_resource='vpnservice')['id'] try: client.update_vpnservice(vpn_id, {'vpnservice': attrs}) except Exception as e: msg = (_("Failed to set vpn service '%(vpn)s': %(e)s") % {'vpn': parsed_args.vpnservice, 'e': e}) raise exceptions.CommandError(msg) class ShowVPNService(command.ShowOne): _description = _("Display VPN service details") def get_parser(self, prog_name): parser = super(ShowVPNService, self).get_parser(prog_name) parser.add_argument( 'vpnservice', metavar='', help=_('VPN service to display (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient vpn_id = client.find_resource( 'vpnservice', parsed_args.vpnservice, cmd_resource='vpnservice')['id'] obj = client.show_vpnservice(vpn_id)['vpnservice'] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return (display_columns, data) python-neutronclient-6.7.0/neutronclient/osc/v2/vpnaas/ipsecpolicy.py0000666000175100017510000002204713232473350026162 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from oslo_log import log as logging from neutronclient._i18n import _ from neutronclient.common import utils as nc_utils from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.vpnaas import utils as vpn_utils LOG = logging.getLogger(__name__) _attr_map = ( ('id', 'ID', osc_utils.LIST_BOTH), ('name', 'Name', osc_utils.LIST_BOTH), ('auth_algorithm', 'Authentication Algorithm', osc_utils.LIST_BOTH), ('encapsulation_mode', 'Encapsulation Mode', osc_utils.LIST_BOTH), ('transform_protocol', 'Transform Protocol', osc_utils.LIST_BOTH), ('encryption_algorithm', 'Encryption Algorithm', osc_utils.LIST_BOTH), ('pfs', 'Perfect Forward Secrecy (PFS)', osc_utils.LIST_LONG_ONLY), ('description', 'Description', osc_utils.LIST_LONG_ONLY), ('tenant_id', 'Project', osc_utils.LIST_LONG_ONLY), ('lifetime', 'Lifetime', osc_utils.LIST_LONG_ONLY), ) def _convert_to_lowercase(string): return string.lower() def _get_common_parser(parser): parser.add_argument( '--description', metavar='', help=_('Description of the IPsec policy')) parser.add_argument( '--auth-algorithm', choices=['sha1', 'sha256', 'sha384', 'sha512'], type=_convert_to_lowercase, help=_('Authentication algorithm for IPsec policy')) parser.add_argument( '--encapsulation-mode', choices=['tunnel', 'transport'], type=_convert_to_lowercase, help=_('Encapsulation mode for IPsec policy')) parser.add_argument( '--encryption-algorithm', choices=['3des', 'aes-128', 'aes-192', 'aes-256'], type=_convert_to_lowercase, help=_('Encryption algorithm for IPsec policy')) parser.add_argument( '--lifetime', metavar="units=UNITS,value=VALUE", type=nc_utils.str2dict_type(optional_keys=['units', 'value']), help=vpn_utils.lifetime_help("IPsec")) parser.add_argument( '--pfs', choices=['group2', 'group5', 'group14'], type=_convert_to_lowercase, help=_('Perfect Forward Secrecy for IPsec policy')) parser.add_argument( '--transform-protocol', type=_convert_to_lowercase, choices=['esp', 'ah', 'ah-esp'], help=_('Transform protocol for IPsec policy')) def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} if is_create: if 'project' in parsed_args and parsed_args.project is not None: attrs['tenant_id'] = osc_utils.find_project( client_manager.identity, parsed_args.project, parsed_args.project_domain, ).id if parsed_args.description: attrs['description'] = str(parsed_args.description) if parsed_args.auth_algorithm: attrs['auth_algorithm'] = parsed_args.auth_algorithm if parsed_args.encapsulation_mode: attrs['encapsulation_mode'] = parsed_args.encapsulation_mode if parsed_args.transform_protocol: attrs['transform_protocol'] = parsed_args.transform_protocol if parsed_args.encryption_algorithm: attrs['encryption_algorithm'] = parsed_args.encryption_algorithm if parsed_args.pfs: attrs['pfs'] = parsed_args.pfs if parsed_args.lifetime: vpn_utils.validate_lifetime_dict(parsed_args.lifetime) attrs['lifetime'] = parsed_args.lifetime return attrs class CreateIPsecPolicy(command.ShowOne): _description = _("Create an IPsec policy") def get_parser(self, prog_name): parser = super(CreateIPsecPolicy, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( 'name', metavar='', help=_('Name of the IPsec policy')) osc_utils.add_project_owner_option_to_parser(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) if parsed_args.name: attrs['name'] = str(parsed_args.name) obj = client.create_ipsecpolicy({'ipsecpolicy': attrs})['ipsecpolicy'] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data class DeleteIPsecPolicy(command.Command): _description = _("Delete IPsec policy(policies)") def get_parser(self, prog_name): parser = super(DeleteIPsecPolicy, self).get_parser(prog_name) parser.add_argument( 'ipsecpolicy', metavar='', nargs='+', help=_('ipsec policy to delete (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient result = 0 for ipsec in parsed_args.ipsecpolicy: try: ipsec_id = client.find_resource( 'ipsecpolicy', ipsec, cmd_resource='ipsecpolicy')['id'] client.delete_ipsecpolicy(ipsec_id) except Exception as e: result += 1 LOG.error(_("Failed to delete IPsec policy with " "name or ID '%(ipsecpolicy)s': %(e)s"), {'ipsecpolicy': ipsec, 'e': e}) if result > 0: total = len(parsed_args.ipsecpolicy) msg = (_("%(result)s of %(total)s IPsec policy failed " "to delete.") % {'result': result, 'total': total}) raise exceptions.CommandError(msg) class ListIPsecPolicy(command.Lister): _description = _("List IPsec policies that belong to a given project") def get_parser(self, prog_name): parser = super(ListIPsecPolicy, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', default=False, help=_("List additional fields in output") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient obj = client.list_ipsecpolicies()['ipsecpolicies'] headers, columns = osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties(s, columns) for s in obj)) class SetIPsecPolicy(command.Command): _description = _("Set IPsec policy properties") def get_parser(self, prog_name): parser = super(SetIPsecPolicy, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( '--name', metavar='', help=_('Name of the IPsec policy')) parser.add_argument( 'ipsecpolicy', metavar='', help=_('IPsec policy to set (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) if parsed_args.name: attrs['name'] = str(parsed_args.name) ipsec_id = client.find_resource( 'ipsecpolicy', parsed_args.ipsecpolicy, cmd_resource='ipsecpolicy')['id'] try: client.update_ipsecpolicy(ipsec_id, {'ipsecpolicy': attrs}) except Exception as e: msg = (_("Failed to set IPsec policy '%(ipsec)s': %(e)s") % {'ipsec': parsed_args.ipsecpolicy, 'e': e}) raise exceptions.CommandError(msg) class ShowIPsecPolicy(command.ShowOne): _description = _("Display IPsec policy details") def get_parser(self, prog_name): parser = super(ShowIPsecPolicy, self).get_parser(prog_name) parser.add_argument( 'ipsecpolicy', metavar='', help=_('IPsec policy to display (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient ipsec_id = client.find_resource( 'ipsecpolicy', parsed_args.ipsecpolicy, cmd_resource='ipsecpolicy')['id'] obj = client.show_ipsecpolicy(ipsec_id)['ipsecpolicy'] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return (display_columns, data) python-neutronclient-6.7.0/neutronclient/osc/v2/vpnaas/ikepolicy.py0000666000175100017510000002146113232473350025626 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils from oslo_log import log as logging from neutronclient._i18n import _ from neutronclient.common import utils as nc_utils from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.vpnaas import utils as vpn_utils LOG = logging.getLogger(__name__) _attr_map = ( ('id', 'ID', osc_utils.LIST_BOTH), ('name', 'Name', osc_utils.LIST_BOTH), ('auth_algorithm', 'Authentication Algorithm', osc_utils.LIST_BOTH), ('encryption_algorithm', 'Encryption Algorithm', osc_utils.LIST_BOTH), ('ike_version', 'IKE Version', osc_utils.LIST_BOTH), ('pfs', 'Perfect Forward Secrecy (PFS)', osc_utils.LIST_BOTH), ('description', 'Description', osc_utils.LIST_LONG_ONLY), ('phase1_negotiation_mode', 'Phase1 Negotiation Mode', osc_utils.LIST_LONG_ONLY), ('tenant_id', 'Project', osc_utils.LIST_LONG_ONLY), ('lifetime', 'Lifetime', osc_utils.LIST_LONG_ONLY), ) def _convert_to_lowercase(string): return string.lower() def _get_common_parser(parser): parser.add_argument( '--description', metavar='', help=_('Description of the IKE policy')) parser.add_argument( '--auth-algorithm', choices=['sha1', 'sha256', 'sha384', 'sha512'], type=_convert_to_lowercase, help=_('Authentication algorithm')) parser.add_argument( '--encryption-algorithm', choices=['aes-128', '3des', 'aes-192', 'aes-256'], type=_convert_to_lowercase, help=_('Encryption algorithm')) parser.add_argument( '--phase1-negotiation-mode', choices=['main'], type=_convert_to_lowercase, help=_('IKE Phase1 negotiation mode')) parser.add_argument( '--ike-version', choices=['v1', 'v2'], type=_convert_to_lowercase, help=_('IKE version for the policy')) parser.add_argument( '--pfs', choices=['group5', 'group2', 'group14'], type=_convert_to_lowercase, help=_('Perfect Forward Secrecy')) parser.add_argument( '--lifetime', metavar="units=UNITS,value=VALUE", type=nc_utils.str2dict_type(optional_keys=['units', 'value']), help=vpn_utils.lifetime_help("IKE")) return parser def _get_common_attrs(client_manager, parsed_args, is_create=True): attrs = {} if is_create: if 'project' in parsed_args and parsed_args.project is not None: attrs['tenant_id'] = osc_utils.find_project( client_manager.identity, parsed_args.project, parsed_args.project_domain, ).id if parsed_args.description: attrs['description'] = parsed_args.description if parsed_args.auth_algorithm: attrs['auth_algorithm'] = parsed_args.auth_algorithm if parsed_args.encryption_algorithm: attrs['encryption_algorithm'] = parsed_args.encryption_algorithm if parsed_args.phase1_negotiation_mode: attrs['phase1_negotiation_mode'] = parsed_args.phase1_negotiation_mode if parsed_args.ike_version: attrs['ike_version'] = parsed_args.ike_version if parsed_args.pfs: attrs['pfs'] = parsed_args.pfs if parsed_args.lifetime: vpn_utils.validate_lifetime_dict(parsed_args.lifetime) attrs['lifetime'] = parsed_args.lifetime return attrs class CreateIKEPolicy(command.ShowOne): _description = _("Create an IKE policy") def get_parser(self, prog_name): parser = super(CreateIKEPolicy, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( 'name', metavar='', help=_('Name of the IKE policy')) osc_utils.add_project_owner_option_to_parser(parser) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args) if parsed_args.name: attrs['name'] = str(parsed_args.name) obj = client.create_ikepolicy({'ikepolicy': attrs})['ikepolicy'] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return display_columns, data class DeleteIKEPolicy(command.Command): _description = _("Delete IKE policy (policies)") def get_parser(self, prog_name): parser = super(DeleteIKEPolicy, self).get_parser(prog_name) parser.add_argument( 'ikepolicy', metavar='', nargs='+', help=_('IKE policy to delete (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient result = 0 for ike in parsed_args.ikepolicy: try: ike_id = client.find_resource( 'ikepolicy', ike, cmd_resource='ikepolicy')['id'] client.delete_ikepolicy(ike_id) except Exception as e: result += 1 LOG.error(_("Failed to delete IKE policy with " "name or ID '%(ikepolicy)s': %(e)s"), {'ikepolicy': ike, 'e': e}) if result > 0: total = len(parsed_args.ikepolicy) msg = (_("%(result)s of %(total)s IKE policy failed " "to delete.") % {'result': result, 'total': total}) raise exceptions.CommandError(msg) class ListIKEPolicy(command.Lister): _description = _("List IKE policies that belong to a given project") def get_parser(self, prog_name): parser = super(ListIKEPolicy, self).get_parser(prog_name) parser.add_argument( '--long', action='store_true', help=_("List additional fields in output") ) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient obj = client.list_ikepolicies()['ikepolicies'] headers, columns = osc_utils.get_column_definitions( _attr_map, long_listing=parsed_args.long) return (headers, (utils.get_dict_properties(s, columns) for s in obj)) class SetIKEPolicy(command.Command): _description = _("Set IKE policy properties") def get_parser(self, prog_name): parser = super(SetIKEPolicy, self).get_parser(prog_name) _get_common_parser(parser) parser.add_argument( '--name', metavar='', help=_('Name of the IKE policy')) parser.add_argument( 'ikepolicy', metavar='', help=_('IKE policy to set (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient attrs = _get_common_attrs(self.app.client_manager, parsed_args, is_create=False) if parsed_args.name: attrs['name'] = parsed_args.name ike_id = client.find_resource( 'ikepolicy', parsed_args.ikepolicy, cmd_resource='ikepolicy')['id'] try: client.update_ikepolicy(ike_id, {'ikepolicy': attrs}) except Exception as e: msg = (_("Failed to set IKE policy '%(ike)s': %(e)s") % {'ike': parsed_args.ikepolicy, 'e': e}) raise exceptions.CommandError(msg) class ShowIKEPolicy(command.ShowOne): _description = _("Display IKE policy details") def get_parser(self, prog_name): parser = super(ShowIKEPolicy, self).get_parser(prog_name) parser.add_argument( 'ikepolicy', metavar='', help=_('IKE policy to display (name or ID)')) return parser def take_action(self, parsed_args): client = self.app.client_manager.neutronclient ike_id = client.find_resource( 'ikepolicy', parsed_args.ikepolicy, cmd_resource='ikepolicy')['id'] obj = client.show_ikepolicy(ike_id)['ikepolicy'] columns, display_columns = osc_utils.get_columns(obj, _attr_map) data = utils.get_dict_properties(obj, columns) return (display_columns, data) python-neutronclient-6.7.0/neutronclient/osc/v2/vpnaas/__init__.py0000666000175100017510000000000013232473350025357 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/__init__.py0000666000175100017510000000000013232473350024067 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/lbaas/0000775000175100017510000000000013232473710023050 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/v2/lbaas/__init__.py0000666000175100017510000000000013232473350025151 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/osc/__init__.py0000666000175100017510000000000013232473350023540 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/client.py0000666000175100017510000004034613232473350022514 0ustar zuulzuul00000000000000# 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 # # 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. # try: import json except ImportError: import simplejson as json import logging import os import debtcollector.renames from keystoneauth1 import access from keystoneauth1 import adapter from oslo_utils import importutils import requests from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils osprofiler_web = importutils.try_import("osprofiler.web") _logger = logging.getLogger(__name__) if os.environ.get('NEUTRONCLIENT_DEBUG'): ch = logging.StreamHandler() _logger.setLevel(logging.DEBUG) _logger.addHandler(ch) _requests_log_level = logging.DEBUG else: _requests_log_level = logging.WARNING logging.getLogger("requests").setLevel(_requests_log_level) MAX_URI_LEN = 8192 USER_AGENT = 'python-neutronclient' REQ_ID_HEADER = 'X-OpenStack-Request-ID' class HTTPClient(object): """Handles the REST calls and responses, include authn.""" CONTENT_TYPE = 'application/json' @debtcollector.renames.renamed_kwarg( 'tenant_id', 'project_id', replace=True) @debtcollector.renames.renamed_kwarg( 'tenant_name', 'project_name', replace=True) def __init__(self, username=None, user_id=None, project_name=None, project_id=None, password=None, auth_url=None, token=None, region_name=None, timeout=None, endpoint_url=None, insecure=False, endpoint_type='publicURL', auth_strategy='keystone', ca_cert=None, log_credentials=False, service_type='network', global_request_id=None, **kwargs): self.username = username self.user_id = user_id self.project_name = project_name self.project_id = project_id self.password = password self.auth_url = auth_url.rstrip('/') if auth_url else None self.service_type = service_type self.endpoint_type = endpoint_type self.region_name = region_name self.timeout = timeout self.auth_token = token self.auth_tenant_id = None self.auth_user_id = None self.endpoint_url = endpoint_url self.auth_strategy = auth_strategy self.log_credentials = log_credentials self.global_request_id = global_request_id if insecure: self.verify_cert = False else: self.verify_cert = ca_cert if ca_cert else True def _cs_request(self, *args, **kwargs): kargs = {} kargs.setdefault('headers', kwargs.get('headers', {})) kargs['headers']['User-Agent'] = USER_AGENT if 'body' in kwargs: kargs['body'] = kwargs['body'] if self.log_credentials: log_kargs = kargs else: log_kargs = self._strip_credentials(kargs) utils.http_log_req(_logger, args, log_kargs) try: resp, body = self.request(*args, **kargs) except requests.exceptions.SSLError as e: raise exceptions.SslCertificateValidationError(reason=e) except Exception as e: # Wrap the low-level connection error (socket timeout, redirect # limit, decompression error, etc) into our custom high-level # connection exception (it is excepted in the upper layers of code) _logger.debug("throwing ConnectionFailed : %s", e) raise exceptions.ConnectionFailed(reason=e) utils.http_log_resp(_logger, resp, body) # log request-id for each api call request_id = resp.headers.get('x-openstack-request-id') if request_id: _logger.debug('%(method)s call to neutron for ' '%(url)s used request id ' '%(response_request_id)s', {'method': resp.request.method, 'url': resp.url, 'response_request_id': request_id}) if resp.status_code == 401: raise exceptions.Unauthorized(message=body) return resp, body def _strip_credentials(self, kwargs): if kwargs.get('body') and self.password: log_kwargs = kwargs.copy() log_kwargs['body'] = kwargs['body'].replace(self.password, 'REDACTED') return log_kwargs else: return kwargs def authenticate_and_fetch_endpoint_url(self): if not self.auth_token: self.authenticate() elif not self.endpoint_url: self.endpoint_url = self._get_endpoint_url() def request(self, url, method, body=None, headers=None, **kwargs): """Request without authentication.""" content_type = kwargs.pop('content_type', None) or 'application/json' headers = headers or {} headers.setdefault('Accept', content_type) if body: headers.setdefault('Content-Type', content_type) if self.global_request_id: headers.setdefault(REQ_ID_HEADER, self.global_request_id) headers['User-Agent'] = USER_AGENT # NOTE(dbelova): osprofiler_web.get_trace_id_headers does not add any # headers in case if osprofiler is not initialized. if osprofiler_web: headers.update(osprofiler_web.get_trace_id_headers()) resp = requests.request( method, url, data=body, headers=headers, verify=self.verify_cert, timeout=self.timeout, **kwargs) return resp, resp.text def _check_uri_length(self, action): uri_len = len(self.endpoint_url) + len(action) if uri_len > MAX_URI_LEN: raise exceptions.RequestURITooLong( excess=uri_len - MAX_URI_LEN) def do_request(self, url, method, **kwargs): # Ensure client always has correct uri - do not guesstimate anything self.authenticate_and_fetch_endpoint_url() self._check_uri_length(url) # Perform the request once. If we get a 401 back then it # might be because the auth token expired, so try to # re-authenticate and try again. If it still fails, bail. try: kwargs['headers'] = kwargs.get('headers') or {} if self.auth_token is None: self.auth_token = "" kwargs['headers']['X-Auth-Token'] = self.auth_token resp, body = self._cs_request(self.endpoint_url + url, method, **kwargs) return resp, body except exceptions.Unauthorized: self.authenticate() kwargs['headers'] = kwargs.get('headers') or {} kwargs['headers']['X-Auth-Token'] = self.auth_token resp, body = self._cs_request( self.endpoint_url + url, method, **kwargs) return resp, body def _extract_service_catalog(self, body): """Set the client's service catalog from the response data.""" self.auth_ref = access.create(body=body) self.service_catalog = self.auth_ref.service_catalog self.auth_token = self.auth_ref.auth_token self.auth_tenant_id = self.auth_ref.tenant_id self.auth_user_id = self.auth_ref.user_id if not self.endpoint_url: self.endpoint_url = self.service_catalog.url_for( region_name=self.region_name, service_type=self.service_type, interface=self.endpoint_type) def _authenticate_keystone(self): if self.user_id: creds = {'userId': self.user_id, 'password': self.password} else: creds = {'username': self.username, 'password': self.password} if self.project_id: body = {'auth': {'passwordCredentials': creds, 'tenantId': self.project_id, }, } else: body = {'auth': {'passwordCredentials': creds, 'tenantName': self.project_name, }, } if self.auth_url is None: raise exceptions.NoAuthURLProvided() token_url = self.auth_url + "/tokens" resp, resp_body = self._cs_request(token_url, "POST", body=json.dumps(body), content_type="application/json", allow_redirects=True) if resp.status_code != 200: raise exceptions.Unauthorized(message=resp_body) if resp_body: try: resp_body = json.loads(resp_body) except ValueError: pass else: resp_body = None self._extract_service_catalog(resp_body) def _authenticate_noauth(self): if not self.endpoint_url: message = _('For "noauth" authentication strategy, the endpoint ' 'must be specified either in the constructor or ' 'using --os-url') raise exceptions.Unauthorized(message=message) def authenticate(self): if self.auth_strategy == 'keystone': self._authenticate_keystone() elif self.auth_strategy == 'noauth': self._authenticate_noauth() else: err_msg = _('Unknown auth strategy: %s') % self.auth_strategy raise exceptions.Unauthorized(message=err_msg) def _get_endpoint_url(self): if self.auth_url is None: raise exceptions.NoAuthURLProvided() url = self.auth_url + '/tokens/%s/endpoints' % self.auth_token try: resp, body = self._cs_request(url, "GET") except exceptions.Unauthorized: # rollback to authenticate() to handle case when neutron client # is initialized just before the token is expired self.authenticate() return self.endpoint_url body = json.loads(body) for endpoint in body.get('endpoints', []): if (endpoint['type'] == 'network' and endpoint.get('region') == self.region_name): if self.endpoint_type not in endpoint: raise exceptions.EndpointTypeNotFound( type_=self.endpoint_type) return endpoint[self.endpoint_type] raise exceptions.EndpointNotFound() def get_auth_info(self): return {'auth_token': self.auth_token, 'auth_tenant_id': self.auth_tenant_id, 'auth_user_id': self.auth_user_id, 'endpoint_url': self.endpoint_url} def get_auth_ref(self): return getattr(self, 'auth_ref', None) class SessionClient(adapter.Adapter): def request(self, *args, **kwargs): kwargs.setdefault('authenticated', False) kwargs.setdefault('raise_exc', False) content_type = kwargs.pop('content_type', None) or 'application/json' headers = kwargs.get('headers') or {} headers.setdefault('Accept', content_type) # NOTE(dbelova): osprofiler_web.get_trace_id_headers does not add any # headers in case if osprofiler is not initialized. if osprofiler_web: headers.update(osprofiler_web.get_trace_id_headers()) try: kwargs.setdefault('data', kwargs.pop('body')) except KeyError: pass if kwargs.get('data'): headers.setdefault('Content-Type', content_type) kwargs['headers'] = headers resp = super(SessionClient, self).request(*args, **kwargs) return resp, resp.text def _check_uri_length(self, url): uri_len = len(self.endpoint_url) + len(url) if uri_len > MAX_URI_LEN: raise exceptions.RequestURITooLong( excess=uri_len - MAX_URI_LEN) def do_request(self, url, method, **kwargs): kwargs.setdefault('authenticated', True) self._check_uri_length(url) return self.request(url, method, **kwargs) @property def endpoint_url(self): # NOTE(jamielennox): This is used purely by the CLI and should be # removed when the CLI gets smarter. return self.get_endpoint() @property def auth_token(self): # NOTE(jamielennox): This is used purely by the CLI and should be # removed when the CLI gets smarter. return self.get_token() def authenticate(self): # NOTE(jamielennox): This is used purely by the CLI and should be # removed when the CLI gets smarter. self.get_token() def get_auth_info(self): auth_info = {'auth_token': self.auth_token, 'endpoint_url': self.endpoint_url} # NOTE(jamielennox): This is the best we can do here. It will work # with identity plugins which is the primary case but we should # deprecate it's usage as much as possible. try: get_access = (self.auth or self.session.auth).get_access except AttributeError: pass else: auth_ref = get_access(self.session) auth_info['auth_tenant_id'] = auth_ref.project_id auth_info['auth_user_id'] = auth_ref.user_id return auth_info def get_auth_ref(self): return self.session.auth.get_auth_ref(self.session) # FIXME(bklei): Should refactor this to use kwargs and only # explicitly list arguments that are not None. @debtcollector.renames.renamed_kwarg('tenant_id', 'project_id', replace=True) @debtcollector.renames.renamed_kwarg( 'tenant_name', 'project_name', replace=True) def construct_http_client(username=None, user_id=None, project_name=None, project_id=None, password=None, auth_url=None, token=None, region_name=None, timeout=None, endpoint_url=None, insecure=False, endpoint_type='public', log_credentials=None, auth_strategy='keystone', ca_cert=None, service_type='network', session=None, global_request_id=None, **kwargs): if session: kwargs.setdefault('user_agent', USER_AGENT) kwargs.setdefault('interface', endpoint_type) return SessionClient(session=session, service_type=service_type, region_name=region_name, global_request_id=global_request_id, **kwargs) else: # FIXME(bklei): username and password are now optional. Need # to test that they were provided in this mode. Should also # refactor to use kwargs. return HTTPClient(username=username, password=password, project_id=project_id, project_name=project_name, user_id=user_id, auth_url=auth_url, token=token, endpoint_url=endpoint_url, insecure=insecure, timeout=timeout, region_name=region_name, endpoint_type=endpoint_type, service_type=service_type, ca_cert=ca_cert, log_credentials=log_credentials, auth_strategy=auth_strategy, global_request_id=global_request_id) python-neutronclient-6.7.0/neutronclient/cliff_sphinxext.py0000666000175100017510000003230113232473350024423 0ustar zuulzuul00000000000000# Copyright (C) 2017, Red Hat, Inc. # # 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 argparse import fnmatch import re from docutils import nodes from docutils.parsers import rst from docutils.parsers.rst import directives from docutils import statemachine from oslo_utils import importutils from cliff import commandmanager def _indent(text): """Indent by four spaces.""" prefix = ' ' * 4 def prefixed_lines(): for line in text.splitlines(True): yield (prefix + line if line.strip() else line) return ''.join(prefixed_lines()) def _format_description(parser): """Get parser description. We parse this as reStructuredText, allowing users to embed rich information in their help messages if they so choose. """ for line in statemachine.string2lines( parser.description, tab_width=4, convert_whitespace=True): yield line def _format_usage(parser): """Get usage without a prefix.""" fmt = argparse.HelpFormatter(parser.prog) optionals = parser._get_optional_actions() positionals = parser._get_positional_actions() groups = parser._mutually_exclusive_groups # hacked variant of the regex used by the actual argparse module. Unlike # that version, this one attempts to group long and short opts with their # optional arguments ensuring that, for example, '---format ' # becomes ['--format '] and not ['--format', '']. # Yes, they really do use regexes to break apart and rewrap their help # string. Don't ask me why. part_regexp = r'\(.*?\)+|\[.*?\]+|(?:(?:-\w|--\w+)(?:\s+<\w+>)?)|\S+' opt_usage = fmt._format_actions_usage(optionals, groups) pos_usage = fmt._format_actions_usage(positionals, groups) opt_parts = re.findall(part_regexp, opt_usage) pos_parts = re.findall(part_regexp, pos_usage) parts = opt_parts + pos_parts if len(' '.join([parser.prog] + parts)) < 72: return [' '.join([parser.prog] + parts)] return [parser.prog] + [_indent(x) for x in parts] def _format_epilog(parser): """Get parser epilog. We parse this as reStructuredText, allowing users to embed rich information in their help messages if they so choose. """ for line in statemachine.string2lines( parser.epilog, tab_width=4, convert_whitespace=True): yield line def _format_positional_action(action): """Format a positional action.""" if action.help == argparse.SUPPRESS: return # NOTE(stephenfin): We strip all types of brackets from 'metavar' because # the 'option' directive dictates that only option argument names should be # surrounded by angle brackets yield '.. option:: {}'.format( (action.metavar or action.dest).strip('<>[]() ')) if action.help: yield '' for line in statemachine.string2lines( action.help, tab_width=4, convert_whitespace=True): yield _indent(line) def _format_optional_action(action): """Format an optional action.""" if action.help == argparse.SUPPRESS: return if action.nargs == 0: yield '.. option:: {}'.format(', '.join(action.option_strings)) else: # TODO(stephenfin): At some point, we may wish to provide more # information about the options themselves, for example, if nargs is # specified option_strings = [' '.join( [x, action.metavar or '<{}>'.format(action.dest.upper())]) for x in action.option_strings] yield '.. option:: {}'.format(', '.join(option_strings)) if action.help: yield '' for line in statemachine.string2lines( action.help, tab_width=4, convert_whitespace=True): yield _indent(line) def _format_parser(parser): """Format the output of an argparse 'ArgumentParser' object. Given the following parser:: >>> import argparse >>> parser = argparse.ArgumentParser(prog='hello-world', \ description='This is my description.', epilog='This is my epilog') >>> parser.add_argument('name', help='User name', metavar='') >>> parser.add_argument('--language', action='store', dest='lang', \ help='Greeting language') Returns the following:: This is my description. .. program:: hello-world .. code:: shell hello-world [-h] [--language LANG] .. option:: name User name .. option:: --language LANG Greeting language .. option:: -h, --help Show this help message and exit This is my epilog. """ if parser.description: for line in _format_description(parser): yield line yield '' yield '.. program:: {}'.format(parser.prog) yield '.. code-block:: shell' yield '' for line in _format_usage(parser): yield _indent(line) yield '' # In argparse, all arguments and parameters are known as "actions". # Optional actions are what would be known as flags or options in other # libraries, while positional actions would generally be known as # arguments. We present these slightly differently. for action in parser._get_optional_actions(): for line in _format_optional_action(action): yield line yield '' for action in parser._get_positional_actions(): for line in _format_positional_action(action): yield line yield '' if parser.epilog: for line in _format_epilog(parser): yield line yield '' class AutoprogramCliffDirective(rst.Directive): """Auto-document a subclass of `cliff.command.Command`.""" has_content = False required_arguments = 1 option_spec = { 'command': directives.unchanged, 'ignored': directives.unchanged, 'application': directives.unchanged, } def _load_command(self, manager, command_name): """Load a command using an instance of a `CommandManager`.""" try: # find_command expects the value of argv so split to emulate that return manager.find_command(command_name.split())[0] except ValueError: raise self.error('"{}" is not a valid command in the "{}" ' 'namespace'.format( command_name, manager.namespace)) def _generate_nodes(self, title, command_name, command_class, ignored_opts): """Generate the relevant Sphinx nodes. This is a little funky. Parts of this use raw docutils nodes while other parts use reStructuredText and nested parsing. The reason for this is simple: it avoids us having to reinvent the wheel. While raw docutils nodes are helpful for the simpler elements of the output, they don't provide an easy way to use Sphinx's own directives, such as the 'option' directive. Refer to [1] for more information. [1] http://www.sphinx-doc.org/en/stable/extdev/markupapi.html :param title: Title of command :param command_name: Name of command, as used on the command line :param command_class: Subclass of :py:class:`cliff.command.Command` :param prefix: Prefix to apply before command, if any :param ignored_opts: A list of options to exclude from output, if any :returns: A list of nested docutil nodes """ command = command_class(None, None) parser = command.get_parser(command_name) ignored_opts = ignored_opts or [] # Drop the automatically-added help action for action in list(parser._actions): for option_string in action.option_strings: if option_string in ignored_opts: del parser._actions[parser._actions.index(action)] break section = nodes.section( '', nodes.title(text=title), ids=[nodes.make_id(title)], names=[nodes.fully_normalize_name(title)]) source_name = '<{}>'.format(command.__class__.__name__) result = statemachine.ViewList() for line in _format_parser(parser): result.append(line, source_name) self.state.nested_parse(result, 0, section) return [section] def run(self): self.env = self.state.document.settings.env command_pattern = self.options.get('command') application_name = (self.options.get('application') or self.env.config.autoprogram_cliff_application) global_ignored = self.env.config.autoprogram_cliff_ignored local_ignored = self.options.get('ignored', '') local_ignored = [x.strip() for x in local_ignored.split(',') if x.strip()] ignored_opts = list(set(global_ignored + local_ignored)) # TODO(sfinucan): We should probably add this wildcarding functionality # to the CommandManager itself to allow things like "show me the # commands like 'foo *'" manager = commandmanager.CommandManager(self.arguments[0]) if command_pattern: commands = [x for x in manager.commands if fnmatch.fnmatch(x, command_pattern)] else: commands = manager.commands.keys() output = [] for command_name in sorted(commands): command_class = self._load_command(manager, command_name) title = command_name if application_name: command_name = ' '.join([application_name, command_name]) output.extend(self._generate_nodes( title, command_name, command_class, ignored_opts)) return output class CliffAppDirective(rst.Directive): """Auto-document a `cliff.app.App`.""" has_content = False required_arguments = 1 option_spec = { 'arguments': directives.unchanged, 'ignored': directives.unchanged, 'application': directives.unchanged, } def _generate_nodes(self, title, app, app_name, ignored_opts): """Generate the relevant Sphinx nodes. This is a little funky. Parts of this use raw docutils nodes while other parts use reStructuredText and nested parsing. The reason for this is simple: it avoids us having to reinvent the wheel. While raw docutils nodes are helpful for the simpler elements of the output, they don't provide an easy way to use Sphinx's own directives, such as the 'option' directive. Refer to [1] for more information. [1] http://www.sphinx-doc.org/en/stable/extdev/markupapi.html :param title: Title of command :param app: Subclass of :py:class`cliff.app.App` :param app_name: The name of the cliff application. This is used as the command name. :param ignored_opts: A list of options to exclude from output, if any :returns: A list of docutil nodes """ parser = app.parser ignored_opts = ignored_opts or [] # Drop the automatically-added help action for action in list(parser._actions): for option_string in action.option_strings: if option_string in ignored_opts: del parser._actions[parser._actions.index(action)] break parser.prog = app_name source_name = '<{}>'.format(app.__class__.__name__) result = statemachine.ViewList() for line in _format_parser(parser): result.append(line, source_name) section = nodes.section() self.state.nested_parse(result, 0, section) return section.children def run(self): self.env = self.state.document.settings.env cliff_app_class = importutils.import_class(self.arguments[0]) app_arguments = self.options.get('arguments', '').split() cliff_app = cliff_app_class(*app_arguments) application_name = (self.options.get('application') or self.env.config.autoprogram_cliff_application) global_ignored = self.env.config.autoprogram_cliff_ignored local_ignored = self.options.get('ignored', '') local_ignored = [x.strip() for x in local_ignored.split(',') if x.strip()] ignored_opts = list(set(global_ignored + local_ignored)) output = [] title = application_name output.extend(self._generate_nodes( title, cliff_app, application_name, ignored_opts)) return output def setup(app): app.add_directive('autoprogram-cliff', AutoprogramCliffDirective) app.add_config_value('autoprogram_cliff_application', '', True) app.add_config_value('autoprogram_cliff_ignored', ['--help'], True) app.add_directive('cliff-app', CliffAppDirective) python-neutronclient-6.7.0/neutronclient/_i18n.py0000666000175100017510000000177713232473350022161 0ustar zuulzuul00000000000000# 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 oslo_i18n DOMAIN = 'neutronclient' _translators = oslo_i18n.TranslatorFactory(domain=DOMAIN) # The translation function using the well-known name "_" _ = _translators.primary # The contextual translation function using the name "_C" _C = _translators.contextual_form # The plural translation function using the name "_P" _P = _translators.plural_form def get_available_languages(): return oslo_i18n.get_available_languages(DOMAIN) python-neutronclient-6.7.0/neutronclient/shell.py0000666000175100017510000005745313232473350022354 0ustar zuulzuul00000000000000# 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 # # 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 Neutron APIs """ from __future__ import print_function import argparse import inspect import itertools import logging import os import sys from keystoneauth1 import session import os_client_config from oslo_utils import encodeutils from oslo_utils import netutils from cliff import app from cliff import command from cliff import commandmanager from neutronclient._i18n import _ from neutronclient.common import clientmanager from neutronclient.common import exceptions as exc from neutronclient.common import extension as client_extension from neutronclient.neutron.v2_0 import subnet from neutronclient.version import __version__ VERSION = '2.0' NEUTRON_API_VERSION = '2.0' NAMESPACE_MAP = {NEUTRON_API_VERSION: 'neutron.cli.v2'} 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) if(isinstance(cmd, subnet.CreateSubnet) and not known_args.cidr): cidr = get_first_valid_cidr(_values_specs) if cidr: known_args.cidr = cidr _values_specs.remove(cidr) cmd.values_specs = (index == -1 and _values_specs or values_specs) return cmd.run(known_args) def get_first_valid_cidr(value_specs): # Bug 1442771, argparse does not allow optional positional parameter # to be separated from previous positional parameter. # When cidr was separated from network, the value will not be able # to be parsed into known_args, but saved to _values_specs instead. for value in value_specs: if netutils.is_valid_cidr(value): return value 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 COMMANDS = {} # NOTE(amotoki): This is only to provide compatibility # to existing neutron CLI extensions. See bug 1706573 for detail. def _set_commands_dict_for_compat(apiversion, command_manager): global COMMANDS COMMANDS = {apiversion: dict((cmd, command_manager.find_command([cmd])[0]) for cmd in command_manager.commands)} class BashCompletionCommand(command.Command): """Prints all of the commands and options for bash-completion.""" def take_action(self, parsed_args): pass class HelpAction(argparse.Action): """Print help message including sub-commands 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.stdout.write(_('\nCommands for 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 NeutronShell(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): namespace = NAMESPACE_MAP[apiversion] description = (__doc__.strip() + " (neutron CLI version: %s)" % __version__) super(NeutronShell, self).__init__( description=description, version=VERSION, command_manager=commandmanager.CommandManager(namespace), ) self._register_extensions(VERSION) # Pop the 'complete' to correct the outputs of 'neutron help'. self.command_manager.commands.pop('complete') # This is instantiated in initialize_app() only when using # password flow auth self.auth_client = None self.api_version = apiversion _set_commands_dict_for_compat(apiversion, self.command_manager) 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 keystoneauth1 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 keystoneauth1. We will need to # refactor this code once this functionality is available in # keystoneauth1. # # 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='', 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='', default=env('OS_ENDPOINT_TYPE', default='public'), help=_('Defaults to env[OS_ENDPOINT_TYPE] or public.')) # FIXME(bklei): --service-type is deprecated but kept in for # backward compatibility. parser.add_argument( '--service-type', metavar='', 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='', default=env('OS_ENDPOINT_TYPE', default='public'), help=_('DEPRECATED! Use --os-endpoint-type.')) parser.add_argument( '--os-auth-strategy', metavar='', 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-cloud', metavar='', help=_('Defaults to env[OS_CLOUD].')) parser.add_argument( '--os-auth-url', metavar='', 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='', help=_('Authentication tenant name, defaults to ' 'env[OS_TENANT_NAME].')) project_name_group.add_argument( '--os-project-name', metavar='', 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='', help=_('Authentication tenant ID, defaults to ' 'env[OS_TENANT_ID].')) project_id_group.add_argument( '--os-project-id', metavar='', 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='', help=_('Authentication username, defaults to env[OS_USERNAME].')) parser.add_argument( '--os_username', help=argparse.SUPPRESS) parser.add_argument( '--os-user-id', metavar='', 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='', 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='', 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='', help=_('Defaults to env[OS_PROJECT_DOMAIN_ID].')) parser.add_argument( '--os-project-domain-name', metavar='', help=_('Defaults to env[OS_PROJECT_DOMAIN_NAME].')) parser.add_argument( '--os-cert', metavar='', 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='', 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='', 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='', help=_('Authentication password, defaults to env[OS_PASSWORD].')) parser.add_argument( '--os_password', help=argparse.SUPPRESS) parser.add_argument( '--os-region-name', metavar='', 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='', help=_('Authentication token, defaults to env[OS_TOKEN].')) parser.add_argument( '--os_token', help=argparse.SUPPRESS) parser.add_argument( '--http-timeout', metavar='', 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='', 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 _name, _command in self.command_manager: commands.add(_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 _register_extensions(self, version): for name, module in itertools.chain( client_extension._discover_via_entry_points()): self._extend_shell_commands(name, module, version) def _extend_shell_commands(self, name, module, version): classes = inspect.getmembers(module, inspect.isclass) for cls_name, cls in classes: if (issubclass(cls, client_extension.NeutronClientExtension) and hasattr(cls, 'shell_command')): cmd = cls.shell_command if hasattr(cls, 'versions'): if version not in cls.versions: continue try: name_prefix = "[%s]" % name cls.__doc__ = ("%s %s" % (name_prefix, cls.__doc__) if cls.__doc__ else name_prefix) self.command_manager.add_command(cmd, cls) except TypeError: pass 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' and help_command_pos == -1: self._bash_completion() return 0 if arg in ('-h', '--help'): if help_pos == -1: help_pos = index # self.command_manager.commands contains 'help', # so we need to check this first. elif arg == 'help': if help_command_pos == -1: help_command_pos = index elif arg in self.command_manager.commands: if command_pos == -1: 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(err) raise else: self.log.error(err) return 1 if self.interactive_mode: _argv = [sys.argv[0]] sys.argv = _argv return self.interact() return self.run_subcommand(remainder) 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) 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 SystemExit: print(_("Try 'neutron help %s' for more information.") % cmd_name, file=sys.stderr) raise except Exception as e: if self.options.verbose_level >= self.DEBUG_LEVEL: self.log.exception("%s", e) raise self.log.error("%s", e) return 1 def authenticate_user(self): """Confirm user authentication Make sure the user has provided all of the authentication info we need. """ cloud_config = os_client_config.OpenStackConfig().get_one_cloud( cloud=self.options.os_cloud, argparse=self.options, network_api_version=self.api_version, verify=not self.options.insecure) verify, cert = cloud_config.get_requests_verify_args() # TODO(singhj): Remove dependancy on HTTPClient # for the case of token-endpoint authentication # When using token-endpoint authentication legacy # HTTPClient will be used, otherwise SessionClient # will be used. if self.options.os_token and self.options.os_url: auth = None auth_session = None else: auth = cloud_config.get_auth() auth_session = session.Session( auth=auth, verify=verify, cert=cert, timeout=self.options.http_timeout) interface = self.options.os_endpoint_type or self.endpoint_type if interface.endswith('URL'): interface = interface[:-3] self.client_manager = clientmanager.ClientManager( retries=self.options.retries, raise_errors=False, session=auth_session, url=self.options.os_url, token=self.options.os_token, region_name=cloud_config.get_region_name(), api_version=cloud_config.get_api_version('network'), service_type=cloud_config.get_service_type('network'), service_name=cloud_config.get_service_name('network'), endpoint_type=interface, auth=auth, insecure=not verify, log_credentials=True) return def initialize_app(self, argv): """Global app init bits: * set up API versions * validate authentication info """ super(NeutronShell, 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 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) # The default log level is INFO, in this situation, set the # log level of the console to WARNING, to avoid displaying # useless messages. This equals using "--quiet" if console_level == logging.INFO: console.setLevel(logging.WARNING) else: 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('iso8601.iso8601').setLevel(logging.WARNING) logging.getLogger('urllib3.connectionpool').setLevel(logging.WARNING) console.setFormatter(formatter) root_logger.addHandler(console) return def main(argv=sys.argv[1:]): try: print(_("neutron CLI is deprecated and will be removed " "in the future. Use openstack CLI instead."), file=sys.stderr) return NeutronShell(NEUTRON_API_VERSION).run( list(map(encodeutils.safe_decode, argv))) except KeyboardInterrupt: print(_("... terminating neutron client"), file=sys.stderr) return 130 except exc.NeutronClientException: return 1 except Exception as e: print(e) return 1 if __name__ == "__main__": sys.exit(main(sys.argv[1:])) python-neutronclient-6.7.0/neutronclient/tests/0000775000175100017510000000000013232473710022015 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/functional/0000775000175100017510000000000013232473710024157 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/functional/hooks/0000775000175100017510000000000013232473710025302 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/functional/hooks/gate_hook.sh0000777000175100017510000000207313232473350027605 0ustar zuulzuul00000000000000#!/usr/bin/env bash set -ex VENV=${1:-"functional"} GATE_DEST=$BASE/new NEUTRONCLIENT_PATH=$GATE_DEST/python-neutronclient GATE_HOOKS=$NEUTRONCLIENT_PATH/neutronclient/tests/functional/hooks DEVSTACK_PATH=$GATE_DEST/devstack LOCAL_CONF=$DEVSTACK_PATH/late-local.conf DSCONF=/tmp/devstack-tools/bin/dsconf # Install devstack-tools used to produce local.conf; we can't rely on # test-requirements.txt because the gate hook is triggered before neutronclient # is installed sudo -H pip install virtualenv virtualenv /tmp/devstack-tools /tmp/devstack-tools/bin/pip install -U devstack-tools==0.4.0 # Inject config from hook into localrc function load_rc_hook { local hook="$1" local tmpfile local config tmpfile=$(tempfile) config=$(cat $GATE_HOOKS/$hook) echo "[[local|localrc]]" > $tmpfile $DSCONF setlc_raw $tmpfile "$config" $DSCONF merge_lc $LOCAL_CONF $tmpfile rm -f $tmpfile } if [ "$VENV" == "functional-adv-svcs" ] then load_rc_hook fwaas fi export DEVSTACK_LOCALCONF=$(cat $LOCAL_CONF) $BASE/new/devstack-gate/devstack-vm-gate.sh python-neutronclient-6.7.0/neutronclient/tests/functional/hooks/fwaas0000666000175100017510000000014313232473350026326 0ustar zuulzuul00000000000000enable_plugin neutron-fwaas git://git.openstack.org/openstack/neutron-fwaas enable_service q-fwaas python-neutronclient-6.7.0/neutronclient/tests/functional/hooks/vpnaas0000666000175100017510000000011613232473350026515 0ustar zuulzuul00000000000000enable_plugin neutron-vpnaas git://git.openstack.org/openstack/neutron-vpnaas python-neutronclient-6.7.0/neutronclient/tests/functional/hooks/post_test_hook.sh0000777000175100017510000000421713232473350030713 0ustar zuulzuul00000000000000#!/bin/bash -xe # 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. # This script is executed inside post_test_hook function in devstack gate. SCRIPTS_DIR="/usr/os-testr-env/bin/" function generate_test_logs { local path="$1" # Compress all $path/*.txt files and move the directories holding those # files to /opt/stack/logs. Files with .log suffix have their # suffix changed to .txt (so browsers will know to open the compressed # files and not download them). if [ -d "$path" ] then sudo find $path -iname "*.log" -type f -exec mv {} {}.txt \; -exec gzip -9 {}.txt \; sudo mv $path/* /opt/stack/logs/ fi } function generate_testr_results { # Give job user rights to access tox logs sudo -H -u $USER chmod o+rw . sudo -H -u $USER chmod o+rw -R .testrepository if [ -f ".testrepository/0" ] ; then .tox/$VENV/bin/subunit-1to2 < .testrepository/0 > ./testrepository.subunit $SCRIPTS_DIR/subunit2html ./testrepository.subunit testr_results.html gzip -9 ./testrepository.subunit gzip -9 ./testr_results.html sudo mv ./*.gz /opt/stack/logs/ fi if [ "$venv" == "functional" ] || [ "$venv" == "functional-adv-svcs" ] then generate_test_logs "/tmp/${venv}-logs" fi } export NEUTRONCLIENT_DIR="$BASE/new/python-neutronclient" sudo chown -R $USER:stack $NEUTRONCLIENT_DIR # Go to the neutronclient dir cd $NEUTRONCLIENT_DIR # Run tests VENV=${1:-"functional"} echo "Running neutronclient functional test suite" set +e # Preserve env for OS_ credentials sudo -E -H -u $USER tox -e $VENV EXIT_CODE=$? set -e # Collect and parse result generate_testr_results exit $EXIT_CODE python-neutronclient-6.7.0/neutronclient/tests/functional/adv-svcs/0000775000175100017510000000000013232473710025705 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/functional/adv-svcs/test_readonly_neutron_vpn.py0000666000175100017510000000512113232473350033571 0ustar zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from neutronclient.tests.functional import base class SimpleReadOnlyNeutronVpnClientTest(base.ClientTestBase): """Tests for vpn based client commands that are read only This is a first pass at a simple read only python-neutronclient test. This only exercises vpn based client commands that are read only. This should test commands: * as a regular user * as a admin user * with and without optional parameters * initially just check return codes, and later test command outputs """ def setUp(self): super(SimpleReadOnlyNeutronVpnClientTest, self).setUp() if not self.is_extension_enabled('vpnaas'): self.skipTest('VPNaaS is not enabled') def test_neutron_vpn_ikepolicy_list(self): ikepolicy = self.parser.listing(self.neutron('vpn-ikepolicy-list')) self.assertTableStruct(ikepolicy, ['id', 'name', 'auth_algorithm', 'encryption_algorithm', 'ike_version', 'pfs']) def test_neutron_vpn_ipsecpolicy_list(self): ipsecpolicy = self.parser.listing(self.neutron('vpn-ipsecpolicy-list')) self.assertTableStruct(ipsecpolicy, ['id', 'name', 'auth_algorithm', 'encryption_algorithm', 'pfs']) def test_neutron_vpn_service_list(self): vpn_list = self.parser.listing(self.neutron('vpn-service-list')) self.assertTableStruct(vpn_list, ['id', 'name', 'router_id', 'status']) def test_neutron_ipsec_site_connection_list(self): ipsec_site = self.parser.listing(self.neutron ('ipsec-site-connection-list')) self.assertTableStruct(ipsec_site, ['id', 'name', 'peer_address', 'auth_mode', 'status']) python-neutronclient-6.7.0/neutronclient/tests/functional/adv-svcs/__init__.py0000666000175100017510000000000013232473350030006 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/functional/adv-svcs/test_readonly_neutron_fwaas.py0000666000175100017510000000360513232473350034074 0ustar zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from neutronclient.tests.functional import base class SimpleReadOnlyNeutronFwv1ClientTest(base.ClientTestBase): """Tests for FWaaS v1 based client commands that are read only""" def setUp(self): super(SimpleReadOnlyNeutronFwv1ClientTest, self).setUp() if not self.is_extension_enabled('fwaas'): self.skipTest('FWaaS is not enabled') def test_neutron_firewall_list(self): firewall_list = self.parser.listing(self.neutron ('firewall-list')) self.assertTableStruct(firewall_list, ['id', 'name', 'firewall_policy_id']) def test_neutron_firewall_policy_list(self): firewall_policy = self.parser.listing(self.neutron ('firewall-policy-list')) self.assertTableStruct(firewall_policy, ['id', 'name', 'firewall_rules']) def test_neutron_firewall_rule_list(self): firewall_rule = self.parser.listing(self.neutron ('firewall-rule-list')) self.assertTableStruct(firewall_rule, ['id', 'name', 'firewall_policy_id', 'summary', 'enabled']) python-neutronclient-6.7.0/neutronclient/tests/functional/core/0000775000175100017510000000000013232473710025107 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/functional/core/test_purge.py0000666000175100017510000001776713232473350027666 0ustar zuulzuul00000000000000# Copyright 2016 Cisco Systems # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from neutronclient.tests.functional import base from tempest.lib import exceptions class PurgeNeutronClientCLITest(base.ClientTestBase): def _safe_cleanup(self, delete_command): try: self.neutron(delete_command) except exceptions.CommandFailed: # This resource was already purged successfully pass def _create_subnet(self, name, tenant_id, cidr): params = ('%(name)s --name %(name)s --tenant-id %(tenant)s ' '%(cidr)s' % {'name': name, 'tenant': tenant_id, 'cidr': cidr}) subnet = self.parser.listing(self.neutron('subnet-create', params=params)) for row in subnet: if row['Field'] == 'id': return row['Value'] def _create_router(self, name, tenant_id): params = ('%(name)s --tenant_id %(tenant)s' % {'name': name, 'tenant': tenant_id}) router = self.parser.listing(self.neutron('router-create', params=params)) for row in router: if row['Field'] == 'id': return row['Value'] def _create_floatingip(self, network, tenant_id): params = ('%(network)s --tenant-id %(tenant)s' % {'network': network, 'tenant': tenant_id}) floatingip = self.parser.listing(self.neutron('floatingip-create', params=params)) for row in floatingip: if row['Field'] == 'id': return row['Value'] def _create_resources(self, name, tenant_id, shared_tenant_id=None): # If no shared_tenant_id is provided, create the resources for the # current tenant to test that they will be deleted when not in use. if not shared_tenant_id: shared_tenant_id = tenant_id self.neutron('net-create', params=('%(name)s --router:external True ' '--tenant-id %(tenant)s' % {'name': name, 'tenant': tenant_id})) self.addCleanup(self._safe_cleanup, 'net-delete %s' % name) self.neutron('net-create', params=('%(name)s-shared --shared ' '--tenant-id %(tenant)s' % {'name': name, 'tenant': shared_tenant_id})) self.addCleanup(self._safe_cleanup, 'net-delete %s-shared' % name) subnet = self._create_subnet(name, tenant_id, '192.168.71.0/24') self.addCleanup(self._safe_cleanup, 'subnet-delete %s' % name) subnet = self._create_subnet('%s-shared' % name, tenant_id, '192.168.81.0/24') self.addCleanup(self._safe_cleanup, 'subnet-delete %s-shared' % name) router = self._create_router(name, tenant_id) self.addCleanup(self._safe_cleanup, 'router-delete %s' % name) self.neutron('router-interface-add', params=('%(router)s %(subnet)s ' '--tenant-id %(tenant)s' % {'router': router, 'subnet': subnet, 'tenant': tenant_id})) self.neutron('port-create', params=('%(name)s --name %(name)s ' '--tenant-id %(tenant)s' % {'name': name, 'tenant': tenant_id})) self.addCleanup(self._safe_cleanup, 'port-delete %s' % name) self.neutron('port-create', params=('%(name)s-shared --name %(name)s-shared ' '--tenant-id %(tenant)s' % {'name': name, 'tenant': tenant_id})) self.addCleanup(self._safe_cleanup, 'port-delete %s-shared' % name) self.neutron('security-group-create', params=('%(name)s --tenant-id %(tenant)s' % {'name': name, 'tenant': tenant_id})) self.addCleanup(self._safe_cleanup, 'security-group-delete %s' % name) floatingip = self._create_floatingip(name, tenant_id) self.addCleanup(self._safe_cleanup, ('floatingip-delete ' '%s' % floatingip)) return floatingip def _verify_deletion(self, resources, resource_type): purged = True no_purge_purged = True router_interface_owners = ['network:router_interface', 'network:router_interface_distributed'] for row in resources: if resource_type == 'port' and row.get('id', None): port = self.parser.listing(self.neutron('port-show', params=row['id'])) port_dict = {} for row in port: port_dict[row['Field']] = row['Value'] if port_dict['device_owner'] in router_interface_owners: if port_dict['tenant_id'] == 'purge-tenant': purged = False elif port_dict['tenant_id'] == 'no-purge-tenant': no_purge_purged = False if not purged or not no_purge_purged: self.addCleanup(self.neutron, ('router-interface-delete %(router)s ' 'port=%(port)s' % {'router': port_dict['device_id'], 'port': port_dict['id']})) if (row.get('name') == 'purge-me' or row.get('id') == self.purge_floatingip): purged = False elif ('no-purge' in row.get('name', '') or row.get('id') == self.no_purge_floatingip): no_purge_purged = False if not purged: self.fail('%s not deleted by neutron purge' % resource_type) if no_purge_purged: self.fail('%s owned by another tenant incorrectly deleted ' 'by neutron purge' % resource_type) def test_purge(self): self.purge_floatingip = self._create_resources('purge-me', 'purge-tenant') self.no_purge_floatingip = self._create_resources('no-purge', 'no-purge-tenant', 'purge-tenant') purge_output = self.neutron('purge', params='purge-tenant').strip() if not purge_output: self.fail('Purge command did not return feedback') networks = self.parser.listing(self.neutron('net-list')) subnets = self.parser.listing(self.neutron('subnet-list')) routers = self.parser.listing(self.neutron('router-list')) ports = self.parser.listing(self.neutron('port-list')) floatingips = self.parser.listing(self.neutron('floatingip-list')) self._verify_deletion(networks, 'network') self._verify_deletion(subnets, 'subnet') self._verify_deletion(ports, 'port') self._verify_deletion(routers, 'router') self._verify_deletion(floatingips, 'floatingip') python-neutronclient-6.7.0/neutronclient/tests/functional/core/test_common.py0000666000175100017510000000256213232473350030017 0ustar zuulzuul00000000000000# Copyright 2016 NEC Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from neutronclient.tests.functional import base class CLICommonFeatureTest(base.ClientTestBase): def test_tenant_id_shown_in_list_by_admin(self): nets = self.parser.table(self.neutron('net-list')) self.assertIn('tenant_id', nets['headers']) def test_tenant_id_not_shown_in_list_with_columns(self): nets = self.parser.table(self.neutron('net-list -c id -c name')) self.assertNotIn('tenant_id', nets['headers']) self.assertListEqual(['id', 'name'], nets['headers']) def test_tenant_id_not_shown_in_list_by_non_admin(self): output = self.neutron_non_admin('net-list') self.assertNotIn('tenant_id', self.parser.table(output)['headers']) self.assertTableStruct(self.parser.listing(output), ['id', 'name']) python-neutronclient-6.7.0/neutronclient/tests/functional/core/test_readonly_neutron.py0000666000175100017510000001205213232473350032111 0ustar zuulzuul00000000000000# 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 re from tempest.lib import exceptions from neutronclient.tests.functional import base class SimpleReadOnlyNeutronClientTest(base.ClientTestBase): """This is a first pass at a simple read only python-neutronclient test. This only exercises client commands that are read only. This should test commands: * as a regular user * as a admin user * with and without optional parameters * initially just check return codes, and later test command outputs """ def test_admin_fake_action(self): self.assertRaises(exceptions.CommandFailed, self.neutron, 'this-does-neutron-exist') # NOTE(mestery): Commands in order listed in 'neutron help' # Optional arguments: def test_neutron_fake_action(self): self.assertRaises(exceptions.CommandFailed, self.neutron, 'this-does-not-exist') def test_neutron_net_list(self): net_list = self.parser.listing(self.neutron('net-list')) self.assertTableStruct(net_list, ['id', 'name', 'subnets']) def test_neutron_ext_list(self): ext = self.parser.listing(self.neutron('ext-list')) self.assertTableStruct(ext, ['alias', 'name']) def test_neutron_dhcp_agent_list_hosting_net(self): self.neutron('dhcp-agent-list-hosting-net', params='private') def test_neutron_agent_list(self): agents = self.parser.listing(self.neutron('agent-list')) field_names = ['id', 'agent_type', 'host', 'alive', 'admin_state_up'] self.assertTableStruct(agents, field_names) def test_neutron_floatingip_list(self): self.neutron('floatingip-list') def test_neutron_meter_label_list(self): self.neutron('meter-label-list') def test_neutron_meter_label_rule_list(self): self.neutron('meter-label-rule-list') def test_neutron_net_external_list(self): net_ext_list = self.parser.listing(self.neutron('net-external-list')) self.assertTableStruct(net_ext_list, ['id', 'name', 'subnets']) def test_neutron_port_list(self): port_list = self.parser.listing(self.neutron('port-list')) self.assertTableStruct(port_list, ['id', 'name', 'mac_address', 'fixed_ips']) def test_neutron_quota_list(self): self.neutron('quota-list') def test_neutron_router_list(self): router_list = self.parser.listing(self.neutron('router-list')) self.assertTableStruct(router_list, ['id', 'name', 'external_gateway_info']) def test_neutron_security_group_list(self): security_grp = self.parser.listing(self.neutron('security-group-list')) self.assertTableStruct(security_grp, ['id', 'name', 'security_group_rules']) def test_neutron_security_group_rule_list(self): security_grp = self.parser.listing(self.neutron ('security-group-rule-list')) self.assertTableStruct(security_grp, ['id', 'security_group', 'direction', 'ethertype', 'port/protocol', 'remote']) def test_neutron_subnet_list(self): subnet_list = self.parser.listing(self.neutron('subnet-list')) self.assertTableStruct(subnet_list, ['id', 'name', 'cidr', 'allocation_pools']) def test_neutron_help(self): help_text = self.neutron('help') lines = help_text.split('\n') self.assertFirstLineStartsWith(lines, 'usage: neutron') commands = [] cmds_start = lines.index('Commands for API v2.0:') command_pattern = re.compile('^ {2}([a-z0-9\-\_]+)') for line in lines[cmds_start:]: match = command_pattern.match(line) if match: commands.append(match.group(1)) commands = set(commands) wanted_commands = set(('net-create', 'subnet-list', 'port-delete', 'router-show', 'agent-update', 'help')) self.assertFalse(wanted_commands - commands) # Optional arguments: def test_neutron_version(self): self.neutron('', flags='--version') def test_neutron_debug_net_list(self): self.neutron('net-list', flags='--debug') def test_neutron_quiet_net_list(self): self.neutron('net-list', flags='--quiet') python-neutronclient-6.7.0/neutronclient/tests/functional/core/test_cli_formatter.py0000666000175100017510000000462313232473350031361 0ustar zuulzuul00000000000000# Copyright 2016 NEC Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo_serialization import jsonutils from oslo_utils import uuidutils import yaml from neutronclient.tests.functional import base class TestCLIFormatter(base.ClientTestBase): def setUp(self): super(TestCLIFormatter, self).setUp() self.net_name = 'net-%s' % uuidutils.generate_uuid() self.addCleanup(self.neutron, 'net-delete %s' % self.net_name) def _create_net(self, fmt, col_attrs): params = ['-c %s' % attr for attr in col_attrs] params.append('-f %s' % fmt) params.append(self.net_name) param_string = ' '.join(params) return self.neutron('net-create', params=param_string) def test_net_create_with_json_formatter(self): result = self._create_net('json', ['name', 'admin_state_up']) self.assertDictEqual({'name': self.net_name, 'admin_state_up': True}, jsonutils.loads(result)) def test_net_create_with_yaml_formatter(self): result = self._create_net('yaml', ['name', 'admin_state_up']) self.assertDictEqual({'name': self.net_name, 'admin_state_up': True}, yaml.load(result)) def test_net_create_with_value_formatter(self): # NOTE(amotoki): In 'value' formatter, there is no guarantee # in the order of attribute, so we use one attribute in this test. result = self._create_net('value', ['name']) self.assertEqual(self.net_name, result.strip()) def test_net_create_with_shell_formatter(self): result = self._create_net('shell', ['name', 'admin_state_up']) result_lines = set(result.strip().split('\n')) self.assertSetEqual(set(['name="%s"' % self.net_name, 'admin_state_up="True"']), result_lines) python-neutronclient-6.7.0/neutronclient/tests/functional/core/__init__.py0000666000175100017510000000000013232473350027210 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/functional/core/test_clientlib.py0000666000175100017510000000447613232473350030502 0ustar zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from keystoneauth1 import session from oslo_utils import uuidutils from tempest.lib import base import testtools from neutronclient.common import exceptions from neutronclient.tests.functional import base as func_base from neutronclient.v2_0 import client as v2_client class LibraryTestCase(base.BaseTestCase): def setUp(self): super(LibraryTestCase, self).setUp() self.client = self._get_client() def _get_client(self): cloud_config = func_base.get_cloud_config() keystone_auth = cloud_config.get_auth() (verify, cert) = cloud_config.get_requests_verify_args() ks_session = session.Session( auth=keystone_auth, verify=verify, cert=cert) return v2_client.Client(session=ks_session) def test_list_network(self): nets = self.client.list_networks() self.assertIsInstance(nets['networks'], list) def test_post_put_delete_network(self): name = uuidutils.generate_uuid() net = self.client.create_network({'network': {'name': name}}) net_id = net['network']['id'] self.assertEqual(name, net['network']['name']) name2 = uuidutils.generate_uuid() net = self.client.update_network(net_id, {'network': {'name': name2}}) self.assertEqual(name2, net['network']['name']) self.client.delete_network(net_id) with testtools.ExpectedException(exceptions.NetworkNotFoundClient): self.client.show_network(net_id) def test_get_auth_ref(self): # Call some API call to ensure the client is authenticated. self.client.list_networks() auth_ref = self.client.httpclient.get_auth_ref() self.assertIsNotNone(auth_ref) self.assertIsNotNone(auth_ref.role_names) python-neutronclient-6.7.0/neutronclient/tests/functional/core/test_subnet_create.py0000666000175100017510000000277513232473350031360 0ustar zuulzuul00000000000000# Copyright 2015 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. from neutronclient.tests.functional import base class SubnetCreateNeutronClientCLITest(base.ClientTestBase): def test_create_subnet_net_name_first(self): self.neutron('net-create', params='netwrk-1') self.addCleanup(self.neutron, 'net-delete netwrk-1') self.neutron('subnet-create netwrk-1', params='--name fake --gateway 192.168.51.1 ' '192.168.51.0/24') self.addCleanup(self.neutron, 'subnet-delete fake') subnet_list = self.parser.listing(self.neutron('subnet-list')) self.assertTableStruct(subnet_list, ['id', 'name', 'cidr', 'allocation_pools']) found = False for row in subnet_list: if row.get('name') == 'fake': found = True break if not found: self.fail('Created subnet not found in list') python-neutronclient-6.7.0/neutronclient/tests/functional/__init__.py0000666000175100017510000000000013232473350026260 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/functional/base.py0000666000175100017510000000577613232473350025464 0ustar zuulzuul00000000000000# 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 os import os_client_config from tempest.lib.cli import base def credentials(cloud='devstack-admin'): """Retrieves credentials to run functional tests Credentials are either read via os-client-config from the environment or from a config file ('clouds.yaml'). Environment variables override those from the config file. devstack produces a clouds.yaml with two named clouds - one named 'devstack' which has user privs and one named 'devstack-admin' which has admin privs. This function will default to getting the devstack-admin cloud as that is the current expected behavior. """ return get_cloud_config(cloud=cloud).get_auth_args() def get_cloud_config(cloud='devstack-admin'): return os_client_config.OpenStackConfig().get_one_cloud(cloud=cloud) class ClientTestBase(base.ClientTestBase): """This is a first pass at a simple read only python-neutronclient test. This only exercises client commands that are read only. This should test commands: * as a regular user * as an admin user * with and without optional parameters * initially just check return codes, and later test command outputs """ def _get_clients_from_os_cloud_config(self, cloud='devstack-admin'): creds = credentials(cloud) cli_dir = os.environ.get( 'OS_NEUTRONCLIENT_EXEC_DIR', os.path.join(os.path.abspath('.'), '.tox/functional/bin')) return base.CLIClient( username=creds['username'], password=creds['password'], tenant_name=creds['project_name'], project_domain_id=creds['project_domain_id'], user_domain_id=creds['user_domain_id'], uri=creds['auth_url'], cli_dir=cli_dir) def _get_clients(self): return self._get_clients_from_os_cloud_config() def neutron(self, *args, **kwargs): return self.clients.neutron(*args, **kwargs) def neutron_non_admin(self, *args, **kwargs): if not hasattr(self, '_non_admin_clients'): self._non_admin_clients = self._get_clients_from_os_cloud_config( cloud='devstack') return self._non_admin_clients.neutron(*args, **kwargs) def is_extension_enabled(self, extension_alias): extensions = self.parser.listing(self.neutron('ext-list')) for extension in extensions: if extension_alias in extension['alias']: return True return False python-neutronclient-6.7.0/neutronclient/tests/unit/0000775000175100017510000000000013232473710022774 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_servicetype.py0000666000175100017510000000420213232473350027740 0ustar zuulzuul00000000000000# Copyright 2013 Mirantis Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0 import servicetype from neutronclient.tests.unit import test_cli20 class CLITestV20ServiceProvidersJSON(test_cli20.CLITestV20Base): id_field = "name" def setUp(self): super(CLITestV20ServiceProvidersJSON, self).setUp( plurals={'tags': 'tag'} ) def test_list_service_providers(self): resources = "service_providers" cmd = servicetype.ListServiceProvider(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_service_providers_pagination(self): resources = "service_providers" cmd = servicetype.ListServiceProvider(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_service_providers_sort(self): resources = "service_providers" cmd = servicetype.ListServiceProvider(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name"], sort_dir=["asc", "desc"]) def test_list_service_providers_limit(self): resources = "service_providers" cmd = servicetype.ListServiceProvider(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) python-neutronclient-6.7.0/neutronclient/tests/unit/qos/0000775000175100017510000000000013232473710023576 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/qos/test_cli20_rule.py0000666000175100017510000000323713232473350027156 0ustar zuulzuul00000000000000# Copyright 2015 Huawei Technologies India Pvt Ltd. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.qos import rule as qos_rule from neutronclient.tests.unit import test_cli20 class CLITestV20QoSRuleJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['bandwidth_limit_rule', 'dscp_marking_rule', 'minimum_bandwidth_rule'] def setUp(self): super(CLITestV20QoSRuleJSON, self).setUp() def test_list_qos_rule_types(self): # qos_rule_types. resources = 'rule_types' cmd_resources = 'qos_rule_types' response_contents = [{'type': 'bandwidth_limit', 'type': 'dscp_marking', 'type': 'minimum_bandwidth'}] cmd = qos_rule.ListQoSRuleTypes(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True, response_contents=response_contents, cmd_resources=cmd_resources) python-neutronclient-6.7.0/neutronclient/tests/unit/qos/test_cli20_minimum_bandwidth_rule.py0000666000175100017510000001353113232473350032733 0ustar zuulzuul00000000000000# Copyright (c) 2016 Intel Corporation. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.qos import minimum_bandwidth_rule as bw_rule from neutronclient.tests.unit import test_cli20 class CLITestV20QoSMinimumBandwidthRuleJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['minimum_bandwidth_rule'] def setUp(self): super(CLITestV20QoSMinimumBandwidthRuleJSON, self).setUp() self.res = 'minimum_bandwidth_rule' self.cmd_res = 'qos_minimum_bandwidth_rule' self.ress = self.res + 's' self.cmd_ress = self.cmd_res + 's' def test_create_minimum_bandwidth_rule_min_kbps_only(self): cmd = bw_rule.CreateQoSMinimumBandwidthRule( test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' min_kbps = '1500' policy_id = 'policy_id' args = ['--min-kbps', min_kbps, policy_id] position_names = ['min_kbps'] position_values = [min_kbps] self.assertRaises(SystemExit, self._test_create_resource, self.res, cmd, '', my_id, args, position_names, position_values, cmd_resource=self.cmd_res, parent_id=policy_id, no_api_call=True) def test_create_minimum_bandwidth_rule_direction_only(self): cmd = bw_rule.CreateQoSMinimumBandwidthRule( test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' direction = 'egress' policy_id = 'policy_id' args = ['--direction', direction, policy_id] position_names = ['direction'] position_values = [direction] self.assertRaises(SystemExit, self._test_create_resource, self.res, cmd, '', my_id, args, position_names, position_values, cmd_resource=self.cmd_res, parent_id=policy_id, no_api_call=True) def test_create_minimum_bandwidth_rule_none(self): cmd = bw_rule.CreateQoSMinimumBandwidthRule( test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' policy_id = 'policy_id' args = [policy_id] position_names = [] position_values = [] self.assertRaises(SystemExit, self._test_create_resource, self.res, cmd, '', my_id, args, position_names, position_values, cmd_resource=self.cmd_res, parent_id=policy_id, no_api_call=True) def test_create_minimum_bandwidth_rule_all(self): cmd = bw_rule.CreateQoSMinimumBandwidthRule( test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' min_kbps = '1500' direction = 'egress' policy_id = 'policy_id' args = ['--min-kbps', min_kbps, '--direction', direction, policy_id] position_names = ['direction', 'min_kbps'] position_values = [direction, min_kbps] self._test_create_resource(self.res, cmd, '', my_id, args, position_names, position_values, cmd_resource=self.cmd_res, parent_id=policy_id) def test_update_minimum_bandwidth_rule(self): cmd = bw_rule.UpdateQoSMinimumBandwidthRule( test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' min_kbps = '1200' direction = 'egress' policy_id = 'policy_id' args = ['--min-kbps', min_kbps, '--direction', direction, my_id, policy_id] self._test_update_resource(self.res, cmd, my_id, args, {'min_kbps': min_kbps, 'direction': direction}, cmd_resource=self.cmd_res, parent_id=policy_id) def test_delete_minimum_bandwidth_rule(self): cmd = bw_rule.DeleteQoSMinimumBandwidthRule( test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' policy_id = 'policy_id' args = [my_id, policy_id] self._test_delete_resource(self.res, cmd, my_id, args, cmd_resource=self.cmd_res, parent_id=policy_id) def test_show_minimum_bandwidth_rule(self): cmd = bw_rule.ShowQoSMinimumBandwidthRule( test_cli20.MyApp(sys.stdout), None) policy_id = 'policy_id' args = [self.test_id, policy_id] self._test_show_resource(self.res, cmd, self.test_id, args, [], cmd_resource=self.cmd_res, parent_id=policy_id) def test_list_minimum_bandwidth_rule(self): cmd = bw_rule.ListQoSMinimumBandwidthRules( test_cli20.MyApp(sys.stdout), None) policy_id = 'policy_id' args = [policy_id] contents = [{'name': 'rule1', 'min-kbps': 1000, 'direction': 'egress'}] self._test_list_resources(self.ress, cmd, parent_id=policy_id, cmd_resources=self.cmd_ress, base_args=args, response_contents=contents) python-neutronclient-6.7.0/neutronclient/tests/unit/qos/test_cli20_policy.py0000666000175100017510000002024313232473350027502 0ustar zuulzuul00000000000000# Copyright 2015 Huawei Technologies India Pvt Ltd. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.qos import policy as policy from neutronclient.tests.unit import test_cli20 class CLITestV20QoSPolicyJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['policy'] def setUp(self): super(CLITestV20QoSPolicyJSON, self).setUp() self.res = 'policy' self.cmd_res = 'qos_policy' self.ress = "policies" self.cmd_ress = 'qos_policies' def test_create_policy_with_only_keyattributes(self): # Create qos policy abc. cmd = policy.CreateQoSPolicy(test_cli20.MyApp(sys.stdout), None) myid = 'myid' name = 'abc' args = [name] position_names = ['name'] position_values = [name] self._test_create_resource(self.res, cmd, name, myid, args, position_names, position_values, cmd_resource=self.cmd_res) def test_create_policy_with_description(self): # Create qos policy xyz --description abc. cmd = policy.CreateQoSPolicy(test_cli20.MyApp(sys.stdout), None) myid = 'myid' name = 'abc' description = 'policy_abc' args = [name, '--description', description] position_names = ['name', 'description'] position_values = [name, description] self._test_create_resource(self.res, cmd, name, myid, args, position_names, position_values, cmd_resource=self.cmd_res) def test_create_policy_with_shared(self): # Create qos policy abc shared across tenants cmd = policy.CreateQoSPolicy(test_cli20.MyApp(sys.stdout), None) myid = 'myid' name = 'abc' description = 'policy_abc' args = [name, '--description', description, '--shared'] position_names = ['name', 'description', 'shared'] position_values = [name, description, True] self._test_create_resource(self.res, cmd, name, myid, args, position_names, position_values, cmd_resource=self.cmd_res) def test_create_policy_with_unicode(self): # Create qos policy u'\u7f51\u7edc'. cmd = policy.CreateQoSPolicy(test_cli20.MyApp(sys.stdout), None) myid = 'myid' name = u'\u7f51\u7edc' description = u'\u7f51\u7edc' args = [name, '--description', description] position_names = ['name', 'description'] position_values = [name, description] self._test_create_resource(self.res, cmd, name, myid, args, position_names, position_values, cmd_resource=self.cmd_res) def test_update_policy(self): # policy-update myid --name newname. cmd = policy.UpdateQoSPolicy(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(self.res, cmd, 'myid', ['myid', '--name', 'newname'], {'name': 'newname', }, cmd_resource=self.cmd_res) def test_update_policy_description(self): # policy-update myid --name newname --description newdesc cmd = policy.UpdateQoSPolicy(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(self.res, cmd, 'myid', ['myid', '--description', 'newdesc'], {'description': 'newdesc', }, cmd_resource=self.cmd_res) def test_update_policy_to_shared(self): # policy-update myid --shared cmd = policy.UpdateQoSPolicy(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(self.res, cmd, 'myid', ['myid', '--shared'], {'shared': True, }, cmd_resource=self.cmd_res) def test_update_policy_to_no_shared(self): # policy-update myid --no-shared cmd = policy.UpdateQoSPolicy(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(self.res, cmd, 'myid', ['myid', '--no-shared'], {'shared': False, }, cmd_resource=self.cmd_res) def test_update_policy_to_shared_no_shared_together(self): # policy-update myid --shared --no-shared cmd = policy.UpdateQoSPolicy(test_cli20.MyApp(sys.stdout), None) self.assertRaises( SystemExit, self._test_update_resource, self.res, cmd, 'myid', ['myid', '--shared', '--no-shared'], {}, cmd_resource=self.cmd_res ) def test_list_policies(self): # qos-policy-list. cmd = policy.ListQoSPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(self.ress, cmd, True, cmd_resources=self.cmd_ress) def test_list_policies_pagination(self): # qos-policy-list for pagination. cmd = policy.ListQoSPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(self.ress, cmd, cmd_resources=self.cmd_ress) def test_list_policies_sort(self): # sorted list: qos-policy-list --sort-key name --sort-key id # --sort-key asc --sort-key desc cmd = policy.ListQoSPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(self.ress, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"], cmd_resources=self.cmd_ress) def test_list_policies_limit(self): # size (1000) limited list: qos-policy-list -P. cmd = policy.ListQoSPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(self.ress, cmd, page_size=1000, cmd_resources=self.cmd_ress) def test_show_policy_id(self): # qos-policy-show test_id. cmd = policy.ShowQoSPolicy(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', self.test_id] self._test_show_resource(self.res, cmd, self.test_id, args, ['id'], cmd_resource=self.cmd_res) def test_show_policy_name(self): # qos-policy-show. cmd = policy.ShowQoSPolicy(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', '--fields', 'name', self.test_id] self._test_show_resource(self.res, cmd, self.test_id, args, ['id', 'name'], cmd_resource=self.cmd_res) def test_delete_policy(self): # qos-policy-delete my-id. cmd = policy.DeleteQoSPolicy(test_cli20.MyApp(sys.stdout), None) my_id = 'myid1' args = [my_id] self._test_delete_resource(self.res, cmd, my_id, args, cmd_resource=self.cmd_res) python-neutronclient-6.7.0/neutronclient/tests/unit/qos/test_cli20_bandwidth_limit_rule.py0000666000175100017510000001407513232473350032402 0ustar zuulzuul00000000000000# Copyright 2015 Huawei Technologies India Pvt Ltd. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.qos import bandwidth_limit_rule as bw_rule from neutronclient.tests.unit import test_cli20 class CLITestV20QoSBandwidthLimitRuleJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['bandwidth_limit_rule'] def setUp(self): super(CLITestV20QoSBandwidthLimitRuleJSON, self).setUp() self.res = 'bandwidth_limit_rule' self.cmd_res = 'qos_bandwidth_limit_rule' self.ress = self.res + 's' self.cmd_ress = self.cmd_res + 's' def test_create_bandwidth_limit_rule_with_max_kbps(self): cmd = bw_rule.CreateQoSBandwidthLimitRule(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' max_kbps = '1337' policy_id = 'policy_id' args = ['--max-kbps', max_kbps, policy_id] position_names = ['max_kbps'] position_values = [max_kbps] self._test_create_resource(self.res, cmd, '', my_id, args, position_names, position_values, cmd_resource=self.cmd_res, parent_id=policy_id) def test_create_bandwidth_limit_rule_with_max_burst_kbps(self): cmd = bw_rule.CreateQoSBandwidthLimitRule(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' max_burst_kbps = '1337' policy_id = 'policy_id' args = ['--max-burst-kbps', max_burst_kbps, policy_id] position_names = ['max_burst_kbps'] position_values = [max_burst_kbps] self._test_create_resource(self.res, cmd, '', my_id, args, position_names, position_values, cmd_resource=self.cmd_res, parent_id=policy_id) def test_create_bandwidth_limit_rule_with_all_params(self): cmd = bw_rule.CreateQoSBandwidthLimitRule(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' max_kbps = '1337' max_burst_kbps = '1337' policy_id = 'policy_id' args = ['--max-kbps', max_kbps, '--max-burst-kbps', max_burst_kbps, policy_id] position_names = ['max_kbps', 'max_burst_kbps'] position_values = [max_kbps, max_burst_kbps] self._test_create_resource(self.res, cmd, '', my_id, args, position_names, position_values, cmd_resource=self.cmd_res, parent_id=policy_id) def test_update_bandwidth_limit_rule_with_max_kbps(self): cmd = bw_rule.UpdateQoSBandwidthLimitRule(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' max_kbps = '1337' policy_id = 'policy_id' args = ['--max-kbps', max_kbps, my_id, policy_id] self._test_update_resource(self.res, cmd, my_id, args, {'max_kbps': max_kbps, }, cmd_resource=self.cmd_res, parent_id=policy_id) def test_update_bandwidth_limit_rule_with_max_burst_kbps(self): cmd = bw_rule.UpdateQoSBandwidthLimitRule(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' max_burst_kbps = '1337' policy_id = 'policy_id' args = ['--max-burst-kbps', max_burst_kbps, my_id, policy_id] self._test_update_resource(self.res, cmd, my_id, args, {'max_burst_kbps': max_burst_kbps}, cmd_resource=self.cmd_res, parent_id=policy_id) def test_update_bandwidth_limit_rule_with_all_params(self): cmd = bw_rule.UpdateQoSBandwidthLimitRule(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' max_kbps = '1337' max_burst_kbps = '1337' policy_id = 'policy_id' args = ['--max-kbps', max_kbps, '--max-burst-kbps', max_burst_kbps, my_id, policy_id] self._test_update_resource(self.res, cmd, my_id, args, {'max_kbps': max_kbps, 'max_burst_kbps': max_burst_kbps}, cmd_resource=self.cmd_res, parent_id=policy_id) def test_delete_bandwidth_limit_rule(self): cmd = bw_rule.DeleteQoSBandwidthLimitRule(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' policy_id = 'policy_id' args = [my_id, policy_id] self._test_delete_resource(self.res, cmd, my_id, args, cmd_resource=self.cmd_res, parent_id=policy_id) def test_show_bandwidth_limit_rule(self): cmd = bw_rule.ShowQoSBandwidthLimitRule(test_cli20.MyApp(sys.stdout), None) policy_id = 'policy_id' args = ['--fields', 'id', self.test_id, policy_id] self._test_show_resource(self.res, cmd, self.test_id, args, ['id'], cmd_resource=self.cmd_res, parent_id=policy_id) python-neutronclient-6.7.0/neutronclient/tests/unit/qos/test_cli20_dscp_marking_rule.py0000666000175100017510000000766513232473350031710 0ustar zuulzuul00000000000000# Copyright 2016 Comcast Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.common import exceptions from neutronclient.neutron.v2_0.qos import dscp_marking_rule as dscp_rule from neutronclient.tests.unit import test_cli20 class CLITestV20QoSDscpMarkingRuleJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['dscp_marking_rule'] def setUp(self): super(CLITestV20QoSDscpMarkingRuleJSON, self).setUp() self.dscp_res = 'dscp_marking_rule' self.dscp_cmd_res = 'qos_dscp_marking_rule' self.dscp_ress = self.dscp_res + 's' self.dscp_cmd_ress = self.dscp_cmd_res + 's' def test_create_dscp_marking_rule_with_dscp_mark(self): cmd = dscp_rule.CreateQoSDscpMarkingRule(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' policy_id = 'policy_id' position_names = ['dscp_mark'] valid_dscp_marks = ['0', '56'] invalid_dscp_marks = ['-1', '19', '42', '44', '57', '58'] for dscp_mark in valid_dscp_marks: args = ['--dscp-mark', dscp_mark, policy_id] position_values = [dscp_mark] self._test_create_resource(self.dscp_res, cmd, '', my_id, args, position_names, position_values, cmd_resource=self.dscp_cmd_res, parent_id=policy_id) for dscp_mark in invalid_dscp_marks: args = ['--dscp-mark', dscp_mark, policy_id] position_values = [dscp_mark] self._test_create_resource( self.dscp_res, cmd, '', my_id, args, position_names, position_values, cmd_resource=self.dscp_cmd_res, parent_id=policy_id, no_api_call=True, expected_exception=exceptions.CommandError) def test_update_dscp_marking_rule_with_dscp_mark(self): cmd = dscp_rule.UpdateQoSDscpMarkingRule(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' dscp_mark = '56' policy_id = 'policy_id' args = ['--dscp-mark', dscp_mark, my_id, policy_id] self._test_update_resource(self.dscp_res, cmd, my_id, args, {'dscp_mark': dscp_mark}, cmd_resource=self.dscp_cmd_res, parent_id=policy_id) def test_delete_dscp_marking_rule(self): cmd = dscp_rule.DeleteQoSDscpMarkingRule(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' policy_id = 'policy_id' args = [my_id, policy_id] self._test_delete_resource(self.dscp_res, cmd, my_id, args, cmd_resource=self.dscp_cmd_res, parent_id=policy_id) def test_show_dscp_marking_rule(self): cmd = dscp_rule.ShowQoSDscpMarkingRule(test_cli20.MyApp(sys.stdout), None) policy_id = 'policy_id' args = ['--fields', 'id', self.test_id, policy_id] self._test_show_resource(self.dscp_res, cmd, self.test_id, args, ['id'], cmd_resource=self.dscp_cmd_res, parent_id=policy_id) python-neutronclient-6.7.0/neutronclient/tests/unit/qos/__init__.py0000666000175100017510000000000013232473350025677 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_address_scope.py0000666000175100017510000001701313232473350030220 0ustar zuulzuul00000000000000# Copyright 2015 Huawei Technologies India Pvt. Ltd. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from mox3 import mox from neutronclient.common import exceptions from neutronclient.neutron.v2_0 import address_scope from neutronclient.tests.unit import test_cli20 class CLITestV20AddressScopeJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['address_scope'] def setUp(self): super(CLITestV20AddressScopeJSON, self).setUp(plurals={'tags': 'tag'}) def test_create_address_scope_with_minimum_option_ipv4(self): """Create address_scope: foo-address-scope with minimum option.""" resource = 'address_scope' cmd = address_scope.CreateAddressScope( test_cli20.MyApp(sys.stdout), None) name = 'foo-address-scope' myid = 'myid' args = [name, '4'] position_names = ['name', 'ip_version'] position_values = [name, 4] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_address_scope_with_minimum_option_ipv6(self): """Create address_scope: foo-address-scope with minimum option.""" resource = 'address_scope' cmd = address_scope.CreateAddressScope( test_cli20.MyApp(sys.stdout), None) name = 'foo-address-scope' myid = 'myid' args = [name, '6'] position_names = ['name', 'ip_version'] position_values = [name, 6] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_address_scope_with_minimum_option_bad_ip_version(self): """Create address_scope: foo-address-scope with minimum option.""" resource = 'address_scope' cmd = address_scope.CreateAddressScope( test_cli20.MyApp(sys.stdout), None) name = 'foo-address-scope' myid = 'myid' args = [name, '5'] position_names = ['name', 'ip_version'] position_values = [name, 5] self.assertRaises(SystemExit, self._test_create_resource, resource, cmd, name, myid, args, position_names, position_values) def test_create_address_scope_with_all_option(self): # Create address_scope: foo-address-scope with all options. resource = 'address_scope' cmd = address_scope.CreateAddressScope( test_cli20.MyApp(sys.stdout), None) name = 'foo-address-scope' myid = 'myid' args = [name, '4', '--shared'] position_names = ['name', 'ip_version', 'shared'] position_values = [name, 4, True] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_address_scope_with_unicode(self): # Create address_scope: u'\u7f51\u7edc'. resource = 'address_scope' cmd = address_scope.CreateAddressScope( test_cli20.MyApp(sys.stdout), None) name = u'\u7f51\u7edc' ip_version = u'4' myid = 'myid' args = [name, ip_version] position_names = ['name', 'ip_version'] position_values = [name, 4] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_update_address_scope_exception(self): # Update address_scope (Negative) : myid. resource = 'address_scope' cmd = address_scope.UpdateAddressScope( test_cli20.MyApp(sys.stdout), None) self.assertRaises(exceptions.CommandError, self._test_update_resource, resource, cmd, 'myid', ['myid'], {}) def test_update_address_scope(self): # Update address_scope: myid --name newname-address-scope. resource = 'address_scope' cmd = address_scope.UpdateAddressScope( test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'newname-address-scope'], {'name': 'newname-address-scope'} ) # Update address_scope: myid --shared self._test_update_resource(resource, cmd, 'myid', ['myid', '--shared', 'True'], {'shared': "True"} ) def test_list_address_scope(self): # address_scope-list. resources = "address_scopes" cmd = address_scope.ListAddressScope(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_address_scope_pagination(self): # address_scope-list. cmd = address_scope.ListAddressScope(test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(address_scope.ListAddressScope, "extend_list") address_scope.ListAddressScope.extend_list(mox.IsA(list), mox.IgnoreArg()) self._test_list_resources_with_pagination("address_scopes", cmd) self.mox.VerifyAll() self.mox.UnsetStubs() def test_list_address_scope_sort(self): # sorted list: # address_scope-list --sort-key name --sort-key id --sort-key asc # --sort-key desc resources = "address_scopes" cmd = address_scope.ListAddressScope(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id", "ip_version"], sort_dir=["asc", "desc"]) def test_list_address_scope_limit(self): # size (1000) limited list: address_scope-list -P. resources = "address_scopes" cmd = address_scope.ListAddressScope(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_address_scope(self): # Show address_scope: --fields id --fields name myid. resource = 'address_scope' cmd = address_scope.ShowAddressScope( test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', '--fields', 'name', self.test_id, '--fields', 'ip_version', '6'] self._test_show_resource(resource, cmd, self.test_id, args, ['id', 'name', 'ip_version']) def test_delete_address_scope(self): # Delete address_scope: address_scope_id. resource = 'address_scope' cmd = address_scope.DeleteAddressScope( test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) python-neutronclient-6.7.0/neutronclient/tests/unit/test_exceptions.py0000666000175100017510000000346113232473350026574 0ustar zuulzuul00000000000000# All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import fixtures from oslo_utils import encodeutils import six import testtools from neutronclient._i18n import _ from neutronclient.common import exceptions class TestExceptions(testtools.TestCase): def test_exception_print_with_unicode(self): class TestException(exceptions.NeutronException): message = _('Exception with %(reason)s') multibyte_unicode_string = u'\uff21\uff22\uff23' e = TestException(reason=multibyte_unicode_string) fixture = fixtures.StringStream('stdout') self.useFixture(fixture) with fixtures.MonkeyPatch('sys.stdout', fixture.stream): print(e) self.assertEqual('Exception with %s' % multibyte_unicode_string, fixture.getDetails().get('stdout').as_text()) def test_exception_message_with_encoded_unicode(self): class TestException(exceptions.NeutronException): message = _('Exception with %(reason)s') multibyte_string = u'\uff21\uff22\uff23' multibyte_binary = encodeutils.safe_encode(multibyte_string) e = TestException(reason=multibyte_binary) self.assertEqual('Exception with %s' % multibyte_string, six.text_type(e)) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_port.py0000666000175100017510000010235313232473350026370 0ustar zuulzuul00000000000000# 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 # # 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 itertools import sys from mox3 import mox from neutronclient.neutron.v2_0 import port from neutronclient import shell from neutronclient.tests.unit import test_cli20 class CLITestV20PortJSON(test_cli20.CLITestV20Base): def setUp(self): super(CLITestV20PortJSON, self).setUp(plurals={'tags': 'tag'}) def test_create_port(self): # Create port: netid. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = [netid, '--description', 'DESC'] position_names = ['network_id'] position_values = [] position_values.extend([netid]) self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, description='DESC') def test_create_port_extra_dhcp_opts_args(self): # Create port: netid --extra_dhcp_opt. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' extra_dhcp_opts = [{'opt_name': 'bootfile-name', 'opt_value': 'pxelinux.0'}, {'opt_name': 'tftp-server', 'opt_value': '123.123.123.123'}, {'opt_name': 'server-ip-address', 'opt_value': '123.123.123.45'}] args = [netid] for dhcp_opt in extra_dhcp_opts: args += ['--extra-dhcp-opt', ('opt_name=%(opt_name)s,opt_value=%(opt_value)s' % dhcp_opt)] position_names = ['network_id', 'extra_dhcp_opts'] position_values = [netid, extra_dhcp_opts] position_values.extend([netid]) self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_extra_dhcp_opts_args_ip_version(self): # Create port: netid --extra_dhcp_opt. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' extra_dhcp_opts = [{'opt_name': 'bootfile-name', 'opt_value': 'pxelinux.0', 'ip_version': "4"}, {'opt_name': 'tftp-server', 'opt_value': '2001:192:168::1', 'ip_version': "6"}, {'opt_name': 'server-ip-address', 'opt_value': '123.123.123.45', 'ip_version': "4"}] args = [netid] for dhcp_opt in extra_dhcp_opts: args += ['--extra-dhcp-opt', ('opt_name=%(opt_name)s,opt_value=%(opt_value)s,' 'ip_version=%(ip_version)s' % dhcp_opt)] position_names = ['network_id', 'extra_dhcp_opts'] position_values = [netid, extra_dhcp_opts] position_values.extend([netid]) self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_full(self): # Create port: --mac_address mac --device_id deviceid netid. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = ['--mac_address', 'mac', '--device_id', 'deviceid', netid] position_names = ['network_id', 'mac_address', 'device_id'] position_values = [netid, 'mac', 'deviceid'] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) # Test dashed options args = ['--mac-address', 'mac', '--device-id', 'deviceid', netid] position_names = ['network_id', 'mac_address', 'device_id'] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_vnic_type_normal(self): # Create port: --vnic_type normal netid. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = ['--vnic_type', 'normal', netid] position_names = ['binding:vnic_type', 'network_id'] position_values = ['normal', netid] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) # Test dashed options args = ['--vnic-type', 'normal', netid] position_names = ['binding:vnic_type', 'network_id'] position_values = ['normal', netid] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_vnic_type_direct(self): # Create port: --vnic_type direct netid. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = ['--vnic_type', 'direct', netid] position_names = ['binding:vnic_type', 'network_id'] position_values = ['direct', netid] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) # Test dashed options args = ['--vnic-type', 'direct', netid] position_names = ['binding:vnic_type', 'network_id'] position_values = ['direct', netid] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_vnic_type_direct_physical(self): # Create port: --vnic_type direct-physical netid. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = ['--vnic_type', 'direct-physical', netid] position_names = ['binding:vnic_type', 'network_id'] position_values = ['direct-physical', netid] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) # Test dashed options args = ['--vnic-type', 'direct-physical', netid] position_names = ['binding:vnic_type', 'network_id'] position_values = ['direct-physical', netid] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_vnic_type_macvtap(self): # Create port: --vnic_type macvtap netid. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = ['--vnic_type', 'macvtap', netid] position_names = ['binding:vnic_type', 'network_id'] position_values = ['macvtap', netid] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) # Test dashed options args = ['--vnic-type', 'macvtap', netid] position_names = ['binding:vnic_type', 'network_id'] position_values = ['macvtap', netid] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_vnic_type_baremetal(self): # Create port: --vnic_type baremetal netid. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = ['--vnic_type', 'baremetal', netid] position_names = ['binding:vnic_type', 'network_id'] position_values = ['baremetal', netid] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) # Test dashed options args = ['--vnic-type', 'baremetal', netid] position_names = ['binding:vnic_type', 'network_id'] position_values = ['baremetal', netid] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_with_binding_profile(self): resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = ['--binding_profile', '{"foo":"bar"}', netid] position_names = ['binding:profile', 'network_id'] position_values = [{'foo': 'bar'}, netid] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) # Test dashed options args = ['--binding-profile', '{"foo":"bar"}', netid] position_names = ['binding:profile', 'network_id'] position_values = [{'foo': 'bar'}, netid] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_tenant(self): # Create port: --tenant_id tenantid netid. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = ['--tenant_id', 'tenantid', netid, ] position_names = ['network_id'] position_values = [] position_values.extend([netid]) self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') # Test dashed options args = ['--tenant-id', 'tenantid', netid, ] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_port_tags(self): # Create port: netid mac_address device_id --tags a b. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = [netid, '--tags', 'a', 'b'] position_names = ['network_id'] position_values = [] position_values.extend([netid]) self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tags=['a', 'b']) def test_create_port_secgroup(self): # Create port: --security-group sg1_id netid. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = ['--security-group', 'sg1_id', netid] position_names = ['network_id', 'security_groups'] position_values = [netid, ['sg1_id']] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_secgroups(self): # Create port: netid # The are --security-group sg1_id # --security-group sg2_id resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = ['--security-group', 'sg1_id', '--security-group', 'sg2_id', netid] position_names = ['network_id', 'security_groups'] position_values = [netid, ['sg1_id', 'sg2_id']] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_secgroup_off(self): resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = ['--no-security-groups', netid] position_names = ['network_id', 'security_groups'] position_values = [netid, []] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_secgroups_list(self): # Create port: netid # The are --security-groups list=true sg_id1 sg_id2 resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = [netid, '--security-groups', 'list=true', 'sg_id1', 'sg_id2'] position_names = ['network_id', 'security_groups'] position_values = [netid, ['sg_id1', 'sg_id2']] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_with_qos_policy(self): # Create port: --qos-policy mypolicy. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' qos_policy_name = 'mypolicy' args = [netid, '--qos-policy', qos_policy_name] position_names = ['network_id', 'qos_policy_id'] position_values = [netid, qos_policy_name] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_with_dns_name(self): # Create port: --dns-name my-port. resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' dns_name_name = 'my-port' args = [netid, '--dns-name', dns_name_name] position_names = ['network_id', 'dns_name'] position_values = [netid, dns_name_name] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_with_allowed_address_pair_ipaddr(self): # Create port: # --allowed-address-pair ip_address=addr0 # --allowed-address-pair ip_address=addr1 resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' pairs = [{'ip_address': '123.123.123.123'}, {'ip_address': '123.123.123.45'}] args = [netid, '--allowed-address-pair', 'ip_address=123.123.123.123', '--allowed-address-pair', 'ip_address=123.123.123.45'] position_names = ['network_id', 'allowed_address_pairs'] position_values = [netid, pairs] position_values.extend([netid]) self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_port_with_allowed_address_pair(self): # Create port: # --allowed-address-pair ip_address=addr0,mac_address=mac0 # --allowed-address-pair ip_address=addr1,mac_address=mac1 resource = 'port' cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' pairs = [{'ip_address': '123.123.123.123', 'mac_address': '10:00:00:00:00:00'}, {'ip_address': '123.123.123.45', 'mac_address': '10:00:00:00:00:01'}] args = [netid, '--allowed-address-pair', 'ip_address=123.123.123.123,mac_address=10:00:00:00:00:00', '--allowed-address-pair', 'ip_address=123.123.123.45,mac_address=10:00:00:00:00:01'] position_names = ['network_id', 'allowed_address_pairs'] position_values = [netid, pairs] position_values.extend([netid]) self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_list_ports(self): # List ports: -D. resources = "ports" cmd = port.ListPort(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_ports_pagination(self): resources = "ports" cmd = port.ListPort(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_ports_sort(self): # list ports: # --sort-key name --sort-key id --sort-key asc --sort-key desc resources = "ports" cmd = port.ListPort(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_ports_limit(self): # list ports: -P. resources = "ports" cmd = port.ListPort(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_list_ports_tags(self): # List ports: -- --tags a b. resources = "ports" cmd = port.ListPort(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, tags=['a', 'b']) def test_list_ports_detail_tags(self): # List ports: -D -- --tags a b. resources = "ports" cmd = port.ListPort(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, detail=True, tags=['a', 'b']) def test_list_ports_fields(self): # List ports: --fields a --fields b -- --fields c d. resources = "ports" cmd = port.ListPort(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, fields_1=['a', 'b'], fields_2=['c', 'd']) def test_list_ports_with_fixed_ips_in_csv(self): # List ports: -f csv. resources = "ports" cmd = port.ListPort(test_cli20.MyApp(sys.stdout), None) fixed_ips = [{"subnet_id": "30422057-d6df-4c90-8314-aefb5e326666", "ip_address": "10.0.0.12"}, {"subnet_id": "30422057-d6df-4c90-8314-aefb5e326666", "ip_address": "10.0.0.4"}] contents = [{'name': 'name1', 'fixed_ips': fixed_ips}] self._test_list_resources(resources, cmd, True, response_contents=contents, output_format='csv') def _test_list_router_port(self, resources, cmd, myid, detail=False, tags=(), fields_1=(), fields_2=()): self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) reses = {resources: [{'id': 'myid1', }, {'id': 'myid2', }, ], } resstr = self.client.serialize(reses) # url method body query = "" args = detail and ['-D', ] or [] if fields_1: for field in fields_1: args.append('--fields') args.append(field) args.append(myid) if tags: args.append('--') args.append("--tag") for tag in tags: args.append(tag) if (not tags) and fields_2: args.append('--') if fields_2: args.append("--fields") for field in fields_2: args.append(field) for field in itertools.chain(fields_1, fields_2): if query: query += "&fields=" + field else: query = "fields=" + field for tag in tags: if query: query += "&tag=" + tag else: query = "tag=" + tag if detail: query = query and query + '&verbose=True' or 'verbose=True' query = query and query + '&device_id=%s' or 'device_id=%s' path = getattr(self.client, resources + "_path") self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, query % myid), self.client), 'GET', body=None, headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN) ).AndReturn((test_cli20.MyResp(200), resstr)) self.mox.ReplayAll() cmd_parser = cmd.get_parser("list_" + resources) shell.run_command(cmd, cmd_parser, args) self.mox.VerifyAll() self.mox.UnsetStubs() _str = self.fake_stdout.make_string() self.assertIn('myid1', _str) def test_list_router_ports(self): # List router ports: -D. resources = "ports" cmd = port.ListRouterPort(test_cli20.MyApp(sys.stdout), None) self._test_list_router_port(resources, cmd, self.test_id, True) def test_list_router_ports_tags(self): # List router ports: -- --tags a b. resources = "ports" cmd = port.ListRouterPort(test_cli20.MyApp(sys.stdout), None) self._test_list_router_port(resources, cmd, self.test_id, tags=['a', 'b']) def test_list_router_ports_detail_tags(self): # List router ports: -D -- --tags a b. resources = "ports" cmd = port.ListRouterPort(test_cli20.MyApp(sys.stdout), None) self._test_list_router_port(resources, cmd, self.test_id, detail=True, tags=['a', 'b']) def test_list_router_ports_fields(self): # List ports: --fields a --fields b -- --fields c d. resources = "ports" cmd = port.ListRouterPort(test_cli20.MyApp(sys.stdout), None) self._test_list_router_port(resources, cmd, self.test_id, fields_1=['a', 'b'], fields_2=['c', 'd']) def test_update_port(self): # Update port: myid --name myname --admin-state-up False --tags a b. resource = 'port' cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'myname', '--admin-state-up', 'False', '--description', 'garbage', '--tags', 'a', 'b'], {'name': 'myname', 'admin_state_up': 'False', 'description': 'garbage', 'tags': ['a', 'b'], }) def test_update_port_secgroup(self): resource = 'port' cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = ['--security-group', 'sg1_id', myid] updatefields = {'security_groups': ['sg1_id']} self._test_update_resource(resource, cmd, myid, args, updatefields) def test_update_port_secgroups(self): resource = 'port' cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = ['--security-group', 'sg1_id', '--security-group', 'sg2_id', myid] updatefields = {'security_groups': ['sg1_id', 'sg2_id']} self._test_update_resource(resource, cmd, myid, args, updatefields) def test_update_port_extra_dhcp_opts(self): # Update port: myid --extra_dhcp_opt. resource = 'port' myid = 'myid' args = [myid, '--extra-dhcp-opt', "opt_name=bootfile-name,opt_value=pxelinux.0", '--extra-dhcp-opt', "opt_name=tftp-server,opt_value=123.123.123.123", '--extra-dhcp-opt', "opt_name=server-ip-address,opt_value=123.123.123.45" ] updatedfields = {'extra_dhcp_opts': [{'opt_name': 'bootfile-name', 'opt_value': 'pxelinux.0'}, {'opt_name': 'tftp-server', 'opt_value': '123.123.123.123'}, {'opt_name': 'server-ip-address', 'opt_value': '123.123.123.45'}]} cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, myid, args, updatedfields) def test_update_port_fixed_ip(self): resource = 'port' cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) myid = 'myid' subnet_id = 'subnet_id' ip_addr = '123.123.123.123' args = [myid, '--fixed-ip', "subnet_id=%(subnet_id)s,ip_address=%(ip_addr)s" % {'subnet_id': subnet_id, 'ip_addr': ip_addr}] updated_fields = {"fixed_ips": [{'subnet_id': subnet_id, 'ip_address': ip_addr}]} self._test_update_resource(resource, cmd, myid, args, updated_fields) def test_update_port_device_id_device_owner(self): resource = 'port' cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = ['--device-id', 'dev_id', '--device-owner', 'fake', myid] updatefields = {'device_id': 'dev_id', 'device_owner': 'fake'} self._test_update_resource(resource, cmd, myid, args, updatefields) def test_update_port_extra_dhcp_opts_ip_version(self): # Update port: myid --extra_dhcp_opt. resource = 'port' myid = 'myid' args = [myid, '--extra-dhcp-opt', "opt_name=bootfile-name,opt_value=pxelinux.0,ip_version=4", '--extra-dhcp-opt', "opt_name=tftp-server,opt_value=2001:192:168::1,ip_version=6", '--extra-dhcp-opt', "opt_name=server-ip-address,opt_value=null,ip_version=4" ] updatedfields = {'extra_dhcp_opts': [{'opt_name': 'bootfile-name', 'opt_value': 'pxelinux.0', 'ip_version': '4'}, {'opt_name': 'tftp-server', 'opt_value': '2001:192:168::1', 'ip_version': '6'}, {'opt_name': 'server-ip-address', 'opt_value': None, 'ip_version': '4'}]} cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, myid, args, updatedfields) def test_update_port_with_qos_policy(self): # Update port: myid --qos-policy mypolicy. resource = 'port' cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--qos-policy', 'mypolicy'], {'qos_policy_id': 'mypolicy', }) def test_update_port_with_no_qos_policy(self): # Update port: myid --no-qos-policy. resource = 'port' cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--no-qos-policy'], {'qos_policy_id': None, }) def test_update_port_with_dns_name(self): # Update port: myid --dns-name my-port. resource = 'port' cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--dns-name', 'my-port'], {'dns_name': 'my-port', }) def test_update_port_with_no_dns_name(self): # Update port: myid --no-dns-name resource = 'port' cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--no-dns-name'], {'dns_name': "", }) def test_delete_extra_dhcp_opts_from_port(self): resource = 'port' myid = 'myid' args = [myid, '--extra-dhcp-opt', "opt_name=bootfile-name,opt_value=null", '--extra-dhcp-opt', "opt_name=tftp-server,opt_value=123.123.123.123", '--extra-dhcp-opt', "opt_name=server-ip-address,opt_value=123.123.123.45" ] # the client code will change the null to None and send to server, # where its interpreted as delete the DHCP option on the port. updatedfields = {'extra_dhcp_opts': [{'opt_name': 'bootfile-name', 'opt_value': None}, {'opt_name': 'tftp-server', 'opt_value': '123.123.123.123'}, {'opt_name': 'server-ip-address', 'opt_value': '123.123.123.45'}]} cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, myid, args, updatedfields) def test_update_port_security_group_off(self): # Update port: --no-security-groups myid. resource = 'port' cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['--no-security-groups', 'myid'], {'security_groups': []}) def test_update_port_allowed_address_pair_ipaddr(self): # Update port(ip_address only): # --allowed-address-pairs ip_address=addr0 # --allowed-address-pairs ip_address=addr1 import sys resource = 'port' cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) myid = 'myid' pairs = [{'ip_address': '123.123.123.123'}, {'ip_address': '123.123.123.45'}] args = [myid, '--allowed-address-pair', 'ip_address=123.123.123.123', '--allowed-address-pair', 'ip_address=123.123.123.45'] updatefields = {'allowed_address_pairs': pairs} self._test_update_resource(resource, cmd, myid, args, updatefields) def test_update_port_allowed_address_pair(self): # Update port: # --allowed-address-pair ip_address=addr0,mac_address=mac0 # --allowed-address-pair ip_address_addr1,mac_address=mac1 resource = 'port' cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) myid = 'myid' pairs = [{'ip_address': '123.123.123.123', 'mac_address': '10:00:00:00:00:00'}, {'ip_address': '123.123.123.45', 'mac_address': '10:00:00:00:00:01'}] args = [myid, '--allowed-address-pair', 'ip_address=123.123.123.123,mac_address=10:00:00:00:00:00', '--allowed-address-pair', 'ip_address=123.123.123.45,mac_address=10:00:00:00:00:01'] updatefields = {'allowed_address_pairs': pairs} self._test_update_resource(resource, cmd, myid, args, updatefields) def test_update_port_allowed_address_pairs_off(self): # Update port: --no-allowed-address-pairs. resource = 'port' cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['--no-allowed-address-pairs', 'myid'], {'allowed_address_pairs': []}) def test_show_port(self): # Show port: --fields id --fields name myid. resource = 'port' cmd = port.ShowPort(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', '--fields', 'name', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id', 'name']) def test_delete_port(self): # Delete port: myid. resource = 'port' cmd = port.DeletePort(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_network.py0000666000175100017510000007051013232473350027074 0ustar zuulzuul00000000000000# All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import itertools import sys from mox3 import mox from oslo_serialization import jsonutils from neutronclient.common import exceptions from neutronclient.neutron.v2_0 import network from neutronclient import shell from neutronclient.tests.unit import test_cli20 class CLITestV20CreateNetworkJSON(test_cli20.CLITestV20Base): def setUp(self): super(CLITestV20CreateNetworkJSON, self).setUp(plurals={'tags': 'tag'}) def _test_create_network(self, **kwargs): cmd = network.CreateNetwork(test_cli20.MyApp(sys.stdout), None) resource = kwargs.pop('resource', 'network') name = kwargs.pop('name', 'myname') myid = kwargs.pop('myid', 'myid') args = kwargs.pop('args', [name, ]) position_names = kwargs.pop('position_names', ['name', ]) position_values = kwargs.pop('position_values', [name, ]) self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, **kwargs) def test_create_network(self): # Create net: myname. self._test_create_network() def test_create_network_with_unicode(self): # Create net: u'\u7f51\u7edc'. self._test_create_network(name=u'\u7f51\u7edc') def test_create_network_description(self): # Create net: --tenant_id tenantid myname. name = 'myname' args = ['--description', 'Nice network', name] self._test_create_network(name=name, args=args, description='Nice network') def test_create_network_tenant_underscore(self): # Create net: --tenant_id tenantid myname. name = 'myname' args = ['--tenant_id', 'tenantid', name] self._test_create_network(name=name, args=args, tenant_id="tenantid") def test_create_network_tenant_dash(self): # Test dashed options # Create net: --tenant_id tenantid myname. name = 'myname' args = ['--tenant-id', 'tenantid', name] self._test_create_network(name=name, args=args, tenant_id="tenantid") def test_create_network_provider_args(self): # Create net: with --provider arguments. # Test --provider attributes before network name name = 'myname' args = ['--provider:network_type', 'vlan', '--provider:physical_network', 'physnet1', '--provider:segmentation_id', '400', name] position_names = ['provider:network_type', 'provider:physical_network', 'provider:segmentation_id', 'name'] position_values = ['vlan', 'physnet1', '400', name] self._test_create_network(name=name, args=args, position_names=position_names, position_values=position_values) def test_create_network_tags(self): # Create net: myname --tags a b. name = 'myname' args = [name, '--tags', 'a', 'b'] self._test_create_network(name=name, args=args, tags=['a', 'b']) def test_create_network_state_underscore(self): # Create net: --admin_state_down myname. name = 'myname' args = ['--admin_state_down', name, ] self._test_create_network(name=name, args=args, admin_state_up=False) def test_create_network_state_dash(self): # Test dashed options name = 'myname' args = ['--admin-state-down', name, ] self._test_create_network(name=name, args=args, admin_state_up=False) def test_create_network_vlan_transparent(self): # Create net: myname --vlan-transparent True. name = 'myname' args = ['--vlan-transparent', 'True', name] self._test_create_network(name=name, args=args, vlan_transparent='True') def test_create_network_with_qos_policy(self): # Create net: --qos-policy mypolicy. name = 'myname' qos_policy_name = 'mypolicy' args = [name, '--qos-policy', qos_policy_name] position_names = ['name', 'qos_policy_id'] position_values = [name, qos_policy_name] self._test_create_network(name=name, args=args, position_names=position_names, position_values=position_values) def test_create_network_with_az_hint(self): # Create net: --availability-zone-hint zone1 # --availability-zone-hint zone2. name = 'myname' args = ['--availability-zone-hint', 'zone1', '--availability-zone-hint', 'zone2', name] position_names = ['availability_zone_hints', 'name'] position_values = [['zone1', 'zone2'], name] self._test_create_network(name=name, args=args, position_names=position_names, position_values=position_values) def test_create_network_with_dns_domain(self): # Create net: --dns-domain my-domain.org. name = 'myname' dns_domain_name = 'my-domain.org.' args = [name, '--dns-domain', dns_domain_name] position_names = ['name', 'dns_domain'] position_values = [name, dns_domain_name] self._test_create_network(name=name, args=args, position_names=position_names, position_values=position_values) class CLITestV20ListNetworkJSON(test_cli20.CLITestV20Base): def setUp(self): super(CLITestV20ListNetworkJSON, self).setUp(plurals={'tags': 'tag'}) def test_list_nets_empty_with_column(self): resources = "networks" cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") self.mox.StubOutWithMock(network.ListNetwork, "extend_list") network.ListNetwork.extend_list(mox.IsA(list), mox.IgnoreArg()) cmd.get_client().MultipleTimes().AndReturn(self.client) reses = {resources: []} resstr = self.client.serialize(reses) # url method body query = "id=myfakeid" args = ['-c', 'id', '--', '--id', 'myfakeid'] path = getattr(self.client, resources + "_path") self.client.httpclient.request( test_cli20.MyUrlComparator(test_cli20.end_url(path, query), self.client), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn( (test_cli20.MyResp(200), resstr)) self.mox.ReplayAll() cmd_parser = cmd.get_parser("list_" + resources) shell.run_command(cmd, cmd_parser, args) self.mox.VerifyAll() self.mox.UnsetStubs() _str = self.fake_stdout.make_string() self.assertEqual('\n', _str) def _test_list_networks(self, cmd, detail=False, tags=(), fields_1=(), fields_2=(), page_size=None, sort_key=(), sort_dir=(), base_args=None, query=''): resources = "networks" self.mox.StubOutWithMock(network.ListNetwork, "extend_list") network.ListNetwork.extend_list(mox.IsA(list), mox.IgnoreArg()) self._test_list_resources(resources, cmd, detail, tags, fields_1, fields_2, page_size=page_size, sort_key=sort_key, sort_dir=sort_dir, base_args=base_args, query=query) def test_list_nets_pagination(self): cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(network.ListNetwork, "extend_list") network.ListNetwork.extend_list(mox.IsA(list), mox.IgnoreArg()) self._test_list_resources_with_pagination("networks", cmd) def test_list_nets_sort(self): # list nets: # --sort-key name --sort-key id --sort-dir asc --sort-dir desc cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_networks(cmd, sort_key=['name', 'id'], sort_dir=['asc', 'desc']) def test_list_nets_sort_with_keys_more_than_dirs(self): # list nets: --sort-key name --sort-key id --sort-dir desc cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_networks(cmd, sort_key=['name', 'id'], sort_dir=['desc']) def test_list_nets_sort_with_dirs_more_than_keys(self): # list nets: --sort-key name --sort-dir desc --sort-dir asc cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_networks(cmd, sort_key=['name'], sort_dir=['desc', 'asc']) def test_list_nets_limit(self): # list nets: -P. cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_networks(cmd, page_size=1000) def test_list_nets_detail(self): # list nets: -D. cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_networks(cmd, True) def test_list_nets_tags(self): # List nets: -- --tags a b. cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_networks(cmd, tags=['a', 'b']) def test_list_nets_tags_with_unicode(self): # List nets: -- --tags u'\u7f51\u7edc'. cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_networks(cmd, tags=[u'\u7f51\u7edc']) def test_list_nets_detail_tags(self): # List nets: -D -- --tags a b. cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_networks(cmd, detail=True, tags=['a', 'b']) def _test_list_nets_extend_subnets(self, data, expected): def setup_list_stub(resources, data, query): reses = {resources: data} resstr = self.client.serialize(reses) resp = (test_cli20.MyResp(200), resstr) path = getattr(self.client, resources + '_path') self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, query), self.client), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(resp) cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(cmd, 'get_client') self.mox.StubOutWithMock(self.client.httpclient, 'request') cmd.get_client().MultipleTimes().AndReturn(self.client) setup_list_stub('networks', data, '') filters = '' for n in data: for s in n['subnets']: filters = filters + "&id=%s" % s setup_list_stub('subnets', [{'id': 'mysubid1', 'cidr': '192.168.1.0/24'}, {'id': 'mysubid2', 'cidr': '172.16.0.0/24'}, {'id': 'mysubid3', 'cidr': '10.1.1.0/24'}], query='fields=id&fields=cidr' + filters) self.mox.ReplayAll() args = [] cmd_parser = cmd.get_parser('list_networks') parsed_args = cmd_parser.parse_args(args) result = cmd.take_action(parsed_args) self.mox.VerifyAll() self.mox.UnsetStubs() _result = [x for x in result[1]] self.assertEqual(len(expected), len(_result)) for res, exp in zip(_result, expected): self.assertEqual(len(exp), len(res)) for obsrvd, expctd in zip(res, exp): self.assertEqual(expctd, obsrvd) def test_list_nets_extend_subnets(self): data = [{'id': 'netid1', 'name': 'net1', 'subnets': ['mysubid1']}, {'id': 'netid2', 'name': 'net2', 'subnets': ['mysubid2', 'mysubid3']}] # id, name, subnets expected = [('netid1', 'net1', 'mysubid1 192.168.1.0/24'), ('netid2', 'net2', 'mysubid2 172.16.0.0/24\nmysubid3 10.1.1.0/24')] self._test_list_nets_extend_subnets(data, expected) def test_list_nets_extend_subnets_no_subnet(self): data = [{'id': 'netid1', 'name': 'net1', 'subnets': ['mysubid1']}, {'id': 'netid2', 'name': 'net2', 'subnets': ['mysubid4']}] # id, name, subnets expected = [('netid1', 'net1', 'mysubid1 192.168.1.0/24'), ('netid2', 'net2', 'mysubid4 ')] self._test_list_nets_extend_subnets(data, expected) def test_list_nets_fields(self): # List nets: --fields a --fields b -- --fields c d. cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_networks(cmd, fields_1=['a', 'b'], fields_2=['c', 'd']) def _test_list_nets_columns(self, cmd, returned_body, args=('-f', 'json')): resources = 'networks' self.mox.StubOutWithMock(network.ListNetwork, "extend_list") network.ListNetwork.extend_list(mox.IsA(list), mox.IgnoreArg()) self._test_list_columns(cmd, resources, returned_body, args=args) def test_list_nets_defined_column(self): cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) returned_body = {"networks": [{"name": "buildname3", "id": "id3", "tenant_id": "tenant_3", "subnets": []}]} self._test_list_nets_columns(cmd, returned_body, args=['-f', 'json', '-c', 'id']) _str = self.fake_stdout.make_string() returned_networks = jsonutils.loads(_str) self.assertEqual(1, len(returned_networks)) net = returned_networks[0] self.assertEqual(1, len(net)) self.assertIn("id", net.keys()) def test_list_nets_with_default_column(self): cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) returned_body = {"networks": [{"name": "buildname3", "id": "id3", "tenant_id": "tenant_3", "subnets": []}]} self._test_list_nets_columns(cmd, returned_body) _str = self.fake_stdout.make_string() returned_networks = jsonutils.loads(_str) self.assertEqual(1, len(returned_networks)) net = returned_networks[0] self.assertEqual(3, len(net)) self.assertEqual(0, len(set(net) ^ set(cmd.list_columns))) def test_list_external_nets_empty_with_column(self): resources = "networks" cmd = network.ListExternalNetwork(test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") self.mox.StubOutWithMock(network.ListNetwork, "extend_list") network.ListNetwork.extend_list(mox.IsA(list), mox.IgnoreArg()) cmd.get_client().MultipleTimes().AndReturn(self.client) reses = {resources: []} resstr = self.client.serialize(reses) # url method body query = "router%3Aexternal=True&id=myfakeid" args = ['-c', 'id', '--', '--id', 'myfakeid'] path = getattr(self.client, resources + "_path") self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, query), self.client), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn( (test_cli20.MyResp(200), resstr)) self.mox.ReplayAll() cmd_parser = cmd.get_parser("list_" + resources) shell.run_command(cmd, cmd_parser, args) self.mox.VerifyAll() self.mox.UnsetStubs() _str = self.fake_stdout.make_string() self.assertEqual('\n', _str) def _test_list_external_nets(self, resources, cmd, detail=False, tags=(), fields_1=(), fields_2=()): self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") self.mox.StubOutWithMock(network.ListNetwork, "extend_list") network.ListNetwork.extend_list(mox.IsA(list), mox.IgnoreArg()) cmd.get_client().MultipleTimes().AndReturn(self.client) reses = {resources: [{'id': 'myid1', }, {'id': 'myid2', }, ], } resstr = self.client.serialize(reses) # url method body query = "" args = detail and ['-D', ] or [] 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 (not tags) and fields_2: args.append('--') if fields_2: args.append("--fields") for field in fields_2: args.append(field) for field in itertools.chain(fields_1, fields_2): if query: query += "&fields=" + field else: query = "fields=" + field if query: query += '&router%3Aexternal=True' else: query += 'router%3Aexternal=True' for tag in tags: if query: query += "&tag=" + tag else: query = "tag=" + tag if detail: query = query and query + '&verbose=True' or 'verbose=True' path = getattr(self.client, resources + "_path") self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, query), self.client), 'GET', body=None, headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN) ).AndReturn((test_cli20.MyResp(200), resstr)) self.mox.ReplayAll() cmd_parser = cmd.get_parser("list_" + resources) shell.run_command(cmd, cmd_parser, args) self.mox.VerifyAll() self.mox.UnsetStubs() _str = self.fake_stdout.make_string() self.assertIn('myid1', _str) def test_list_external_nets_detail(self): # list external nets: -D. resources = "networks" cmd = network.ListExternalNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_external_nets(resources, cmd, True) def test_list_external_nets_tags(self): # List external nets: -- --tags a b. resources = "networks" cmd = network.ListExternalNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_external_nets(resources, cmd, tags=['a', 'b']) def test_list_external_nets_detail_tags(self): # List external nets: -D -- --tags a b. resources = "networks" cmd = network.ListExternalNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_external_nets(resources, cmd, detail=True, tags=['a', 'b']) def test_list_external_nets_fields(self): # List external nets: --fields a --fields b -- --fields c d. resources = "networks" cmd = network.ListExternalNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_external_nets(resources, cmd, fields_1=['a', 'b'], fields_2=['c', 'd']) def test_list_shared_networks(self): # list nets : --shared False cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self._test_list_networks(cmd, base_args='--shared False'.split(), query='shared=False') class CLITestV20UpdateNetworkJSON(test_cli20.CLITestV20Base): def test_update_network_exception(self): # Update net: myid. resource = 'network' cmd = network.UpdateNetwork(test_cli20.MyApp(sys.stdout), None) self.assertRaises(exceptions.CommandError, self._test_update_resource, resource, cmd, 'myid', ['myid'], {}) def test_update_network(self): # Update net: myid --name myname --tags a b. resource = 'network' cmd = network.UpdateNetwork(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'myname', '--tags', 'a', 'b', '--description', 'This network takes the scenic route'], {'name': 'myname', 'tags': ['a', 'b'], 'description': 'This network takes the ' 'scenic route'}) def test_update_network_with_unicode(self): # Update net: myid --name u'\u7f51\u7edc' --tags a b. resource = 'network' cmd = network.UpdateNetwork(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', u'\u7f51\u7edc', '--tags', 'a', 'b'], {'name': u'\u7f51\u7edc', 'tags': ['a', 'b'], } ) def test_update_network_with_qos_policy(self): # Update net: myid --qos-policy mypolicy. resource = 'network' cmd = network.UpdateNetwork(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--qos-policy', 'mypolicy'], {'qos_policy_id': 'mypolicy', }) def test_update_network_with_no_qos_policy(self): # Update net: myid --no-qos-policy. resource = 'network' cmd = network.UpdateNetwork(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--no-qos-policy'], {'qos_policy_id': None, }) def test_update_network_with_dns_domain(self): # Update net: myid --dns-domain my-domain.org. resource = 'network' cmd = network.UpdateNetwork(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--dns-domain', 'my-domain.org.'], {'dns_domain': 'my-domain.org.', }) def test_update_network_with_no_dns_domain(self): # Update net: myid --no-dns-domain resource = 'network' cmd = network.UpdateNetwork(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--no-dns-domain'], {'dns_domain': "", }) class CLITestV20ShowNetworkJSON(test_cli20.CLITestV20Base): def test_show_network(self): # Show net: --fields id --fields name myid. resource = 'network' cmd = network.ShowNetwork(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']) class CLITestV20DeleteNetworkJSON(test_cli20.CLITestV20Base): def test_delete_network(self): # Delete net: myid. resource = 'network' cmd = network.DeleteNetwork(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) def test_bulk_delete_network(self): # Delete net: myid1 myid2. resource = 'network' cmd = network.DeleteNetwork(test_cli20.MyApp(sys.stdout), None) myid1 = 'myid1' myid2 = 'myid2' args = [myid1, myid2] self._test_delete_resource(resource, cmd, myid1, args, extra_id=myid2) def test_bulk_delete_network_fail(self): # Delete net: myid1 myid2. resource = 'network' cmd = network.DeleteNetwork(test_cli20.MyApp(sys.stdout), None) myid1 = 'myid1' myid2 = 'myid2' args = [myid1, myid2] self.assertRaises(exceptions.NeutronCLIError, self._test_delete_resource, resource, cmd, myid1, args, extra_id=myid2, delete_fail=True) class CLITestV20ExtendListNetworkJSON(test_cli20.CLITestV20Base): def _test_extend_list(self, mox_calls): data = [{'id': 'netid%d' % i, 'name': 'net%d' % i, 'subnets': ['mysubid%d' % i]} for i in range(10)] self.mox.StubOutWithMock(self.client.httpclient, "request") path = getattr(self.client, 'subnets_path') cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(cmd, "get_client") cmd.get_client().MultipleTimes().AndReturn(self.client) mox_calls(path, data) self.mox.ReplayAll() known_args, _vs = cmd.get_parser('create_subnets').parse_known_args() cmd.extend_list(data, known_args) self.mox.VerifyAll() def _build_test_data(self, data): subnet_ids = [] response = [] filters = "" for n in data: if 'subnets' in n: subnet_ids.extend(n['subnets']) for subnet_id in n['subnets']: filters = "%s&id=%s" % (filters, subnet_id) response.append({'id': subnet_id, 'cidr': '192.168.0.0/16'}) resp_str = self.client.serialize({'subnets': response}) resp = (test_cli20.MyResp(200), resp_str) return filters, resp def test_extend_list(self): def mox_calls(path, data): filters, response = self._build_test_data(data) self.client.httpclient.request( test_cli20.MyUrlComparator(test_cli20.end_url( path, 'fields=id&fields=cidr' + filters), self.client), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(response) self._test_extend_list(mox_calls) def test_extend_list_exceed_max_uri_len(self): def mox_calls(path, data): sub_data_lists = [data[:len(data) - 1], data[len(data) - 1:]] filters, response = self._build_test_data(data) # 1 char of extra URI len will cause a split in 2 requests self.mox.StubOutWithMock(self.client.httpclient, "_check_uri_length") self.client.httpclient._check_uri_length(mox.IgnoreArg()).AndRaise( exceptions.RequestURITooLong(excess=1)) for data in sub_data_lists: filters, response = self._build_test_data(data) self.client.httpclient._check_uri_length( mox.IgnoreArg()).AndReturn(None) self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url( path, 'fields=id&fields=cidr%s' % filters), self.client), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(response) self._test_extend_list(mox_calls) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_router.py0000666000175100017510000004603413232473350026727 0ustar zuulzuul00000000000000# Copyright 2012 VMware, Inc # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.common import exceptions from neutronclient.neutron.v2_0 import router from neutronclient.tests.unit import test_cli20 class CLITestV20RouterJSON(test_cli20.CLITestV20Base): def test_create_router(self): # Create router: router1. resource = 'router' cmd = router.CreateRouter(test_cli20.MyApp(sys.stdout), None) name = 'router1' myid = 'myid' args = [name, '--description', 'rooter'] position_names = ['name', ] position_values = [name, ] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, description='rooter') def test_create_router_flavor(self): resource = 'router' cmd = router.CreateRouter(test_cli20.MyApp(sys.stdout), None) name = 'router1' myid = 'myid' flavor = 'router-flavor' args = [name, '--flavor', flavor] position_names = ['name', ] position_values = [name, flavor] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, flavor_id='router-flavor') def test_create_router_tenant(self): # Create router: --tenant_id tenantid myname. resource = 'router' cmd = router.CreateRouter(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' args = ['--tenant_id', 'tenantid', name] position_names = ['name', ] position_values = [name, ] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_router_admin_state(self): # Create router: --admin_state_down myname. resource = 'router' cmd = router.CreateRouter(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' args = ['--admin_state_down', name, ] position_names = ['name', ] position_values = [name, ] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, admin_state_up=False) def _create_router_distributed_or_ha(self, distributed=None, ha=None): # Create router: --distributed distributed --ha ha myname. resource = 'router' cmd = router.CreateRouter(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' args = [] if distributed is not None: args += ['--distributed', str(distributed)] if ha is not None: args += ['--ha', str(ha)] args.append(name) position_names = ['name', ] position_values = [name, ] expected = {} if distributed is not None: expected['distributed'] = str(distributed) if ha is not None: expected['ha'] = str(ha) self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, **expected) def test_create_router_distributed_True(self): # Create router: --distributed=True. self._create_router_distributed_or_ha(distributed='True') def test_create_router_ha_with_True(self): self._create_router_distributed_or_ha(ha='True') def test_create_router_ha_with_true(self): self._create_router_distributed_or_ha(ha='true') def test_create_router_ha_with_False(self): self._create_router_distributed_or_ha(ha='False') def test_create_router_ha_with_false(self): self._create_router_distributed_or_ha(ha='false') def test_create_router_distributed_False(self): # Create router: --distributed=False. self._create_router_distributed_or_ha(distributed='False') def test_create_router_distributed_true(self): # Create router: --distributed=true. self._create_router_distributed_or_ha(distributed='true') def test_create_router_distributed_false(self): # Create router: --distributed=false. self._create_router_distributed_or_ha(distributed='false') def test_create_router_with_az_hint(self): # Create router: --availability-zone-hint zone1 # --availability-zone-hint zone2. resource = 'router' cmd = router.CreateRouter(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' args = ['--availability-zone-hint', 'zone1', '--availability-zone-hint', 'zone2', name] position_names = ['availability_zone_hints', 'name'] position_values = [['zone1', 'zone2'], name] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_list_routers_detail(self): # list routers: -D. resources = "routers" cmd = router.ListRouter(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_routers_pagination(self): resources = "routers" cmd = router.ListRouter(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_routers_sort(self): # list routers: # --sort-key name --sort-key id --sort-key asc --sort-key desc resources = "routers" cmd = router.ListRouter(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_routers_limit(self): # list routers: -P. resources = "routers" cmd = router.ListRouter(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_update_router_exception(self): # Update router: myid. resource = 'router' cmd = router.UpdateRouter(test_cli20.MyApp(sys.stdout), None) self.assertRaises(exceptions.CommandError, self._test_update_resource, resource, cmd, 'myid', ['myid'], {}) def test_update_router(self): # Update router: myid --name myname --tags a b. resource = 'router' cmd = router.UpdateRouter(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'myname', '--description', ':D'], {'name': 'myname', 'description': ':D'}) def test_update_router_admin_state(self): # Update router: myid --admin-state-up . resource = 'router' cmd = router.UpdateRouter(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--admin-state-up', 'True'], {'admin_state_up': 'True'} ) self._test_update_resource(resource, cmd, 'myid', ['myid', '--admin-state-up', 'true'], {'admin_state_up': 'true'} ) self._test_update_resource(resource, cmd, 'myid', ['myid', '--admin-state-up', 'False'], {'admin_state_up': 'False'} ) self._test_update_resource(resource, cmd, 'myid', ['myid', '--admin-state-up', 'false'], {'admin_state_up': 'false'} ) def test_update_router_distributed(self): # Update router: myid --distributed . resource = 'router' cmd = router.UpdateRouter(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--distributed', 'True'], {'distributed': 'True'} ) self._test_update_resource(resource, cmd, 'myid', ['myid', '--distributed', 'true'], {'distributed': 'true'} ) self._test_update_resource(resource, cmd, 'myid', ['myid', '--distributed', 'False'], {'distributed': 'False'} ) self._test_update_resource(resource, cmd, 'myid', ['myid', '--distributed', 'false'], {'distributed': 'false'} ) def test_update_router_no_routes(self): # Update router: myid --no-routes resource = 'router' cmd = router.UpdateRouter(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--no-routes'], {'routes': None}) def test_update_router_add_route(self): # Update router: myid --route destination=10.0.3.0/24,nexthop=10.0.0.10 resource = 'router' cmd = router.UpdateRouter(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid, '--route', 'destination=10.0.3.0/24,nexthop=10.0.0.10'] routes = [{'destination': '10.0.3.0/24', 'nexthop': '10.0.0.10'}] updatefields = {'routes': routes} self._test_update_resource(resource, cmd, myid, args, updatefields) def test_update_router_add_routes(self): # Update router: myid --route destination=10.0.3.0/24,nexthop=10.0.0.10 # --route destination=fd7a:1d63:2063::/64, # nexthop=fd7a:1d63:2063:0:f816:3eff:fe0e:a697 resource = 'router' cmd = router.UpdateRouter(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid, '--route', 'destination=10.0.3.0/24,nexthop=10.0.0.10', '--route', 'destination=fd7a:1d63:2063::/64,' 'nexthop=fd7a:1d63:2063:0:f816:3eff:fe0e:a697'] routes = [{'destination': '10.0.3.0/24', 'nexthop': '10.0.0.10'}, {'destination': 'fd7a:1d63:2063::/64', 'nexthop': 'fd7a:1d63:2063:0:f816:3eff:fe0e:a697'}] updatefields = {'routes': routes} self._test_update_resource(resource, cmd, myid, args, updatefields) def test_update_router_no_routes_with_add_route(self): # Update router: --no-routes with --route resource = 'router' cmd = router.UpdateRouter(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid, '--no-routes', '--route', 'destination=10.0.3.0/24,nexthop=10.0.0.10'] exception = self.assertRaises(SystemExit, self._test_update_resource, resource, cmd, myid, args, None) self.assertEqual(2, exception.code) def test_delete_router(self): # Delete router: myid. resource = 'router' cmd = router.DeleteRouter(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) def test_show_router(self): # Show router: myid. resource = 'router' cmd = router.ShowRouter(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_add_remove_interface(self, action, mode, cmd, args): resource = 'router' subcmd = '%s_router_interface' % action if mode == 'port': body = {'port_id': 'portid'} else: body = {'subnet_id': 'subnetid'} if action == 'add': retval = {'subnet_id': 'subnetid', 'port_id': 'portid'} retval = self.client.serialize(retval) expected_code = 200 else: retval = None expected_code = 204 self._test_update_resource_action(resource, cmd, 'myid', subcmd, args, body, expected_code, retval) def test_add_interface_compat(self): # Add interface to router: myid subnetid. cmd = router.AddInterfaceRouter(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'subnetid'] self._test_add_remove_interface('add', 'subnet', cmd, args) def test_add_interface_by_subnet(self): # Add interface to router: myid subnet=subnetid. cmd = router.AddInterfaceRouter(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'subnet=subnetid'] self._test_add_remove_interface('add', 'subnet', cmd, args) def test_add_interface_by_port(self): # Add interface to router: myid port=portid. cmd = router.AddInterfaceRouter(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'port=portid'] self._test_add_remove_interface('add', 'port', cmd, args) def test_del_interface_compat(self): # Delete interface from router: myid subnetid. cmd = router.RemoveInterfaceRouter(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'subnetid'] self._test_add_remove_interface('remove', 'subnet', cmd, args) def test_del_interface_by_subnet(self): # Delete interface from router: myid subnet=subnetid. cmd = router.RemoveInterfaceRouter(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'subnet=subnetid'] self._test_add_remove_interface('remove', 'subnet', cmd, args) def test_del_interface_by_port(self): # Delete interface from router: myid port=portid. cmd = router.RemoveInterfaceRouter(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'port=portid'] self._test_add_remove_interface('remove', 'port', cmd, args) def test_set_gateway(self): # Set external gateway for router: myid externalid. resource = 'router' cmd = router.SetGatewayRouter(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'externalid'] self._test_update_resource(resource, cmd, 'myid', args, {"external_gateway_info": {"network_id": "externalid"}} ) def test_set_gateway_enable_snat(self): # enable external gateway for router: myid externalid. resource = 'router' cmd = router.SetGatewayRouter(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'externalid', '--enable-snat'] self._test_update_resource(resource, cmd, 'myid', args, {"external_gateway_info": {"network_id": "externalid", "enable_snat": True}} ) def test_set_gateway_disable_snat(self): # set external gateway for router: myid externalid. resource = 'router' cmd = router.SetGatewayRouter(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'externalid', '--disable-snat'] self._test_update_resource(resource, cmd, 'myid', args, {"external_gateway_info": {"network_id": "externalid", "enable_snat": False}} ) def test_set_gateway_external_ip(self): # set external gateway for router: myid externalid --fixed-ip ... resource = 'router' cmd = router.SetGatewayRouter(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'externalid', '--fixed-ip', 'ip_address=10.0.0.2'] self._test_update_resource(resource, cmd, 'myid', args, {"external_gateway_info": {"network_id": "externalid", "external_fixed_ips": [ {"ip_address": "10.0.0.2"}]}} ) def test_set_gateway_external_subnet(self): # set external gateway for router: myid externalid --fixed-ip ... resource = 'router' cmd = router.SetGatewayRouter(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'externalid', '--fixed-ip', 'subnet_id=mysubnet'] self._test_update_resource(resource, cmd, 'myid', args, {"external_gateway_info": {"network_id": "externalid", "external_fixed_ips": [ {"subnet_id": "mysubnet"}]}} ) def test_set_gateway_external_ip_and_subnet(self): # set external gateway for router: myid externalid --fixed-ip ... resource = 'router' cmd = router.SetGatewayRouter(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'externalid', '--fixed-ip', 'ip_address=10.0.0.2,subnet_id=mysubnet'] self._test_update_resource(resource, cmd, 'myid', args, {"external_gateway_info": {"network_id": "externalid", "external_fixed_ips": [ {"subnet_id": "mysubnet", "ip_address": "10.0.0.2"}]}} ) def test_remove_gateway(self): # Remove external gateway from router: externalid. resource = 'router' cmd = router.RemoveGatewayRouter(test_cli20.MyApp(sys.stdout), None) args = ['externalid'] self._test_update_resource(resource, cmd, 'externalid', args, {"external_gateway_info": {}} ) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_agentschedulers.py0000666000175100017510000002053313232473350030563 0ustar zuulzuul00000000000000# Copyright 2013 Mirantis Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from mox3 import mox from neutronclient.neutron.v2_0 import agentscheduler from neutronclient.neutron.v2_0 import network from neutronclient.tests.unit import test_cli20 AGENT_ID = 'agent_id1' NETWORK_ID = 'net_id1' ROUTER_ID = 'router_id1' class CLITestV20AgentScheduler(test_cli20.CLITestV20Base): def _test_add_to_agent(self, resource, cmd, cmd_args, destination, body, result): path = ((self.client.agent_path + destination) % cmd_args[0]) self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) result_str = self.client.serialize(result) return_tup = (test_cli20.MyResp(200), result_str) self.client.httpclient.request( test_cli20.end_url(path), 'POST', body=test_cli20.MyComparator(body, self.client), headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(return_tup) self.mox.ReplayAll() cmd_parser = cmd.get_parser('test_' + resource) parsed_args = cmd_parser.parse_args(cmd_args) cmd.run(parsed_args) self.mox.VerifyAll() self.mox.UnsetStubs() def _test_remove_from_agent(self, resource, cmd, cmd_args, destination): path = ((self.client.agent_path + destination + '/%s') % cmd_args) self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) return_tup = (test_cli20.MyResp(204), None) self.client.httpclient.request( test_cli20.end_url(path), 'DELETE', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(return_tup) self.mox.ReplayAll() cmd_parser = cmd.get_parser('test_' + resource) parsed_args = cmd_parser.parse_args(cmd_args) cmd.run(parsed_args) self.mox.VerifyAll() self.mox.UnsetStubs() class CLITestV20DHCPAgentScheduler(CLITestV20AgentScheduler): def test_add_network_to_agent(self): resource = 'agent' cmd = agentscheduler.AddNetworkToDhcpAgent( test_cli20.MyApp(sys.stdout), None) args = (AGENT_ID, NETWORK_ID) body = {'network_id': NETWORK_ID} result = {'network_id': 'net_id', } self._test_add_to_agent(resource, cmd, args, self.client.DHCP_NETS, body, result) def test_remove_network_from_agent(self): resource = 'agent' cmd = agentscheduler.RemoveNetworkFromDhcpAgent( test_cli20.MyApp(sys.stdout), None) args = (AGENT_ID, NETWORK_ID) self._test_remove_from_agent(resource, cmd, args, self.client.DHCP_NETS) def test_list_networks_on_agent(self): resources = 'networks' cmd = agentscheduler.ListNetworksOnDhcpAgent( test_cli20.MyApp(sys.stdout), None) agent_id = 'agent_id1' path = ((self.client.agent_path + self.client.DHCP_NETS) % agent_id) self.mox.StubOutWithMock(network.ListNetwork, "extend_list") network.ListNetwork.extend_list(mox.IsA(list), mox.IgnoreArg()) self._test_list_resources(resources, cmd, base_args=[agent_id], path=path) def test_list_agents_hosting_network(self): resources = 'agent' cmd = agentscheduler.ListDhcpAgentsHostingNetwork( test_cli20.MyApp(sys.stdout), None) agent_id = 'agent_id1' path = ((self.client.network_path + self.client.DHCP_AGENTS) % agent_id) contents = {self.id_field: 'myid1', 'alive': True} self._test_list_resources(resources, cmd, base_args=[agent_id], path=path, response_contents=contents) class CLITestV20L3AgentScheduler(CLITestV20AgentScheduler): def test_add_router_to_agent(self): resource = 'agent' cmd = agentscheduler.AddRouterToL3Agent( test_cli20.MyApp(sys.stdout), None) args = (AGENT_ID, ROUTER_ID) body = {'router_id': ROUTER_ID} result = {'network_id': 'net_id', } self._test_add_to_agent(resource, cmd, args, self.client.L3_ROUTERS, body, result) def test_remove_router_from_agent(self): resource = 'agent' cmd = agentscheduler.RemoveRouterFromL3Agent( test_cli20.MyApp(sys.stdout), None) args = (AGENT_ID, ROUTER_ID) self._test_remove_from_agent(resource, cmd, args, self.client.L3_ROUTERS) def test_list_routers_on_agent(self): resources = 'router' cmd = agentscheduler.ListRoutersOnL3Agent( test_cli20.MyApp(sys.stdout), None) agent_id = 'agent_id1' path = ((self.client.agent_path + self.client.L3_ROUTERS) % agent_id) contents = {self.id_field: 'myid1', 'name': 'my_name'} self._test_list_resources(resources, cmd, base_args=[agent_id], path=path, response_contents=contents) def test_list_agents_hosting_router(self): resources = 'agent' cmd = agentscheduler.ListL3AgentsHostingRouter( test_cli20.MyApp(sys.stdout), None) agent_id = 'agent_id1' path = ((self.client.router_path + self.client.L3_AGENTS) % agent_id) contents = {self.id_field: 'myid1', 'alive': True} self._test_list_resources(resources, cmd, base_args=[agent_id], path=path, response_contents=contents) class CLITestV20LBaaSAgentScheduler(test_cli20.CLITestV20Base): def test_list_pools_on_agent(self): resources = 'pools' cmd = agentscheduler.ListPoolsOnLbaasAgent( test_cli20.MyApp(sys.stdout), None) agent_id = 'agent_id1' path = ((self.client.agent_path + self.client.LOADBALANCER_POOLS) % agent_id) self._test_list_resources(resources, cmd, base_args=[agent_id], path=path) def test_get_lbaas_agent_hosting_pool(self): resources = 'agent' cmd = agentscheduler.GetLbaasAgentHostingPool( test_cli20.MyApp(sys.stdout), None) pool_id = 'pool_id1' path = ((self.client.pool_path + self.client.LOADBALANCER_AGENT) % pool_id) contents = {self.id_field: 'myid1', 'alive': True} self._test_list_resources(resources, cmd, base_args=[pool_id], path=path, response_contents=contents) class CLITestV20LBaaSV2AgentScheduler(test_cli20.CLITestV20Base): def test_list_loadbalancers_on_agent(self): resources = 'loadbalancers' cmd = agentscheduler.ListLoadBalancersOnLbaasAgent( test_cli20.MyApp(sys.stdout), None) agent_id = 'agent_id1' path = ((self.client.agent_path + self.client.AGENT_LOADBALANCERS) % agent_id) self._test_list_resources(resources, cmd, base_args=[agent_id], path=path) def test_get_lbaas_agent_hosting_pool(self): resources = 'agent' cmd = agentscheduler.GetLbaasAgentHostingLoadBalancer( test_cli20.MyApp(sys.stdout), None) lb_id = 'lb_id1' path = ((self.client.lbaas_loadbalancer_path + self.client.LOADBALANCER_HOSTING_AGENT) % lb_id) contents = {self.id_field: 'myid1', 'alive': True} self._test_list_resources(resources, cmd, base_args=[lb_id], path=path, response_contents=contents) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_agents.py0000666000175100017510000000710413232473350026663 0ustar zuulzuul00000000000000# All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sys from oslo_serialization import jsonutils from neutronclient.neutron.v2_0 import agent from neutronclient.tests.unit import test_cli20 class CLITestV20Agent(test_cli20.CLITestV20Base): def test_list_agents(self): contents = {'agents': [{'id': 'myname', 'agent_type': 'mytype', 'alive': True}]} args = ['-f', 'json'] resources = "agents" cmd = agent.ListAgent(test_cli20.MyApp(sys.stdout), None) self._test_list_columns(cmd, resources, contents, args) _str = self.fake_stdout.make_string() returned_agents = jsonutils.loads(_str) self.assertEqual(1, len(returned_agents)) ag = returned_agents[0] self.assertEqual(3, len(ag)) self.assertIn("alive", ag.keys()) def test_list_agents_field(self): contents = {'agents': [{'alive': True}]} args = ['-f', 'json'] resources = "agents" smile = ':-)' cmd = agent.ListAgent(test_cli20.MyApp(sys.stdout), None) self._test_list_columns(cmd, resources, contents, args) _str = self.fake_stdout.make_string() returned_agents = jsonutils.loads(_str) self.assertEqual(1, len(returned_agents)) ag = returned_agents[0] self.assertEqual(1, len(ag)) self.assertIn("alive", ag.keys()) self.assertIn(smile, ag.values()) def test_list_agents_zone_field(self): contents = {'agents': [{'availability_zone': 'myzone'}]} args = ['-f', 'json'] resources = "agents" cmd = agent.ListAgent(test_cli20.MyApp(sys.stdout), None) self._test_list_columns(cmd, resources, contents, args) _str = self.fake_stdout.make_string() returned_agents = jsonutils.loads(_str) self.assertEqual(1, len(returned_agents)) ag = returned_agents[0] self.assertEqual(1, len(ag)) self.assertIn("availability_zone", ag.keys()) self.assertIn('myzone', ag.values()) def test_update_agent(self): # agent-update myid --admin-state-down --description mydescr. resource = 'agent' cmd = agent.UpdateAgent(test_cli20.MyApp(sys.stdout), None) self._test_update_resource( resource, cmd, 'myid', ['myid', '--admin-state-down', '--description', 'mydescr'], {'description': 'mydescr', 'admin_state_up': False} ) def test_show_agent(self): # Show agent: --field id --field binary myid. resource = 'agent' cmd = agent.ShowAgent(test_cli20.MyApp(sys.stdout), None) args = ['--field', 'id', '--field', 'binary', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id', 'binary']) def test_delete_agent(self): # Delete agent: myid. resource = 'agent' cmd = agent.DeleteAgent(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) python-neutronclient-6.7.0/neutronclient/tests/unit/fw/0000775000175100017510000000000013232473710023410 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/fw/test_cli20_firewallpolicy.py0000666000175100017510000002364413232473350031052 0ustar zuulzuul00000000000000# Copyright 2013 Big Switch Networks Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from mox3 import mox from neutronclient.neutron.v2_0.fw import firewallpolicy from neutronclient import shell from neutronclient.tests.unit import test_cli20 class CLITestV20FirewallPolicyJSON(test_cli20.CLITestV20Base): def setUp(self): super(CLITestV20FirewallPolicyJSON, self).setUp() def test_create_firewall_policy_with_mandatory_params(self): # firewall-policy-create with mandatory (none) params only. resource = 'firewall_policy' cmd = firewallpolicy.CreateFirewallPolicy(test_cli20.MyApp(sys.stdout), None) tenant_id = 'my-tenant' name = 'my-name' my_id = 'myid' args = ['--tenant-id', tenant_id, '--admin-state_up', name, ] position_names = ['name', ] position_values = [name, ] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, admin_state_up=True, tenant_id=tenant_id) def test_create_firewall_policy_with_all_params(self): # firewall-policy-create with rule param of misc format. resource = 'firewall_policy' cmd = firewallpolicy.CreateFirewallPolicy(test_cli20.MyApp(sys.stdout), None) name = 'my-name' description = 'my-desc' firewall_rules_res = ['rule_id1', 'rule_id2'] tenant_id = 'my-tenant' my_id = 'myid' position_names = ['name', ] position_values = [name, ] # check for both str and unicode format firewall_rules_arg for firewall_rules_arg in ['rule_id1 rule_id2', u'rule_id1 rule_id2']: args = ['--description', description, '--shared', '--firewall-rules', firewall_rules_arg, '--audited', '--tenant-id', tenant_id, '--admin-state_up', name] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, description=description, shared=True, firewall_rules=firewall_rules_res, audited=True, admin_state_up=True, tenant_id=tenant_id) def test_list_firewall_policies(self): # firewall-policy-list. resources = "firewall_policies" cmd = firewallpolicy.ListFirewallPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_firewall_policies_pagination(self): # firewall-policy-list.""" resources = "firewall_policies" cmd = firewallpolicy.ListFirewallPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_firewall_policies_sort(self): # sorted list: firewall-policy-list --sort-key name --sort-key id # --sort-key asc --sort-key desc resources = "firewall_policies" cmd = firewallpolicy.ListFirewallPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_firewall_policies_limit(self): # size (1000) limited list: firewall-policy-list -P. resources = "firewall_policies" cmd = firewallpolicy.ListFirewallPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_firewall_policy_id(self): # firewall-policy-show test_id. resource = 'firewall_policy' cmd = firewallpolicy.ShowFirewallPolicy(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_firewall_policy_id_name(self): # firewall-policy-show. resource = 'firewall_policy' cmd = firewallpolicy.ShowFirewallPolicy(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_firewall_policy(self): # firewall-policy-update myid --name newname. resource = 'firewall_policy' cmd = firewallpolicy.UpdateFirewallPolicy(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'newname'], {'name': 'newname', }) def test_update_firewall_policy_with_rules(self): # firewall-policy-update myid --firewall-rules "rule1 rule2". resource = 'firewall_policy' cmd = firewallpolicy.UpdateFirewallPolicy(test_cli20.MyApp(sys.stdout), None) firewall_rules_arg = u'rule_id3 rule_id4' firewall_rules_res = ['rule_id3', 'rule_id4'] self._test_update_resource( resource, cmd, 'myid', ['myid', '--firewall-rules', firewall_rules_arg], {'firewall_rules': firewall_rules_res, }) def test_delete_firewall_policy(self): # firewall-policy-delete my-id. resource = 'firewall_policy' cmd = firewallpolicy.DeleteFirewallPolicy(test_cli20.MyApp(sys.stdout), None) my_id = 'myid1' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) def test_insert_firewall_rule(self): # firewall-policy-insert-rule myid newruleid --insert-before ruleAid # --insert-after ruleBid resource = 'firewall_policy' cmd = firewallpolicy.FirewallPolicyInsertRule( test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = ['myid', 'newrule', '--insert-before', 'rule2', '--insert-after', 'rule1'] extrafields = {'firewall_rule_id': 'newrule', 'insert_before': 'rule2', 'insert_after': 'rule1'} self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) body = extrafields path = getattr(self.client, resource + "_insert_path") self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path % myid), self.client), 'PUT', body=test_cli20.MyComparator(body, self.client), headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn((test_cli20.MyResp(204), None)) self.mox.ReplayAll() cmd_parser = cmd.get_parser(resource + "_insert_rule") shell.run_command(cmd, cmd_parser, args) self.mox.VerifyAll() self.mox.UnsetStubs() def test_remove_firewall_rule(self): # firewall-policy-remove-rule myid ruleid resource = 'firewall_policy' cmd = firewallpolicy.FirewallPolicyRemoveRule( test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = ['myid', 'removerule'] extrafields = {'firewall_rule_id': 'removerule', } self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) body = extrafields path = getattr(self.client, resource + "_remove_path") self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path % myid), self.client), 'PUT', body=test_cli20.MyComparator(body, self.client), headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn((test_cli20.MyResp(204), None)) self.mox.ReplayAll() cmd_parser = cmd.get_parser(resource + "_remove_rule") shell.run_command(cmd, cmd_parser, args) self.mox.VerifyAll() self.mox.UnsetStubs() def test_update_firewall_policy_name_shared_audited(self): # firewall-policy-update myid --name newname2 --shared --audited resource = 'firewall_policy' cmd = firewallpolicy.UpdateFirewallPolicy(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'newname2', '--shared', 'True', '--audited', 'True'], {'name': 'newname2', 'shared': 'True', 'audited': 'True'}) python-neutronclient-6.7.0/neutronclient/tests/unit/fw/test_cli20_firewallrule.py0000666000175100017510000002647613232473350030530 0ustar zuulzuul00000000000000# Copyright 2013 Big Switch Networks Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.fw import firewallrule from neutronclient.tests.unit import test_cli20 class CLITestV20FirewallRuleJSON(test_cli20.CLITestV20Base): def _test_create_firewall_rule_with_mandatory_params(self, enabled): # firewall-rule-create with mandatory (none) params only. resource = 'firewall_rule' cmd = firewallrule.CreateFirewallRule(test_cli20.MyApp(sys.stdout), None) tenant_id = 'my-tenant' name = '' my_id = 'myid' protocol = 'tcp' action = 'allow' ip_version = 4 args = ['--tenant-id', tenant_id, '--admin-state-up', '--protocol', protocol, '--action', action, '--enabled', enabled] position_names = [] position_values = [] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, protocol=protocol, action=action, enabled=enabled, tenant_id=tenant_id, ip_version=ip_version) def test_create_enabled_firewall_rule_with_mandatory_params_lcase(self): self._test_create_firewall_rule_with_mandatory_params(enabled='true') def test_create_disabled_firewall_rule_with_mandatory_params_lcase(self): self._test_create_firewall_rule_with_mandatory_params(enabled='false') def test_create_enabled_firewall_rule_with_mandatory_params(self): self._test_create_firewall_rule_with_mandatory_params(enabled='True') def test_create_disabled_firewall_rule_with_mandatory_params(self): self._test_create_firewall_rule_with_mandatory_params(enabled='False') def _setup_create_firewall_rule_with_all_params( self, protocol='tcp', protocol_cli=None, action='allow', action_cli=None, ip_version='4'): # firewall-rule-create with all params set. resource = 'firewall_rule' cmd = firewallrule.CreateFirewallRule(test_cli20.MyApp(sys.stdout), None) name = 'my-name' description = 'my-desc' source_ip = '192.168.1.0/24' destination_ip = '192.168.2.0/24' source_port = '0:65535' destination_port = '0:65535' tenant_id = 'my-tenant' my_id = 'myid' enabled = 'True' args = ['--description', description, '--shared', '--protocol', protocol_cli or protocol, '--ip-version', ip_version, '--source-ip-address', source_ip, '--destination-ip-address', destination_ip, '--source-port', source_port, '--destination-port', destination_port, '--action', action_cli or action, '--enabled', enabled, '--admin-state-up', '--tenant-id', tenant_id] position_names = [] position_values = [] if protocol == 'any': protocol = None if ip_version == '4' or ip_version == '6': self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, description=description, shared=True, protocol=protocol, ip_version=int(ip_version), source_ip_address=source_ip, destination_ip_address=destination_ip, source_port=source_port, destination_port=destination_port, action=action, enabled='True', tenant_id=tenant_id) else: self.assertRaises(SystemExit, self._test_create_resource, resource, cmd, name, my_id, args, position_names, position_values, ip_version=int(ip_version), source_ip_address=source_ip, destination_ip_address=destination_ip, source_port=source_port, destination_port=destination_port, action=action, enabled='True', tenant_id=tenant_id) def test_create_firewall_rule_with_all_params(self): self._setup_create_firewall_rule_with_all_params() def test_create_firewall_rule_with_proto_any(self): self._setup_create_firewall_rule_with_all_params(protocol='any') def test_create_firewall_rule_with_IP_version_6(self): self._setup_create_firewall_rule_with_all_params(ip_version='6') def test_create_firewall_rule_with_invalid_IP_version(self): self._setup_create_firewall_rule_with_all_params(ip_version='5') def test_create_firewall_rule_with_proto_action_upper_capitalized(self): for protocol in ('TCP', 'Tcp', 'ANY', 'AnY'): self._setup_create_firewall_rule_with_all_params( protocol=protocol.lower(), protocol_cli=protocol) for action in ('Allow', 'DENY', 'reject'): self._setup_create_firewall_rule_with_all_params( action=action.lower(), action_cli=action) def test_list_firewall_rules(self): # firewall-rule-list. resources = "firewall_rules" cmd = firewallrule.ListFirewallRule(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_firewall_rules_pagination(self): # firewall-rule-list. resources = "firewall_rules" cmd = firewallrule.ListFirewallRule(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_firewall_rules_sort(self): # firewall-rule-list --sort-key name --sort-key id --sort-key asc # --sort-key desc resources = "firewall_rules" cmd = firewallrule.ListFirewallRule(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_firewall_rules_limit(self): # firewall-rule-list -P.""" resources = "firewall_rules" cmd = firewallrule.ListFirewallRule(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_firewall_rule_id(self): # firewall-rule-show test_id. resource = 'firewall_rule' cmd = firewallrule.ShowFirewallRule(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_firewall_rule_id_name(self): # firewall-rule-show. resource = 'firewall_rule' cmd = firewallrule.ShowFirewallRule(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_firewall_rule(self): # firewall-rule-update myid --name newname. resource = 'firewall_rule' cmd = firewallrule.UpdateFirewallRule(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'newname'], {'name': 'newname', }) # firewall-rule-update myid --protocol any. self._test_update_resource(resource, cmd, 'myid', ['myid', '--protocol', 'any'], {'protocol': None, }) # firewall-rule-update myid --description any self._test_update_resource(resource, cmd, 'myid', ['myid', '--description', 'any'], {'description': 'any', }) # firewall-rule-update myid --source_ip_address 192.192.192.192 self._test_update_resource(resource, cmd, 'myid', ['myid', '--source_ip_address', '192.192.192.192'], {'source_ip_address': '192.192.192.192', }) # firewall-rule-update myid --source_port 32767 self._test_update_resource(resource, cmd, 'myid', ['myid', '--source_port', '32767'], {'source_port': '32767', }) # firewall-rule-update myid --destination_ip_address 0.1.0.1 self._test_update_resource(resource, cmd, 'myid', ['myid', '--destination_ip_address', '0.1.0.1'], {'destination_ip_address': '0.1.0.1', }) # firewall-rule-update myid --destination_port 65432 self._test_update_resource(resource, cmd, 'myid', ['myid', '--destination_port', '65432'], {'destination_port': '65432', }) # firewall-rule-update myid --enabled False self._test_update_resource(resource, cmd, 'myid', ['myid', '--enabled', 'False'], {'enabled': 'False', }) # firewall-rule-update myid --action reject self._test_update_resource(resource, cmd, 'myid', ['myid', '--action', 'reject'], {'action': 'reject', }) # firewall-rule-update myid --shared false self._test_update_resource(resource, cmd, 'myid', ['myid', '--shared', 'false'], {'shared': 'false', }) def test_delete_firewall_rule(self): # firewall-rule-delete my-id. resource = 'firewall_rule' cmd = firewallrule.DeleteFirewallRule(test_cli20.MyApp(sys.stdout), None) my_id = 'myid1' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) python-neutronclient-6.7.0/neutronclient/tests/unit/fw/test_cli20_firewall.py0000666000175100017510000001620113232473350027621 0ustar zuulzuul00000000000000# Copyright 2013 Big Switch Networks Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.fw import firewall from neutronclient.tests.unit import test_cli20 class CLITestV20FirewallJSON(test_cli20.CLITestV20Base): def test_create_firewall_with_mandatory_params(self): # firewall-create with mandatory (none) params. resource = 'firewall' cmd = firewall.CreateFirewall(test_cli20.MyApp(sys.stdout), None) name = '' tenant_id = 'my-tenant' my_id = 'my-id' policy_id = 'my-policy-id' args = ['--tenant-id', tenant_id, policy_id, ] position_names = ['firewall_policy_id', ] position_values = [policy_id, ] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, admin_state_up=True, tenant_id=tenant_id) def test_create_firewall_with_all_params(self): # firewall-create with all params set. resource = 'firewall' cmd = firewall.CreateFirewall(test_cli20.MyApp(sys.stdout), None) name = 'my-name' description = 'my-desc' policy_id = 'my-policy-id' tenant_id = 'my-tenant' my_id = 'my-id' args = ['--description', description, '--admin-state-down', '--tenant-id', tenant_id, policy_id] position_names = ['firewall_policy_id', ] position_values = [policy_id, ] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, description=description, admin_state_up=False, tenant_id=tenant_id) def test_create_firewall_with_routers(self): resource = 'firewall' cmd = firewall.CreateFirewall(test_cli20.MyApp(sys.stdout), None) name = 'my-name' policy_id = 'my-policy-id' my_id = 'my-id' args = ['--router', 'fake-id', '--router', 'fake-name', policy_id] router_ids = ['fake-id', 'fake-name'] position_names = ['firewall_policy_id', 'router_ids'] position_values = [policy_id, router_ids] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values) def test_list_firewalls(self): # firewall-list. resources = "firewalls" cmd = firewall.ListFirewall(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_firewalls_pagination(self): # firewall-list with pagination. resources = "firewalls" cmd = firewall.ListFirewall(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_firewalls_sort(self): # sorted list: firewall-list --sort-key name --sort-key id # --sort-key asc --sort-key desc resources = "firewalls" cmd = firewall.ListFirewall(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_firewalls_limit(self): # size (1000) limited list: firewall-list -P. resources = "firewalls" cmd = firewall.ListFirewall(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_firewall_id(self): # firewall-show test_id. resource = 'firewall' cmd = firewall.ShowFirewall(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_firewall_id_name(self): # firewall-show. resource = 'firewall' cmd = firewall.ShowFirewall(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_firewall(self): # firewall-update myid --name newname --tags a b. resource = 'firewall' cmd = firewall.UpdateFirewall(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'newname'], {'name': 'newname', }) def test_update_firewall_using_policy_name(self): # firewall-update myid --policy newpolicy. resource = 'firewall' cmd = firewall.UpdateFirewall(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--policy', 'newpolicy'], {'firewall_policy_id': 'newpolicy'}) def test_update_firewall_with_routers(self): resource = 'firewall' cmd = firewall.UpdateFirewall(test_cli20.MyApp(sys.stdout), None) self._test_update_resource( resource, cmd, 'myid', ['myid', '--router', 'fake-id', '--router', 'fake-name'], {'router_ids': ['fake-id', 'fake-name']}) def test_update_firewall_with_no_routers(self): resource = 'firewall' cmd = firewall.UpdateFirewall(test_cli20.MyApp(sys.stdout), None) self._test_update_resource( resource, cmd, 'myid', ['myid', '--no-routers'], {'router_ids': []}) def test_update_firewall_with_bad_router_options(self): resource = 'firewall' cmd = firewall.UpdateFirewall(test_cli20.MyApp(sys.stdout), None) self.assertRaises( SystemExit, self._test_update_resource, resource, cmd, 'myid', ['myid', '--no-routers', '--router', 'fake-id'], {}) def test_delete_firewall(self): # firewall-delete my-id. resource = 'firewall' cmd = firewall.DeleteFirewall(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) def test_update_firewall_admin_state(self): # firewall-update myid --admin-state-up True. resource = 'firewall' cmd = firewall.UpdateFirewall(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--admin-state-up', 'True'], {'admin_state_up': 'True'}) python-neutronclient-6.7.0/neutronclient/tests/unit/fw/__init__.py0000666000175100017510000000000013232473350025511 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_network_ip_availability.py0000666000175100017510000000446513232473350032324 0ustar zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sys from neutronclient.neutron.v2_0 import network_ip_availability from neutronclient.tests.unit import test_cli20 class CLITestV20NetworkIPAvailability(test_cli20.CLITestV20Base): id_field = 'network_id' def _test_list_network_ip_availability(self, args, query): resources = "network_ip_availabilities" cmd = network_ip_availability.ListIpAvailability(test_cli20.MyApp (sys.stdout), None) self._test_list_resources(resources, cmd, base_args=args, query=query) def test_list_network_ip_availability(self): self._test_list_network_ip_availability(args=None, query='ip_version=4') def test_list_network_ip_availability_ipv6(self): self._test_list_network_ip_availability( args=['--ip-version', '6'], query='ip_version=6') def test_list_network_ip_availability_net_id_and_ipv4(self): self._test_list_network_ip_availability( args=['--ip-version', '4', '--network-id', 'myid'], query='ip_version=4&network_id=myid') def test_list_network_ip_availability_net_name_and_tenant_id(self): self._test_list_network_ip_availability( args=['--network-name', 'foo', '--tenant-id', 'mytenant'], query='network_name=foo&tenant_id=mytenant&ip_version=4') def test_show_network_ip_availability(self): resource = "network_ip_availability" cmd = network_ip_availability.ShowIpAvailability( test_cli20.MyApp(sys.stdout), None) self._test_show_resource(resource, cmd, self.test_id, args=[self.test_id]) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20.py0000666000175100017510000013316213232473350025326 0ustar zuulzuul00000000000000# 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 # # 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 contextlib import itertools import json import sys import mock from mox3 import mox from oslo_utils import encodeutils from oslotest import base import requests import six import six.moves.urllib.parse as urlparse import yaml from neutronclient.common import constants from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV2_0 from neutronclient.neutron.v2_0 import network from neutronclient import shell from neutronclient.v2_0 import client API_VERSION = "2.0" TOKEN = 'testtoken' ENDURL = 'localurl' REQUEST_ID = 'test_request_id' @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(object): def __init__(self): self.content = [] def write(self, text): self.content.append(text) def make_string(self): result = '' for line in self.content: result += encodeutils.safe_decode(line, 'utf-8') return result class MyRequest(requests.Request): def __init__(self, method=None): self.method = method class MyResp(requests.Response): def __init__(self, status_code, headers=None, reason=None, request=None, url=None): self.status_code = status_code self.headers = headers or {} self.reason = reason self.request = request or MyRequest() self.url = url class MyApp(object): def __init__(self, _stdout): self.stdout = _stdout def end_url(path, query=None): _url_str = ENDURL + "/v" + API_VERSION + path return query and _url_str + "?" + query or _url_str class MyUrlComparator(mox.Comparator): def __init__(self, lhs, client): self.lhs = lhs self.client = client def equals(self, rhs): lhsp = urlparse.urlparse(self.lhs) rhsp = urlparse.urlparse(rhs) lhs_qs = urlparse.parse_qsl(lhsp.query) rhs_qs = urlparse.parse_qsl(rhsp.query) return (lhsp.scheme == rhsp.scheme and lhsp.netloc == rhsp.netloc and lhsp.path == rhsp.path and len(lhs_qs) == len(rhs_qs) and set(lhs_qs) == set(rhs_qs)) def __str__(self): 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): test_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' id_field = 'id' non_admin_status_resources = [] def _find_resourceid(self, client, resource, name_or_id, cmd_resource=None, parent_id=None): return name_or_id 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} self.mox = mox.Mox() self.endurl = ENDURL self.fake_stdout = FakeStdout() self.addCleanup(mock.patch.stopall) mock.patch('sys.stdout', new=self.fake_stdout).start() mock.patch('neutronclient.neutron.v2_0.find_resourceid_by_name_or_id', new=self._find_resourceid).start() mock.patch('neutronclient.neutron.v2_0.find_resourceid_by_id', new=self._find_resourceid).start() self.client = client.Client(token=TOKEN, endpoint_url=self.endurl) def register_non_admin_status_resource(self, resource_name): # TODO(amotoki): # It is recommended to define # "non_admin_status_resources in each test class rather than # using register_non_admin_status_resource method. # If we change self.non_admin_status_resources like this, # we need to ensure this should be an instance variable # to avoid changing the class variable. if (id(self.non_admin_status_resources) == id(self.__class__.non_admin_status_resources)): self.non_admin_status_resources = (self.__class__. non_admin_status_resources[:]) self.non_admin_status_resources.append(resource_name) def _test_create_resource(self, resource, cmd, name, myid, args, position_names, position_values, tenant_id=None, tags=None, admin_state_up=True, extra_body=None, cmd_resource=None, parent_id=None, no_api_call=False, expected_exception=None, **kwargs): 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 if (resource in self.non_admin_status_resources): body = {resource: {}, } else: body = {resource: {'admin_state_up': admin_state_up, }, } if tenant_id: body[resource].update({'tenant_id': tenant_id}) if tags: body[resource].update({'tags': tags}) if extra_body: body[resource].update(extra_body) body[resource].update(kwargs) for i in range(len(position_names)): body[resource].update({position_names[i]: position_values[i]}) ress = {resource: {self.id_field: myid}, } if name: ress[resource].update({'name': name}) resstr = self.client.serialize(ress) # url method body resource_plural = self.client.get_resource_plural(cmd_resource) path = getattr(self.client, resource_plural + "_path") if parent_id: path = path % parent_id mox_body = MyComparator(body, self.client) if not no_api_call: self.client.httpclient.request( end_url(path), 'POST', body=mox_body, headers=mox.ContainsKeyValue( 'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr)) self.mox.ReplayAll() cmd_parser = cmd.get_parser('create_' + resource) if expected_exception: self.assertRaises(expected_exception, shell.run_command, cmd, cmd_parser, args) else: shell.run_command(cmd, cmd_parser, args) _str = self.fake_stdout.make_string() self.assertIn(myid, _str) if name: self.assertIn(name, _str) self.mox.VerifyAll() self.mox.UnsetStubs() 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) 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), '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() 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, output_format=None, query=""): 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} resstr = self.client.serialize(reses) # url method body args = base_args if base_args is not None else [] if detail: args.append('-D') 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) tag_query = urlparse.urlencode( {'tag': encodeutils.safe_encode(tag)}) if query: query += "&" + tag_query else: query = tag_query 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 if output_format: args.append('-f') args.append(output_format) self.client.httpclient.request( MyUrlComparator(end_url(path, query), 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, base_args=None, cmd_resources=None, parent_id=None, query=""): 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', }]} resstr1 = self.client.serialize(reses1) resstr2 = self.client.serialize(reses2) self.client.httpclient.request( end_url(path, query), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr1)) self.client.httpclient.request( MyUrlComparator(end_url(path, fake_query), 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 = base_args if base_args is not None else [] 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 mox_body = MyComparator(body, self.client) self.client.httpclient.request( MyUrlComparator(end_url(path), self.client), 'PUT', body=mox_body, headers=mox.ContainsKeyValue( 'X-Auth-Token', TOKEN)).AndReturn((MyResp(204), None)) 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', }, } 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), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr)) 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_set_path_and_delete(self, path, parent_id, myid, delete_fail=False): return_val = 404 if delete_fail else 204 if parent_id: path = path % (parent_id, myid) else: path = path % (myid) self.client.httpclient.request( end_url(path), 'DELETE', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', TOKEN)).AndReturn((MyResp( return_val), None)) def _test_delete_resource(self, resource, cmd, myid, args, cmd_resource=None, parent_id=None, extra_id=None, delete_fail=False): 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") self._test_set_path_and_delete(path, parent_id, myid) # extra_id is used to test for bulk_delete if extra_id: self._test_set_path_and_delete(path, parent_id, extra_id, delete_fail) 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) if extra_id: self.assertIn(extra_id, _str) def _test_update_resource_action(self, resource, cmd, myid, action, args, body, expected_code=200, 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), 'PUT', body=MyComparator(body, self.client), headers=mox.ContainsKeyValue( 'X-Auth-Token', TOKEN)).AndReturn((MyResp(expected_code), retval)) 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) class TestListCommand(neutronV2_0.ListCommand): resource = 'test_resource' filter_attrs = [ 'name', 'admin_state_up', {'name': 'foo', 'help': 'non-boolean attribute foo'}, {'name': 'bar', 'help': 'boolean attribute bar', 'boolean': True}, {'name': 'baz', 'help': 'integer attribute baz', 'argparse_kwargs': {'choices': ['baz1', 'baz2']}}, ] class ListCommandTestCase(CLITestV20Base): def setUp(self): super(ListCommandTestCase, self).setUp() self.client.extend_list('test_resources', '/test_resources', None) setattr(self.client, 'test_resources_path', '/test_resources') def _test_list_resources_filter_params(self, base_args='', query=''): resources = 'test_resources' cmd = TestListCommand(MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, base_args=base_args.split(), query=query) def _test_list_resources_with_arg_error(self, base_args=''): self.addCleanup(self.mox.UnsetStubs) resources = 'test_resources' cmd = TestListCommand(MyApp(sys.stdout), None) # argparse parse error leads to SystemExit self.assertRaises(SystemExit, self._test_list_resources, resources, cmd, base_args=base_args.split()) def test_list_resources_without_filter(self): self._test_list_resources_filter_params() def test_list_resources_use_default_filter(self): self._test_list_resources_filter_params( base_args='--name val1 --admin-state-up False', query='name=val1&admin_state_up=False') def test_list_resources_use_custom_filter(self): self._test_list_resources_filter_params( base_args='--foo FOO --bar True', query='foo=FOO&bar=True') def test_list_resources_boolean_check_default_filter(self): self._test_list_resources_filter_params( base_args='--admin-state-up True', query='admin_state_up=True') self._test_list_resources_filter_params( base_args='--admin-state-up False', query='admin_state_up=False') self._test_list_resources_with_arg_error( base_args='--admin-state-up non-true-false') def test_list_resources_boolean_check_custom_filter(self): self._test_list_resources_filter_params( base_args='--bar True', query='bar=True') self._test_list_resources_filter_params( base_args='--bar False', query='bar=False') self._test_list_resources_with_arg_error( base_args='--bar non-true-false') def test_list_resources_argparse_kwargs(self): self._test_list_resources_filter_params( base_args='--baz baz1', query='baz=baz1') self._test_list_resources_filter_params( base_args='--baz baz2', query='baz=baz2') self._test_list_resources_with_arg_error( base_args='--bar non-choice') class ClientV2TestJson(CLITestV20Base): def test_do_request_unicode(self): self.mox.StubOutWithMock(self.client.httpclient, "request") unicode_text = u'\u7f51\u7edc' # url with unicode action = u'/test' expected_action = action # query string with unicode params = {'test': unicode_text} expect_query = urlparse.urlencode(utils.safe_encode_dict(params)) # request body with unicode body = params expect_body = self.client.serialize(body) self.client.httpclient.auth_token = encodeutils.safe_encode( unicode_text) expected_auth_token = encodeutils.safe_encode(unicode_text) resp_headers = {'x-openstack-request-id': REQUEST_ID} self.client.httpclient.request( end_url(expected_action, query=expect_query), 'PUT', body=expect_body, headers=mox.ContainsKeyValue( 'X-Auth-Token', expected_auth_token)).AndReturn((MyResp(200, resp_headers), expect_body)) self.mox.ReplayAll() result = self.client.do_request('PUT', action, body=body, params=params) self.mox.VerifyAll() self.mox.UnsetStubs() # test response with unicode self.assertEqual(body, result) def test_do_request_error_without_response_body(self): self.mox.StubOutWithMock(self.client.httpclient, "request") params = {'test': 'value'} expect_query = six.moves.urllib.parse.urlencode(params) self.client.httpclient.auth_token = 'token' resp_headers = {'x-openstack-request-id': REQUEST_ID} self.client.httpclient.request( MyUrlComparator(end_url('/test', query=expect_query), self.client), 'PUT', body='', headers=mox.ContainsKeyValue('X-Auth-Token', 'token') ).AndReturn((MyResp(400, headers=resp_headers, reason='An error'), '')) self.mox.ReplayAll() error = self.assertRaises(exceptions.NeutronClientException, self.client.do_request, 'PUT', '/test', body='', params=params) expected_error = "An error\nNeutron server returns " \ "request_ids: %s" % [REQUEST_ID] self.assertEqual(expected_error, str(error)) self.mox.VerifyAll() self.mox.UnsetStubs() def test_do_request_with_long_uri_exception(self): long_string = 'x' * 8200 # 8200 > MAX_URI_LEN:8192 params = {'id': long_string} exception = self.assertRaises(exceptions.RequestURITooLong, self.client.do_request, 'GET', '/test', body='', params=params) self.assertNotEqual(0, exception.excess) def test_do_request_request_ids(self): self.mox.StubOutWithMock(self.client.httpclient, "request") params = {'test': 'value'} expect_query = six.moves.urllib.parse.urlencode(params) self.client.httpclient.auth_token = 'token' body = params expect_body = self.client.serialize(body) resp_headers = {'x-openstack-request-id': REQUEST_ID} self.client.httpclient.request( MyUrlComparator(end_url('/test', query=expect_query), self.client), 'PUT', body=expect_body, headers=mox.ContainsKeyValue('X-Auth-Token', 'token') ).AndReturn((MyResp(200, resp_headers), expect_body)) self.mox.ReplayAll() result = self.client.do_request('PUT', '/test', body=body, params=params) self.mox.VerifyAll() self.mox.UnsetStubs() self.assertEqual(body, result) self.assertEqual([REQUEST_ID], result.request_ids) def test_list_request_ids_with_retrieve_all_true(self): self.mox.StubOutWithMock(self.client.httpclient, "request") path = '/test' resources = 'tests' 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', }]} resstr1 = self.client.serialize(reses1) resstr2 = self.client.serialize(reses2) resp_headers = {'x-openstack-request-id': REQUEST_ID} self.client.httpclient.request( end_url(path, ""), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', TOKEN)).AndReturn((MyResp(200, resp_headers), resstr1)) self.client.httpclient.request( MyUrlComparator(end_url(path, fake_query), self.client), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', TOKEN)).AndReturn((MyResp(200, resp_headers), resstr2)) self.mox.ReplayAll() result = self.client.list(resources, path) self.mox.VerifyAll() self.mox.UnsetStubs() self.assertEqual([REQUEST_ID, REQUEST_ID], result.request_ids) def test_list_request_ids_with_retrieve_all_false(self): self.mox.StubOutWithMock(self.client.httpclient, "request") path = '/test' resources = 'tests' 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', }]} resstr1 = self.client.serialize(reses1) resstr2 = self.client.serialize(reses2) resp_headers = {'x-openstack-request-id': REQUEST_ID} self.client.httpclient.request( end_url(path, ""), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', TOKEN)).AndReturn((MyResp(200, resp_headers), resstr1)) self.client.httpclient.request( MyUrlComparator(end_url(path, fake_query), self.client), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', TOKEN)).AndReturn((MyResp(200, resp_headers), resstr2)) self.mox.ReplayAll() result = self.client.list(resources, path, retrieve_all=False) next(result) self.assertEqual([REQUEST_ID], result.request_ids) next(result) self.assertEqual([REQUEST_ID, REQUEST_ID], result.request_ids) self.mox.VerifyAll() self.mox.UnsetStubs() def test_deserialize_without_data(self): data = u'' result = self.client.deserialize(data, 200) self.assertEqual(data, result) def test_update_resource(self): self.mox.StubOutWithMock(self.client.httpclient, "request") params = {'test': 'value'} expect_query = six.moves.urllib.parse.urlencode(params) self.client.httpclient.auth_token = 'token' body = params expect_body = self.client.serialize(body) resp_headers = {'x-openstack-request-id': REQUEST_ID} self.client.httpclient.request( MyUrlComparator(end_url('/test', query=expect_query), self.client), 'PUT', body=expect_body, headers=mox.And( mox.ContainsKeyValue('X-Auth-Token', 'token'), mox.Not(mox.In('If-Match'))) ).AndReturn((MyResp(200, resp_headers), expect_body)) self.mox.ReplayAll() result = self.client._update_resource('/test', body=body, params=params) self.mox.VerifyAll() self.mox.UnsetStubs() self.assertEqual(body, result) self.assertEqual([REQUEST_ID], result.request_ids) def test_update_resource_with_revision_number(self): self.mox.StubOutWithMock(self.client.httpclient, "request") params = {'test': 'value'} expect_query = six.moves.urllib.parse.urlencode(params) self.client.httpclient.auth_token = 'token' body = params expect_body = self.client.serialize(body) resp_headers = {'x-openstack-request-id': REQUEST_ID} self.client.httpclient.request( MyUrlComparator(end_url('/test', query=expect_query), self.client), 'PUT', body=expect_body, headers=mox.And( mox.ContainsKeyValue('X-Auth-Token', 'token'), mox.ContainsKeyValue('If-Match', 'revision_number=1')) ).AndReturn((MyResp(200, resp_headers), expect_body)) self.mox.ReplayAll() result = self.client._update_resource('/test', body=body, params=params, revision_number=1) self.mox.VerifyAll() self.mox.UnsetStubs() self.assertEqual(body, result) self.assertEqual([REQUEST_ID], result.request_ids) class CLITestV20ExceptionHandler(CLITestV20Base): def _test_exception_handler_v20( self, expected_exception, status_code, expected_msg, error_type=None, error_msg=None, error_detail=None, request_id=None, error_content=None): resp = MyResp(status_code, {'x-openstack-request-id': request_id}) if request_id is not None: expected_msg += "\nNeutron server returns " \ "request_ids: %s" % [request_id] if error_content is None: error_content = {'NeutronError': {'type': error_type, 'message': error_msg, 'detail': error_detail}} expected_content = self.client._convert_into_with_meta(error_content, resp) e = self.assertRaises(expected_exception, client.exception_handler_v20, status_code, expected_content) self.assertEqual(status_code, e.status_code) self.assertEqual(expected_exception.__name__, e.__class__.__name__) if expected_msg is None: if error_detail: expected_msg = '\n'.join([error_msg, error_detail]) else: 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, '', REQUEST_ID) 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), ('InvalidIpForNetwork', exceptions.InvalidIpForNetworkClient, 400), ('InvalidIpForSubnet', exceptions.InvalidIpForSubnetClient, 400), ('IpAddressAlreadyAllocated', exceptions.IpAddressAlreadyAllocatedClient, 400), ] 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, REQUEST_ID) 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, REQUEST_ID) def test_exception_handler_v20_unknown_error_to_per_code_exception(self): for status_code, client_exc in exceptions.HTTP_EXCEPTION_MAP.items(): error_msg = 'Unknown error' error_detail = 'This is detail' self._test_exception_handler_v20( client_exc, status_code, error_msg + '\n' + error_detail, 'UnknownError', error_msg, error_detail, [REQUEST_ID]) def test_exception_handler_v20_neutron_unknown_status_code(self): error_msg = 'Unknown error' error_detail = 'This is detail' self._test_exception_handler_v20( exceptions.NeutronClientException, 501, error_msg + '\n' + error_detail, 'UnknownError', error_msg, error_detail, REQUEST_ID) def test_exception_handler_v20_bad_neutron_error(self): for status_code, client_exc in exceptions.HTTP_EXCEPTION_MAP.items(): error_content = {'NeutronError': {'unknown_key': 'UNKNOWN'}} self._test_exception_handler_v20( client_exc, status_code, expected_msg="{'unknown_key': 'UNKNOWN'}", error_content=error_content, request_id=REQUEST_ID) def test_exception_handler_v20_error_dict_contains_message(self): error_content = {'message': 'This is an error message'} for status_code, client_exc in exceptions.HTTP_EXCEPTION_MAP.items(): self._test_exception_handler_v20( client_exc, status_code, expected_msg='This is an error message', error_content=error_content, request_id=REQUEST_ID) def test_exception_handler_v20_error_dict_not_contain_message(self): # 599 is not contained in HTTP_EXCEPTION_MAP. error_content = {'error': 'This is an error message'} expected_msg = '%s-%s' % (599, error_content) self._test_exception_handler_v20( exceptions.NeutronClientException, 599, expected_msg=expected_msg, request_id=None, error_content=error_content) def test_exception_handler_v20_default_fallback(self): # 599 is not contained in HTTP_EXCEPTION_MAP. error_content = 'This is an error message' expected_msg = '%s-%s' % (599, error_content) self._test_exception_handler_v20( exceptions.NeutronClientException, 599, expected_msg=expected_msg, request_id=None, error_content=error_content) def test_exception_status(self): e = exceptions.BadRequest() self.assertEqual(400, e.status_code) e = exceptions.BadRequest(status_code=499) self.assertEqual(499, e.status_code) # SslCertificateValidationError has no explicit status_code, # but should have a 'safe' defined fallback. e = exceptions.SslCertificateValidationError() self.assertIsNotNone(e.status_code) e = exceptions.SslCertificateValidationError(status_code=599) self.assertEqual(599, e.status_code) def test_connection_failed(self): self.mox.StubOutWithMock(self.client.httpclient, 'request') self.client.httpclient.auth_token = 'token' self.client.httpclient.request( end_url('/test'), 'GET', headers=mox.ContainsKeyValue('X-Auth-Token', 'token') ).AndRaise(requests.exceptions.ConnectionError('Connection refused')) self.mox.ReplayAll() error = self.assertRaises(exceptions.ConnectionFailed, self.client.get, '/test') # NB: ConnectionFailed has no explicit status_code, so this # tests that there is a fallback defined. self.assertIsNotNone(error.status_code) self.mox.VerifyAll() self.mox.UnsetStubs() class DictWithMetaTest(base.BaseTestCase): def test_dict_with_meta(self): body = {'test': 'value'} resp = MyResp(200, {'x-openstack-request-id': REQUEST_ID}) obj = client._DictWithMeta(body, resp) self.assertEqual(body, obj) # Check request_ids attribute is added to obj self.assertTrue(hasattr(obj, 'request_ids')) self.assertEqual([REQUEST_ID], obj.request_ids) class TupleWithMetaTest(base.BaseTestCase): def test_tuple_with_meta(self): body = ('test', 'value') resp = MyResp(200, {'x-openstack-request-id': REQUEST_ID}) obj = client._TupleWithMeta(body, resp) self.assertEqual(body, obj) # Check request_ids attribute is added to obj self.assertTrue(hasattr(obj, 'request_ids')) self.assertEqual([REQUEST_ID], obj.request_ids) class StrWithMetaTest(base.BaseTestCase): def test_str_with_meta(self): body = "test_string" resp = MyResp(200, {'x-openstack-request-id': REQUEST_ID}) obj = client._StrWithMeta(body, resp) self.assertEqual(body, obj) # Check request_ids attribute is added to obj self.assertTrue(hasattr(obj, 'request_ids')) self.assertEqual([REQUEST_ID], obj.request_ids) class GeneratorWithMetaTest(base.BaseTestCase): body = {'test': 'value'} resp = MyResp(200, {'x-openstack-request-id': REQUEST_ID}) def _pagination(self, collection, path, **params): obj = client._DictWithMeta(self.body, self.resp) yield obj def test_generator(self): obj = client._GeneratorWithMeta(self._pagination, 'test_collection', 'test_path', test_args='test_args') self.assertEqual(self.body, next(obj)) self.assertTrue(hasattr(obj, 'request_ids')) self.assertEqual([REQUEST_ID], obj.request_ids) class CLITestV20OutputFormatter(CLITestV20Base): def _test_create_resource_with_formatter(self, fmt): resource = 'network' cmd = network.CreateNetwork(MyApp(sys.stdout), None) args = ['-f', fmt, 'myname'] position_names = ['name'] position_values = ['myname'] self._test_create_resource(resource, cmd, 'myname', 'myid', args, position_names, position_values) def test_create_resource_table(self): self._test_create_resource_with_formatter('table') print(self.fake_stdout.content) # table data is contains in the third element. data = self.fake_stdout.content[2].split('\n') self.assertTrue(any(' id ' in d for d in data)) self.assertTrue(any(' name ' in d for d in data)) def test_create_resource_json(self): self._test_create_resource_with_formatter('json') data = json.loads(self.fake_stdout.make_string()) self.assertEqual('myname', data['name']) self.assertEqual('myid', data['id']) def test_create_resource_yaml(self): self._test_create_resource_with_formatter('yaml') data = yaml.load(self.fake_stdout.make_string()) self.assertEqual('myname', data['name']) self.assertEqual('myid', data['id']) def _test_show_resource_with_formatter(self, fmt): resource = 'network' cmd = network.ShowNetwork(MyApp(sys.stdout), None) args = ['-f', fmt, '-F', 'id', '-F', 'name', 'myid'] self._test_show_resource(resource, cmd, 'myid', args, ['id', 'name']) def test_show_resource_table(self): self._test_show_resource_with_formatter('table') data = self.fake_stdout.content[0].split('\n') self.assertTrue(any(' id ' in d for d in data)) self.assertTrue(any(' name ' in d for d in data)) def test_show_resource_json(self): self._test_show_resource_with_formatter('json') data = json.loads(''.join(self.fake_stdout.content)) self.assertEqual('myname', data['name']) self.assertEqual('myid', data['id']) def test_show_resource_yaml(self): self._test_show_resource_with_formatter('yaml') data = yaml.load(''.join(self.fake_stdout.content)) self.assertEqual('myname', data['name']) self.assertEqual('myid', data['id']) def _test_list_resources_with_formatter(self, fmt): resources = 'networks' cmd = network.ListNetwork(MyApp(sys.stdout), None) # ListNetwork has its own extend_list, so we need to stub out it # to avoid an extra API call. self.mox.StubOutWithMock(network.ListNetwork, "extend_list") network.ListNetwork.extend_list(mox.IsA(list), mox.IgnoreArg()) self._test_list_resources(resources, cmd, output_format=fmt) def test_list_resources_table(self): self._test_list_resources_with_formatter('table') data = self.fake_stdout.content[0].split('\n') self.assertTrue(any(' id ' in d for d in data)) self.assertTrue(any(' myid1 ' in d for d in data)) self.assertTrue(any(' myid2 ' in d for d in data)) def test_list_resources_json(self): self._test_list_resources_with_formatter('json') data = json.loads(''.join(self.fake_stdout.content)) self.assertEqual(['myid1', 'myid2'], [d['id'] for d in data]) def test_list_resources_yaml(self): self._test_list_resources_with_formatter('yaml') data = yaml.load(''.join(self.fake_stdout.content)) self.assertEqual(['myid1', 'myid2'], [d['id'] for d in data]) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_metering.py0000666000175100017510000000760113232473350027216 0ustar zuulzuul00000000000000# Copyright (C) 2013 eNovance SAS # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sys from neutronclient.neutron.v2_0 import metering from neutronclient.tests.unit import test_cli20 class CLITestV20MeteringJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['metering_label', 'metering_label_rule'] def test_create_metering_label(self): # Create a metering label. resource = 'metering_label' cmd = metering.CreateMeteringLabel( test_cli20.MyApp(sys.stdout), None) name = 'my label' myid = 'myid' description = 'my description' args = [name, '--description', description, '--shared'] position_names = ['name', 'description', 'shared'] position_values = [name, description, True] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_list_metering_labels(self): resources = "metering_labels" cmd = metering.ListMeteringLabel( test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd) def test_delete_metering_label(self): # Delete a metering label. resource = 'metering_label' cmd = metering.DeleteMeteringLabel( test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) def test_show_metering_label(self): resource = 'metering_label' cmd = metering.ShowMeteringLabel( 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_create_metering_label_rule(self): resource = 'metering_label_rule' cmd = metering.CreateMeteringLabelRule( test_cli20.MyApp(sys.stdout), None) myid = 'myid' metering_label_id = 'aaa' remote_ip_prefix = '10.0.0.0/24' direction = 'ingress' args = [metering_label_id, remote_ip_prefix, '--direction', direction, '--excluded'] position_names = ['metering_label_id', 'remote_ip_prefix', 'direction', 'excluded'] position_values = [metering_label_id, remote_ip_prefix, direction, True] self._test_create_resource(resource, cmd, metering_label_id, myid, args, position_names, position_values) def test_list_metering_label_rules(self): resources = "metering_label_rules" cmd = metering.ListMeteringLabelRule( test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd) def test_delete_metering_label_rule(self): resource = 'metering_label_rule' cmd = metering.DeleteMeteringLabelRule( test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) def test_show_metering_label_rule(self): resource = 'metering_label_rule' cmd = metering.ShowMeteringLabelRule( test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id']) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_purge.py0000666000175100017510000000756613232473350026540 0ustar zuulzuul00000000000000# Copyright 2016 Cisco Systems # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0 import purge from neutronclient.tests.unit import test_cli20 class CLITestV20Purge(test_cli20.CLITestV20Base): def setUp(self): super(CLITestV20Purge, self).setUp() self.resource_types = ['floatingip', 'port', 'router', 'network', 'security_group'] def _generate_resources_dict(self, value=0): resources_dict = {} resources_dict['true'] = value for resource_type in self.resource_types: resources_dict[resource_type] = value return resources_dict def _verify_suffix(self, resources, message): for resource, value in resources.items(): if value > 0: suffix = list('%(value)d %(resource)s' % {'value': value, 'resource': resource}) if value != 1: suffix.append('s') suffix = ''.join(suffix) self.assertIn(suffix, message) else: self.assertNotIn(resource, message) def _verify_message(self, message, deleted, failed): message = message.split('.') success_prefix = "Deleted " failure_prefix = "The following resources could not be deleted: " if not deleted['true']: for msg in message: self.assertNotIn(success_prefix, msg) message = message[0] if not failed['true']: expected = 'Tenant has no supported resources' self.assertEqual(expected, message) else: self.assertIn(failure_prefix, message) self._verify_suffix(failed, message) else: resources_deleted = message[0] self.assertIn(success_prefix, resources_deleted) self._verify_suffix(deleted, resources_deleted) if failed['true']: resources_failed = message[1] self.assertIn(failure_prefix, resources_failed) self._verify_suffix(failed, resources_failed) else: for msg in message: self.assertNotIn(failure_prefix, msg) def _verify_result(self, my_purge, deleted, failed): message = my_purge._build_message(deleted, failed, failed['true']) self._verify_message(message, deleted, failed) def test_build_message(self): my_purge = purge.Purge(test_cli20.MyApp(sys.stdout), None) # Verify message when tenant has no supported resources deleted = self._generate_resources_dict() failed = self._generate_resources_dict() self._verify_result(my_purge, deleted, failed) # Verify message when tenant has supported resources, # and they are all deleteable deleted = self._generate_resources_dict(1) self._verify_result(my_purge, deleted, failed) # Verify message when tenant has supported resources, # and some are not deleteable failed = self._generate_resources_dict(1) self._verify_result(my_purge, deleted, failed) # Verify message when tenant has supported resources, # and all are not deleteable deleted = self._generate_resources_dict() self._verify_result(my_purge, deleted, failed) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/0000775000175100017510000000000013232473710023560 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/0000775000175100017510000000000013232473710024107 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/logging/0000775000175100017510000000000013232473710025535 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/logging/fakes.py0000666000175100017510000000465513232473350027214 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import collections import copy import uuid import mock class FakeLogging(object): def create(self, attrs={}): """Create a fake network logs :param Dictionary attrs: A dictionary with all attributes :return: A OrderedDict faking the network log """ self.ordered.update(attrs) return copy.deepcopy(self.ordered) def bulk_create(self, attrs=None, count=2): """Create multiple fake network logs :param Dictionary attrs: A dictionary with all attributes :param int count: The number of network logs to fake :return: A list of dictionaries faking the network logs """ return [self.create(attrs=attrs) for i in range(0, count)] def get(self, attrs=None, count=2): """Create multiple fake network logs :param Dictionary attrs: A dictionary with all attributes :param int count: The number of network logs to fake :return: A list of dictionaries faking the network log """ if attrs is None: self.attrs = self.bulk_create(count=count) return mock.Mock(side_effect=attrs) class NetworkLog(FakeLogging): """Fake one or more network log""" def __init__(self): super(NetworkLog, self).__init__() self.ordered = collections.OrderedDict(( ('id', 'log-id-' + uuid.uuid4().hex), ('description', 'my-desc-' + uuid.uuid4().hex), ('enabled', False), ('name', 'my-log-' + uuid.uuid4().hex), ('target_id', None), ('project_id', 'project-id-' + uuid.uuid4().hex), ('resource_id', None), ('resource_type', 'security_group'), ('event', 'all'), )) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/logging/test_network_log.py0000666000175100017510000005455113232473350031514 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy import mock from osc_lib import exceptions from osc_lib.tests import utils import testtools from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.logging import network_log from neutronclient.tests.unit.osc.v2 import fakes as test_fakes from neutronclient.tests.unit.osc.v2.logging import fakes _log = fakes.NetworkLog().create() RES_TYPE_SG = 'security_group' CONVERT_MAP = { 'project': 'project_id', 'enable': 'enabled', 'disable': 'enabled', 'target': 'target_id', 'resource': 'resource_id', 'event': 'event', } def _generate_data(ordered_dict=None, data=None): source = ordered_dict if ordered_dict else _log if data: source.update(data) return tuple(source[key] for key in source) def _generate_req_and_res(verifylist): request = dict(verifylist) response = copy.deepcopy(_log) for key, val in verifylist: converted = CONVERT_MAP.get(key, key) del request[key] if key == 'enable' and val: new_value = True elif key == 'disable' and val: new_value = False else: new_value = val request[converted] = new_value response[converted] = new_value return request, response class TestNetworkLog(test_fakes.TestNeutronClientOSCV2): def check_results(self, headers, data, exp_req, is_list=False): if is_list: req_body = {'logs': [exp_req]} else: req_body = {'log': exp_req} self.mocked.assert_called_once_with(req_body) self.assertEqual(self.ordered_headers, headers) self.assertEqual(self.ordered_data, data) def setUp(self): super(TestNetworkLog, self).setUp() self.neutronclient.find_resource = mock.Mock() self.neutronclient.find_resource.side_effect = \ lambda x, y, **k: {'id': y} osc_utils.find_project = mock.Mock() osc_utils.find_project.id = _log['project_id'] self.res = _log self.headers = ( 'ID', 'Description', 'Enabled', 'Name', 'Target', 'Project', 'Resource', 'Type', 'Event', ) self.data = _generate_data() self.ordered_headers = ( 'Description', 'Enabled', 'Event', 'ID', 'Name', 'Project', 'Resource', 'Target', 'Type', ) self.ordered_data = ( _log['description'], _log['enabled'], _log['event'], _log['id'], _log['name'], _log['project_id'], _log['resource_id'], _log['target_id'], _log['resource_type'], ) self.ordered_columns = ( 'description', 'enabled', 'event', 'id', 'name', 'project_id', 'resource_id', 'target_id', 'resource_type', ) class TestCreateNetworkLog(TestNetworkLog): def setUp(self): super(TestCreateNetworkLog, self).setUp() self.neutronclient.create_network_log = mock.Mock( return_value={'log': _log}) self.mocked = self.neutronclient.create_network_log self.cmd = network_log.CreateNetworkLog(self.app, self.namespace) def _update_expect_response(self, request, response): """Set expected request and response :param request A dictionary of request body(dict of verifylist) :param response A OrderedDict of request body """ # Update response body self.neutronclient.create_network_log.return_value = \ {'log': dict(response)} osc_utils.find_project.return_value.id = response['project_id'] # Update response(finally returns 'data') self.data = _generate_data(ordered_dict=response) self.ordered_data = tuple( response[column] for column in self.ordered_columns ) def _set_all_params(self, args={}): name = args.get('name', 'my-log') desc = args.get('description', 'my-description-for-log') event = args.get('event', 'ACCEPT') resource = args.get('resource', 'id-target-log') target = args.get('target', 'id-target-log') resource_type = args.get('resource_type', 'security_group') project = args.get('project_id', 'id-my-project') arglist = [ name, '--description', desc, '--enable', '--target', target, '--resource', resource, '--event', event, '--project', project, '--resource-type', resource_type, ] verifylist = [ ('description', desc), ('enable', True), ('event', event), ('name', name), ('target', target), ('project', project), ('resource', target), ('resource_type', resource_type), ] return arglist, verifylist def _test_create_with_all_params(self, args={}): arglist, verifylist = self._set_all_params(args) request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.check_results(headers, data, request) def test_create_with_no_options_and_raise(self): arglist = [] verifylist = [] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_mandatory_params(self): name = self.res['name'] arglist = [ name, '--resource-type', RES_TYPE_SG, ] verifylist = [ ('name', name), ('resource_type', RES_TYPE_SG), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) expect = { 'name': self.res['name'], 'resource_type': self.res['resource_type'], } self.mocked.assert_called_once_with({'log': expect}) self.assertEqual(self.ordered_headers, headers) self.assertEqual(self.ordered_data, data) def test_create_with_disable(self): name = self.res['name'] arglist = [ name, '--resource-type', RES_TYPE_SG, '--disable', ] verifylist = [ ('name', name), ('resource_type', RES_TYPE_SG), ('disable', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) expect = { 'name': self.res['name'], 'resource_type': self.res['resource_type'], 'enabled': False, } self.mocked.assert_called_once_with({'log': expect}) self.assertEqual(self.ordered_headers, headers) self.assertEqual(self.ordered_data, data) def test_create_with_all_params(self): self._test_create_with_all_params() def test_create_with_all_params_event_drop(self): self._test_create_with_all_params({'event': 'DROP'}) def test_create_with_all_params_event_all(self): self._test_create_with_all_params({'event': 'ALL'}) def test_create_with_all_params_except_event(self): arglist, verifylist = self._set_all_params({'event': ''}) self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_all_params_event_upper_capitalized(self): for event in ('all', 'All', 'dROP', 'accePt', 'accept', 'drop'): arglist, verifylist = self._set_all_params({'event': event}) self.assertRaises( testtools.matchers._impl.MismatchError, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_all_params_resource_type_upper_capitalized(self): for res_type in ('SECURITY_GROUP', 'Security_group', 'security_Group'): arglist, verifylist = self._set_all_params( {'resource_type': res_type}) self.assertRaises( testtools.matchers._impl.MismatchError, self.check_parser, self.cmd, arglist, verifylist) class TestListNetworkLog(TestNetworkLog): def _setup_summary(self, expect=None): event = 'Event: ' + self.res['event'].upper() target = 'Logged: (None specified)' if expect: if expect.get('event'): event = expect['event'] if expect.get('resource'): target = expect['resource'] summary = ',\n'.join([event, target]) self.short_data = ( expect['id'] if expect else self.res['id'], expect['enabled'] if expect else self.res['enabled'], expect['name'] if expect else self.res['name'], expect['resource_type'] if expect else self.res['resource_type'], summary ) def setUp(self): super(TestListNetworkLog, self).setUp() self.cmd = network_log.ListNetworkLog(self.app, self.namespace) self.short_header = ( 'ID', 'Enabled', 'Name', 'Type', 'Summary', ) self._setup_summary() self.neutronclient.list_network_logs = mock.Mock( return_value={'logs': [self.res]}) self.mocked = self.neutronclient.list_network_logs def test_list_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.headers), headers) self.assertEqual([self.data], list(data)) def test_list_with_no_option(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.short_header), headers) self.assertEqual([self.short_data], list(data)) def test_list_with_target_and_resource(self): arglist = [] verifylist = [] target_id = 'aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaaaaaaa' resource_id = 'bbbbbbbb-bbbb-bbbb-bbbbbbbbbbbbbbbbb' log = fakes.NetworkLog().create({ 'target_id': target_id, 'resource_id': resource_id}) self.mocked.return_value = {'logs': [log]} logged = 'Logged: (security_group) %(res_id)s on (port) %(t_id)s' % { 'res_id': resource_id, 't_id': target_id} expect_log = copy.deepcopy(log) expect_log.update({ 'resource': logged, 'event': 'Event: ALL'}) self._setup_summary(expect=expect_log) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.short_header), headers) self.assertEqual([self.short_data], list(data)) def test_list_with_resource(self): arglist = [] verifylist = [] resource_id = 'bbbbbbbb-bbbb-bbbb-bbbbbbbbbbbbbbbbb' log = fakes.NetworkLog().create({'resource_id': resource_id}) self.mocked.return_value = {'logs': [log]} logged = 'Logged: (security_group) %s' % resource_id expect_log = copy.deepcopy(log) expect_log.update({ 'resource': logged, 'event': 'Event: ALL'}) self._setup_summary(expect=expect_log) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.short_header), headers) self.assertEqual([self.short_data], list(data)) def test_list_with_target(self): arglist = [] verifylist = [] target_id = 'aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaaaaaaa' log = fakes.NetworkLog().create({'target_id': target_id}) self.mocked.return_value = {'logs': [log]} logged = 'Logged: (port) %s' % target_id expect_log = copy.deepcopy(log) expect_log.update({ 'resource': logged, 'event': 'Event: ALL'}) self._setup_summary(expect=expect_log) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.short_header), headers) self.assertEqual([self.short_data], list(data)) class TestShowNetworkLog(TestNetworkLog): def setUp(self): super(TestShowNetworkLog, self).setUp() self.neutronclient.show_network_log = mock.Mock( return_value={'log': self.res}) self.mocked = self.neutronclient.show_network_log self.cmd = network_log.ShowNetworkLog(self.app, self.namespace) def test_show_filtered_by_id_or_name(self): target = self.res['id'] arglist = [target] verifylist = [('network_log', target)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with(target) self.assertEqual(self.ordered_headers, headers) self.assertEqual(self.ordered_data, data) class TestSetNetworkLog(TestNetworkLog): def setUp(self): super(TestSetNetworkLog, self).setUp() self.neutronclient.update_network_log = mock.Mock( return_value={'log': self.res}) self.mocked = self.neutronclient.update_network_log self.cmd = network_log.SetNetworkLog(self.app, self.namespace) def test_set_name(self): target = self.res['id'] update = 'change' arglist = [target, '--name', update] verifylist = [ ('network_log', target), ('name', update), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {'log': {'name': update}}) self.assertIsNone(result) def test_set_description(self): target = self.res['id'] update = 'change-desc' arglist = [target, '--description', update] verifylist = [ ('network_log', target), ('description', update), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {'log': {'description': update}}) self.assertIsNone(result) def test_set_enable(self): target = self.res['id'] arglist = [target, '--enable'] verifylist = [ ('network_log', target), ('enable', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {'log': {'enabled': True}}) self.assertIsNone(result) def test_set_disable(self): target = self.res['id'] arglist = [target, '--disable'] verifylist = [ ('network_log', target), ('disable', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {'log': {'enabled': False}}) self.assertIsNone(result) # Illegal tests def test_illegal_set_resource_type(self): target = self.res['id'] resource_type = 'security_group' arglist = [target, '--resource-type', resource_type] verifylist = [ ('network_log', target), ('resource_type', resource_type), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_illegal_set_event(self): target = self.res['id'] for event in ['all', 'accept', 'drop']: arglist = [target, '--event', event] verifylist = [ ('network_log', target), ('event', event), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_illegal_set_resource_id(self): target = self.res['id'] resource_id = 'resource-id-for-logged-target' arglist = [target, '--resource', resource_id] verifylist = [ ('network_log', target), ('resource', resource_id), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_illegal_set_project(self): target = self.res['id'] arglist = [ target, '--project', ] verifylist = [ ('network_log', target), ('project', 'other-project'), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_illegal_set_project_domain(self): target = self.res['id'] arglist = [ target, '--project-domain', ] verifylist = [ ('network_log', target), ('project_domain', 'other-project-domain'), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_illegal_set_and_raises(self): self.neutronclient.update_network_log = mock.Mock( side_effect=Exception) target = self.res['id'] arglist = [target, '--name', 'my-name'] verifylist = [('network_log', target), ('name', 'my-name')] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args) class TestDeleteNetworkLog(TestNetworkLog): def setUp(self): super(TestDeleteNetworkLog, self).setUp() self.neutronclient.delete_network_log = mock.Mock( return_value={'log': self.res}) self.mocked = self.neutronclient.delete_network_log self.cmd = network_log.DeleteNetworkLog(self.app, self.namespace) def test_delete_with_one_resource(self): target = self.res['id'] arglist = [target] verifylist = [('network_log', [target])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with(target) self.assertIsNone(result) def test_delete_with_multiple_resources(self): target1 = 'target1' target2 = 'target2' arglist = [target1, target2] verifylist = [('network_log', [target1, target2])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.assertIsNone(result) self.assertEqual(2, self.mocked.call_count) for idx, reference in enumerate([target1, target2]): actual = ''.join(self.mocked.call_args_list[idx][0]) self.assertEqual(reference, actual) def test_delete_with_no_exist_id(self): self.neutronclient.find_resource.side_effect = Exception target = 'not_exist' arglist = [target] verifylist = [('network_log', [target])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args) class TestLoggableResource(test_fakes.TestNeutronClientOSCV2): def check_results(self, headers, data, exp_req, is_list=False): if is_list: req_body = {'logs': [exp_req]} else: req_body = {'log': exp_req} self.mocked.assert_called_once_with(req_body) self.assertEqual(self.ordered_headers, headers) self.assertEqual(self.ordered_data, data) def setUp(self): super(TestLoggableResource, self).setUp() self.headers = ('Supported types',) self.data = ('security_group', ) class TestListLoggableResource(TestLoggableResource): def setUp(self): super(TestListLoggableResource, self).setUp() self.cmd = network_log.ListLoggableResource(self.app, self.namespace) loggables = { "loggable_resources": [{"type": "security_group"}] } self.neutronclient.list_network_loggable_resources = mock.Mock( return_value=loggables) self.mocked = self.neutronclient.list_network_loggable_resources def test_list_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.headers), headers) self.assertEqual([self.data], list(data)) def test_list_with_no_option(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.headers), headers) self.assertEqual([self.data], list(data)) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/logging/__init__.py0000666000175100017510000000000013232473350027636 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/sfc/0000775000175100017510000000000013232473710024662 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/sfc/test_port_pair.py0000777000175100017510000002611713232473350030306 0ustar zuulzuul00000000000000# Copyright (c) 2017 Huawei Technologies India Pvt.Limited. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import mock from neutronclient.osc.v2.sfc import sfc_port_pair from neutronclient.tests.unit.osc.v2.sfc import fakes def _get_id(client, id_or_name, resource): return id_or_name class TestCreateSfcPortPair(fakes.TestNeutronClientOSCV2): # The new port_pair created _port_pair = fakes.FakeSfcPortPair.create_port_pair() columns = ('Description', 'Egress Logical Port', 'ID', 'Ingress Logical Port', 'Name', 'Project', 'Service Function Parameters') def get_data(self): return ( self._port_pair['description'], self._port_pair['egress'], self._port_pair['id'], self._port_pair['ingress'], self._port_pair['name'], self._port_pair['project_id'], self._port_pair['service_function_parameters'] ) def setUp(self): super(TestCreateSfcPortPair, self).setUp() mock.patch('neutronclient.osc.v2.sfc.sfc_port_pair._get_id', new=_get_id).start() self.neutronclient.create_sfc_port_pair = mock.Mock( return_value={'port_pair': self._port_pair}) self.data = self.get_data() # Get the command object to test self.cmd = sfc_port_pair.CreateSfcPortPair(self.app, self.namespace) def test_create_port_pair_default_options(self): arglist = [ "--ingress", self._port_pair['ingress'], "--egress", self._port_pair['egress'], self._port_pair['name'], ] verifylist = [ ('ingress', self._port_pair['ingress']), ('egress', self._port_pair['egress']), ('name', self._port_pair['name']) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) self.neutronclient.create_sfc_port_pair.assert_called_once_with({ 'port_pair': {'name': self._port_pair['name'], 'ingress': self._port_pair['ingress'], 'egress': self._port_pair['egress'], } }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def _test_create_port_pair_all_options(self, correlation): arglist = [ "--description", self._port_pair['description'], "--egress", self._port_pair['egress'], "--ingress", self._port_pair['ingress'], self._port_pair['name'], "--service-function-parameters", 'correlation=%s,weight=1' % correlation, ] verifylist = [ ('ingress', self._port_pair['ingress']), ('egress', self._port_pair['egress']), ('name', self._port_pair['name']), ('description', self._port_pair['description']), ('service_function_parameters', [{'correlation': correlation, 'weight': '1'}]) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) if correlation == "None": correlation_param = None else: correlation_param = correlation self.neutronclient.create_sfc_port_pair.assert_called_once_with({ 'port_pair': {'name': self._port_pair['name'], 'ingress': self._port_pair['ingress'], 'egress': self._port_pair['egress'], 'description': self._port_pair['description'], 'service_function_parameters': {'correlation': correlation_param, 'weight': '1'}, } }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_create_port_pair_all_options(self): self._test_create_port_pair_all_options('None') def test_create_port_pair_all_options_mpls(self): self._test_create_port_pair_all_options('mpls') class TestDeleteSfcPortPair(fakes.TestNeutronClientOSCV2): _port_pair = fakes.FakeSfcPortPair.create_port_pairs(count=1) def setUp(self): super(TestDeleteSfcPortPair, self).setUp() mock.patch('neutronclient.osc.v2.sfc.sfc_port_pair._get_id', new=_get_id).start() self.neutronclient.delete_sfc_port_pair = mock.Mock(return_value=None) self.cmd = sfc_port_pair.DeleteSfcPortPair(self.app, self.namespace) def test_delete_port_pair(self): client = self.app.client_manager.neutronclient mock_port_pair_delete = client.delete_sfc_port_pair arglist = [ self._port_pair[0]['id'], ] verifylist = [ ('port_pair', self._port_pair[0]['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) mock_port_pair_delete.assert_called_once_with( self._port_pair[0]['id']) self.assertIsNone(result) class TestListSfcPortPair(fakes.TestNeutronClientOSCV2): _port_pairs = fakes.FakeSfcPortPair.create_port_pairs() columns = ('ID', 'Name', 'Ingress Logical Port', 'Egress Logical Port') columns_long = ('ID', 'Name', 'Ingress Logical Port', 'Egress Logical Port', 'Service Function Parameters', 'Description', 'Project') _port_pair = _port_pairs[0] data = [ _port_pair['id'], _port_pair['name'], _port_pair['ingress'], _port_pair['egress'] ] data_long = [ _port_pair['id'], _port_pair['name'], _port_pair['ingress'], _port_pair['egress'], _port_pair['service_function_parameters'], _port_pair['description'] ] _port_pair1 = {'port_pairs': _port_pair} _port_pair_id = _port_pair['id'], def setUp(self): super(TestListSfcPortPair, self).setUp() mock.patch('neutronclient.osc.v2.sfc.sfc_port_pair._get_id', new=_get_id).start() self.neutronclient.list_sfc_port_pairs = mock.Mock( return_value={'port_pairs': self._port_pairs} ) # Get the command object to test self.cmd = sfc_port_pair.ListSfcPortPair(self.app, self.namespace) def test_list_port_pairs(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns = self.cmd.take_action(parsed_args)[0] port_pairs = self.neutronclient.list_sfc_port_pairs()['port_pairs'] port_pair = port_pairs[0] data = [ port_pair['id'], port_pair['name'], port_pair['ingress'], port_pair['egress'] ] self.assertEqual(list(self.columns), columns) self.assertEqual(self.data, data) def test_list_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] port_pairs = self.neutronclient.list_sfc_port_pairs()['port_pairs'] port_pair = port_pairs[0] data = [ port_pair['id'], port_pair['name'], port_pair['ingress'], port_pair['egress'], port_pair['service_function_parameters'], port_pair['description'] ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns_long = self.cmd.take_action(parsed_args)[0] self.assertEqual(list(self.columns_long), columns_long) self.assertEqual(self.data_long, data) class TestSetSfcPortPair(fakes.TestNeutronClientOSCV2): _port_pair = fakes.FakeSfcPortPair.create_port_pair() _port_pair_name = _port_pair['name'] _port_pair_id = _port_pair['id'] def setUp(self): super(TestSetSfcPortPair, self).setUp() mock.patch('neutronclient.osc.v2.sfc.sfc_port_pair._get_id', new=_get_id).start() self.neutronclient.update_sfc_port_pair = mock.Mock(return_value=None) self.cmd = sfc_port_pair.SetSfcPortPair(self.app, self.namespace) def test_set_port_pair(self): client = self.app.client_manager.neutronclient mock_port_pair_update = client.update_sfc_port_pair arglist = [ self._port_pair_name, '--name', 'name_updated', '--description', 'desc_updated' ] verifylist = [ ('port_pair', self._port_pair_name), ('name', 'name_updated'), ('description', 'desc_updated'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = {'port_pair': { 'name': 'name_updated', 'description': 'desc_updated'} } mock_port_pair_update.assert_called_once_with(self._port_pair_name, attrs) self.assertIsNone(result) class TestShowSfcPortPair(fakes.TestNeutronClientOSCV2): _pp = fakes.FakeSfcPortPair.create_port_pair() data = ( _pp['description'], _pp['egress'], _pp['id'], _pp['ingress'], _pp['name'], _pp['project_id'], _pp['service_function_parameters'], ) _port_pair = {'port_pair': _pp} _port_pair_id = _pp['id'] columns = ( 'Description', 'Egress Logical Port', 'ID', 'Ingress Logical Port', 'Name', 'Project', 'Service Function Parameters' ) def setUp(self): super(TestShowSfcPortPair, self).setUp() mock.patch('neutronclient.osc.v2.sfc.sfc_port_pair._get_id', new=_get_id).start() self.neutronclient.show_sfc_port_pair = mock.Mock( return_value=self._port_pair ) # Get the command object to test self.cmd = sfc_port_pair.ShowSfcPortPair(self.app, self.namespace) def test_show_port_pair(self): client = self.app.client_manager.neutronclient mock_port_pair_show = client.show_sfc_port_pair arglist = [ self._port_pair_id, ] verifylist = [ ('port_pair', self._port_pair_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) mock_port_pair_show.assert_called_once_with(self._port_pair_id) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/sfc/fakes.py0000777000175100017510000002161713232473350026341 0ustar zuulzuul00000000000000# Copyright (c) 2017 Huawei Technologies India Pvt.Limited. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import argparse import copy import mock from osc_lib.tests import utils from oslo_utils import uuidutils class TestNeutronClientOSCV2(utils.TestCommand): def setUp(self): super(TestNeutronClientOSCV2, self).setUp() self.namespace = argparse.Namespace() self.app.client_manager.session = mock.Mock() self.app.client_manager.neutronclient = mock.Mock() self.neutronclient = self.app.client_manager.neutronclient self.neutronclient.find_resource = mock.Mock( side_effect=lambda resource, name_or_id, project_id=None, cmd_resource=None, parent_id=None, fields=None: {'id': name_or_id}) class FakeSfcPortPair(object): """Fake port pair attributes.""" @staticmethod def create_port_pair(attrs=None): """Create a fake port pair. :param Dictionary attrs: A dictionary with all attributes :return: A Dictionary with id, name, description, ingress, egress, service-function-parameter, project_id """ attrs = attrs or {} # Set default attributes. port_pair_attrs = { 'description': 'description', 'egress': uuidutils.generate_uuid(), 'id': uuidutils.generate_uuid(), 'ingress': uuidutils.generate_uuid(), 'name': 'port-pair-name', 'service_function_parameters': 'correlation=None,weight=1', 'project_id': uuidutils.generate_uuid(), } # Overwrite default attributes. port_pair_attrs.update(attrs) return copy.deepcopy(port_pair_attrs) @staticmethod def create_port_pairs(attrs=None, count=1): """Create multiple port_pairs. :param Dictionary attrs: A dictionary with all attributes :param int count: The number of port_pairs to fake :return: A list of dictionaries faking the port_pairs """ port_pairs = [] for _ in range(count): port_pairs.append(FakeSfcPortPair.create_port_pair(attrs)) return port_pairs class FakeSfcPortPairGroup(object): """Fake port pair group attributes.""" @staticmethod def create_port_pair_group(attrs=None): """Create a fake port pair group. :param Dictionary attrs: A dictionary with all attributes :return: A Dictionary with id, name, description, port_pairs, group_id port_pair_group_parameters, project_id """ attrs = attrs or {} # Set default attributes. port_pair_group_attrs = { 'id': uuidutils.generate_uuid(), 'group_id': uuidutils.generate_uuid(), 'name': 'port-pair-group-name', 'description': 'description', 'port_pairs': uuidutils.generate_uuid(), 'port_pair_group_parameters': '{"lb_fields": []}', 'project_id': uuidutils.generate_uuid(), 'tap_enabled': False } # port_pair_group_attrs default attributes. port_pair_group_attrs.update(attrs) return copy.deepcopy(port_pair_group_attrs) @staticmethod def create_port_pair_groups(attrs=None, count=1): """Create multiple port pair groups. :param Dictionary attrs: A dictionary with all attributes :param int count: The number of port_pair_groups to fake :return: A list of dictionaries faking the port pair groups """ port_pair_groups = [] for _ in range(count): port_pair_groups.append( FakeSfcPortPairGroup.create_port_pair_group(attrs)) return port_pair_groups class FakeSfcFlowClassifier(object): """Fake flow classifier attributes.""" @staticmethod def create_flow_classifier(attrs=None): """Create a fake flow classifier. :param Dictionary attrs: A dictionary with all attributes :return: A Dictionary with faking port chain attributes """ attrs = attrs or {} # Set default attributes. flow_classifier_attrs = { 'id': uuidutils.generate_uuid(), 'destination_ip_prefix': '2.2.2.2/32', 'destination_port_range_max': '90', 'destination_port_range_min': '80', 'ethertype': 'IPv4', 'logical_destination_port': uuidutils.generate_uuid(), 'logical_source_port': uuidutils.generate_uuid(), 'name': 'flow-classifier-name', 'description': 'fc_description', 'protocol': 'tcp', 'source_ip_prefix': '1.1.1.1/32', 'source_port_range_max': '20', 'source_port_range_min': '10', 'project_id': uuidutils.generate_uuid(), 'l7_parameters': '{}' } flow_classifier_attrs.update(attrs) return copy.deepcopy(flow_classifier_attrs) @staticmethod def create_flow_classifiers(attrs=None, count=1): """Create multiple flow classifiers. :param Dictionary attrs: A dictionary with all attributes :param int count: The number of flow classifiers to fake :return: A list of dictionaries faking the flow classifiers """ flow_classifiers = [] for _ in range(count): flow_classifiers.append( FakeSfcFlowClassifier.create_flow_classifier(attrs)) return flow_classifiers class FakeSfcPortChain(object): """Fake port chain attributes.""" @staticmethod def create_port_chain(attrs=None): """Create a fake port chain. :param Dictionary attrs: A dictionary with all attributes :return: A Dictionary with faking port chain attributes """ attrs = attrs or {} # Set default attributes. port_chain_attrs = { 'id': uuidutils.generate_uuid(), 'chain_id': uuidutils.generate_uuid(), 'name': 'port-chain-name', 'description': 'description', 'port_pair_groups': uuidutils.generate_uuid(), 'flow_classifiers': uuidutils.generate_uuid(), 'chain_parameters': '{"correlation": mpls}', 'project_id': uuidutils.generate_uuid(), } # port_pair_group_attrs default attributes. port_chain_attrs.update(attrs) return copy.deepcopy(port_chain_attrs) @staticmethod def create_port_chains(attrs=None, count=1): """Create multiple port chains. :param Dictionary attrs: A dictionary with all attributes :param int count: The number of port chains to fake :return: A list of dictionaries faking the port chains. """ port_chains = [] for _ in range(count): port_chains.append(FakeSfcPortChain.create_port_chain(attrs)) return port_chains class FakeSfcServiceGraph(object): """Fake service graph attributes.""" @staticmethod def create_sfc_service_graph(attrs=None): """Create a fake service graph. :param Dictionary attrs: A dictionary with all attributes :return: A Dictionary with faking service graph attributes """ attrs = attrs or {} # Set default attributes. service_graph_attrs = { 'id': uuidutils.generate_uuid(), 'name': 'port-pair-group-name', 'description': 'description', 'port_chains': {uuidutils.generate_uuid(): [ uuidutils.generate_uuid()]}, 'project_id': uuidutils.generate_uuid(), } service_graph_attrs.update(attrs) return copy.deepcopy(service_graph_attrs) @staticmethod def create_sfc_service_graphs(attrs=None, count=1): """Create multiple service graphs. :param Dictionary attrs: A dictionary with all attributes :param int count: The number of service graphs to fake :return: A list of dictionaries faking the service graphs. """ service_graphs = [] for _ in range(count): service_graphs.append( FakeSfcServiceGraph.create_sfc_service_graph(attrs)) return service_graphs python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/sfc/test_port_chain.py0000777000175100017510000005174513232473350030442 0ustar zuulzuul00000000000000# Copyright (c) 2017 Huawei Technologies India Pvt.Limited. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import mock from osc_lib import exceptions from neutronclient.osc.v2.sfc import sfc_port_chain from neutronclient.tests.unit.osc.v2.sfc import fakes def _get_id(client, id_or_name, resource): return id_or_name class TestCreateSfcPortChain(fakes.TestNeutronClientOSCV2): # The new port_chain created _port_chain = fakes.FakeSfcPortChain.create_port_chain() columns = ('Chain ID', 'Chain Parameters', 'Description', 'Flow Classifiers', 'ID', 'Name', 'Port Pair Groups', 'Project') def get_data(self): return ( self._port_chain['chain_id'], self._port_chain['chain_parameters'], self._port_chain['description'], self._port_chain['flow_classifiers'], self._port_chain['id'], self._port_chain['name'], self._port_chain['port_pair_groups'], self._port_chain['project_id'], ) def setUp(self): super(TestCreateSfcPortChain, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_port_chain._get_id', new=_get_id).start() self.neutronclient.create_sfc_port_chain = mock.Mock( return_value={'port_chain': self._port_chain}) self.data = self.get_data() # Get the command object to test self.cmd = sfc_port_chain.CreateSfcPortChain(self.app, self.namespace) def test_create_port_chain_default_options(self): arglist = [ self._port_chain['name'], "--port-pair-group", self._port_chain['port_pair_groups'] ] verifylist = [ ('name', self._port_chain['name']), ('port_pair_groups', [self._port_chain['port_pair_groups']]), ('flow_classifiers', []), ('chain_parameters', None), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) self.neutronclient.create_sfc_port_chain.assert_called_once_with({ 'port_chain': { 'name': self._port_chain['name'], 'port_pair_groups': [self._port_chain['port_pair_groups']]} }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_create_port_chain_all_options(self): arglist = [ "--description", self._port_chain['description'], "--port-pair-group", self._port_chain['port_pair_groups'], self._port_chain['name'], "--flow-classifier", self._port_chain['flow_classifiers'], "--chain-parameters", 'correlation=mpls,symmetric=true', ] cp = {'correlation': 'mpls', 'symmetric': 'true'} verifylist = [ ('port_pair_groups', [self._port_chain['port_pair_groups']]), ('name', self._port_chain['name']), ('description', self._port_chain['description']), ('flow_classifiers', [self._port_chain['flow_classifiers']]), ('chain_parameters', [cp]) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) self.neutronclient.create_sfc_port_chain.assert_called_once_with({ 'port_chain': { 'name': self._port_chain['name'], 'port_pair_groups': [self._port_chain['port_pair_groups']], 'description': self._port_chain['description'], 'flow_classifiers': [self._port_chain['flow_classifiers']], 'chain_parameters': cp } }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) class TestDeleteSfcPortChain(fakes.TestNeutronClientOSCV2): _port_chain = fakes.FakeSfcPortChain.create_port_chains(count=1) def setUp(self): super(TestDeleteSfcPortChain, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_port_chain._get_id', new=_get_id).start() self.neutronclient.delete_sfc_port_chain = mock.Mock(return_value=None) self.cmd = sfc_port_chain.DeleteSfcPortChain(self.app, self.namespace) def test_delete_port_chain(self): client = self.app.client_manager.neutronclient mock_port_chain_delete = client.delete_sfc_port_chain arglist = [ self._port_chain[0]['id'], ] verifylist = [ ('port_chain', self._port_chain[0]['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) mock_port_chain_delete.assert_called_once_with( self._port_chain[0]['id']) self.assertIsNone(result) class TestListSfcPortChain(fakes.TestNeutronClientOSCV2): _port_chains = fakes.FakeSfcPortChain.create_port_chains(count=1) columns = ('ID', 'Name', 'Port Pair Groups', 'Flow Classifiers', 'Chain Parameters', 'Chain ID') columns_long = ('ID', 'Name', 'Port Pair Groups', 'Flow Classifiers', 'Chain Parameters', 'Description', 'Chain ID', 'Project') _port_chain = _port_chains[0] data = [ _port_chain['id'], _port_chain['name'], _port_chain['port_pair_groups'], _port_chain['flow_classifiers'], _port_chain['chain_parameters'], _port_chain['chain_id'] ] data_long = [ _port_chain['id'], _port_chain['name'], _port_chain['project_id'], _port_chain['chain_id'], _port_chain['port_pair_groups'], _port_chain['flow_classifiers'], _port_chain['chain_parameters'], _port_chain['description'] ] _port_chain1 = {'port_chains': _port_chain} _port_chain_id = _port_chain['id'] def setUp(self): super(TestListSfcPortChain, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_port_chain._get_id', new=_get_id).start() self.neutronclient.list_sfc_port_chains = mock.Mock( return_value={'port_chains': self._port_chains} ) # Get the command object to test self.cmd = sfc_port_chain.ListSfcPortChain(self.app, self.namespace) def test_list_port_chains(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns = self.cmd.take_action(parsed_args)[0] pcs = self.neutronclient.list_sfc_port_chains()['port_chains'] pc = pcs[0] data = [ pc['id'], pc['name'], pc['port_pair_groups'], pc['flow_classifiers'], pc['chain_parameters'], pc['chain_id'] ] self.assertEqual(list(self.columns), columns) self.assertEqual(self.data, data) def test_list_port_chain_with_long_opion(self): arglist = ['--long'] verifylist = [('long', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns = self.cmd.take_action(parsed_args)[0] pcs = self.neutronclient.list_sfc_port_chains()['port_chains'] pc = pcs[0] data = [ pc['id'], pc['name'], pc['project_id'], pc['chain_id'], pc['port_pair_groups'], pc['flow_classifiers'], pc['chain_parameters'], pc['description'] ] self.assertEqual(list(self.columns_long), columns) self.assertEqual(self.data_long, data) class TestSetSfcPortChain(fakes.TestNeutronClientOSCV2): _port_chain = fakes.FakeSfcPortChain.create_port_chain() resource = _port_chain res = 'port_chain' _port_chain_name = _port_chain['name'] _port_chain_id = _port_chain['id'] pc_ppg = _port_chain['port_pair_groups'] pc_fc = _port_chain['flow_classifiers'] def setUp(self): super(TestSetSfcPortChain, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_port_chain._get_id', new=_get_id).start() self.mocked = self.neutronclient.update_sfc_port_chain self.cmd = sfc_port_chain.SetSfcPortChain(self.app, self.namespace) def test_set_port_chain(self): client = self.app.client_manager.neutronclient mock_port_chain_update = client.update_sfc_port_chain arglist = [ self._port_chain_name, '--name', 'name_updated', '--description', 'desc_updated', ] verifylist = [ ('port_chain', self._port_chain_name), ('name', 'name_updated'), ('description', 'desc_updated'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = {'port_chain': {'name': 'name_updated', 'description': 'desc_updated'}} mock_port_chain_update.assert_called_once_with(self._port_chain_name, attrs) self.assertIsNone(result) def test_set_flow_classifiers(self): target = self.resource['id'] fc1 = 'flow_classifier1' fc2 = 'flow_classifier2' def _mock_flow_classifier(*args, **kwargs): if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource='sfc_port_chain') return {'flow_classifiers': [self.pc_fc]} if self.neutronclient.find_resource.call_count == 2: self.neutronclient.find_resource.assert_called_with( 'flow_classifier', fc1, cmd_resource='sfc_flow_classifier') return {'id': args[1]} if self.neutronclient.find_resource.call_count == 3: self.neutronclient.find_resource.assert_called_with( 'flow_classifier', fc2, cmd_resource='sfc_flow_classifier') return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_flow_classifier arglist = [ target, '--flow-classifier', fc1, '--flow-classifier', fc2, ] verifylist = [ (self.res, target), ('flow_classifiers', [fc1, fc2]) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) expect = {'flow_classifiers': [self.pc_fc, fc1, fc2]} self.mocked.assert_called_once_with(target, {self.res: expect}) self.assertEqual(3, self.neutronclient.find_resource.call_count) self.assertIsNone(result) def test_set_no_flow_classifier(self): client = self.app.client_manager.neutronclient mock_port_chain_update = client.update_sfc_port_chain arglist = [ self._port_chain_name, '--no-flow-classifier', ] verifylist = [ ('port_chain', self._port_chain_name), ('no_flow_classifier', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = {'port_chain': {'flow_classifiers': []}} mock_port_chain_update.assert_called_once_with(self._port_chain_name, attrs) self.assertIsNone(result) def test_set_port_pair_groups(self): target = self.resource['id'] existing_ppg = self.pc_ppg ppg1 = 'port_pair_group1' ppg2 = 'port_pair_group2' def _mock_flow_classifier(*args, **kwargs): if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource='sfc_port_chain') return {'port_pair_groups': [self.pc_ppg]} if self.neutronclient.find_resource.call_count == 2: self.neutronclient.find_resource.assert_called_with( 'port_pair_group', ppg1, cmd_resource='sfc_port_pair_group') return {'id': args[1]} if self.neutronclient.find_resource.call_count == 3: self.neutronclient.find_resource.assert_called_with( 'port_pair_group', ppg2, cmd_resource='sfc_port_pair_group') return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_flow_classifier arglist = [ target, '--port-pair-group', ppg1, '--port-pair-group', ppg2, ] verifylist = [ (self.res, target), ('port_pair_groups', [ppg1, ppg2]) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) expect = {'port_pair_groups': [existing_ppg, ppg1, ppg2]} self.mocked.assert_called_once_with(target, {self.res: expect}) self.assertEqual(3, self.neutronclient.find_resource.call_count) self.assertIsNone(result) def test_set_no_port_pair_group(self): target = self.resource['id'] ppg1 = 'port_pair_group1' def _mock_port_pair_group(*args, **kwargs): if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( 'port_pair_group', ppg1, cmd_resource='sfc_port_pair_group') return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_port_pair_group arglist = [ target, '--no-port-pair-group', '--port-pair-group', ppg1, ] verifylist = [ (self.res, target), ('no_port_pair_group', True), ('port_pair_groups', [ppg1]) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) expect = {'port_pair_groups': [ppg1]} self.mocked.assert_called_once_with(target, {self.res: expect}) self.assertEqual(1, self.neutronclient.find_resource.call_count) self.assertIsNone(result) def test_set_only_no_port_pair_group(self): target = self.resource['id'] arglist = [ target, '--no-port-pair-group', ] verifylist = [ (self.res, target), ('no_port_pair_group', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args) class TestShowSfcPortChain(fakes.TestNeutronClientOSCV2): _pc = fakes.FakeSfcPortChain.create_port_chain() data = ( _pc['chain_id'], _pc['chain_parameters'], _pc['description'], _pc['flow_classifiers'], _pc['id'], _pc['name'], _pc['port_pair_groups'], _pc['project_id'] ) _port_chain = {'port_chain': _pc} _port_chain_id = _pc['id'] columns = ('Chain ID', 'Chain Parameters', 'Description', 'Flow Classifiers', 'ID', 'Name', 'Port Pair Groups', 'Project') def setUp(self): super(TestShowSfcPortChain, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_port_chain._get_id', new=_get_id).start() self.neutronclient.show_sfc_port_chain = mock.Mock( return_value=self._port_chain ) # Get the command object to test self.cmd = sfc_port_chain.ShowSfcPortChain(self.app, self.namespace) def test_show_port_chain(self): client = self.app.client_manager.neutronclient mock_port_chain_show = client.show_sfc_port_chain arglist = [ self._port_chain_id, ] verifylist = [ ('port_chain', self._port_chain_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) mock_port_chain_show.assert_called_once_with(self._port_chain_id) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) class TestUnsetSfcPortChain(fakes.TestNeutronClientOSCV2): _port_chain = fakes.FakeSfcPortChain.create_port_chain() resource = _port_chain res = 'port_chain' _port_chain_name = _port_chain['name'] _port_chain_id = _port_chain['id'] pc_ppg = _port_chain['port_pair_groups'] pc_fc = _port_chain['flow_classifiers'] def setUp(self): super(TestUnsetSfcPortChain, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_port_chain._get_id', new=_get_id).start() self.neutronclient.update_sfc_port_chain = mock.Mock( return_value=None) self.mocked = self.neutronclient.update_sfc_port_chain self.cmd = sfc_port_chain.UnsetSfcPortChain(self.app, self.namespace) def test_unset_port_pair_group(self): target = self.resource['id'] ppg1 = 'port_pair_group1' def _mock_port_pair_group(*args, **kwargs): if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource='sfc_port_chain') return {'port_pair_groups': [self.pc_ppg]} if self.neutronclient.find_resource.call_count == 2: self.neutronclient.find_resource.assert_called_with( 'port_pair_group', ppg1, cmd_resource='sfc_port_pair_group') return {'id': args[1]} if self.neutronclient.find_resource.call_count == 3: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource='sfc_port_chain') return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_port_pair_group arglist = [ target, '--port-pair-group', ppg1, ] verifylist = [ (self.res, target), ('port_pair_groups', [ppg1]) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) expect = {'port_pair_groups': [self.pc_ppg]} self.mocked.assert_called_once_with(target, {self.res: expect}) self.assertIsNone(result) def test_unset_flow_classifier(self): target = self.resource['id'] fc1 = 'flow_classifier1' def _mock_flow_classifier(*args, **kwargs): if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource='sfc_port_chain') return {'flow_classifiers': [self.pc_fc]} if self.neutronclient.find_resource.call_count == 2: self.neutronclient.find_resource.assert_called_with( 'flow_classifier', fc1, cmd_resource='sfc_flow_classifier') return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_flow_classifier arglist = [ target, '--flow-classifier', fc1, ] verifylist = [ (self.res, target), ('flow_classifiers', [fc1]) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) expect = {'flow_classifiers': [self.pc_fc]} self.mocked.assert_called_once_with(target, {self.res: expect}) self.assertIsNone(result) def test_unset_all_flow_classifier(self): client = self.app.client_manager.neutronclient target = self.resource['id'] mock_port_chain_update = client.update_sfc_port_chain arglist = [ target, '--all-flow-classifier', ] verifylist = [ (self.res, target), ('all_flow_classifier', True) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) expect = {'flow_classifiers': []} mock_port_chain_update.assert_called_once_with(target, {self.res: expect}) self.assertIsNone(result) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/sfc/test_port_pair_group.py0000777000175100017510000004356413232473350031527 0ustar zuulzuul00000000000000# Copyright (c) 2017 Huawei Technologies India Pvt.Limited. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import mock from neutronclient.osc.v2.sfc import sfc_port_pair_group from neutronclient.tests.unit.osc.v2.sfc import fakes def _get_id(client, id_or_name, resource): return id_or_name class TestCreateSfcPortPairGroup(fakes.TestNeutronClientOSCV2): _port_pair_group = fakes.FakeSfcPortPairGroup.create_port_pair_group() columns = ('Description', 'ID', 'Loadbalance ID', 'Name', 'Port Pair', 'Port Pair Group Parameters', 'Project', 'Tap Enabled') def get_data(self, ppg): return ( ppg['description'], ppg['id'], ppg['group_id'], ppg['name'], ppg['port_pairs'], ppg['port_pair_group_parameters'], ppg['project_id'], ppg['tap_enabled'] ) def setUp(self): super(TestCreateSfcPortPairGroup, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_port_pair_group._get_id', new=_get_id).start() self.neutronclient.create_sfc_port_pair_group = mock.Mock( return_value={'port_pair_group': self._port_pair_group}) self.data = self.get_data(self._port_pair_group) # Get the command object to test self.cmd = sfc_port_pair_group.CreateSfcPortPairGroup(self.app, self.namespace) def test_create_port_pair_group_default_options(self): arglist = [ "--port-pair", self._port_pair_group['port_pairs'], self._port_pair_group['name'], ] verifylist = [ ('port_pairs', [self._port_pair_group['port_pairs']]), ('name', self._port_pair_group['name']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) self.neutronclient.create_sfc_port_pair_group.assert_called_once_with({ 'port_pair_group': { 'name': self._port_pair_group['name'], 'port_pairs': [self._port_pair_group['port_pairs']] } }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_create_port_pair_group(self): arglist = [ "--description", self._port_pair_group['description'], "--port-pair", self._port_pair_group['port_pairs'], self._port_pair_group['name'], ] verifylist = [ ('port_pairs', [self._port_pair_group['port_pairs']]), ('name', self._port_pair_group['name']), ('description', self._port_pair_group['description']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) self.neutronclient.create_sfc_port_pair_group.assert_called_once_with({ 'port_pair_group': { 'name': self._port_pair_group['name'], 'port_pairs': [self._port_pair_group['port_pairs']], 'description': self._port_pair_group['description'], } }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_create_tap_enabled_port_pair_group(self): arglist = [ "--description", self._port_pair_group['description'], "--port-pair", self._port_pair_group['port_pairs'], self._port_pair_group['name'], "--enable-tap" ] verifylist = [ ('port_pairs', [self._port_pair_group['port_pairs']]), ('name', self._port_pair_group['name']), ('description', self._port_pair_group['description']), ('enable_tap', True) ] expected_data = self._update_expected_response_data( data={ 'tap_enabled': True } ) parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) self.neutronclient.create_sfc_port_pair_group.assert_called_once_with({ 'port_pair_group': { 'name': self._port_pair_group['name'], 'port_pairs': [self._port_pair_group['port_pairs']], 'description': self._port_pair_group['description'], 'tap_enabled': True } }) self.assertEqual(self.columns, columns) self.assertEqual(expected_data, data) def _update_expected_response_data(self, data): # REVISIT(vks1) - This method can be common for other test functions. ppg = fakes.FakeSfcPortPairGroup.create_port_pair_group(data) self.neutronclient.create_sfc_port_pair_group.return_value = { 'port_pair_group': ppg} return self.get_data(ppg) class TestDeleteSfcPortPairGroup(fakes.TestNeutronClientOSCV2): _port_pair_group = (fakes.FakeSfcPortPairGroup.create_port_pair_groups (count=1)) def setUp(self): super(TestDeleteSfcPortPairGroup, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_port_pair_group._get_id', new=_get_id).start() self.neutronclient.delete_sfc_port_pair_group = mock.Mock( return_value=None) self.cmd = sfc_port_pair_group.DeleteSfcPortPairGroup(self.app, self.namespace) def test_delete_port_pair_group(self): client = self.app.client_manager.neutronclient mock_port_pair_group_delete = client.delete_sfc_port_pair_group arglist = [ self._port_pair_group[0]['id'], ] verifylist = [ ('port_pair_group', self._port_pair_group[0]['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) mock_port_pair_group_delete.assert_called_once_with( self._port_pair_group[0]['id']) self.assertIsNone(result) class TestListSfcPortPairGroup(fakes.TestNeutronClientOSCV2): _ppgs = fakes.FakeSfcPortPairGroup.create_port_pair_groups(count=1) columns = ('ID', 'Name', 'Port Pair', 'Port Pair Group Parameters', 'Tap Enabled') columns_long = ('ID', 'Name', 'Port Pair', 'Port Pair Group Parameters', 'Description', 'Loadbalance ID', 'Project', 'Tap Enabled') _port_pair_group = _ppgs[0] data = [ _port_pair_group['id'], _port_pair_group['name'], _port_pair_group['port_pairs'], _port_pair_group['port_pair_group_parameters'], _port_pair_group['tap_enabled'] ] data_long = [ _port_pair_group['id'], _port_pair_group['name'], _port_pair_group['port_pairs'], _port_pair_group['port_pair_group_parameters'], _port_pair_group['description'], _port_pair_group['tap_enabled'] ] _port_pair_group1 = {'port_pair_groups': _port_pair_group} _port_pair_id = _port_pair_group['id'] def setUp(self): super(TestListSfcPortPairGroup, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_port_pair_group._get_id', new=_get_id).start() self.neutronclient.list_sfc_port_pair_groups = mock.Mock( return_value={'port_pair_groups': self._ppgs} ) # Get the command object to test self.cmd = sfc_port_pair_group.ListSfcPortPairGroup(self.app, self.namespace) def test_list_port_pair_groups(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns = self.cmd.take_action(parsed_args)[0] ppgs = self.neutronclient \ .list_sfc_port_pair_groups()['port_pair_groups'] ppg = ppgs[0] data = [ ppg['id'], ppg['name'], ppg['port_pairs'], ppg['port_pair_group_parameters'], ppg['tap_enabled'] ] self.assertEqual(list(self.columns), columns) self.assertEqual(self.data, data) def test_list_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] ppgs = self.neutronclient \ .list_sfc_port_pair_groups()['port_pair_groups'] ppg = ppgs[0] data = [ ppg['id'], ppg['name'], ppg['port_pairs'], ppg['port_pair_group_parameters'], ppg['description'], ppg['tap_enabled'] ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns_long = self.cmd.take_action(parsed_args)[0] self.assertEqual(list(self.columns_long), columns_long) self.assertEqual(self.data_long, data) class TestSetSfcPortPairGroup(fakes.TestNeutronClientOSCV2): _port_pair_group = fakes.FakeSfcPortPairGroup.create_port_pair_group() resource = _port_pair_group res = 'port_pair_group' _port_pair_group_name = _port_pair_group['name'] ppg_pp = _port_pair_group['port_pairs'] _port_pair_group_id = _port_pair_group['id'] def setUp(self): super(TestSetSfcPortPairGroup, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_port_pair_group._get_id', new=_get_id).start() self.neutronclient.update_sfc_port_pair_group = mock.Mock( return_value=None) self.mocked = self.neutronclient.update_sfc_port_pair_group self.cmd = sfc_port_pair_group.SetSfcPortPairGroup(self.app, self.namespace) def test_set_port_pair_group(self): target = self.resource['id'] port_pair1 = 'additional_port1' port_pair2 = 'additional_port2' def _mock_port_pair_group(*args, **kwargs): if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( 'port_pair', port_pair1, cmd_resource='sfc_port_pair') return {'id': args[1]} if self.neutronclient.find_resource.call_count == 2: self.neutronclient.find_resource.assert_called_with( 'port_pair', port_pair2, cmd_resource='sfc_port_pair') return {'id': args[1]} if self.neutronclient.find_resource.call_count == 3: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource='sfc_port_pair_group') return {'port_pairs': self.ppg_pp} self.neutronclient.find_resource.side_effect = _mock_port_pair_group arglist = [ target, '--port-pair', port_pair1, '--port-pair', port_pair2, ] verifylist = [ (self.res, target), ('port_pairs', [port_pair1, port_pair2]) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) expect = {'port_pairs': sorted([self.ppg_pp, port_pair1, port_pair2])} self.mocked.assert_called_once_with(target, {self.res: expect}) self.assertEqual(3, self.neutronclient.find_resource.call_count) self.assertIsNone(result) def test_set_no_port_pair(self): client = self.app.client_manager.neutronclient mock_port_pair_group_update = client.update_sfc_port_pair_group arglist = [ self._port_pair_group_name, '--name', 'name_updated', '--description', 'desc_updated', '--no-port-pair', ] verifylist = [ ('port_pair_group', self._port_pair_group_name), ('name', 'name_updated'), ('description', 'desc_updated'), ('no_port_pair', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = {'port_pair_group': {'name': 'name_updated', 'description': 'desc_updated', 'port_pairs': []}} mock_port_pair_group_update.assert_called_once_with( self._port_pair_group_name, attrs) self.assertIsNone(result) class TestShowSfcPortPairGroup(fakes.TestNeutronClientOSCV2): _ppg = fakes.FakeSfcPortPairGroup.create_port_pair_group() data = ( _ppg['description'], _ppg['id'], _ppg['group_id'], _ppg['name'], _ppg['port_pairs'], _ppg['port_pair_group_parameters'], _ppg['project_id'], _ppg['tap_enabled']) _port_pair_group = {'port_pair_group': _ppg} _port_pair_group_id = _ppg['id'] columns = ( 'Description', 'ID', 'Loadbalance ID', 'Name', 'Port Pair', 'Port Pair Group Parameters', 'Project', 'Tap Enabled' ) def setUp(self): super(TestShowSfcPortPairGroup, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_port_pair_group._get_id', new=_get_id).start() self.neutronclient.show_sfc_port_pair_group = mock.Mock( return_value=self._port_pair_group ) self.cmd = sfc_port_pair_group.ShowSfcPortPairGroup(self.app, self.namespace) def test_show_port_pair_group(self): client = self.app.client_manager.neutronclient mock_port_pair_group_show = client.show_sfc_port_pair_group arglist = [ self._port_pair_group_id, ] verifylist = [ ('port_pair_group', self._port_pair_group_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) mock_port_pair_group_show.assert_called_once_with( self._port_pair_group_id) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) class TestUnsetSfcPortPairGroup(fakes.TestNeutronClientOSCV2): _port_pair_group = fakes.FakeSfcPortPairGroup.create_port_pair_group() resource = _port_pair_group res = 'port_pair_group' _port_pair_group_name = _port_pair_group['name'] _port_pair_group_id = _port_pair_group['id'] ppg_pp = _port_pair_group['port_pairs'] def setUp(self): super(TestUnsetSfcPortPairGroup, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_port_pair_group._get_id', new=_get_id).start() self.neutronclient.update_sfc_port_pair_group = mock.Mock( return_value=None) self.mocked = self.neutronclient.update_sfc_port_pair_group self.cmd = sfc_port_pair_group.UnsetSfcPortPairGroup( self.app, self.namespace) def test_unset_port_pair(self): target = self.resource['id'] port_pair1 = 'additional_port1' port_pair2 = 'additional_port2' def _mock_port_pair(*args, **kwargs): if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource='sfc_port_pair_group') return {'port_pairs': self.ppg_pp} if self.neutronclient.find_resource.call_count == 2: self.neutronclient.find_resource.assert_called_with( 'port_pair', port_pair1, cmd_resource='sfc_port_pair') return {'id': args[1]} if self.neutronclient.find_resource.call_count == 3: self.neutronclient.find_resource.assert_called_with( 'port_pair', port_pair2, cmd_resource='sfc_port_pair') return {'id': args[1]} if self.neutronclient.find_resource.call_count == 4: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource='sfc_port_pair_group') return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_port_pair arglist = [ target, '--port-pair', port_pair1, '--port-pair', port_pair2, ] verifylist = [ (self.res, target), ('port_pairs', [port_pair1, port_pair2]) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) expect = {'port_pairs': sorted([self.ppg_pp])} self.mocked.assert_called_once_with(target, {self.res: expect}) self.assertIsNone(result) def test_unset_all_port_pair(self): client = self.app.client_manager.neutronclient mock_port_pair_group_update = client.update_sfc_port_pair_group arglist = [ self._port_pair_group_name, '--all-port-pair', ] verifylist = [ ('port_pair_group', self._port_pair_group_name), ('all_port_pair', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = {'port_pair_group': {'port_pairs': []}} mock_port_pair_group_update.assert_called_once_with( self._port_pair_group_name, attrs) self.assertIsNone(result) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/sfc/test_flow_classifier.py0000777000175100017510000003424213232473350031460 0ustar zuulzuul00000000000000# Copyright (c) 2017 Huawei Technologies India Pvt.Limited. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import mock from neutronclient.osc.v2.sfc import sfc_flow_classifier from neutronclient.tests.unit.osc.v2.sfc import fakes get_id = 'neutronclient.osc.v2.sfc.sfc_flow_classifier._get_id' def _get_id(client, id_or_name, resource): return id_or_name class TestCreateSfcFlowClassifier(fakes.TestNeutronClientOSCV2): _fc = fakes.FakeSfcFlowClassifier.create_flow_classifier() columns = ('Description', 'Destination IP', 'Destination Port Range Max', 'Destination Port Range Min', 'Ethertype', 'ID', 'L7 Parameters', 'Logical Destination Port', 'Logical Source Port', 'Name', 'Project', 'Protocol', 'Source IP', 'Source Port Range Max', 'Source Port Range Min') def get_data(self): return ( self._fc['description'], self._fc['destination_ip_prefix'], self._fc['destination_port_range_max'], self._fc['destination_port_range_min'], self._fc['ethertype'], self._fc['id'], self._fc['l7_parameters'], self._fc['logical_destination_port'], self._fc['logical_source_port'], self._fc['name'], self._fc['project_id'], self._fc['protocol'], self._fc['source_ip_prefix'], self._fc['source_port_range_max'], self._fc['source_port_range_min'] ) def setUp(self): super(TestCreateSfcFlowClassifier, self).setUp() mock.patch(get_id, new=_get_id).start() self.neutronclient.create_sfc_flow_classifier = mock.Mock( return_value={'flow_classifier': self._fc}) self.data = self.get_data() # Get the command object to test self.cmd = sfc_flow_classifier.CreateSfcFlowClassifier(self.app, self.namespace) def test_create_flow_classifier_default_options(self): arglist = [ "--logical-source-port", self._fc['logical_source_port'], "--ethertype", self._fc['ethertype'], self._fc['name'], ] verifylist = [ ('logical_source_port', self._fc['logical_source_port']), ('ethertype', self._fc['ethertype']), ('name', self._fc['name']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) self.neutronclient.create_sfc_flow_classifier.assert_called_once_with({ 'flow_classifier': { 'name': self._fc['name'], 'logical_source_port': self._fc['logical_source_port'], 'ethertype': self._fc['ethertype']} }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_create_flow_classifier(self): arglist = [ "--description", self._fc['description'], "--ethertype", self._fc['ethertype'], "--protocol", self._fc['protocol'], "--source-ip-prefix", self._fc['source_ip_prefix'], "--destination-ip-prefix", self._fc['destination_ip_prefix'], "--logical-source-port", self._fc['logical_source_port'], "--logical-destination-port", self._fc['logical_destination_port'], self._fc['name'], "--l7-parameters", 'url=path', ] param = 'url=path' verifylist = [ ('description', self._fc['description']), ('name', self._fc['name']), ('ethertype', self._fc['ethertype']), ('protocol', self._fc['protocol']), ('source_ip_prefix', self._fc['source_ip_prefix']), ('destination_ip_prefix', self._fc['destination_ip_prefix']), ('logical_source_port', self._fc['logical_source_port']), ('logical_destination_port', self._fc['logical_destination_port']), ('l7_parameters', param) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) self.neutronclient.create_sfc_flow_classifier.assert_called_once_with({ 'flow_classifier': { 'name': self._fc['name'], 'description': self._fc['description'], 'ethertype': self._fc['ethertype'], 'protocol': self._fc['protocol'], 'source_ip_prefix': self._fc['source_ip_prefix'], 'destination_ip_prefix': self._fc['destination_ip_prefix'], 'logical_source_port': self._fc['logical_source_port'], 'logical_destination_port': self._fc['logical_destination_port'], 'l7_parameters': param } }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) class TestDeleteSfcFlowClassifier(fakes.TestNeutronClientOSCV2): _flow_classifier = \ fakes.FakeSfcFlowClassifier.create_flow_classifiers(count=1) def setUp(self): super(TestDeleteSfcFlowClassifier, self).setUp() mock.patch(get_id, new=_get_id).start() self.neutronclient.delete_sfc_flow_classifier = mock.Mock( return_value=None) self.cmd = sfc_flow_classifier.DeleteSfcFlowClassifier(self.app, self.namespace) def test_delete_flow_classifier(self): client = self.app.client_manager.neutronclient mock_flow_classifier_delete = client.delete_sfc_flow_classifier arglist = [ self._flow_classifier[0]['id'], ] verifylist = [ ('flow_classifier', self._flow_classifier[0]['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) mock_flow_classifier_delete.assert_called_once_with( self._flow_classifier[0]['id']) self.assertIsNone(result) class TestSetSfcFlowClassifier(fakes.TestNeutronClientOSCV2): _flow_classifier = fakes.FakeSfcFlowClassifier.create_flow_classifier() _flow_classifier_name = _flow_classifier['name'] _flow_classifier_id = _flow_classifier['id'] def setUp(self): super(TestSetSfcFlowClassifier, self).setUp() mock.patch(get_id, new=_get_id).start() self.neutronclient.update_sfc_flow_classifier = mock.Mock( return_value=None) self.cmd = sfc_flow_classifier.SetSfcFlowClassifier(self.app, self.namespace) def test_set_flow_classifier(self): client = self.app.client_manager.neutronclient mock_flow_classifier_update = client.update_sfc_flow_classifier arglist = [ self._flow_classifier_name, '--name', 'name_updated', '--description', 'desc_updated' ] verifylist = [ ('flow_classifier', self._flow_classifier_name), ('name', 'name_updated'), ('description', 'desc_updated'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = {'flow_classifier': { 'name': 'name_updated', 'description': 'desc_updated'}} mock_flow_classifier_update.assert_called_once_with( self._flow_classifier_name, attrs) self.assertIsNone(result) class TestShowSfcFlowClassifier(fakes.TestNeutronClientOSCV2): _fc = fakes.FakeSfcFlowClassifier.create_flow_classifier() data = ( _fc['description'], _fc['destination_ip_prefix'], _fc['destination_port_range_max'], _fc['destination_port_range_min'], _fc['ethertype'], _fc['id'], _fc['l7_parameters'], _fc['logical_destination_port'], _fc['logical_source_port'], _fc['name'], _fc['project_id'], _fc['protocol'], _fc['source_ip_prefix'], _fc['source_port_range_max'], _fc['source_port_range_min'] ) _flow_classifier = {'flow_classifier': _fc} _flow_classifier_id = _fc['id'] columns = ('Description', 'Destination IP', 'Destination Port Range Max', 'Destination Port Range Min', 'Ethertype', 'ID', 'L7 Parameters', 'Logical Destination Port', 'Logical Source Port', 'Name', 'Project', 'Protocol', 'Source IP', 'Source Port Range Max', 'Source Port Range Min') def setUp(self): super(TestShowSfcFlowClassifier, self).setUp() mock.patch(get_id, new=_get_id).start() self.neutronclient.show_sfc_flow_classifier = mock.Mock( return_value=self._flow_classifier ) # Get the command object to test self.cmd = sfc_flow_classifier.ShowSfcFlowClassifier(self.app, self.namespace) def test_show_flow_classifier(self): client = self.app.client_manager.neutronclient mock_flow_classifier_show = client.show_sfc_flow_classifier arglist = [ self._flow_classifier_id, ] verifylist = [ ('flow_classifier', self._flow_classifier_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) mock_flow_classifier_show.assert_called_once_with( self._flow_classifier_id) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) class TestListSfcFlowClassifier(fakes.TestNeutronClientOSCV2): _fc = fakes.FakeSfcFlowClassifier.create_flow_classifiers(count=1) columns = ('ID', 'Name', 'Summary') columns_long = ('ID', 'Name', 'Protocol', 'Ethertype', 'Source IP', 'Destination IP', 'Logical Source Port', 'Logical Destination Port', 'Source Port Range Min', 'Source Port Range Max', 'Destination Port Range Min', 'Destination Port Range Max', 'L7 Parameters', 'Description', 'Project') _flow_classifier = _fc[0] data = [ _flow_classifier['id'], _flow_classifier['name'], _flow_classifier['protocol'], _flow_classifier['source_ip_prefix'], _flow_classifier['destination_ip_prefix'], _flow_classifier['logical_source_port'], _flow_classifier['logical_destination_port'] ] data_long = [ _flow_classifier['id'], _flow_classifier['name'], _flow_classifier['protocol'], _flow_classifier['ethertype'], _flow_classifier['source_ip_prefix'], _flow_classifier['destination_ip_prefix'], _flow_classifier['logical_source_port'], _flow_classifier['logical_destination_port'], _flow_classifier['source_port_range_min'], _flow_classifier['source_port_range_max'], _flow_classifier['destination_port_range_min'], _flow_classifier['destination_port_range_max'], _flow_classifier['l7_parameters'], _flow_classifier['description'] ] _flow_classifier1 = {'flow_classifiers': _flow_classifier} _flow_classifier_id = _flow_classifier['id'] def setUp(self): super(TestListSfcFlowClassifier, self).setUp() mock.patch(get_id, new=_get_id).start() self.neutronclient.list_sfc_flow_classifiers = mock.Mock( return_value={'flow_classifiers': self._fc} ) # Get the command object to test self.cmd = sfc_flow_classifier.ListSfcFlowClassifier(self.app, self.namespace) def test_list_flow_classifiers(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns = self.cmd.take_action(parsed_args) fcs = self.neutronclient \ .list_sfc_flow_classifiers()['flow_classifiers'] fc = fcs[0] data = [ fc['id'], fc['name'], fc['protocol'], fc['source_ip_prefix'], fc['destination_ip_prefix'], fc['logical_source_port'], fc['logical_destination_port'] ] self.assertEqual(list(self.columns), columns[0]) self.assertEqual(self.data, data) def test_list_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] fcs = self.neutronclient \ .list_sfc_flow_classifiers()['flow_classifiers'] fc = fcs[0] data = [ fc['id'], fc['name'], fc['protocol'], fc['ethertype'], fc['source_ip_prefix'], fc['destination_ip_prefix'], fc['logical_source_port'], fc['logical_destination_port'], fc['source_port_range_min'], fc['source_port_range_max'], fc['destination_port_range_min'], fc['destination_port_range_max'], fc['l7_parameters'], fc['description'] ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns_long = self.cmd.take_action(parsed_args)[0] self.assertEqual(list(self.columns_long), columns_long) self.assertEqual(self.data_long, data) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/sfc/test_service_graph.py0000666000175100017510000002755313232473350031132 0ustar zuulzuul00000000000000# Copyright 2017 Intel Corporation. # # 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 mock from osc_lib import exceptions from osc_lib.tests import utils as tests_utils from neutronclient.osc.v2.sfc import sfc_service_graph from neutronclient.tests.unit.osc.v2.sfc import fakes def _get_id(client, id_or_name, resource): return id_or_name class TestListSfcServiceGraph(fakes.TestNeutronClientOSCV2): _service_graphs = fakes.FakeSfcServiceGraph.create_sfc_service_graphs( count=1) columns = ('ID', 'Name', 'Branching Points') columns_long = ('ID', 'Name', 'Branching Points', 'Description', 'Project') _service_graph = _service_graphs[0] data = [ _service_graph['id'], _service_graph['name'], _service_graph['port_chains'] ] data_long = [ _service_graph['id'], _service_graph['name'], _service_graph['port_chains'], _service_graph['description'], _service_graph['project_id'] ] _service_graph1 = {'service_graphs': _service_graph} _service_graph_id = _service_graph['id'] def setUp(self): super(TestListSfcServiceGraph, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_service_graph._get_id', new=_get_id).start() self.neutronclient.list_sfc_service_graphs = mock.Mock( return_value={'service_graphs': self._service_graphs} ) # Get the command object to test self.cmd = sfc_service_graph.ListSfcServiceGraph( self.app, self.namespace) def test_list_sfc_service_graphs(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns = self.cmd.take_action(parsed_args)[0] sgs = self.neutronclient.list_sfc_service_graphs()['service_graphs'] sg = sgs[0] data = [ sg['id'], sg['name'], sg['port_chains'] ] self.assertEqual(list(self.columns), columns) self.assertEqual(self.data, data) def test_list_sfc_service_graphs_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns = self.cmd.take_action(parsed_args)[0] sgs = self.neutronclient.list_sfc_service_graphs()['service_graphs'] sg = sgs[0] data = [ sg['id'], sg['name'], sg['port_chains'], sg['description'], sg['project_id'] ] self.assertEqual(list(self.columns_long), columns) self.assertEqual(self.data_long, data) class TestCreateSfcServiceGraph(fakes.TestNeutronClientOSCV2): _service_graph = fakes.FakeSfcServiceGraph.create_sfc_service_graph() columns = ('ID', 'Name', 'Branching Points') columns_long = ('Branching Points', 'Description', 'ID', 'Name', 'Project') def get_data(self): return ( self._service_graph['port_chains'], self._service_graph['description'], self._service_graph['id'], self._service_graph['name'], self._service_graph['project_id'], ) def setUp(self): super(TestCreateSfcServiceGraph, self).setUp() mock.patch('neutronclient.osc.v2.sfc.sfc_service_graph._get_id', new=_get_id).start() self.neutronclient.create_sfc_service_graph = mock.Mock( return_value={'service_graph': self._service_graph}) self.data = self.get_data() self.cmd = sfc_service_graph.CreateSfcServiceGraph( self.app, self.namespace) def test_create_sfc_service_graph(self): arglist = [] verifylist = [] self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_sfc_service_graph_without_loop(self): bp1_str = 'pc1:pc2,pc3' bp2_str = 'pc2:pc4' self.cmd = sfc_service_graph.CreateSfcServiceGraph( self.app, self.namespace) arglist = [ "--description", self._service_graph['description'], "--branching-point", bp1_str, "--branching-point", bp2_str, self._service_graph['name']] pcs = {'pc1': ['pc2', 'pc3'], 'pc2': ['pc4']} verifylist = [ ("description", self._service_graph['description']), ("branching_points", [bp1_str, bp2_str]), ("name", self._service_graph['name']) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) self.neutronclient.create_sfc_service_graph.assert_called_once_with({ 'service_graph': { 'description': self._service_graph['description'], 'name': self._service_graph['name'], 'port_chains': pcs } }) self.assertEqual(self.columns_long, columns) self.assertEqual(self.data, data) def test_create_sfc_service_graph_with_loop(self): bp1_str = 'pc1:pc2,pc3;' bp2_str = 'pc2:pc1' self.cmd = sfc_service_graph.CreateSfcServiceGraph( self.app, self.namespace) arglist = [ "--description", self._service_graph['description'], "--branching-point", bp1_str, "--branching-point", bp2_str, self._service_graph['name']] verifylist = [ ("description", self._service_graph['description']), ("branching_points", [bp1_str, bp2_str]), ("name", self._service_graph['name']) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args) def test_create_sfc_service_graph_invalid_port_chains(self): bp1_str = 'pc1:pc2,pc3:' self.cmd = sfc_service_graph.CreateSfcServiceGraph( self.app, self.namespace) arglist = [ "--description", self._service_graph['description'], "--branching-point", bp1_str, self._service_graph['name']] verifylist = [ ("description", self._service_graph['description']), ("branching_points", [bp1_str]), ("name", self._service_graph['name']) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args) def test_create_sfc_service_graph_duplicate_src_chains(self): bp1_str = 'pc1:pc2,pc3;' bp2_str = 'pc1:pc4' self.cmd = sfc_service_graph.CreateSfcServiceGraph( self.app, self.namespace) arglist = [ "--description", self._service_graph['description'], "--branching-point", bp1_str, "--branching-point", bp2_str, self._service_graph['name']] verifylist = [ ("description", self._service_graph['description']), ("branching_points", [bp1_str, bp2_str]), ("name", self._service_graph['name']) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args) class TestDeleteSfcServiceGraph(fakes.TestNeutronClientOSCV2): _service_graph = fakes.FakeSfcServiceGraph.create_sfc_service_graphs( count=1) def setUp(self): super(TestDeleteSfcServiceGraph, self).setUp() self.neutronclient.delete_sfc_service_graph = mock.Mock( return_value=None) self.cmd = sfc_service_graph.DeleteSfcServiceGraph( self.app, self.namespace) def test_delete_sfc_service_graph(self): client = self.app.client_manager.neutronclient mock_service_graph_delete = client.delete_sfc_service_graph arglist = [ self._service_graph[0]['id'], ] verifylist = [ ('service_graph', self._service_graph[0]['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) mock_service_graph_delete.assert_called_once_with( self._service_graph[0]['id']) self.assertIsNone(result) class TestShowSfcServiceGraph(fakes.TestNeutronClientOSCV2): _sg = fakes.FakeSfcServiceGraph.create_sfc_service_graph() columns = ('ID', 'Name', 'Branching Points') columns_long = ('Branching Points', 'Description', 'ID', 'Name', 'Project') data = ( _sg['id'], _sg['name'], _sg['port_chains'] ) data_long = ( _sg['port_chains'], _sg['description'], _sg['id'], _sg['name'], _sg['project_id'] ) _service_graph = {'service_graph': _sg} _service_graph_id = _sg['id'] def setUp(self): super(TestShowSfcServiceGraph, self).setUp() mock.patch( 'neutronclient.osc.v2.sfc.sfc_service_graph._get_id', new=_get_id).start() self.neutronclient.show_sfc_service_graph = mock.Mock( return_value=self._service_graph ) # Get the command object to test self.cmd = sfc_service_graph.ShowSfcServiceGraph( self.app, self.namespace) def test_service_graph_show(self): client = self.app.client_manager.neutronclient mock_service_graph_show = client.show_sfc_service_graph arglist = [ self._service_graph_id, ] verifylist = [ ('service_graph', self._service_graph_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) mock_service_graph_show.assert_called_once_with(self._service_graph_id) self.assertEqual(self.columns_long, columns) self.assertEqual(self.data_long, data) class TestSetSfcServiceGraph(fakes.TestNeutronClientOSCV2): _service_graph = fakes.FakeSfcServiceGraph.create_sfc_service_graph() _service_graph_name = _service_graph['name'] _service_graph_id = _service_graph['id'] def setUp(self): super(TestSetSfcServiceGraph, self).setUp() mock.patch('neutronclient.osc.v2.sfc.sfc_service_graph._get_id', new=_get_id).start() self.neutronclient.update_sfc_service_graph = mock.Mock( return_value=None) self.cmd = sfc_service_graph.SetSfcServiceGraph( self.app, self.namespace) def test_set_service_graph(self): client = self.app.client_manager.neutronclient mock_service_graph_update = client.update_sfc_service_graph arglist = [ self._service_graph_name, '--name', 'name_updated', '--description', 'desc_updated' ] verifylist = [ ('service_graph', self._service_graph_name), ('name', 'name_updated'), ('description', 'desc_updated'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = {'service_graph': { 'name': 'name_updated', 'description': 'desc_updated'} } mock_service_graph_update.assert_called_once_with( self._service_graph_name, attrs) self.assertIsNone(result) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/sfc/__init__.py0000666000175100017510000000000013232473350026763 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/dynamic_routing/0000775000175100017510000000000013232473710027302 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/dynamic_routing/test_bgp_peer.py0000666000175100017510000001152213232473350032501 0ustar zuulzuul00000000000000# 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 mock from neutronclient.osc.v2.dynamic_routing import bgp_peer from neutronclient.tests.unit.osc.v2.dynamic_routing import fakes class TestListBgpPeer(fakes.TestNeutronDynamicRoutingOSCV2): _bgp_peers = fakes.FakeBgpPeer.create_bgp_peers(count=1) columns = ('ID', 'Name', 'Peer IP', 'Remote AS') data = [] for _bgp_peer in _bgp_peers['bgp_peers']: data.append(( _bgp_peer['id'], _bgp_peer['name'], _bgp_peer['peer_ip'], _bgp_peer['remote_as'])) def setUp(self): super(TestListBgpPeer, self).setUp() self.neutronclient.list_bgp_peers = mock.Mock( return_value=self._bgp_peers ) # Get the command object to test self.cmd = bgp_peer.ListBgpPeer(self.app, self.namespace) def test_bgp_peer_list(self): parsed_args = self.check_parser(self.cmd, [], []) columns, data = self.cmd.take_action(parsed_args) self.neutronclient.list_bgp_peers.assert_called_once_with() self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) class TestDeleteBgpPeer(fakes.TestNeutronDynamicRoutingOSCV2): _bgp_peer = fakes.FakeBgpPeer.create_one_bgp_peer() def setUp(self): super(TestDeleteBgpPeer, self).setUp() self.neutronclient.delete_bgp_peer = mock.Mock(return_value=None) self.cmd = bgp_peer.DeleteBgpPeer(self.app, self.namespace) def test_delete_bgp_peer(self): arglist = [ self._bgp_peer['name'], ] verifylist = [ ('bgp_peer', self._bgp_peer['name']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.neutronclient.delete_bgp_peer.assert_called_once_with( self._bgp_peer['name']) self.assertIsNone(result) class TestShowBgpPeer(fakes.TestNeutronDynamicRoutingOSCV2): _one_bgp_peer = fakes.FakeBgpPeer.create_one_bgp_peer() data = ( _one_bgp_peer['auth_type'], _one_bgp_peer['id'], _one_bgp_peer['name'], _one_bgp_peer['peer_ip'], _one_bgp_peer['remote_as'], _one_bgp_peer['tenant_id'] ) _bgp_peer = {'bgp_peer': _one_bgp_peer} _bgp_peer_name = _one_bgp_peer['name'] columns = ( 'auth_type', 'id', 'name', 'peer_ip', 'remote_as', 'tenant_id' ) def setUp(self): super(TestShowBgpPeer, self).setUp() self.neutronclient.show_bgp_peer = mock.Mock( return_value=self._bgp_peer ) bgp_peer.get_bgp_peer_id = mock.Mock(return_value=self._bgp_peer_name) # Get the command object to test self.cmd = bgp_peer.ShowBgpPeer(self.app, self.namespace) def test_bgp_peer_list(self): arglist = [ self._bgp_peer_name, ] verifylist = [ ('bgp_peer', self._bgp_peer_name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) data = self.cmd.take_action(parsed_args) self.neutronclient.show_bgp_peer.assert_called_once_with( self._bgp_peer_name) self.assertEqual(self.columns, data[0]) self.assertEqual(self.data, data[1]) class TestSetBgpPeer(fakes.TestNeutronDynamicRoutingOSCV2): _one_bgp_peer = fakes.FakeBgpPeer.create_one_bgp_peer() _bgp_peer_name = _one_bgp_peer['name'] def setUp(self): super(TestSetBgpPeer, self).setUp() self.neutronclient.update_bgp_peer = mock.Mock(return_value=None) bgp_peer.get_bgp_peer_id = mock.Mock(return_value=self._bgp_peer_name) self.cmd = bgp_peer.SetBgpPeer(self.app, self.namespace) def test_set_bgp_peer(self): arglist = [ self._bgp_peer_name, '--name', 'noob', ] verifylist = [ ('bgp_peer', self._bgp_peer_name), ('name', 'noob'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = {'bgp_peer': { 'name': 'noob', 'password': None} } self.neutronclient.update_bgp_peer.assert_called_once_with( self._bgp_peer_name, attrs) self.assertIsNone(result) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/dynamic_routing/fakes.py0000666000175100017510000000565413232473350030761 0ustar zuulzuul00000000000000# 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 copy import uuid import mock from neutronclient.tests.unit.osc.v2 import fakes class TestNeutronDynamicRoutingOSCV2(fakes.TestNeutronClientOSCV2): def setUp(self): super(TestNeutronDynamicRoutingOSCV2, self).setUp() self.neutronclient.find_resource = mock.Mock( side_effect=lambda resource, name_or_id, project_id=None, cmd_resource=None, parent_id=None, fields=None: {'id': name_or_id}) class FakeBgpSpeaker(object): """Fake one or more bgp speakers.""" @staticmethod def create_one_bgp_speaker(attrs=None): attrs = attrs or {} # Set default attributes. bgp_speaker_attrs = { 'peers': [], 'local_as': 200, 'advertise_tenant_networks': True, 'networks': [], 'ip_version': 4, 'advertise_floating_ip_host_routes': True, 'id': uuid.uuid4().hex, 'name': 'bgp-speaker-' + uuid.uuid4().hex, 'tenant_id': uuid.uuid4().hex, } # Overwrite default attributes. bgp_speaker_attrs.update(attrs) return copy.deepcopy(bgp_speaker_attrs) @staticmethod def create_bgp_speakers(attrs=None, count=1): """Create multiple fake bgp speakers. """ bgp_speakers = [] for i in range(0, count): bgp_speaker = FakeBgpSpeaker.create_one_bgp_speaker(attrs) bgp_speakers.append(bgp_speaker) return {'bgp_speakers': bgp_speakers} class FakeBgpPeer(object): """Fake one or more bgp peers.""" @staticmethod def create_one_bgp_peer(attrs=None): attrs = attrs or {} # Set default attributes. bgp_peer_attrs = { 'auth_type': None, 'peer_ip': '1.1.1.1', 'remote_as': 100, 'id': uuid.uuid4().hex, 'name': 'bgp-peer-' + uuid.uuid4().hex, 'tenant_id': uuid.uuid4().hex, } # Overwrite default attributes. bgp_peer_attrs.update(attrs) return copy.deepcopy(bgp_peer_attrs) @staticmethod def create_bgp_peers(attrs=None, count=1): """Create one or multiple fake bgp peers.""" bgp_peers = [] for i in range(0, count): bgp_peer = FakeBgpPeer.create_one_bgp_peer(attrs) bgp_peers.append(bgp_peer) return {'bgp_peers': bgp_peers} python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/dynamic_routing/test_bgp_speaker.py0000666000175100017510000001220213232473350033174 0ustar zuulzuul00000000000000# 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 mock from neutronclient.osc.v2.dynamic_routing import bgp_speaker from neutronclient.tests.unit.osc.v2.dynamic_routing import fakes class TestListBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2): _bgp_speakers = fakes.FakeBgpSpeaker.create_bgp_speakers() columns = ('ID', 'Name', 'Local AS', 'IP Version') data = [] for _bgp_speaker in _bgp_speakers['bgp_speakers']: data.append(( _bgp_speaker['id'], _bgp_speaker['name'], _bgp_speaker['local_as'], _bgp_speaker['ip_version'])) def setUp(self): super(TestListBgpSpeaker, self).setUp() self.neutronclient.list_bgp_speakers = mock.Mock( return_value=self._bgp_speakers ) # Get the command object to test self.cmd = bgp_speaker.ListBgpSpeaker(self.app, self.namespace) def test_bgp_speaker_list(self): parsed_args = self.check_parser(self.cmd, [], []) columns, data = self.cmd.take_action(parsed_args) self.neutronclient.list_bgp_speakers.assert_called_once_with() self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) class TestDeleteBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2): _bgp_speaker = fakes.FakeBgpSpeaker.create_one_bgp_speaker() def setUp(self): super(TestDeleteBgpSpeaker, self).setUp() self.neutronclient.delete_bgp_speaker = mock.Mock(return_value=None) self.cmd = bgp_speaker.DeleteBgpSpeaker(self.app, self.namespace) def test_delete_bgp_speaker(self): arglist = [ self._bgp_speaker['name'], ] verifylist = [ ('bgp_speaker', self._bgp_speaker['name']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.neutronclient.delete_bgp_speaker.assert_called_once_with( self._bgp_speaker['name']) self.assertIsNone(result) class TestShowBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2): _one_bgp_speaker = fakes.FakeBgpSpeaker.create_one_bgp_speaker() data = ( _one_bgp_speaker['advertise_floating_ip_host_routes'], _one_bgp_speaker['advertise_tenant_networks'], _one_bgp_speaker['id'], _one_bgp_speaker['ip_version'], _one_bgp_speaker['local_as'], _one_bgp_speaker['name'], _one_bgp_speaker['networks'], _one_bgp_speaker['peers'], _one_bgp_speaker['tenant_id'] ) _bgp_speaker = {'bgp_speaker': _one_bgp_speaker} _bgp_speaker_name = _one_bgp_speaker['name'] columns = ( 'advertise_floating_ip_host_routes', 'advertise_tenant_networks', 'id', 'ip_version', 'local_as', 'name', 'networks', 'peers', 'tenant_id' ) def setUp(self): super(TestShowBgpSpeaker, self).setUp() self.neutronclient.show_bgp_speaker = mock.Mock( return_value=self._bgp_speaker ) # Get the command object to test self.cmd = bgp_speaker.ShowBgpSpeaker(self.app, self.namespace) def test_bgp_speaker_show(self): arglist = [ self._bgp_speaker_name, ] verifylist = [ ('bgp_speaker', self._bgp_speaker_name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) data = self.cmd.take_action(parsed_args) self.neutronclient.show_bgp_speaker.assert_called_once_with( self._bgp_speaker_name) self.assertEqual(self.columns, data[0]) self.assertEqual(self.data, data[1]) class TestSetBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2): _one_bgp_speaker = fakes.FakeBgpSpeaker.create_one_bgp_speaker() _bgp_speaker_name = _one_bgp_speaker['name'] def setUp(self): super(TestSetBgpSpeaker, self).setUp() self.neutronclient.update_bgp_speaker = mock.Mock( return_value=None) self.cmd = bgp_speaker.SetBgpSpeaker(self.app, self.namespace) def test_set_bgp_speaker(self): arglist = [ self._bgp_speaker_name, '--name', 'noob', ] verifylist = [ ('bgp_speaker', self._bgp_speaker_name), ('name', 'noob'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = {'bgp_speaker': { 'name': 'noob'} } self.neutronclient.update_bgp_speaker.assert_called_once_with( self._bgp_speaker_name, attrs) self.assertIsNone(result) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/dynamic_routing/__init__.py0000666000175100017510000000000013232473350031403 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/fakes.py0000666000175100017510000000355413232473350025563 0ustar zuulzuul00000000000000# 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 argparse from cliff import columns as cliff_columns import mock from osc_lib.tests import utils class TestNeutronClientOSCV2(utils.TestCommand): def setUp(self): super(TestNeutronClientOSCV2, self).setUp() self.namespace = argparse.Namespace() self.app.client_manager.session = mock.Mock() self.app.client_manager.neutronclient = mock.Mock() self.neutronclient = self.app.client_manager.neutronclient self.addCleanup(mock.patch.stopall) # TODO(amotoki): Move this to osc_lib def assertListItemEqual(self, expected, actual): self.assertEqual(len(expected), len(actual)) for item_expected, item_actual in zip(expected, actual): self.assertItemEqual(item_expected, item_actual) # TODO(amotoki): Move this to osc_lib def assertItemEqual(self, expected, actual): self.assertEqual(len(expected), len(actual)) for col_expected, col_actual in zip(expected, actual): if isinstance(col_expected, cliff_columns.FormattableColumn): self.assertIsInstance(col_actual, col_expected.__class__) self.assertEqual(col_expected.human_readable(), col_actual.human_readable()) else: self.assertEqual(col_expected, col_actual) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/fwaas/0000775000175100017510000000000013232473710025210 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/fwaas/common.py0000666000175100017510000002543413232473350027064 0ustar zuulzuul00000000000000# Copyright 2016-2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import testtools from osc_lib import exceptions from osc_lib.tests import utils from neutronclient.tests.unit.osc.v2 import fakes as test_fakes class TestListFWaaS(test_fakes.TestNeutronClientOSCV2): def test_list_with_no_option(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.list_headers), headers) self.assertEqual([self.list_data], list(data)) def test_list_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.headers), headers) self.assertListItemEqual([self.data], list(data)) class TestShowFWaaS(test_fakes.TestNeutronClientOSCV2): def test_show_filtered_by_id_or_name(self): target = self.resource['id'] def _mock_fwaas(*args, **kwargs): # Find specified ingress_firewall_policy if self.neutronclient.find_resource.call_count == 1: self.assertEqual(self.res, args[0]) self.assertEqual(self.resource['id'], args[1]) self.assertEqual({'cmd_resource': 'fwaas_' + self.res}, kwargs) return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_fwaas arglist = [target] verifylist = [(self.res, target)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with(target) self.assertEqual(self.ordered_headers, headers) self.assertItemEqual(self.ordered_data, data) class TestCreateFWaaS(test_fakes.TestNeutronClientOSCV2): pass class TestSetFWaaS(test_fakes.TestNeutronClientOSCV2): def test_set_name(self): target = self.resource['id'] update = 'change' arglist = [target, '--name', update] verifylist = [ (self.res, target), ('name', update), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'name': update}}) self.assertIsNone(result) def test_set_description(self): target = self.resource['id'] update = 'change-desc' arglist = [target, '--description', update] verifylist = [ (self.res, target), ('description', update), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'description': update}}) self.assertIsNone(result) def test_set_shared(self): target = self.resource['id'] arglist = [target, '--share'] verifylist = [ (self.res, target), ('share', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'shared': True}}) self.assertIsNone(result) def test_set_public(self): target = self.resource['id'] arglist = [target, '--public'] verifylist = [ (self.res, target), ('public', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'shared': True}}) self.assertIsNone(result) def test_set_duplicate_shared(self): target = self.resource['id'] arglist = [target, '--share', '--share'] verifylist = [ (self.res, target), ('share', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'shared': True}}) self.assertIsNone(result) def test_set_no_share(self): target = self.resource['id'] arglist = [target, '--no-share'] verifylist = [ (self.res, target), ('share', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'shared': False}}) self.assertIsNone(result) def test_set_duplicate_no_share(self): target = self.resource['id'] arglist = [target, '--no-share', '--no-share'] verifylist = [ (self.res, target), ('no_share', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'shared': False}}) self.assertIsNone(result) def test_set_no_share_and_shared(self): target = self.resource['id'] arglist = [target, '--no-share', '--share'] verifylist = [ (self.res, target), ('no_share', True), ('share', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_set_shared_and_no_share(self): target = self.resource['id'] arglist = [target, '--share', '--no_share'] verifylist = [ (self.res, target), ('share', True), ('no_share', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_set_project(self): target = self.resource['id'] project_id = 'b14ce3b699594d13819a859480286489' arglist = [target, '--project', project_id] verifylist = [ (self.res, target), ('tenant_id', project_id), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_set_project_domain(self): target = self.resource['id'] project_domain = 'mydomain.com' arglist = [target, '--project-domain', project_domain] verifylist = [ (self.res, target), ('project_domain', project_domain), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) class TestDeleteFWaaS(test_fakes.TestNeutronClientOSCV2): def test_delete_with_one_resource(self): target = self.resource['id'] arglist = [target] verifylist = [(self.res, [target])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with(target) self.assertIsNone(result) def test_delete_with_multiple_resources(self): def _mock_fwaas(*args, **kwargs): self.assertEqual(self.res, args[0]) self.assertIsNotNone(args[1]) self.assertEqual({'cmd_resource': 'fwaas_' + self.res}, kwargs) return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_fwaas target1 = 'target1' target2 = 'target2' arglist = [target1, target2] verifylist = [(self.res, [target1, target2])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.assertIsNone(result) self.assertEqual(2, self.mocked.call_count) for idx, reference in enumerate([target1, target2]): actual = ''.join(self.mocked.call_args_list[idx][0]) self.assertEqual(reference, actual) def test_delete_multiple_with_exception(self): target1 = 'target' arglist = [target1] verifylist = [(self.res, [target1])] self.neutronclient.find_resource.side_effect = [ target1, exceptions.CommandError ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) resource_name = self.res.replace('_', ' ') msg = "1 of 2 %s(s) failed to delete." % resource_name with testtools.ExpectedException(exceptions.CommandError) as e: self.cmd.take_action(parsed_args) self.assertEqual(msg, str(e)) class TestUnsetFWaaS(test_fakes.TestNeutronClientOSCV2): def test_unset_shared(self): target = self.resource['id'] arglist = [ target, '--share', ] verifylist = [ (self.res, target), ('share', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'shared': False}}) self.assertIsNone(result) def test_set_shared_and_no_shared(self): target = self.resource['id'] arglist = [target, '--share', '--no-share'] verifylist = [ (self.res, target), ('share', True), ('no_share', True), ] # check_parser: error: unrecognized arguments: --no-share self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_set_duplicate_shared(self): target = self.resource['id'] arglist = [target, '--share', '--share'] verifylist = [ (self.res, target), ('share', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'shared': False}}) self.assertIsNone(result) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/fwaas/test_firewallgroup.py0000666000175100017510000006263313232473350031517 0ustar zuulzuul00000000000000# Copyright 2016 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy import re import mock from osc_lib import exceptions from osc_lib.tests import utils from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.fwaas import constants as const from neutronclient.osc.v2.fwaas import firewallgroup from neutronclient.osc.v2 import utils as v2_utils from neutronclient.tests.unit.osc.v2 import fakes as test_fakes from neutronclient.tests.unit.osc.v2.fwaas import common from neutronclient.tests.unit.osc.v2.fwaas import fakes _fwg = fakes.FirewallGroup().create() CONVERT_MAP = { 'ingress_firewall_policy': 'ingress_firewall_policy_id', 'egress_firewall_policy': 'egress_firewall_policy_id', 'no_ingress_firewall_policy': 'ingress_firewall_policy_id', 'no_egress_firewall_policy': 'egress_firewall_policy_id', 'share': 'shared', 'no_share': 'shared', 'project': 'tenant_id', 'enable': 'admin_state_up', 'disable': 'admin_state_up', 'port': 'ports', } def _generate_response(ordered_dict=None, data=None): source = ordered_dict if ordered_dict else _fwg up = {'admin_state_up': v2_utils.AdminStateColumn(source['admin_state_up'])} if data: up.append(data) source.update(up) return tuple(source[key] for key in source) def _generate_req_and_res(verifylist): request = dict(verifylist) response = copy.deepcopy(_fwg) for key, val in verifylist: del request[key] if re.match('^no_', key) and val is True: new_value = None elif key == 'enable' and val: new_value = True elif key == 'disable' and val: new_value = False else: new_value = val converted = CONVERT_MAP.get(key, key) request[converted] = new_value response[converted] = new_value return request, response class TestFirewallGroup(test_fakes.TestNeutronClientOSCV2): def check_results(self, headers, data, exp_req, is_list=False): if is_list: req_body = {self.res_plural: [exp_req]} else: req_body = {self.res: exp_req} self.mocked.assert_called_once_with(req_body) self.assertEqual(self.ordered_headers, headers) self.assertItemEqual(self.ordered_data, data) def setUp(self): super(TestFirewallGroup, self).setUp() def _find_resource(*args, **kwargs): return {'id': args[1], 'ports': _fwg['ports']} self.neutronclient.find_resource = mock.Mock( side_effect=_find_resource) osc_utils.find_project = mock.Mock() osc_utils.find_project.id = _fwg['tenant_id'] self.res = 'firewall_group' self.res_plural = 'firewall_groups' self.resource = _fwg self.list_headers = ( 'ID', 'Name', 'Ingress Policy ID', 'Egress Policy ID', ) self.list_data = ( _fwg['id'], _fwg['name'], _fwg['ingress_firewall_policy_id'], _fwg['egress_firewall_policy_id'], ) self.headers = tuple(self.list_headers + ( 'Description', 'Status', 'Ports', 'State', 'Shared', 'Project', )) self.data = _generate_response() self.ordered_headers = copy.deepcopy(tuple(sorted(self.headers))) self.ordered_data = ( _fwg['description'], _fwg['egress_firewall_policy_id'], _fwg['id'], _fwg['ingress_firewall_policy_id'], _fwg['name'], _fwg['ports'], _fwg['tenant_id'], _fwg['shared'], v2_utils.AdminStateColumn(_fwg['admin_state_up']), _fwg['status'], ) self.ordered_columns = ( 'description', 'egress_firewall_policy_id', 'id', 'ingress_firewall_policy_id', 'name', 'ports', 'tenant_id', 'shared', 'admin_state_up', 'status', ) class TestCreateFirewallGroup(TestFirewallGroup, common.TestCreateFWaaS): def setUp(self): # Mock objects super(TestCreateFirewallGroup, self).setUp() self.neutronclient.create_fwaas_firewall_group = mock.Mock( return_value={self.res: _fwg}) self.mocked = self.neutronclient.create_fwaas_firewall_group self.cmd = firewallgroup.CreateFirewallGroup(self.app, self.namespace) def _update_expect_response(self, request, response): """Set expected request and response :param request A dictionary of request body(dict of verifylist) :param response A OrderedDict of request body """ # Update response body self.neutronclient.create_fwaas_firewall_group.return_value = \ {self.res: dict(response)} osc_utils.find_project.return_value.id = response['tenant_id'] # Update response(finally returns 'data') self.data = _generate_response(ordered_dict=response) self.ordered_data = tuple( response[column] for column in self.ordered_columns ) def test_create_with_no_option(self): # firewall_group-create with mandatory (none) params. arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.assertEqual(self.ordered_headers, headers) self.assertItemEqual(self.ordered_data, data) def test_create_with_port(self): # firewall_group-create with 'port' port_id = 'id_for_port' arglist = ['--port', port_id] verifylist = [('port', [port_id])] request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.check_results(headers, data, request) def test_create_with_ingress_policy(self): ingress_policy = 'my-ingress-policy' def _mock_port_fwg(*args, **kwargs): return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_port_fwg arglist = ['--ingress-firewall-policy', ingress_policy] verifylist = [('ingress_firewall_policy', ingress_policy)] request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.neutronclient.find_resource.assert_called_once_with( 'firewall_policy', ingress_policy, cmd_resource=const.CMD_FWP) self.check_results(headers, data, request) def test_create_with_egress_policy(self): egress_policy = 'my-egress-policy' def _mock_port_fwg(*args, **kwargs): return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_port_fwg arglist = ['--egress-firewall-policy', egress_policy] verifylist = [('egress_firewall_policy', egress_policy)] request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.neutronclient.find_resource.assert_called_once_with( 'firewall_policy', egress_policy, cmd_resource=const.CMD_FWP) self.check_results(headers, data, request) def test_create_with_all_params(self): name = 'my-name' description = 'my-desc' ingress_policy = 'my-ingress-policy' egress_policy = 'my-egress-policy' port = 'port' tenant_id = 'my-tenant' arglist = [ '--name', name, '--description', description, '--ingress-firewall-policy', ingress_policy, '--egress-firewall-policy', egress_policy, '--port', port, '--project', tenant_id, '--share', '--disable', ] verifylist = [ ('name', name), ('description', description), ('ingress_firewall_policy', ingress_policy), ('egress_firewall_policy', egress_policy), ('port', [port]), ('share', True), ('project', tenant_id), ('disable', True), ] request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.check_results(headers, data, request) def test_create_with_shared_and_no_share(self): arglist = [ '--share', '--no-share', ] verifylist = [ ('share', True), ('no_share', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_ports_and_no(self): port = 'my-port' arglist = [ '--port', port, '--no-port', ] verifylist = [ ('port', [port]), ('no_port', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_ingress_policy_and_no(self): policy = 'my-policy' arglist = [ '--ingress-firewall-policy', policy, '--no-ingress-firewall-policy', ] verifylist = [ ('ingress_firewall_policy', policy), ('no_ingress_firewall_policy', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_egress_policy_and_no(self): policy = 'my-policy' arglist = [ '--egress-firewall-policy', policy, '--no-egress-firewall-policy', ] verifylist = [ ('egress_firewall_policy', policy), ('no_egress_firewall_policy', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) class TestListFirewallGroup(TestFirewallGroup, common.TestListFWaaS): def setUp(self): super(TestListFirewallGroup, self).setUp() # Mock objects self.neutronclient.list_fwaas_firewall_groups = mock.Mock( return_value={self.res_plural: [_fwg]}) self.mocked = self.neutronclient.list_fwaas_firewall_groups self.cmd = firewallgroup.ListFirewallGroup(self.app, self.namespace) class TestShowFirewallGroup(TestFirewallGroup, common.TestShowFWaaS): def setUp(self): super(TestShowFirewallGroup, self).setUp() # Mock objects self.neutronclient.show_fwaas_firewall_group = mock.Mock( return_value={self.res: _fwg}) self.mocked = self.neutronclient.show_fwaas_firewall_group self.cmd = firewallgroup.ShowFirewallGroup(self.app, self.namespace) class TestSetFirewallGroup(TestFirewallGroup, common.TestSetFWaaS): def setUp(self): super(TestSetFirewallGroup, self).setUp() # Mock objects _fwg['ports'] = ['old_port'] self.neutronclient.update_fwaas_firewall_group = mock.Mock( return_value={self.res: _fwg}) self.mocked = self.neutronclient.update_fwaas_firewall_group self.cmd = firewallgroup.SetFirewallGroup(self.app, self.namespace) def _update_expect_response(self, request, response): """Set expected request and response :param request A dictionary of request body(dict of verifylist) :param response A OrderedDict of request body """ osc_utils.find_project.return_value.id = response['tenant_id'] # Update response(finally returns 'data') self.data = _generate_response(ordered_dict=response) self.ordered_data = tuple( response[column] for column in self.ordered_columns ) def test_set_ingress_policy_and_egress_policy(self): target = self.resource['id'] ingress_policy = 'ingress_policy' egress_policy = 'egress_policy' def _mock_fwg_policy(*args, **kwargs): # 1. Find specified firewall_group if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource=const.CMD_FWG) # 2. Find specified 'ingress_firewall_policy' if self.neutronclient.find_resource.call_count == 2: self.neutronclient.find_resource.assert_called_with( 'firewall_policy', ingress_policy, cmd_resource=const.CMD_FWP) # 3. Find specified 'ingress_firewall_policy' if self.neutronclient.find_resource.call_count == 3: self.neutronclient.find_resource.assert_called_with( 'firewall_policy', egress_policy, cmd_resource=const.CMD_FWP) return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_fwg_policy arglist = [ target, '--ingress-firewall-policy', ingress_policy, '--egress-firewall-policy', egress_policy, ] verifylist = [ (self.res, target), ('ingress_firewall_policy', ingress_policy), ('egress_firewall_policy', egress_policy), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'ingress_firewall_policy_id': ingress_policy, 'egress_firewall_policy_id': egress_policy}}) self.assertIsNone(result) def test_set_port(self): target = self.resource['id'] port1 = 'additional_port1' port2 = 'additional_port2' def _mock_port_fwg(*args, **kwargs): # 1. Find specified firewall_group if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource=const.CMD_FWG) return {'id': args[1]} # 2. Find specified 'port' #1 if self.neutronclient.find_resource.call_count == 2: self.neutronclient.find_resource.assert_called_with( 'port', args[1]) return {'id': args[1]} # 3. Find specified 'port' #2 if self.neutronclient.find_resource.call_count == 3: self.neutronclient.find_resource.assert_called_with( 'port', args[1]) return {'id': args[1]} # 4. Find specified firewall_group and refer 'ports' attribute if self.neutronclient.find_resource.call_count == 4: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource=const.CMD_FWG) return {'ports': _fwg['ports']} self.neutronclient.find_resource.side_effect = _mock_port_fwg arglist = [ target, '--port', port1, '--port', port2, ] verifylist = [ (self.res, target), ('port', [port1, port2]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) expect = {'ports': sorted(_fwg['ports'] + [port1, port2])} self.mocked.assert_called_once_with(target, {self.res: expect}) self.assertEqual(4, self.neutronclient.find_resource.call_count) self.assertIsNone(result) def test_set_no_port(self): # firewall_group-update myid --policy newpolicy. target = self.resource['id'] arglist = [target, '--no-port'] verifylist = [ (self.res, target), ('no_port', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'ports': []}}) self.assertIsNone(result) def test_set_admin_state(self): target = self.resource['id'] arglist = [target, '--enable'] verifylist = [ (self.res, target), ('enable', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'admin_state_up': True}}) self.assertIsNone(result) def test_set_egress_policy(self): target = self.resource['id'] policy = 'egress_policy' arglist = [target, '--egress-firewall-policy', policy] verifylist = [ (self.res, target), ('egress_firewall_policy', policy), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'egress_firewall_policy_id': policy}}) self.assertIsNone(result) def test_set_no_ingress_policies(self): target = self.resource['id'] arglist = [target, '--no-ingress-firewall-policy'] verifylist = [ (self.res, target), ('no_ingress_firewall_policy', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'ingress_firewall_policy_id': None}}) self.assertIsNone(result) def test_set_no_egress_policies(self): target = self.resource['id'] arglist = [target, '--no-egress-firewall-policy'] verifylist = [ (self.res, target), ('no_egress_firewall_policy', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'egress_firewall_policy_id': None}}) self.assertIsNone(result) def test_set_port_and_no_port(self): target = self.resource['id'] port = 'my-port' arglist = [ target, '--port', port, '--no-port', ] verifylist = [ (self.res, target), ('port', [port]), ('no_port', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'ports': [port]}}) self.assertIsNone(result) def test_set_ingress_policy_and_no_ingress_policy(self): target = self.resource['id'] arglist = [ target, '--ingress-firewall-policy', 'my-ingress', '--no-ingress-firewall-policy', ] verifylist = [ (self.res, target), ('ingress_firewall_policy', 'my-ingress'), ('no_ingress_firewall_policy', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_set_egress_policy_and_no_egress_policy(self): target = self.resource['id'] arglist = [ target, '--egress-firewall-policy', 'my-egress', '--no-egress-firewall-policy', ] verifylist = [ (self.res, target), ('egress_firewall_policy', 'my-egress'), ('no_egress_firewall_policy', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_set_and_raises(self): self.neutronclient.update_fwaas_firewall_group = mock.Mock( side_effect=Exception) target = self.resource['id'] arglist = [target, '--name', 'my-name'] verifylist = [(self.res, target), ('name', 'my-name')] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args) class TestDeleteFirewallGroup(TestFirewallGroup, common.TestDeleteFWaaS): def setUp(self): super(TestDeleteFirewallGroup, self).setUp() # Mock objects self.neutronclient.delete_fwaas_firewall_group = mock.Mock() self.mocked = self.neutronclient.delete_fwaas_firewall_group self.cmd = firewallgroup.DeleteFirewallGroup(self.app, self.namespace) class TestUnsetFirewallGroup(TestFirewallGroup, common.TestUnsetFWaaS): def setUp(self): super(TestUnsetFirewallGroup, self).setUp() _fwg['ports'] = ['old_port'] # Mock objects self.neutronclient.update_fwaas_firewall_group = mock.Mock() self.mocked = self.neutronclient.update_fwaas_firewall_group self.cmd = firewallgroup.UnsetFirewallGroup(self.app, self.namespace) def test_unset_ingress_policy(self): target = self.resource['id'] arglist = [ target, '--ingress-firewall-policy', ] verifylist = [ (self.res, target), ('ingress_firewall_policy', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'ingress_firewall_policy_id': None}}) self.assertIsNone(result) def test_unset_egress_policy(self): target = self.resource['id'] arglist = [ target, '--egress-firewall-policy', ] verifylist = [ (self.res, target), ('egress_firewall_policy', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'egress_firewall_policy_id': None}}) self.assertIsNone(result) def test_unset_enable(self): target = self.resource['id'] arglist = [ target, '--enable', ] verifylist = [ (self.res, target), ('enable', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'admin_state_up': False}}) self.assertIsNone(result) def test_unset_port(self): target = self.resource['id'] port = 'old_port' def _mock_port_fwg(*args, **kwargs): # 1. Find specified firewall_group if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource=const.CMD_FWG) return {'id': args[1]} # 2. Find specified firewall_group and refer 'ports' attribute if self.neutronclient.find_resource.call_count == 2: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource=const.CMD_FWG) return {'ports': _fwg['ports']} # 3. Find specified 'port' if self.neutronclient.find_resource.call_count == 3: self.neutronclient.find_resource.assert_called_with( 'port', port) return {'id': args[1]} self.neutronclient.find_resource.side_effect = mock.Mock( side_effect=_mock_port_fwg) arglist = [ target, '--port', port, ] verifylist = [ (self.res, target), ('port', [port]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with(target, {self.res: {'ports': []}}) self.assertIsNone(result) def test_unset_all_port(self): target = self.resource['id'] arglist = [ target, '--all-port', ] verifylist = [ (self.res, target), ('all_port', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with(target, {self.res: {'ports': []}}) self.assertIsNone(result) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/fwaas/fakes.py0000666000175100017510000001035013232473350026654 0ustar zuulzuul00000000000000# Copyright 2016 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import collections import copy import mock from oslo_utils import uuidutils class FakeFWaaS(object): def create(self, attrs={}): """Create a fake fwaas resources :param Dictionary attrs: A dictionary with all attributes :return: A OrderedDict faking the fwaas resource """ self.ordered.update(attrs) return copy.deepcopy(self.ordered) def bulk_create(self, attrs=None, count=2): """Create multiple fake fwaas resources :param Dictionary attrs: A dictionary with all attributes :param int count: The number of fwaas resources to fake :return: A list of dictionaries faking the fwaas resources """ return [self.create(attrs=attrs) for i in range(0, count)] def get(self, attrs=None, count=2): """Create multiple fake fwaas resources :param Dictionary attrs: A dictionary with all attributes :param int count: The number of fwaas resources to fake :return: A list of dictionaries faking the fwaas resource """ if attrs is None: self.attrs = self.bulk_create(count=count) return mock.Mock(side_effect=attrs) class FirewallGroup(FakeFWaaS): """Fake one or more firewall group""" def __init__(self): super(FirewallGroup, self).__init__() self.ordered = collections.OrderedDict(( ('id', 'firewall-group-id-' + uuidutils.generate_uuid(dashed=False)), ('name', 'my-group-' + uuidutils.generate_uuid(dashed=False)), ('ingress_firewall_policy_id', None), ('egress_firewall_policy_id', None), ('description', 'my-desc-' + uuidutils.generate_uuid(dashed=False)), ('status', 'INACTIVE'), ('ports', []), ('admin_state_up', True), ('shared', False), ('tenant_id', 'tenant-id-' + uuidutils.generate_uuid(dashed=False)), )) class FirewallPolicy(FakeFWaaS): """Fake one or more firewall policy""" def __init__(self): super(FirewallPolicy, self).__init__() self.ordered = collections.OrderedDict(( ('id', 'firewall-policy-' + uuidutils.generate_uuid(dashed=False)), ('name', 'my-policy-' + uuidutils.generate_uuid(dashed=False)), ('firewall_rules', []), ('description', 'my-desc-' + uuidutils.generate_uuid(dashed=False)), ('audited', True), ('shared', False), ('tenant_id', 'tenant-id-' + uuidutils.generate_uuid(dashed=False)), )) class FirewallRule(FakeFWaaS): """Fake one or more firewall rule""" def __init__(self): super(FirewallRule, self).__init__() self.ordered = collections.OrderedDict(( ('id', 'firewall-rule-id-' + uuidutils.generate_uuid(dashed=False)), ('name', 'my-rule-' + uuidutils.generate_uuid(dashed=False)), ('enabled', False), ('description', 'my-desc-' + uuidutils.generate_uuid(dashed=False)), ('ip_version', 4), ('action', 'deny'), ('protocol', None), ('source_ip_address', '192.168.1.0/24'), ('source_port', '1:11111'), ('destination_ip_address', '192.168.2.2'), ('destination_port', '2:22222'), ('shared', False), ('tenant_id', 'tenant-id-' + uuidutils.generate_uuid(dashed=False)), )) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/fwaas/test_firewallrule.py0000666000175100017510000006322513232473350031330 0ustar zuulzuul00000000000000# Copyright 2016 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy import re import mock from osc_lib import exceptions from osc_lib.tests import utils import testtools from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.fwaas import constants as const from neutronclient.osc.v2.fwaas import firewallrule from neutronclient.tests.unit.osc.v2 import fakes as test_fakes from neutronclient.tests.unit.osc.v2.fwaas import common from neutronclient.tests.unit.osc.v2.fwaas import fakes _fwr = fakes.FirewallRule().create() CONVERT_MAP = { 'project': 'tenant_id', 'enable_rule': 'enabled', 'disable_rule': 'enabled', 'share': 'shared', 'no_share': 'shared', } def _generate_data(ordered_dict=None, data=None): source = ordered_dict if ordered_dict else _fwr if data: source.update(data) return tuple(_replace_display_columns(key, source[key]) for key in source) def _replace_display_columns(key, val): if key == 'protocol': return firewallrule.ProtocolColumn(val) return val def _generate_req_and_res(verifylist): request = dict(verifylist) response = copy.deepcopy(_fwr) for key, val in verifylist: converted = CONVERT_MAP.get(key, key) del request[key] if re.match('^no_', key) and val is True: new_value = None elif (key == 'enable' or key == 'enable_rule') and val: new_value = True elif (key == 'disable' or key == 'disable_rule') and val: new_value = False elif (key == 'protocol' and val and val.lower() == 'any'): new_value = None else: new_value = val request[converted] = new_value response[converted] = new_value return request, response class TestFirewallRule(test_fakes.TestNeutronClientOSCV2): def check_results(self, headers, data, exp_req, is_list=False): if is_list: req_body = {self.res_plural: [exp_req]} else: req_body = {self.res: exp_req} self.mocked.assert_called_once_with(req_body) self.assertEqual(self.ordered_headers, headers) self.assertItemEqual(self.ordered_data, data) def setUp(self): super(TestFirewallRule, self).setUp() def _mock_fwr(*args, **kwargs): self.neutronclient.find_resource.assert_called_once_with( self.res, self.resource['id'], cmd_resource=const.CMD_FWR) return {'id': args[1]} self.neutronclient.find_resource.side_effect = mock.Mock( side_effect=_mock_fwr) osc_utils.find_project = mock.Mock() osc_utils.find_project.id = _fwr['tenant_id'] self.res = 'firewall_rule' self.res_plural = 'firewall_rules' self.resource = _fwr self.headers = ( 'ID', 'Name', 'Enabled', 'Description', 'IP Version', 'Action', 'Protocol', 'Source IP Address', 'Source Port', 'Destination IP Address', 'Destination Port', 'Shared', 'Project', ) self.data = _generate_data() self.ordered_headers = ( 'Action', 'Description', 'Destination IP Address', 'Destination Port', 'Enabled', 'ID', 'IP Version', 'Name', 'Project', 'Protocol', 'Shared', 'Source IP Address', 'Source Port', ) self.ordered_data = ( _fwr['action'], _fwr['description'], _fwr['destination_ip_address'], _fwr['destination_port'], _fwr['enabled'], _fwr['id'], _fwr['ip_version'], _fwr['name'], _fwr['tenant_id'], _replace_display_columns('protocol', _fwr['protocol']), _fwr['shared'], _fwr['source_ip_address'], _fwr['source_port'], ) self.ordered_columns = ( 'action', 'description', 'destination_ip_address', 'destination_port', 'enabled', 'id', 'ip_version', 'name', 'tenant_id', 'protocol', 'shared', 'source_ip_address', 'source_port', ) class TestCreateFirewallRule(TestFirewallRule, common.TestCreateFWaaS): def setUp(self): super(TestCreateFirewallRule, self).setUp() self.neutronclient.create_fwaas_firewall_rule = mock.Mock( return_value={self.res: _fwr}) self.mocked = self.neutronclient.create_fwaas_firewall_rule self.cmd = firewallrule.CreateFirewallRule(self.app, self.namespace) def _update_expect_response(self, request, response): """Set expected request and response :param request A dictionary of request body(dict of verifylist) :param response A OrderedDict of request body """ # Update response body self.neutronclient.create_fwaas_firewall_rule.return_value = \ {self.res: dict(response)} osc_utils.find_project.return_value.id = response['tenant_id'] # Update response(finally returns 'data') self.data = _generate_data(ordered_dict=response) self.ordered_data = tuple( _replace_display_columns(column, response[column]) for column in self.ordered_columns ) def _set_all_params(self, args={}): name = args.get('name') or 'my-name' description = args.get('description') or 'my-desc' source_ip = args.get('source_ip_address') or '192.168.1.0/24' destination_ip = args.get('destination_ip_address') or '192.168.2.0/24' source_port = args.get('source_port') or '0:65535' protocol = args.get('protocol') or 'udp' action = args.get('action') or 'deny' ip_version = args.get('ip_version') or '4' destination_port = args.get('destination_port') or '0:65535' tenant_id = args.get('tenant_id') or 'my-tenant' arglist = [ '--description', description, '--name', name, '--protocol', protocol, '--ip-version', ip_version, '--source-ip-address', source_ip, '--destination-ip-address', destination_ip, '--source-port', source_port, '--destination-port', destination_port, '--action', action, '--project', tenant_id, '--disable-rule', '--share', ] verifylist = [ ('name', name), ('description', description), ('share', True), ('protocol', protocol), ('ip_version', ip_version), ('source_ip_address', source_ip), ('destination_ip_address', destination_ip), ('source_port', source_port), ('destination_port', destination_port), ('action', action), ('disable_rule', True), ('project', tenant_id), ] return arglist, verifylist def _test_create_with_all_params(self, args={}): arglist, verifylist = self._set_all_params(args) request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.check_results(headers, data, request) def test_create_with_no_options(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.check_results(headers, data, {}) def test_create_with_all_params(self): self._test_create_with_all_params() def test_create_with_all_params_protocol_any(self): self._test_create_with_all_params({'protocol': 'any'}) def test_create_with_all_params_ip_version_6(self): self._test_create_with_all_params({'ip_version': '6'}) def test_create_with_all_params_invalid_ip_version(self): arglist, verifylist = self._set_all_params({'ip_version': '128'}) self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_all_params_action_upper_capitalized(self): for action in ('Allow', 'DENY', 'Reject'): arglist, verifylist = self._set_all_params({'action': action}) self.assertRaises( testtools.matchers._impl.MismatchError, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_all_params_protocol_upper_capitalized(self): for protocol in ('TCP', 'Tcp', 'ANY', 'AnY', 'iCMp'): arglist, verifylist = self._set_all_params({'protocol': protocol}) self.assertRaises( testtools.matchers._impl.MismatchError, self.check_parser, self.cmd, arglist, verifylist) class TestListFirewallRule(TestFirewallRule): def _setup_summary(self, expect=None): protocol = (_fwr['protocol'] or 'any').upper() src = 'source(port): 192.168.1.0/24(1:11111)' dst = 'dest(port): 192.168.2.2(2:22222)' action = 'deny' if expect: if expect.get('protocol'): protocol = expect['protocol'] if expect.get('source'): src = expect['source'] if expect.get('dest'): dst = expect['dest'] if expect.get('action'): action = expect['action'] summary = ',\n '.join([protocol, src, dst, action]) self.short_data = ( _fwr['id'], _fwr['name'], _fwr['enabled'], summary ) def setUp(self): super(TestListFirewallRule, self).setUp() self.cmd = firewallrule.ListFirewallRule(self.app, self.namespace) self.short_header = ( 'ID', 'Name', 'Enabled', 'Summary', ) self._setup_summary() self.neutronclient.list_fwaas_firewall_rules = mock.Mock( return_value={self.res_plural: [_fwr]}) self.mocked = self.neutronclient.list_fwaas_firewall_rules def test_list_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.headers), headers) self.assertListItemEqual([self.data], list(data)) def test_list_with_no_option(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.short_header), headers) self.assertListItemEqual([self.short_data], list(data)) class TestShowFirewallRule(TestFirewallRule, common.TestShowFWaaS): def setUp(self): super(TestShowFirewallRule, self).setUp() self.neutronclient.show_fwaas_firewall_rule = mock.Mock( return_value={self.res: _fwr}) self.mocked = self.neutronclient.show_fwaas_firewall_rule self.cmd = firewallrule.ShowFirewallRule(self.app, self.namespace) class TestSetFirewallRule(TestFirewallRule, common.TestSetFWaaS): def setUp(self): super(TestSetFirewallRule, self).setUp() self.neutronclient.update_fwaas_firewall_rule = mock.Mock( return_value={self.res: _fwr}) self.mocked = self.neutronclient.update_fwaas_firewall_rule self.cmd = firewallrule.SetFirewallRule(self.app, self.namespace) def test_set_protocol_with_any(self): target = self.resource['id'] protocol = 'any' arglist = [target, '--protocol', protocol] verifylist = [ (self.res, target), ('protocol', protocol), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'protocol': None}}) self.assertIsNone(result) def test_set_protocol_with_udp(self): target = self.resource['id'] protocol = 'udp' arglist = [target, '--protocol', protocol] verifylist = [ (self.res, target), ('protocol', protocol), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'protocol': protocol}}) self.assertIsNone(result) def test_set_source_ip_address(self): target = self.resource['id'] src_ip = '192.192.192.192' arglist = [target, '--source-ip-address', src_ip] verifylist = [ (self.res, target), ('source_ip_address', src_ip), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'source_ip_address': src_ip}}) self.assertIsNone(result) def test_set_source_port(self): target = self.resource['id'] src_port = '32678' arglist = [target, '--source-port', src_port] verifylist = [ (self.res, target), ('source_port', src_port), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'source_port': src_port}}) self.assertIsNone(result) def test_set_destination_ip_address(self): target = self.resource['id'] dst_ip = '0.1.0.1' arglist = [target, '--destination-ip-address', dst_ip] verifylist = [ (self.res, target), ('destination_ip_address', dst_ip), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'destination_ip_address': dst_ip}}) self.assertIsNone(result) def test_set_destination_port(self): target = self.resource['id'] dst_port = '65432' arglist = [target, '--destination-port', dst_port] verifylist = [ (self.res, target), ('destination_port', dst_port), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'destination_port': dst_port}}) self.assertIsNone(result) def test_set_enable_rule(self): target = self.resource['id'] arglist = [target, '--enable-rule'] verifylist = [ (self.res, target), ('enable_rule', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'enabled': True}}) self.assertIsNone(result) def test_set_disable_rule(self): target = self.resource['id'] arglist = [target, '--disable-rule'] verifylist = [ (self.res, target), ('disable_rule', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'enabled': False}}) self.assertIsNone(result) def test_set_action(self): target = self.resource['id'] action = 'reject' arglist = [target, '--action', action] verifylist = [ (self.res, target), ('action', action), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'action': action}}) self.assertIsNone(result) def test_set_enable_rule_and_disable_rule(self): target = self.resource['id'] arglist = [target, '--enable-rule', '--disable-rule'] verifylist = [ (self.res, target), ('enable_rule', True), ('disable_rule', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_set_no_source_ip_address(self): target = self.resource['id'] arglist = [ target, '--no-source-ip-address', ] verifylist = [ (self.res, target), ('no_source_ip_address', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'source_ip_address': None}}) self.assertIsNone(result) def test_set_no_source_port(self): target = self.resource['id'] arglist = [ target, '--no-source-port', ] verifylist = [ (self.res, target), ('no_source_port', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'source_port': None}}) self.assertIsNone(result) def test_set_no_destination_ip_address(self): target = self.resource['id'] arglist = [ target, '--no-destination-ip-address', ] verifylist = [ (self.res, target), ('no_destination_ip_address', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'destination_ip_address': None}}) self.assertIsNone(result) def test_set_no_destination_port(self): target = self.resource['id'] arglist = [ target, '--no-destination-port', ] verifylist = [ (self.res, target), ('no_destination_port', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'destination_port': None}}) self.assertIsNone(result) def test_set_source_ip_address_and_no(self): target = self.resource['id'] arglist = [ target, '--source-ip-address', '192.168.1.0/24', '--no-source-ip-address', ] verifylist = [ (self.res, target), ('source_ip_address', '192.168.1.0/24'), ('no_source_ip_address', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_set_destination_ip_address_and_no(self): target = self.resource['id'] arglist = [ target, '--destination-ip-address', '192.168.2.0/24', '--no-destination-ip-address', ] verifylist = [ (self.res, target), ('destination_ip_address', '192.168.2.0/24'), ('no_destination_ip_address', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_set_source_port_and_no(self): target = self.resource['id'] arglist = [ target, '--source-port', '1:12345', '--no-source-port', ] verifylist = [ (self.res, target), ('source_port', '1:12345'), ('no_source_port', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_set_destination_port_and_no(self): target = self.resource['id'] arglist = [ target, '--destination-port', '1:54321', '--no-destination-port', ] verifylist = [ (self.res, target), ('destination_port', '1:54321'), ('no_destination_port', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_set_and_raises(self): self.neutronclient.update_fwaas_firewall_rule = mock.Mock( side_effect=Exception) target = self.resource['id'] arglist = [target, '--name', 'my-name'] verifylist = [(self.res, target), ('name', 'my-name')] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args) class TestUnsetFirewallRule(TestFirewallRule, common.TestUnsetFWaaS): def setUp(self): super(TestUnsetFirewallRule, self).setUp() self.neutronclient.update_fwaas_firewall_rule = mock.Mock( return_value={self.res: _fwr}) self.mocked = self.neutronclient.update_fwaas_firewall_rule self.cmd = firewallrule.UnsetFirewallRule(self.app, self.namespace) def test_unset_protocol_and_raise(self): self.neutronclient.update_fwaas_firewall_rule.side_effect = Exception target = self.resource['id'] arglist = [ target, '--protocol', ] verifylist = [ (self.res, target), ('protocol', False) ] self.assertRaises(utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_unset_source_port(self): target = self.resource['id'] arglist = [ target, '--source-port', ] verifylist = [ (self.res, target), ('source_port', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'source_port': None}}) self.assertIsNone(result) def test_unset_destination_port(self): target = self.resource['id'] arglist = [ target, '--destination-port', ] verifylist = [ (self.res, target), ('destination_port', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'destination_port': None}}) self.assertIsNone(result) def test_unset_source_ip_address(self): target = self.resource['id'] arglist = [ target, '--source-ip-address', ] verifylist = [ (self.res, target), ('source_ip_address', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'source_ip_address': None}}) self.assertIsNone(result) def test_unset_destination_ip_address(self): target = self.resource['id'] arglist = [ target, '--destination-ip-address', ] verifylist = [ (self.res, target), ('destination_ip_address', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'destination_ip_address': None}}) self.assertIsNone(result) def test_unset_enable_rule(self): target = self.resource['id'] arglist = [ target, '--enable-rule', ] verifylist = [ (self.res, target), ('enable_rule', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'enabled': False}}) self.assertIsNone(result) class TestDeleteFirewallRule(TestFirewallRule, common.TestDeleteFWaaS): def setUp(self): super(TestDeleteFirewallRule, self).setUp() self.neutronclient.delete_fwaas_firewall_rule = mock.Mock( return_value={self.res: _fwr}) self.mocked = self.neutronclient.delete_fwaas_firewall_rule self.cmd = firewallrule.DeleteFirewallRule(self.app, self.namespace) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/fwaas/__init__.py0000666000175100017510000000000013232473350027311 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/fwaas/test_firewallpolicy.py0000666000175100017510000006051713232473350031661 0ustar zuulzuul00000000000000# Copyright 2016 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy import re import mock from osc_lib import exceptions from osc_lib.tests import utils from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.fwaas import constants as const from neutronclient.osc.v2.fwaas import firewallpolicy from neutronclient.tests.unit.osc.v2 import fakes as test_fakes from neutronclient.tests.unit.osc.v2.fwaas import common from neutronclient.tests.unit.osc.v2.fwaas import fakes _fwp = fakes.FirewallPolicy().create() CONVERT_MAP = { 'share': 'shared', 'no_share': 'shared', 'project': 'tenant_id', 'port': 'ports', 'name': 'name', 'id': 'id', 'firewall_rule': 'firewall_rules', 'description': 'description' } def _generate_data(ordered_dict=None, data=None): source = ordered_dict if ordered_dict else _fwp if data: source.update(data) return tuple(source[key] for key in source) def _generate_req_and_res(verifylist): request = dict(verifylist) response = copy.deepcopy(_fwp) for key, val in verifylist: converted = CONVERT_MAP.get(key, key) del request[key] if re.match('^no_', key) and val is True: new_value = None elif key == 'enable' and val: new_value = True elif key == 'disable' and val: new_value = False else: new_value = val request[converted] = new_value response[converted] = new_value return request, response class TestFirewallPolicy(test_fakes.TestNeutronClientOSCV2): def check_results(self, headers, data, exp_req, is_list=False): if is_list: req_body = {self.res_plural: [exp_req]} else: req_body = {self.res: exp_req} self.mocked.assert_called_once_with(req_body) self.assertEqual(self.ordered_headers, headers) self.assertEqual(self.ordered_data, data) def setUp(self): super(TestFirewallPolicy, self).setUp() def _find_resource(*args, **kwargs): rule_id = args[1] rules = [] if self.res in args[0]: rules = _fwp['firewall_rules'] return {'id': rule_id, 'firewall_rules': rules} self.neutronclient.find_resource = mock.Mock( side_effect=_find_resource) osc_utils.find_project = mock.Mock() osc_utils.find_project.id = _fwp['tenant_id'] self.res = 'firewall_policy' self.res_plural = 'firewall_policies' self.resource = _fwp self.list_headers = ( 'ID', 'Name', 'Firewall Rules', ) self.list_data = ( _fwp['id'], _fwp['name'], _fwp['firewall_rules'], ) self.headers = tuple(self.list_headers + ( 'Description', 'Audited', 'Shared', 'Project') ) self.data = _generate_data() self.ordered_headers = ( 'Audited', 'Description', 'Firewall Rules', 'ID', 'Name', 'Project', 'Shared', ) self.ordered_data = ( _fwp['audited'], _fwp['description'], _fwp['firewall_rules'], _fwp['id'], _fwp['name'], _fwp['tenant_id'], _fwp['shared'], ) self.ordered_columns = ( 'audited', 'description', 'firewall_rules', 'id', 'name', 'tenant_id', 'shared', ) class TestCreateFirewallPolicy(TestFirewallPolicy, common.TestCreateFWaaS): def setUp(self): super(TestCreateFirewallPolicy, self).setUp() self.neutronclient.create_fwaas_firewall_policy = mock.Mock( return_value={self.res: _fwp}) self.mocked = self.neutronclient.create_fwaas_firewall_policy self.cmd = firewallpolicy.CreateFirewallPolicy(self.app, self.namespace) def _update_expect_response(self, request, response): """Set expected request and response :param request A dictionary of request body(dict of verifylist) :param response A OrderedDict of request body """ # Update response body self.neutronclient.create_fwaas_firewall_policy.return_value = \ {self.res: dict(response)} osc_utils.find_project.return_value.id = response['tenant_id'] # Update response(finally returns 'data') self.data = _generate_data(data=response) self.ordered_data = tuple( response[column] for column in self.ordered_columns ) def test_create_with_no_options(self): arglist = [] verifylist = [] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_mandatory_param(self): name = 'my-fwg' arglist = [ name, ] verifylist = [ ('name', name), ] request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.check_results(headers, data, request) def test_create_with_rules(self): name = 'my-fwg' rule1 = 'rule1' rule2 = 'rule2' def _mock_policy(*args, **kwargs): self.neutronclient.find_resource.assert_called_with( 'firewall_rule', args[1], cmd_resource=const.CMD_FWR) return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_policy arglist = [ name, '--firewall-rule', rule1, '--firewall-rule', rule2, ] verifylist = [ ('name', name), ('firewall_rule', [rule1, rule2]), ] request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.assertEqual(2, self.neutronclient.find_resource.call_count) self.check_results(headers, data, request) def test_create_with_all_params(self): name = 'my-fwp' desc = 'my-desc' rule1 = 'rule1' rule2 = 'rule2' project = 'my-tenant' arglist = [ name, '--description', desc, '--firewall-rule', rule1, '--firewall-rule', rule2, '--project', project, '--share', '--audited', ] verifylist = [ ('name', name), ('description', desc), ('firewall_rule', [rule1, rule2]), ('project', project), ('share', True), ('audited', True), ] request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.check_results(headers, data, request) def test_create_with_firewall_rule_and_no(self): name = 'my-fwp' rule1 = 'rule1' rule2 = 'rule2' arglist = [ name, '--firewall-rule', rule1, '--firewall-rule', rule2, '--no-firewall-rule', ] verifylist = [ ('name', name), ('firewall_rule', [rule1, rule2]), ('no_firewall_rule', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_shared_and_no_share(self): name = 'my-fwp' arglist = [ name, '--share', '--no-share', ] verifylist = [ ('name', name), ('share', True), ('no_share', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_audited_and_no(self): name = 'my-fwp' arglist = [ name, '--audited', '--no-audited', ] verifylist = [ ('name', name), ('audited', True), ('no_audited', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) class TestListFirewallPolicy(TestFirewallPolicy, common.TestListFWaaS): def setUp(self): super(TestListFirewallPolicy, self).setUp() self.neutronclient.list_fwaas_firewall_policies = mock.Mock( return_value={'firewall_policies': [_fwp]}) self.mocked = self.neutronclient.list_fwaas_firewall_policies self.cmd = firewallpolicy.ListFirewallPolicy(self.app, self.namespace) class TestShowFirewallPolicy(TestFirewallPolicy, common.TestShowFWaaS): def setUp(self): super(TestShowFirewallPolicy, self).setUp() self.neutronclient.show_fwaas_firewall_policy = mock.Mock( return_value={self.res: _fwp}) self.mocked = self.neutronclient.show_fwaas_firewall_policy self.cmd = firewallpolicy.ShowFirewallPolicy(self.app, self.namespace) class TestSetFirewallPolicy(TestFirewallPolicy, common.TestSetFWaaS): def setUp(self): super(TestSetFirewallPolicy, self).setUp() self.neutronclient.update_fwaas_firewall_policy = mock.Mock( return_value={self.res: _fwp}) self.mocked = self.neutronclient.update_fwaas_firewall_policy self.cmd = firewallpolicy.SetFirewallPolicy(self.app, self.namespace) def test_set_rules(self): target = self.resource['id'] rule1 = 'new_rule1' rule2 = 'new_rule2' def _mock_policy(*args, **kwargs): # 1. Find specified firewall_policy if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource=const.CMD_FWP) # 2. Find specified firewall_policy's 'firewall_rules' attribute if self.neutronclient.find_resource.call_count == 2: self.neutronclient.find_resource.assert_called_with( self.res, args[1], cmd_resource=const.CMD_FWP) return {'firewall_rules': _fwp['firewall_rules']} # 3. Find specified firewall_rule if self.neutronclient.find_resource.call_count == 3: self.neutronclient.find_resource.assert_called_with( 'firewall_rule', args[1], cmd_resource=const.CMD_FWR) # 4. Find specified firewall_rule if self.neutronclient.find_resource.call_count == 4: self.neutronclient.find_resource.assert_called_with( 'firewall_rule', args[1], cmd_resource=const.CMD_FWR) return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_policy arglist = [ target, '--firewall-rule', rule1, '--firewall-rule', rule2, ] verifylist = [ (self.res, target), ('firewall_rule', [rule1, rule2]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) expect = _fwp['firewall_rules'] + [rule1, rule2] body = {self.res: {'firewall_rules': expect}} self.mocked.assert_called_once_with(target, body) self.assertEqual(4, self.neutronclient.find_resource.call_count) self.assertIsNone(result) def test_set_no_rules(self): target = self.resource['id'] arglist = [target, '--no-firewall-rule'] verifylist = [ (self.res, target), ('no_firewall_rule', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) body = {self.res: {'firewall_rules': []}} self.mocked.assert_called_once_with(target, body) self.assertIsNone(result) def test_set_rules_and_no_rules(self): target = self.resource['id'] rule1 = 'rule1' arglist = [ target, '--firewall-rule', rule1, '--no-firewall-rule', ] verifylist = [ (self.res, target), ('firewall_rule', [rule1]), ('no_firewall_rule', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) body = {self.res: {'firewall_rules': [rule1]}} self.mocked.assert_called_once_with(target, body) self.assertEqual(2, self.neutronclient.find_resource.call_count) self.assertIsNone(result) def test_set_audited(self): target = self.resource['id'] arglist = [target, '--audited'] verifylist = [ (self.res, target), ('audited', True), ] body = {'audited': True} parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with(target, {self.res: body}) self.assertIsNone(result) def test_set_no_audited(self): target = self.resource['id'] arglist = [target, '--no-audited'] verifylist = [ (self.res, target), ('no_audited', True), ] body = {'audited': False} parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with(target, {self.res: body}) self.assertIsNone(result) def test_set_audited_and_no_audited(self): target = self.resource['id'] arglist = [ target, '--audited', '--no-audited', ] verifylist = [ (self.res, target), ('audited', True), ('no_audited', True), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_set_and_raises(self): self.neutronclient.update_fwaas_firewall_policy = mock.Mock( side_effect=Exception) target = self.resource['id'] arglist = [target, '--name', 'my-name'] verifylist = [(self.res, target), ('name', 'my-name')] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args) class TestDeleteFirewallPolicy(TestFirewallPolicy, common.TestDeleteFWaaS): def setUp(self): super(TestDeleteFirewallPolicy, self).setUp() self.neutronclient.delete_fwaas_firewall_policy = mock.Mock( return_value={self.res: _fwp}) self.mocked = self.neutronclient.delete_fwaas_firewall_policy self.cmd = firewallpolicy.DeleteFirewallPolicy( self.app, self.namespace) class TestFirewallPolicyInsertRule(TestFirewallPolicy): def setUp(self): super(TestFirewallPolicyInsertRule, self).setUp() self.neutronclient.insert_rule_fwaas_firewall_policy = mock.Mock( return_value={self.res: _fwp}) self.mocked = self.neutronclient.insert_rule_fwaas_firewall_policy self.cmd = firewallpolicy.FirewallPolicyInsertRule(self.app, self.namespace) def test_insert_firewall_rule(self): target = self.resource['id'] rule = 'new-rule' before = 'before' after = 'after' def _mock_policy(*args, **kwargs): # 1. Find specified firewall_policy if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource=const.CMD_FWP) # 2. Find specified firewall_rule if self.neutronclient.find_resource.call_count == 2: self.neutronclient.find_resource.assert_called_with( 'firewall_rule', args[1], cmd_resource=const.CMD_FWR) # 3. Find specified firewall_rule as 'before' if self.neutronclient.find_resource.call_count == 3: self.neutronclient.find_resource.assert_called_with( 'firewall_rule', args[1], cmd_resource=const.CMD_FWR) # 4. Find specified firewall_rule as 'after' if self.neutronclient.find_resource.call_count == 4: self.neutronclient.find_resource.assert_called_with( 'firewall_rule', args[1], cmd_resource=const.CMD_FWR) return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_policy arglist = [ target, rule, '--insert-before', before, '--insert-after', after, ] verifylist = [ (self.res, target), ('firewall_rule', rule), ('insert_before', before), ('insert_after', after), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, { 'firewall_rule_id': rule, 'insert_before': before, 'insert_after': after }) self.assertIsNone(result) self.assertEqual(4, self.neutronclient.find_resource.call_count) def test_insert_with_no_firewall_rule(self): target = self.resource['id'] arglist = [ target, ] verifylist = [ (self.res, target), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) class TestFirewallPolicyRemoveRule(TestFirewallPolicy): def setUp(self): super(TestFirewallPolicyRemoveRule, self).setUp() self.neutronclient.remove_rule_fwaas_firewall_policy = mock.Mock( return_value={self.res: _fwp}) self.mocked = self.neutronclient.remove_rule_fwaas_firewall_policy self.cmd = firewallpolicy.FirewallPolicyRemoveRule(self.app, self.namespace) def test_remove_firewall_rule(self): target = self.resource['id'] rule = 'remove-rule' def _mock_policy(*args, **kwargs): # 1. Find specified firewall_policy if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource=const.CMD_FWP) # 2. Find specified firewall_rule if self.neutronclient.find_resource.call_count == 2: self.neutronclient.find_resource.assert_called_with( 'firewall_rule', rule, cmd_resource=const.CMD_FWR) return {'id': args[1]} self.neutronclient.find_resource.side_effect = mock.Mock( side_effect=_mock_policy) arglist = [ target, rule, ] verifylist = [ (self.res, target), ('firewall_rule', rule), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {'firewall_rule_id': rule}) self.assertIsNone(result) self.assertEqual(2, self.neutronclient.find_resource.call_count) def test_remove_with_no_firewall_rule(self): target = self.resource['id'] arglist = [ target, ] verifylist = [ (self.res, target), ] self.assertRaises( utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) class TestUnsetFirewallPolicy(TestFirewallPolicy, common.TestUnsetFWaaS): def setUp(self): super(TestUnsetFirewallPolicy, self).setUp() self.neutronclient.update_fwaas_firewall_policy = mock.Mock( return_value={self.res: _fwp}) self.mocked = self.neutronclient.update_fwaas_firewall_policy self.cmd = firewallpolicy.UnsetFirewallPolicy(self.app, self.namespace) def test_unset_audited(self): target = self.resource['id'] arglist = [ target, '--audited', ] verifylist = [ (self.res, target), ('audited', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) body = {self.res: {'audited': False}} self.mocked.assert_called_once_with(target, body) self.assertIsNone(result) def test_unset_firewall_rule_not_matched(self): _fwp['firewall_rules'] = ['old_rule'] target = self.resource['id'] rule = 'new_rule' arglist = [ target, '--firewall-rule', rule, ] verifylist = [ (self.res, target), ('firewall_rule', [rule]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) body = {self.res: {'firewall_rules': _fwp['firewall_rules']}} self.mocked.assert_called_once_with(target, body) self.assertIsNone(result) def test_unset_firewall_rule_matched(self): _fwp['firewall_rules'] = ['rule1', 'rule2'] target = self.resource['id'] rule = 'rule1' def _mock_policy(*args, **kwargs): # 1. Find specified firewall_policy if self.neutronclient.find_resource.call_count == 1: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource=const.CMD_FWP) # 2. Find 'firewall_rules' attribute from specified firewall_policy if self.neutronclient.find_resource.call_count == 2: self.neutronclient.find_resource.assert_called_with( self.res, target, cmd_resource=const.CMD_FWP) return {'firewall_rules': _fwp['firewall_rules']} # 3. Find specified 'firewall_rule' if self.neutronclient.find_resource.call_count == 3: self.neutronclient.find_resource.assert_called_with( 'firewall_rule', rule, cmd_resource=const.CMD_FWR) return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_policy arglist = [ target, '--firewall-rule', rule, ] verifylist = [ (self.res, target), ('firewall_rule', [rule]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) body = {self.res: {'firewall_rules': ['rule2']}} self.mocked.assert_called_once_with(target, body) self.assertIsNone(result) self.assertEqual(3, self.neutronclient.find_resource.call_count) def test_unset_all_firewall_rule(self): target = self.resource['id'] arglist = [ target, '--all-firewall-rule', ] verifylist = [ (self.res, target), ('all_firewall_rule', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) body = {self.res: {'firewall_rules': []}} self.mocked.assert_called_once_with(target, body) self.assertIsNone(result) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/trunk/0000775000175100017510000000000013232473710025252 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/trunk/fakes.py0000666000175100017510000000562713232473350026731 0ustar zuulzuul00000000000000# 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 copy import mock from oslo_utils import uuidutils class FakeTrunk(object): """Fake one or more trunks.""" @staticmethod def create_one_trunk(attrs=None): """Create a fake trunk. :param Dictionary attrs: A dictionary with all attributes :return: A Dictionary with id, name, description, admin_state_up, port_id, sub_ports, status and project_id """ attrs = attrs or {} # Set default attributes. trunk_attrs = { 'id': 'trunk-id-' + uuidutils.generate_uuid(dashed=False), 'name': 'trunk-name-' + uuidutils.generate_uuid(dashed=False), 'description': '', 'port_id': 'port-' + uuidutils.generate_uuid(dashed=False), 'admin_state_up': True, 'project_id': 'project-id-' + uuidutils.generate_uuid(dashed=False), 'status': 'ACTIVE', 'sub_ports': [{'port_id': 'subport-' + uuidutils.generate_uuid(dashed=False), 'segmentation_type': 'vlan', 'segmentation_id': 100}], } # Overwrite default attributes. trunk_attrs.update(attrs) return copy.deepcopy(trunk_attrs) @staticmethod def create_trunks(attrs=None, count=2): """Create multiple fake trunks. :param Dictionary attrs: A dictionary with all attributes :param int count: The number of routers to fake :return: A list of dictionaries faking the trunks """ trunks = [] for i in range(0, count): trunks.append(FakeTrunk.create_one_trunk(attrs)) return trunks @staticmethod def get_trunks(trunks=None, count=2): """Get an iterable Mock object with a list of faked trunks. If trunks list is provided, then initialize the Mock object with the list. Otherwise create one. :param List trunks: A list of FakeResource objects faking trunks :param int count: The number of trunks to fake :return: An iterable Mock object with side_effect set to a list of faked trunks """ if trunks is None: trunks = FakeTrunk.create_trunks(count) return mock.Mock(side_effect=trunks) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/trunk/__init__.py0000666000175100017510000000000013232473350027353 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/trunk/test_network_trunk.py0000666000175100017510000006243213232473350031610 0ustar zuulzuul00000000000000# Copyright 2016 ZTE Corporation. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import argparse import copy import mock from mock import call from osc_lib.cli import format_columns from osc_lib import exceptions from osc_lib.tests import utils as tests_utils import testtools from neutronclient.osc.v2.trunk import network_trunk as trunk from neutronclient.osc.v2 import utils as v2_utils from neutronclient.tests.unit.osc.v2 import fakes as test_fakes from neutronclient.tests.unit.osc.v2.trunk import fakes def _get_id(client, id_or_name, resource): return id_or_name class TestCreateNetworkTrunk(test_fakes.TestNeutronClientOSCV2): # The new trunk created _trunk = fakes.FakeTrunk.create_one_trunk() columns = ( 'admin_state_up', 'description', 'id', 'name', 'port_id', 'project_id', 'status', 'sub_ports', ) def get_data(self): return ( v2_utils.AdminStateColumn(self._trunk['admin_state_up']), self._trunk['description'], self._trunk['id'], self._trunk['name'], self._trunk['port_id'], self._trunk['project_id'], self._trunk['status'], format_columns.ListDictColumn(self._trunk['sub_ports']), ) def setUp(self): super(TestCreateNetworkTrunk, self).setUp() mock.patch('neutronclient.osc.v2.trunk.network_trunk._get_id', new=_get_id).start() self.neutronclient.create_trunk = mock.Mock( return_value={trunk.TRUNK: self._trunk}) self.data = self.get_data() # Get the command object to test self.cmd = trunk.CreateNetworkTrunk(self.app, self.namespace) def test_create_no_options(self): arglist = [] verifylist = [] self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_default_options(self): arglist = [ "--parent-port", self._trunk['port_id'], self._trunk['name'], ] verifylist = [ ('parent_port', self._trunk['port_id']), ('name', self._trunk['name']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) self.neutronclient.create_trunk.assert_called_once_with({ trunk.TRUNK: {'name': self._trunk['name'], 'admin_state_up': self._trunk['admin_state_up'], 'port_id': self._trunk['port_id']} }) self.assertEqual(self.columns, columns) self.assertItemEqual(self.data, data) def test_create_full_options(self): self._trunk['description'] = 'foo description' self.data = self.get_data() subport = self._trunk['sub_ports'][0] arglist = [ "--disable", "--description", self._trunk['description'], "--parent-port", self._trunk['port_id'], "--subport", 'port=%(port)s,segmentation-type=%(seg_type)s,' 'segmentation-id=%(seg_id)s' % { 'seg_id': subport['segmentation_id'], 'seg_type': subport['segmentation_type'], 'port': subport['port_id']}, self._trunk['name'], ] verifylist = [ ('name', self._trunk['name']), ('description', self._trunk['description']), ('parent_port', self._trunk['port_id']), ('add_subports', [{ 'port': subport['port_id'], 'segmentation-id': str(subport['segmentation_id']), 'segmentation-type': subport['segmentation_type']}]), ('disable', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) self.neutronclient.create_trunk.assert_called_once_with({ trunk.TRUNK: {'name': self._trunk['name'], 'description': self._trunk['description'], 'admin_state_up': False, 'sub_ports': [subport], 'port_id': self._trunk['port_id']} }) self.assertEqual(self.columns, columns) self.assertItemEqual(self.data, data) def test_create_trunk_with_subport_invalid_segmentation_id_fail(self): subport = self._trunk['sub_ports'][0] arglist = [ "--parent-port", self._trunk['port_id'], "--subport", "port=%(port)s,segmentation-type=%(seg_type)s," "segmentation-id=boom" % { 'seg_type': subport['segmentation_type'], 'port': subport['port_id']}, self._trunk['name'], ] verifylist = [ ('name', self._trunk['name']), ('parent_port', self._trunk['port_id']), ('add_subports', [{ 'port': subport['port_id'], 'segmentation-id': 'boom', 'segmentation-type': subport['segmentation_type']}]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with testtools.ExpectedException(exceptions.CommandError) as e: self.cmd.take_action(parsed_args) self.assertEqual("Segmentation-id 'boom' is not an integer", str(e)) def test_create_network_trunk_subports_without_optional_keys(self): subport = copy.copy(self._trunk['sub_ports'][0]) # Pop out the segmentation-id and segmentation-type subport.pop('segmentation_type') subport.pop('segmentation_id') arglist = [ '--parent-port', self._trunk['port_id'], '--subport', 'port=%(port)s' % {'port': subport['port_id']}, self._trunk['name'], ] verifylist = [ ('name', self._trunk['name']), ('parent_port', self._trunk['port_id']), ('add_subports', [{ 'port': subport['port_id']}]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) self.neutronclient.create_trunk.assert_called_once_with({ trunk.TRUNK: {'name': self._trunk['name'], 'admin_state_up': True, 'sub_ports': [subport], 'port_id': self._trunk['port_id']} }) self.assertEqual(self.columns, columns) self.assertItemEqual(self.data, data) def test_create_network_trunk_subports_without_required_key_fail(self): subport = self._trunk['sub_ports'][0] arglist = [ '--parent-port', self._trunk['port_id'], '--subport', 'segmentation-type=%(seg_type)s,' 'segmentation-id=%(seg_id)s' % { 'seg_id': subport['segmentation_id'], 'seg_type': subport['segmentation_type']}, self._trunk['name'], ] verifylist = [ ('name', self._trunk['name']), ('parent_port', self._trunk['port_id']), ('add_subports', [{ 'segmentation-id': str(subport['segmentation_id']), 'segmentation-type': subport['segmentation_type']}]), ] with testtools.ExpectedException(argparse.ArgumentTypeError): self.check_parser(self.cmd, arglist, verifylist) class TestDeleteNetworkTrunk(test_fakes.TestNeutronClientOSCV2): # The trunk to be deleted. _trunks = fakes.FakeTrunk.create_trunks(count=2) def setUp(self): super(TestDeleteNetworkTrunk, self).setUp() mock.patch('neutronclient.osc.v2.trunk.network_trunk._get_id', new=_get_id).start() self.neutronclient.delete_trunk = mock.Mock(return_value=None) # Get the command object to test self.cmd = trunk.DeleteNetworkTrunk(self.app, self.namespace) def test_delete_trunk(self): arglist = [ self._trunks[0]['name'], ] verifylist = [ ('trunk', [self._trunks[0]['name']]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.neutronclient.delete_trunk.assert_called_once_with( self._trunks[0]['name']) self.assertIsNone(result) def test_delete_trunk_multiple(self): arglist = [] verifylist = [] for t in self._trunks: arglist.append(t['name']) verifylist = [ ('trunk', arglist), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) calls = [] for t in self._trunks: calls.append(call(t['name'])) self.neutronclient.delete_trunk.assert_has_calls(calls) self.assertIsNone(result) def test_delete_trunk_multiple_with_exception(self): arglist = [ self._trunks[0]['name'], 'unexist_trunk', ] verifylist = [ ('trunk', [self._trunks[0]['name'], 'unexist_trunk']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) get_mock_result = [self._trunks[0], exceptions.CommandError] trunk._get_id = ( mock.Mock(side_effect=get_mock_result) ) with testtools.ExpectedException(exceptions.CommandError) as e: self.cmd.take_action(parsed_args) self.assertEqual('1 of 2 trunks failed to delete.', str(e)) self.neutronclient.delete_trunk.assert_called_once_with( self._trunks[0] ) class TestShowNetworkTrunk(test_fakes.TestNeutronClientOSCV2): # The trunk to set. _trunk = fakes.FakeTrunk.create_one_trunk() columns = ( 'admin_state_up', 'description', 'id', 'name', 'port_id', 'project_id', 'status', 'sub_ports', ) data = ( v2_utils.AdminStateColumn(_trunk['admin_state_up']), _trunk['description'], _trunk['id'], _trunk['name'], _trunk['port_id'], _trunk['project_id'], _trunk['status'], format_columns.ListDictColumn(_trunk['sub_ports']), ) def setUp(self): super(TestShowNetworkTrunk, self).setUp() mock.patch('neutronclient.osc.v2.trunk.network_trunk._get_id', new=_get_id).start() self.neutronclient.show_trunk = mock.Mock( return_value={trunk.TRUNK: self._trunk}) # Get the command object to test self.cmd = trunk.ShowNetworkTrunk(self.app, self.namespace) def test_show_no_options(self): arglist = [] verifylist = [] self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_show_all_options(self): arglist = [ self._trunk['id'], ] verifylist = [ ('trunk', self._trunk['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.neutronclient.show_trunk.assert_called_once_with( self._trunk['id']) self.assertEqual(self.columns, columns) self.assertItemEqual(self.data, data) class TestListNetworkTrunk(test_fakes.TestNeutronClientOSCV2): # Create trunks to be listed. _trunks = fakes.FakeTrunk.create_trunks( {'created_at': '2001-01-01 00:00:00', 'updated_at': '2001-01-01 00:00:00'}, count=3) columns = ( 'ID', 'Name', 'Parent Port', 'Description' ) columns_long = columns + ( 'Status', 'State', 'Created At', 'Updated At' ) data = [] for t in _trunks: data.append(( t['id'], t['name'], t['port_id'], t['description'] )) data_long = [] for t in _trunks: data_long.append(( t['id'], t['name'], t['port_id'], t['description'], t['status'], v2_utils.AdminStateColumn(t['admin_state_up']), '2001-01-01 00:00:00', '2001-01-01 00:00:00', )) def setUp(self): super(TestListNetworkTrunk, self).setUp() mock.patch('neutronclient.osc.v2.trunk.network_trunk._get_id', new=_get_id).start() self.neutronclient.list_trunks = mock.Mock( return_value={trunk.TRUNKS: self._trunks}) # Get the command object to test self.cmd = trunk.ListNetworkTrunk(self.app, self.namespace) def test_trunk_list_no_option(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.neutronclient.list_trunks.assert_called_once_with() self.assertEqual(self.columns, columns) self.assertListItemEqual(self.data, list(data)) def test_trunk_list_long(self): arglist = [ '--long', ] verifylist = [ ('long', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.neutronclient.list_trunks.assert_called_once_with() self.assertEqual(self.columns_long, columns) self.assertListItemEqual(self.data_long, list(data)) class TestSetNetworkTrunk(test_fakes.TestNeutronClientOSCV2): # Create trunks to be listed. _trunk = fakes.FakeTrunk.create_one_trunk() columns = ( 'admin_state_up', 'id', 'name', 'description', 'port_id', 'project_id', 'status', 'sub_ports', ) data = ( v2_utils.AdminStateColumn(_trunk['admin_state_up']), _trunk['id'], _trunk['name'], _trunk['description'], _trunk['port_id'], _trunk['project_id'], _trunk['status'], format_columns.ListDictColumn(_trunk['sub_ports']), ) def setUp(self): super(TestSetNetworkTrunk, self).setUp() mock.patch('neutronclient.osc.v2.trunk.network_trunk._get_id', new=_get_id).start() self.neutronclient.update_trunk = mock.Mock( return_value={trunk.TRUNK: self._trunk}) self.neutronclient.trunk_add_subports = mock.Mock( return_value=self._trunk) # Get the command object to test self.cmd = trunk.SetNetworkTrunk(self.app, self.namespace) def _test_set_network_trunk_attr(self, attr, value): arglist = [ '--%s' % attr, value, self._trunk[attr], ] verifylist = [ (attr, value), ('trunk', self._trunk[attr]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = { attr: value, } self.neutronclient.update_trunk.assert_called_once_with( self._trunk[attr], {trunk.TRUNK: attrs}) self.assertIsNone(result) def test_set_network_trunk_name(self): self._test_set_network_trunk_attr('name', 'trunky') def test_test_set_network_trunk_description(self): self._test_set_network_trunk_attr('description', 'description') def test_set_network_trunk_admin_state_up_disable(self): arglist = [ '--disable', self._trunk['name'], ] verifylist = [ ('disable', True), ('trunk', self._trunk['name']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = { 'admin_state_up': False, } self.neutronclient.update_trunk.assert_called_once_with( self._trunk['name'], {trunk.TRUNK: attrs}) self.assertIsNone(result) def test_set_network_trunk_admin_state_up_enable(self): arglist = [ '--enable', self._trunk['name'], ] verifylist = [ ('enable', True), ('trunk', self._trunk['name']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = { 'admin_state_up': True, } self.neutronclient.update_trunk.assert_called_once_with( self._trunk['name'], {trunk.TRUNK: attrs}) self.assertIsNone(result) def test_set_network_trunk_nothing(self): arglist = [self._trunk['name'], ] verifylist = [('trunk', self._trunk['name']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = {} self.neutronclient.update_trunk.assert_called_once_with( self._trunk['name'], {trunk.TRUNK: attrs}) self.assertIsNone(result) def test_set_network_trunk_subports(self): subport = self._trunk['sub_ports'][0] arglist = [ '--subport', 'port=%(port)s,segmentation-type=%(seg_type)s,' 'segmentation-id=%(seg_id)s' % { 'seg_id': subport['segmentation_id'], 'seg_type': subport['segmentation_type'], 'port': subport['port_id']}, self._trunk['name'], ] verifylist = [ ('trunk', self._trunk['name']), ('set_subports', [{ 'port': subport['port_id'], 'segmentation-id': str(subport['segmentation_id']), 'segmentation-type': subport['segmentation_type']}]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.neutronclient.trunk_add_subports.assert_called_once_with( self._trunk['name'], {'sub_ports': [subport]} ) self.assertIsNone(result) def test_set_network_trunk_subports_without_optional_keys(self): subport = copy.copy(self._trunk['sub_ports'][0]) # Pop out the segmentation-id and segmentation-type subport.pop('segmentation_type') subport.pop('segmentation_id') arglist = [ '--subport', 'port=%(port)s' % {'port': subport['port_id']}, self._trunk['name'], ] verifylist = [ ('trunk', self._trunk['name']), ('set_subports', [{ 'port': subport['port_id']}]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.neutronclient.trunk_add_subports.assert_called_once_with( self._trunk['name'], {'sub_ports': [subport]} ) self.assertIsNone(result) def test_set_network_trunk_subports_without_required_key_fail(self): subport = self._trunk['sub_ports'][0] arglist = [ '--subport', 'segmentation-type=%(seg_type)s,' 'segmentation-id=%(seg_id)s' % { 'seg_id': subport['segmentation_id'], 'seg_type': subport['segmentation_type']}, self._trunk['name'], ] verifylist = [ ('trunk', self._trunk['name']), ('set_subports', [{ 'segmentation-id': str(subport['segmentation_id']), 'segmentation-type': subport['segmentation_type']}]), ] with testtools.ExpectedException(argparse.ArgumentTypeError): self.check_parser(self.cmd, arglist, verifylist) self.neutronclient.trunk_add_subports.assert_not_called() def test_set_trunk_attrs_with_exception(self): arglist = [ '--name', 'reallylongname', self._trunk['name'], ] verifylist = [ ('trunk', self._trunk['name']), ('name', 'reallylongname'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.neutronclient.update_trunk = ( mock.Mock(side_effect=exceptions.CommandError) ) with testtools.ExpectedException(exceptions.CommandError) as e: self.cmd.take_action(parsed_args) self.assertEqual( "Failed to set trunk '%s': " % self._trunk['name'], str(e)) attrs = {'name': 'reallylongname'} self.neutronclient.update_trunk.assert_called_once_with( self._trunk['name'], {trunk.TRUNK: attrs}) self.neutronclient.trunk_add_subports.assert_not_called() def test_set_trunk_add_subport_with_exception(self): arglist = [ '--subport', 'port=invalid_subport', self._trunk['name'], ] verifylist = [ ('trunk', self._trunk['name']), ('set_subports', [{'port': 'invalid_subport'}]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.neutronclient.trunk_add_subports = ( mock.Mock(side_effect=exceptions.CommandError) ) with testtools.ExpectedException(exceptions.CommandError) as e: self.cmd.take_action(parsed_args) self.assertEqual( "Failed to add subports to trunk '%s': " % self._trunk['name'], str(e)) self.neutronclient.update_trunk.assert_called_once_with( self._trunk['name'], {trunk.TRUNK: {}}) self.neutronclient.trunk_add_subports.assert_called_once_with( self._trunk['name'], {'sub_ports': [{'port_id': 'invalid_subport'}]} ) class TestListNetworkSubport(test_fakes.TestNeutronClientOSCV2): _trunk = fakes.FakeTrunk.create_one_trunk() _subports = _trunk['sub_ports'] columns = ( 'Port', 'Segmentation Type', 'Segmentation ID', ) data = [] for s in _subports: data.append(( s['port_id'], s['segmentation_type'], s['segmentation_id'], )) def setUp(self): super(TestListNetworkSubport, self).setUp() mock.patch('neutronclient.osc.v2.trunk.network_trunk._get_id', new=_get_id).start() self.neutronclient.trunk_get_subports = mock.Mock( return_value={trunk.SUB_PORTS: self._subports}) # Get the command object to test self.cmd = trunk.ListNetworkSubport(self.app, self.namespace) def test_subport_list(self): arglist = [ '--trunk', self._trunk['name'], ] verifylist = [ ('trunk', self._trunk['name']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.neutronclient.trunk_get_subports.assert_called_once_with( self._trunk['name']) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) class TestUnsetNetworkTrunk(test_fakes.TestNeutronClientOSCV2): _trunk = fakes.FakeTrunk.create_one_trunk() columns = ( 'admin_state_up', 'id', 'name', 'port_id', 'project_id', 'status', 'sub_ports', ) data = ( v2_utils.AdminStateColumn(_trunk['admin_state_up']), _trunk['id'], _trunk['name'], _trunk['port_id'], _trunk['project_id'], _trunk['status'], format_columns.ListDictColumn(_trunk['sub_ports']), ) def setUp(self): super(TestUnsetNetworkTrunk, self).setUp() mock.patch('neutronclient.osc.v2.trunk.network_trunk._get_id', new=_get_id).start() self.neutronclient.trunk_remove_subports = mock.Mock( return_value=None) # Get the command object to test self.cmd = trunk.UnsetNetworkTrunk(self.app, self.namespace) def test_unset_network_trunk_subport(self): subport = self._trunk['sub_ports'][0] arglist = [ "--subport", subport['port_id'], self._trunk['name'], ] verifylist = [ ('trunk', self._trunk['name']), ('unset_subports', [subport['port_id']]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.neutronclient.trunk_remove_subports.assert_called_once_with( self._trunk['name'], {trunk.SUB_PORTS: [{'port_id': subport['port_id']}]} ) self.assertIsNone(result) def test_unset_subport_no_arguments_fail(self): arglist = [ self._trunk['name'], ] verifylist = [ ('trunk', self._trunk['name']), ] self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/networking_bgpvpn/0000775000175100017510000000000013232473710027652 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/networking_bgpvpn/test_bgpvpn.py0000666000175100017510000004750313232473407032575 0ustar zuulzuul00000000000000# Copyright (c) 2016 Juniper Networks Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy import operator import mock from osc_lib import exceptions from osc_lib import utils as osc_utils from neutronclient.osc import utils as nc_osc_utils from neutronclient.osc.v2.networking_bgpvpn import bgpvpn from neutronclient.osc.v2.networking_bgpvpn import constants from neutronclient.tests.unit.osc.v2.networking_bgpvpn import fakes columns_short = tuple(col for col, _, listing_mode in bgpvpn._attr_map if listing_mode in (nc_osc_utils.LIST_BOTH, nc_osc_utils.LIST_SHORT_ONLY)) columns_long = tuple(col for col, _, listing_mode in bgpvpn._attr_map if listing_mode in (nc_osc_utils.LIST_BOTH, nc_osc_utils.LIST_LONG_ONLY)) headers_short = tuple(head for _, head, listing_mode in bgpvpn._attr_map if listing_mode in (nc_osc_utils.LIST_BOTH, nc_osc_utils.LIST_SHORT_ONLY)) headers_long = tuple(head for _, head, listing_mode in bgpvpn._attr_map if listing_mode in (nc_osc_utils.LIST_BOTH, nc_osc_utils.LIST_LONG_ONLY)) sorted_attr_map = sorted(bgpvpn._attr_map, key=operator.itemgetter(1)) sorted_columns = tuple(col for col, _, _ in sorted_attr_map) sorted_headers = tuple(head for _, head, _ in sorted_attr_map) def _get_data(attrs, columns=sorted_columns): return osc_utils.get_dict_properties(attrs, columns, formatters=bgpvpn._formatters) class TestCreateBgpvpn(fakes.TestNeutronClientBgpvpn): def setUp(self): super(TestCreateBgpvpn, self).setUp() self.cmd = bgpvpn.CreateBgpvpn(self.app, self.namespace) def test_create_bgpvpn_with_no_args(self): fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn() self.neutronclient.create_bgpvpn = mock.Mock( return_value={constants.BGPVPN: fake_bgpvpn}) arglist = [] verifylist = [ ('project', None), ('name', None), ('type', 'l3'), ('vni', None), ('route_targets', None), ('import_targets', None), ('export_targets', None), ('route_distinguishers', None), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) cols, data = self.cmd.take_action(parsed_args) self.neutronclient.create_bgpvpn.assert_called_once_with( {constants.BGPVPN: {'type': 'l3'}}) self.assertEqual(sorted_headers, cols) self.assertItemEqual(_get_data(fake_bgpvpn), data) def test_create_bgpvpn_with_all_args(self): attrs = { 'tenant_id': 'new_fake_project_id', 'name': 'fake_name', 'type': 'l2', 'vni': 100, 'route_targets': ['fake_rt1', 'fake_rt2', 'fake_rt3'], 'import_targets': ['fake_irt1', 'fake_irt2', 'fake_irt3'], 'export_targets': ['fake_ert1', 'fake_ert2', 'fake_ert3'], 'route_distinguishers': ['fake_rd1', 'fake_rd2', 'fake_rd3'], } fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn(attrs) self.neutronclient.create_bgpvpn = mock.Mock( return_value={constants.BGPVPN: fake_bgpvpn}) arglist = [ '--project', fake_bgpvpn['tenant_id'], '--name', fake_bgpvpn['name'], '--type', fake_bgpvpn['type'], '--vni', str(fake_bgpvpn['vni']), ] for rt in fake_bgpvpn['route_targets']: arglist.extend(['--route-target', rt]) for rt in fake_bgpvpn['import_targets']: arglist.extend(['--import-target', rt]) for rt in fake_bgpvpn['export_targets']: arglist.extend(['--export-target', rt]) for rd in fake_bgpvpn['route_distinguishers']: arglist.extend(['--route-distinguisher', rd]) verifylist = [ ('project', fake_bgpvpn['tenant_id']), ('name', fake_bgpvpn['name']), ('type', fake_bgpvpn['type']), ('vni', fake_bgpvpn['vni']), ('route_targets', fake_bgpvpn['route_targets']), ('import_targets', fake_bgpvpn['import_targets']), ('export_targets', fake_bgpvpn['export_targets']), ('route_distinguishers', fake_bgpvpn['route_distinguishers']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) cols, data = self.cmd.take_action(parsed_args) fake_bgpvpn_call = copy.deepcopy(fake_bgpvpn) fake_bgpvpn_call.pop('id') fake_bgpvpn_call.pop('networks') fake_bgpvpn_call.pop('routers') fake_bgpvpn_call.pop('ports') self.neutronclient.create_bgpvpn.assert_called_once_with( {constants.BGPVPN: fake_bgpvpn_call}) self.assertEqual(sorted_headers, cols) self.assertItemEqual(_get_data(fake_bgpvpn), data) class TestSetBgpvpn(fakes.TestNeutronClientBgpvpn): def setUp(self): super(TestSetBgpvpn, self).setUp() self.cmd = bgpvpn.SetBgpvpn(self.app, self.namespace) def test_set_bgpvpn(self): attrs = { 'route_targets': ['set_rt1', 'set_rt2', 'set_rt3'], 'import_targets': ['set_irt1', 'set_irt2', 'set_irt3'], 'export_targets': ['set_ert1', 'set_ert2', 'set_ert3'], 'route_distinguishers': ['set_rd1', 'set_rd2', 'set_rd3'], } fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn(attrs) self.neutronclient.show_bgpvpn = mock.Mock( return_value={constants.BGPVPN: fake_bgpvpn}) self.neutronclient.update_bgpvpn = mock.Mock() arglist = [ fake_bgpvpn['id'], '--name', 'set_name', '--route-target', 'set_rt1', '--import-target', 'set_irt1', '--export-target', 'set_ert1', '--route-distinguisher', 'set_rd1', ] verifylist = [ ('bgpvpn', fake_bgpvpn['id']), ('name', 'set_name'), ('route_targets', ['set_rt1']), ('purge_route_target', False), ('import_targets', ['set_irt1']), ('purge_import_target', False), ('export_targets', ['set_ert1']), ('purge_export_target', False), ('route_distinguishers', ['set_rd1']), ('purge_route_distinguisher', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = { 'name': 'set_name', 'route_targets': list(set(fake_bgpvpn['route_targets']) | set(['set_rt1'])), 'import_targets': list(set(fake_bgpvpn['import_targets']) | set(['set_irt1'])), 'export_targets': list(set(fake_bgpvpn['export_targets']) | set(['set_ert1'])), 'route_distinguishers': list( set(fake_bgpvpn['route_distinguishers']) | set(['set_rd1'])), } self.neutronclient.update_bgpvpn.assert_called_once_with( fake_bgpvpn['id'], {constants.BGPVPN: attrs}) self.assertIsNone(result) def test_set_bgpvpn_with_purge_list(self): fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn() self.neutronclient.show_bgpvpn = mock.Mock( return_value={constants.BGPVPN: fake_bgpvpn}) self.neutronclient.update_bgpvpn = mock.Mock() arglist = [ fake_bgpvpn['id'], '--route-target', 'set_rt1', '--no-route-target', '--import-target', 'set_irt1', '--no-import-target', '--export-target', 'set_ert1', '--no-export-target', '--route-distinguisher', 'set_rd1', '--no-route-distinguisher', ] verifylist = [ ('bgpvpn', fake_bgpvpn['id']), ('route_targets', ['set_rt1']), ('purge_route_target', True), ('import_targets', ['set_irt1']), ('purge_import_target', True), ('export_targets', ['set_ert1']), ('purge_export_target', True), ('route_distinguishers', ['set_rd1']), ('purge_route_distinguisher', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = { 'route_targets': [], 'import_targets': [], 'export_targets': [], 'route_distinguishers': [], } self.neutronclient.update_bgpvpn.assert_called_once_with( fake_bgpvpn['id'], {constants.BGPVPN: attrs}) self.assertIsNone(result) class TestUnsetBgpvpn(fakes.TestNeutronClientBgpvpn): def setUp(self): super(TestUnsetBgpvpn, self).setUp() self.cmd = bgpvpn.UnsetBgpvpn(self.app, self.namespace) def test_unset_bgpvpn(self): attrs = { 'route_targets': ['unset_rt1', 'unset_rt2', 'unset_rt3'], 'import_targets': ['unset_irt1', 'unset_irt2', 'unset_irt3'], 'export_targets': ['unset_ert1', 'unset_ert2', 'unset_ert3'], 'route_distinguishers': ['unset_rd1', 'unset_rd2', 'unset_rd3'], } fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn(attrs) self.neutronclient.show_bgpvpn = mock.Mock( return_value={constants.BGPVPN: fake_bgpvpn}) self.neutronclient.update_bgpvpn = mock.Mock() arglist = [ fake_bgpvpn['id'], '--route-target', 'unset_rt1', '--import-target', 'unset_irt1', '--export-target', 'unset_ert1', '--route-distinguisher', 'unset_rd1', ] verifylist = [ ('bgpvpn', fake_bgpvpn['id']), ('route_targets', ['unset_rt1']), ('purge_route_target', False), ('import_targets', ['unset_irt1']), ('purge_import_target', False), ('export_targets', ['unset_ert1']), ('purge_export_target', False), ('route_distinguishers', ['unset_rd1']), ('purge_route_distinguisher', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = { 'route_targets': list(set(fake_bgpvpn['route_targets']) - set(['unset_rt1'])), 'import_targets': list(set(fake_bgpvpn['import_targets']) - set(['unset_irt1'])), 'export_targets': list(set(fake_bgpvpn['export_targets']) - set(['unset_ert1'])), 'route_distinguishers': list( set(fake_bgpvpn['route_distinguishers']) - set(['unset_rd1'])), } self.neutronclient.update_bgpvpn.assert_called_once_with( fake_bgpvpn['id'], {constants.BGPVPN: attrs}) self.assertIsNone(result) def test_unset_bgpvpn_with_purge_list(self): fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn() self.neutronclient.show_bgpvpn = mock.Mock( return_value={constants.BGPVPN: fake_bgpvpn}) self.neutronclient.update_bgpvpn = mock.Mock() arglist = [ fake_bgpvpn['id'], '--route-target', 'unset_rt1', '--all-route-target', '--import-target', 'unset_irt1', '--all-import-target', '--export-target', 'unset_ert1', '--all-export-target', '--route-distinguisher', 'unset_rd1', '--all-route-distinguisher', ] verifylist = [ ('bgpvpn', fake_bgpvpn['id']), ('route_targets', ['unset_rt1']), ('purge_route_target', True), ('import_targets', ['unset_irt1']), ('purge_import_target', True), ('export_targets', ['unset_ert1']), ('purge_export_target', True), ('route_distinguishers', ['unset_rd1']), ('purge_route_distinguisher', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = { 'route_targets': [], 'import_targets': [], 'export_targets': [], 'route_distinguishers': [], } self.neutronclient.update_bgpvpn.assert_called_once_with( fake_bgpvpn['id'], {constants.BGPVPN: attrs}) self.assertIsNone(result) class TestDeleteBgpvpn(fakes.TestNeutronClientBgpvpn): def setUp(self): super(TestDeleteBgpvpn, self).setUp() self.neutronclient.find_resource = mock.Mock( side_effect=lambda _, name_or_id: {'id': name_or_id}) self.cmd = bgpvpn.DeleteBgpvpn(self.app, self.namespace) def test_delete_one_bgpvpn(self): fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn() self.neutronclient.delete_bgpvpn = mock.Mock() arglist = [ fake_bgpvpn['id'], ] verifylist = [ ('bgpvpns', [fake_bgpvpn['id']]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.neutronclient.delete_bgpvpn.assert_called_once_with( fake_bgpvpn['id']) self.assertIsNone(result) def test_delete_multi_bpgvpn(self): fake_bgpvpns = fakes.FakeBgpvpn.create_bgpvpns(count=3) fake_bgpvpn_ids = [fake_bgpvpn['id'] for fake_bgpvpn in fake_bgpvpns[constants.BGPVPNS]] self.neutronclient.delete_bgpvpn = mock.Mock() arglist = fake_bgpvpn_ids verifylist = [ ('bgpvpns', fake_bgpvpn_ids), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.neutronclient.delete_bgpvpn.assert_has_calls( [mock.call(id) for id in fake_bgpvpn_ids]) self.assertIsNone(result) def test_delete_multi_bpgvpn_with_unknown(self): count = 3 fake_bgpvpns = fakes.FakeBgpvpn.create_bgpvpns(count=count) fake_bgpvpn_ids = [fake_bgpvpn['id'] for fake_bgpvpn in fake_bgpvpns[constants.BGPVPNS]] def raise_unknonw_resource(resource_path, name_or_id): if str(count - 2) in name_or_id: raise Exception() self.neutronclient.delete_bgpvpn = mock.Mock( side_effect=raise_unknonw_resource) arglist = fake_bgpvpn_ids verifylist = [ ('bgpvpns', fake_bgpvpn_ids), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises(exceptions.CommandError, self.cmd.take_action, parsed_args) self.neutronclient.delete_bgpvpn.assert_has_calls( [mock.call(id) for id in fake_bgpvpn_ids]) class TestListBgpvpn(fakes.TestNeutronClientBgpvpn): def setUp(self): super(TestListBgpvpn, self).setUp() self.cmd = bgpvpn.ListBgpvpn(self.app, self.namespace) def test_list_all_bgpvpn(self): count = 3 fake_bgpvpns = fakes.FakeBgpvpn.create_bgpvpns(count=count) self.neutronclient.list_bgpvpns = mock.Mock(return_value=fake_bgpvpns) arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.neutronclient.list_bgpvpns.assert_called_once() self.assertEqual(headers, list(headers_short)) self.assertListItemEqual( list(data), [_get_data(fake_bgpvpn, columns_short) for fake_bgpvpn in fake_bgpvpns[constants.BGPVPNS]]) def test_list_all_bgpvpn_long_mode(self): count = 3 fake_bgpvpns = fakes.FakeBgpvpn.create_bgpvpns(count=count) self.neutronclient.list_bgpvpns = mock.Mock(return_value=fake_bgpvpns) arglist = [ '--long', ] verifylist = [ ('long', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.neutronclient.list_bgpvpns.assert_called_once() self.assertEqual(headers, list(headers_long)) self.assertListItemEqual( list(data), [_get_data(fake_bgpvpn, columns_long) for fake_bgpvpn in fake_bgpvpns[constants.BGPVPNS]]) def test_list_project_bgpvpn(self): count = 3 project_id = 'list_fake_project_id' attrs = {'tenant_id': project_id} fake_bgpvpns = fakes.FakeBgpvpn.create_bgpvpns(count=count, attrs=attrs) self.neutronclient.list_bgpvpns = mock.Mock(return_value=fake_bgpvpns) arglist = [ '--project', project_id, ] verifylist = [ ('project', project_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.neutronclient.list_bgpvpns.assert_called_once_with( tenant_id=project_id) self.assertEqual(headers, list(headers_short)) self.assertListItemEqual( list(data), [_get_data(fake_bgpvpn, columns_short) for fake_bgpvpn in fake_bgpvpns[constants.BGPVPNS]]) def test_list_bgpvpn_with_filters(self): count = 3 name = 'fake_id0' layer_type = 'l2' attrs = {'type': layer_type} fake_bgpvpns = fakes.FakeBgpvpn.create_bgpvpns(count=count, attrs=attrs) returned_bgpvpn = fake_bgpvpns[constants.BGPVPNS][0] self.neutronclient.list_bgpvpns = mock.Mock( return_value={constants.BGPVPNS: [returned_bgpvpn]}) arglist = [ '--property', 'name=%s' % name, '--property', 'type=%s' % layer_type, ] verifylist = [ ('property', {'name': name, 'type': layer_type}), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.neutronclient.list_bgpvpns.assert_called_once_with( name=name, type=layer_type) self.assertEqual(headers, list(headers_short)) self.assertListItemEqual(list(data), [_get_data(returned_bgpvpn, columns_short)]) class TestShowBgpvpn(fakes.TestNeutronClientBgpvpn): def setUp(self): super(TestShowBgpvpn, self).setUp() self.cmd = bgpvpn.ShowBgpvpn(self.app, self.namespace) def test_show_bgpvpn(self): fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn() self.neutronclient.show_bgpvpn = mock.Mock( return_value={constants.BGPVPN: fake_bgpvpn}) arglist = [ fake_bgpvpn['id'], ] verifylist = [ ('bgpvpn', fake_bgpvpn['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.neutronclient.show_bgpvpn.assert_called_once_with( fake_bgpvpn['id']) self.assertEqual(sorted_headers, headers) self.assertItemEqual(_get_data(fake_bgpvpn), data) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/networking_bgpvpn/fakes.py0000666000175100017510000001422313232473407031324 0ustar zuulzuul00000000000000# Copyright (c) 2016 Juniper Networks Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy import mock from neutronclient.osc import utils as nc_osc_utils from neutronclient.osc.v2.networking_bgpvpn import constants from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ CreateBgpvpnResAssoc from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ DeleteBgpvpnResAssoc from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ ListBgpvpnResAssoc from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ SetBgpvpnResAssoc from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ ShowBgpvpnResAssoc from neutronclient.osc.v2.networking_bgpvpn.resource_association import\ UnsetBgpvpnResAssoc from neutronclient.tests.unit.osc.v2 import fakes as test_fakes _FAKE_PROJECT_ID = 'fake_project_id' class TestNeutronClientBgpvpn(test_fakes.TestNeutronClientOSCV2): def setUp(self): super(TestNeutronClientBgpvpn, self).setUp() self.neutronclient.find_resource = mock.Mock( side_effect=lambda resource, name_or_id, project_id=None, cmd_resource=None, parent_id=None, fields=None: {'id': name_or_id, 'tenant_id': _FAKE_PROJECT_ID}) self.neutronclient.find_resource_by_id = mock.Mock( side_effect=lambda resource, resource_id, cmd_resource=None, parent_id=None, fields=None: {'id': resource_id, 'tenant_id': _FAKE_PROJECT_ID}) nc_osc_utils.find_project = mock.Mock( side_effect=lambda _, name_or_id, __: mock.Mock(id=name_or_id)) class FakeBgpvpn(object): """Fake BGP VPN with attributes.""" @staticmethod def create_one_bgpvpn(attrs=None): """Create a fake BGP VPN.""" attrs = attrs or {} # Set default attributes. bgpvpn_attrs = { 'id': 'fake_bgpvpn_id', 'tenant_id': _FAKE_PROJECT_ID, 'name': '', 'type': 'l3', 'route_targets': [], 'import_targets': [], 'export_targets': [], 'route_distinguishers': [], 'networks': [], 'routers': [], 'ports': [], 'vni': 100, } # Overwrite default attributes. bgpvpn_attrs.update(attrs) return copy.deepcopy(bgpvpn_attrs) @staticmethod def create_bgpvpns(attrs=None, count=1): """Create multiple fake BGP VPN.""" bgpvpns = [] for i in range(0, count): if attrs is None: attrs = {'id': 'fake_id%d' % i} elif getattr(attrs, 'id', None) is None: attrs['id'] = 'fake_id%d' % i bgpvpns.append(FakeBgpvpn.create_one_bgpvpn(attrs)) return {constants.BGPVPNS: bgpvpns} class BgpvpnFakeAssoc(object): _assoc_res_name = 'fake_resource' _resource = '%s_association' % _assoc_res_name _resource_plural = '%ss' % _resource _attr_map = ( ('id', 'ID', nc_osc_utils.LIST_BOTH), ('tenant_id', 'Project', nc_osc_utils.LIST_LONG_ONLY), ('%s_id' % _assoc_res_name, '%s ID' % _assoc_res_name.capitalize(), nc_osc_utils.LIST_BOTH), ) _formatters = {} class CreateBgpvpnFakeResAssoc(BgpvpnFakeAssoc, CreateBgpvpnResAssoc): pass class SetBgpvpnFakeResAssoc(BgpvpnFakeAssoc, SetBgpvpnResAssoc): pass class UnsetBgpvpnFakeResAssoc(BgpvpnFakeAssoc, UnsetBgpvpnResAssoc): pass class DeleteBgpvpnFakeResAssoc(BgpvpnFakeAssoc, DeleteBgpvpnResAssoc): pass class ListBgpvpnFakeResAssoc(BgpvpnFakeAssoc, ListBgpvpnResAssoc): pass class ShowBgpvpnFakeResAssoc(BgpvpnFakeAssoc, ShowBgpvpnResAssoc): pass class FakeResource(object): """Fake resource with minimal attributes.""" @staticmethod def create_one_resource(attrs=None): """Create a fake resource.""" attrs = attrs or {} # Set default attributes. res_attrs = { 'id': 'fake_resource_id', 'tenant_id': _FAKE_PROJECT_ID, } # Overwrite default attributes. res_attrs.update(attrs) return copy.deepcopy(res_attrs) @staticmethod def create_resources(attrs=None, count=1): """Create multiple fake resources.""" resources = [] for i in range(0, count): if attrs is None: attrs = {'id': 'fake_id%d' % i} elif getattr(attrs, 'id', None) is None: attrs['id'] = 'fake_id%d' % i resources.append(FakeResource.create_one_resource(attrs)) return {'%ss' % BgpvpnFakeAssoc._assoc_res_name: resources} class FakeResAssoc(object): """Fake resource association with minimal attributes.""" @staticmethod def create_one_resource_association(resource): """Create a fake resource association.""" res_assoc_attrs = { 'id': 'fake_association_id', 'tenant_id': resource['tenant_id'], 'fake_resource_id': resource['id'], } return copy.deepcopy(res_assoc_attrs) @staticmethod def create_resource_associations(resources): """Create multiple fake resource associations.""" res_assocs = [] for idx, resource in enumerate( resources['%ss' % BgpvpnFakeAssoc._assoc_res_name]): res_assoc_attrs = { 'id': 'fake_association_id%d' % idx, 'tenant_id': resource['tenant_id'], 'fake_resource_id': resource['id'], } res_assocs.append(copy.deepcopy(res_assoc_attrs)) return {BgpvpnFakeAssoc._resource_plural: res_assocs} ././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/networking_bgpvpn/test_resource_association.pypython-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/networking_bgpvpn/test_resource_associati0000666000175100017510000002714113232473407034534 0ustar zuulzuul00000000000000# Copyright (c) 2016 Juniper Networks Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy import operator import mock from osc_lib import exceptions from osc_lib import utils as osc_utils from neutronclient.osc import utils as nc_osc_utils from neutronclient.tests.unit.osc.v2.networking_bgpvpn import fakes columns_short = tuple(col for col, _, listing_mode in fakes.BgpvpnFakeAssoc._attr_map if listing_mode in (nc_osc_utils.LIST_BOTH, nc_osc_utils.LIST_SHORT_ONLY)) columns_long = tuple(col for col, _, listing_mode in fakes.BgpvpnFakeAssoc._attr_map if listing_mode in (nc_osc_utils.LIST_BOTH, nc_osc_utils.LIST_LONG_ONLY)) headers_short = tuple(head for _, head, listing_mode in fakes.BgpvpnFakeAssoc._attr_map if listing_mode in (nc_osc_utils.LIST_BOTH, nc_osc_utils.LIST_SHORT_ONLY)) headers_long = tuple(head for _, head, listing_mode in fakes.BgpvpnFakeAssoc._attr_map if listing_mode in (nc_osc_utils.LIST_BOTH, nc_osc_utils.LIST_LONG_ONLY)) sorted_attr_map = sorted(fakes.BgpvpnFakeAssoc._attr_map, key=operator.itemgetter(1)) sorted_columns = tuple(col for col, _, _ in sorted_attr_map) sorted_headers = tuple(head for _, head, _ in sorted_attr_map) def _get_data(attrs, columns=sorted_columns): return osc_utils.get_dict_properties( attrs, columns, formatters=fakes.BgpvpnFakeAssoc._formatters) class TestCreateResAssoc(fakes.TestNeutronClientBgpvpn): def setUp(self): super(TestCreateResAssoc, self).setUp() self.cmd = fakes.CreateBgpvpnFakeResAssoc(self.app, self.namespace) def test_create_resource_association(self): fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn() fake_res = fakes.FakeResource.create_one_resource() fake_res_assoc = fakes.FakeResAssoc.create_one_resource_association( fake_res) self.neutronclient.create_bgpvpn_fake_resource_assoc = mock.Mock( return_value={fakes.BgpvpnFakeAssoc._resource: fake_res_assoc}) arglist = [ fake_bgpvpn['id'], fake_res['id'], '--project', fake_bgpvpn['tenant_id'], ] verifylist = [ ('bgpvpn', fake_bgpvpn['id']), ('resource', fake_res['id']), ('project', fake_bgpvpn['tenant_id']) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) cols, data = self.cmd.take_action(parsed_args) fake_res_assoc_call = copy.deepcopy(fake_res_assoc) fake_res_assoc_call.pop('id') self.neutronclient.create_bgpvpn_fake_resource_assoc.\ assert_called_once_with( fake_bgpvpn['id'], {fakes.BgpvpnFakeAssoc._resource: fake_res_assoc_call}) self.assertEqual(sorted_headers, cols) self.assertEqual(_get_data(fake_res_assoc), data) class TestSetResAssoc(fakes.TestNeutronClientBgpvpn): def setUp(self): super(TestSetResAssoc, self).setUp() self.cmd = fakes.SetBgpvpnFakeResAssoc(self.app, self.namespace) def test_set_resource_association(self): fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn() fake_res = fakes.FakeResource.create_one_resource() fake_res_assoc = fakes.FakeResAssoc.create_one_resource_association( fake_res) self.neutronclient.update_bgpvpn_fake_resource_assoc = mock.Mock( return_value={fakes.BgpvpnFakeAssoc._resource: fake_res_assoc}) arglist = [ fake_res_assoc['id'], fake_bgpvpn['id'], ] verifylist = [ ('resource_association_id', fake_res_assoc['id']), ('bgpvpn', fake_bgpvpn['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.neutronclient.update_bgpvpn_fake_resource_assoc.\ assert_not_called() self.assertIsNone(result) class TestDeleteResAssoc(fakes.TestNeutronClientBgpvpn): def setUp(self): super(TestDeleteResAssoc, self).setUp() self.cmd = fakes.DeleteBgpvpnFakeResAssoc(self.app, self.namespace) def test_delete_one_association(self): fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn() fake_res = fakes.FakeResource.create_one_resource() fake_res_assoc = fakes.FakeResAssoc.create_one_resource_association( fake_res) self.neutronclient.delete_bgpvpn_fake_resource_assoc = mock.Mock() arglist = [ fake_res_assoc['id'], fake_bgpvpn['id'], ] verifylist = [ ('resource_association_ids', [fake_res_assoc['id']]), ('bgpvpn', fake_bgpvpn['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.neutronclient.delete_bgpvpn_fake_resource_assoc.\ assert_called_once_with(fake_bgpvpn['id'], fake_res_assoc['id']) self.assertIsNone(result) def test_delete_multi_bpgvpn(self): count = 3 fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn() fake_res = fakes.FakeResource.create_resources(count=count) fake_res_assocs = fakes.FakeResAssoc.create_resource_associations( fake_res) fake_res_assoc_ids = [ fake_res_assoc['id'] for fake_res_assoc in fake_res_assocs[fakes.BgpvpnFakeAssoc._resource_plural] ] self.neutronclient.delete_bgpvpn_fake_resource_assoc = mock.Mock() arglist = \ fake_res_assoc_ids + [ fake_bgpvpn['id'] ] verifylist = [ ('resource_association_ids', fake_res_assoc_ids), ('bgpvpn', fake_bgpvpn['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.neutronclient.delete_bgpvpn_fake_resource_assoc.assert_has_calls( [mock.call(fake_bgpvpn['id'], id) for id in fake_res_assoc_ids]) self.assertIsNone(result) def test_delete_multi_bpgvpn_with_unknown(self): count = 3 fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn() fake_res = fakes.FakeResource.create_resources(count=count) fake_res_assocs = fakes.FakeResAssoc.create_resource_associations( fake_res) fake_res_assoc_ids = [ fake_res_assoc['id'] for fake_res_assoc in fake_res_assocs[fakes.BgpvpnFakeAssoc._resource_plural] ] def raise_unknonw_resource(resource_path, name_or_id): if str(count - 2) in name_or_id: raise Exception() self.neutronclient.delete_bgpvpn_fake_resource_assoc = mock.Mock( side_effect=raise_unknonw_resource) arglist = \ fake_res_assoc_ids + [ fake_bgpvpn['id'] ] verifylist = [ ('resource_association_ids', fake_res_assoc_ids), ('bgpvpn', fake_bgpvpn['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises(exceptions.CommandError, self.cmd.take_action, parsed_args) self.neutronclient.delete_bgpvpn_fake_resource_assoc.assert_has_calls( [mock.call(fake_bgpvpn['id'], id) for id in fake_res_assoc_ids]) class TestListResAssoc(fakes.TestNeutronClientBgpvpn): def setUp(self): super(TestListResAssoc, self).setUp() self.cmd = fakes.ListBgpvpnFakeResAssoc(self.app, self.namespace) def test_list_bgpvpn_associations(self): count = 3 fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn() fake_res = fakes.FakeResource.create_resources(count=count) fake_res_assocs = fakes.FakeResAssoc.create_resource_associations( fake_res) self.neutronclient.list_bgpvpn_fake_resource_assocs = mock.Mock( return_value=fake_res_assocs) arglist = [ fake_bgpvpn['id'], ] verifylist = [ ('bgpvpn', fake_bgpvpn['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.neutronclient.list_bgpvpn_fake_resource_assocs.\ assert_called_once_with(fake_bgpvpn['id'], retrieve_all=True) self.assertEqual(headers, list(headers_short)) self.assertEqual( list(data), [_get_data(fake_res_assoc, columns_short) for fake_res_assoc in fake_res_assocs[fakes.BgpvpnFakeAssoc._resource_plural]]) def test_list_bgpvpn_associations_long_mode(self): count = 3 fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn() fake_res = fakes.FakeResource.create_resources(count=count) fake_res_assocs = fakes.FakeResAssoc.create_resource_associations( fake_res) self.neutronclient.list_bgpvpn_fake_resource_assocs = mock.Mock( return_value=fake_res_assocs) arglist = [ '--long', fake_bgpvpn['id'], ] verifylist = [ ('long', True), ('bgpvpn', fake_bgpvpn['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.neutronclient.list_bgpvpn_fake_resource_assocs.\ assert_called_once_with(fake_bgpvpn['id'], retrieve_all=True) self.assertEqual(headers, list(headers_long)) self.assertEqual( list(data), [_get_data(fake_res_assoc, columns_long) for fake_res_assoc in fake_res_assocs[fakes.BgpvpnFakeAssoc._resource_plural]]) class TestShowResAssoc(fakes.TestNeutronClientBgpvpn): def setUp(self): super(TestShowResAssoc, self).setUp() self.cmd = fakes.ShowBgpvpnFakeResAssoc(self.app, self.namespace) def test_show_resource_association(self): fake_bgpvpn = fakes.FakeBgpvpn.create_one_bgpvpn() fake_res = fakes.FakeResource.create_one_resource() fake_res_assoc = fakes.FakeResAssoc.create_one_resource_association( fake_res) self.neutronclient.show_bgpvpn_fake_resource_assoc = mock.Mock( return_value={fakes.BgpvpnFakeAssoc._resource: fake_res_assoc}) arglist = [ fake_res_assoc['id'], fake_bgpvpn['id'], ] verifylist = [ ('resource_association_id', fake_res_assoc['id']), ('bgpvpn', fake_bgpvpn['id']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.neutronclient.show_bgpvpn_fake_resource_assoc.\ assert_called_once_with(fake_bgpvpn['id'], fake_res_assoc['id']) self.assertEqual(sorted_headers, headers) self.assertEqual(data, _get_data(fake_res_assoc)) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/networking_bgpvpn/__init__.py0000666000175100017510000000000013232473350031753 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/vpnaas/0000775000175100017510000000000013232473710025377 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/vpnaas/common.py0000666000175100017510000001263313232473350027250 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import testtools from osc_lib import exceptions from neutronclient.tests.unit.osc.v2 import fakes as test_fakes class TestCreateVPNaaS(test_fakes.TestNeutronClientOSCV2): pass class TestDeleteVPNaaS(test_fakes.TestNeutronClientOSCV2): def test_delete_with_one_resource(self): target = self.resource['id'] arglist = [target] verifylist = [(self.res, [target])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with(target) self.assertIsNone(result) def test_delete_with_multiple_resources(self): def _mock_vpnaas(*args, **kwargs): self.assertEqual(self.res, args[0]) self.assertIsNotNone(args[1]) self.assertEqual({'cmd_resource': self.res}, kwargs) return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_vpnaas target1 = 'target1' target2 = 'target2' arglist = [target1, target2] verifylist = [(self.res, [target1, target2])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.assertIsNone(result) self.assertEqual(2, self.mocked.call_count) for idx, reference in enumerate([target1, target2]): actual = ''.join(self.mocked.call_args_list[idx][0]) self.assertEqual(reference, actual) def test_delete_multiple_with_exception(self): target1 = 'target' arglist = [target1] verifylist = [(self.res, [target1])] self.neutronclient.find_resource.side_effect = [ target1, exceptions.CommandError ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) resource_name = self.res.replace('_', ' ') msg = "1 of 2 %s(s) failed to delete." % resource_name with testtools.ExpectedException(exceptions.CommandError) as e: self.cmd.take_action(parsed_args) self.assertEqual(msg, str(e)) class TestListVPNaaS(test_fakes.TestNeutronClientOSCV2): def test_list_with_no_option(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.list_headers), headers) self.assertEqual([self.list_data], list(data)) def test_list_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.headers), headers) self.assertEqual([self.data], list(data)) class TestSetVPNaaS(test_fakes.TestNeutronClientOSCV2): def test_set_name(self): target = self.resource['id'] update = 'change' arglist = [target, '--name', update] verifylist = [ (self.res, target), ('name', update), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'name': update}}) self.assertIsNone(result) def test_set_description(self): target = self.resource['id'] update = 'change-desc' arglist = [target, '--description', update] verifylist = [ (self.res, target), ('description', update), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'description': update}}) self.assertIsNone(result) class TestShowVPNaaS(test_fakes.TestNeutronClientOSCV2): def test_show_filtered_by_id_or_name(self): target = self.resource['id'] def _mock_vpnaas(*args, **kwargs): if self.neutronclient.find_resource.call_count == 1: self.assertEqual(self.res, args[0]) self.assertEqual(self.resource['id'], args[1]) self.assertEqual({'cmd_resource': self.res}, kwargs) return {'id': args[1]} self.neutronclient.find_resource.side_effect = _mock_vpnaas arglist = [target] verifylist = [(self.res, target)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with(target) self.assertEqual(self.ordered_headers, headers) self.assertItemEqual(self.ordered_data, data) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/vpnaas/test_ikepolicy.py0000666000175100017510000002450113232473350031004 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy import mock from osc_lib.tests import utils as tests_utils from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.vpnaas import ikepolicy from neutronclient.tests.unit.osc.v2 import fakes as test_fakes from neutronclient.tests.unit.osc.v2.vpnaas import common from neutronclient.tests.unit.osc.v2.vpnaas import fakes _ikepolicy = fakes.IKEPolicy().create() CONVERT_MAP = { 'project': 'tenant_id', } def _generate_data(ordered_dict=None, data=None): source = ordered_dict if ordered_dict else _ikepolicy if data: source.update(data) return tuple(source[key] for key in source) def _generate_req_and_res(verifylist): request = dict(verifylist) response = copy.deepcopy(_ikepolicy) for key, val in verifylist: converted = CONVERT_MAP.get(key, key) del request[key] new_value = val request[converted] = new_value response[converted] = new_value return request, response class TestIKEPolicy(test_fakes.TestNeutronClientOSCV2): def check_results(self, headers, data, exp_req, is_list=False): if is_list: req_body = {self.res_plural: [exp_req]} else: req_body = {self.res: exp_req} self.mocked.assert_called_once_with(req_body) self.assertEqual(self.ordered_headers, headers) self.assertEqual(self.ordered_data, data) def setUp(self): super(TestIKEPolicy, self).setUp() def _mock_ikepolicy(*args, **kwargs): self.neutronclient.find_resource.assert_called_once_with( self.res, self.resource['id'], cmd_resource='ikepolicy') return {'id': args[1]} self.neutronclient.find_resource.side_effect = mock.Mock( side_effect=_mock_ikepolicy) osc_utils.find_project = mock.Mock() osc_utils.find_project.id = _ikepolicy['tenant_id'] self.res = 'ikepolicy' self.res_plural = 'ikepolicies' self.resource = _ikepolicy self.headers = ( 'ID', 'Name', 'Authentication Algorithm', 'Encryption Algorithm', 'IKE Version', 'Perfect Forward Secrecy (PFS)', 'Description', 'Phase1 Negotiation Mode', 'Project', 'Lifetime', ) self.data = _generate_data() self.ordered_headers = ( 'Authentication Algorithm', 'Description', 'Encryption Algorithm', 'ID', 'IKE Version', 'Lifetime', 'Name', 'Perfect Forward Secrecy (PFS)', 'Phase1 Negotiation Mode', 'Project', ) self.ordered_data = ( _ikepolicy['auth_algorithm'], _ikepolicy['description'], _ikepolicy['encryption_algorithm'], _ikepolicy['id'], _ikepolicy['ike_version'], _ikepolicy['lifetime'], _ikepolicy['name'], _ikepolicy['pfs'], _ikepolicy['phase1_negotiation_mode'], _ikepolicy['tenant_id'], ) self.ordered_columns = ( 'auth_algorithm', 'description', 'encryption_algorithm', 'id', 'ike_version', 'lifetime', 'name', 'pfs', 'phase1_negotiation_mode', 'tenant_id', ) class TestCreateIKEPolicy(TestIKEPolicy, common.TestCreateVPNaaS): def setUp(self): super(TestCreateIKEPolicy, self).setUp() self.neutronclient.create_ikepolicy = mock.Mock( return_value={self.res: _ikepolicy}) self.mocked = self.neutronclient.create_ikepolicy self.cmd = ikepolicy.CreateIKEPolicy(self.app, self.namespace) def _update_expect_response(self, request, response): """Set expected request and response :param request A dictionary of request body(dict of verifylist) :param response A OrderedDict of request body """ # Update response body self.neutronclient.create_ikepolicy.return_value = \ {self.res: dict(response)} osc_utils.find_project.return_value.id = response['tenant_id'] # Update response(finally returns 'data') self.data = _generate_data(ordered_dict=response) self.ordered_data = tuple( response[column] for column in self.ordered_columns ) def _set_all_params(self, args={}): name = args.get('name') or 'my-name' description = args.get('description') or 'my-desc' auth_algorithm = args.get('auth_algorithm') or 'sha1' encryption_algorithm = args.get('encryption_algorithm') or 'aes-128' phase1_negotiation_mode = args.get('phase1_negotiation_mode') or 'main' ike_version = args.get('ike_version') or 'v1' pfs = args.get('pfs') or 'group5' tenant_id = args.get('tenant_id') or 'my-tenant' arglist = [ '--description', description, '--auth-algorithm', auth_algorithm, '--encryption-algorithm', encryption_algorithm, '--phase1-negotiation-mode', phase1_negotiation_mode, '--ike-version', ike_version, '--pfs', pfs, '--project', tenant_id, name, ] verifylist = [ ('description', description), ('auth_algorithm', auth_algorithm), ('encryption_algorithm', encryption_algorithm), ('phase1_negotiation_mode', phase1_negotiation_mode), ('ike_version', ike_version), ('pfs', pfs), ('project', tenant_id), ('name', name), ] return arglist, verifylist def _test_create_with_all_params(self, args={}): arglist, verifylist = self._set_all_params(args) request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.check_results(headers, data, request) def test_create_with_no_options(self): arglist = [] verifylist = [] self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_all_params(self): self._test_create_with_all_params() def test_create_with_all_params_name(self): self._test_create_with_all_params({'name': 'new_ikepolicy'}) class TestDeleteIKEPolicy(TestIKEPolicy, common.TestDeleteVPNaaS): def setUp(self): super(TestDeleteIKEPolicy, self).setUp() self.neutronclient.delete_ikepolicy = mock.Mock( return_value={self.res: _ikepolicy}) self.mocked = self.neutronclient.delete_ikepolicy self.cmd = ikepolicy.DeleteIKEPolicy(self.app, self.namespace) class TestListIKEPolicy(TestIKEPolicy): def setUp(self): super(TestListIKEPolicy, self).setUp() self.cmd = ikepolicy.ListIKEPolicy(self.app, self.namespace) self.short_header = ( 'ID', 'Name', 'Authentication Algorithm', 'Encryption Algorithm', 'IKE Version', 'Perfect Forward Secrecy (PFS)', ) self.short_data = ( _ikepolicy['id'], _ikepolicy['name'], _ikepolicy['auth_algorithm'], _ikepolicy['encryption_algorithm'], _ikepolicy['ike_version'], _ikepolicy['pfs'], ) self.neutronclient.list_ikepolicies = mock.Mock( return_value={self.res_plural: [_ikepolicy]}) self.mocked = self.neutronclient.list_ikepolicies def test_list_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.headers), headers) self.assertEqual([self.data], list(data)) def test_list_with_no_option(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.short_header), headers) self.assertEqual([self.short_data], list(data)) class TestSetIKEPolicy(TestIKEPolicy, common.TestSetVPNaaS): def setUp(self): super(TestSetIKEPolicy, self).setUp() self.neutronclient.update_ikepolicy = mock.Mock( return_value={self.res: _ikepolicy}) self.mocked = self.neutronclient.update_ikepolicy self.cmd = ikepolicy.SetIKEPolicy(self.app, self.namespace) def test_set_auth_algorithm_with_sha256(self): target = self.resource['id'] auth_algorithm = 'sha256' arglist = [target, '--auth-algorithm', auth_algorithm] verifylist = [ (self.res, target), ('auth_algorithm', auth_algorithm), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'auth_algorithm': 'sha256'}}) self.assertIsNone(result) class TestShowIKEPolicy(TestIKEPolicy, common.TestShowVPNaaS): def setUp(self): super(TestShowIKEPolicy, self).setUp() self.neutronclient.show_ikepolicy = mock.Mock( return_value={self.res: _ikepolicy}) self.mocked = self.neutronclient.show_ikepolicy self.cmd = ikepolicy.ShowIKEPolicy(self.app, self.namespace) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/vpnaas/test_ipsec_site_connection.py0000666000175100017510000003255213232473350033367 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy import mock from osc_lib.cli import format_columns from osc_lib.tests import utils as tests_utils from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.vpnaas import ipsec_site_connection from neutronclient.tests.unit.osc.v2 import fakes as test_fakes from neutronclient.tests.unit.osc.v2.vpnaas import common from neutronclient.tests.unit.osc.v2.vpnaas import fakes _ipsec_site_conn = fakes.IPsecSiteConnection().create_conn() CONVERT_MAP = { 'project': 'tenant_id', 'ikepolicy': 'ikepolicy_id', 'ipsecpolicy': 'ipsecpolicy_id', 'vpnservice': 'vpnservice_id', 'peer_endpoint_group': 'peer_ep_group_id', 'local_endpoint_group': 'local_ep_group_id', } def _generate_data(ordered_dict=None, data=None): source = ordered_dict if ordered_dict else _ipsec_site_conn if data: source.update(data) return ( _ipsec_site_conn['id'], _ipsec_site_conn['name'], _ipsec_site_conn['peer_address'], _ipsec_site_conn['auth_mode'], _ipsec_site_conn['status'], _ipsec_site_conn['tenant_id'], format_columns.ListColumn(_ipsec_site_conn['peer_cidrs']), _ipsec_site_conn['vpnservice_id'], _ipsec_site_conn['ipsecpolicy_id'], _ipsec_site_conn['ikepolicy_id'], _ipsec_site_conn['mtu'], _ipsec_site_conn['initiator'], _ipsec_site_conn['admin_state_up'], _ipsec_site_conn['description'], _ipsec_site_conn['psk'], _ipsec_site_conn['route_mode'], _ipsec_site_conn['local_id'], _ipsec_site_conn['peer_id'], _ipsec_site_conn['local_ep_group_id'], _ipsec_site_conn['peer_ep_group_id'], ) def _generate_req_and_res(verifylist): request = dict(verifylist) response = copy.deepcopy(_ipsec_site_conn) for key, val in verifylist: converted = CONVERT_MAP.get(key, key) del request[key] new_value = val request[converted] = new_value response[converted] = new_value return request, response class TestIPsecSiteConn(test_fakes.TestNeutronClientOSCV2): def check_results(self, headers, data, exp_req, is_list=False): if is_list: req_body = {self.res_plural: [exp_req]} else: req_body = {self.res: exp_req} self.mocked.assert_called_once_with(req_body) self.assertEqual(self.ordered_headers, headers) self.assertItemEqual(self.ordered_data, data) def setUp(self): super(TestIPsecSiteConn, self).setUp() def _mock_ipsec_site_conn(*args, **kwargs): return {'id': args[1]} self.neutronclient.find_resource.side_effect = mock.Mock( side_effect=_mock_ipsec_site_conn) osc_utils.find_project = mock.Mock() osc_utils.find_project.id = _ipsec_site_conn['tenant_id'] self.res = 'ipsec_site_connection' self.res_plural = 'ipsec_site_connections' self.resource = _ipsec_site_conn self.headers = ( 'ID', 'Name', 'Peer Address', 'Authentication Algorithm', 'Status', 'Project', 'Peer CIDRs', 'VPN Service', 'IPSec Policy', 'IKE Policy', 'MTU', 'Initiator', 'State', 'Description', 'Pre-shared Key', 'Route Mode', 'Local ID', 'Peer ID', 'Local Endpoint Group ID', 'Peer Endpoint Group ID' ) self.data = _generate_data() self.ordered_headers = ( 'Authentication Algorithm', 'Description', 'ID', 'IKE Policy', 'IPSec Policy', 'Initiator', 'Local Endpoint Group ID', 'Local ID', 'MTU', 'Name', 'Peer Address', 'Peer CIDRs', 'Peer Endpoint Group ID', 'Peer ID', 'Pre-shared Key', 'Project', 'Route Mode', 'State', 'Status', 'VPN Service', ) self.ordered_data = ( _ipsec_site_conn['auth_mode'], _ipsec_site_conn['description'], _ipsec_site_conn['id'], _ipsec_site_conn['ikepolicy_id'], _ipsec_site_conn['ipsecpolicy_id'], _ipsec_site_conn['initiator'], _ipsec_site_conn['local_ep_group_id'], _ipsec_site_conn['local_id'], _ipsec_site_conn['mtu'], _ipsec_site_conn['name'], _ipsec_site_conn['peer_address'], format_columns.ListColumn(_ipsec_site_conn['peer_cidrs']), _ipsec_site_conn['peer_ep_group_id'], _ipsec_site_conn['peer_id'], _ipsec_site_conn['psk'], _ipsec_site_conn['tenant_id'], _ipsec_site_conn['route_mode'], _ipsec_site_conn['admin_state_up'], _ipsec_site_conn['status'], _ipsec_site_conn['vpnservice_id'], ) class TestCreateIPsecSiteConn(TestIPsecSiteConn, common.TestCreateVPNaaS): def setUp(self): super(TestCreateIPsecSiteConn, self).setUp() self.neutronclient.create_ipsec_site_connection = mock.Mock( return_value={self.res: _ipsec_site_conn}) self.mocked = self.neutronclient.create_ipsec_site_connection self.cmd = ipsec_site_connection.CreateIPsecSiteConnection( self.app, self.namespace) def _update_expect_response(self, request, response): """Set expected request and response :param request A dictionary of request body(dict of verifylist) :param response A OrderedDict of request body """ # Update response body self.neutronclient.create_ipsec_site_connection.return_value = \ {self.res: dict(response)} osc_utils.find_project.return_value.id = response['tenant_id'] # Update response(finally returns 'data') self.data = _generate_data(ordered_dict=response) self.ordered_data = ( response['auth_mode'], response['description'], response['id'], response['ikepolicy_id'], response['ipsecpolicy_id'], response['initiator'], response['local_ep_group_id'], response['local_id'], response['mtu'], response['name'], response['peer_address'], format_columns.ListColumn(response['peer_cidrs']), response['peer_ep_group_id'], response['peer_id'], response['psk'], response['tenant_id'], response['route_mode'], response['admin_state_up'], response['status'], response['vpnservice_id'], ) def _set_all_params(self, args={}): tenant_id = args.get('tenant_id') or 'my-tenant' name = args.get('name') or 'connection1' peer_address = args.get('peer_address') or '192.168.2.10' peer_id = args.get('peer_id') or '192.168.2.10' psk = args.get('psk') or 'abcd' mtu = args.get('mtu') or '1500' initiator = args.get('initiator') or 'bi-directional' vpnservice_id = args.get('vpnservice') or 'vpnservice_id' ikepolicy_id = args.get('ikepolicy') or 'ikepolicy_id' ipsecpolicy_id = args.get('ipsecpolicy') or 'ipsecpolicy_id' local_ep_group = args.get('local_ep_group_id') or 'local-epg' peer_ep_group = args.get('peer_ep_group_id') or 'peer-epg' description = args.get('description') or 'my-vpn-connection' arglist = [ '--project', tenant_id, '--peer-address', peer_address, '--peer-id', peer_id, '--psk', psk, '--initiator', initiator, '--vpnservice', vpnservice_id, '--ikepolicy', ikepolicy_id, '--ipsecpolicy', ipsecpolicy_id, '--mtu', mtu, '--description', description, '--local-endpoint-group', local_ep_group, '--peer-endpoint-group', peer_ep_group, name, ] verifylist = [ ('project', tenant_id), ('peer_address', peer_address), ('peer_id', peer_id), ('psk', psk), ('initiator', initiator), ('vpnservice', vpnservice_id), ('ikepolicy', ikepolicy_id), ('ipsecpolicy', ipsecpolicy_id), ('mtu', mtu), ('description', description), ('local_endpoint_group', local_ep_group), ('peer_endpoint_group', peer_ep_group), ('name', name), ] return arglist, verifylist def _test_create_with_all_params(self, args={}): arglist, verifylist = self._set_all_params(args) request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.check_results(headers, data, request) def test_create_with_no_options(self): arglist = [] verifylist = [] self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_all_params(self): self._test_create_with_all_params() class TestDeleteIPsecSiteConn(TestIPsecSiteConn, common.TestDeleteVPNaaS): def setUp(self): super(TestDeleteIPsecSiteConn, self).setUp() self.neutronclient.delete_ipsec_site_connection = mock.Mock( return_value={self.res: _ipsec_site_conn}) self.mocked = self.neutronclient.delete_ipsec_site_connection self.cmd = ipsec_site_connection.DeleteIPsecSiteConnection( self.app, self.namespace) class TestListIPsecSiteConn(TestIPsecSiteConn): def setUp(self): super(TestListIPsecSiteConn, self).setUp() self.cmd = ipsec_site_connection.ListIPsecSiteConnection( self.app, self.namespace) self.short_header = ( 'ID', 'Name', 'Peer Address', 'Authentication Algorithm', 'Status', ) self.short_data = ( _ipsec_site_conn['id'], _ipsec_site_conn['name'], _ipsec_site_conn['peer_address'], _ipsec_site_conn['auth_mode'], _ipsec_site_conn['status'], ) self.neutronclient.list_ipsec_site_connections = mock.Mock( return_value={self.res_plural: [_ipsec_site_conn]}) self.mocked = self.neutronclient.list_ipsec_site_connections def test_list_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.headers), headers) self.assertListItemEqual([self.data], list(data)) def test_list_with_no_option(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.short_header), headers) self.assertEqual([self.short_data], list(data)) class TestSetIPsecSiteConn(TestIPsecSiteConn, common.TestSetVPNaaS): def setUp(self): super(TestSetIPsecSiteConn, self).setUp() self.neutronclient.update_ipsec_site_connection = mock.Mock( return_value={self.res: _ipsec_site_conn}) self.mocked = self.neutronclient.update_ipsec_site_connection self.cmd = ipsec_site_connection.SetIPsecSiteConnection( self.app, self.namespace) def test_set_ipsec_site_conn_with_peer_id(self): target = self.resource['id'] peer_id = '192.168.3.10' arglist = [target, '--peer-id', peer_id] verifylist = [ (self.res, target), ('peer_id', peer_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'peer_id': peer_id}}) self.assertIsNone(result) class TestShowIPsecSiteConn(TestIPsecSiteConn, common.TestShowVPNaaS): def setUp(self): super(TestShowIPsecSiteConn, self).setUp() self.neutronclient.show_ipsec_site_connection = mock.Mock( return_value={self.res: _ipsec_site_conn}) self.mocked = self.neutronclient.show_ipsec_site_connection self.cmd = ipsec_site_connection.ShowIPsecSiteConnection( self.app, self.namespace) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/vpnaas/test_ipsecpolicy.py0000666000175100017510000002477213232473350031351 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy import mock from osc_lib.tests import utils as tests_utils from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.vpnaas import ipsecpolicy from neutronclient.tests.unit.osc.v2 import fakes as test_fakes from neutronclient.tests.unit.osc.v2.vpnaas import common from neutronclient.tests.unit.osc.v2.vpnaas import fakes _ipsecpolicy = fakes.IPSecPolicy().create() CONVERT_MAP = { 'project': 'tenant_id', } def _generate_data(ordered_dict=None, data=None): source = ordered_dict if ordered_dict else _ipsecpolicy if data: source.update(data) return tuple(source[key] for key in source) def _generate_req_and_res(verifylist): request = dict(verifylist) response = copy.deepcopy(_ipsecpolicy) for key, val in verifylist: converted = CONVERT_MAP.get(key, key) del request[key] new_value = val request[converted] = new_value response[converted] = new_value return request, response class TestIPSecPolicy(test_fakes.TestNeutronClientOSCV2): def check_results(self, headers, data, exp_req, is_list=False): if is_list: req_body = {self.res_plural: [exp_req]} else: req_body = {self.res: exp_req} self.mocked.assert_called_once_with(req_body) self.assertEqual(self.ordered_headers, headers) self.assertEqual(self.ordered_data, data) def setUp(self): super(TestIPSecPolicy, self).setUp() def _mock_ipsecpolicy(*args, **kwargs): self.neutronclient.find_resource.assert_called_once_with( self.res, self.resource['id'], cmd_resource='ipsecpolicy') return {'id': args[1]} self.neutronclient.find_resource.side_effect = mock.Mock( side_effect=_mock_ipsecpolicy) osc_utils.find_project = mock.Mock() osc_utils.find_project.id = _ipsecpolicy['tenant_id'] self.res = 'ipsecpolicy' self.res_plural = 'ipsecpolicies' self.resource = _ipsecpolicy self.headers = ( 'ID', 'Name', 'Authentication Algorithm', 'Encapsulation Mode', 'Transform Protocol', 'Encryption Algorithm', 'Perfect Forward Secrecy (PFS)', 'Description', 'Project', 'Lifetime', ) self.data = _generate_data() self.ordered_headers = ( 'Authentication Algorithm', 'Description', 'Encapsulation Mode', 'Encryption Algorithm', 'ID', 'Lifetime', 'Name', 'Perfect Forward Secrecy (PFS)', 'Project', 'Transform Protocol', ) self.ordered_data = ( _ipsecpolicy['auth_algorithm'], _ipsecpolicy['description'], _ipsecpolicy['encapsulation_mode'], _ipsecpolicy['encryption_algorithm'], _ipsecpolicy['id'], _ipsecpolicy['lifetime'], _ipsecpolicy['name'], _ipsecpolicy['pfs'], _ipsecpolicy['tenant_id'], _ipsecpolicy['transform_protocol'], ) self.ordered_columns = ( 'auth_algorithm', 'description', 'encapsulation_mode', 'encryption_algorithm', 'id', 'lifetime', 'name', 'pfs', 'tenant_id', 'transform_protocol', ) class TestCreateIPSecPolicy(TestIPSecPolicy, common.TestCreateVPNaaS): def setUp(self): super(TestCreateIPSecPolicy, self).setUp() self.neutronclient.create_ipsecpolicy = mock.Mock( return_value={self.res: _ipsecpolicy}) self.mocked = self.neutronclient.create_ipsecpolicy self.cmd = ipsecpolicy.CreateIPsecPolicy(self.app, self.namespace) def _update_expect_response(self, request, response): """Set expected request and response :param request A dictionary of request body(dict of verifylist) :param response A OrderedDict of request body """ # Update response body self.neutronclient.create_ipsecpolicy.return_value = \ {self.res: dict(response)} osc_utils.find_project.return_value.id = response['tenant_id'] # Update response(finally returns 'data') self.data = _generate_data(ordered_dict=response) self.ordered_data = tuple( response[column] for column in self.ordered_columns ) def _set_all_params(self, args={}): name = args.get('name') or 'my-name' auth_algorithm = args.get('auth_algorithm') or 'sha1' encapsulation_mode = args.get('encapsulation_mode') or 'tunnel' transform_protocol = args.get('transform_protocol') or 'esp' encryption_algorithm = args.get('encryption_algorithm') or 'aes-128' pfs = args.get('pfs') or 'group5' description = args.get('description') or 'my-desc' tenant_id = args.get('tenant_id') or 'my-tenant' arglist = [ name, '--auth-algorithm', auth_algorithm, '--encapsulation-mode', encapsulation_mode, '--transform-protocol', transform_protocol, '--encryption-algorithm', encryption_algorithm, '--pfs', pfs, '--description', description, '--project', tenant_id, ] verifylist = [ ('name', name), ('auth_algorithm', auth_algorithm), ('encapsulation_mode', encapsulation_mode), ('transform_protocol', transform_protocol), ('encryption_algorithm', encryption_algorithm), ('pfs', pfs), ('description', description), ('project', tenant_id), ] return arglist, verifylist def _test_create_with_all_params(self, args={}): arglist, verifylist = self._set_all_params(args) request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.check_results(headers, data, request) def test_create_with_no_options(self): arglist = [] verifylist = [] self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_all_params(self): self._test_create_with_all_params() def test_create_with_all_params_name(self): self._test_create_with_all_params({'name': 'new_ipsecpolicy'}) class TestDeleteIPSecPolicy(TestIPSecPolicy, common.TestDeleteVPNaaS): def setUp(self): super(TestDeleteIPSecPolicy, self).setUp() self.neutronclient.delete_ipsecpolicy = mock.Mock( return_value={self.res: _ipsecpolicy}) self.mocked = self.neutronclient.delete_ipsecpolicy self.cmd = ipsecpolicy.DeleteIPsecPolicy(self.app, self.namespace) class TestListIPSecPolicy(TestIPSecPolicy): def setUp(self): super(TestListIPSecPolicy, self).setUp() self.cmd = ipsecpolicy.ListIPsecPolicy(self.app, self.namespace) self.short_header = ( 'ID', 'Name', 'Authentication Algorithm', 'Encapsulation Mode', 'Transform Protocol', 'Encryption Algorithm', ) self.short_data = ( _ipsecpolicy['id'], _ipsecpolicy['name'], _ipsecpolicy['auth_algorithm'], _ipsecpolicy['encapsulation_mode'], _ipsecpolicy['transform_protocol'], _ipsecpolicy['encryption_algorithm'], ) self.neutronclient.list_ipsecpolicies = mock.Mock( return_value={self.res_plural: [_ipsecpolicy]}) self.mocked = self.neutronclient.list_ipsecpolicies def test_list_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.headers), headers) self.assertEqual([self.data], list(data)) def test_list_with_no_option(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.short_header), headers) self.assertEqual([self.short_data], list(data)) class TestSetIPSecPolicy(TestIPSecPolicy, common.TestSetVPNaaS): def setUp(self): super(TestSetIPSecPolicy, self).setUp() self.neutronclient.update_ipsecpolicy = mock.Mock( return_value={self.res: _ipsecpolicy}) self.mocked = self.neutronclient.update_ipsecpolicy self.cmd = ipsecpolicy.SetIPsecPolicy(self.app, self.namespace) def test_set_auth_algorithm_with_sha256(self): target = self.resource['id'] auth_algorithm = 'sha256' arglist = [target, '--auth-algorithm', auth_algorithm] verifylist = [ (self.res, target), ('auth_algorithm', auth_algorithm), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'auth_algorithm': 'sha256'}}) self.assertIsNone(result) class TestShowIPSecPolicy(TestIPSecPolicy, common.TestShowVPNaaS): def setUp(self): super(TestShowIPSecPolicy, self).setUp() self.neutronclient.show_ipsecpolicy = mock.Mock( return_value={self.res: _ipsecpolicy}) self.mocked = self.neutronclient.show_ipsecpolicy self.cmd = ipsecpolicy.ShowIPsecPolicy(self.app, self.namespace) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/vpnaas/fakes.py0000666000175100017510000001416213232473350027050 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import collections import copy import uuid import mock class FakeVPNaaS(object): def create(self, attrs={}): """Create a fake vpnaas resources :param Dictionary attrs: A dictionary with all attributes :return: A OrderedDict faking the vpnaas resource """ self.ordered.update(attrs) return copy.deepcopy(self.ordered) def bulk_create(self, attrs=None, count=2): """Create multiple fake vpnaas resources :param Dictionary attrs: A dictionary with all attributes :param int count: The number of vpnaas resources to fake :return: A list of dictionaries faking the vpnaas resources """ return [self.create(attrs=attrs) for i in range(0, count)] def get(self, attrs=None, count=2): """Get multiple fake vpnaas resources :param Dictionary attrs: A dictionary with all attributes :param int count: The number of vpnaas resources to fake :return: A list of dictionaries faking the vpnaas resource """ if attrs is None: self.attrs = self.bulk_create(count=count) return mock.Mock(side_effect=attrs) class IKEPolicy(FakeVPNaaS): """Fake one or more IKE policies""" def __init__(self): super(IKEPolicy, self).__init__() self.ordered = collections.OrderedDict(( ('id', 'ikepolicy-id-' + uuid.uuid4().hex), ('name', 'my-ikepolicy-' + uuid.uuid4().hex), ('auth_algorithm', 'sha1'), ('encryption_algorithm', 'aes-128'), ('ike_version', 'v1'), ('pfs', 'group5'), ('description', 'my-desc-' + uuid.uuid4().hex), ('phase1_negotiation_mode', 'main'), ('tenant_id', 'tenant-id-' + uuid.uuid4().hex), ('lifetime', {'units': 'seconds', 'value': 3600}), )) class IPSecPolicy(FakeVPNaaS): """Fake one or more IPsec policies""" def __init__(self): super(IPSecPolicy, self).__init__() self.ordered = collections.OrderedDict(( ('id', 'ikepolicy-id-' + uuid.uuid4().hex), ('name', 'my-ikepolicy-' + uuid.uuid4().hex), ('auth_algorithm', 'sha1'), ('encapsulation_mode', 'tunnel'), ('transform_protocol', 'esp'), ('encryption_algorithm', 'aes-128'), ('pfs', 'group5'), ('description', 'my-desc-' + uuid.uuid4().hex), ('tenant_id', 'tenant-id-' + uuid.uuid4().hex), ('lifetime', {'units': 'seconds', 'value': 3600}), )) class VPNService(FakeVPNaaS): """Fake one or more VPN services""" def __init__(self): super(VPNService, self).__init__() self.ordered = collections.OrderedDict(( ('id', 'vpnservice-id-' + uuid.uuid4().hex), ('name', 'my-vpnservice-' + uuid.uuid4().hex), ('router_id', 'router-id-' + uuid.uuid4().hex), ('subnet_id', 'subnet-id-' + uuid.uuid4().hex), ('flavor_id', 'flavor-id-' + uuid.uuid4().hex), ('admin_state_up', True), ('status', 'ACTIVE'), ('description', 'my-desc-' + uuid.uuid4().hex), ('tenant_id', 'tenant-id-' + uuid.uuid4().hex), )) class EndpointGroup(FakeVPNaaS): """Fake one or more Endpoint Groups""" def __init__(self): super(EndpointGroup, self).__init__() self.ordered = collections.OrderedDict(( ('id', 'ep-group-id-' + uuid.uuid4().hex), ('name', 'my-ep-group-' + uuid.uuid4().hex), ('type', 'cidr'), ('endpoints', ['10.0.0.0/24', '20.0.0.0/24']), ('description', 'my-desc-' + uuid.uuid4().hex), ('tenant_id', 'tenant-id-' + uuid.uuid4().hex), )) class IPsecSiteConnection(object): """Fake one or more IPsec site connections""" @staticmethod def create_conn(attrs=None): """Create a fake IPsec conn. :param Dictionary attrs: A dictionary with all attributes :return: A Dictionary with id, name, peer_address, auth_mode, status, tenant_id, peer_cidrs, vpnservice_id, ipsecpolicy_id, ikepolicy_id, mtu, initiator, admin_state_up, description, psk, route_mode, local_id, peer_id, local_ep_group_id, peer_ep_group_id """ attrs = attrs or {} # Set default attributes. conn_attrs = { 'id': 'ipsec-site-conn-id-' + uuid.uuid4().hex, 'name': 'my-ipsec-site-conn-' + uuid.uuid4().hex, 'peer_address': '192.168.2.10', 'auth_mode': '', 'status': '', 'tenant_id': 'tenant-id-' + uuid.uuid4().hex, 'peer_cidrs': [], 'vpnservice_id': 'vpnservice-id-' + uuid.uuid4().hex, 'ipsecpolicy_id': 'ipsecpolicy-id-' + uuid.uuid4().hex, 'ikepolicy_id': 'ikepolicy-id-' + uuid.uuid4().hex, 'mtu': 1500, 'initiator': 'bi-directional', 'admin_state_up': True, 'description': 'my-vpn-connection', 'psk': 'abcd', 'route_mode': '', 'local_id': '', 'peer_id': '192.168.2.10', 'local_ep_group_id': 'local-ep-group-id-' + uuid.uuid4().hex, 'peer_ep_group_id': 'peer-ep-group-id-' + uuid.uuid4().hex, } # Overwrite default attributes. conn_attrs.update(attrs) return copy.deepcopy(conn_attrs) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/vpnaas/test_endpoint_group.py0000666000175100017510000002127213232473350032052 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy import mock from osc_lib.tests import utils as tests_utils from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.vpnaas import endpoint_group from neutronclient.tests.unit.osc.v2 import fakes as test_fakes from neutronclient.tests.unit.osc.v2.vpnaas import common from neutronclient.tests.unit.osc.v2.vpnaas import fakes _endpoint_group = fakes.EndpointGroup().create() CONVERT_MAP = { 'project': 'tenant_id', } def _generate_data(ordered_dict=None, data=None): source = ordered_dict if ordered_dict else _endpoint_group if data: source.update(data) return tuple(source[key] for key in source) def _generate_req_and_res(verifylist): request = dict(verifylist) response = copy.deepcopy(_endpoint_group) for key, val in verifylist: converted = CONVERT_MAP.get(key, key) del request[key] new_value = val request[converted] = new_value response[converted] = new_value return request, response class TestEndpointGroup(test_fakes.TestNeutronClientOSCV2): def check_results(self, headers, data, exp_req, is_list=False): if is_list: req_body = {self.res_plural: [exp_req]} else: req_body = {self.res: exp_req} self.mocked.assert_called_once_with(req_body) self.assertEqual(self.ordered_headers, headers) self.assertEqual(self.ordered_data, data) def setUp(self): super(TestEndpointGroup, self).setUp() def _mock_endpoint_group(*args, **kwargs): self.neutronclient.find_resource.assert_called_once_with( self.res, self.resource['id'], cmd_resource='endpoint_group') return {'id': args[1]} self.neutronclient.find_resource.side_effect = mock.Mock( side_effect=_mock_endpoint_group) osc_utils.find_project = mock.Mock() osc_utils.find_project.id = _endpoint_group['tenant_id'] self.res = 'endpoint_group' self.res_plural = 'endpoint_groups' self.resource = _endpoint_group self.headers = ( 'ID', 'Name', 'Type', 'Endpoints', 'Description', 'Project', ) self.data = _generate_data() self.ordered_headers = ( 'Description', 'Endpoints', 'ID', 'Name', 'Project', 'Type', ) self.ordered_data = ( _endpoint_group['description'], _endpoint_group['endpoints'], _endpoint_group['id'], _endpoint_group['name'], _endpoint_group['tenant_id'], _endpoint_group['type'], ) self.ordered_columns = ( 'description', 'endpoints', 'id', 'name', 'tenant_id', 'type', ) class TestCreateEndpointGroup(TestEndpointGroup, common.TestCreateVPNaaS): def setUp(self): super(TestCreateEndpointGroup, self).setUp() self.neutronclient.create_endpoint_group = mock.Mock( return_value={self.res: _endpoint_group}) self.mocked = self.neutronclient.create_endpoint_group self.cmd = endpoint_group.CreateEndpointGroup(self.app, self.namespace) def _update_expect_response(self, request, response): """Set expected request and response :param request A dictionary of request body(dict of verifylist) :param response A OrderedDict of request body """ # Update response body self.neutronclient.create_endpoint_group.return_value = \ {self.res: dict(response)} osc_utils.find_project.return_value.id = response['tenant_id'] # Update response(finally returns 'data') self.data = _generate_data(ordered_dict=response) self.ordered_data = tuple( response[column] for column in self.ordered_columns ) def _set_all_params_cidr(self, args={}): name = args.get('name') or 'my-name' description = args.get('description') or 'my-desc' endpoint_type = args.get('type') or 'cidr' endpoints = args.get('endpoints') or ['10.0.0.0/24', '20.0.0.0/24'] tenant_id = args.get('tenant_id') or 'my-tenant' arglist = [ '--description', description, '--type', endpoint_type, '--value', '10.0.0.0/24', '--value', '20.0.0.0/24', '--project', tenant_id, name, ] verifylist = [ ('description', description), ('type', endpoint_type), ('endpoints', endpoints), ('project', tenant_id), ('name', name), ] return arglist, verifylist def _test_create_with_all_params_cidr(self, args={}): arglist, verifylist = self._set_all_params_cidr(args) request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.check_results(headers, data, request) def test_create_with_no_options(self): arglist = [] verifylist = [] self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_create_with_all_params_cidr(self): self._test_create_with_all_params_cidr() class TestDeleteEndpointGroup(TestEndpointGroup, common.TestDeleteVPNaaS): def setUp(self): super(TestDeleteEndpointGroup, self).setUp() self.neutronclient.delete_endpoint_group = mock.Mock( return_value={self.res: _endpoint_group}) self.mocked = self.neutronclient.delete_endpoint_group self.cmd = endpoint_group.DeleteEndpointGroup(self.app, self.namespace) class TestListEndpointGroup(TestEndpointGroup): def setUp(self): super(TestListEndpointGroup, self).setUp() self.cmd = endpoint_group.ListEndpointGroup(self.app, self.namespace) self.short_header = ( 'ID', 'Name', 'Type', 'Endpoints', ) self.short_data = ( _endpoint_group['id'], _endpoint_group['name'], _endpoint_group['type'], _endpoint_group['endpoints'], ) self.neutronclient.list_endpoint_groups = mock.Mock( return_value={self.res_plural: [_endpoint_group]}) self.mocked = self.neutronclient.list_endpoint_groups def test_list_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.headers), headers) self.assertEqual([self.data], list(data)) def test_list_with_no_option(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.short_header), headers) self.assertEqual([self.short_data], list(data)) class TestSetEndpointGroup(TestEndpointGroup, common.TestSetVPNaaS): def setUp(self): super(TestSetEndpointGroup, self).setUp() self.neutronclient.update_endpoint_group = mock.Mock( return_value={self.res: _endpoint_group}) self.mocked = self.neutronclient.update_endpoint_group self.cmd = endpoint_group.SetEndpointGroup(self.app, self.namespace) class TestShowEndpointGroup(TestEndpointGroup, common.TestShowVPNaaS): def setUp(self): super(TestShowEndpointGroup, self).setUp() self.neutronclient.show_endpoint_group = mock.Mock( return_value={self.res: _endpoint_group}) self.mocked = self.neutronclient.show_endpoint_group self.cmd = endpoint_group.ShowEndpointGroup(self.app, self.namespace) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/vpnaas/test_vpnservice.py0000666000175100017510000002363313232473350031205 0ustar zuulzuul00000000000000# Copyright 2017 FUJITSU LIMITED # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import copy import uuid import mock from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.vpnaas import vpnservice from neutronclient.tests.unit.osc.v2 import fakes as test_fakes from neutronclient.tests.unit.osc.v2.vpnaas import common from neutronclient.tests.unit.osc.v2.vpnaas import fakes _vpnservice = fakes.VPNService().create() CONVERT_MAP = { 'project': 'tenant_id', 'router': 'router_id', 'subnet': 'subnet_id' } def _generate_data(ordered_dict=None, data=None): source = ordered_dict if ordered_dict else _vpnservice if data: source.update(data) return tuple(source[key] for key in source) def _generate_req_and_res(verifylist): request = dict(verifylist) response = copy.deepcopy(_vpnservice) for key, val in verifylist: converted = CONVERT_MAP.get(key, key) del request[key] new_value = val request[converted] = new_value response[converted] = new_value return request, response class TestVPNService(test_fakes.TestNeutronClientOSCV2): def _check_results(self, headers, data, exp_req, is_list=False): if is_list: req_body = {self.res_plural: [exp_req]} else: req_body = {self.res: exp_req} self.mocked.assert_called_once_with(req_body) self.assertEqual(self.ordered_headers, headers) self.assertEqual(self.ordered_data, data) def setUp(self): super(TestVPNService, self).setUp() def _mock_vpnservice(*args, **kwargs): self.neutronclient.find_resource.assert_called_once_with( self.res, self.resource['id'], cmd_resource='vpnservice') return {'id': args[1]} self.app.client_manager.network = mock.Mock() self.app.client_manager.network.find_router = mock.Mock() self.app.client_manager.network.find_subnet = mock.Mock() self.fake_router = mock.Mock() self.fake_subnet = mock.Mock() self.app.client_manager.network.find_router.return_value = \ self.fake_router self.app.client_manager.network.find_subnet.return_value = \ self.fake_subnet self.args = { 'name': 'my-name', 'description': 'my-desc', 'tenant_id': 'tenant-id-' + uuid.uuid4().hex, 'router_id': 'router-id-' + uuid.uuid4().hex, 'subnet_id': 'subnet-id-' + uuid.uuid4().hex, } self.fake_subnet.id = self.args['subnet_id'] self.fake_router.id = self.args['router_id'] self.neutronclient.find_resource.side_effect = mock.Mock( side_effect=_mock_vpnservice) osc_utils.find_project = mock.Mock() osc_utils.find_project.id = _vpnservice['tenant_id'] self.res = 'vpnservice' self.res_plural = 'vpnservices' self.resource = _vpnservice self.headers = ( 'ID', 'Name', 'Router', 'Subnet', 'Flavor', 'State', 'Status', 'Description', 'Project', ) self.data = _generate_data() self.ordered_headers = ( 'Description', 'Flavor', 'ID', 'Name', 'Project', 'Router', 'State', 'Status', 'Subnet', ) self.ordered_data = ( _vpnservice['description'], _vpnservice['flavor_id'], _vpnservice['id'], _vpnservice['name'], _vpnservice['tenant_id'], _vpnservice['router_id'], _vpnservice['admin_state_up'], _vpnservice['status'], _vpnservice['subnet_id'], ) self.ordered_columns = ( 'description', 'flavor_id', 'id', 'name', 'tenant_id', 'router_id', 'admin_state_up', 'status', 'subnet_id', ) class TestCreateVPNService(TestVPNService, common.TestCreateVPNaaS): def setUp(self): super(TestCreateVPNService, self).setUp() self.neutronclient.create_vpnservice = mock.Mock( return_value={self.res: _vpnservice}) self.mocked = self.neutronclient.create_vpnservice self.cmd = vpnservice.CreateVPNService(self.app, self.namespace) def _update_expect_response(self, request, response): """Set expected request and response :param request A dictionary of request body(dict of verifylist) :param response A OrderedDict of request body """ # Update response body self.neutronclient.create_vpnservice.return_value = \ {self.res: dict(response)} osc_utils.find_project.return_value.id = response['tenant_id'] # Update response(finally returns 'data') self.data = _generate_data(ordered_dict=response) self.ordered_data = tuple( response[column] for column in self.ordered_columns ) def _set_all_params(self): name = self.args.get('name') description = self.args.get('description') router_id = self.args.get('router_id') subnet_id = self.args.get('subnet_id') tenant_id = self.args.get('tenant_id') arglist = [ '--description', description, '--project', tenant_id, '--subnet', subnet_id, '--router', router_id, name, ] verifylist = [ ('description', description), ('project', tenant_id), ('subnet', subnet_id), ('router', router_id), ('name', name), ] return arglist, verifylist def _test_create_with_all_params(self): arglist, verifylist = self._set_all_params() request, response = _generate_req_and_res(verifylist) self._update_expect_response(request, response) parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self._check_results(headers, data, request) def test_create_with_all_params(self): self._test_create_with_all_params() class TestDeleteVPNService(TestVPNService, common.TestDeleteVPNaaS): def setUp(self): super(TestDeleteVPNService, self).setUp() self.neutronclient.delete_vpnservice = mock.Mock( return_value={self.res: _vpnservice}) self.mocked = self.neutronclient.delete_vpnservice self.cmd = vpnservice.DeleteVPNService(self.app, self.namespace) class TestListVPNService(TestVPNService): def setUp(self): super(TestListVPNService, self).setUp() self.cmd = vpnservice.ListVPNService(self.app, self.namespace) self.short_header = ( 'ID', 'Name', 'Router', 'Subnet', 'Flavor', 'State', 'Status', ) self.short_data = ( _vpnservice['id'], _vpnservice['name'], _vpnservice['router_id'], _vpnservice['subnet_id'], _vpnservice['flavor_id'], _vpnservice['admin_state_up'], _vpnservice['status'], ) self.neutronclient.list_vpnservices = mock.Mock( return_value={self.res_plural: [_vpnservice]}) self.mocked = self.neutronclient.list_vpnservices def test_list_with_long_option(self): arglist = ['--long'] verifylist = [('long', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.headers), headers) self.assertEqual([self.data], list(data)) def test_list_with_no_option(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) headers, data = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with() self.assertEqual(list(self.short_header), headers) self.assertEqual([self.short_data], list(data)) class TestSetVPNService(TestVPNService, common.TestSetVPNaaS): def setUp(self): super(TestSetVPNService, self).setUp() self.neutronclient.update_vpnservice = mock.Mock( return_value={self.res: _vpnservice}) self.mocked = self.neutronclient.update_vpnservice self.cmd = vpnservice.SetVPNSercice(self.app, self.namespace) def test_set_name(self): target = self.resource['id'] update = 'change' arglist = [target, '--name', update] verifylist = [ (self.res, target), ('name', update), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.mocked.assert_called_once_with( target, {self.res: {'name': update}}) self.assertIsNone(result) class TestShowVPNService(TestVPNService, common.TestShowVPNaaS): def setUp(self): super(TestShowVPNService, self).setUp() self.neutronclient.show_vpnservice = mock.Mock( return_value={self.res: _vpnservice}) self.mocked = self.neutronclient.show_vpnservice self.cmd = vpnservice.ShowVPNService(self.app, self.namespace) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/vpnaas/__init__.py0000666000175100017510000000000013232473350027500 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/__init__.py0000666000175100017510000000000013232473350026210 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/lbaas/0000775000175100017510000000000013232473710025171 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/v2/lbaas/__init__.py0000666000175100017510000000000013232473350027272 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/osc/test_utils.py0000666000175100017510000000455113232473350026340 0ustar zuulzuul00000000000000# Copyright 2016 NEC Corporation # # 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 testtools from neutronclient.osc import utils class TestUtils(testtools.TestCase): def test_get_column_definitions(self): attr_map = ( ('id', 'ID', utils.LIST_BOTH), ('tenant_id', 'Project', utils.LIST_LONG_ONLY), ('name', 'Name', utils.LIST_BOTH), ('summary', 'Summary', utils.LIST_SHORT_ONLY), ) headers, columns = utils.get_column_definitions(attr_map, long_listing=False) self.assertEqual(['id', 'name', 'summary'], columns) self.assertEqual(['ID', 'Name', 'Summary'], headers) def test_get_column_definitions_long(self): attr_map = ( ('id', 'ID', utils.LIST_BOTH), ('tenant_id', 'Project', utils.LIST_LONG_ONLY), ('name', 'Name', utils.LIST_BOTH), ('summary', 'Summary', utils.LIST_SHORT_ONLY), ) headers, columns = utils.get_column_definitions(attr_map, long_listing=True) self.assertEqual(['id', 'tenant_id', 'name'], columns) self.assertEqual(['ID', 'Project', 'Name'], headers) def test_get_columns(self): item = { 'id': 'test-id', 'tenant_id': 'test-tenant_id', # 'name' is not included 'foo': 'bar', # unknown attribute } attr_map = ( ('id', 'ID', utils.LIST_BOTH), ('tenant_id', 'Project', utils.LIST_LONG_ONLY), ('name', 'Name', utils.LIST_BOTH), ) columns, display_names = utils.get_columns(item, attr_map) self.assertEqual(tuple(['id', 'tenant_id', 'foo']), columns) self.assertEqual(tuple(['ID', 'Project', 'foo']), display_names) python-neutronclient-6.7.0/neutronclient/tests/unit/osc/__init__.py0000666000175100017510000000000013232473350025661 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/test_http.py0000666000175100017510000001300513232473350025365 0ustar zuulzuul00000000000000# Copyright (C) 2013 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 # # 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 abc from oslo_utils import uuidutils import osprofiler.profiler import osprofiler.web from requests_mock.contrib import fixture as mock_fixture import six import testtools from neutronclient import client from neutronclient.common import exceptions AUTH_TOKEN = 'test_token' END_URL = 'test_url' METHOD = 'GET' URL = 'http://test.test:1234/v2.0/test' BODY = 'IAMFAKE' @six.add_metaclass(abc.ABCMeta) class TestHTTPClientMixin(object): def setUp(self): super(TestHTTPClientMixin, self).setUp() self.requests = self.useFixture(mock_fixture.Fixture()) self.http = self.initialize() @abc.abstractmethod def initialize(self): """Return client class, instance.""" def _test_headers(self, expected_headers, **kwargs): # Test headers. self.requests.register_uri(METHOD, URL, request_headers=expected_headers) self.http.request(URL, METHOD, **kwargs) self.assertEqual(kwargs.get('body'), self.requests.last_request.body) def test_headers_without_body(self): self._test_headers({'Accept': 'application/json'}) def test_headers_with_body(self): headers = {'Accept': 'application/json', 'Content-Type': 'application/json'} self._test_headers(headers, body=BODY) def test_headers_without_body_with_content_type(self): headers = {'Accept': 'application/json'} self._test_headers(headers, content_type='application/json') def test_headers_with_body_with_content_type(self): headers = {'Accept': 'application/json', 'Content-Type': 'application/json'} self._test_headers(headers, body=BODY, content_type='application/json') def test_headers_defined_in_headers(self): headers = {'Accept': 'application/json', 'Content-Type': 'application/json'} self._test_headers(headers, body=BODY, headers=headers) def test_osprofiler_headers_are_injected(self): osprofiler.profiler.init('SWORDFISH') self.addCleanup(osprofiler.profiler._clean) headers = {'Accept': 'application/json'} headers.update(osprofiler.web.get_trace_id_headers()) self._test_headers(headers) class TestHTTPClient(TestHTTPClientMixin, testtools.TestCase): def initialize(self): return client.HTTPClient(token=AUTH_TOKEN, endpoint_url=END_URL) def test_request_error(self): def cb(*args, **kwargs): raise Exception('error msg') self.requests.get(URL, body=cb) self.assertRaises( exceptions.ConnectionFailed, self.http._cs_request, URL, METHOD ) def test_request_success(self): text = 'test content' self.requests.register_uri(METHOD, URL, text=text) resp, resp_text = self.http._cs_request(URL, METHOD) self.assertEqual(200, resp.status_code) self.assertEqual(text, resp_text) def test_request_unauthorized(self): text = 'unauthorized message' self.requests.register_uri(METHOD, URL, status_code=401, text=text) e = self.assertRaises(exceptions.Unauthorized, self.http._cs_request, URL, METHOD) self.assertEqual(text, e.message) def test_request_forbidden_is_returned_to_caller(self): text = 'forbidden message' self.requests.register_uri(METHOD, URL, status_code=403, text=text) resp, resp_text = self.http._cs_request(URL, METHOD) self.assertEqual(403, resp.status_code) self.assertEqual(text, resp_text) def test_do_request_success(self): text = 'test content' self.requests.register_uri(METHOD, END_URL + URL, text=text) resp, resp_text = self.http.do_request(URL, METHOD) self.assertEqual(200, resp.status_code) self.assertEqual(text, resp_text) def test_do_request_with_headers_success(self): text = 'test content' self.requests.register_uri(METHOD, END_URL + URL, text=text, request_headers={'key': 'value'}) resp, resp_text = self.http.do_request(URL, METHOD, headers={'key': 'value'}) self.assertEqual(200, resp.status_code) self.assertEqual(text, resp_text) class TestHTTPClientWithReqId(TestHTTPClientMixin, testtools.TestCase): """Tests for when global_request_id is set.""" def initialize(self): self.req_id = "req-%s" % uuidutils.generate_uuid() return client.HTTPClient(token=AUTH_TOKEN, endpoint_url=END_URL, global_request_id=self.req_id) def test_request_success(self): headers = { 'Accept': 'application/json', 'X-OpenStack-Request-ID': self.req_id } self.requests.register_uri(METHOD, URL, request_headers=headers) self.http.request(URL, METHOD) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_tag.py0000666000175100017510000001352413232473350026160 0ustar zuulzuul00000000000000# 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 mox3 import mox from neutronclient.common import exceptions from neutronclient.neutron.v2_0 import network from neutronclient.neutron.v2_0 import tag from neutronclient import shell from neutronclient.tests.unit import test_cli20 class CLITestV20Tag(test_cli20.CLITestV20Base): def _test_tag_operation(self, cmd, path, method, args, prog_name, body=None): self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) if body: body = test_cli20.MyComparator(body, self.client) self.client.httpclient.request( test_cli20.MyUrlComparator(test_cli20.end_url(path), self.client), method, body=body, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn( (test_cli20.MyResp(204), None)) self.mox.ReplayAll() cmd_parser = cmd.get_parser(prog_name) shell.run_command(cmd, cmd_parser, args) self.mox.VerifyAll() self.mox.UnsetStubs() def _test_tags_query(self, cmd, resources, args, query): self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) path = getattr(self.client, resources + "_path") res = {resources: [{'id': 'myid'}]} resstr = self.client.serialize(res) self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, query), self.client), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn( (test_cli20.MyResp(200), resstr)) self.mox.ReplayAll() cmd_parser = cmd.get_parser("list_networks") shell.run_command(cmd, cmd_parser, args) self.mox.VerifyAll() self.mox.UnsetStubs() _str = self.fake_stdout.make_string() self.assertIn('myid', _str) def _make_tag_path(self, resource, resource_id, tag): path = getattr(self.client, "tag_path") resource_plural = self.client.get_resource_plural(resource) return path % (resource_plural, resource_id, tag) def _make_tags_path(self, resource, resource_id): path = getattr(self.client, "tags_path") resource_plural = self.client.get_resource_plural(resource) return path % (resource_plural, resource_id) def test_add_tag(self): cmd = tag.AddTag(test_cli20.MyApp(sys.stdout), None) path = self._make_tag_path('network', 'myid', 'red') args = ['--resource-type', 'network', '--resource', 'myid', '--tag', 'red'] self._test_tag_operation(cmd, path, 'PUT', args, "tag-add") def test_add_tag_empty_tag(self): cmd = tag.AddTag(test_cli20.MyApp(sys.stdout), None) path = self._make_tag_path('network', 'myid', '') args = ['--resource-type', 'network', '--resource', 'myid', '--tag', ''] self.assertRaises(exceptions.CommandError, self._test_tag_operation, cmd, path, 'PUT', args, "tag-add") def test_replace_tag(self): cmd = tag.ReplaceTag(test_cli20.MyApp(sys.stdout), None) path = self._make_tags_path('network', 'myid') args = ['--resource-type', 'network', '--resource', 'myid', '--tag', 'red', '--tag', 'blue'] body = {'tags': ['red', 'blue']} self._test_tag_operation(cmd, path, 'PUT', args, "tag-replace", body=body) def test_remove_tag(self): cmd = tag.RemoveTag(test_cli20.MyApp(sys.stdout), None) path = self._make_tag_path('network', 'myid', 'red') args = ['--resource-type', 'network', '--resource', 'myid', '--tag', 'red'] self._test_tag_operation(cmd, path, 'DELETE', args, "tag-remove") def test_remove_tag_all(self): cmd = tag.RemoveTag(test_cli20.MyApp(sys.stdout), None) path = self._make_tags_path('network', 'myid') args = ['--resource-type', 'network', '--resource', 'myid', '--all'] self._test_tag_operation(cmd, path, 'DELETE', args, "tag-remove") def test_no_tag_nor_all(self): cmd = tag.RemoveTag(test_cli20.MyApp(sys.stdout), None) path = self._make_tags_path('network', 'myid') args = ['--resource-type', 'network', '--resource', 'myid'] self.assertRaises(exceptions.CommandError, self._test_tag_operation, cmd, path, 'DELETE', args, "tag-remove") def test_tags_query(self): # This test examines that '-' in the tag related filters # is not converted to '_'. resources = 'networks' cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(network.ListNetwork, "extend_list") network.ListNetwork.extend_list(mox.IsA(list), mox.IgnoreArg()) args = ['--not-tags', 'red,blue', '--tags-any', 'green', '--not-tags-any', 'black'] query = "not-tags=red,blue&tags-any=green¬-tags-any=black" self._test_tags_query(cmd, resources, args, query) python-neutronclient-6.7.0/neutronclient/tests/unit/lb/0000775000175100017510000000000013232473710023371 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/lb/test_cli20_member.py0000666000175100017510000001132013232473350027241 0ustar zuulzuul00000000000000# Copyright 2013 Mirantis Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.lb import member from neutronclient.tests.unit import test_cli20 class CLITestV20LbMemberJSON(test_cli20.CLITestV20Base): def setUp(self): super(CLITestV20LbMemberJSON, self).setUp(plurals={'tags': 'tag'}) def test_create_member(self): # lb-member-create with mandatory params only. resource = 'member' cmd = member.CreateMember(test_cli20.MyApp(sys.stdout), None) address = '10.0.0.1' port = '8080' tenant_id = 'my-tenant' my_id = 'my-id' pool_id = 'pool-id' args = ['--address', address, '--protocol-port', port, '--tenant-id', tenant_id, pool_id] position_names = ['address', 'protocol_port', 'tenant_id', 'pool_id', 'admin_state_up'] position_values = [address, port, tenant_id, pool_id, True] self._test_create_resource(resource, cmd, None, my_id, args, position_names, position_values, admin_state_up=None) def test_create_member_all_params(self): # lb-member-create with all available params. resource = 'member' cmd = member.CreateMember(test_cli20.MyApp(sys.stdout), None) address = '10.0.0.1' admin_state_up = False port = '8080' weight = '1' tenant_id = 'my-tenant' my_id = 'my-id' pool_id = 'pool-id' args = ['--address', address, '--admin-state-down', '--protocol-port', port, '--weight', weight, '--tenant-id', tenant_id, pool_id] position_names = [ 'address', 'admin_state_up', 'protocol_port', 'weight', 'tenant_id', 'pool_id' ] position_values = [address, admin_state_up, port, weight, tenant_id, pool_id] self._test_create_resource(resource, cmd, None, my_id, args, position_names, position_values, admin_state_up=None) def test_list_members(self): # lb-member-list. resources = "members" cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_members_pagination(self): # lb-member-list. resources = "members" cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_members_sort(self): # lb-member-list --sort-key name --sort-key id --sort-key asc # --sort-key desc resources = "members" cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_members_limit(self): # lb-member-list -P. resources = "members" cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_member_id(self): # lb-member-show test_id. resource = 'member' cmd = member.ShowMember(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_update_member(self): # lb-member-update myid --name myname --tags a b. resource = 'member' cmd = member.UpdateMember(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_delete_member(self): # lb-member-delete my-id. resource = 'member' cmd = member.DeleteMember(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) python-neutronclient-6.7.0/neutronclient/tests/unit/lb/test_cli20_vip.py0000666000175100017510000002000413232473350026567 0ustar zuulzuul00000000000000# Copyright 2013 Mirantis Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.lb import vip from neutronclient.tests.unit import test_cli20 class CLITestV20LbVipJSON(test_cli20.CLITestV20Base): def setUp(self): super(CLITestV20LbVipJSON, self).setUp(plurals={'tags': 'tag'}) def test_create_vip_with_mandatory_params(self): # lb-vip-create with all mandatory params. resource = 'vip' cmd = vip.CreateVip(test_cli20.MyApp(sys.stdout), None) pool_id = 'my-pool-id' name = 'my-name' subnet_id = 'subnet-id' protocol_port = '1000' protocol = 'TCP' tenant_id = 'my-tenant' my_id = 'my-id' args = ['--name', name, '--protocol-port', protocol_port, '--protocol', protocol, '--subnet-id', subnet_id, '--tenant-id', tenant_id, pool_id] position_names = ['pool_id', 'name', 'protocol_port', 'protocol', 'subnet_id', 'tenant_id'] position_values = [pool_id, name, protocol_port, protocol, subnet_id, tenant_id] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, admin_state_up=True) def test_create_vip_with_all_params(self): # lb-vip-create with all params. resource = 'vip' cmd = vip.CreateVip(test_cli20.MyApp(sys.stdout), None) pool_id = 'my-pool-id' name = 'my-name' description = 'my-desc' address = '10.0.0.2' admin_state = False connection_limit = '1000' subnet_id = 'subnet-id' protocol_port = '80' protocol = 'TCP' tenant_id = 'my-tenant' my_id = 'my-id' args = ['--name', name, '--description', description, '--address', address, '--admin-state-down', '--connection-limit', connection_limit, '--protocol-port', protocol_port, '--protocol', protocol, '--subnet-id', subnet_id, '--tenant-id', tenant_id, pool_id] position_names = ['pool_id', 'name', 'description', 'address', 'admin_state_up', 'connection_limit', 'protocol_port', 'protocol', 'subnet_id', 'tenant_id'] position_values = [pool_id, name, description, address, admin_state, connection_limit, protocol_port, protocol, subnet_id, tenant_id] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values) def test_create_vip_with_session_persistence_params(self): # lb-vip-create with mandatory and session-persistence params. resource = 'vip' cmd = vip.CreateVip(test_cli20.MyApp(sys.stdout), None) pool_id = 'my-pool-id' name = 'my-name' subnet_id = 'subnet-id' protocol_port = '1000' protocol = 'TCP' tenant_id = 'my-tenant' my_id = 'my-id' args = ['--name', name, '--protocol-port', protocol_port, '--protocol', protocol, '--subnet-id', subnet_id, '--tenant-id', tenant_id, pool_id, '--session-persistence', 'type=dict', 'type=cookie,cookie_name=pie', '--optional-param', 'any'] position_names = ['pool_id', 'name', 'protocol_port', 'protocol', 'subnet_id', 'tenant_id', 'optional_param'] position_values = [pool_id, name, protocol_port, protocol, subnet_id, tenant_id, 'any'] extra_body = { 'session_persistence': { 'type': 'cookie', 'cookie_name': 'pie', }, } self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, admin_state_up=True, extra_body=extra_body) def test_list_vips(self): # lb-vip-list. resources = "vips" cmd = vip.ListVip(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_vips_pagination(self): # lb-vip-list. resources = "vips" cmd = vip.ListVip(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_vips_sort(self): # lb-vip-list --sort-key name --sort-key id --sort-key asc # --sort-key desc resources = "vips" cmd = vip.ListVip(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_vips_limit(self): # lb-vip-list -P. resources = "vips" cmd = vip.ListVip(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_vip_id(self): # lb-vip-show test_id. resource = 'vip' cmd = vip.ShowVip(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_vip_id_name(self): # lb-vip-show. resource = 'vip' cmd = vip.ShowVip(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_vip(self): # lb-vip-update myid --name myname --tags a b. resource = 'vip' cmd = vip.UpdateVip(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_vip_with_session_persistence(self): resource = 'vip' cmd = vip.UpdateVip(test_cli20.MyApp(sys.stdout), None) body = { 'session_persistence': { 'type': 'source', }, } args = ['myid', '--session-persistence', 'type=dict', 'type=source'] self._test_update_resource(resource, cmd, 'myid', args, body) def test_update_vip_with_session_persistence_and_name(self): resource = 'vip' cmd = vip.UpdateVip(test_cli20.MyApp(sys.stdout), None) body = { 'name': 'newname', 'session_persistence': { 'type': 'cookie', 'cookie_name': 'pie', }, } args = ['myid', '--name', 'newname', '--session-persistence', 'type=dict', 'type=cookie,cookie_name=pie'] self._test_update_resource(resource, cmd, 'myid', args, body) def test_delete_vip(self): # lb-vip-delete my-id. resource = 'vip' cmd = vip.DeleteVip(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) python-neutronclient-6.7.0/neutronclient/tests/unit/lb/test_cli20_healthmonitor.py0000666000175100017510000002042513232473350030655 0ustar zuulzuul00000000000000# Copyright 2013 Mirantis Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from mox3 import mox from neutronclient.neutron.v2_0.lb import healthmonitor from neutronclient.tests.unit import test_cli20 class CLITestV20LbHealthmonitorJSON(test_cli20.CLITestV20Base): def test_create_healthmonitor_with_mandatory_params(self): # lb-healthmonitor-create with mandatory params only. resource = 'health_monitor' cmd = healthmonitor.CreateHealthMonitor(test_cli20.MyApp(sys.stdout), None) admin_state_up = False delay = '60' max_retries = '2' timeout = '10' type = 'TCP' tenant_id = 'my-tenant' my_id = 'my-id' args = ['--admin-state-down', '--delay', delay, '--max-retries', max_retries, '--timeout', timeout, '--type', type, '--tenant-id', tenant_id] position_names = ['admin_state_up', 'delay', 'max_retries', 'timeout', 'type', 'tenant_id'] position_values = [admin_state_up, delay, max_retries, timeout, type, tenant_id] self._test_create_resource(resource, cmd, '', my_id, args, position_names, position_values) def test_create_healthmonitor_with_all_params(self): # lb-healthmonitor-create with all params set. resource = 'health_monitor' cmd = healthmonitor.CreateHealthMonitor(test_cli20.MyApp(sys.stdout), None) admin_state_up = False delay = '60' expected_codes = '200-202,204' http_method = 'HEAD' max_retries = '2' timeout = '10' type = 'TCP' tenant_id = 'my-tenant' url_path = '/health' my_id = 'my-id' args = ['--admin-state-down', '--delay', delay, '--expected-codes', expected_codes, '--http-method', http_method, '--max-retries', max_retries, '--timeout', timeout, '--type', type, '--tenant-id', tenant_id, '--url-path', url_path] position_names = ['admin_state_up', 'delay', 'expected_codes', 'http_method', 'max_retries', 'timeout', 'type', 'tenant_id', 'url_path'] position_values = [admin_state_up, delay, expected_codes, http_method, max_retries, timeout, type, tenant_id, url_path] self._test_create_resource(resource, cmd, '', my_id, args, position_names, position_values) def test_list_healthmonitors(self): # lb-healthmonitor-list. resources = "health_monitors" cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_healthmonitors_pagination(self): # lb-healthmonitor-list. resources = "health_monitors" cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_healthmonitors_sort(self): # lb-healthmonitor-list --sort-key name --sort-key id --sort-key asc # --sort-key desc resources = "health_monitors" cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_healthmonitors_limit(self): # lb-healthmonitor-list -P. resources = "health_monitors" cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_healthmonitor_id(self): # lb-healthmonitor-show test_id. resource = 'health_monitor' cmd = healthmonitor.ShowHealthMonitor(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_update_health_monitor(self): # lb-healthmonitor-update myid --name myname --tags a b. resource = 'health_monitor' cmd = healthmonitor.UpdateHealthMonitor(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--timeout', '5'], {'timeout': '5', }) def test_delete_healthmonitor(self): # lb-healthmonitor-delete my-id.""" resource = 'health_monitor' cmd = healthmonitor.DeleteHealthMonitor(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) def test_associate_healthmonitor(self): cmd = healthmonitor.AssociateHealthMonitor( test_cli20.MyApp(sys.stdout), None) resource = 'health_monitor' health_monitor_id = 'hm-id' pool_id = 'p_id' args = [health_monitor_id, pool_id] self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) body = {resource: {'id': health_monitor_id}} result = {resource: {'id': health_monitor_id}, } result_str = self.client.serialize(result) path = getattr(self.client, "associate_pool_health_monitors_path") % pool_id return_tup = (test_cli20.MyResp(200), result_str) self.client.httpclient.request( test_cli20.end_url(path), 'POST', body=test_cli20.MyComparator(body, self.client), headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(return_tup) self.mox.ReplayAll() cmd_parser = cmd.get_parser('test_' + resource) parsed_args = cmd_parser.parse_args(args) cmd.run(parsed_args) self.mox.VerifyAll() self.mox.UnsetStubs() def test_disassociate_healthmonitor(self): cmd = healthmonitor.DisassociateHealthMonitor( test_cli20.MyApp(sys.stdout), None) resource = 'health_monitor' health_monitor_id = 'hm-id' pool_id = 'p_id' args = [health_monitor_id, pool_id] self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) path = (getattr(self.client, "disassociate_pool_health_monitors_path") % {'pool': pool_id, 'health_monitor': health_monitor_id}) return_tup = (test_cli20.MyResp(204), None) self.client.httpclient.request( test_cli20.end_url(path), 'DELETE', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(return_tup) self.mox.ReplayAll() cmd_parser = cmd.get_parser('test_' + resource) parsed_args = cmd_parser.parse_args(args) cmd.run(parsed_args) self.mox.VerifyAll() self.mox.UnsetStubs() python-neutronclient-6.7.0/neutronclient/tests/unit/lb/v2/0000775000175100017510000000000013232473710023720 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/lb/v2/test_cli20_member.py0000666000175100017510000001704513232473350027602 0ustar zuulzuul00000000000000# Copyright 2014 Blue Box Group, Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.lb.v2 import member from neutronclient.tests.unit import test_cli20 class CLITestV20LbMemberJSON(test_cli20.CLITestV20Base): def test_create_member_with_mandatory_params(self): # lbaas-member-create with mandatory params only. resource = 'member' cmd_resource = 'lbaas_member' cmd = member.CreateMember(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' address = '10.1.1.1' protocol_port = '80' pool_id = 'pool-id' subnet_id = 'subnet-id' args = ['--address', address, '--protocol-port', protocol_port, '--subnet', subnet_id, pool_id] position_names = ['admin_state_up', 'address', 'protocol_port', 'subnet_id'] position_values = [True, address, protocol_port, subnet_id] self._test_create_resource(resource, cmd, '', my_id, args, position_names, position_values, cmd_resource=cmd_resource, parent_id=pool_id) def test_create_member_with_all_params(self): # lbaas-member-create with all params set. resource = 'member' cmd_resource = 'lbaas_member' cmd = member.CreateMember(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' address = '10.1.1.1' protocol_port = '80' pool_id = 'pool-id' subnet_id = 'subnet-id' weight = '100' name = 'member1' args = ['--address', address, '--protocol-port', protocol_port, '--subnet', subnet_id, pool_id, '--weight', weight, '--admin-state-down', '--name', name] position_names = ['admin_state_up', 'address', 'protocol_port', 'subnet_id', 'weight', 'name'] position_values = [False, address, protocol_port, subnet_id, weight, name] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, cmd_resource=cmd_resource, parent_id=pool_id) def test_list_members(self): # lbaas-member-list. resources = 'members' cmd_resources = 'lbaas_members' pool_id = 'pool-id' cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True, base_args=[pool_id], cmd_resources=cmd_resources, parent_id=pool_id, query="pool_id=%s" % pool_id) def test_list_members_pagination(self): # lbaas-member-list with pagination. resources = 'members' cmd_resources = 'lbaas_members' pool_id = 'pool-id' cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd, base_args=[pool_id], cmd_resources=cmd_resources, parent_id=pool_id, query="pool_id=%s" % pool_id) def test_list_members_sort(self): # lbaas-member-list --sort-key id --sort-key asc. resources = 'members' cmd_resources = 'lbaas_members' pool_id = 'pool-id' cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True, base_args=[pool_id], cmd_resources=cmd_resources, parent_id=pool_id, query="pool_id=%s" % pool_id) def test_list_members_limit(self): # lbaas-member-list -P. resources = 'members' cmd_resources = 'lbaas_members' pool_id = 'pool-id' cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000, base_args=[pool_id], cmd_resources=cmd_resources, parent_id=pool_id, query="pool_id=%s" % pool_id) def test_show_member_id(self): # lbaas-member-show test_id. resource = 'member' cmd_resource = 'lbaas_member' pool_id = 'pool-id' cmd = member.ShowMember(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', self.test_id, pool_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id'], cmd_resource=cmd_resource, parent_id=pool_id) def test_show_member_id_name(self): # lbaas-member-show. resource = 'member' cmd_resource = 'lbaas_member' pool_id = 'pool-id' cmd = member.ShowMember(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', '--fields', 'name', self.test_id, pool_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id', 'name'], cmd_resource=cmd_resource, parent_id=pool_id) def test_update_member(self): # lbaas-member-update myid --name newname. resource = 'member' cmd_resource = 'lbaas_member' my_id = 'my-id' pool_id = 'pool-id' args = [my_id, pool_id, '--name', 'newname'] cmd = member.UpdateMember(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, my_id, args, {'name': 'newname', }, cmd_resource=cmd_resource, parent_id=pool_id) # lbaas-member-update myid --weight 100. args = [my_id, pool_id, '--weight', '100'] self._test_update_resource(resource, cmd, my_id, args, {'weight': '100', }, cmd_resource=cmd_resource, parent_id=pool_id) # lbaas-member-update myid --admin-state-up False args = [my_id, pool_id, '--admin-state-up', 'False'] self._test_update_resource(resource, cmd, my_id, args, {'admin_state_up': 'False', }, cmd_resource=cmd_resource, parent_id=pool_id) def test_delete_member(self): # lbaas-member-delete my-id. resource = 'member' cmd_resource = 'lbaas_member' cmd = member.DeleteMember(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' pool_id = 'pool-id' args = [my_id, pool_id] self._test_delete_resource(resource, cmd, my_id, args, cmd_resource=cmd_resource, parent_id=pool_id) python-neutronclient-6.7.0/neutronclient/tests/unit/lb/v2/test_cli20_healthmonitor.py0000666000175100017510000002007613232473350031206 0ustar zuulzuul00000000000000# Copyright 2014 Blue Box Group, Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.lb.v2 import healthmonitor from neutronclient.tests.unit import test_cli20 class CLITestV20LbHealthMonitorJSON(test_cli20.CLITestV20Base): def test_create_healthmonitor_with_mandatory_params(self): # lbaas-healthmonitor-create with mandatory params only. resource = 'healthmonitor' cmd_resource = 'lbaas_healthmonitor' cmd = healthmonitor.CreateHealthMonitor(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' type = 'PING' max_retries = '3' delay = '10' timeout = '60' pool = 'pool1' args = ['--type', type, '--max-retries', max_retries, '--delay', delay, '--timeout', timeout, '--pool', pool] position_names = ['type', 'max_retries', 'delay', 'timeout', 'pool_id'] position_values = [type, max_retries, delay, timeout, pool] self._test_create_resource(resource, cmd, '', my_id, args, position_names, position_values, cmd_resource=cmd_resource) def test_create_healthmonitor_with_all_params(self): # lbaas-healthmonitor-create with all params set. resource = 'healthmonitor' cmd_resource = 'lbaas_healthmonitor' cmd = healthmonitor.CreateHealthMonitor(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' type = 'PING' max_retries = '3' delay = '10' timeout = '60' http_method = 'GET' expected_codes = '201' url_path = '/somepath' pool = 'pool1' name = 'healthmonitor1' args = ['--admin-state-down', '--http-method', http_method, '--expected-codes', expected_codes, '--url-path', url_path, '--type', type, '--max-retries', max_retries, '--delay', delay, '--timeout', timeout, '--pool', pool, '--name', name] position_names = ['admin_state_up', 'http_method', 'expected_codes', 'url_path', 'type', 'max_retries', 'delay', 'timeout', 'pool_id', 'name'] position_values = [False, http_method, expected_codes, url_path, type, max_retries, delay, timeout, pool, name] self._test_create_resource(resource, cmd, '', my_id, args, position_names, position_values, cmd_resource=cmd_resource) def test_list_healthmonitors(self): # lbaas-healthmonitor-list. resources = 'healthmonitors' cmd_resources = 'lbaas_healthmonitors' cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True, cmd_resources=cmd_resources) def test_list_healthmonitors_pagination(self): # lbaas-healthmonitor-list with pagination. resources = 'healthmonitors' cmd_resources = 'lbaas_healthmonitors' cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd, cmd_resources=cmd_resources) def test_list_healthmonitors_sort(self): # lbaas-healthmonitor-list --sort-key id --sort-key asc. resources = 'healthmonitors' cmd_resources = 'lbaas_healthmonitors' cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True, cmd_resources=cmd_resources) def test_list_healthmonitors_limit(self): # lbaas-healthmonitor-list -P. resources = 'healthmonitors' cmd_resources = 'lbaas_healthmonitors' cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000, cmd_resources=cmd_resources) def test_show_healthmonitor_id(self): # lbaas-healthmonitor-show test_id. resource = 'healthmonitor' cmd_resource = 'lbaas_healthmonitor' cmd = healthmonitor.ShowHealthMonitor(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id'], cmd_resource=cmd_resource) def test_show_healthmonitor_id_name(self): # lbaas-healthmonitor-show. resource = 'healthmonitor' cmd_resource = 'lbaas_healthmonitor' cmd = healthmonitor.ShowHealthMonitor(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'], cmd_resource=cmd_resource) def _test_update_hm(self, args, expected_values): resource = 'healthmonitor' cmd_resource = 'lbaas_healthmonitor' my_id = 'myid' cmd = healthmonitor.UpdateHealthMonitor(test_cli20.MyApp(sys.stdout), None) args.insert(0, my_id) self._test_update_resource(resource, cmd, my_id, args, expected_values, cmd_resource=cmd_resource) def test_update_healthmonitor(self): # lbaas-healthmonitor-update myid --name newname. self._test_update_hm(['--name', 'newname'], {'name': 'newname', }) # lbaas-healthmonitor-update myid --delay 10. self._test_update_hm(['--delay', '10'], {'delay': '10'}) # lbaas-healthmonitor-update myid --timeout 5. self._test_update_hm(['--timeout', '5'], {'timeout': '5', }) # lbaas-healthmonitor-update myid --delay 10. self._test_update_hm(['--http-method', 'OPTIONS'], {'http_method': 'OPTIONS'}) # lbaas-healthmonitor-update myid --url-path /test/string . self._test_update_hm(['--url-path', '/test/string'], {'url_path': '/test/string', }) # lbaas-healthmonitor-update myid --max-retries 5 self._test_update_hm(['--max-retries', '5'], {'max_retries': '5'}) # lbaas-healthmonitor-update myid --expected-codes 201 self._test_update_hm(['--expected-codes', '201'], {'expected_codes': '201'}) # lbaas-healthmonitor-update myid --admin-state-up False self._test_update_hm(['--admin-state-up', 'False'], {'admin_state_up': 'False'}) def test_delete_healthmonitor(self): # lbaas-healthmonitor-delete my-id. resource = 'healthmonitor' cmd_resource = 'lbaas_healthmonitor' cmd = healthmonitor.DeleteHealthMonitor(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args, cmd_resource=cmd_resource) python-neutronclient-6.7.0/neutronclient/tests/unit/lb/v2/test_cli20_listener.py0000666000175100017510000002141013232473350030147 0ustar zuulzuul00000000000000# Copyright 2014 Blue Box Group, Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.common import exceptions from neutronclient.neutron.v2_0.lb.v2 import listener from neutronclient.tests.unit import test_cli20 class CLITestV20LbListenerJSON(test_cli20.CLITestV20Base): def test_create_listener_with_loadbalancer(self): # lbaas-listener-create with --loadbalancer resource = 'listener' cmd_resource = 'lbaas_listener' cmd = listener.CreateListener(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' loadbalancer_id = 'loadbalancer' protocol = 'TCP' protocol_port = '80' args = ['--protocol', protocol, '--protocol-port', protocol_port, '--loadbalancer', loadbalancer_id] position_names = ['protocol', 'protocol_port', 'loadbalancer_id'] position_values = [protocol, protocol_port, loadbalancer_id, True] self._test_create_resource(resource, cmd, '', my_id, args, position_names, position_values, cmd_resource=cmd_resource) def test_create_listener_with_default_pool(self): # lbaas-listener-create with --default-pool and no --loadbalancer. resource = 'listener' cmd_resource = 'lbaas_listener' cmd = listener.CreateListener(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' default_pool_id = 'default-pool' protocol = 'TCP' protocol_port = '80' args = ['--protocol', protocol, '--protocol-port', protocol_port, '--default-pool', default_pool_id] position_names = ['protocol', 'protocol_port', 'default_pool_id'] position_values = [protocol, protocol_port, default_pool_id, True] self._test_create_resource(resource, cmd, '', my_id, args, position_names, position_values, cmd_resource=cmd_resource) def test_create_listener_with_no_loadbalancer_or_default_pool(self): # lbaas-listener-create without --default-pool or --loadbalancer. resource = 'listener' cmd_resource = 'lbaas_listener' cmd = listener.CreateListener(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' protocol = 'TCP' protocol_port = '80' args = ['--protocol', protocol, '--protocol-port', protocol_port] position_names = ['protocol', 'protocol_port'] position_values = [protocol, protocol_port, True] self._test_create_resource(resource, cmd, '', my_id, args, position_names, position_values, cmd_resource=cmd_resource, no_api_call=True, expected_exception=exceptions.CommandError) def test_create_listener_with_all_params(self): # lbaas-listener-create with all params set. resource = 'listener' cmd_resource = 'lbaas_listener' cmd = listener.CreateListener(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' loadbalancer = 'loadbalancer' default_pool_id = 'default-pool' protocol = 'TCP' protocol_port = '80' connection_limit = 10 def_tls_cont_ref = '11111' args = ['--admin-state-down', '--protocol', protocol, '--protocol-port', protocol_port, '--loadbalancer', loadbalancer, '--default-pool', default_pool_id, '--default-tls-container-ref', def_tls_cont_ref, '--sni-container-refs', '1111', '2222', '3333', '--connection-limit', '10'] position_names = ['admin_state_up', 'protocol', 'protocol_port', 'loadbalancer_id', 'default_pool_id', 'default_tls_container_ref', 'sni_container_refs', 'connection_limit'] position_values = [False, protocol, protocol_port, loadbalancer, default_pool_id, def_tls_cont_ref, ['1111', '2222', '3333'], connection_limit] self._test_create_resource(resource, cmd, '', my_id, args, position_names, position_values, cmd_resource=cmd_resource) def test_list_listeners(self): # lbaas-listener-list. resources = 'listeners' cmd_resources = 'lbaas_listeners' cmd = listener.ListListener(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True, cmd_resources=cmd_resources) def test_list_listeners_pagination(self): # lbaas-listener-list with pagination. resources = 'listeners' cmd_resources = 'lbaas_listeners' cmd = listener.ListListener(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd, cmd_resources=cmd_resources) def test_list_listeners_sort(self): # lbaas-listener-list --sort-key id --sort-key asc. resources = 'listeners' cmd_resources = 'lbaas_listeners' cmd = listener.ListListener(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True, cmd_resources=cmd_resources) def test_list_listeners_limit(self): # lbaas-listener-list -P. resources = 'listeners' cmd_resources = 'lbaas_listeners' cmd = listener.ListListener(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000, cmd_resources=cmd_resources) def test_show_listener_id(self): # lbaas-listener-show test_id. resource = 'listener' cmd_resource = 'lbaas_listener' cmd = listener.ShowListener(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id'], cmd_resource=cmd_resource) def test_show_listener_id_name(self): # lbaas-listener-show. resource = 'listener' cmd_resource = 'lbaas_listener' cmd = listener.ShowListener(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'], cmd_resource=cmd_resource) def _test_update_listener(self, args, expected_values): resource = 'listener' cmd_resource = 'lbaas_listener' my_id = 'myid' args.insert(0, my_id) cmd = listener.UpdateListener(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, my_id, args, expected_values, cmd_resource=cmd_resource) def test_update_listener(self): # lbaas-listener-update myid --name newname. self._test_update_listener(['--name', 'newname'], {'name': 'newname', }) # lbaas-listener-update myid --description check. self._test_update_listener(['--description', 'check'], {'description': 'check', }) # lbaas-listener-update myid --connection-limit -1 self._test_update_listener(['--connection-limit', '-1'], {'connection_limit': -1, }) # lbaas-listener-update myid --admin-state-up False. self._test_update_listener(['--admin-state-up', 'False'], {'admin_state_up': 'False', }) def test_delete_listener(self): # lbaas-listener-delete my-id. resource = 'listener' cmd_resource = 'lbaas_listener' cmd = listener.DeleteListener(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args, cmd_resource=cmd_resource) python-neutronclient-6.7.0/neutronclient/tests/unit/lb/v2/test_cli20_l7policy.py0000666000175100017510000002476413232473350030103 0ustar zuulzuul00000000000000# Copyright 2016 Radware LTD. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.common import exceptions from neutronclient.neutron.v2_0.lb.v2 import l7policy from neutronclient.tests.unit import test_cli20 """Structure for mapping cli and api arguments The structure maps cli arguments and a list of its api argument name, default cli value and default api value. It helps to make tests more general for different argument types. """ args_conf = { 'name': ['name', 'test_policy', 'test_policy'], 'description': ['description', 'test policy', 'test policy'], 'listener': ['listener_id', 'test_listener', 'test_listener'], 'admin-state-up': ['admin_state_up', True, True], 'admin-state-down': ['admin_state_up', None, False], 'action': ['action', 'REJECT', 'REJECT'], 'redirect-url': ['redirect_url', 'http://url', 'http://url'], 'redirect-pool': ['redirect_pool_id', 'test_pool', 'test_pool'], 'position': ['position', '1', 1]} class CLITestV20LbL7PolicyJSON(test_cli20.CLITestV20Base): def _get_test_args(self, *args, **kwargs): """Function for generically building testing arguments""" cli_args = [] api_args = {} for arg in args: cli_args.append('--' + arg) if not args_conf[arg][1]: pass elif arg in kwargs: cli_args.append(str(kwargs[arg])) else: cli_args.append(args_conf[arg][1]) if arg in kwargs: api_args[args_conf[arg][0]] = kwargs[arg] else: api_args[args_conf[arg][0]] = args_conf[arg][2] return cli_args, api_args def _test_create_policy(self, *args, **kwargs): resource = 'l7policy' cmd_resource = 'lbaas_l7policy' cmd = l7policy.CreateL7Policy(test_cli20.MyApp(sys.stdout), None) cli_args, api_args = self._get_test_args(*args, **kwargs) position_names = list(api_args.keys()) position_values = list(api_args.values()) self._test_create_resource(resource, cmd, None, 'test_id', cli_args, position_names, position_values, cmd_resource=cmd_resource) def _test_update_policy(self, *args, **kwargs): resource = 'l7policy' cmd_resource = 'lbaas_l7policy' cmd = l7policy.UpdateL7Policy(test_cli20.MyApp(sys.stdout), None) cli_args, api_args = self._get_test_args(*args, **kwargs) cli_args.append('test_id') self._test_update_resource(resource, cmd, 'test_id', cli_args, api_args, cmd_resource=cmd_resource) def test_create_policy_with_mandatory_params(self): # lbaas-l7policy-create with mandatory params only. self._test_create_policy('action', 'listener') def test_create_policy_with_all_params(self): # lbaas-l7policy-create REJECT policy. self._test_create_policy('name', 'description', 'action', 'listener', 'position') def test_create_disabled_policy(self): # lbaas-l7policy-create disabled REJECT policy. self._test_create_policy('action', 'listener', 'admin-state-down') def test_create_url_redirect_policy(self): # lbaas-l7policy-create REDIRECT_TO_URL policy. self._test_create_policy('name', 'description', 'action', 'listener', 'redirect-url', action='REDIRECT_TO_URL') def test_create_url_redirect_policy_no_url(self): # lbaas-l7policy-create REDIRECT_TO_URL policy without url argument. self.assertRaises(exceptions.CommandError, self._test_create_policy, 'name', 'description', 'action', 'listener', action='REDIRECT_TO_URL') def test_create_pool_redirect_policy(self): # lbaas-l7policy-create REDIRECT_TO_POOL policy. self._test_create_policy('name', 'description', 'action', 'listener', 'redirect-pool', action='REDIRECT_TO_POOL') def test_create_pool_redirect_policy_no_pool(self): # lbaas-l7policy-create REDIRECT_TO_POOL policy without pool argument. self.assertRaises(exceptions.CommandError, self._test_create_policy, 'name', 'description', 'action', 'listener', action='REDIRECT_TO_POOL') def test_create_reject_policy_with_url(self): # lbaas-l7policy-create REJECT policy while specifying url argument. self.assertRaises(exceptions.CommandError, self._test_create_policy, 'action', 'listener', 'redirect-url') def test_create_reject_policy_with_pool(self): # lbaas-l7policy-create REJECT policy while specifying pool argument. self.assertRaises(exceptions.CommandError, self._test_create_policy, 'action', 'listener', 'redirect-pool') def test_create_pool_redirect_policy_with_url(self): # lbaas-l7policy-create REDIRECT_TO_POOL policy with url argument. self.assertRaises(exceptions.CommandError, self._test_create_policy, 'action', 'listener', 'redirect-pool', 'redirect-url', action='REDIRECT_TO_POOL') def test_create_url_redirect_policy_with_pool(self): # lbaas-l7policy-create REDIRECT_TO_URL policy with pool argument. self.assertRaises(exceptions.CommandError, self._test_create_policy, 'action', 'listener', 'redirect-pool', 'redirect-url', action='REDIRECT_TO_URL') def test_list_policies(self): # lbaas-l7policy-list. resources = 'l7policies' cmd_resources = 'lbaas_l7policies' cmd = l7policy.ListL7Policy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True, cmd_resources=cmd_resources) def test_list_policies_pagination(self): # lbaas-l7policy-list with pagination. resources = 'l7policies' cmd_resources = 'lbaas_l7policies' cmd = l7policy.ListL7Policy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination( resources, cmd, cmd_resources=cmd_resources) def test_list_policies_sort(self): # lbaas-l7policy-list --sort-key id --sort-key asc. resources = 'l7policies' cmd_resources = 'lbaas_l7policies' cmd = l7policy.ListL7Policy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources( resources, cmd, True, cmd_resources=cmd_resources) def test_list_policies_limit(self): # lbaas-l7policy-list -P. resources = 'l7policies' cmd_resources = 'lbaas_l7policies' cmd = l7policy.ListL7Policy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources( resources, cmd, page_size=1000, cmd_resources=cmd_resources) def test_show_policy_id(self): # lbaas-l7policy-show test_id. resource = 'l7policy' cmd_resource = 'lbaas_l7policy' cmd = l7policy.ShowL7Policy(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'test_id', self.test_id] self._test_show_resource( resource, cmd, self.test_id, args, ['test_id'], cmd_resource=cmd_resource) def test_show_policy_id_name(self): # lbaas-l7policy-show. resource = 'l7policy' cmd_resource = 'lbaas_l7policy' cmd = l7policy.ShowL7Policy(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'test_id', '--fields', 'name', self.test_id] self._test_show_resource( resource, cmd, self.test_id, args, ['test_id', 'name'], cmd_resource=cmd_resource) def test_disable_policy(self): # lbaas-l7policy-update test_id --admin-state-up False. self._test_update_policy('admin-state-up', **{'admin-state-up': 'False'}) def test_update_policy_name_and_description(self): # lbaas-l7policy-update test_id --name other --description other_desc. self._test_update_policy('name', 'description', name='name', description='other desc') def test_update_pool_redirect_policy(self): # lbaas-l7policy-update test_id --action REDIRECT_TO_POOL # --redirect-pool id. self._test_update_policy('action', 'redirect-pool', **{'action': 'REDIRECT_TO_POOL', 'redirect-pool': 'id'}) def test_update_url_redirect_policy(self): # lbaas-l7policy-update test_id --action REDIRECT_TO_URL # --redirect-url http://other_url. self._test_update_policy('action', 'redirect-url', **{'action': 'REDIRECT_TO_URL', 'redirect-url': 'http://other_url'}) def test_update_policy_position(self): # lbaas-l7policy-update test_id --position 2. self._test_update_policy('position', position=2) def test_delete_policy(self): # lbaas-l7policy-delete test_id. resource = 'l7policy' cmd_resource = 'lbaas_l7policy' cmd = l7policy.DeleteL7Policy(test_cli20.MyApp(sys.stdout), None) test_id = 'test_id' args = [test_id] self._test_delete_resource(resource, cmd, test_id, args, cmd_resource=cmd_resource) python-neutronclient-6.7.0/neutronclient/tests/unit/lb/v2/test_cli20_loadbalancer.py0000666000175100017510000002235013232473350030735 0ustar zuulzuul00000000000000# Copyright 2014 Blue Box Group, Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from mox3 import mox from neutronclient.neutron.v2_0.lb.v2 import loadbalancer as lb from neutronclient.tests.unit import test_cli20 class CLITestV20LbLoadBalancerJSON(test_cli20.CLITestV20Base): def test_create_loadbalancer_with_mandatory_params(self): # lbaas-loadbalancer-create with mandatory params only. resource = 'loadbalancer' cmd_resource = 'lbaas_loadbalancer' cmd = lb.CreateLoadBalancer(test_cli20.MyApp(sys.stdout), None) name = 'lbaas-loadbalancer-name' vip_subnet_id = 'vip-subnet' my_id = 'my-id' args = [vip_subnet_id] position_names = ['vip_subnet_id'] position_values = [vip_subnet_id] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, cmd_resource=cmd_resource) def test_create_loadbalancer_with_all_params(self): # lbaas-loadbalancer-create with all params set. resource = 'loadbalancer' cmd_resource = 'lbaas_loadbalancer' cmd = lb.CreateLoadBalancer(test_cli20.MyApp(sys.stdout), None) name = 'lbaas-loadbalancer-name' description = 'lbaas-loadbalancer-desc' flavor_id = 'lbaas-loadbalancer-flavor' vip_subnet_id = 'vip-subnet' my_id = 'my-id' args = ['--admin-state-down', '--description', description, '--name', name, '--flavor', flavor_id, vip_subnet_id] position_names = ['admin_state_up', 'description', 'name', 'flavor_id', 'vip_subnet_id'] position_values = [False, description, name, flavor_id, vip_subnet_id] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, cmd_resource=cmd_resource) def test_list_loadbalancers(self): # lbaas-loadbalancer-list. resources = 'loadbalancers' cmd_resources = 'lbaas_loadbalancers' cmd = lb.ListLoadBalancer(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True, cmd_resources=cmd_resources) def test_list_loadbalancers_pagination(self): # lbaas-loadbalancer-list with pagination. resources = 'loadbalancers' cmd_resources = 'lbaas_loadbalancers' cmd = lb.ListLoadBalancer(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd, cmd_resources=cmd_resources) def test_list_loadbalancers_sort(self): # lbaas-loadbalancer-list --sort-key name --sort-key id --sort-key asc # --sort-key desc resources = 'loadbalancers' cmd_resources = 'lbaas_loadbalancers' cmd = lb.ListLoadBalancer(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"], cmd_resources=cmd_resources) def test_list_loadbalancers_limit(self): # lbaas-loadbalancer-list -P. resources = 'loadbalancers' cmd_resources = 'lbaas_loadbalancers' cmd = lb.ListLoadBalancer(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000, cmd_resources=cmd_resources) def test_show_loadbalancer_id(self): # lbaas-loadbalancer-loadbalancer-show test_id. resource = 'loadbalancer' cmd_resource = 'lbaas_loadbalancer' cmd = lb.ShowLoadBalancer(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id'], cmd_resource=cmd_resource) def test_show_loadbalancer_id_name(self): # lbaas-loadbalancer-loadbalancer-show. resource = 'loadbalancer' cmd_resource = 'lbaas_loadbalancer' cmd = lb.ShowLoadBalancer(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'], cmd_resource=cmd_resource) def _test_update_lb(self, args, expected_values): resource = 'loadbalancer' cmd_resource = 'lbaas_loadbalancer' my_id = 'myid' args.insert(0, my_id) cmd = lb.UpdateLoadBalancer(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, my_id, args, expected_values, cmd_resource=cmd_resource) def test_update_loadbalancer(self): # lbaas-loadbalancer-update myid --name newname. self._test_update_lb(['--name', 'newname'], {'name': 'newname', }) # lbaas-loadbalancer-update myid --description check. self._test_update_lb(['--description', 'check'], {'description': 'check', }) # lbaas-loadbalancer-update myid --admin-state-up False. self._test_update_lb(['--admin-state-up', 'False'], {'admin_state_up': 'False', }) def test_delete_loadbalancer(self): # lbaas-loadbalancer-loadbalancer-delete my-id. resource = 'loadbalancer' cmd_resource = 'lbaas_loadbalancer' cmd = lb.DeleteLoadBalancer(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args, cmd_resource=cmd_resource) def test_retrieve_loadbalancer_stats(self): # lbaas-loadbalancer-stats test_id. resource = 'loadbalancer' cmd = lb.RetrieveLoadBalancerStats(test_cli20.MyApp(sys.stdout), None) my_id = self.test_id fields = ['bytes_in', 'bytes_out'] args = ['--fields', 'bytes_in', '--fields', 'bytes_out', my_id] self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) query = "&".join(["fields=%s" % field for field in fields]) expected_res = {'stats': {'bytes_in': '1234', 'bytes_out': '4321'}} resstr = self.client.serialize(expected_res) path = getattr(self.client, "lbaas_loadbalancer_path_stats") return_tup = (test_cli20.MyResp(200), resstr) self.client.httpclient.request( test_cli20.end_url(path % my_id, query), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(return_tup) self.mox.ReplayAll() cmd_parser = cmd.get_parser("test_" + resource) parsed_args = cmd_parser.parse_args(args) cmd.run(parsed_args) self.mox.VerifyAll() self.mox.UnsetStubs() _str = self.fake_stdout.make_string() self.assertIn('bytes_in', _str) self.assertIn('1234', _str) self.assertIn('bytes_out', _str) self.assertIn('4321', _str) def test_get_loadbalancer_statuses(self): # lbaas-loadbalancer-status test_id. resource = 'loadbalancer' cmd = lb.RetrieveLoadBalancerStatus(test_cli20.MyApp(sys.stdout), None) my_id = self.test_id args = [my_id] self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) expected_res = {'statuses': {'operating_status': 'ONLINE', 'provisioning_status': 'ACTIVE'}} resstr = self.client.serialize(expected_res) path = getattr(self.client, "lbaas_loadbalancer_path_status") return_tup = (test_cli20.MyResp(200), resstr) self.client.httpclient.request( test_cli20.end_url(path % my_id), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(return_tup) self.mox.ReplayAll() cmd_parser = cmd.get_parser("test_" + resource) parsed_args = cmd_parser.parse_args(args) cmd.run(parsed_args) self.mox.VerifyAll() self.mox.UnsetStubs() _str = self.fake_stdout.make_string() self.assertIn('operating_status', _str) self.assertIn('ONLINE', _str) self.assertIn('provisioning_status', _str) self.assertIn('ACTIVE', _str) python-neutronclient-6.7.0/neutronclient/tests/unit/lb/v2/test_cli20_pool.py0000666000175100017510000002146013232473350027300 0ustar zuulzuul00000000000000# Copyright 2014 Blue Box Group, Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.common import exceptions from neutronclient.neutron.v2_0.lb.v2 import pool from neutronclient.tests.unit import test_cli20 class CLITestV20LbPoolJSON(test_cli20.CLITestV20Base): def test_create_pool_with_listener(self): # lbaas-pool-create with listener resource = 'pool' cmd_resource = 'lbaas_pool' cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' lb_algorithm = 'ROUND_ROBIN' listener = 'listener' protocol = 'TCP' args = ['--lb-algorithm', lb_algorithm, '--protocol', protocol, '--listener', listener] position_names = ['admin_state_up', 'lb_algorithm', 'protocol', 'listener_id'] position_values = [True, lb_algorithm, protocol, listener] self._test_create_resource(resource, cmd, '', my_id, args, position_names, position_values, cmd_resource=cmd_resource) def test_create_pool_with_loadbalancer_no_listener(self): """lbaas-pool-create with loadbalancer, no listener.""" resource = 'pool' cmd_resource = 'lbaas_pool' cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' lb_algorithm = 'ROUND_ROBIN' loadbalancer = 'loadbalancer' protocol = 'TCP' args = ['--lb-algorithm', lb_algorithm, '--protocol', protocol, '--loadbalancer', loadbalancer] position_names = ['admin_state_up', 'lb_algorithm', 'protocol', 'loadbalancer_id'] position_values = [True, lb_algorithm, protocol, loadbalancer] self._test_create_resource(resource, cmd, '', my_id, args, position_names, position_values, cmd_resource=cmd_resource) def test_create_pool_with_no_listener_or_loadbalancer(self): """lbaas-pool-create with no listener or loadbalancer.""" resource = 'pool' cmd_resource = 'lbaas_pool' cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' lb_algorithm = 'ROUND_ROBIN' protocol = 'TCP' args = ['--lb-algorithm', lb_algorithm, '--protocol', protocol] position_names = ['admin_state_up', 'lb_algorithm', 'protocol'] position_values = [True, lb_algorithm, protocol] self._test_create_resource(resource, cmd, '', my_id, args, position_names, position_values, cmd_resource=cmd_resource, no_api_call=True, expected_exception=exceptions.CommandError) def test_create_pool_with_all_params(self): # lbaas-pool-create with all params set. resource = 'pool' cmd_resource = 'lbaas_pool' cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' lb_algorithm = 'ROUND_ROBIN' listener = 'listener' loadbalancer = 'loadbalancer' protocol = 'TCP' description = 'description' session_persistence_str = 'type=APP_COOKIE,cookie_name=1234' session_persistence = {'type': 'APP_COOKIE', 'cookie_name': '1234'} name = 'my-pool' args = ['--lb-algorithm', lb_algorithm, '--protocol', protocol, '--description', description, '--session-persistence', session_persistence_str, '--admin-state-down', '--name', name, '--listener', listener, '--loadbalancer', loadbalancer] position_names = ['lb_algorithm', 'protocol', 'description', 'session_persistence', 'admin_state_up', 'name', 'listener_id', 'loadbalancer_id'] position_values = [lb_algorithm, protocol, description, session_persistence, False, name, listener, loadbalancer] self._test_create_resource(resource, cmd, '', my_id, args, position_names, position_values, cmd_resource=cmd_resource) def test_list_pools(self): # lbaas-pool-list. resources = 'pools' cmd_resources = 'lbaas_pools' cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True, cmd_resources=cmd_resources) def test_list_pools_pagination(self): # lbaas-pool-list with pagination. resources = 'pools' cmd_resources = 'lbaas_pools' cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd, cmd_resources=cmd_resources) def test_list_pools_sort(self): # lbaas-pool-list --sort-key id --sort-key asc. resources = 'pools' cmd_resources = 'lbaas_pools' cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True, cmd_resources=cmd_resources) def test_list_pools_limit(self): # lbaas-pool-list -P. resources = 'pools' cmd_resources = 'lbaas_pools' cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000, cmd_resources=cmd_resources) def test_show_pool_id(self): # lbaas-pool-show test_id. resource = 'pool' cmd_resource = 'lbaas_pool' cmd = pool.ShowPool(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id'], cmd_resource=cmd_resource) def test_show_pool_id_name(self): # lbaas-pool-show. resource = 'pool' cmd_resource = 'lbaas_pool' cmd = pool.ShowPool(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'], cmd_resource=cmd_resource) def test_update_pool(self): # lbaas-pool-update myid --name newname --description SuperPool # --lb-algorithm SOURCE_IP --admin-state-up # --session-persistence type=dict,type=HTTP_COOKIE,cookie_name=pie resource = 'pool' cmd_resource = 'lbaas_pool' cmd = pool.UpdatePool(test_cli20.MyApp(sys.stdout), None) args = ['myid', '--name', 'newname', '--description', 'SuperPool', '--lb-algorithm', "SOURCE_IP", '--admin-state-up', 'True', '--session-persistence', 'type=dict,' 'type=HTTP_COOKIE,cookie_name=pie'] body = {'name': 'newname', "description": "SuperPool", "lb_algorithm": "SOURCE_IP", "admin_state_up": 'True', 'session_persistence': { 'type': 'HTTP_COOKIE', 'cookie_name': 'pie', }, } self._test_update_resource(resource, cmd, 'myid', args, body, cmd_resource=cmd_resource) # lbaas-pool-update myid --name Name # --no-session-persistence resource = 'pool' cmd_resource = 'lbaas_pool' cmd = pool.UpdatePool(test_cli20.MyApp(sys.stdout), None) args = ['myid', '--name', 'Name', '--no-session-persistence'] body = {'name': "Name", "session_persistence": None, } self._test_update_resource(resource, cmd, 'myid', args, body, cmd_resource=cmd_resource) def test_delete_pool(self): # lbaas-pool-delete my-id. resource = 'pool' cmd_resource = 'lbaas_pool' cmd = pool.DeletePool(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args, cmd_resource=cmd_resource) python-neutronclient-6.7.0/neutronclient/tests/unit/lb/v2/test_cli20_l7rule.py0000666000175100017510000001765413232473350027553 0ustar zuulzuul00000000000000# Copyright 2016 Radware LTD. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.lb.v2 import l7rule from neutronclient.tests.unit import test_cli20 """Structure for mapping cli and api arguments The structure maps cli arguments and a list of its api argument name, default cli value and default api value. It helps to make tests more general for different argument types. """ args_conf = { 'admin-state-up': ['admin_state_up', True, True], 'admin-state-down': ['admin_state_up', None, False], 'type': ['type', 'HOST_NAME', 'HOST_NAME'], 'compare-type': ['compare_type', 'EQUAL_TO', 'EQUAL_TO'], 'invert-compare': ['invert', None, True], 'key': ['key', 'key', 'key'], 'value': ['value', 'value', 'value']} class CLITestV20LbL7RuleJSON(test_cli20.CLITestV20Base): def _get_test_args(self, *args, **kwargs): """Function for generically building testing arguments""" cli_args = [] api_args = {} for arg in args: cli_args.append('--' + arg) if not args_conf[arg][1]: pass elif arg in kwargs: cli_args.append(str(kwargs[arg])) else: cli_args.append(args_conf[arg][1]) if arg in kwargs: api_args[args_conf[arg][0]] = kwargs[arg] else: api_args[args_conf[arg][0]] = args_conf[arg][2] if 'invert' not in api_args: api_args['invert'] = False return cli_args, api_args def _test_create_rule(self, *args, **kwargs): resource = 'rule' cmd_resource = 'lbaas_l7rule' cmd = l7rule.CreateL7Rule(test_cli20.MyApp(sys.stdout), None) cli_args, api_args = self._get_test_args(*args, **kwargs) position_names = list(api_args.keys()) position_values = list(api_args.values()) cli_args.append('test_policy') self._test_create_resource(resource, cmd, None, 'test_id', cli_args, position_names, position_values, cmd_resource=cmd_resource, parent_id='test_policy') def _test_update_rule(self, *args, **kwargs): resource = 'rule' cmd_resource = 'lbaas_l7rule' cmd = l7rule.UpdateL7Rule(test_cli20.MyApp(sys.stdout), None) cli_args, api_args = self._get_test_args(*args, **kwargs) cli_args.append('test_id') cli_args.append('test_policy') self._test_update_resource(resource, cmd, 'test_id', cli_args, api_args, cmd_resource=cmd_resource, parent_id='test_policy') def test_create_rule_with_mandatory_params(self): # lbaas-l7rule-create with mandatory params only. self._test_create_rule('type', 'compare-type', 'value') def test_create_disabled_rule(self): # lbaas-l7rule-create disabled rule. self._test_create_rule('type', 'compare-type', 'value', 'admin-state-down') def test_create_rule_with_all_params(self): # lbaas-l7rule-create with all params set. self._test_create_rule('type', 'compare-type', 'invert-compare', 'key', 'value', type='HEADER', compare_type='CONTAINS', key='other_key', value='other_value') def test_create_rule_with_inverted_compare(self): # lbaas-l7rule-create with invertted compare type. self._test_create_rule('type', 'compare-type', 'invert-compare', 'value') def test_list_rules(self): # lbaas-l7rule-list. resources = 'rules' cmd_resources = 'lbaas_l7rules' cmd = l7rule.ListL7Rule(test_cli20.MyApp(sys.stdout), None) policy_id = 'policy_id' self._test_list_resources(resources, cmd, True, base_args=[policy_id], cmd_resources=cmd_resources, parent_id=policy_id, query="l7policy_id=%s" % policy_id) def test_list_rules_pagination(self): # lbaas-l7rule-list with pagination. resources = 'rules' cmd_resources = 'lbaas_l7rules' cmd = l7rule.ListL7Rule(test_cli20.MyApp(sys.stdout), None) policy_id = 'policy_id' self._test_list_resources_with_pagination( resources, cmd, base_args=[policy_id], cmd_resources=cmd_resources, parent_id=policy_id, query="l7policy_id=%s" % policy_id) def test_list_rules_sort(self): # lbaas-l7rule-list --sort-key id --sort-key asc. resources = 'rules' cmd_resources = 'lbaas_l7rules' cmd = l7rule.ListL7Rule(test_cli20.MyApp(sys.stdout), None) policy_id = 'policy_id' self._test_list_resources( resources, cmd, True, base_args=[policy_id], cmd_resources=cmd_resources, parent_id=policy_id, query="l7policy_id=%s" % policy_id) def test_list_rules_limit(self): # lbaas-l7rule-list -P. resources = 'rules' cmd_resources = 'lbaas_l7rules' cmd = l7rule.ListL7Rule(test_cli20.MyApp(sys.stdout), None) policy_id = 'policy_id' self._test_list_resources(resources, cmd, page_size=1000, base_args=[policy_id], cmd_resources=cmd_resources, parent_id=policy_id, query="l7policy_id=%s" % policy_id) def test_show_rule_id(self): # lbaas-l7rule-show test_id. resource = 'rule' cmd_resource = 'lbaas_l7rule' policy_id = 'policy_id' cmd = l7rule.ShowL7Rule(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', self.test_id, policy_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id'], cmd_resource=cmd_resource, parent_id=policy_id) def test_update_rule_type(self): # lbaas-l7rule-update test_id --type HEADER test_policy self._test_update_rule('type', type='HEADER') def test_update_rule_compare_type(self): # lbaas-l7rule-update test_id --compare-type CONTAINS test_policy. self._test_update_rule('compare-type', **{'compare-type': 'CONTAINS'}) def test_update_rule_inverted_compare_type(self): # lbaas-l7rule-update test_id --invert-compare test_policy. self._test_update_rule('invert-compare') def test_update_rule_key_value(self): # lbaas-l7rule-update test_id --key other --value other test_policy. self._test_update_rule('key', 'value', key='other', value='other') def test_delete_rule(self): # lbaas-l7rule-delete test_id policy_id. resource = 'rule' cmd_resource = 'lbaas_l7rule' policy_id = 'policy_id' test_id = 'test_id' cmd = l7rule.DeleteL7Rule(test_cli20.MyApp(sys.stdout), None) args = [test_id, policy_id] self._test_delete_resource(resource, cmd, test_id, args, cmd_resource=cmd_resource, parent_id=policy_id) python-neutronclient-6.7.0/neutronclient/tests/unit/lb/v2/__init__.py0000666000175100017510000000000013232473350026021 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/lb/test_cli20_pool.py0000666000175100017510000001473413232473350026757 0ustar zuulzuul00000000000000# Copyright 2013 Mirantis Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from mox3 import mox from neutronclient.neutron.v2_0.lb import pool from neutronclient.tests.unit import test_cli20 class CLITestV20LbPoolJSON(test_cli20.CLITestV20Base): def test_create_pool_with_mandatory_params(self): # lb-pool-create with mandatory params only. resource = 'pool' cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None) name = 'my-name' lb_method = 'ROUND_ROBIN' protocol = 'HTTP' subnet_id = 'subnet-id' tenant_id = 'my-tenant' my_id = 'my-id' args = ['--lb-method', lb_method, '--name', name, '--protocol', protocol, '--subnet-id', subnet_id, '--tenant-id', tenant_id] position_names = ['admin_state_up', 'lb_method', 'name', 'protocol', 'subnet_id', 'tenant_id'] position_values = [True, lb_method, name, protocol, subnet_id, tenant_id] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values) def test_create_pool_with_all_params(self): # lb-pool-create with all params set. resource = 'pool' cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None) name = 'my-name' description = 'my-desc' lb_method = 'ROUND_ROBIN' protocol = 'HTTP' subnet_id = 'subnet-id' tenant_id = 'my-tenant' my_id = 'my-id' provider = 'lbaas' args = ['--admin-state-down', '--description', description, '--lb-method', lb_method, '--name', name, '--protocol', protocol, '--subnet-id', subnet_id, '--tenant-id', tenant_id, '--provider', provider] position_names = ['admin_state_up', 'description', 'lb_method', 'name', 'protocol', 'subnet_id', 'tenant_id', 'provider'] position_values = [False, description, lb_method, name, protocol, subnet_id, tenant_id, provider] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values) def test_list_pools(self): # lb-pool-list. resources = "pools" cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_pools_pagination(self): # lb-pool-list. resources = "pools" cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_pools_sort(self): # lb-pool-list --sort-key name --sort-key id --sort-key asc # --sort-key desc resources = "pools" cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_pools_limit(self): # lb-pool-list -P. resources = "pools" cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_pool_id(self): # lb-pool-show test_id. resource = 'pool' cmd = pool.ShowPool(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_pool_id_name(self): # lb-pool-show. resource = 'pool' cmd = pool.ShowPool(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_pool(self): # lb-pool-update myid --name newname --tags a b. resource = 'pool' cmd = pool.UpdatePool(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'newname'], {'name': 'newname', }) def test_delete_pool(self): # lb-pool-delete my-id. resource = 'pool' cmd = pool.DeletePool(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) def test_retrieve_pool_stats(self): # lb-pool-stats test_id. resource = 'pool' cmd = pool.RetrievePoolStats(test_cli20.MyApp(sys.stdout), None) my_id = self.test_id fields = ['bytes_in', 'bytes_out'] args = ['--fields', 'bytes_in', '--fields', 'bytes_out', my_id] self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) query = "&".join(["fields=%s" % field for field in fields]) expected_res = {'stats': {'bytes_in': '1234', 'bytes_out': '4321'}} resstr = self.client.serialize(expected_res) path = getattr(self.client, "pool_path_stats") return_tup = (test_cli20.MyResp(200), resstr) self.client.httpclient.request( test_cli20.end_url(path % my_id, query), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(return_tup) self.mox.ReplayAll() cmd_parser = cmd.get_parser("test_" + resource) parsed_args = cmd_parser.parse_args(args) cmd.run(parsed_args) self.mox.VerifyAll() self.mox.UnsetStubs() _str = self.fake_stdout.make_string() self.assertIn('bytes_in', _str) self.assertIn('bytes_out', _str) python-neutronclient-6.7.0/neutronclient/tests/unit/lb/__init__.py0000666000175100017510000000000013232473350025472 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/bgp/0000775000175100017510000000000013232473710023544 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/bgp/test_cli20_speaker.py0000666000175100017510000002772413232473350027616 0ustar zuulzuul00000000000000# Copyright 2016 Huawei Technologies India Pvt. Ltd. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from mox3 import mox from neutronclient.common import exceptions from neutronclient.neutron.v2_0.bgp import speaker as bgp_speaker from neutronclient.tests.unit import test_cli20 class CLITestV20BGPSpeakerJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['bgp_speaker'] def test_create_bgp_speaker_with_minimal_options(self): # Create BGP Speaker with mandatory params. resource = 'bgp_speaker' cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout), None) name = 'my-name' my_id = 'my-id' local_asnum = '1' args = [name, '--local-as', local_asnum, ] position_names = ['name', 'local_as', 'ip_version'] position_values = [name, local_asnum, 4] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values) def test_create_ipv4_bgp_speaker_with_all_params(self): # Create BGP Speaker with all params. resource = 'bgp_speaker' cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout), None) name = 'my-name' my_id = 'my-id' local_asnum = '1' args = [name, '--local-as', local_asnum, '--ip-version', '4', '--advertise-floating-ip-host-routes', 'True', '--advertise-tenant-networks', 'True'] position_names = ['name', 'local_as', 'ip_version', 'advertise_floating_ip_host_routes', 'advertise_tenant_networks'] position_values = [name, local_asnum, 4, 'True', 'True'] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values) def test_create_ipv6_bgp_speaker_with_all_params(self): # Create BGP Speaker with all params. resource = 'bgp_speaker' cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout), None) name = 'my-name' my_id = 'my-id' local_asnum = '65535' args = [name, '--local-as', local_asnum, '--ip-version', '6', '--advertise-floating-ip-host-routes', 'True', '--advertise-tenant-networks', 'True'] position_names = ['name', 'local_as', 'ip_version', 'advertise_floating_ip_host_routes', 'advertise_tenant_networks'] position_values = [name, local_asnum, 6, 'True', 'True'] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values) def test_create_bgp_speaker_with_invalid_min_local_asnum(self): # Create BGP Speaker with invalid minimum local-asnum. resource = 'bgp_speaker' cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout), None) name = 'my-name' my_id = 'my-id' local_asnum = '0' args = [name, '--local-as', local_asnum] position_names = ['name', 'local_as'] position_values = [name, local_asnum] exc = self.assertRaises(exceptions.CommandError, self._test_create_resource, resource, cmd, name, my_id, args, position_names, position_values) self.assertEqual('local-as "0" should be an integer [%s:%s].' % (bgp_speaker.MIN_AS_NUM, bgp_speaker.MAX_AS_NUM), str(exc)) def test_create_bgp_speaker_with_invalid_max_local_asnum(self): # Create BGP Speaker with invalid maximum local-asnum. resource = 'bgp_speaker' cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout), None) name = 'my-name' my_id = 'my-id' local_asnum = '65536' args = [name, '--local-as', local_asnum] position_names = ['name', 'local_as', ] position_values = [name, local_asnum, ] exc = self.assertRaises(exceptions.CommandError, self._test_create_resource, resource, cmd, name, my_id, args, position_names, position_values) self.assertEqual('local-as "65536" should be an integer [%s:%s].' % (bgp_speaker.MIN_AS_NUM, bgp_speaker.MAX_AS_NUM), str(exc)) def test_update_bgp_speaker(self): # Update BGP Speaker: # myid --advertise-tenant-networks True # --advertise-floating-ip-host-routes False resource = 'bgp_speaker' cmd = bgp_speaker.UpdateSpeaker(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'new-name', '--advertise-tenant-networks', 'True', '--advertise-floating-ip-host-routes', 'False'], {'name': 'new-name', 'advertise_tenant_networks': 'True', 'advertise_floating_ip_host_routes': 'False'}) def test_update_bgp_speaker_exception(self): # Update BGP Speaker: myid. resource = 'bgp_speaker' cmd = bgp_speaker.UpdateSpeaker(test_cli20.MyApp(sys.stdout), None) self.assertRaises(exceptions.CommandError, self._test_update_resource, resource, cmd, 'myid', ['myid'], {}) def test_list_bgp_speaker(self): # List all BGP Speakers. resources = "bgp_speakers" cmd = bgp_speaker.ListSpeakers(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_bgp_speaker_pagination(self): # List all BGP Speakers with pagination support. cmd = bgp_speaker.ListSpeakers(test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(bgp_speaker.ListSpeakers, "extend_list") bgp_speaker.ListSpeakers.extend_list(mox.IsA(list), mox.IgnoreArg()) self._test_list_resources_with_pagination("bgp_speakers", cmd) self.mox.VerifyAll() self.mox.UnsetStubs() def test_list_bgp_speaker_sort(self): # sorted list: bgp-speaker-list --sort-key name --sort-key id # --sort-key asc --sort-key desc resources = "bgp_speakers" cmd = bgp_speaker.ListSpeakers(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_bgp_speaker_limit(self): # size (1000) limited list: bgp-speaker-list -P. resources = "bgp_speakers" cmd = bgp_speaker.ListSpeakers(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_bgp_speaker(self): # Show BGP Speaker: --fields id --fields name myid. resource = 'bgp_speaker' cmd = bgp_speaker.ShowSpeaker(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', '--fields', 'name', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id', 'name']) def test_delete_bgp_speaker(self): # Delete BGP Speaker: bgp_speaker_id. resource = 'bgp_speaker' cmd = bgp_speaker.DeleteSpeaker(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) def _test_add_remove_peer(self, action, cmd, args): """Add or Remove BGP Peer to/from a BGP Speaker.""" resource = 'bgp_speaker' subcmd = '%s_bgp_peer' % action body = {'bgp_peer_id': 'peerid'} if action == 'add': retval = {'bgp_peer': 'peerid'} retval = self.client.serialize(retval) expected_code = 200 else: retval = None expected_code = 204 self._test_update_resource_action(resource, cmd, 'myid', subcmd, args, body, expected_code, retval) def test_add_peer_to_bgp_speaker(self): # Add peer to BGP speaker: myid peer_id=peerid cmd = bgp_speaker.AddPeerToSpeaker(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'peerid'] self._test_add_remove_peer('add', cmd, args) def test_remove_peer_from_bgp_speaker(self): # Remove peer from BGP speaker: myid peer_id=peerid cmd = bgp_speaker.RemovePeerFromSpeaker(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'peerid'] self._test_add_remove_peer('remove', cmd, args) def _test_add_remove_network(self, action, cmd, args): # Add or Remove network to/from a BGP Speaker. resource = 'bgp_speaker' subcmd = '%s_gateway_network' % action body = {'network_id': 'netid'} if action == 'add': retval = {'network': 'netid'} retval = self.client.serialize(retval) expected_code = 200 else: retval = None expected_code = 204 self._test_update_resource_action(resource, cmd, 'myid', subcmd, args, body, expected_code, retval) def test_add_network_to_bgp_speaker(self): # Add peer to BGP speaker: myid network_id=netid cmd = bgp_speaker.AddNetworkToSpeaker(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'netid'] self._test_add_remove_network('add', cmd, args) def test_remove_network_from_bgp_speaker(self): # Remove network from BGP speaker: myid network_id=netid cmd = bgp_speaker.RemoveNetworkFromSpeaker( test_cli20.MyApp(sys.stdout), None) args = ['myid', 'netid'] self._test_add_remove_network('remove', cmd, args) def test_list_routes_advertised_by_a_bgp_speaker(self): # Retrieve advertised route list resources = 'advertised_routes' cmd = bgp_speaker.ListRoutesAdvertisedBySpeaker( test_cli20.MyApp(sys.stdout), None) bs_id = 'bgp_speaker_id1' path = ((self.client.bgp_speaker_path + '/get_advertised_routes') % bs_id) self._test_list_resources(resources, cmd, base_args=[bs_id], path=path) python-neutronclient-6.7.0/neutronclient/tests/unit/bgp/test_cli20_peer.py0000666000175100017510000002251213232473350027105 0ustar zuulzuul00000000000000# Copyright 2016 Huawei Technologies India Pvt. Ltd. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.common import exceptions from neutronclient.neutron.v2_0.bgp import peer as bgp_peer from neutronclient.neutron.v2_0.bgp import speaker as bgp_speaker from neutronclient.tests.unit import test_cli20 class CLITestV20BGPPeerJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['bgp_peer'] def test_create_bgp_peer_with_mandatory_params(self): # Create BGP peer with mandatory params. resource = 'bgp_peer' cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout), None) name = 'my-name' my_id = 'my-id' peerip = '1.1.1.1' remote_asnum = '1' args = [name, '--peer-ip', peerip, '--remote-as', remote_asnum, ] position_names = ['name', 'peer_ip', 'remote_as', 'auth_type'] position_values = [name, peerip, remote_asnum, 'none'] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values) def test_create_bgp_peer_with_all_params(self): # Create BGP peer with all params. resource = 'bgp_peer' cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout), None) name = 'my-name' my_id = 'my-id' peerip = '1.1.1.1' remote_asnum = '65535' authType = 'md5' password = 'abc' args = [name, '--peer-ip', peerip, '--remote-as', remote_asnum, '--auth-type', authType, '--password', password] position_names = ['name', 'peer_ip', 'remote_as', 'auth_type', 'password'] position_values = [name, peerip, remote_asnum, authType, password] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values) def test_create_bgp_peer_with_invalid_min_remote_asnum(self): # Create BGP peer with invalid minimum remote-asnum. resource = 'bgp_peer' cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout), None) name = 'my-name' my_id = 'my-id' peerip = '1.1.1.1' remote_asnum = '0' args = [name, '--peer-ip', peerip, '--remote-as', remote_asnum, ] position_names = ['name', 'peer_ip', 'remote_as', ] position_values = [name, peerip, remote_asnum, ] exc = self.assertRaises(exceptions.CommandError, self._test_create_resource, resource, cmd, name, my_id, args, position_names, position_values) self.assertEqual('remote-as "0" should be an integer [%s:%s].' % (bgp_speaker.MIN_AS_NUM, bgp_speaker.MAX_AS_NUM), str(exc)) def test_create_bgp_peer_with_invalid_max_remote_asnum(self): # Create BGP peer with invalid maximum remote-asnum. resource = 'bgp_peer' cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout), None) name = 'my-name' my_id = 'my-id' peerip = '1.1.1.1' remote_asnum = '65536' args = [name, '--peer-ip', peerip, '--remote-as', remote_asnum, ] position_names = ['name', 'peer_ip', 'remote_as', 'auth_type', 'password'] position_values = [name, peerip, remote_asnum, 'none', ''] exc = self.assertRaises(exceptions.CommandError, self._test_create_resource, resource, cmd, name, my_id, args, position_names, position_values) self.assertEqual('remote-as "65536" should be an integer [%s:%s].' % (bgp_speaker.MIN_AS_NUM, bgp_speaker.MAX_AS_NUM), str(exc)) def test_create_authenticated_bgp_peer_without_authtype(self): # Create authenticated BGP peer without auth-type. resource = 'bgp_peer' cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout), None) name = 'my-name' my_id = 'my-id' peerip = '1.1.1.1' remote_asnum = '2048' password = 'abc' args = [name, '--peer-ip', peerip, '--remote-as', remote_asnum, '--password', password] position_names = ['name', 'peer_ip', 'remote_as', 'password'] position_values = [name, peerip, remote_asnum, password] exc = self.assertRaises(exceptions.CommandError, self._test_create_resource, resource, cmd, name, my_id, args, position_names, position_values) self.assertEqual('Must provide auth-type if password is specified.', str(exc)) def test_create_authenticated_bgp_peer_without_password(self): # Create authenticated BGP peer without password. resource = 'bgp_peer' cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout), None) name = 'my-name' my_id = 'my-id' peerip = '1.1.1.1' remote_asnum = '2048' authType = 'md5' args = [name, '--peer-ip', peerip, '--remote-as', remote_asnum, '--auth-type', authType] position_names = ['name', 'peer_ip', 'remote_as', 'auth_type'] position_values = [name, peerip, remote_asnum, authType] exc = self.assertRaises(exceptions.CommandError, self._test_create_resource, resource, cmd, name, my_id, args, position_names, position_values) self.assertEqual('Must provide password if auth-type is specified.', str(exc)) def test_update_bgp_peer(self): # Update BGP peer: # myid --advertise-tenant-networks True # --advertise-floating-ip-host-routes False resource = 'bgp_peer' cmd = bgp_peer.UpdatePeer(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'new-name', '--password', 'abc'], {'name': 'new-name', 'password': 'abc'}) def test_update_bgp_peer_exception(self): # Update BGP peer: myid. resource = 'bgp_peer' cmd = bgp_peer.UpdatePeer(test_cli20.MyApp(sys.stdout), None) self.assertRaises(exceptions.CommandError, self._test_update_resource, resource, cmd, 'myid', ['myid'], {}) def test_list_bgp_peer(self): # List all BGP peers. resources = "bgp_peers" cmd = bgp_peer.ListPeers(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) # TODO(Vikram): Add test_list_bgp_peer_pagination def test_list_bgp_peer_sort(self): # sorted list: bgp-peer-list --sort-key name --sort-key id # --sort-key asc --sort-key desc resources = "bgp_peers" cmd = bgp_peer.ListPeers(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_bgp_peer_limit(self): # size (1000) limited list: bgp-peer-list -P. resources = "bgp_peers" cmd = bgp_peer.ListPeers(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_bgp_peer(self): # Show BGP peer: --fields id --fields name myid. resource = 'bgp_peer' cmd = bgp_peer.ShowPeer(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', '--fields', 'name', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id', 'name']) def test_delete_bgp_peer(self): # Delete BGP peer: bgp_peer_id. resource = 'bgp_peer' cmd = bgp_peer.DeletePeer(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) python-neutronclient-6.7.0/neutronclient/tests/unit/bgp/test_cli20_dragentscheduler.py0000666000175100017510000000530113232473350031472 0ustar zuulzuul00000000000000# Copyright 2016 Huawei Technologies India Pvt. Ltd. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.bgp import dragentscheduler as bgp_drsched from neutronclient.tests.unit import test_cli20 from neutronclient.tests.unit import test_cli20_agentschedulers as test_as BGP_DRAGENT_ID = 'bgp_dragent_id1' BGP_SPEAKER = 'bgp_speaker_id1' class CLITestV20DRAgentScheduler(test_as.CLITestV20AgentScheduler): def test_add_bgp_speaker_to_dragent(self): resource = 'agent' cmd = bgp_drsched.AddBGPSpeakerToDRAgent( test_cli20.MyApp(sys.stdout), None) args = (BGP_DRAGENT_ID, BGP_SPEAKER) body = {'bgp_speaker_id': BGP_SPEAKER} result = {'bgp_speaker_id': 'bgp_speaker_id', } self._test_add_to_agent(resource, cmd, args, self.client.BGP_DRINSTANCES, body, result) def test_remove_bgp_speaker_from_dragent(self): resource = 'agent' cmd = bgp_drsched.RemoveBGPSpeakerFromDRAgent( test_cli20.MyApp(sys.stdout), None) args = (BGP_DRAGENT_ID, BGP_SPEAKER) self._test_remove_from_agent(resource, cmd, args, self.client.BGP_DRINSTANCES) def test_list_bgp_speakers_on_dragent(self): resources = 'bgp_speakers' cmd = bgp_drsched.ListBGPSpeakersOnDRAgent( test_cli20.MyApp(sys.stdout), None) path = ((self.client.agent_path + self.client.BGP_DRINSTANCES) % BGP_DRAGENT_ID) self._test_list_resources(resources, cmd, base_args=[BGP_DRAGENT_ID], path=path) def test_list_dragents_hosting_bgp_speaker(self): resources = 'agent' cmd = bgp_drsched.ListDRAgentsHostingBGPSpeaker( test_cli20.MyApp(sys.stdout), None) path = ((self.client.bgp_speaker_path + self.client.BGP_DRAGENTS) % BGP_DRAGENT_ID) contents = {self.id_field: 'myid1', 'alive': True} self._test_list_resources(resources, cmd, base_args=[BGP_DRAGENT_ID], path=path, response_contents=contents) python-neutronclient-6.7.0/neutronclient/tests/unit/bgp/__init__.py0000666000175100017510000000000013232473350025645 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/vpn/0000775000175100017510000000000013232473710023577 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/vpn/test_cli20_ipsec_site_connection.py0000666000175100017510000003455613232473350032566 0ustar zuulzuul00000000000000# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.common import exceptions from neutronclient.neutron.v2_0.vpn import ipsec_site_connection from neutronclient.tests.unit import test_cli20 class CLITestV20IPsecSiteConnectionJSON(test_cli20.CLITestV20Base): # TODO(pcm): Remove, once peer-cidr is deprecated completely def test_create_ipsec_site_connection_all_params_using_peer_cidrs(self): # ipsecsite-connection-create all params using peer CIDRs. resource = 'ipsec_site_connection' cmd = ipsec_site_connection.CreateIPsecSiteConnection( test_cli20.MyApp(sys.stdout), None ) tenant_id = 'mytenant_id' name = 'connection1' my_id = 'my_id' peer_address = '192.168.2.10' peer_id = '192.168.2.10' psk = 'abcd' mtu = '1500' initiator = 'bi-directional' vpnservice_id = 'vpnservice_id' ikepolicy_id = 'ikepolicy_id' ipsecpolicy_id = 'ipsecpolicy_id' peer_cidrs = ['192.168.3.0/24', '192.168.2.0/24'] admin_state = True description = 'my-vpn-connection' dpd = 'action=restart,interval=30,timeout=120' args = ['--tenant-id', tenant_id, '--peer-address', peer_address, '--peer-id', peer_id, '--psk', psk, '--initiator', initiator, '--vpnservice-id', vpnservice_id, '--ikepolicy-id', ikepolicy_id, '--name', name, '--ipsecpolicy-id', ipsecpolicy_id, '--mtu', mtu, '--description', description, '--peer-cidr', '192.168.3.0/24', '--peer-cidr', '192.168.2.0/24', '--dpd', dpd] position_names = ['name', 'tenant_id', 'admin_state_up', 'peer_address', 'peer_id', 'peer_cidrs', 'psk', 'mtu', 'initiator', 'description', 'vpnservice_id', 'ikepolicy_id', 'ipsecpolicy_id'] position_values = [name, tenant_id, admin_state, peer_address, peer_id, peer_cidrs, psk, mtu, initiator, description, vpnservice_id, ikepolicy_id, ipsecpolicy_id] extra_body = { 'dpd': { 'action': 'restart', 'interval': 30, 'timeout': 120, }, } self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, extra_body=extra_body) def test_create_ipsec_site_conn_all_params(self): # ipsecsite-connection-create all params using endpoint groups. resource = 'ipsec_site_connection' cmd = ipsec_site_connection.CreateIPsecSiteConnection( test_cli20.MyApp(sys.stdout), None ) tenant_id = 'mytenant_id' name = 'connection1' my_id = 'my_id' peer_address = '192.168.2.10' peer_id = '192.168.2.10' psk = 'abcd' mtu = '1500' initiator = 'bi-directional' vpnservice_id = 'vpnservice_id' ikepolicy_id = 'ikepolicy_id' ipsecpolicy_id = 'ipsecpolicy_id' local_ep_group = 'local-epg' peer_ep_group = 'peer-epg' admin_state = True description = 'my-vpn-connection' dpd = 'action=restart,interval=30,timeout=120' args = ['--tenant-id', tenant_id, '--peer-address', peer_address, '--peer-id', peer_id, '--psk', psk, '--initiator', initiator, '--vpnservice-id', vpnservice_id, '--ikepolicy-id', ikepolicy_id, '--name', name, '--ipsecpolicy-id', ipsecpolicy_id, '--mtu', mtu, '--description', description, '--local-ep-group', local_ep_group, '--peer-ep-group', peer_ep_group, '--dpd', dpd] position_names = ['name', 'tenant_id', 'admin_state_up', 'peer_address', 'peer_id', 'psk', 'mtu', 'local_ep_group_id', 'peer_ep_group_id', 'initiator', 'description', 'vpnservice_id', 'ikepolicy_id', 'ipsecpolicy_id'] position_values = [name, tenant_id, admin_state, peer_address, peer_id, psk, mtu, local_ep_group, peer_ep_group, initiator, description, vpnservice_id, ikepolicy_id, ipsecpolicy_id] extra_body = { 'dpd': { 'action': 'restart', 'interval': 30, 'timeout': 120, }, } self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, extra_body=extra_body) def test_create_ipsec_site_connection_with_limited_params(self): # ipsecsite-connection-create with limited params. resource = 'ipsec_site_connection' cmd = ipsec_site_connection.CreateIPsecSiteConnection( test_cli20.MyApp(sys.stdout), None ) tenant_id = 'mytenant_id' my_id = 'my_id' peer_address = '192.168.2.10' peer_id = '192.168.2.10' psk = 'abcd' mtu = '1500' initiator = 'bi-directional' vpnservice_id = 'vpnservice_id' ikepolicy_id = 'ikepolicy_id' ipsecpolicy_id = 'ipsecpolicy_id' local_ep_group = 'local-epg' peer_ep_group = 'peer-epg' admin_state = True args = ['--tenant-id', tenant_id, '--peer-address', peer_address, '--peer-id', peer_id, '--psk', psk, '--vpnservice-id', vpnservice_id, '--ikepolicy-id', ikepolicy_id, '--ipsecpolicy-id', ipsecpolicy_id, '--local-ep-group', local_ep_group, '--peer-ep-group', peer_ep_group] position_names = ['tenant_id', 'admin_state_up', 'peer_address', 'peer_id', 'local_ep_group_id', 'peer_ep_group_id', 'psk', 'mtu', 'initiator', 'vpnservice_id', 'ikepolicy_id', 'ipsecpolicy_id'] position_values = [tenant_id, admin_state, peer_address, peer_id, local_ep_group, peer_ep_group, psk, mtu, initiator, vpnservice_id, ikepolicy_id, ipsecpolicy_id] self._test_create_resource(resource, cmd, None, my_id, args, position_names, position_values) def _test_create_failure(self, additional_args=None, expected_exc=None): # Helper to test failure of IPSec site-to-site creation failure. resource = 'ipsec_site_connection' cmd = ipsec_site_connection.CreateIPsecSiteConnection( test_cli20.MyApp(sys.stdout), None ) tenant_id = 'mytenant_id' my_id = 'my_id' peer_address = '192.168.2.10' peer_id = '192.168.2.10' psk = 'abcd' mtu = '1500' initiator = 'bi-directional' vpnservice_id = 'vpnservice_id' ikepolicy_id = 'ikepolicy_id' ipsecpolicy_id = 'ipsecpolicy_id' admin_state = True args = ['--tenant-id', tenant_id, '--peer-address', peer_address, '--peer-id', peer_id, '--psk', psk, '--vpnservice-id', vpnservice_id, '--ikepolicy-id', ikepolicy_id, '--ipsecpolicy-id', ipsecpolicy_id] if additional_args is not None: args += additional_args position_names = ['tenant_id', 'admin_state_up', 'peer_address', 'peer_id', 'psk', 'mtu', 'initiator', 'local_ep_group_id', 'peer_ep_group_id', 'vpnservice_id', 'ikepolicy_id', 'ipsecpolicy_id'] position_values = [tenant_id, admin_state, peer_address, peer_id, psk, mtu, initiator, None, None, vpnservice_id, ikepolicy_id, ipsecpolicy_id] if not expected_exc: expected_exc = exceptions.CommandError self.assertRaises(expected_exc, self._test_create_resource, resource, cmd, None, my_id, args, position_names, position_values) def test_fail_create_with_invalid_mtu(self): # ipsecsite-connection-create with invalid dpd values. bad_mtu = ['--mtu', '67'] self._test_create_failure(bad_mtu) def test_fail_create_with_invalid_dpd_keys(self): bad_dpd_key = ['--dpd', 'act=restart,interval=30,time=120'] self._test_create_failure(bad_dpd_key, SystemExit) def test_fail_create_with_invalid_dpd_values(self): bad_dpd_values = ['--dpd', 'action=hold,interval=30,timeout=-1'] self._test_create_failure(bad_dpd_values) def test_fail_create_missing_endpoint_groups_or_cidr(self): # Must provide either endpoint groups or peer cidrs. self._test_create_failure() def test_fail_create_missing_peer_endpoint_group(self): # Fails if dont have both endpoint groups - missing peer. self._test_create_failure(['--local-ep-group', 'local-epg']) def test_fail_create_missing_local_endpoint_group(self): # Fails if dont have both endpoint groups - missing local. self._test_create_failure(['--peer-ep-group', 'peer-epg']) def test_fail_create_when_both_endpoints_and_peer_cidr(self): # Cannot intermix endpoint groups and peer CIDRs for create. additional_args = ['--local-ep-group', 'local-epg', '--peer-ep-group', 'peer-epg', '--peer-cidr', '10.2.0.0/24'] self._test_create_failure(additional_args) def test_list_ipsec_site_connection(self): # ipsecsite-connection-list. resources = "ipsec_site_connections" cmd = ipsec_site_connection.ListIPsecSiteConnection( test_cli20.MyApp(sys.stdout), None ) self._test_list_resources(resources, cmd, True) def test_list_ipsec_site_connection_pagination(self): # ipsecsite-connection-list. resources = "ipsec_site_connections" cmd = ipsec_site_connection.ListIPsecSiteConnection( test_cli20.MyApp(sys.stdout), None ) self._test_list_resources_with_pagination(resources, cmd) def test_list_ipsec_site_connection_sort(self): # ipsecsite-connection-list. # --sort-key name --sort-key id --sort-key asc --sort-key desc resources = "ipsec_site_connections" cmd = ipsec_site_connection.ListIPsecSiteConnection( test_cli20.MyApp(sys.stdout), None ) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_ipsec_site_connection_limit(self): # ipsecsite-connection-list -P. resources = "ipsec_site_connections" cmd = ipsec_site_connection.ListIPsecSiteConnection( test_cli20.MyApp(sys.stdout), None ) self._test_list_resources(resources, cmd, page_size=1000) def test_delete_ipsec_site_connection(self): # ipsecsite-connection-delete my-id. resource = 'ipsec_site_connection' cmd = ipsec_site_connection.DeleteIPsecSiteConnection( test_cli20.MyApp(sys.stdout), None ) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) def test_update_ipsec_site_connection(self): # ipsecsite-connection-update myid --name Branch-new --tags a b. resource = 'ipsec_site_connection' cmd = ipsec_site_connection.UpdateIPsecSiteConnection( test_cli20.MyApp(sys.stdout), None ) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'Branch-new', '--tags', 'a', 'b'], {'name': 'Branch-new', 'tags': ['a', 'b'], }) # ipsecsite-connection-update myid --mtu 69 --initiator response-only # --peer-id '192.168.2.11' --peer-ep-group 'update-grp' self._test_update_resource(resource, cmd, 'myid', ['myid', '--mtu', '69', '--initiator', 'response-only', '--peer-id', '192.168.2.11', '--peer-ep-group', 'update-grp'], {'mtu': '69', 'initiator': 'response-only', 'peer_id': '192.168.2.11', 'peer_ep_group_id': 'update-grp', },) def test_show_ipsec_site_connection_id(self): # ipsecsite-connection-show test_id.""" resource = 'ipsec_site_connection' cmd = ipsec_site_connection.ShowIPsecSiteConnection( 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_ipsec_site_connection_id_name(self): # ipsecsite-connection-show.""" resource = 'ipsec_site_connection' cmd = ipsec_site_connection.ShowIPsecSiteConnection( 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']) python-neutronclient-6.7.0/neutronclient/tests/unit/vpn/test_cli20_vpnservice.py0000666000175100017510000001401013232473350030363 0ustar zuulzuul00000000000000# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.vpn import vpnservice from neutronclient.tests.unit import test_cli20 class CLITestV20VpnServiceJSON(test_cli20.CLITestV20Base): def test_create_vpnservice_all_params(self): # vpn-service-create all params. resource = 'vpnservice' cmd = vpnservice.CreateVPNService(test_cli20.MyApp(sys.stdout), None) subnet = 'mysubnet-id' router = 'myrouter-id' tenant_id = 'mytenant-id' my_id = 'my-id' name = 'myvpnservice' description = 'my-vpn-service' admin_state = True args = ['--name', name, '--description', description, router, subnet, '--tenant-id', tenant_id] position_names = ['admin_state_up', 'name', 'description', 'subnet_id', 'router_id', 'tenant_id'] position_values = [admin_state, name, description, subnet, router, tenant_id] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values) def test_create_vpnservice_with_limited_params(self): # vpn-service-create with limited params. resource = 'vpnservice' cmd = vpnservice.CreateVPNService(test_cli20.MyApp(sys.stdout), None) subnet = 'mysubnet-id' router = 'myrouter-id' tenant_id = 'mytenant-id' my_id = 'my-id' admin_state = True args = [router, subnet, '--tenant-id', tenant_id] position_names = ['admin_state_up', 'subnet_id', 'router_id', 'tenant_id'] position_values = [admin_state, subnet, router, tenant_id] self._test_create_resource(resource, cmd, None, my_id, args, position_names, position_values) def test_create_vpnservice_without_subnet(self): # vpn-service-create with no subnet provided. resource = 'vpnservice' cmd = vpnservice.CreateVPNService(test_cli20.MyApp(sys.stdout), None) router = 'myrouter-id' tenant_id = 'mytenant-id' my_id = 'my-id' admin_state = True args = [router, '--tenant-id', tenant_id] position_names = ['admin_state_up', 'subnet_id', 'router_id', 'tenant_id'] position_values = [admin_state, None, router, tenant_id] self._test_create_resource(resource, cmd, None, my_id, args, position_names, position_values) def test_list_vpnservice(self): # vpn-service-list. resources = "vpnservices" cmd = vpnservice.ListVPNService(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_vpnservice_pagination(self): # vpn-service-list. resources = "vpnservices" cmd = vpnservice.ListVPNService(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_vpnservice_sort(self): # vpn-service-list --sort-key name --sort-key id --sort-key asc # --sort-key desc resources = "vpnservices" cmd = vpnservice.ListVPNService(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_vpnservice_limit(self): # vpn-service-list -P. resources = "vpnservices" cmd = vpnservice.ListVPNService(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_vpnservice_id(self): # vpn-service-show test_id. resource = 'vpnservice' cmd = vpnservice.ShowVPNService(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_vpnservice_id_name(self): # vpn-service-show.""" resource = 'vpnservice' cmd = vpnservice.ShowVPNService(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_vpnservice(self): # vpn-service-update myid --name newname --tags a b. resource = 'vpnservice' cmd = vpnservice.UpdateVPNService(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'newname'], {'name': 'newname', }) # vpn-service-update myid --admin-state-up False self._test_update_resource(resource, cmd, 'myid', ['myid', '--admin-state-up', 'False'], {'admin_state_up': 'False', }) def test_delete_vpnservice(self): # vpn-service-delete my-id. resource = 'vpnservice' cmd = vpnservice.DeleteVPNService(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) python-neutronclient-6.7.0/neutronclient/tests/unit/vpn/test_cli20_ikepolicy.py0000666000175100017510000002265713232473350030207 0ustar zuulzuul00000000000000# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.common import exceptions from neutronclient.neutron.v2_0.vpn import ikepolicy from neutronclient.tests.unit import test_cli20 class CLITestV20VpnIkePolicyJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['ikepolicy'] def _test_create_ikepolicy_all_params(self, auth='sha1', expected_exc=None): # vpn-ikepolicy-create all params. resource = 'ikepolicy' cmd = ikepolicy.CreateIKEPolicy(test_cli20.MyApp(sys.stdout), None) name = 'ikepolicy1' description = 'my-ike-policy' auth_algorithm = auth encryption_algorithm = 'aes-256' ike_version = 'v1' phase1_negotiation_mode = 'main' pfs = 'group5' tenant_id = 'my-tenant' my_id = 'my-id' lifetime = 'units=seconds,value=20000' args = [name, '--description', description, '--tenant-id', tenant_id, '--auth-algorithm', auth_algorithm, '--encryption-algorithm', encryption_algorithm, '--ike-version', ike_version, '--phase1-negotiation-mode', phase1_negotiation_mode, '--lifetime', lifetime, '--pfs', pfs] position_names = ['name', 'description', 'auth_algorithm', 'encryption_algorithm', 'phase1_negotiation_mode', 'ike_version', 'pfs', 'tenant_id'] position_values = [name, description, auth_algorithm, encryption_algorithm, phase1_negotiation_mode, ike_version, pfs, tenant_id] extra_body = { 'lifetime': { 'units': 'seconds', 'value': 20000, }, } if not expected_exc: self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, extra_body=extra_body) else: self.assertRaises( expected_exc, self._test_create_resource, resource, cmd, name, my_id, args, position_names, position_values, extra_body=extra_body) def test_create_ikepolicy_all_params(self): self._test_create_ikepolicy_all_params() def test_create_ikepolicy_auth_sha256(self): self._test_create_ikepolicy_all_params(auth='sha256') def test_create_ikepolicy_auth_sha384(self): self._test_create_ikepolicy_all_params(auth='sha384') def test_create_ikepolicy_auth_sha512(self): self._test_create_ikepolicy_all_params(auth='sha512') def test_create_ikepolicy_invalid_auth(self): self._test_create_ikepolicy_all_params(auth='invalid', expected_exc=SystemExit) def test_create_ikepolicy_with_limited_params(self): # vpn-ikepolicy-create with limited params. resource = 'ikepolicy' cmd = ikepolicy.CreateIKEPolicy(test_cli20.MyApp(sys.stdout), None) name = 'ikepolicy1' auth_algorithm = 'sha1' encryption_algorithm = 'aes-128' ike_version = 'v1' phase1_negotiation_mode = 'main' pfs = 'group5' tenant_id = 'my-tenant' my_id = 'my-id' args = [name, '--tenant-id', tenant_id] position_names = ['name', 'auth_algorithm', 'encryption_algorithm', 'phase1_negotiation_mode', 'ike_version', 'pfs', 'tenant_id'] position_values = [name, auth_algorithm, encryption_algorithm, phase1_negotiation_mode, ike_version, pfs, tenant_id] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values) def _test_lifetime_values(self, lifetime, expected_exc=None): resource = 'ikepolicy' cmd = ikepolicy.CreateIKEPolicy(test_cli20.MyApp(sys.stdout), None) name = 'ikepolicy1' description = 'my-ike-policy' auth_algorithm = 'sha1' encryption_algorithm = 'aes-256' ike_version = 'v1' phase1_negotiation_mode = 'main' pfs = 'group5' tenant_id = 'my-tenant' my_id = 'my-id' args = [name, '--description', description, '--tenant-id', tenant_id, '--auth-algorithm', auth_algorithm, '--encryption-algorithm', encryption_algorithm, '--ike-version', ike_version, '--phase1-negotiation-mode', phase1_negotiation_mode, '--lifetime', lifetime, '--pfs', pfs] position_names = ['name', 'description', 'auth_algorithm', 'encryption_algorithm', 'phase1_negotiation_mode', 'ike_version', 'pfs', 'tenant_id'] position_values = [name, description, auth_algorithm, encryption_algorithm, phase1_negotiation_mode, ike_version, pfs, tenant_id] if not expected_exc: expected_exc = exceptions.CommandError self.assertRaises( expected_exc, self._test_create_resource, resource, cmd, name, my_id, args, position_names, position_values) def test_create_ikepolicy_with_invalid_lifetime_keys(self): lifetime = 'uts=seconds,val=20000' self._test_lifetime_values(lifetime, expected_exc=SystemExit) def test_create_ikepolicy_with_invalid_lifetime_value(self): lifetime = 'units=seconds,value=-1' self._test_lifetime_values(lifetime) def test_list_ikepolicy(self): # vpn-ikepolicy-list. resources = "ikepolicies" cmd = ikepolicy.ListIKEPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_ikepolicy_pagination(self): # vpn-ikepolicy-list. resources = "ikepolicies" cmd = ikepolicy.ListIKEPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_ikepolicy_sort(self): # vpn-ikepolicy-list --sort-key name --sort-key id --sort-key asc # --sort-key desc resources = "ikepolicies" cmd = ikepolicy.ListIKEPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_ikepolicy_limit(self): # vpn-ikepolicy-list -P. resources = "ikepolicies" cmd = ikepolicy.ListIKEPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_ikepolicy_id(self): # vpn-ikepolicy-show ikepolicy_id. resource = 'ikepolicy' cmd = ikepolicy.ShowIKEPolicy(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_ikepolicy_id_name(self): # vpn-ikepolicy-show. resource = 'ikepolicy' cmd = ikepolicy.ShowIKEPolicy(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_ikepolicy(self): # vpn-ikepolicy-update myid --name newname --tags a b. resource = 'ikepolicy' cmd = ikepolicy.UpdateIKEPolicy(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'newname'], {'name': 'newname', }) # vpn-ikepolicy-update myid --pfs group2 --ike-version v2. self._test_update_resource(resource, cmd, 'myid', ['myid', '--pfs', 'group2', '--ike-version', 'v2'], {'pfs': 'group2', 'ike_version': 'v2'}) def test_delete_ikepolicy(self): # vpn-ikepolicy-delete my-id. resource = 'ikepolicy' cmd = ikepolicy.DeleteIKEPolicy(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) python-neutronclient-6.7.0/neutronclient/tests/unit/vpn/test_utils.py0000666000175100017510000001361113232473350026354 0ustar zuulzuul00000000000000# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import testtools from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron.v2_0.vpn import utils as vpn_utils class TestVPNUtils(testtools.TestCase): def test_validate_lifetime_dictionary_seconds(self): input_str = utils.str2dict("units=seconds,value=3600") self.assertIsNone(vpn_utils.validate_lifetime_dict(input_str)) def test_validate_dpd_dictionary_action_hold(self): input_str = utils.str2dict("action=hold,interval=30,timeout=120") self.assertIsNone(vpn_utils.validate_dpd_dict(input_str)) def test_validate_dpd_dictionary_action_restart(self): input_str = utils.str2dict("action=restart,interval=30,timeout=120") self.assertIsNone(vpn_utils.validate_dpd_dict(input_str)) def test_validate_dpd_dictionary_action_restart_by_peer(self): input_str = utils.str2dict( "action=restart-by-peer,interval=30,timeout=120" ) self.assertIsNone(vpn_utils.validate_dpd_dict(input_str)) def test_validate_dpd_dictionary_action_clear(self): input_str = utils.str2dict('action=clear,interval=30,timeout=120') self.assertIsNone(vpn_utils.validate_dpd_dict(input_str)) def test_validate_dpd_dictionary_action_disabled(self): input_str = utils.str2dict('action=disabled,interval=30,timeout=120') self.assertIsNone(vpn_utils.validate_dpd_dict(input_str)) def test_validate_lifetime_dictionary_invalid_unit_key(self): input_str = utils.str2dict('ut=seconds,value=3600') self._test_validate_lifetime_negative_test_case(input_str) def test_validate_lifetime_dictionary_invalid_unit_key_value(self): input_str = utils.str2dict('units=seconds,val=3600') self._test_validate_lifetime_negative_test_case(input_str) def test_validate_lifetime_dictionary_unsupported_units(self): input_str = utils.str2dict('units=minutes,value=3600') self._test_validate_lifetime_negative_test_case(input_str) def test_validate_lifetime_dictionary_invalid_empty_unit(self): input_str = utils.str2dict('units=,value=3600') self._test_validate_lifetime_negative_test_case(input_str) def test_validate_lifetime_dictionary_under_minimum_integer_value(self): input_str = utils.str2dict('units=seconds,value=59') self._test_validate_lifetime_negative_test_case(input_str) def test_validate_lifetime_dictionary_negative_integer_value(self): input_str = utils.str2dict('units=seconds,value=-1') self._test_validate_lifetime_negative_test_case(input_str) def test_validate_lifetime_dictionary_empty_value(self): input_str = utils.str2dict('units=seconds,value=') self._test_validate_lifetime_negative_test_case(input_str) def test_validate_dpd_dictionary_invalid_key_action(self): input_str = utils.str2dict('act=hold,interval=30,timeout=120') self._test_validate_dpd_negative_test_case(input_str) def test_validate_dpd_dictionary_invalid_key_interval(self): input_str = utils.str2dict('action=hold,int=30,timeout=120') self._test_validate_dpd_negative_test_case(input_str) def test_validate_dpd_dictionary_invalid_key_timeout(self): input_str = utils.str2dict('action=hold,interval=30,tiut=120') self._test_validate_dpd_negative_test_case(input_str) def test_validate_dpd_dictionary_unsupported_action(self): input_str = utils.str2dict('action=bye-bye,interval=30,timeout=120') self._test_validate_dpd_negative_test_case(input_str) def test_validate_dpd_dictionary_empty_action(self): input_str = utils.str2dict('action=,interval=30,timeout=120') self._test_validate_dpd_negative_test_case(input_str) def test_validate_dpd_dictionary_empty_interval(self): input_str = utils.str2dict('action=hold,interval=,timeout=120') self._test_validate_dpd_negative_test_case(input_str) def test_validate_dpd_dictionary_negative_interval_value(self): input_str = utils.str2dict('action=hold,interval=-1,timeout=120') self._test_validate_lifetime_negative_test_case(input_str) def test_validate_dpd_dictionary_zero_timeout(self): input_str = utils.str2dict('action=hold,interval=30,timeout=0') self._test_validate_dpd_negative_test_case(input_str) def test_validate_dpd_dictionary_empty_timeout(self): input_str = utils.str2dict('action=hold,interval=30,timeout=') self._test_validate_dpd_negative_test_case(input_str) def test_validate_dpd_dictionary_negative_timeout_value(self): input_str = utils.str2dict('action=hold,interval=30,timeout=-1') self._test_validate_lifetime_negative_test_case(input_str) def _test_validate_lifetime_negative_test_case(self, input_str): """Generic handler for negative lifetime tests.""" self.assertRaises(exceptions.CommandError, vpn_utils.validate_lifetime_dict, (input_str)) def _test_validate_dpd_negative_test_case(self, input_str): """Generic handler for negative lifetime tests.""" self.assertRaises(exceptions.CommandError, vpn_utils.validate_lifetime_dict, (input_str)) python-neutronclient-6.7.0/neutronclient/tests/unit/vpn/test_cli20_ipsecpolicy.py0000666000175100017510000002405713232473350030536 0ustar zuulzuul00000000000000# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.common import exceptions from neutronclient.neutron.v2_0.vpn import ipsecpolicy from neutronclient.tests.unit import test_cli20 class CLITestV20VpnIpsecPolicyJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['ipsecpolicy'] def _test_create_ipsecpolicy_all_params(self, auth='sha1', expected_exc=None): # vpn-ipsecpolicy-create all params with dashes. resource = 'ipsecpolicy' cmd = ipsecpolicy.CreateIPsecPolicy(test_cli20.MyApp(sys.stdout), None) name = 'ipsecpolicy1' description = 'first-ipsecpolicy1' auth_algorithm = auth encryption_algorithm = 'aes-256' encapsulation_mode = 'tunnel' pfs = 'group5' transform_protocol = 'ah' tenant_id = 'my-tenant' my_id = 'my-id' lifetime = 'units=seconds,value=20000' args = [name, '--description', description, '--tenant-id', tenant_id, '--auth-algorithm', auth_algorithm, '--encryption-algorithm', encryption_algorithm, '--transform-protocol', transform_protocol, '--encapsulation-mode', encapsulation_mode, '--lifetime', lifetime, '--pfs', pfs] position_names = ['name', 'auth_algorithm', 'encryption_algorithm', 'encapsulation_mode', 'description', 'transform_protocol', 'pfs', 'tenant_id'] position_values = [name, auth_algorithm, encryption_algorithm, encapsulation_mode, description, transform_protocol, pfs, tenant_id] extra_body = { 'lifetime': { 'units': 'seconds', 'value': 20000, }, } if not expected_exc: self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values, extra_body=extra_body) else: self.assertRaises( expected_exc, self._test_create_resource, resource, cmd, name, my_id, args, position_names, position_values, extra_body=extra_body) def test_create_ipsecpolicy_all_params(self): self._test_create_ipsecpolicy_all_params() def test_create_ipsecpolicy_auth_sha256(self): self._test_create_ipsecpolicy_all_params(auth='sha256') def test_create_ipsecpolicy_auth_sha384(self): self._test_create_ipsecpolicy_all_params(auth='sha384') def test_create_ipsecpolicy_auth_sha512(self): self._test_create_ipsecpolicy_all_params(auth='sha512') def test_create_ipsecpolicy_invalid_auth(self): self._test_create_ipsecpolicy_all_params(auth='invalid', expected_exc=SystemExit) def test_create_ipsecpolicy_with_limited_params(self): # vpn-ipsecpolicy-create with limited params. resource = 'ipsecpolicy' cmd = ipsecpolicy.CreateIPsecPolicy(test_cli20.MyApp(sys.stdout), None) name = 'ipsecpolicy1' auth_algorithm = 'sha1' encryption_algorithm = 'aes-128' encapsulation_mode = 'tunnel' pfs = 'group5' transform_protocol = 'esp' tenant_id = 'my-tenant' my_id = 'my-id' args = [name, '--tenant-id', tenant_id] position_names = ['name', 'auth_algorithm', 'encryption_algorithm', 'encapsulation_mode', 'transform_protocol', 'pfs', 'tenant_id'] position_values = [name, auth_algorithm, encryption_algorithm, encapsulation_mode, transform_protocol, pfs, tenant_id] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values) def _test_lifetime_values(self, lifetime, expected_exc=None): resource = 'ipsecpolicy' cmd = ipsecpolicy.CreateIPsecPolicy(test_cli20.MyApp(sys.stdout), None) name = 'ipsecpolicy1' description = 'my-ipsec-policy' auth_algorithm = 'sha1' encryption_algorithm = 'aes-256' ike_version = 'v1' phase1_negotiation_mode = 'main' pfs = 'group5' tenant_id = 'my-tenant' my_id = 'my-id' args = [name, '--description', description, '--tenant-id', tenant_id, '--auth-algorithm', auth_algorithm, '--encryption-algorithm', encryption_algorithm, '--ike-version', ike_version, '--phase1-negotiation-mode', phase1_negotiation_mode, '--lifetime', lifetime, '--pfs', pfs] position_names = ['name', 'description', 'auth_algorithm', 'encryption_algorithm', 'phase1_negotiation_mode', 'ike_version', 'pfs', 'tenant_id'] position_values = [name, description, auth_algorithm, encryption_algorithm, phase1_negotiation_mode, ike_version, pfs, tenant_id] if not expected_exc: expected_exc = exceptions.CommandError self.assertRaises( expected_exc, self._test_create_resource, resource, cmd, name, my_id, args, position_names, position_values) def test_create_ipsecpolicy_with_invalid_lifetime_keys(self): lifetime = 'uts=seconds,val=20000' self._test_lifetime_values(lifetime, SystemExit) def test_create_ipsecpolicy_with_invalid_lifetime_units(self): lifetime = 'units=minutes,value=600' self._test_lifetime_values(lifetime) def test_create_ipsecpolicy_with_invalid_lifetime_value(self): lifetime = 'units=seconds,value=0' self._test_lifetime_values(lifetime) def test_list_ipsecpolicy(self): # vpn-ipsecpolicy-list. resources = "ipsecpolicies" cmd = ipsecpolicy.ListIPsecPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_ipsecpolicy_pagination(self): # vpn-ipsecpolicy-list. resources = "ipsecpolicies" cmd = ipsecpolicy.ListIPsecPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_ipsecpolicy_sort(self): # vpn-ipsecpolicy-list --sort-key name --sort-key id --sort-key asc # --sort-key desc resources = "ipsecpolicies" cmd = ipsecpolicy.ListIPsecPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_ipsecpolicy_limit(self): # vpn-ipsecpolicy-list -P. resources = "ipsecpolicies" cmd = ipsecpolicy.ListIPsecPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_ipsecpolicy_id(self): # vpn-ipsecpolicy-show ipsecpolicy_id. resource = 'ipsecpolicy' cmd = ipsecpolicy.ShowIPsecPolicy(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_ipsecpolicy_id_name(self): # vpn-ipsecpolicy-show. resource = 'ipsecpolicy' cmd = ipsecpolicy.ShowIPsecPolicy(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_ipsecpolicy_name(self): # vpn-ipsecpolicy-update myid --name newname --tags a b. resource = 'ipsecpolicy' cmd = ipsecpolicy.UpdateIPsecPolicy(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'newname'], {'name': 'newname', }) def test_update_ipsecpolicy_other_params(self): # vpn-ipsecpolicy-update myid --transform-protocol esp # --pfs group14 --encapsulation-mode transport resource = 'ipsecpolicy' cmd = ipsecpolicy.UpdateIPsecPolicy(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--transform-protocol', 'esp', '--pfs', 'group14', '--encapsulation-mode', 'transport'], {'transform_protocol': 'esp', 'pfs': 'group14', 'encapsulation_mode': 'transport', }) def test_delete_ipsecpolicy(self): # vpn-ipsecpolicy-delete my-id. resource = 'ipsecpolicy' cmd = ipsecpolicy.DeleteIPsecPolicy(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) python-neutronclient-6.7.0/neutronclient/tests/unit/vpn/test_cli20_endpoint_group.py0000666000175100017510000001373613232473350031251 0ustar zuulzuul00000000000000# (c) Copyright 2015 Cisco Systems, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.vpn import endpoint_group from neutronclient.tests.unit import test_cli20 class CLITestV20VpnEndpointGroupJSON(test_cli20.CLITestV20Base): def setUp(self): super(CLITestV20VpnEndpointGroupJSON, self).setUp() self.register_non_admin_status_resource('endpoint_group') def test_create_endpoint_group_with_cidrs(self): # vpn-endpoint-group-create with CIDR endpoints.""" resource = 'endpoint_group' cmd = endpoint_group.CreateEndpointGroup(test_cli20.MyApp(sys.stdout), None) tenant_id = 'mytenant-id' my_id = 'my-id' name = 'my-endpoint-group' description = 'my endpoint group' endpoint_type = 'cidr' endpoints = ['10.0.0.0/24', '20.0.0.0/24'] args = ['--name', name, '--description', description, '--tenant-id', tenant_id, '--type', endpoint_type, '--value', '10.0.0.0/24', '--value', '20.0.0.0/24'] position_names = ['name', 'description', 'tenant_id', 'type', 'endpoints'] position_values = [name, description, tenant_id, endpoint_type, endpoints] self._test_create_resource(resource, cmd, name, my_id, args, position_names, position_values) def test_create_endpoint_group_with_subnets(self): # vpn-endpoint-group-create with subnet endpoints.""" resource = 'endpoint_group' cmd = endpoint_group.CreateEndpointGroup(test_cli20.MyApp(sys.stdout), None) tenant_id = 'mytenant-id' my_id = 'my-id' endpoint_type = 'subnet' subnet = 'subnet-id' endpoints = [subnet] args = ['--type', endpoint_type, '--value', subnet, '--tenant-id', tenant_id] position_names = ['type', 'endpoints', 'tenant_id'] position_values = [endpoint_type, endpoints, tenant_id] self._test_create_resource(resource, cmd, None, my_id, args, position_names, position_values) def test_list_endpoint_group(self): # vpn-endpoint-group-list. resources = "endpoint_groups" cmd = endpoint_group.ListEndpointGroup(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_endpoint_group_pagination(self): # vpn-endpoint-group-list. resources = "endpoint_groups" cmd = endpoint_group.ListEndpointGroup(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_endpoint_group_sort(self): # vpn-endpoint-group-list --sort-key name --sort-key id # --sort-key asc --sort-key desc resources = "endpoint_groups" cmd = endpoint_group.ListEndpointGroup(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_endpoint_group_limit(self): # vpn-endpoint-group-list -P. resources = "endpoint_groups" cmd = endpoint_group.ListEndpointGroup(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_endpoint_group_id(self): # vpn-endpoint-group-show test_id. resource = 'endpoint_group' cmd = endpoint_group.ShowEndpointGroup(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_endpoint_group_id_name(self): # vpn-endpoint-group-show. resource = 'endpoint_group' cmd = endpoint_group.ShowEndpointGroup(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_endpoint_group(self): # vpn-endpoint-group-update myid --name newname --description newdesc. resource = 'endpoint_group' cmd = endpoint_group.UpdateEndpointGroup(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'newname', '--description', 'newdesc'], {'name': 'newname', 'description': 'newdesc'}) def test_delete_endpoint_group(self): # vpn-endpoint-group-delete my-id. resource = 'endpoint_group' cmd = endpoint_group.DeleteEndpointGroup(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) python-neutronclient-6.7.0/neutronclient/tests/unit/vpn/__init__.py0000666000175100017510000000000013232473350025700 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/test_validators.py0000666000175100017510000001000513232473350026553 0ustar zuulzuul00000000000000# Copyright 2014 NEC Corporation # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import testtools from neutronclient.common import exceptions from neutronclient.common import validators class FakeParsedArgs(object): pass class ValidatorTest(testtools.TestCase): def _test_validate_int(self, attr_val, attr_name='attr1', min_value=1, max_value=10): obj = FakeParsedArgs() setattr(obj, attr_name, attr_val) ret = validators.validate_int_range(obj, attr_name, min_value, max_value) # Come here only if there is no exception. self.assertIsNone(ret) def _test_validate_int_error(self, attr_val, expected_msg, attr_name='attr1', expected_exc=None, min_value=1, max_value=10): if expected_exc is None: expected_exc = exceptions.CommandError e = self.assertRaises(expected_exc, self._test_validate_int, attr_val, attr_name, min_value, max_value) self.assertEqual(expected_msg, str(e)) def test_validate_int_min_max(self): self._test_validate_int(1) self._test_validate_int(10) self._test_validate_int('1') self._test_validate_int('10') self._test_validate_int('0x0a') self._test_validate_int_error( 0, 'attr1 "0" should be an integer [1:10].') self._test_validate_int_error( 11, 'attr1 "11" should be an integer [1:10].') self._test_validate_int_error( '0x10', 'attr1 "0x10" should be an integer [1:10].') def test_validate_int_min_only(self): self._test_validate_int(1, max_value=None) self._test_validate_int(10, max_value=None) self._test_validate_int(11, max_value=None) self._test_validate_int_error( 0, 'attr1 "0" should be an integer greater than or equal to 1.', max_value=None) def test_validate_int_max_only(self): self._test_validate_int(0, min_value=None) self._test_validate_int(1, min_value=None) self._test_validate_int(10, min_value=None) self._test_validate_int_error( 11, 'attr1 "11" should be an integer smaller than or equal to 10.', min_value=None) def test_validate_int_no_limit(self): self._test_validate_int(0, min_value=None, max_value=None) self._test_validate_int(1, min_value=None, max_value=None) self._test_validate_int(10, min_value=None, max_value=None) self._test_validate_int(11, min_value=None, max_value=None) self._test_validate_int_error( 'abc', 'attr1 "abc" should be an integer.', min_value=None, max_value=None) def _test_validate_subnet(self, attr_val, attr_name='attr1'): obj = FakeParsedArgs() setattr(obj, attr_name, attr_val) ret = validators.validate_ip_subnet(obj, attr_name) # Come here only if there is no exception. self.assertIsNone(ret) def test_validate_ip_subnet(self): self._test_validate_subnet('192.168.2.0/24') self._test_validate_subnet('192.168.2.3/20') self._test_validate_subnet('192.168.2.1') e = self.assertRaises(exceptions.CommandError, self._test_validate_subnet, '192.168.2.256') self.assertEqual('attr1 "192.168.2.256" is not a valid CIDR.', str(e)) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_rbac.py0000666000175100017510000001317313232473350026314 0ustar zuulzuul00000000000000# Copyright 2015 Huawei Technologies India Pvt Ltd. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sys import testscenarios from neutronclient.neutron.v2_0 import rbac from neutronclient.tests.unit import test_cli20 load_tests = testscenarios.load_tests_apply_scenarios class CLITestV20RBACBaseJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['rbac_policy'] scenarios = [ ('network rbac objects', {'object_type_name': 'network', 'object_type_val': 'network'}), ('qos policy rbac objects', {'object_type_name': 'qos-policy', 'object_type_val': 'qos_policy'}), ] def test_create_rbac_policy_with_mandatory_params(self): # Create rbac: rbac_object --type --action # access_as_shared resource = 'rbac_policy' cmd = rbac.CreateRBACPolicy(test_cli20.MyApp(sys.stdout), None) name = 'rbac_object' myid = 'myid' args = [name, '--type', self.object_type_name, '--action', 'access_as_shared'] position_names = ['object_id', 'object_type', 'target_tenant', 'action'] position_values = [name, self.object_type_val, '*', 'access_as_shared'] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_rbac_policy_with_all_params(self): # Create rbac: rbac_object --type # --target-tenant tenant_id --action access_as_external resource = 'rbac_policy' cmd = rbac.CreateRBACPolicy(test_cli20.MyApp(sys.stdout), None) name = 'rbac_object' myid = 'myid' args = [name, '--type', self.object_type_name, '--target-tenant', 'tenant_id', '--action', 'access_as_external'] position_names = ['object_id', 'object_type', 'target_tenant', 'action'] position_values = [name, self.object_type_val, 'tenant_id', 'access_as_external'] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_rbac_policy_with_unicode(self): # Create rbac policy u'\u7f51\u7edc'. resource = 'rbac_policy' cmd = rbac.CreateRBACPolicy(test_cli20.MyApp(sys.stdout), None) name = u'\u7f51\u7edc' myid = 'myid' args = [name, '--type', self.object_type_name, '--target-tenant', 'tenant_id', '--action', 'access_as_external'] position_names = ['object_id', 'object_type', 'target_tenant', 'action'] position_values = [name, self.object_type_val, 'tenant_id', 'access_as_external'] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_update_rbac_policy(self): # rbac-update --target-tenant . resource = 'rbac_policy' cmd = rbac.UpdateRBACPolicy(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--target-tenant', 'tenant_id'], {'target_tenant': 'tenant_id', }) def test_delete_rbac_policy(self): # rbac-delete my-id. resource = 'rbac_policy' cmd = rbac.DeleteRBACPolicy(test_cli20.MyApp(sys.stdout), None) my_id = 'myid1' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) def test_list_rbac_policies(self): # rbac-list. resources = "rbac_policies" cmd = rbac.ListRBACPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_rbac_policies_pagination(self): # rbac-list with pagination. resources = "rbac_policies" cmd = rbac.ListRBACPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_rbac_policies_sort(self): # sorted list: # rbac-list --sort-key name --sort-key id --sort-key asc # --sort-key desc resources = "rbac_policies" cmd = rbac.ListRBACPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_rbac_policies_limit(self): # size (1000) limited list: rbac-list -P. resources = "rbac_policies" cmd = rbac.ListRBACPolicy(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_rbac_policy(self): # rbac-show test_id. resource = 'rbac_policy' cmd = rbac.ShowRBACPolicy(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id']) python-neutronclient-6.7.0/neutronclient/tests/unit/flavor/0000775000175100017510000000000013232473710024265 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/flavor/test_cli20_flavor.py0000666000175100017510000001402613232473350030165 0ustar zuulzuul00000000000000# Copyright 2015 Hewlett-Packard Development Company, L.P. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.flavor import flavor from neutronclient.tests.unit import test_cli20 class CLITestV20FlavorJSON(test_cli20.CLITestV20Base): def setUp(self): """Prepare test environment.""" super(CLITestV20FlavorJSON, self).setUp(plurals={'flavors': 'flavor'}) self.register_non_admin_status_resource('flavor') self.register_non_admin_status_resource('service_profile') def test_create_flavor_with_missing_params(self): """Create test flavor with missing parameters.""" resource = 'flavor' cmd = flavor.CreateFlavor( test_cli20.MyApp(sys.stdout), None) name = 'Test flavor' myid = 'myid' position_names = [] position_values = [] args = [] self.assertRaises( SystemExit, self._test_create_resource, resource, cmd, name, myid, args, position_names, position_values) def test_create_flavor_with_mandatory_params(self): """Create test flavor with minimal parameters.""" resource = 'flavor' cmd = flavor.CreateFlavor( test_cli20.MyApp(sys.stdout), None) name = 'Test flavor' myid = 'myid' service_type = 'DUMMY' # Defaults are returned in body position_names = ['name', 'service_type'] position_values = [name, service_type] args = [name, service_type] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_flavor_with_optional_params(self): """Create test flavor including optional parameters.""" resource = 'flavor' cmd = flavor.CreateFlavor( test_cli20.MyApp(sys.stdout), None) name = 'Test flavor' myid = 'myid' service_type = 'DUMMY' description = 'Test description' position_names = ['name', 'service_type', 'description', 'enabled'] position_values = [name, service_type, description, 'False'] args = [name, service_type, '--description', description, '--enabled=False'] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_delete_flavor(self): """Delete flavor.""" resource = 'flavor' cmd = flavor.DeleteFlavor(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) def test_list_flavors(self): """List flavors test.""" resources = 'flavors' cmd = flavor.ListFlavor( test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_flavors_with_pagination(self): """List flavors test with pagination.""" resources = 'flavors' cmd = flavor.ListFlavor( test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_flavors_with_sort(self): """List flavors test with sorting by name and id.""" resources = 'flavors' cmd = flavor.ListFlavor( test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_show_flavor(self): """Show flavor test.""" resource = 'flavor' cmd = flavor.ShowFlavor( 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_update_flavor_with_name(self): """Update flavor test.""" resource = 'flavor' cmd = flavor.UpdateFlavor( test_cli20.MyApp(sys.stdout), None) newname = 'Test New Name' newdescription = 'New Description' args = ['--name', newname, '--description', newdescription, '--enabled', 'False', self.test_id] self._test_update_resource(resource, cmd, self.test_id, args, {'name': newname, 'description': newdescription, 'enabled': 'False'}) def test_associate_flavor(self): """Associate flavor test.""" resource = 'service_profile' cmd = flavor.AssociateFlavor(test_cli20.MyApp(sys.stdout), None) flavor_id = 'flavor-id' profile_id = 'profile-id' name = '' args = [flavor_id, profile_id] position_names = ['id'] position_values = [profile_id] self._test_create_resource(resource, cmd, name, profile_id, args, position_names, position_values, cmd_resource='flavor_profile_binding', parent_id=flavor_id) def test_disassociate_flavor(self): """Disassociate flavor test.""" resource = 'flavor_profile_binding' cmd = flavor.DisassociateFlavor(test_cli20.MyApp(sys.stdout), None) flavor_id = 'flavor-id' profile_id = 'profile-id' args = [flavor_id, profile_id] self._test_delete_resource(resource, cmd, profile_id, args, parent_id=flavor_id) python-neutronclient-6.7.0/neutronclient/tests/unit/flavor/__init__.py0000666000175100017510000000000013232473350026366 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/flavor/test_cli20_flavor_profile.py0000666000175100017510000001211313232473350031700 0ustar zuulzuul00000000000000# Copyright 2015 Hewlett-Packard Development Company, L.P. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0.flavor import flavor_profile from neutronclient.tests.unit import test_cli20 class CLITestV20FlavorProfileJSON(test_cli20.CLITestV20Base): def setUp(self): """Prepare test environment.""" super(CLITestV20FlavorProfileJSON, self).setUp( plurals={'service_profiles': 'service_profile'}) self.register_non_admin_status_resource('service_profile') def test_create_flavor_profile_with_mandatory_params(self): """Create test flavor profile test.""" resource = 'service_profile' cmd = flavor_profile.CreateFlavorProfile( test_cli20.MyApp(sys.stdout), None) name = '' description = 'Test flavor profile' myid = 'myid' metainfo = "{'a':'b'}" # Defaults are returned in body position_names = ['description', 'metainfo'] position_values = [description, metainfo] args = ['--description', description, '--metainfo', metainfo] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_flavor_profile_with_optional_params(self): """Create test flavor profile disabled test.""" resource = 'service_profile' cmd = flavor_profile.CreateFlavorProfile( test_cli20.MyApp(sys.stdout), None) name = '' description = 'Test flavor profile - disabled' myid = 'myid' driver = 'mydriver' metainfo = "{'a':'b'}" position_names = ['description', 'driver', 'metainfo', 'enabled'] position_values = [description, driver, metainfo, 'False'] args = ['--description', description, '--driver', driver, '--metainfo', metainfo, '--enabled=False'] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_list_flavor_profiles(self): """List flavor profiles test.""" resources = 'service_profiles' cmd = flavor_profile.ListFlavorProfile( test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_flavor_profiles_with_pagination(self): """List flavor profiles test with pagination.""" resources = 'service_profiles' cmd = flavor_profile.ListFlavorProfile( test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_flavor_profiles_with_sort(self): """List flavor profiles test with sort by description.""" resources = 'service_profiles' cmd = flavor_profile.ListFlavorProfile( test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["description"], sort_dir=["asc"]) def test_show_flavor_profile(self): """Show flavor profile test.""" resource = 'service_profile' cmd = flavor_profile.ShowFlavorProfile( 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_update_flavor_profile(self): """Update flavor profile test.""" resource = 'service_profile' cmd = flavor_profile.UpdateFlavorProfile( test_cli20.MyApp(sys.stdout), None) newdescription = 'Test new description' newdriver = 'NewDriver' newmetainfo = "{'c':'d'}" newenabled = "False" args = ['--description', newdescription, '--driver', newdriver, '--metainfo', newmetainfo, '--enabled', newenabled, self.test_id] self._test_update_resource(resource, cmd, self.test_id, args, {'description': newdescription, 'driver': newdriver, 'metainfo': newmetainfo, 'enabled': newenabled}) def test_delete_flavor_profile(self): """Delete flavor profile.""" resource = 'service_profile' cmd = flavor_profile.DeleteFlavorProfile(test_cli20.MyApp(sys.stdout), None) my_id = 'my-id' args = [my_id] self._test_delete_resource(resource, cmd, my_id, args) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_subnetpool.py0000666000175100017510000002222213232473350027572 0ustar zuulzuul00000000000000# Copyright 2015 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 # # 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 mox3 import mox from neutronclient.common import exceptions from neutronclient.neutron.v2_0 import subnetpool from neutronclient.tests.unit import test_cli20 class CLITestV20SubnetPoolJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['subnetpool'] def setUp(self): super(CLITestV20SubnetPoolJSON, self).setUp(plurals={'tags': 'tag'}) def test_create_subnetpool_with_options(self): # Create subnetpool: myname. resource = 'subnetpool' cmd = subnetpool.CreateSubnetPool(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' min_prefixlen = 30 prefix1 = '10.11.12.0/24' prefix2 = '12.11.13.0/24' args = [name, '--min-prefixlen', str(min_prefixlen), '--pool-prefix', prefix1, '--pool-prefix', prefix2, '--shared', '--description', 'public pool', '--tenant-id', 'tenantid'] position_names = ['name', 'min_prefixlen', 'prefixes', 'shared', 'tenant_id'] position_values = [name, min_prefixlen, [prefix1, prefix2], True, 'tenantid'] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, description='public pool') def test_create_subnetpool_only_with_required_options(self): # Create subnetpool: myname. resource = 'subnetpool' cmd = subnetpool.CreateSubnetPool(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' min_prefixlen = 30 prefix1 = '10.11.12.0/24' prefix2 = '12.11.13.0/24' args = [name, '--min-prefixlen', str(min_prefixlen), '--pool-prefix', prefix1, '--pool-prefix', prefix2] position_names = ['name', 'min_prefixlen', 'prefixes'] position_values = [name, min_prefixlen, [prefix1, prefix2]] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_subnetpool_with_is_default(self, default='false'): # Create subnetpool: myname. resource = 'subnetpool' cmd = subnetpool.CreateSubnetPool(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' min_prefixlen = 30 prefix1 = '10.11.12.0/24' prefix2 = '12.11.13.0/24' args = [name, '--min-prefixlen', str(min_prefixlen), '--pool-prefix', prefix1, '--pool-prefix', prefix2, '--is-default', default] position_names = ['name', 'min_prefixlen', 'prefixes', 'is_default'] position_values = [name, min_prefixlen, [prefix1, prefix2], default] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_subnetpool_default(self): self.test_create_subnetpool_with_is_default(default='true') def test_create_subnetpool_with_unicode(self): # Create subnetpool: u'\u7f51\u7edc'. resource = 'subnetpool' cmd = subnetpool.CreateSubnetPool(test_cli20.MyApp(sys.stdout), None) name = u'\u7f51\u7edc' myid = 'myid' min_prefixlen = 30 prefixes = '10.11.12.0/24' args = [name, '--min-prefixlen', str(min_prefixlen), '--pool-prefix', prefixes] position_names = ['name', 'min_prefixlen', 'prefixes'] position_values = [name, min_prefixlen, [prefixes]] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_subnetpool_with_addrscope(self): # Create subnetpool: myname in addrscope: foo-address-scope resource = 'subnetpool' cmd = subnetpool.CreateSubnetPool(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' min_prefixlen = 30 prefix1 = '11.11.11.0/24' prefix2 = '12.12.12.0/24' address_scope = 'foo-address-scope' args = [name, '--min-prefixlen', str(min_prefixlen), '--pool-prefix', prefix1, '--pool-prefix', prefix2, '--address-scope', address_scope] position_names = ['name', 'min_prefixlen', 'prefixes', 'address_scope_id'] position_values = [name, min_prefixlen, [prefix1, prefix2], address_scope] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_subnetpool_no_poolprefix(self): # Should raise an error because --pool-prefix is required resource = 'subnetpool' cmd = subnetpool.CreateSubnetPool(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' args = [name] position_names = ['name'] position_values = [name] self.assertRaises(SystemExit, self._test_create_resource, resource, cmd, name, myid, args, position_names, position_values) def test_list_subnetpool_pagination(self): cmd = subnetpool.ListSubnetPool(test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(subnetpool.ListSubnetPool, "extend_list") subnetpool.ListSubnetPool.extend_list(mox.IsA(list), mox.IgnoreArg()) self._test_list_resources_with_pagination("subnetpools", cmd) self.mox.VerifyAll() self.mox.UnsetStubs() def test_list_subnetpools_sort(self): # List subnetpools: # --sort-key name --sort-key id --sort-key asc --sort-key desc resources = "subnetpools" cmd = subnetpool.ListSubnetPool(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_subnetpools_limit(self): # List subnetpools: -P. resources = "subnetpools" cmd = subnetpool.ListSubnetPool(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_update_subnetpool_exception(self): # Update subnetpool: myid. resource = 'subnetpool' cmd = subnetpool.UpdateSubnetPool(test_cli20.MyApp(sys.stdout), None) self.assertRaises(exceptions.CommandError, self._test_update_resource, resource, cmd, 'myid', ['myid'], {}) def test_update_subnetpool(self): # Update subnetpool: myid --name myname. resource = 'subnetpool' cmd = subnetpool.UpdateSubnetPool(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'myname', '--description', ':)'], {'name': 'myname', 'description': ':)'}) def test_update_subnetpool_with_address_scope(self): # Update subnetpool: myid --address-scope newscope. resource = 'subnetpool' cmd = subnetpool.UpdateSubnetPool(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--address-scope', 'newscope'], {'address_scope_id': 'newscope'} ) def test_update_subnetpool_with_no_address_scope(self): # Update subnetpool: myid --no-address-scope. resource = 'subnetpool' cmd = subnetpool.UpdateSubnetPool(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--no-address-scope'], {'address_scope_id': None} ) def test_show_subnetpool(self): # Show subnetpool: --fields id --fields name myid. resource = 'subnetpool' cmd = subnetpool.ShowSubnetPool(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', '--fields', 'name', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id', 'name']) def test_delete_subnetpool(self): # Delete subnetpool: subnetpoolid. resource = 'subnetpool' cmd = subnetpool.DeleteSubnetPool(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) python-neutronclient-6.7.0/neutronclient/tests/unit/test_auto_allocated_topology.py0000666000175100017510000000641513232473350031331 0ustar zuulzuul00000000000000# Copyright 2016 IBM # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient.neutron.v2_0 import auto_allocated_topology as aat from neutronclient.tests.unit import test_cli20 class TestAutoAllocatedTopologyJSON(test_cli20.CLITestV20Base): def test_show_auto_allocated_topology_arg(self): resource = 'auto_allocated_topology' cmd = aat.ShowAutoAllocatedTopology(test_cli20.MyApp(sys.stdout), None) args = ['--tenant-id', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args) def test_show_auto_allocated_topology_posarg(self): resource = 'auto_allocated_topology' cmd = aat.ShowAutoAllocatedTopology(test_cli20.MyApp(sys.stdout), None) args = ['some-tenant'] self._test_show_resource(resource, cmd, "some-tenant", args) def test_show_auto_allocated_topology_no_arg(self): resource = 'auto_allocated_topology' cmd = aat.ShowAutoAllocatedTopology(test_cli20.MyApp(sys.stdout), None) args = [] self._test_show_resource(resource, cmd, "None", args) def test_show_auto_allocated_topology_dry_run_as_tenant(self): resource = 'auto_allocated_topology' cmd = aat.ShowAutoAllocatedTopology(test_cli20.MyApp(sys.stdout), None) args = ['--dry-run'] self._test_show_resource(resource, cmd, "None", args, fields=('dry-run',)) def test_show_auto_allocated_topology_dry_run_as_admin(self): resource = 'auto_allocated_topology' cmd = aat.ShowAutoAllocatedTopology(test_cli20.MyApp(sys.stdout), None) args = ['--dry-run', 'some-tenant'] self._test_show_resource(resource, cmd, "some-tenant", args, fields=('dry-run',)) def test_delete_auto_allocated_topology_arg(self): resource = 'auto_allocated_topology' cmd = aat.DeleteAutoAllocatedTopology(test_cli20.MyApp(sys.stdout), None) args = ['--tenant-id', self.test_id] self._test_delete_resource(resource, cmd, self.test_id, args) def test_delete_auto_allocated_topology_posarg(self): resource = 'auto_allocated_topology' cmd = aat.DeleteAutoAllocatedTopology(test_cli20.MyApp(sys.stdout), None) args = ['some-tenant'] self._test_delete_resource(resource, cmd, "some-tenant", args) def test_delete_auto_allocated_topology_no_arg(self): resource = 'auto_allocated_topology' cmd = aat.DeleteAutoAllocatedTopology(test_cli20.MyApp(sys.stdout), None) args = [] self._test_delete_resource(resource, cmd, "None", args) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_floatingips.py0000666000175100017510000002010713232473350027717 0ustar zuulzuul00000000000000#!/usr/bin/env python # Copyright 2012 Red Hat # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sys from neutronclient.neutron.v2_0 import floatingip as fip from neutronclient.tests.unit import test_cli20 class CLITestV20FloatingIpsJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['floatingip'] def test_create_floatingip(self): # Create floatingip: fip1. resource = 'floatingip' cmd = fip.CreateFloatingIP(test_cli20.MyApp(sys.stdout), None) name = 'fip1' myid = 'myid' args = [name, '--description', 'floats like a butterfly'] position_names = ['floating_network_id'] position_values = [name] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, description='floats like a butterfly') def test_create_floatingip_and_port(self): # Create floatingip: fip1. resource = 'floatingip' cmd = fip.CreateFloatingIP(test_cli20.MyApp(sys.stdout), None) name = 'fip1' myid = 'myid' pid = 'mypid' args = [name, '--port_id', pid] position_names = ['floating_network_id', 'port_id'] position_values = [name, pid] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) # Test dashed options args = [name, '--port-id', pid] position_names = ['floating_network_id', 'port_id'] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_floatingip_and_port_and_address(self): # Create floatingip: fip1 with a given port and address. resource = 'floatingip' cmd = fip.CreateFloatingIP(test_cli20.MyApp(sys.stdout), None) name = 'fip1' myid = 'myid' pid = 'mypid' addr = '10.0.0.99' args = [name, '--port_id', pid, '--fixed_ip_address', addr] position_names = ['floating_network_id', 'port_id', 'fixed_ip_address'] position_values = [name, pid, addr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) # Test dashed options args = [name, '--port-id', pid, '--fixed-ip-address', addr] position_names = ['floating_network_id', 'port_id', 'fixed_ip_address'] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_floatingip_with_ip_address_of_floating_ip(self): # Create floatingip: fip1 with a given IP address of floating IP. resource = 'floatingip' cmd = fip.CreateFloatingIP(test_cli20.MyApp(sys.stdout), None) name = 'fip1' myid = 'myid' addr = '10.0.0.99' args = [name, '--floating-ip-address', addr] position_values = [name, addr] position_names = ['floating_network_id', 'floating_ip_address'] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_floatingip_with_subnet_id(self): # Create floatingip: fip1 on a given subnet id. resource = 'floatingip' cmd = fip.CreateFloatingIP(test_cli20.MyApp(sys.stdout), None) name = 'fip1' myid = 'myid' subnet_id = 'mysubnetid' args = [name, '--subnet', subnet_id] position_values = [name, subnet_id] position_names = ['floating_network_id', 'subnet_id'] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_floatingip_with_subnet_id_and_port(self): # Create floatingip: fip1 on a given subnet id and port. resource = 'floatingip' cmd = fip.CreateFloatingIP(test_cli20.MyApp(sys.stdout), None) name = 'fip1' myid = 'myid' pid = 'mypid' subnet_id = 'mysubnetid' args = [name, '--subnet', subnet_id, '--port-id', pid] position_values = [name, subnet_id, pid] position_names = ['floating_network_id', 'subnet_id', 'port_id'] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_floatingip_with_dns_name_and_dns_domain(self): # Create floatingip: fip1 with dns name and dns domain. resource = 'floatingip' cmd = fip.CreateFloatingIP(test_cli20.MyApp(sys.stdout), None) name = 'fip1' myid = 'myid' dns_name_name = 'my-floatingip' dns_domain_name = 'my-domain.org.' args = [name, '--dns-name', dns_name_name, '--dns-domain', dns_domain_name] position_names = ['floating_network_id', 'dns_name', 'dns_domain'] position_values = [name, dns_name_name, dns_domain_name] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_list_floatingips(self): # list floatingips: -D. resources = 'floatingips' cmd = fip.ListFloatingIP(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_floatingips_pagination(self): resources = 'floatingips' cmd = fip.ListFloatingIP(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_floatingips_sort(self): # list floatingips: # --sort-key name --sort-key id --sort-key asc --sort-key desc resources = 'floatingips' cmd = fip.ListFloatingIP(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_floatingips_limit(self): # list floatingips: -P. resources = 'floatingips' cmd = fip.ListFloatingIP(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_delete_floatingip(self): # Delete floatingip: fip1. resource = 'floatingip' cmd = fip.DeleteFloatingIP(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) def test_show_floatingip(self): # Show floatingip: --fields id. resource = 'floatingip' cmd = fip.ShowFloatingIP(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_disassociate_ip(self): # Disassociate floating IP: myid. resource = 'floatingip' cmd = fip.DisassociateFloatingIP(test_cli20.MyApp(sys.stdout), None) args = ['myid'] self._test_update_resource(resource, cmd, 'myid', args, {"port_id": None} ) def test_associate_ip(self): # Associate floating IP: myid portid. resource = 'floatingip' cmd = fip.AssociateFloatingIP(test_cli20.MyApp(sys.stdout), None) args = ['myid', 'portid'] self._test_update_resource(resource, cmd, 'myid', args, {"port_id": "portid"} ) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_az.py0000666000175100017510000000254613232473350026021 0ustar zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sys from neutronclient.neutron.v2_0 import availability_zone as az from neutronclient.tests.unit import test_cli20 class CLITestV20Agent(test_cli20.CLITestV20Base): def test_list_agents(self): contents = {'availability_zones': [{'name': 'zone1', 'resource': 'network', 'state': 'available'}, {'name': 'zone2', 'resource': 'router', 'state': 'unavailable'}]} args = ['-f', 'json'] resources = "availability_zones" cmd = az.ListAvailabilityZone(test_cli20.MyApp(sys.stdout), None) self._test_list_columns(cmd, resources, contents, args) python-neutronclient-6.7.0/neutronclient/tests/unit/test_name_or_id.py0000666000175100017510000002275413232473350026515 0ustar zuulzuul00000000000000# 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 # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from mox3 import mox from oslo_utils import uuidutils import testtools from neutronclient.common import exceptions from neutronclient.neutron import v2_0 as neutronV20 from neutronclient.tests.unit import test_cli20 from neutronclient.v2_0 import client class CLITestNameorID(testtools.TestCase): def setUp(self): """Prepare the test environment.""" super(CLITestNameorID, self).setUp() self.mox = mox.Mox() self.endurl = test_cli20.ENDURL self.client = client.Client(token=test_cli20.TOKEN, endpoint_url=self.endurl) self.addCleanup(self.mox.VerifyAll) self.addCleanup(self.mox.UnsetStubs) def test_get_id_from_id(self): _id = uuidutils.generate_uuid() reses = {'networks': [{'id': _id, }, ], } resstr = self.client.serialize(reses) self.mox.StubOutWithMock(self.client.httpclient, "request") path = getattr(self.client, "networks_path") self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, "fields=id&id=" + _id), self.client), 'GET', body=None, headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN) ).AndReturn((test_cli20.MyResp(200), resstr)) self.mox.ReplayAll() returned_id = neutronV20.find_resourceid_by_name_or_id( self.client, 'network', _id) self.assertEqual(_id, returned_id) def test_get_id_from_id_then_name_empty(self): _id = uuidutils.generate_uuid() reses = {'networks': [{'id': _id, }, ], } resstr = self.client.serialize(reses) resstr1 = self.client.serialize({'networks': []}) self.mox.StubOutWithMock(self.client.httpclient, "request") path = getattr(self.client, "networks_path") self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, "fields=id&id=" + _id), self.client), 'GET', body=None, headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN) ).AndReturn((test_cli20.MyResp(200), resstr1)) self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, "fields=id&name=" + _id), self.client), 'GET', body=None, headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN) ).AndReturn((test_cli20.MyResp(200), resstr)) self.mox.ReplayAll() returned_id = neutronV20.find_resourceid_by_name_or_id( self.client, 'network', _id) self.assertEqual(_id, returned_id) def test_get_id_from_name(self): name = 'myname' _id = uuidutils.generate_uuid() reses = {'networks': [{'id': _id, }, ], } resstr = self.client.serialize(reses) self.mox.StubOutWithMock(self.client.httpclient, "request") path = getattr(self.client, "networks_path") self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, "fields=id&name=" + name), self.client), 'GET', body=None, headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN) ).AndReturn((test_cli20.MyResp(200), resstr)) self.mox.ReplayAll() returned_id = neutronV20.find_resourceid_by_name_or_id( self.client, 'network', name) self.assertEqual(_id, returned_id) def test_get_id_from_name_multiple(self): name = 'myname' reses = {'networks': [{'id': uuidutils.generate_uuid()}, {'id': uuidutils.generate_uuid()}]} resstr = self.client.serialize(reses) self.mox.StubOutWithMock(self.client.httpclient, "request") path = getattr(self.client, "networks_path") self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, "fields=id&name=" + name), self.client), 'GET', body=None, headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN) ).AndReturn((test_cli20.MyResp(200), resstr)) self.mox.ReplayAll() exception = self.assertRaises(exceptions.NeutronClientNoUniqueMatch, neutronV20.find_resourceid_by_name_or_id, self.client, 'network', name) self.assertIn('Multiple', exception.message) def test_get_id_from_name_notfound(self): name = 'myname' reses = {'networks': []} resstr = self.client.serialize(reses) self.mox.StubOutWithMock(self.client.httpclient, "request") path = getattr(self.client, "networks_path") self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, "fields=id&name=" + name), self.client), 'GET', body=None, headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN) ).AndReturn((test_cli20.MyResp(200), resstr)) self.mox.ReplayAll() exception = self.assertRaises(exceptions.NotFound, neutronV20.find_resourceid_by_name_or_id, self.client, 'network', name) self.assertIn('Unable to find', exception.message) self.assertEqual(404, exception.status_code) def test_get_id_from_name_multiple_with_project(self): name = 'web_server' project = uuidutils.generate_uuid() expect_id = uuidutils.generate_uuid() reses = {'security_groups': [{'id': expect_id, 'tenant_id': project}]} resstr = self.client.serialize(reses) self.mox.StubOutWithMock(self.client.httpclient, "request") path = getattr(self.client, "security_groups_path") self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, "fields=id&name=%s&tenant_id=%s" % (name, project)), self.client), 'GET', body=None, headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN) ).AndReturn((test_cli20.MyResp(200), resstr)) self.mox.ReplayAll() observed_id = neutronV20.find_resourceid_by_name_or_id( self.client, 'security_group', name, project) self.assertEqual(expect_id, observed_id) def test_get_id_from_name_multiple_with_project_not_found(self): name = 'web_server' project = uuidutils.generate_uuid() resstr_notfound = self.client.serialize({'security_groups': []}) self.mox.StubOutWithMock(self.client.httpclient, "request") path = getattr(self.client, "security_groups_path") self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, "fields=id&name=%s&tenant_id=%s" % (name, project)), self.client), 'GET', body=None, headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN) ).AndReturn((test_cli20.MyResp(200), resstr_notfound)) self.mox.ReplayAll() exc = self.assertRaises(exceptions.NotFound, neutronV20.find_resourceid_by_name_or_id, self.client, 'security_group', name, project) self.assertIn('Unable to find', exc.message) self.assertEqual(404, exc.status_code) def _test_get_resource_by_id(self, id_only=False): _id = uuidutils.generate_uuid() net = {'id': _id, 'name': 'test'} reses = {'networks': [net], } resstr = self.client.serialize(reses) self.mox.StubOutWithMock(self.client.httpclient, "request") path = getattr(self.client, "networks_path") if id_only: query_params = "fields=id&id=%s" % _id else: query_params = "id=%s" % _id self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, query_params), self.client), 'GET', body=None, headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN) ).AndReturn((test_cli20.MyResp(200), resstr)) self.mox.ReplayAll() if id_only: returned_id = neutronV20.find_resourceid_by_id( self.client, 'network', _id) self.assertEqual(_id, returned_id) else: result = neutronV20.find_resource_by_id( self.client, 'network', _id) self.assertEqual(net, result) def test_get_resource_by_id(self): self._test_get_resource_by_id(id_only=False) def test_get_resourceid_by_id(self): self._test_get_resource_by_id(id_only=True) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_securitygroup.py0000666000175100017510000007175513232473350030343 0ustar zuulzuul00000000000000#!/usr/bin/env python # Copyright 2012 Red Hat # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sys from mox3 import mox from oslo_utils import uuidutils import six from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron.v2_0 import securitygroup from neutronclient.tests.unit import test_cli20 class CLITestV20SecurityGroupsJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['security_group', 'security_group_rule'] def test_create_security_group(self): # Create security group: webservers. resource = 'security_group' cmd = securitygroup.CreateSecurityGroup( test_cli20.MyApp(sys.stdout), None) name = 'webservers' myid = 'myid' args = [name, ] position_names = ['name'] position_values = [name] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_security_group_tenant(self): # Create security group: webservers. resource = 'security_group' cmd = securitygroup.CreateSecurityGroup( test_cli20.MyApp(sys.stdout), None) name = 'webservers' description = 'my webservers' myid = 'myid' args = ['--tenant_id', 'tenant_id', '--description', description, name] position_names = ['name', 'description'] position_values = [name, description] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenant_id') def test_create_security_group_with_description(self): # Create security group: webservers. resource = 'security_group' cmd = securitygroup.CreateSecurityGroup( test_cli20.MyApp(sys.stdout), None) name = 'webservers' description = 'my webservers' myid = 'myid' args = [name, '--description', description] position_names = ['name', 'description'] position_values = [name, description] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_list_security_groups(self): resources = "security_groups" cmd = securitygroup.ListSecurityGroup( test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_security_groups_pagination(self): resources = "security_groups" cmd = securitygroup.ListSecurityGroup( test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_security_groups_sort(self): resources = "security_groups" cmd = securitygroup.ListSecurityGroup( test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_security_groups_limit(self): resources = "security_groups" cmd = securitygroup.ListSecurityGroup( test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_show_security_group_id(self): resource = 'security_group' cmd = securitygroup.ShowSecurityGroup( 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_security_group_id_name(self): resource = 'security_group' cmd = securitygroup.ShowSecurityGroup( test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', '--fields', 'name', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id', 'name']) def test_delete_security_group(self): # Delete security group: myid. resource = 'security_group' cmd = securitygroup.DeleteSecurityGroup( test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) def test_update_security_group(self): # Update security group: myid --name myname --description desc. resource = 'security_group' cmd = securitygroup.UpdateSecurityGroup( test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'myname', '--description', 'mydescription'], {'name': 'myname', 'description': 'mydescription'} ) def test_update_security_group_with_unicode(self): resource = 'security_group' cmd = securitygroup.UpdateSecurityGroup( test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', u'\u7f51\u7edc', '--description', u'\u7f51\u7edc'], {'name': u'\u7f51\u7edc', 'description': u'\u7f51\u7edc'} ) def test_create_security_group_rule_full(self): # Create security group rule. resource = 'security_group_rule' cmd = securitygroup.CreateSecurityGroupRule( test_cli20.MyApp(sys.stdout), None) myid = 'myid' direction = 'ingress' ethertype = 'IPv4' protocol = 'tcp' port_range_min = '22' port_range_max = '22' remote_ip_prefix = '10.0.0.0/24' security_group_id = '1' remote_group_id = '1' args = ['--remote_ip_prefix', remote_ip_prefix, '--direction', direction, '--ethertype', ethertype, '--protocol', protocol, '--port_range_min', port_range_min, '--port_range_max', port_range_max, '--remote_group_id', remote_group_id, security_group_id, '--description', 'PCI policy 1421912'] position_names = ['remote_ip_prefix', 'direction', 'ethertype', 'protocol', 'port_range_min', 'port_range_max', 'remote_group_id', 'security_group_id'] position_values = [remote_ip_prefix, direction, ethertype, protocol, port_range_min, port_range_max, remote_group_id, security_group_id] self._test_create_resource(resource, cmd, None, myid, args, position_names, position_values, description='PCI policy 1421912') def test_create_security_group_rule_with_integer_protocol_value(self): resource = 'security_group_rule' cmd = securitygroup.CreateSecurityGroupRule( test_cli20.MyApp(sys.stdout), None) myid = 'myid' direction = 'ingress' ethertype = 'IPv4' protocol = '2' port_range_min = '22' port_range_max = '22' remote_ip_prefix = '10.0.0.0/24' security_group_id = '1' remote_group_id = '1' args = ['--remote_ip_prefix', remote_ip_prefix, '--direction', direction, '--ethertype', ethertype, '--protocol', protocol, '--port_range_min', port_range_min, '--port_range_max', port_range_max, '--remote_group_id', remote_group_id, security_group_id] position_names = ['remote_ip_prefix', 'direction', 'ethertype', 'protocol', 'port_range_min', 'port_range_max', 'remote_group_id', 'security_group_id'] position_values = [remote_ip_prefix, direction, ethertype, protocol, port_range_min, port_range_max, remote_group_id, security_group_id] self._test_create_resource(resource, cmd, None, myid, args, position_names, position_values) def test_delete_security_group_rule(self): # Delete security group rule: myid. resource = 'security_group_rule' cmd = securitygroup.DeleteSecurityGroupRule( test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) def test_list_security_group_rules(self): resources = "security_group_rules" cmd = securitygroup.ListSecurityGroupRule( test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(securitygroup.ListSecurityGroupRule, "extend_list") securitygroup.ListSecurityGroupRule.extend_list(mox.IsA(list), mox.IgnoreArg()) self._test_list_resources(resources, cmd, True) def _test_extend_list(self, mox_calls, data): resources = "security_groups" cmd = securitygroup.ListSecurityGroupRule( test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) path = getattr(self.client, resources + '_path') mox_calls(path, data) self.mox.ReplayAll() known_args, _vs = cmd.get_parser( 'list' + resources).parse_known_args() cmd.extend_list(data, known_args) self.mox.VerifyAll() self.mox.UnsetStubs() def _build_test_data(self, data, excess=0): # Length of a query filter on security group rule id # in these testcases, id='secgroupid%02d' (with len(id)=12) sec_group_id_filter_len = 12 response = [] replace_rules = {'security_group_id': 'security_group', 'remote_group_id': 'remote_group'} search_opts = {'fields': ['id', 'name']} sec_group_ids = set() for rule in data: for key in replace_rules: if rule.get(key): sec_group_ids.add(rule[key]) response.append({'id': rule[key], 'name': 'default'}) sec_group_ids = list(sec_group_ids) result = [] sec_group_count = len(sec_group_ids) max_size = ((sec_group_id_filter_len * sec_group_count) - excess) chunk_size = max_size // sec_group_id_filter_len for i in range(0, sec_group_count, chunk_size): search_opts['id'] = sec_group_ids[i: i + chunk_size] params = utils.safe_encode_dict(search_opts) resp_str = self.client.serialize({'security_groups': response}) result.append({ 'filter': six.moves.urllib.parse.urlencode(params, doseq=1), 'response': (test_cli20.MyResp(200), resp_str), }) return result def test_extend_list(self): def mox_calls(path, data): responses = self._build_test_data(data) self.client.httpclient.request( test_cli20.MyUrlComparator(test_cli20.end_url( path, responses[0]['filter']), self.client), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn( responses[0]['response']) data = [{'name': 'default', 'remote_group_id': 'remgroupid%02d' % i} for i in range(10)] data.append({'name': 'default', 'remote_group_id': None}) self._test_extend_list(mox_calls, data) def test_extend_list_exceed_max_uri_len(self): def mox_calls(path, data): # 1 char of extra URI len will cause a split in 2 requests self.mox.StubOutWithMock(self.client.httpclient, '_check_uri_length') self.client.httpclient._check_uri_length(mox.IgnoreArg()).AndRaise( exceptions.RequestURITooLong(excess=1)) responses = self._build_test_data(data, excess=1) for item in responses: self.client.httpclient._check_uri_length( mox.IgnoreArg()).AndReturn(None) self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, item['filter']), self.client), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn( item['response']) data = [{'name': 'default', 'security_group_id': 'secgroupid%02d' % i, 'remote_group_id': 'remgroupid%02d' % i} for i in range(10)] data.append({'name': 'default', 'security_group_id': 'secgroupid10', 'remote_group_id': None}) self._test_extend_list(mox_calls, data) def test_list_security_group_rules_pagination(self): resources = "security_group_rules" cmd = securitygroup.ListSecurityGroupRule( test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(securitygroup.ListSecurityGroupRule, "extend_list") securitygroup.ListSecurityGroupRule.extend_list(mox.IsA(list), mox.IgnoreArg()) self._test_list_resources_with_pagination(resources, cmd) def test_list_security_group_rules_sort(self): resources = "security_group_rules" cmd = securitygroup.ListSecurityGroupRule( test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(securitygroup.ListSecurityGroupRule, "extend_list") securitygroup.ListSecurityGroupRule.extend_list(mox.IsA(list), mox.IgnoreArg()) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_security_group_rules_limit(self): resources = "security_group_rules" cmd = securitygroup.ListSecurityGroupRule( test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(securitygroup.ListSecurityGroupRule, "extend_list") securitygroup.ListSecurityGroupRule.extend_list(mox.IsA(list), mox.IgnoreArg()) self._test_list_resources(resources, cmd, page_size=1000) def test_show_security_group_rule(self): resource = 'security_group_rule' cmd = securitygroup.ShowSecurityGroupRule( 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_list_security_group_rules_extend(self, api_data, expected, args=(), conv=True, query_fields=None): def setup_list_stub(resources, data, query): reses = {resources: data} resstr = self.client.serialize(reses) resp = (test_cli20.MyResp(200), resstr) path = getattr(self.client, resources + '_path') self.client.httpclient.request( test_cli20.MyUrlComparator( test_cli20.end_url(path, query), self.client), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(resp) cmd = securitygroup.ListSecurityGroupRule( test_cli20.MyApp(sys.stdout), None) self.mox.StubOutWithMock(cmd, 'get_client') self.mox.StubOutWithMock(self.client.httpclient, 'request') cmd.get_client().MultipleTimes().AndReturn(self.client) query = '' if query_fields: query = '&'.join(['fields=' + f for f in query_fields]) setup_list_stub('security_group_rules', api_data, query) if conv: sec_ids = set() for n in api_data: sec_ids.add(n['security_group_id']) if n.get('remote_group_id'): sec_ids.add(n['remote_group_id']) filters = '' for id in sec_ids: filters = filters + "&id=%s" % id setup_list_stub('security_groups', [{'id': 'myid1', 'name': 'group1'}, {'id': 'myid2', 'name': 'group2'}, {'id': 'myid3', 'name': 'group3'}], query='fields=id&fields=name' + filters) self.mox.ReplayAll() cmd_parser = cmd.get_parser('list_security_group_rules') parsed_args = cmd_parser.parse_args(args) result = cmd.take_action(parsed_args) self.mox.VerifyAll() self.mox.UnsetStubs() # Check columns self.assertEqual(expected['cols'], result[0]) # Check data _result = [x for x in result[1]] self.assertEqual(len(expected['data']), len(_result)) for res, exp in zip(_result, expected['data']): self.assertEqual(len(exp), len(res)) self.assertEqual(exp, res) def _test_list_security_group_rules_extend_sg_name( self, expected_mode=None, args=(), conv=True, query_field=False): if query_field: field_filters = ['id', 'security_group_id', 'remote_ip_prefix', 'remote_group_id'] else: field_filters = None data = [self._prepare_rule(rule_id='ruleid1', sg_id='myid1', remote_group_id='myid1', filters=field_filters), self._prepare_rule(rule_id='ruleid2', sg_id='myid2', remote_group_id='myid3', filters=field_filters), self._prepare_rule(rule_id='ruleid3', sg_id='myid2', remote_group_id='myid2', filters=field_filters), ] if expected_mode == 'noconv': expected = {'cols': ['id', 'security_group_id', 'remote_group_id'], 'data': [('ruleid1', 'myid1', 'myid1'), ('ruleid2', 'myid2', 'myid3'), ('ruleid3', 'myid2', 'myid2')]} elif expected_mode == 'remote_group_id': expected = {'cols': ['id', 'security_group', 'remote_group'], 'data': [('ruleid1', 'group1', 'group1'), ('ruleid2', 'group2', 'group3'), ('ruleid3', 'group2', 'group2')]} else: expected = {'cols': ['id', 'security_group', 'remote'], 'data': [('ruleid1', 'group1', 'group1 (group)'), ('ruleid2', 'group2', 'group3 (group)'), ('ruleid3', 'group2', 'group2 (group)')]} self._test_list_security_group_rules_extend( data, expected, args=args, conv=conv, query_fields=field_filters) def test_list_security_group_rules_extend_remote_sg_name(self): args = '-c id -c security_group -c remote'.split() self._test_list_security_group_rules_extend_sg_name(args=args) def test_list_security_group_rules_extend_sg_name_noconv(self): args = '--no-nameconv -c id -c security_group_id -c remote_group_id' args = args.split() self._test_list_security_group_rules_extend_sg_name( expected_mode='noconv', args=args, conv=False) def test_list_security_group_rules_extend_sg_name_with_columns(self): args = '-c id -c security_group_id -c remote_group_id'.split() self._test_list_security_group_rules_extend_sg_name( expected_mode='remote_group_id', args=args) def test_list_security_group_rules_extend_sg_name_with_columns_no_id(self): args = '-c id -c security_group -c remote_group'.split() self._test_list_security_group_rules_extend_sg_name( expected_mode='remote_group_id', args=args) def test_list_security_group_rules_extend_sg_name_with_fields(self): # NOTE: remote_ip_prefix is required to show "remote" column args = ('-F id -F security_group_id ' '-F remote_ip_prefix -F remote_group_id').split() self._test_list_security_group_rules_extend_sg_name( args=args, query_field=True) def test_list_security_group_rules_extend_sg_name_with_fields_no_id(self): # NOTE: remote_ip_prefix is required to show "remote" column args = ('-F id -F security_group ' '-F remote_ip_prefix -F remote_group').split() self._test_list_security_group_rules_extend_sg_name(args=args, query_field=True) def test_list_security_group_rules_extend_remote(self): args = '-c id -c security_group -c remote'.split() data = [self._prepare_rule(rule_id='ruleid1', sg_id='myid1', remote_ip_prefix='172.16.18.0/24'), self._prepare_rule(rule_id='ruleid2', sg_id='myid2', remote_ip_prefix='172.16.20.0/24'), self._prepare_rule(rule_id='ruleid3', sg_id='myid2', remote_group_id='myid3')] expected = {'cols': ['id', 'security_group', 'remote'], 'data': [('ruleid1', 'group1', '172.16.18.0/24 (CIDR)'), ('ruleid2', 'group2', '172.16.20.0/24 (CIDR)'), ('ruleid3', 'group2', 'group3 (group)')]} self._test_list_security_group_rules_extend(data, expected, args) def test_list_security_group_rules_extend_proto_port(self): data = [self._prepare_rule(rule_id='ruleid1', sg_id='myid1', protocol='tcp', port_range_min=22, port_range_max=22), self._prepare_rule(rule_id='ruleid2', sg_id='myid2', direction='egress', ethertype='IPv6', protocol='udp', port_range_min=80, port_range_max=81), self._prepare_rule(rule_id='ruleid3', sg_id='myid2', protocol='icmp', remote_ip_prefix='10.2.0.0/16')] expected = { 'cols': ['id', 'security_group', 'direction', 'ethertype', 'port/protocol', 'remote'], 'data': [ ('ruleid1', 'group1', 'ingress', 'IPv4', '22/tcp', 'any'), ('ruleid2', 'group2', 'egress', 'IPv6', '80-81/udp', 'any'), ('ruleid3', 'group2', 'ingress', 'IPv4', 'icmp', '10.2.0.0/16 (CIDR)') ]} self._test_list_security_group_rules_extend(data, expected) def _prepare_rule(self, rule_id=None, sg_id=None, tenant_id=None, direction=None, ethertype=None, protocol=None, port_range_min=None, port_range_max=None, remote_ip_prefix=None, remote_group_id=None, filters=None): rule = {'id': rule_id or uuidutils.generate_uuid(), 'tenant_id': tenant_id or uuidutils.generate_uuid(), 'security_group_id': sg_id or uuidutils.generate_uuid(), 'direction': direction or 'ingress', 'ethertype': ethertype or 'IPv4', 'protocol': protocol, 'port_range_min': port_range_min, 'port_range_max': port_range_max, 'remote_ip_prefix': remote_ip_prefix, 'remote_group_id': remote_group_id} if filters: return dict([(k, v) for k, v in rule.items() if k in filters]) else: return rule def test__get_remote_both_unspecified(self): sg_rule = self._prepare_rule(remote_ip_prefix=None, remote_group_id=None) self.assertIsNone(securitygroup._get_remote(sg_rule)) def test__get_remote_remote_ip_prefix_specified(self): sg_rule = self._prepare_rule(remote_ip_prefix='172.16.18.0/24') self.assertEqual('172.16.18.0/24 (CIDR)', securitygroup._get_remote(sg_rule)) def test__get_remote_remote_group_specified(self): sg_rule = self._prepare_rule(remote_group_id='sg_id1') self.assertEqual('sg_id1 (group)', securitygroup._get_remote(sg_rule)) def test__get_protocol_port_all_none(self): sg_rule = self._prepare_rule() self.assertIsNone(securitygroup._get_protocol_port(sg_rule)) def test__get_protocol_port_tcp_all_port(self): sg_rule = self._prepare_rule(protocol='tcp') self.assertEqual('tcp', securitygroup._get_protocol_port(sg_rule)) def test__get_protocol_port_tcp_one_port(self): sg_rule = self._prepare_rule(protocol='tcp', port_range_min=22, port_range_max=22) self.assertEqual('22/tcp', securitygroup._get_protocol_port(sg_rule)) def test__get_protocol_port_tcp_port_range(self): sg_rule = self._prepare_rule(protocol='tcp', port_range_min=5000, port_range_max=5010) self.assertEqual('5000-5010/tcp', securitygroup._get_protocol_port(sg_rule)) def test__get_protocol_port_udp_all_port(self): sg_rule = self._prepare_rule(protocol='udp') self.assertEqual('udp', securitygroup._get_protocol_port(sg_rule)) def test__get_protocol_port_udp_one_port(self): sg_rule = self._prepare_rule(protocol='udp', port_range_min=22, port_range_max=22) self.assertEqual('22/udp', securitygroup._get_protocol_port(sg_rule)) def test__get_protocol_port_udp_port_range(self): sg_rule = self._prepare_rule(protocol='udp', port_range_min=5000, port_range_max=5010) self.assertEqual('5000-5010/udp', securitygroup._get_protocol_port(sg_rule)) def test__get_protocol_port_icmp_all(self): sg_rule = self._prepare_rule(protocol='icmp') self.assertEqual('icmp', securitygroup._get_protocol_port(sg_rule)) def test_get_ethertype_for_protocol_icmpv6(self): self.assertEqual('IPv6', securitygroup.generate_default_ethertype('icmpv6')) def test_get_ethertype_for_protocol_icmp(self): self.assertEqual('IPv4', securitygroup.generate_default_ethertype('icmp')) def test__get_protocol_port_udp_code_type(self): sg_rule = self._prepare_rule(protocol='icmp', port_range_min=1, port_range_max=8) self.assertEqual('icmp (type:1, code:8)', securitygroup._get_protocol_port(sg_rule)) def test__format_sg_rules(self): rules = [self._prepare_rule(), self._prepare_rule(protocol='tcp', port_range_min=80, port_range_max=80), self._prepare_rule(remote_ip_prefix='192.168.1.0/24'), self._prepare_rule(remote_group_id='group1'), self._prepare_rule(protocol='tcp', remote_ip_prefix='10.1.1.0/24'), self._prepare_rule(direction='egress'), self._prepare_rule(direction='egress', ethertype='IPv6'), ] sg = {'security_group_rules': rules} expected_data = ['ingress, IPv4', 'ingress, IPv4, 80/tcp', 'ingress, IPv4, remote_ip_prefix: 192.168.1.0/24', 'ingress, IPv4, remote_group_id: group1', 'ingress, IPv4, tcp, remote_ip_prefix: 10.1.1.0/24', 'egress, IPv4', 'egress, IPv6', ] expected = '\n'.join(sorted(expected_data)) self.assertEqual(expected, securitygroup._format_sg_rules(sg)) python-neutronclient-6.7.0/neutronclient/tests/unit/test_command_meta.py0000666000175100017510000000273013232473350027035 0ustar zuulzuul00000000000000# Copyright 2013 Intel # Copyright 2013 Isaku Yamahata # # All Rights Reserved. # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import logging import testtools from testtools import helpers from neutronclient.neutron import v2_0 as neutronV20 class TestCommandMeta(testtools.TestCase): def test_neutron_command_meta_defines_log(self): class FakeCommand(neutronV20.NeutronCommand): pass self.assertTrue(helpers.safe_hasattr(FakeCommand, 'log')) self.assertIsInstance(FakeCommand.log, logging.getLoggerClass()) self.assertEqual(__name__ + ".FakeCommand", FakeCommand.log.name) def test_neutron_command_log_defined_explicitly(self): class FakeCommand(neutronV20.NeutronCommand): log = None self.assertTrue(helpers.safe_hasattr(FakeCommand, 'log')) self.assertIsNone(FakeCommand.log) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_extensions.py0000666000175100017510000000351013232473350027576 0ustar zuulzuul00000000000000# Copyright 2013 NEC Corporation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sys from neutronclient.neutron.v2_0 import extension from neutronclient.tests.unit import test_cli20 class CLITestV20Extension(test_cli20.CLITestV20Base): id_field = 'alias' def test_list_extensions(self): resources = 'extensions' cmd = extension.ListExt(test_cli20.MyApp(sys.stdout), None) contents = [{'alias': 'ext1', 'name': 'name1', 'other': 'other1'}, {'alias': 'ext2', 'name': 'name2', 'other': 'other2'}] ret = self._test_list_resources(resources, cmd, response_contents=contents) ret_words = set(ret.split()) # Check only the default columns are shown. self.assertIn('name', ret_words) self.assertIn('alias', ret_words) self.assertNotIn('other', ret_words) def test_show_extension(self): # -F option does not work for ext-show at the moment, so -F option # is not passed in the commandline args as other tests do. resource = 'extension' cmd = extension.ShowExt(test_cli20.MyApp(sys.stdout), None) args = [self.test_id] ext_alias = self.test_id self._test_show_resource(resource, cmd, ext_alias, args, fields=[]) python-neutronclient-6.7.0/neutronclient/tests/unit/test_quota.py0000666000175100017510000000763413232473350025552 0ustar zuulzuul00000000000000#!/usr/bin/env python # Copyright (C) 2013 Yahoo! Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sys from mox3 import mox from neutronclient.common import exceptions from neutronclient.neutron.v2_0 import quota as test_quota from neutronclient.tests.unit import test_cli20 class CLITestV20Quota(test_cli20.CLITestV20Base): def test_show_quota(self): resource = 'quota' cmd = test_quota.ShowQuota( test_cli20.MyApp(sys.stdout), None) args = ['--tenant-id', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args) def test_update_quota(self): resource = 'quota' cmd = test_quota.UpdateQuota( test_cli20.MyApp(sys.stdout), None) args = ['--tenant-id', self.test_id, '--network', 'test'] self.assertRaises( exceptions.CommandError, self._test_update_resource, resource, cmd, self.test_id, args=args, extrafields={'network': 'new'}) def test_delete_quota_get_parser(self): cmd = test_cli20.MyApp(sys.stdout) test_quota.DeleteQuota(cmd, None).get_parser(cmd) def test_show_quota_positional(self): resource = 'quota' cmd = test_quota.ShowQuota( test_cli20.MyApp(sys.stdout), None) args = [self.test_id] self._test_show_resource(resource, cmd, self.test_id, args) def test_update_quota_positional(self): resource = 'quota' cmd = test_quota.UpdateQuota( test_cli20.MyApp(sys.stdout), None) args = [self.test_id, '--network', 'test'] self.assertRaises( exceptions.CommandError, self._test_update_resource, resource, cmd, self.test_id, args=args, extrafields={'network': 'new'}) def test_show_quota_default(self): resource = 'quota' cmd = test_quota.ShowQuotaDefault( test_cli20.MyApp(sys.stdout), None) args = ['--tenant-id', self.test_id] self.mox.StubOutWithMock(cmd, "get_client") self.mox.StubOutWithMock(self.client.httpclient, "request") cmd.get_client().MultipleTimes().AndReturn(self.client) expected_res = {'quota': {'port': 50, 'network': 10, 'subnet': 10}} resstr = self.client.serialize(expected_res) path = getattr(self.client, "quota_default_path") return_tup = (test_cli20.MyResp(200), resstr) self.client.httpclient.request( test_cli20.end_url(path % self.test_id), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(return_tup) self.mox.ReplayAll() cmd_parser = cmd.get_parser("test_" + resource) parsed_args = cmd_parser.parse_args(args) cmd.run(parsed_args) self.mox.VerifyAll() self.mox.UnsetStubs() _str = self.fake_stdout.make_string() self.assertIn('network', _str) self.assertIn('subnet', _str) self.assertIn('port', _str) self.assertNotIn('subnetpool', _str) def test_update_quota_noargs(self): resource = 'quota' cmd = test_quota.UpdateQuota(test_cli20.MyApp(sys.stdout), None) args = [self.test_id] self.assertRaises(exceptions.CommandError, self._test_update_resource, resource, cmd, self.test_id, args=args, extrafields=None) python-neutronclient-6.7.0/neutronclient/tests/unit/test_casual_args.py0000666000175100017510000001160113232473350026672 0ustar zuulzuul00000000000000# 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 # # 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 testtools from neutronclient.common import exceptions from neutronclient.neutron import v2_0 as neutronV20 class CLITestArgs(testtools.TestCase): def test_empty(self): _mydict = neutronV20.parse_args_to_dict([]) self.assertEqual({}, _mydict) def test_default_bool(self): _specs = ['--my_bool', '--arg1', 'value1'] _mydict = neutronV20.parse_args_to_dict(_specs) self.assertTrue(_mydict['my_bool']) def test_bool_true(self): _specs = ['--my-bool', 'type=bool', 'true', '--arg1', 'value1'] _mydict = neutronV20.parse_args_to_dict(_specs) self.assertTrue(_mydict['my_bool']) def test_bool_false(self): _specs = ['--my_bool', 'type=bool', 'false', '--arg1', 'value1'] _mydict = neutronV20.parse_args_to_dict(_specs) self.assertFalse(_mydict['my_bool']) def test_nargs(self): _specs = ['--tag', 'x', 'y', '--arg1', 'value1'] _mydict = neutronV20.parse_args_to_dict(_specs) self.assertIn('x', _mydict['tag']) self.assertIn('y', _mydict['tag']) def test_badarg(self): _specs = ['--tag=t', 'x', 'y', '--arg1', 'value1'] self.assertRaises(exceptions.CommandError, neutronV20.parse_args_to_dict, _specs) def test_badarg_with_minus(self): _specs = ['--arg1', 'value1', '-D'] self.assertRaises(exceptions.CommandError, neutronV20.parse_args_to_dict, _specs) def test_goodarg_with_minus_number(self): _specs = ['--arg1', 'value1', '-1', '-1.0'] _mydict = neutronV20.parse_args_to_dict(_specs) self.assertEqual(['value1', '-1', '-1.0'], _mydict['arg1']) def test_badarg_duplicate(self): _specs = ['--tag=t', '--arg1', 'value1', '--arg1', 'value1'] self.assertRaises(exceptions.CommandError, neutronV20.parse_args_to_dict, _specs) def test_badarg_early_type_specification(self): _specs = ['type=dict', 'key=value'] self.assertRaises(exceptions.CommandError, neutronV20.parse_args_to_dict, _specs) def test_arg(self): _specs = ['--tag=t', '--arg1', 'value1'] self.assertEqual('value1', neutronV20.parse_args_to_dict(_specs)['arg1']) def test_arg_invalid_syntax(self): _specs = ['--tag=t', '---arg1', 'value1'] self.assertRaises(exceptions.CommandError, neutronV20.parse_args_to_dict, _specs) def test_dict_arg(self): _specs = ['--tag=t', '--arg1', 'type=dict', 'key1=value1,key2=value2'] arg1 = neutronV20.parse_args_to_dict(_specs)['arg1'] self.assertEqual('value1', arg1['key1']) self.assertEqual('value2', arg1['key2']) def test_dict_arg_with_attribute_named_type(self): _specs = ['--tag=t', '--arg1', 'type=dict', 'type=value1,key2=value2'] arg1 = neutronV20.parse_args_to_dict(_specs)['arg1'] self.assertEqual('value1', arg1['type']) self.assertEqual('value2', arg1['key2']) def test_list_of_dict_arg(self): _specs = ['--tag=t', '--arg1', 'type=dict', 'list=true', 'key1=value1,key2=value2'] arg1 = neutronV20.parse_args_to_dict(_specs)['arg1'] self.assertEqual('value1', arg1[0]['key1']) self.assertEqual('value2', arg1[0]['key2']) def test_clear_action(self): _specs = ['--anyarg', 'action=clear'] args = neutronV20.parse_args_to_dict(_specs) self.assertIsNone(args['anyarg']) def test_bad_values_str(self): _specs = ['--strarg', 'type=str'] self.assertRaises(exceptions.CommandError, neutronV20.parse_args_to_dict, _specs) def test_bad_values_list(self): _specs = ['--listarg', 'list=true', 'type=str'] self.assertRaises(exceptions.CommandError, neutronV20.parse_args_to_dict, _specs) _specs = ['--listarg', 'type=list'] self.assertRaises(exceptions.CommandError, neutronV20.parse_args_to_dict, _specs) _specs = ['--listarg', 'type=list', 'action=clear'] self.assertRaises(exceptions.CommandError, neutronV20.parse_args_to_dict, _specs) python-neutronclient-6.7.0/neutronclient/tests/unit/test_utils.py0000666000175100017510000001434013232473350025551 0ustar zuulzuul00000000000000# Copyright (C) 2013 Yahoo! Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import argparse from oslo_utils import netutils import testtools from neutronclient.common import exceptions from neutronclient.common import utils class TestUtils(testtools.TestCase): def test_string_to_bool_true(self): self.assertTrue(utils.str2bool('true')) def test_string_to_bool_false(self): self.assertFalse(utils.str2bool('false')) def test_string_to_bool_None(self): self.assertIsNone(utils.str2bool(None)) def test_string_to_dictionary(self): input_str = 'key1=value1,key2=value2' expected = {'key1': 'value1', 'key2': 'value2'} self.assertEqual(expected, utils.str2dict(input_str)) def test_none_string_to_dictionary(self): input_str = '' expected = {} self.assertEqual(expected, utils.str2dict(input_str)) input_str = None expected = {} self.assertEqual(expected, utils.str2dict(input_str)) def test_invalid_string_to_dictionary(self): input_str = 'invalid' self.assertRaises(argparse.ArgumentTypeError, utils.str2dict, input_str) def test_string_with_comma_value_to_dictionary(self): input_str = ('opt_name=classless-static-route,' 'opt_value=169.254.169.254/32,10.0.0.1') expected = {'opt_name': 'classless-static-route', 'opt_value': '169.254.169.254/32,10.0.0.1'} self.assertEqual(expected, utils.str2dict(input_str)) def test_str2dict_optional_keys(self): self.assertDictEqual({'key1': 'value1'}, utils.str2dict('key1=value1', optional_keys=['key1', 'key2'])) self.assertDictEqual({'key1': 'value1', 'key2': 'value2'}, utils.str2dict('key1=value1,key2=value2', optional_keys=['key1', 'key2'])) e = self.assertRaises(argparse.ArgumentTypeError, utils.str2dict, 'key1=value1,key2=value2,key3=value3', optional_keys=['key1', 'key2']) self.assertEqual("Invalid key(s) 'key3' specified. " "Valid key(s): 'key1, key2'.", str(e)) def test_str2dict_required_keys(self): self.assertDictEqual( {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}, utils.str2dict('key1=value1,key2=value2,key3=value3', required_keys=['key1', 'key2'], optional_keys=['key3'])) self.assertDictEqual( {'key1': 'value1', 'key2': 'value2'}, utils.str2dict('key1=value1,key2=value2', required_keys=['key1', 'key2'])) e = self.assertRaises(argparse.ArgumentTypeError, utils.str2dict, 'key1=value1', required_keys=['key1', 'key2']) self.assertEqual("Required key(s) 'key2' not specified.", str(e)) def test_get_dict_item_properties(self): item = {'name': 'test_name', 'id': 'test_id'} fields = ('name', 'id') actual = utils.get_item_properties(item=item, fields=fields) self.assertEqual(('test_name', 'test_id'), actual) def test_get_object_item_properties_mixed_case_fields(self): class Fake(object): def __init__(self): self.id = 'test_id' self.name = 'test_name' self.test_user = 'test' fields = ('name', 'id', 'test user') mixed_fields = ('test user', 'ID') item = Fake() actual = utils.get_item_properties(item, fields, mixed_fields) self.assertEqual(('test_name', 'test_id', 'test'), actual) def test_get_object_item_desired_fields_differ_from_item(self): class Fake(object): def __init__(self): self.id = 'test_id_1' self.name = 'test_name' self.test_user = 'test' fields = ('name', 'id', 'test user') item = Fake() actual = utils.get_item_properties(item, fields) self.assertNotEqual(('test_name', 'test_id', 'test'), actual) def test_get_object_item_desired_fields_is_empty(self): class Fake(object): def __init__(self): self.id = 'test_id_1' self.name = 'test_name' self.test_user = 'test' fields = [] item = Fake() actual = utils.get_item_properties(item, fields) self.assertEqual((), actual) def test_get_object_item_with_formatters(self): class Fake(object): def __init__(self): self.id = 'test_id' self.name = 'test_name' self.test_user = 'test' class FakeCallable(object): def __call__(self, *args, **kwargs): return 'pass' fields = ('name', 'id', 'test user', 'is_public') formatters = {'is_public': FakeCallable()} item = Fake() act = utils.get_item_properties(item, fields, formatters=formatters) self.assertEqual(('test_name', 'test_id', 'test', 'pass'), act) def test_is_cidr(self): self.assertTrue(netutils.is_valid_cidr('10.10.10.0/24')) self.assertFalse(netutils.is_valid_cidr('10.10.10..0/24')) self.assertFalse(netutils.is_valid_cidr('wrong_cidr_format')) class ImportClassTestCase(testtools.TestCase): def test_get_client_class_invalid_version(self): self.assertRaises( exceptions.UnsupportedVersion, utils.get_client_class, 'image', '2', {'image': '2'}) python-neutronclient-6.7.0/neutronclient/tests/unit/test_cli20_subnet.py0000666000175100017510000007323413232473350026711 0ustar zuulzuul00000000000000# 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 # # 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 mox3 import mox from neutronclient.common import exceptions from neutronclient.neutron import v2_0 as neutronV20 from neutronclient.neutron.v2_0 import subnet from neutronclient.tests.unit import test_cli20 class CLITestV20SubnetJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['subnet'] def setUp(self): super(CLITestV20SubnetJSON, self).setUp(plurals={'tags': 'tag'}) def test_create_subnet(self): # Create subnet: --gateway gateway netid cidr. resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = '10.10.10.0/24' gateway = 'gatewayvalue' args = ['--gateway', gateway, netid, cidr, '--description', 'cave'] position_names = ['ip_version', 'network_id', 'cidr', 'gateway_ip'] position_values = [4, netid, cidr, gateway] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, description='cave') def test_create_subnet_network_cidr_seperated(self): # For positional value, network_id and cidr can be separated. # Create subnet: --gateway gateway netid cidr. resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = '10.10.10.0/24' gateway = 'gatewayvalue' args = [netid, '--gateway', gateway, cidr] position_names = ['ip_version', 'network_id', 'cidr', 'gateway_ip'] position_values = [4, netid, cidr, gateway] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_subnet_with_no_gateway(self): # Create subnet: --no-gateway netid cidr. resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'cidrvalue' args = ['--no-gateway', netid, cidr] position_names = ['ip_version', 'network_id', 'cidr', 'gateway_ip'] position_values = [4, netid, cidr, None] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_create_subnet_with_segment(self): # Create subnet: --segment segment netid cidr. resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = '10.10.10.0/24' segment = 'segment' args = ['--segment', segment, netid, cidr, '--description', 'cave'] position_names = ['ip_version', 'network_id', 'cidr', 'segment_id'] position_values = [4, netid, cidr, segment] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, description='cave') def test_create_subnet_with_bad_gateway_option(self): # Create sbunet: --no-gateway netid cidr. resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'cidrvalue' gateway = 'gatewayvalue' args = ['--gateway', gateway, '--no-gateway', netid, cidr] position_names = ['ip_version', 'network_id', 'cidr', 'gateway_ip'] position_values = [4, netid, cidr, None] self.assertRaises( SystemExit, self._test_create_resource, resource, cmd, name, myid, args, position_names, position_values) def _test_create_resource_and_catch_command_error(self, should_fail, *args): if should_fail: params = {'no_api_call': True, 'expected_exception': exceptions.CommandError} else: params = {} self._test_create_resource(*args, **params) def test_create_subnet_with_enable_and_disable_dhcp(self): # Create subnet: --enable-dhcp and --disable-dhcp. resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'cidrvalue' position_names = ['ip_version', 'network_id', 'cidr', 'enable_dhcp'] # enable_dhcp value is appended later inside the loop position_values = [4, netid, cidr] for enable_dhcp_arg, should_fail in ( ('--enable-dhcp=False', False), ('--enable-dhcp=True', True), ('--enable-dhcp', True) ): tested_args = [enable_dhcp_arg, '--disable-dhcp'] args = tested_args + [netid, cidr] pos_values = position_values + [should_fail] self._test_create_resource_and_catch_command_error( should_fail, resource, cmd, name, myid, args, position_names, pos_values) def test_create_subnet_with_multiple_enable_dhcp(self): # Create subnet with multiple --enable-dhcp arguments passed. resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'cidrvalue' position_names = ['ip_version', 'network_id', 'cidr', 'enable_dhcp'] # enable_dhcp value is appended later inside the loop position_values = [4, netid, cidr] _ = 'UNUSED_MARKER' for tested_args, should_fail, pos_value in ( (['--enable-dhcp', '--enable-dhcp=True'], False, True), (['--enable-dhcp', '--enable-dhcp=False'], True, _), (['--enable-dhcp=False', '--enable-dhcp'], True, _), (['--enable-dhcp=True', '--enable-dhcp=False'], True, _), (['--enable-dhcp=False', '--enable-dhcp=True'], True, _) ): args = tested_args + [netid, cidr] pos_values = position_values + [pos_value] self._test_create_resource_and_catch_command_error( should_fail, resource, cmd, name, myid, args, position_names, pos_values) def test_create_subnet_tenant(self): # Create subnet: --tenant_id tenantid netid cidr. resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', netid, cidr] position_names = ['ip_version', 'network_id', 'cidr'] position_values = [4, netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_tags(self): # Create subnet: netid cidr --tags a b. resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = [netid, cidr, '--tags', 'a', 'b'] position_names = ['ip_version', 'network_id', 'cidr'] position_values = [4, netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tags=['a', 'b']) def test_create_subnet_allocation_pool(self): # Create subnet: --tenant_id tenantid netid cidr. # The is --allocation_pool start=1.1.1.10,end=1.1.1.20 resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--allocation_pool', 'start=1.1.1.10,end=1.1.1.20', netid, cidr] position_names = ['ip_version', 'allocation_pools', 'network_id', 'cidr'] pool = [{'start': '1.1.1.10', 'end': '1.1.1.20'}] position_values = [4, pool, netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_allocation_pools(self): # Create subnet: --tenant-id tenantid netid cidr. # The are --allocation_pool start=1.1.1.10,end=1.1.1.20 and # --allocation_pool start=1.1.1.30,end=1.1.1.40 resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--allocation_pool', 'start=1.1.1.10,end=1.1.1.20', '--allocation_pool', 'start=1.1.1.30,end=1.1.1.40', netid, cidr] position_names = ['ip_version', 'allocation_pools', 'network_id', 'cidr'] pools = [{'start': '1.1.1.10', 'end': '1.1.1.20'}, {'start': '1.1.1.30', 'end': '1.1.1.40'}] position_values = [4, pools, netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_host_route(self): # Create subnet: --tenant_id tenantid netid cidr. # The is # --host-route destination=172.16.1.0/24,nexthop=1.1.1.20 resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--host-route', 'destination=172.16.1.0/24,nexthop=1.1.1.20', netid, cidr] position_names = ['ip_version', 'host_routes', 'network_id', 'cidr'] route = [{'destination': '172.16.1.0/24', 'nexthop': '1.1.1.20'}] position_values = [4, route, netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_host_routes(self): # Create subnet: --tenant-id tenantid netid cidr. # The are # --host-route destination=172.16.1.0/24,nexthop=1.1.1.20 and # --host-route destination=172.17.7.0/24,nexthop=1.1.1.40 resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--host-route', 'destination=172.16.1.0/24,nexthop=1.1.1.20', '--host-route', 'destination=172.17.7.0/24,nexthop=1.1.1.40', netid, cidr] position_names = ['ip_version', 'host_routes', 'network_id', 'cidr'] routes = [{'destination': '172.16.1.0/24', 'nexthop': '1.1.1.20'}, {'destination': '172.17.7.0/24', 'nexthop': '1.1.1.40'}] position_values = [4, routes, netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_dns_nameservers(self): # Create subnet: --tenant-id tenantid netid cidr. # The are # --dns-nameserver 1.1.1.20 and --dns-nameserver 1.1.1.40 resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--dns-nameserver', '1.1.1.20', '--dns-nameserver', '1.1.1.40', netid, cidr] position_names = ['ip_version', 'dns_nameservers', 'network_id', 'cidr'] nameservers = ['1.1.1.20', '1.1.1.40'] position_values = [4, nameservers, netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_with_use_default_subnetpool(self): # Create subnet: --tenant-id tenantid --use-default-subnetpool \ # netid cidr. resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--use-default-subnetpool', netid, cidr] position_names = ['ip_version', 'use_default_subnetpool', 'network_id', 'cidr'] position_values = [4, True, netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_with_disable_dhcp(self): # Create subnet: --tenant-id tenantid --disable-dhcp netid cidr. resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--disable-dhcp', netid, cidr] position_names = ['ip_version', 'enable_dhcp', 'network_id', 'cidr'] position_values = [4, False, netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_merge_single_plurar(self): resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--allocation-pool', 'start=1.1.1.10,end=1.1.1.20', netid, cidr, '--allocation-pools', 'list=true', 'type=dict', 'start=1.1.1.30,end=1.1.1.40'] position_names = ['ip_version', 'allocation_pools', 'network_id', 'cidr'] pools = [{'start': '1.1.1.10', 'end': '1.1.1.20'}, {'start': '1.1.1.30', 'end': '1.1.1.40'}] position_values = [4, pools, netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_merge_plurar(self): resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', netid, cidr, '--allocation-pools', 'list=true', 'type=dict', 'start=1.1.1.30,end=1.1.1.40'] position_names = ['ip_version', 'allocation_pools', 'network_id', 'cidr'] pools = [{'start': '1.1.1.30', 'end': '1.1.1.40'}] position_values = [4, pools, netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_merge_single_single(self): resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--allocation-pool', 'start=1.1.1.10,end=1.1.1.20', netid, cidr, '--allocation-pool', 'start=1.1.1.30,end=1.1.1.40'] position_names = ['ip_version', 'allocation_pools', 'network_id', 'cidr'] pools = [{'start': '1.1.1.10', 'end': '1.1.1.20'}, {'start': '1.1.1.30', 'end': '1.1.1.40'}] position_values = [4, pools, netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_max_v4_cidr(self): # Create subnet: --gateway gateway netid cidr. resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = '192.168.0.1/32' gateway = 'gatewayvalue' args = ['--gateway', gateway, netid, cidr] position_names = ['ip_version', 'network_id', 'cidr', 'gateway_ip'] position_values = [4, netid, cidr, gateway] self.mox.StubOutWithMock(cmd.log, 'warning') cmd.log.warning(mox.IgnoreArg(), {'ip': 4, 'cidr': '/32'}) self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) self.mox.VerifyAll() self.mox.UnsetStubs() def test_create_subnet_with_ipv6_ra_mode(self): resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--ip-version', '6', '--ipv6-ra-mode', 'dhcpv6-stateful', netid, cidr] position_names = ['ip_version', 'ipv6_ra_mode', 'network_id', 'cidr'] position_values = [6, 'dhcpv6-stateful', netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_with_ipv6_address_mode(self): resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--ip-version', '6', '--ipv6-address-mode', 'dhcpv6-stateful', netid, cidr] position_names = ['ip_version', 'ipv6_address_mode', 'network_id', 'cidr'] position_values = [6, 'dhcpv6-stateful', netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_with_ipv6_modes(self): resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--ip-version', '6', '--ipv6-address-mode', 'slaac', '--ipv6-ra-mode', 'slaac', netid, cidr] position_names = ['ip_version', 'ipv6_address_mode', 'ipv6_ra_mode', 'network_id', 'cidr'] position_values = [6, 'slaac', 'slaac', netid, cidr] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_with_ipv6_ra_mode_ipv4(self): resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--ip-version', '4', '--ipv6-ra-mode', 'slaac', netid, cidr] position_names = ['ip_version', 'ipv6_ra_mode', 'network_id', 'cidr'] position_values = [4, None, netid, cidr] self._test_create_resource( resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid', no_api_call=True, expected_exception=exceptions.CommandError) def test_create_subnet_with_ipv6_address_mode_ipv4(self): resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'prefixvalue' args = ['--tenant_id', 'tenantid', '--ip-version', '4', '--ipv6-address-mode', 'slaac', netid, cidr] position_names = ['ip_version', 'ipv6_address_mode', 'network_id', 'cidr'] position_values = [4, None, netid, cidr] self._test_create_resource( resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid', no_api_call=True, expected_exception=exceptions.CommandError) def test_create_subnet_with_subnetpool_ipv6_and_ip_ver_ignored(self): resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = ['--tenant_id', 'tenantid', '--ip-version', '4', '--subnetpool', 'subnetpool_id', netid] position_names = ['ip_version', 'network_id', 'subnetpool_id'] position_values = [6, netid, 'subnetpool_id'] self.mox.StubOutWithMock(neutronV20, 'find_resource_by_name_or_id') neutronV20.find_resource_by_name_or_id( self.client, 'subnetpool', 'subnetpool_id').AndReturn({'id': 'subnetpool_id', 'ip_version': 6}) self._test_create_resource( resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid') def test_create_subnet_with_subnetpool_ipv4_with_cidr_wildcard(self): resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' cidr = 'cidrwildcard' args = ['--tenant_id', 'tenantid', '--ip-version', '4', '--ipv6-address-mode', 'slaac', '--subnetpool', 'subnetpool_id', netid, cidr] position_names = ['ip_version', 'ipv6_address_mode', 'network_id', 'subnetpool_id', 'cidr'] position_values = [4, None, netid, 'subnetpool_id', cidr] self.mox.StubOutWithMock(neutronV20, 'find_resource_by_name_or_id') neutronV20.find_resource_by_name_or_id( self.client, 'subnetpool', 'subnetpool_id').AndReturn({'id': 'subnetpool_id', 'ip_version': 4}) self._test_create_resource( resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid', no_api_call=True, expected_exception=exceptions.CommandError) def test_create_subnet_with_subnetpool_ipv4_with_prefixlen(self): resource = 'subnet' cmd = subnet.CreateSubnet(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' netid = 'netid' args = ['--tenant_id', 'tenantid', '--ip-version', '4', '--ipv6-address-mode', 'slaac', '--subnetpool', 'subnetpool_id', '--prefixlen', '31', netid] position_names = ['ip_version', 'ipv6_address_mode', 'network_id', 'subnetpool_id'] position_values = [4, None, netid, 'subnetpool_id'] self.mox.StubOutWithMock(neutronV20, 'find_resource_by_name_or_id') neutronV20.find_resource_by_name_or_id( self.client, 'subnetpool', 'subnetpool_id').AndReturn({'id': 'subnetpool_id', 'ip_version': 4}) self._test_create_resource( resource, cmd, name, myid, args, position_names, position_values, tenant_id='tenantid', no_api_call=True, expected_exception=exceptions.CommandError) def test_list_subnets_detail(self): # List subnets: -D. resources = "subnets" cmd = subnet.ListSubnet(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_subnets_tags(self): # List subnets: -- --tags a b. resources = "subnets" cmd = subnet.ListSubnet(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, tags=['a', 'b']) def test_list_subnets_detail_tags(self): # List subnets: -D -- --tags a b. resources = "subnets" cmd = subnet.ListSubnet(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, detail=True, tags=['a', 'b']) def test_list_subnets_fields(self): # List subnets: --fields a --fields b -- --fields c d. resources = "subnets" cmd = subnet.ListSubnet(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, fields_1=['a', 'b'], fields_2=['c', 'd']) def test_list_subnets_pagination(self): resources = "subnets" cmd = subnet.ListSubnet(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_list_subnets_sort(self): # List subnets: --sort-key name --sort-key id --sort-key asc # --sort-key desc resources = "subnets" cmd = subnet.ListSubnet(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, sort_key=["name", "id"], sort_dir=["asc", "desc"]) def test_list_subnets_limit(self): # List subnets: -P. resources = "subnets" cmd = subnet.ListSubnet(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, page_size=1000) def test_update_subnet(self): # Update subnet: myid --name myname --tags a b. resource = 'subnet' cmd = subnet.UpdateSubnet(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'myname', '--description', 'cavern', '--tags', 'a', 'b'], {'name': 'myname', 'tags': ['a', 'b'], 'description': 'cavern'}) def test_update_subnet_allocation_pools(self): # Update subnet: myid --name myname --tags a b. resource = 'subnet' cmd = subnet.UpdateSubnet(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--allocation-pool', 'start=1.2.0.2,end=1.2.0.127'], {'allocation_pools': [{'start': '1.2.0.2', 'end': '1.2.0.127'}]} ) def test_update_subnet_enable_disable_dhcp(self): # Update sbunet: --enable-dhcp and --disable-dhcp. resource = 'subnet' cmd = subnet.UpdateSubnet(test_cli20.MyApp(sys.stdout), None) self.assertRaises(exceptions.CommandError, self._test_update_resource, resource, cmd, 'myid', ['myid', '--name', 'myname', '--enable-dhcp', '--disable-dhcp'], {'name': 'myname', }) def test_show_subnet(self): # Show subnet: --fields id --fields name myid. resource = 'subnet' cmd = subnet.ShowSubnet(test_cli20.MyApp(sys.stdout), None) args = ['--fields', 'id', '--fields', 'name', self.test_id] self._test_show_resource(resource, cmd, self.test_id, args, ['id', 'name']) def test_delete_subnet(self): # Delete subnet: subnetid. resource = 'subnet' cmd = subnet.DeleteSubnet(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) python-neutronclient-6.7.0/neutronclient/tests/unit/test_client_extension.py0000666000175100017510000002232513232473350027765 0ustar zuulzuul00000000000000# Copyright 2015 Rackspace Hosting Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import inspect import sys import mock from neutronclient.common import extension from neutronclient.neutron.v2_0.contrib import _fox_sockets as fox_sockets from neutronclient import shell from neutronclient.tests.unit import test_cli20 class CLITestV20ExtensionJSON(test_cli20.CLITestV20Base): non_admin_status_resources = ['fox_socket'] def setUp(self): # need to mock before super because extensions loaded on instantiation self._mock_extension_loading() super(CLITestV20ExtensionJSON, self).setUp(plurals={'tags': 'tag'}) def _mock_extension_loading(self): ext_pkg = 'neutronclient.common.extension' contrib = mock.patch(ext_pkg + '._discover_via_entry_points').start() contrib.return_value = [("_fox_sockets", fox_sockets)] return contrib def test_ext_cmd_loaded(self): neutron_shell = shell.NeutronShell('2.0') ext_cmd = {'fox-sockets-list': fox_sockets.FoxInSocketsList, 'fox-sockets-create': fox_sockets.FoxInSocketsCreate, 'fox-sockets-update': fox_sockets.FoxInSocketsUpdate, 'fox-sockets-delete': fox_sockets.FoxInSocketsDelete, 'fox-sockets-show': fox_sockets.FoxInSocketsShow} for cmd_name, cmd_class in ext_cmd.items(): found = neutron_shell.command_manager.find_command([cmd_name]) self.assertEqual(cmd_class, found[0]) def test_ext_cmd_help_doc_with_extension_name(self): neutron_shell = shell.NeutronShell('2.0') ext_cmd = {'fox-sockets-list': fox_sockets.FoxInSocketsList, 'fox-sockets-create': fox_sockets.FoxInSocketsCreate, 'fox-sockets-update': fox_sockets.FoxInSocketsUpdate, 'fox-sockets-delete': fox_sockets.FoxInSocketsDelete, 'fox-sockets-show': fox_sockets.FoxInSocketsShow} for cmd_name, cmd_class in ext_cmd.items(): found = neutron_shell.command_manager.find_command([cmd_name]) found_factory = found[0] self.assertEqual(cmd_class, found_factory) self.assertTrue(found_factory.__doc__.startswith("[_fox_sockets]")) def test_delete_fox_socket(self): # Delete fox socket: myid. resource = 'fox_socket' cmd = fox_sockets.FoxInSocketsDelete(test_cli20.MyApp(sys.stdout), None) myid = 'myid' args = [myid] self._test_delete_resource(resource, cmd, myid, args) def test_update_fox_socket(self): # Update fox_socket: myid --name myname. resource = 'fox_socket' cmd = fox_sockets.FoxInSocketsUpdate(test_cli20.MyApp(sys.stdout), None) self._test_update_resource(resource, cmd, 'myid', ['myid', '--name', 'myname'], {'name': 'myname'}) def test_create_fox_socket(self): # Create fox_socket: myname. resource = 'fox_socket' cmd = fox_sockets.FoxInSocketsCreate(test_cli20.MyApp(sys.stdout), None) name = 'myname' myid = 'myid' args = [name, ] position_names = ['name', ] position_values = [name, ] self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) def test_list_fox_sockets(self): # List fox_sockets. resources = 'fox_sockets' cmd = fox_sockets.FoxInSocketsList(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) def test_list_fox_pagination(self): resources = 'fox_sockets' cmd = fox_sockets.FoxInSocketsList(test_cli20.MyApp(sys.stdout), None) self._test_list_resources_with_pagination(resources, cmd) def test_show_fox_socket(self): # Show fox_socket: --fields id --fields name myid. resource = 'fox_socket' cmd = fox_sockets.FoxInSocketsShow(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']) class CLITestV20ExtensionJSONAlternatePlurals(test_cli20.CLITestV20Base): class IPAddress(extension.NeutronClientExtension): resource = 'ip_address' resource_plural = '%ses' % resource object_path = '/%s' % resource_plural resource_path = '/%s/%%s' % resource_plural versions = ['2.0'] class IPAddressesList(extension.ClientExtensionList, IPAddress): shell_command = 'ip-address-list' def setUp(self): # need to mock before super because extensions loaded on instantiation self._mock_extension_loading() super(CLITestV20ExtensionJSONAlternatePlurals, self).setUp() def _mock_extension_loading(self): ext_pkg = 'neutronclient.common.extension' contrib = mock.patch(ext_pkg + '._discover_via_entry_points').start() ip_address = mock.Mock() ip_address.IPAddress = self.IPAddress ip_address.IPAddressesList = self.IPAddressesList contrib.return_value = [("ip_address", ip_address)] return contrib def test_ext_cmd_loaded(self): neutron_shell = shell.NeutronShell('2.0') ext_cmd = {'ip-address-list': self.IPAddressesList} for cmd_name, cmd_class in ext_cmd.items(): found = neutron_shell.command_manager.find_command([cmd_name]) self.assertEqual(cmd_class, found[0]) def test_list_ip_addresses(self): # List ip_addresses. resources = 'ip_addresses' cmd = self.IPAddressesList(test_cli20.MyApp(sys.stdout), None) self._test_list_resources(resources, cmd, True) class CLITestV20ExtensionJSONChildResource(test_cli20.CLITestV20Base): class Child(extension.NeutronClientExtension): parent_resource = 'parents' child_resource = 'child' resource = '%s_%s' % (parent_resource, child_resource) resource_plural = '%sren' % resource child_resource_plural = '%ren' % child_resource object_path = '/%s/%%s/%s' % (parent_resource, child_resource_plural) resource_path = '/%s/%%s/%s/%%s' % (parent_resource, child_resource_plural) versions = ['2.0'] class ChildrenList(extension.ClientExtensionList, Child): shell_command = 'parent-child-list' class ChildShow(extension.ClientExtensionShow, Child): shell_command = 'parent-child-show' class ChildUpdate(extension.ClientExtensionUpdate, Child): shell_command = 'parent-child-update' class ChildDelete(extension.ClientExtensionDelete, Child): shell_command = 'parent-child-delete' class ChildCreate(extension.ClientExtensionCreate, Child): shell_command = 'parent-child-create' def setUp(self): # need to mock before super because extensions loaded on instantiation self._mock_extension_loading() super(CLITestV20ExtensionJSONChildResource, self).setUp() def _mock_extension_loading(self): ext_pkg = 'neutronclient.common.extension' contrib = mock.patch(ext_pkg + '._discover_via_entry_points').start() child = mock.Mock() child.Child = self.Child child.ChildrenList = self.ChildrenList child.ChildShow = self.ChildShow child.ChildUpdate = self.ChildUpdate child.ChildDelete = self.ChildDelete child.ChildCreate = self.ChildCreate contrib.return_value = [("child", child)] return contrib def test_ext_cmd_loaded(self): neutron_shell = shell.NeutronShell('2.0') ext_cmd = {'parent-child-list': self.ChildrenList, 'parent-child-show': self.ChildShow, 'parent-child-update': self.ChildUpdate, 'parent-child-delete': self.ChildDelete, 'parent-child-create': self.ChildCreate} for cmd_name, cmd_class in ext_cmd.items(): found = neutron_shell.command_manager.find_command([cmd_name]) self.assertEqual(cmd_class, found[0]) def test_client_methods_have_parent_id_arg(self): methods = (self.client.list_parents_children, self.client.show_parents_child, self.client.update_parents_child, self.client.delete_parents_child, self.client.create_parents_child) for method in methods: argspec = inspect.getargspec(method) self.assertIn("parent_id", argspec.args) python-neutronclient-6.7.0/neutronclient/tests/unit/__init__.py0000666000175100017510000000000013232473350025075 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/tests/unit/test_shell.py0000666000175100017510000003367513232473350025534 0ustar zuulzuul00000000000000# Copyright (C) 2013 Yahoo! Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import argparse import logging import os import re import sys import fixtures from keystoneauth1 import session import mock import six import testtools from testtools import matchers from neutronclient.common import clientmanager from neutronclient.neutron.v2_0 import network from neutronclient import shell as openstack_shell DEFAULT_USERNAME = 'username' DEFAULT_PASSWORD = 'password' DEFAULT_TENANT_ID = 'tenant_id' DEFAULT_TENANT_NAME = 'tenant_name' DEFAULT_AUTH_URL = 'http://127.0.0.1:5000/v2.0/' DEFAULT_TOKEN = '3bcc3d3a03f44e3d8377f9247b0ad155' DEFAULT_URL = 'http://quantum.example.org:9696/' DEFAULT_REGION = 'regionOne' DEFAULT_ENDPOINT_TYPE = 'public' DEFAULT_API_VERSION = '2.0' DEFAULT_SERVICE_TYPE = 'network' DEFAULT_SERVICE_NAME = 'neutron' DEFAULT_RETRIES = 3 DEFAULT_TIMEOUT = 3.0 class ShellTest(testtools.TestCase): FAKE_ENV = { 'OS_USERNAME': DEFAULT_USERNAME, 'OS_PASSWORD': DEFAULT_PASSWORD, 'OS_TENANT_ID': DEFAULT_TENANT_ID, 'OS_TENANT_NAME': DEFAULT_TENANT_NAME, 'OS_AUTH_URL': DEFAULT_AUTH_URL, 'OS_REGION_NAME': None, 'HTTP_PROXY': None, 'http_proxy': None, } # Patch os.environ to avoid required auth info. def setUp(self): super(ShellTest, self).setUp() for var in self.FAKE_ENV: self.useFixture( fixtures.EnvironmentVariable( var, self.FAKE_ENV[var])) def shell(self, argstr, check=False, expected_val=0): # expected_val is the expected return value after executing # the command in NeutronShell orig = (sys.stdout, sys.stderr) clean_env = {} _old_env, os.environ = os.environ, clean_env.copy() try: sys.stdout = six.moves.cStringIO() sys.stderr = six.moves.cStringIO() _shell = openstack_shell.NeutronShell('2.0') _shell.run(argstr.split()) except SystemExit: exc_type, exc_value, exc_traceback = sys.exc_info() self.assertEqual(expected_val, exc_value.code) finally: stdout = sys.stdout.getvalue() stderr = sys.stderr.getvalue() sys.stdout.close() sys.stderr.close() sys.stdout, sys.stderr = orig os.environ = _old_env return stdout, stderr def test_run_unknown_command(self): self.useFixture(fixtures.FakeLogger(level=logging.DEBUG)) stdout, stderr = self.shell('fake', check=True) self.assertFalse(stdout) self.assertEqual("Unknown command ['fake']", stderr.strip()) def test_help(self): required = 'usage:' help_text, stderr = self.shell('help') self.assertThat( help_text, matchers.MatchesRegex(required)) def test_bash_completion(self): required = '.*os_user_domain_id.*' bash_completion, stderr = self.shell('bash-completion') self.assertThat( bash_completion, matchers.MatchesRegex(required)) def test_help_on_subcommand(self): required = [ '.*?^usage: .* quota-list'] stdout, stderr = self.shell('help quota-list') for r in required: self.assertThat( stdout, matchers.MatchesRegex(r, re.DOTALL | re.MULTILINE)) def test_help_command(self): required = 'usage:' help_text, stderr = self.shell('help network-create') self.assertThat( help_text, matchers.MatchesRegex(required)) def test_bash_completion_in_outputs_of_help_command(self): help_text, stderr = self.shell('help') completion_cmd = "bash-completion" completion_help_str = ("Prints all of the commands and options " "for bash-completion.") self.assertIn(completion_cmd, help_text) self.assertIn(completion_help_str, help_text) def test_bash_completion_command(self): # just check we have some output required = [ '.*--tenant_id', '.*help', '.*--dns-nameserver'] help_text, stderr = self.shell('neutron bash-completion') for r in required: self.assertThat(help_text, matchers.MatchesRegex(r, re.DOTALL | re.MULTILINE)) def test_build_option_parser(self): neutron_shell = openstack_shell.NeutronShell('2.0') result = neutron_shell.build_option_parser('descr', '2.0') self.assertIsInstance(result, argparse.ArgumentParser) @mock.patch.object(openstack_shell.NeutronShell, 'run') def test_main_with_unicode(self, fake_shell): unicode_text = u'\u7f51\u7edc' argv = ['net-list', unicode_text, unicode_text] fake_shell.return_value = 0 ret = openstack_shell.main(argv=argv) fake_shell.assert_called_once_with([u'net-list', unicode_text, unicode_text]) self.assertEqual(0, ret) def test_endpoint_option(self): shell = openstack_shell.NeutronShell('2.0') parser = shell.build_option_parser('descr', '2.0') # Neither $OS_ENDPOINT_TYPE nor --os-endpoint-type namespace = parser.parse_args([]) self.assertEqual('public', namespace.os_endpoint_type) # --endpoint-type but not $OS_ENDPOINT_TYPE namespace = parser.parse_args(['--os-endpoint-type=admin']) self.assertEqual('admin', namespace.os_endpoint_type) def test_endpoint_environment_variable(self): fixture = fixtures.EnvironmentVariable("OS_ENDPOINT_TYPE", "public") self.useFixture(fixture) shell = openstack_shell.NeutronShell('2.0') parser = shell.build_option_parser('descr', '2.0') # $OS_ENDPOINT_TYPE but not --endpoint-type namespace = parser.parse_args([]) self.assertEqual("public", namespace.os_endpoint_type) # --endpoint-type and $OS_ENDPOINT_TYPE namespace = parser.parse_args(['--endpoint-type=admin']) self.assertEqual('admin', namespace.endpoint_type) def test_timeout_option(self): shell = openstack_shell.NeutronShell('2.0') parser = shell.build_option_parser('descr', '2.0') # Neither $OS_ENDPOINT_TYPE nor --endpoint-type namespace = parser.parse_args([]) self.assertIsNone(namespace.http_timeout) # --endpoint-type but not $OS_ENDPOINT_TYPE namespace = parser.parse_args(['--http-timeout=50']) self.assertEqual(50, namespace.http_timeout) def test_timeout_environment_variable(self): fixture = fixtures.EnvironmentVariable("OS_NETWORK_TIMEOUT", "50") self.useFixture(fixture) shell = openstack_shell.NeutronShell('2.0') parser = shell.build_option_parser('descr', '2.0') namespace = parser.parse_args([]) self.assertEqual(50, namespace.http_timeout) def test_run_incomplete_command(self): self.useFixture(fixtures.FakeLogger(level=logging.DEBUG)) cmd = ( '--os-username test --os-password test --os-project-id test ' '--os-auth-strategy keystone --os-auth-url ' '%s port-create' % DEFAULT_AUTH_URL) stdout, stderr = self.shell(cmd, check=True, expected_val=2) search_str = "Try 'neutron help port-create' for more information" self.assertTrue(any(search_str in string for string in stderr.split('\n'))) def _test_authenticate_user(self, expect_verify, expect_insecure, **options): base_options = {'os_cloud': None, 'http_timeout': DEFAULT_TIMEOUT, 'region_name': DEFAULT_REGION, 'network_service_name': DEFAULT_SERVICE_NAME, 'neutron_service_type': DEFAULT_SERVICE_TYPE} options.update(base_options) if options.get('os_token'): options.update({'auth_type': 'token'}) options.update({'os_token': 'token', 'os_url': 'url'}) else: options.update({'os_token': None, 'os_url': None}) with mock.patch.object(openstack_shell.NeutronShell, 'run_subcommand'), \ mock.patch.object(session, 'Session') as session_mock, \ mock.patch.object(clientmanager, 'ClientManager') as cmgr_mock: shell = openstack_shell.NeutronShell(DEFAULT_API_VERSION) shell.options = mock.Mock(spec=options.keys()) for k, v in options.items(): setattr(shell.options, k, v) shell.options.os_endpoint_type = DEFAULT_ENDPOINT_TYPE shell.options.retries = DEFAULT_RETRIES if not (options.get('os_token') and options.get('os_url')): auth = mock.ANY auth_session = mock.sentinel.session session_mock.return_value = auth_session else: auth = None auth_session = None shell.authenticate_user() if not (options.get('os_token') and options.get('os_url')): session_mock.assert_called_once_with( auth=mock.ANY, verify=expect_verify, cert=options.get('cert'), timeout=DEFAULT_TIMEOUT) else: self.assertFalse(session_mock.called) cmgr_mock.assert_called_once_with( retries=DEFAULT_RETRIES, raise_errors=False, session=auth_session, url=options.get('os_url'), token=options.get('os_token'), region_name=DEFAULT_REGION, api_version=DEFAULT_API_VERSION, service_type=DEFAULT_SERVICE_TYPE, service_name=DEFAULT_SERVICE_NAME, endpoint_type=DEFAULT_ENDPOINT_TYPE, auth=auth, insecure=expect_insecure, log_credentials=True) def test_authenticate_secure_with_cacert_with_cert(self): self._test_authenticate_user( insecure=False, cacert='cacert', cert='cert', expect_verify='cacert', expect_insecure=False) def test_authenticate_secure_with_cacert_with_cert_with_token(self): self._test_authenticate_user( os_token='token', insecure=False, cacert='cacert', cert='cert', expect_verify='cacert', expect_insecure=False) def test_authenticate_insecure_with_cacert_with_cert(self): self._test_authenticate_user( insecure=True, cacert='cacert', cert='cert', expect_verify=False, expect_insecure=True) def test_authenticate_insecure_with_cacert_with_cert_with_token(self): self._test_authenticate_user( os_token='token', insecure=True, cacert='cacert', cert='cert', expect_verify=False, expect_insecure=True) def test_authenticate_secure_without_cacert_with_cert(self): self._test_authenticate_user( insecure=False, cert='cert', expect_verify=True, expect_insecure=False) def test_authenticate_secure_without_cacert_with_cert_with_token(self): self._test_authenticate_user( os_token='token', insecure=False, cert='cert', expect_verify=True, expect_insecure=False) def test_authenticate_insecure_without_cacert_with_cert(self): self._test_authenticate_user( insecure=True, cert='cert', expect_verify=False, expect_insecure=True) def test_authenticate_insecure_without_cacert_with_cert_with_token(self): self._test_authenticate_user( os_token='token', insecure=True, cert='cert', expect_verify=False, expect_insecure=True) def test_authenticate_secure_with_cacert_without_cert(self): self._test_authenticate_user( insecure=False, cacert='cacert', expect_verify='cacert', expect_insecure=False) def test_authenticate_secure_with_cacert_without_cert_with_token(self): self._test_authenticate_user( os_token='token', insecure=False, cacert='cacert', expect_verify='cacert', expect_insecure=False) def test_authenticate_insecure_with_cacert_without_cert(self): self._test_authenticate_user( insecure=True, cacert='cacert', expect_verify=False, expect_insecure=True) def test_authenticate_insecure_with_cacert_without_cert_with_token(self): self._test_authenticate_user( os_token='token', insecure=True, cacert='cacert', expect_verify=False, expect_insecure=True) def test_commands_dict_populated(self): # neutron.shell.COMMANDS is populated once NeutronShell is initialized. # To check COMMANDS during NeutronShell initialization, # reset COMMANDS to some dummy value before calling NeutronShell(). self.useFixture(fixtures.MockPatchObject(openstack_shell, 'COMMANDS', None)) openstack_shell.NeutronShell('2.0') self.assertDictContainsSubset( {'net-create': network.CreateNetwork, 'net-delete': network.DeleteNetwork, 'net-list': network.ListNetwork, 'net-show': network.ShowNetwork, 'net-update': network.UpdateNetwork}, openstack_shell.COMMANDS['2.0']) python-neutronclient-6.7.0/neutronclient/tests/__init__.py0000666000175100017510000000000013232473350024116 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/common/0000775000175100017510000000000013232473710022143 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/common/utils.py0000666000175100017510000001761613232473350023672 0ustar zuulzuul00000000000000# Copyright 2011, VMware, Inc. # # 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. # # Borrowed from nova code base, more utilities will be added/borrowed as and # when needed. """Utilities and helper functions.""" import argparse import functools import hashlib import logging import os from oslo_utils import encodeutils from oslo_utils import importutils import six from neutronclient._i18n import _ from neutronclient.common import exceptions SENSITIVE_HEADERS = ('X-Auth-Token',) def env(*vars, **kwargs): """Returns the first environment variable set. If none are non-empty, defaults to '' or keyword arg default. """ for v in vars: value = os.environ.get(v) if value: return value return kwargs.get('default', '') def convert_to_uppercase(string): return string.upper() def convert_to_lowercase(string): return string.lower() def get_client_class(api_name, version, version_map): """Returns the client class for the requested API version. :param api_name: the name of the API, e.g. 'compute', 'image', etc :param version: the requested API version :param version_map: a dict of client classes keyed by version :rtype: a client class for the requested API version """ try: client_path = version_map[str(version)] except (KeyError, ValueError): msg = _("Invalid %(api_name)s client version '%(version)s'. must be " "one of: %(map_keys)s") msg = msg % {'api_name': api_name, 'version': version, 'map_keys': ', '.join(version_map.keys())} raise exceptions.UnsupportedVersion(msg) return importutils.import_class(client_path) def get_item_properties(item, fields, mixed_case_fields=(), formatters=None): """Return a tuple containing the item properties. :param item: a single item resource (e.g. Server, Tenant, etc) :param fields: tuple of strings with the desired field names :param mixed_case_fields: tuple of field names to preserve case :param formatters: dictionary mapping field names to callables to format the values """ if formatters is None: formatters = {} row = [] for field in fields: if field in formatters: row.append(formatters[field](item)) else: if field in mixed_case_fields: field_name = field.replace(' ', '_') else: field_name = field.lower().replace(' ', '_') if not hasattr(item, field_name) and isinstance(item, dict): data = item[field_name] else: data = getattr(item, field_name, '') if data is None: data = '' row.append(data) return tuple(row) def str2bool(strbool): if strbool is None: return None return strbool.lower() == 'true' def str2dict(strdict, required_keys=None, optional_keys=None): """Convert key1=value1,key2=value2,... string into dictionary. :param strdict: string in the form of key1=value1,key2=value2 :param required_keys: list of required keys. All keys in this list must be specified. Otherwise ArgumentTypeError will be raised. If this parameter is unspecified, no required key check will be done. :param optional_keys: list of optional keys. This parameter is used for valid key check. When at least one of required_keys and optional_keys, a key must be a member of either of required_keys or optional_keys. Otherwise, ArgumentTypeError will be raised. When both required_keys and optional_keys are unspecified, no valid key check will be done. """ result = {} if strdict: i = 0 kvlist = [] for kv in strdict.split(','): if '=' in kv: kvlist.append(kv) i += 1 elif i == 0: msg = _("missing value for key '%s'") raise argparse.ArgumentTypeError(msg % kv) else: kvlist[i-1] = "%s,%s" % (kvlist[i-1], kv) for kv in kvlist: key, sep, value = kv.partition('=') if not sep: msg = _("invalid key-value '%s', expected format: key=value") raise argparse.ArgumentTypeError(msg % kv) result[key] = value valid_keys = set(required_keys or []) | set(optional_keys or []) if valid_keys: invalid_keys = [k for k in result if k not in valid_keys] if invalid_keys: msg = _("Invalid key(s) '%(invalid_keys)s' specified. " "Valid key(s): '%(valid_keys)s'.") raise argparse.ArgumentTypeError( msg % {'invalid_keys': ', '.join(sorted(invalid_keys)), 'valid_keys': ', '.join(sorted(valid_keys))}) if required_keys: not_found_keys = [k for k in required_keys if k not in result] if not_found_keys: msg = _("Required key(s) '%s' not specified.") raise argparse.ArgumentTypeError(msg % ', '.join(not_found_keys)) return result def str2dict_type(optional_keys=None, required_keys=None): return functools.partial(str2dict, optional_keys=optional_keys, required_keys=required_keys) def http_log_req(_logger, args, kwargs): if not _logger.isEnabledFor(logging.DEBUG): return string_parts = ['curl -i'] for element in args: if element in ('GET', 'POST', 'DELETE', 'PUT'): string_parts.append(' -X %s' % element) else: string_parts.append(' %s' % element) for (key, value) in six.iteritems(kwargs['headers']): if key in SENSITIVE_HEADERS: v = value.encode('utf-8') h = hashlib.sha1(v) d = h.hexdigest() value = "{SHA1}%s" % d header = ' -H "%s: %s"' % (key, value) string_parts.append(header) if 'body' in kwargs and kwargs['body']: string_parts.append(" -d '%s'" % (kwargs['body'])) req = encodeutils.safe_encode("".join(string_parts)) _logger.debug("REQ: %s", req) def http_log_resp(_logger, resp, body): if not _logger.isEnabledFor(logging.DEBUG): return _logger.debug("RESP: %(code)s %(headers)s %(body)s", {'code': resp.status_code, 'headers': resp.headers, 'body': body}) def _safe_encode_without_obj(data): if isinstance(data, six.string_types): return encodeutils.safe_encode(data) return data def safe_encode_list(data): return list(map(_safe_encode_without_obj, data)) def safe_encode_dict(data): def _encode_item(item): k, v = item if isinstance(v, list): return (k, safe_encode_list(v)) elif isinstance(v, dict): return (k, safe_encode_dict(v)) return (k, _safe_encode_without_obj(v)) return dict(list(map(_encode_item, data.items()))) def add_boolean_argument(parser, name, **kwargs): for keyword in ('metavar', 'choices'): kwargs.pop(keyword, None) default = kwargs.pop('default', argparse.SUPPRESS) parser.add_argument( name, metavar='{True,False}', choices=['True', 'true', 'False', 'false'], default=default, **kwargs) python-neutronclient-6.7.0/neutronclient/common/serializer.py0000666000175100017510000000734613232473350024702 0ustar zuulzuul00000000000000# Copyright 2013 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 # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo_serialization import jsonutils import six from neutronclient._i18n import _ from neutronclient.common import exceptions as exception if six.PY3: long = int class ActionDispatcher(object): """Maps method name to local methods through action name.""" def dispatch(self, *args, **kwargs): """Find and call local method.""" action = kwargs.pop('action', 'default') action_method = getattr(self, str(action), self.default) return action_method(*args, **kwargs) def default(self, data): raise NotImplementedError() class DictSerializer(ActionDispatcher): """Default request body serialization.""" def serialize(self, data, action='default'): return self.dispatch(data, action=action) def default(self, data): return "" class JSONDictSerializer(DictSerializer): """Default JSON request body serialization.""" def default(self, data): def sanitizer(obj): return six.text_type(obj) return jsonutils.dumps(data, default=sanitizer) class TextDeserializer(ActionDispatcher): """Default request body deserialization.""" def deserialize(self, datastring, action='default'): return self.dispatch(datastring, action=action) def default(self, datastring): return {} class JSONDeserializer(TextDeserializer): def _from_json(self, datastring): try: return jsonutils.loads(datastring) except ValueError: msg = _("Cannot understand JSON") raise exception.MalformedResponseBody(reason=msg) def default(self, datastring): return {'body': self._from_json(datastring)} # NOTE(maru): this class is duplicated from neutron.wsgi class Serializer(object): """Serializes and deserializes dictionaries to certain MIME types.""" def __init__(self, metadata=None): """Create a serializer based on the given WSGI environment. 'metadata' is an optional dict mapping MIME types to information needed to serialize a dictionary to that type. """ self.metadata = metadata or {} def _get_serialize_handler(self, content_type): handlers = { 'application/json': JSONDictSerializer(), } try: return handlers[content_type] except Exception: raise exception.InvalidContentType(content_type=content_type) def serialize(self, data): """Serialize a dictionary into the specified content type.""" return self._get_serialize_handler("application/json").serialize(data) def deserialize(self, datastring): """Deserialize a string to a dictionary. The string must be in the format of a supported MIME type. """ return self.get_deserialize_handler("application/json").deserialize( datastring) def get_deserialize_handler(self, content_type): handlers = { 'application/json': JSONDeserializer(), } try: return handlers[content_type] except Exception: raise exception.InvalidContentType(content_type=content_type) python-neutronclient-6.7.0/neutronclient/common/exceptions.py0000666000175100017510000001520413232473350024702 0ustar zuulzuul00000000000000# Copyright 2011 VMware, Inc # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo_utils import encodeutils import six from neutronclient._i18n import _ """ Neutron base exception handling. Exceptions are classified into three categories: * Exceptions corresponding to exceptions from neutron server: This type of exceptions should inherit one of exceptions in HTTP_EXCEPTION_MAP. * Exceptions from client library: This type of exceptions should inherit NeutronClientException. * Exceptions from CLI code: This type of exceptions should inherit NeutronCLIError. """ # NOTE: This method is defined here to avoid # an import loop between common.utils and this module. def _safe_decode_dict(kwargs): for k, v in kwargs.items(): kwargs[k] = encodeutils.safe_decode(v) return kwargs @six.python_2_unicode_compatible class NeutronException(Exception): """Base Neutron Exception. To correctly use this class, inherit from it and define a 'message' property. That message will get printf'd with the keyword arguments provided to the constructor. """ message = _("An unknown exception occurred.") def __init__(self, message=None, **kwargs): if message: self.message = message try: self._error_string = self.message % _safe_decode_dict(kwargs) except Exception: # at least get the core message out if something happened self._error_string = self.message def __str__(self): return self._error_string class NeutronClientException(NeutronException): """Base exception which exceptions from Neutron are mapped into. NOTE: on the client side, we use different exception types in order to allow client library users to handle server exceptions in try...except blocks. The actual error message is the one generated on the server side. """ status_code = 0 req_ids_msg = _("Neutron server returns request_ids: %s") request_ids = [] def __init__(self, message=None, **kwargs): self.request_ids = kwargs.get('request_ids') if 'status_code' in kwargs: self.status_code = kwargs['status_code'] if self.request_ids: req_ids_msg = self.req_ids_msg % self.request_ids if message: message = _('%(msg)s\n%(id)s') % {'msg': message, 'id': req_ids_msg} else: message = req_ids_msg super(NeutronClientException, self).__init__(message, **kwargs) # Base exceptions from Neutron class BadRequest(NeutronClientException): status_code = 400 class Unauthorized(NeutronClientException): status_code = 401 message = _("Unauthorized: bad credentials.") class Forbidden(NeutronClientException): status_code = 403 message = _("Forbidden: your credentials don't give you access to this " "resource.") class NotFound(NeutronClientException): status_code = 404 class Conflict(NeutronClientException): status_code = 409 class InternalServerError(NeutronClientException): status_code = 500 class ServiceUnavailable(NeutronClientException): status_code = 503 HTTP_EXCEPTION_MAP = { 400: BadRequest, 401: Unauthorized, 403: Forbidden, 404: NotFound, 409: Conflict, 500: InternalServerError, 503: ServiceUnavailable, } # Exceptions mapped to Neutron server exceptions # These are defined if a user of client library needs specific exception. # Exception name should be + 'Client' # e.g., NetworkNotFound -> NetworkNotFoundClient class NetworkNotFoundClient(NotFound): pass class PortNotFoundClient(NotFound): pass class StateInvalidClient(BadRequest): pass class NetworkInUseClient(Conflict): pass class PortInUseClient(Conflict): pass class IpAddressInUseClient(Conflict): pass class IpAddressAlreadyAllocatedClient(Conflict): pass class InvalidIpForNetworkClient(BadRequest): pass class InvalidIpForSubnetClient(BadRequest): pass class OverQuotaClient(Conflict): pass class IpAddressGenerationFailureClient(Conflict): pass class MacAddressInUseClient(Conflict): pass class HostNotCompatibleWithFixedIpsClient(Conflict): pass class ExternalIpAddressExhaustedClient(BadRequest): pass # Exceptions from client library class NoAuthURLProvided(Unauthorized): message = _("auth_url was not provided to the Neutron client") class EndpointNotFound(NeutronClientException): message = _("Could not find Service or Region in Service Catalog.") class EndpointTypeNotFound(NeutronClientException): message = _("Could not find endpoint type %(type_)s in Service Catalog.") class AmbiguousEndpoints(NeutronClientException): message = _("Found more than one matching endpoint in Service Catalog: " "%(matching_endpoints)") class RequestURITooLong(NeutronClientException): """Raised when a request fails with HTTP error 414.""" def __init__(self, **kwargs): self.excess = kwargs.get('excess', 0) super(RequestURITooLong, self).__init__(**kwargs) class ConnectionFailed(NeutronClientException): message = _("Connection to neutron failed: %(reason)s") class SslCertificateValidationError(NeutronClientException): message = _("SSL certificate validation has failed: %(reason)s") class MalformedResponseBody(NeutronClientException): message = _("Malformed response body: %(reason)s") class InvalidContentType(NeutronClientException): message = _("Invalid content type %(content_type)s.") # Command line exceptions class NeutronCLIError(NeutronException): """Exception raised when command line parsing fails.""" pass class CommandError(NeutronCLIError): pass class UnsupportedVersion(NeutronCLIError): """Indicates usage of an unsupported API version Indicates that the user is trying to use an unsupported version of the API. """ pass class NeutronClientNoUniqueMatch(NeutronCLIError): message = _("Multiple %(resource)s matches found for name '%(name)s'," " use an ID to be more specific.") python-neutronclient-6.7.0/neutronclient/common/extension.py0000666000175100017510000000655213232473350024543 0ustar zuulzuul00000000000000# Copyright 2015 Rackspace Hosting Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from stevedore import extension from neutronclient.neutron import v2_0 as neutronV20 def _discover_via_entry_points(): emgr = extension.ExtensionManager('neutronclient.extension', invoke_on_load=False) return ((ext.name, ext.plugin) for ext in emgr) class NeutronClientExtension(neutronV20.NeutronCommand): pagination_support = False _formatters = {} sorting_support = False class ClientExtensionShow(NeutronClientExtension, neutronV20.ShowCommand): def take_action(self, parsed_args): # NOTE(mdietz): Calls 'execute' to provide a consistent pattern # for any implementers adding extensions with # regard to any other extension verb. return self.execute(parsed_args) def execute(self, parsed_args): return super(ClientExtensionShow, self).take_action(parsed_args) class ClientExtensionList(NeutronClientExtension, neutronV20.ListCommand): def take_action(self, parsed_args): # NOTE(mdietz): Calls 'execute' to provide a consistent pattern # for any implementers adding extensions with # regard to any other extension verb. return self.execute(parsed_args) def execute(self, parsed_args): return super(ClientExtensionList, self).take_action(parsed_args) class ClientExtensionDelete(NeutronClientExtension, neutronV20.DeleteCommand): def take_action(self, parsed_args): # NOTE(mdietz): Calls 'execute' to provide a consistent pattern # for any implementers adding extensions with # regard to any other extension verb. return self.execute(parsed_args) def execute(self, parsed_args): return super(ClientExtensionDelete, self).take_action(parsed_args) class ClientExtensionCreate(NeutronClientExtension, neutronV20.CreateCommand): def take_action(self, parsed_args): # NOTE(mdietz): Calls 'execute' to provide a consistent pattern # for any implementers adding extensions with # regard to any other extension verb. return self.execute(parsed_args) def execute(self, parsed_args): return super(ClientExtensionCreate, self).take_action(parsed_args) class ClientExtensionUpdate(NeutronClientExtension, neutronV20.UpdateCommand): def take_action(self, parsed_args): # NOTE(mdietz): Calls 'execute' to provide a consistent pattern # for any implementers adding extensions with # regard to any other extension verb. return self.execute(parsed_args) def execute(self, parsed_args): return super(ClientExtensionUpdate, self).take_action(parsed_args) python-neutronclient-6.7.0/neutronclient/common/constants.py0000666000175100017510000000203513232473350024533 0ustar zuulzuul00000000000000# Copyright (c) 2012 OpenStack Foundation. # # 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. TYPE_BOOL = "bool" TYPE_INT = "int" TYPE_LONG = "long" TYPE_FLOAT = "float" TYPE_LIST = "list" TYPE_DICT = "dict" PLURALS = {'networks': 'network', 'ports': 'port', 'subnets': 'subnet', 'subnetpools': 'subnetpool', 'dns_nameservers': 'dns_nameserver', 'host_routes': 'host_route', 'allocation_pools': 'allocation_pool', 'fixed_ips': 'fixed_ip', 'extensions': 'extension'} python-neutronclient-6.7.0/neutronclient/common/clientmanager.py0000666000175100017510000001023413232473350025330 0ustar zuulzuul00000000000000# 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 # # 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. # """Manage access to the clients, including authenticating when needed. """ import debtcollector.renames from neutronclient import client from neutronclient.neutron import client as neutron_client class ClientCache(object): """Descriptor class for caching created client handles.""" def __init__(self, factory): self.factory = factory self._handle = None def __get__(self, instance, owner): # Tell the ClientManager to login to keystone if self._handle is None: self._handle = self.factory(instance) return self._handle class ClientManager(object): """Manages access to API clients, including authentication.""" neutron = ClientCache(neutron_client.make_client) # Provide support for old quantum commands (for example # in stable versions) quantum = neutron @debtcollector.renames.renamed_kwarg( 'tenant_id', 'project_id', replace=True) @debtcollector.renames.renamed_kwarg( 'tenant_name', 'project_name', replace=True) def __init__(self, token=None, url=None, auth_url=None, endpoint_type=None, project_name=None, project_id=None, username=None, user_id=None, password=None, region_name=None, api_version=None, auth_strategy=None, insecure=False, ca_cert=None, log_credentials=False, service_type=None, service_name=None, timeout=None, retries=0, raise_errors=True, session=None, auth=None, ): self._token = token self._url = url self._auth_url = auth_url self._service_type = service_type self._service_name = service_name self._endpoint_type = endpoint_type self._project_name = project_name self._project_id = project_id self._username = username self._user_id = user_id self._password = password self._region_name = region_name self._api_version = api_version self._service_catalog = None self._auth_strategy = auth_strategy self._insecure = insecure self._ca_cert = ca_cert self._log_credentials = log_credentials self._timeout = timeout self._retries = retries self._raise_errors = raise_errors self._session = session self._auth = auth return def initialize(self): if not self._url: httpclient = client.construct_http_client( username=self._username, user_id=self._user_id, project_name=self._project_name, project_id=self._project_id, password=self._password, region_name=self._region_name, auth_url=self._auth_url, service_type=self._service_type, service_name=self._service_name, endpoint_type=self._endpoint_type, insecure=self._insecure, ca_cert=self._ca_cert, timeout=self._timeout, session=self._session, auth=self._auth, log_credentials=self._log_credentials) httpclient.authenticate() # Populate other password flow attributes self._token = httpclient.auth_token self._url = httpclient.endpoint_url python-neutronclient-6.7.0/neutronclient/common/validators.py0000666000175100017510000000504113232473350024667 0ustar zuulzuul00000000000000# Copyright 2014 NEC Corporation # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import netaddr from neutronclient._i18n import _ from neutronclient.common import exceptions def validate_int_range(parsed_args, attr_name, min_value=None, max_value=None): val = getattr(parsed_args, attr_name, None) if val is None: return try: if not isinstance(val, int): int_val = int(val, 0) else: int_val = val if ((min_value is None or min_value <= int_val) and (max_value is None or int_val <= max_value)): return except (ValueError, TypeError): pass if min_value is not None and max_value is not None: msg = (_('%(attr_name)s "%(val)s" should be an integer ' '[%(min)i:%(max)i].') % {'attr_name': attr_name.replace('_', '-'), 'val': val, 'min': min_value, 'max': max_value}) elif min_value is not None: msg = (_('%(attr_name)s "%(val)s" should be an integer ' 'greater than or equal to %(min)i.') % {'attr_name': attr_name.replace('_', '-'), 'val': val, 'min': min_value}) elif max_value is not None: msg = (_('%(attr_name)s "%(val)s" should be an integer ' 'smaller than or equal to %(max)i.') % {'attr_name': attr_name.replace('_', '-'), 'val': val, 'max': max_value}) else: msg = (_('%(attr_name)s "%(val)s" should be an integer.') % {'attr_name': attr_name.replace('_', '-'), 'val': val}) raise exceptions.CommandError(msg) def validate_ip_subnet(parsed_args, attr_name): val = getattr(parsed_args, attr_name) if not val: return try: netaddr.IPNetwork(val) except (netaddr.AddrFormatError, ValueError): raise exceptions.CommandError( (_('%(attr_name)s "%(val)s" is not a valid CIDR.') % {'attr_name': attr_name.replace('_', '-'), 'val': val})) python-neutronclient-6.7.0/neutronclient/common/__init__.py0000666000175100017510000000000013232473350024244 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/0000775000175100017510000000000013232473710022345 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/0000775000175100017510000000000013232473710023113 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/tag.py0000666000175100017510000001017613232473350024247 0ustar zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.neutron import v2_0 as neutronv20 # List of resources can be set tag TAG_RESOURCES = ['network', 'subnet', 'port', 'router', 'subnetpool'] def _convert_resource_args(client, parsed_args): resource_type = client.get_resource_plural(parsed_args.resource_type) resource_id = neutronv20.find_resourceid_by_name_or_id( client, parsed_args.resource_type, parsed_args.resource) return resource_type, resource_id def _add_common_arguments(parser): parser.add_argument('--resource-type', choices=TAG_RESOURCES, dest='resource_type', required=True, help=_('Resource Type.')) parser.add_argument('--resource', required=True, help=_('Resource name or ID.')) class AddTag(neutronv20.NeutronCommand): """Add a tag into the resource.""" def get_parser(self, prog_name): parser = super(AddTag, self).get_parser(prog_name) _add_common_arguments(parser) parser.add_argument('--tag', required=True, help=_('Tag to be added.')) return parser def take_action(self, parsed_args): client = self.get_client() if not parsed_args.tag: raise exceptions.CommandError( _('Cannot add an empty value as tag')) resource_type, resource_id = _convert_resource_args(client, parsed_args) client.add_tag(resource_type, resource_id, parsed_args.tag) class ReplaceTag(neutronv20.NeutronCommand): """Replace all tags on the resource.""" def get_parser(self, prog_name): parser = super(ReplaceTag, self).get_parser(prog_name) _add_common_arguments(parser) parser.add_argument('--tag', metavar='TAG', action='append', dest='tags', required=True, help=_('Tag (This option can be repeated).')) return parser def take_action(self, parsed_args): client = self.get_client() resource_type, resource_id = _convert_resource_args(client, parsed_args) body = {'tags': parsed_args.tags} client.replace_tag(resource_type, resource_id, body) class RemoveTag(neutronv20.NeutronCommand): """Remove a tag on the resource.""" def get_parser(self, prog_name): parser = super(RemoveTag, self).get_parser(prog_name) _add_common_arguments(parser) tag_opt = parser.add_mutually_exclusive_group() tag_opt.add_argument('--all', action='store_true', help=_('Remove all tags on the resource.')) tag_opt.add_argument('--tag', help=_('Tag to be removed.')) return parser def take_action(self, parsed_args): if not parsed_args.all and not parsed_args.tag: raise exceptions.CommandError( _("--all or --tag must be specified")) client = self.get_client() resource_type, resource_id = _convert_resource_args(client, parsed_args) if parsed_args.all: client.remove_tag_all(resource_type, resource_id) else: client.remove_tag(resource_type, resource_id, parsed_args.tag) python-neutronclient-6.7.0/neutronclient/neutron/v2_0/availability_zone.py0000666000175100017510000000260213232473350027174 0ustar zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronv20 def add_az_hint_argument(parser, resource): parser.add_argument( '--availability-zone-hint', metavar='AVAILABILITY_ZONE', action='append', dest='availability_zone_hints', help=_('Availability Zone for the %s ' '(requires availability zone extension, ' 'this option can be repeated).') % resource) def args2body_az_hint(parsed_args, resource): if parsed_args.availability_zone_hints: resource['availability_zone_hints'] = ( parsed_args.availability_zone_hints) class ListAvailabilityZone(neutronv20.ListCommand): """List availability zones.""" resource = 'availability_zone' list_columns = ['name', 'resource', 'state'] pagination_support = True sorting_support = True python-neutronclient-6.7.0/neutronclient/neutron/v2_0/qos/0000775000175100017510000000000013232473710023715 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/qos/rule.py0000666000175100017510000000364713232473350025252 0ustar zuulzuul00000000000000# Copyright 2015 Huawei Technologies India Pvt Ltd, Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronv20 from neutronclient.neutron.v2_0.qos import policy as qos_policy def add_policy_argument(parser): parser.add_argument( 'policy', metavar='QOS_POLICY', help=_('ID or name of the QoS policy.')) def add_rule_argument(parser): parser.add_argument( 'rule', metavar='QOS_RULE', help=_('ID of the QoS rule.')) def update_policy_args2body(parsed_args, body): neutronv20.update_dict(parsed_args, body, ['policy']) def update_rule_args2body(parsed_args, body): neutronv20.update_dict(parsed_args, body, ['rule']) class QosRuleMixin(object): def add_known_arguments(self, parser): add_policy_argument(parser) def set_extra_attrs(self, parsed_args): self.parent_id = qos_policy.get_qos_policy_id(self.get_client(), parsed_args.policy) def args2body(self, parsed_args): body = {} update_policy_args2body(parsed_args, body) return {'qos_rule': body} class ListQoSRuleTypes(neutronv20.ListCommand): """List available qos rule types.""" resource = 'rule_type' shadow_resource = 'qos_rule_type' pagination_support = True sorting_support = True python-neutronclient-6.7.0/neutronclient/neutron/v2_0/qos/policy.py0000666000175100017510000001251413232473350025573 0ustar zuulzuul00000000000000# Copyright 2015 Huawei Technologies India Pvt Ltd, Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import os from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronv20 def get_qos_policy_id(client, policy_id_or_name): _policy_id = neutronv20.find_resourceid_by_name_or_id( client, 'policy', policy_id_or_name, cmd_resource='qos_policy') return _policy_id class CreateQosPolicyMixin(object): def add_arguments_qos_policy(self, parser): qos_policy_args = parser.add_mutually_exclusive_group() qos_policy_args.add_argument( '--qos-policy', help=_('ID or name of the QoS policy that should' 'be attached to the resource.')) return qos_policy_args def args2body_qos_policy(self, parsed_args, resource): if parsed_args.qos_policy: _policy_id = get_qos_policy_id(self.get_client(), parsed_args.qos_policy) resource['qos_policy_id'] = _policy_id class UpdateQosPolicyMixin(CreateQosPolicyMixin): def add_arguments_qos_policy(self, parser): qos_policy_args = (super(UpdateQosPolicyMixin, self). add_arguments_qos_policy(parser)) qos_policy_args.add_argument( '--no-qos-policy', action='store_true', help=_('Detach QoS policy from the resource.')) return qos_policy_args def args2body_qos_policy(self, parsed_args, resource): super(UpdateQosPolicyMixin, self).args2body_qos_policy(parsed_args, resource) if parsed_args.no_qos_policy: resource['qos_policy_id'] = None class ListQoSPolicy(neutronv20.ListCommand): """List QoS policies that belong to a given tenant connection.""" resource = 'policy' shadow_resource = 'qos_policy' list_columns = ['id', 'name'] pagination_support = True sorting_support = True class ShowQoSPolicy(neutronv20.ShowCommand): """Show information of a given qos policy.""" resource = 'policy' shadow_resource = 'qos_policy' def format_output_data(self, data): rules = [] for rule in data['policy'].get('rules', []): rules.append("%s (type: %s)" % (rule['id'], rule['type'])) data['policy']['rules'] = os.linesep.join(rules) super(ShowQoSPolicy, self).format_output_data(data) class CreateQoSPolicy(neutronv20.CreateCommand): """Create a qos policy.""" resource = 'policy' shadow_resource = 'qos_policy' def add_known_arguments(self, parser): parser.add_argument( 'name', metavar='NAME', help=_('Name of the QoS policy to be created.')) parser.add_argument( '--description', help=_('Description of the QoS policy to be created.')) parser.add_argument( '--shared', action='store_true', help=_('Accessible by other tenants. ' 'Set shared to True (default is False).')) def args2body(self, parsed_args): body = {'name': parsed_args.name} if parsed_args.description: body['description'] = parsed_args.description if parsed_args.shared: body['shared'] = parsed_args.shared if parsed_args.tenant_id: body['tenant_id'] = parsed_args.tenant_id return {self.resource: body} class UpdateQoSPolicy(neutronv20.UpdateCommand): """Update a given qos policy.""" resource = 'policy' shadow_resource = 'qos_policy' def add_known_arguments(self, parser): parser.add_argument( '--name', help=_('Name of the QoS policy.')) parser.add_argument( '--description', help=_('Description of the QoS policy.')) shared_group = parser.add_mutually_exclusive_group() shared_group.add_argument( '--shared', action='store_true', help=_('Accessible by other tenants. ' 'Set shared to True (default is False).')) shared_group.add_argument( '--no-shared', action='store_true', help=_('Not accessible by other tenants. ' 'Set shared to False.')) def args2body(self, parsed_args): body = {} if parsed_args.name: body['name'] = parsed_args.name if parsed_args.description: body['description'] = parsed_args.description if parsed_args.shared: body['shared'] = True if parsed_args.no_shared: body['shared'] = False return {self.resource: body} class DeleteQoSPolicy(neutronv20.DeleteCommand): """Delete a given qos policy.""" resource = 'policy' shadow_resource = 'qos_policy' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/qos/bandwidth_limit_rule.py0000666000175100017510000000660713232473350030473 0ustar zuulzuul00000000000000# Copyright 2015 Huawei Technologies India Pvt Ltd, Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.neutron import v2_0 as neutronv20 from neutronclient.neutron.v2_0.qos import rule as qos_rule BANDWIDTH_LIMIT_RULE_RESOURCE = 'bandwidth_limit_rule' def add_bandwidth_limit_arguments(parser): parser.add_argument( '--max-kbps', help=_('Maximum bandwidth in kbps.')) parser.add_argument( '--max-burst-kbps', help=_('Maximum burst bandwidth in kbps.')) def update_bandwidth_limit_args2body(parsed_args, body): max_kbps = parsed_args.max_kbps max_burst_kbps = parsed_args.max_burst_kbps if not (max_kbps or max_burst_kbps): raise exceptions.CommandError(_("Must provide max-kbps" " or max-burst-kbps option.")) neutronv20.update_dict(parsed_args, body, ['max_kbps', 'max_burst_kbps', 'tenant_id']) class CreateQoSBandwidthLimitRule(qos_rule.QosRuleMixin, neutronv20.CreateCommand): """Create a qos bandwidth limit rule.""" resource = BANDWIDTH_LIMIT_RULE_RESOURCE def add_known_arguments(self, parser): super(CreateQoSBandwidthLimitRule, self).add_known_arguments(parser) add_bandwidth_limit_arguments(parser) def args2body(self, parsed_args): body = {} update_bandwidth_limit_args2body(parsed_args, body) return {self.resource: body} class ListQoSBandwidthLimitRules(qos_rule.QosRuleMixin, neutronv20.ListCommand): """List all qos bandwidth limit rules belonging to the specified policy.""" resource = BANDWIDTH_LIMIT_RULE_RESOURCE _formatters = {} pagination_support = True sorting_support = True class ShowQoSBandwidthLimitRule(qos_rule.QosRuleMixin, neutronv20.ShowCommand): """Show information about the given qos bandwidth limit rule.""" resource = BANDWIDTH_LIMIT_RULE_RESOURCE allow_names = False class UpdateQoSBandwidthLimitRule(qos_rule.QosRuleMixin, neutronv20.UpdateCommand): """Update the given qos bandwidth limit rule.""" resource = BANDWIDTH_LIMIT_RULE_RESOURCE allow_names = False def add_known_arguments(self, parser): super(UpdateQoSBandwidthLimitRule, self).add_known_arguments(parser) add_bandwidth_limit_arguments(parser) def args2body(self, parsed_args): body = {} update_bandwidth_limit_args2body(parsed_args, body) return {self.resource: body} class DeleteQoSBandwidthLimitRule(qos_rule.QosRuleMixin, neutronv20.DeleteCommand): """Delete a given qos bandwidth limit rule.""" resource = BANDWIDTH_LIMIT_RULE_RESOURCE allow_names = False python-neutronclient-6.7.0/neutronclient/neutron/v2_0/qos/minimum_bandwidth_rule.py0000666000175100017510000000740613232473350031026 0ustar zuulzuul00000000000000# Copyright (c) 2016 Intel Corporation. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronv20 from neutronclient.neutron.v2_0.qos import rule as qos_rule MINIMUM_BANDWIDTH_RULE_RESOURCE = 'minimum_bandwidth_rule' def add_minimum_bandwidth_arguments(parser): parser.add_argument( '--min-kbps', required=True, type=str, help=_('QoS minimum bandwidth assurance, expressed in kilobits ' 'per second.')) # NOTE(ralonsoh): the only direction implemented is "egress". Please, # refer to the spec (https://review.openstack.org/#/c/316082/). parser.add_argument( '--direction', # NOTE(ihrachys): though server picks the default for us (egress), it's # better to require the argument to make the UI more explicit and the # intentions more clear in the future when we add other values for the # attribute on server side. required=True, type=utils.convert_to_lowercase, choices=['egress'], help=_('Traffic direction.')) def update_minimum_bandwidth_args2body(parsed_args, body): neutronv20.update_dict(parsed_args, body, ['min_kbps', 'direction']) class CreateQoSMinimumBandwidthRule(qos_rule.QosRuleMixin, neutronv20.CreateCommand): """Create a qos minimum bandwidth rule.""" resource = MINIMUM_BANDWIDTH_RULE_RESOURCE def add_known_arguments(self, parser): super(CreateQoSMinimumBandwidthRule, self).add_known_arguments( parser) add_minimum_bandwidth_arguments(parser) def args2body(self, parsed_args): body = {} update_minimum_bandwidth_args2body(parsed_args, body) return {self.resource: body} class ListQoSMinimumBandwidthRules(qos_rule.QosRuleMixin, neutronv20.ListCommand): """List all qos minimum bandwidth rules belonging to the specified policy. """ resource = MINIMUM_BANDWIDTH_RULE_RESOURCE _formatters = {} pagination_support = True sorting_support = True class ShowQoSMinimumBandwidthRule(qos_rule.QosRuleMixin, neutronv20.ShowCommand): """Show information about the given qos minimum bandwidth rule.""" resource = MINIMUM_BANDWIDTH_RULE_RESOURCE allow_names = False class UpdateQoSMinimumBandwidthRule(qos_rule.QosRuleMixin, neutronv20.UpdateCommand): """Update the given qos minimum bandwidth rule.""" resource = MINIMUM_BANDWIDTH_RULE_RESOURCE allow_names = False def add_known_arguments(self, parser): super(UpdateQoSMinimumBandwidthRule, self).add_known_arguments( parser) add_minimum_bandwidth_arguments(parser) def args2body(self, parsed_args): body = {} update_minimum_bandwidth_args2body(parsed_args, body) return {self.resource: body} class DeleteQoSMinimumBandwidthRule(qos_rule.QosRuleMixin, neutronv20.DeleteCommand): """Delete a given qos minimum bandwidth rule.""" resource = MINIMUM_BANDWIDTH_RULE_RESOURCE allow_names = False python-neutronclient-6.7.0/neutronclient/neutron/v2_0/qos/dscp_marking_rule.py0000666000175100017510000000745213232473350027771 0ustar zuulzuul00000000000000# Copyright 2016 Comcast, Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.neutron import v2_0 as neutronv20 from neutronclient.neutron.v2_0.qos import rule as qos_rule DSCP_MARKING_RESOURCE = 'dscp_marking_rule' # DSCP DETAILS # 0 - none | 8 - cs1 | 10 - af11 | 12 - af12 | 14 - af13 | # 16 - cs2 | 18 - af21 | 20 - af22 | 22 - af23 | 24 - cs3 | # 26 - af31 | 28 - af32 | 30 - af33 | 32 - cs4 | 34 - af41 | # 36 - af42 | 38 - af43 | 40 - cs5 | 46 - ef | 48 - cs6 | # 56 - cs7 DSCP_VALID_MARKS = [0, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 46, 48, 56] def add_dscp_marking_arguments(parser): parser.add_argument( '--dscp-mark', required=True, type=str, help=_('DSCP mark: value can be 0, even numbers from 8-56, \ excluding 42, 44, 50, 52, and 54.')) def update_dscp_args2body(parsed_args, body): dscp_mark = parsed_args.dscp_mark if int(dscp_mark) not in DSCP_VALID_MARKS: raise exceptions.CommandError(_("DSCP mark: %s not supported. " "Please note value can either be 0 " "or any even number from 8-56 " "excluding 42, 44, 50, 52 and " "54.") % dscp_mark) neutronv20.update_dict(parsed_args, body, ['dscp_mark']) class CreateQoSDscpMarkingRule(qos_rule.QosRuleMixin, neutronv20.CreateCommand): """Create a QoS DSCP marking rule.""" resource = DSCP_MARKING_RESOURCE def add_known_arguments(self, parser): super(CreateQoSDscpMarkingRule, self).add_known_arguments(parser) add_dscp_marking_arguments(parser) def args2body(self, parsed_args): body = {} update_dscp_args2body(parsed_args, body) return {self.resource: body} class ListQoSDscpMarkingRules(qos_rule.QosRuleMixin, neutronv20.ListCommand): """List all QoS DSCP marking rules belonging to the specified policy.""" _formatters = {} pagination_support = True sorting_support = True resource = DSCP_MARKING_RESOURCE class ShowQoSDscpMarkingRule(qos_rule.QosRuleMixin, neutronv20.ShowCommand): """Show information about the given qos dscp marking rule.""" resource = DSCP_MARKING_RESOURCE allow_names = False class UpdateQoSDscpMarkingRule(qos_rule.QosRuleMixin, neutronv20.UpdateCommand): """Update the given QoS DSCP marking rule.""" allow_names = False resource = DSCP_MARKING_RESOURCE def add_known_arguments(self, parser): super(UpdateQoSDscpMarkingRule, self).add_known_arguments(parser) add_dscp_marking_arguments(parser) def args2body(self, parsed_args): body = {} update_dscp_args2body(parsed_args, body) return {self.resource: body} class DeleteQoSDscpMarkingRule(qos_rule.QosRuleMixin, neutronv20.DeleteCommand): """Delete a given qos dscp marking rule.""" allow_names = False resource = DSCP_MARKING_RESOURCE python-neutronclient-6.7.0/neutronclient/neutron/v2_0/qos/__init__.py0000666000175100017510000000000013232473350026016 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/agentscheduler.py0000666000175100017510000003025413232473350026470 0ustar zuulzuul00000000000000# Copyright 2013 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 # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from __future__ import print_function from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronV20 from neutronclient.neutron.v2_0 import network from neutronclient.neutron.v2_0 import router PERFECT_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f" class AddNetworkToDhcpAgent(neutronV20.NeutronCommand): """Add a network to a DHCP agent.""" def get_parser(self, prog_name): parser = super(AddNetworkToDhcpAgent, self).get_parser(prog_name) parser.add_argument( 'dhcp_agent', metavar='DHCP_AGENT', help=_('ID of the DHCP agent.')) parser.add_argument( 'network', metavar='NETWORK', help=_('Network to add.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() _net_id = neutronV20.find_resourceid_by_name_or_id( neutron_client, 'network', parsed_args.network) neutron_client.add_network_to_dhcp_agent(parsed_args.dhcp_agent, {'network_id': _net_id}) print(_('Added network %s to DHCP agent') % parsed_args.network, file=self.app.stdout) class RemoveNetworkFromDhcpAgent(neutronV20.NeutronCommand): """Remove a network from a DHCP agent.""" def get_parser(self, prog_name): parser = super(RemoveNetworkFromDhcpAgent, self).get_parser(prog_name) parser.add_argument( 'dhcp_agent', metavar='DHCP_AGENT', help=_('ID of the DHCP agent.')) parser.add_argument( 'network', metavar='NETWORK', help=_('Network to remove.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() _net_id = neutronV20.find_resourceid_by_name_or_id( neutron_client, 'network', parsed_args.network) neutron_client.remove_network_from_dhcp_agent( parsed_args.dhcp_agent, _net_id) print(_('Removed network %s from DHCP agent') % parsed_args.network, file=self.app.stdout) class ListNetworksOnDhcpAgent(network.ListNetwork): """List the networks on a DHCP agent.""" unknown_parts_flag = False def get_parser(self, prog_name): parser = super(ListNetworksOnDhcpAgent, self).get_parser(prog_name) parser.add_argument( 'dhcp_agent', metavar='DHCP_AGENT', help=_('ID of the DHCP agent.')) return parser def call_server(self, neutron_client, search_opts, parsed_args): data = neutron_client.list_networks_on_dhcp_agent( parsed_args.dhcp_agent, **search_opts) return data class ListDhcpAgentsHostingNetwork(neutronV20.ListCommand): """List DHCP agents hosting a network.""" resource = 'agent' _formatters = {} list_columns = ['id', 'host', 'admin_state_up', 'alive'] unknown_parts_flag = False def get_parser(self, prog_name): parser = super(ListDhcpAgentsHostingNetwork, self).get_parser(prog_name) parser.add_argument( 'network', metavar='NETWORK', help=_('Network to query.')) return parser def extend_list(self, data, parsed_args): for agent in data: agent['alive'] = ":-)" if agent['alive'] else 'xxx' def call_server(self, neutron_client, search_opts, parsed_args): _id = neutronV20.find_resourceid_by_name_or_id(neutron_client, 'network', parsed_args.network) search_opts['network'] = _id data = neutron_client.list_dhcp_agent_hosting_networks(**search_opts) return data class AddRouterToL3Agent(neutronV20.NeutronCommand): """Add a router to a L3 agent.""" def get_parser(self, prog_name): parser = super(AddRouterToL3Agent, self).get_parser(prog_name) parser.add_argument( 'l3_agent', metavar='L3_AGENT', help=_('ID of the L3 agent.')) parser.add_argument( 'router', metavar='ROUTER', help=_('Router to add.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() _id = neutronV20.find_resourceid_by_name_or_id( neutron_client, 'router', parsed_args.router) neutron_client.add_router_to_l3_agent(parsed_args.l3_agent, {'router_id': _id}) print(_('Added router %s to L3 agent') % parsed_args.router, file=self.app.stdout) class RemoveRouterFromL3Agent(neutronV20.NeutronCommand): """Remove a router from a L3 agent.""" def get_parser(self, prog_name): parser = super(RemoveRouterFromL3Agent, self).get_parser(prog_name) parser.add_argument( 'l3_agent', metavar='L3_AGENT', help=_('ID of the L3 agent.')) parser.add_argument( 'router', metavar='ROUTER', help=_('Router to remove.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() _id = neutronV20.find_resourceid_by_name_or_id( neutron_client, 'router', parsed_args.router) neutron_client.remove_router_from_l3_agent( parsed_args.l3_agent, _id) print(_('Removed router %s from L3 agent') % parsed_args.router, file=self.app.stdout) class ListRoutersOnL3Agent(neutronV20.ListCommand): """List the routers on a L3 agent.""" _formatters = {'external_gateway_info': router._format_external_gateway_info} list_columns = ['id', 'name', 'external_gateway_info'] resource = 'router' unknown_parts_flag = False def get_parser(self, prog_name): parser = super(ListRoutersOnL3Agent, self).get_parser(prog_name) parser.add_argument( 'l3_agent', metavar='L3_AGENT', help=_('ID of the L3 agent to query.')) return parser def call_server(self, neutron_client, search_opts, parsed_args): data = neutron_client.list_routers_on_l3_agent( parsed_args.l3_agent, **search_opts) return data class ListL3AgentsHostingRouter(neutronV20.ListCommand): """List L3 agents hosting a router.""" resource = 'agent' _formatters = {} list_columns = ['id', 'host', 'admin_state_up', 'alive'] unknown_parts_flag = False def get_parser(self, prog_name): parser = super(ListL3AgentsHostingRouter, self).get_parser(prog_name) parser.add_argument('router', metavar='ROUTER', help=_('Router to query.')) return parser def extend_list(self, data, parsed_args): # Show the ha_state column only if the server responds with it, # as some plugins do not support HA routers. if any('ha_state' in agent for agent in data): if 'ha_state' not in self.list_columns: self.list_columns.append('ha_state') for agent in data: agent['alive'] = ":-)" if agent['alive'] else 'xxx' def call_server(self, neutron_client, search_opts, parsed_args): _id = neutronV20.find_resourceid_by_name_or_id(neutron_client, 'router', parsed_args.router) search_opts['router'] = _id data = neutron_client.list_l3_agent_hosting_routers(**search_opts) return data class ListPoolsOnLbaasAgent(neutronV20.ListCommand): """List the pools on a loadbalancer agent.""" list_columns = ['id', 'name', 'lb_method', 'protocol', 'admin_state_up', 'status'] resource = 'pool' unknown_parts_flag = False def get_parser(self, prog_name): parser = super(ListPoolsOnLbaasAgent, self).get_parser(prog_name) parser.add_argument( 'lbaas_agent', metavar='LBAAS_AGENT', help=_('ID of the loadbalancer agent to query.')) return parser def call_server(self, neutron_client, search_opts, parsed_args): data = neutron_client.list_pools_on_lbaas_agent( parsed_args.lbaas_agent, **search_opts) return data class GetLbaasAgentHostingPool(neutronV20.ListCommand): """Get loadbalancer agent hosting a pool. Deriving from ListCommand though server will return only one agent to keep common output format for all agent schedulers """ resource = 'agent' list_columns = ['id', 'host', 'admin_state_up', 'alive'] unknown_parts_flag = False def get_parser(self, prog_name): parser = super(GetLbaasAgentHostingPool, self).get_parser(prog_name) parser.add_argument('pool', metavar='POOL', help=_('Pool to query.')) return parser def extend_list(self, data, parsed_args): for agent in data: agent['alive'] = ":-)" if agent['alive'] else 'xxx' def call_server(self, neutron_client, search_opts, parsed_args): _id = neutronV20.find_resourceid_by_name_or_id(neutron_client, 'pool', parsed_args.pool) search_opts['pool'] = _id agent = neutron_client.get_lbaas_agent_hosting_pool(**search_opts) data = {'agents': [agent['agent']]} return data class ListLoadBalancersOnLbaasAgent(neutronV20.ListCommand): """List the loadbalancers on a loadbalancer v2 agent.""" list_columns = ['id', 'name', 'admin_state_up', 'provisioning_status'] resource = 'loadbalancer' unknown_parts_flag = False def get_parser(self, prog_name): parser = super(ListLoadBalancersOnLbaasAgent, self).get_parser( prog_name) parser.add_argument( 'lbaas_agent', metavar='LBAAS_AGENT', help=_('ID of the loadbalancer agent to query.')) return parser def call_server(self, neutron_client, search_opts, parsed_args): data = neutron_client.list_loadbalancers_on_lbaas_agent( parsed_args.lbaas_agent, **search_opts) return data class GetLbaasAgentHostingLoadBalancer(neutronV20.ListCommand): """Get lbaas v2 agent hosting a loadbalancer. Deriving from ListCommand though server will return only one agent to keep common output format for all agent schedulers """ resource = 'agent' list_columns = ['id', 'host', 'admin_state_up', 'alive'] unknown_parts_flag = False def get_parser(self, prog_name): parser = super(GetLbaasAgentHostingLoadBalancer, self).get_parser(prog_name) parser.add_argument('loadbalancer', metavar='LOADBALANCER', help=_('LoadBalancer to query.')) return parser def extend_list(self, data, parsed_args): for agent in data: agent['alive'] = ":-)" if agent['alive'] else 'xxx' def call_server(self, neutron_client, search_opts, parsed_args): _id = neutronV20.find_resourceid_by_name_or_id( neutron_client, 'loadbalancer', parsed_args.loadbalancer) search_opts['loadbalancer'] = _id agent = neutron_client.get_lbaas_agent_hosting_loadbalancer( **search_opts) data = {'agents': [agent['agent']]} return data python-neutronclient-6.7.0/neutronclient/neutron/v2_0/fw/0000775000175100017510000000000013232473710023527 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/fw/firewallrule.py0000666000175100017510000001314213232473350026601 0ustar zuulzuul00000000000000# Copyright 2013 Big Switch Networks # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import argparse from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronv20 def _add_common_args(parser, is_create=True): """If is_create is True, protocol and action become mandatory arguments. CreateCommand = is_create : True UpdateCommand = is_create : False """ parser.add_argument( '--name', help=_('Name for the firewall rule.')) parser.add_argument( '--description', help=_('Description for the firewall rule.')) parser.add_argument( '--source-ip-address', help=_('Source IP address or subnet.')) parser.add_argument( '--destination-ip-address', help=_('Destination IP address or subnet.')) parser.add_argument( '--source-port', help=_('Source port (integer in [1, 65535] or range in a:b).')) parser.add_argument( '--destination-port', help=_('Destination port (integer in [1, 65535] or range in ' 'a:b).')) utils.add_boolean_argument( parser, '--enabled', dest='enabled', help=_('Whether to enable or disable this rule.')) parser.add_argument( '--protocol', choices=['tcp', 'udp', 'icmp', 'any'], required=is_create, type=utils.convert_to_lowercase, help=_('Protocol for the firewall rule.')) parser.add_argument( '--action', required=is_create, type=utils.convert_to_lowercase, choices=['allow', 'deny', 'reject'], help=_('Action for the firewall rule.')) def common_args2body(parsed_args): body = {} neutronv20.update_dict(parsed_args, body, ['name', 'description', 'shared', 'tenant_id', 'source_ip_address', 'destination_ip_address', 'source_port', 'destination_port', 'action', 'enabled', 'ip_version']) protocol = parsed_args.protocol if protocol: if protocol == 'any': protocol = None body['protocol'] = protocol return body class ListFirewallRule(neutronv20.ListCommand): """List firewall rules that belong to a given tenant.""" resource = 'firewall_rule' list_columns = ['id', 'name', 'firewall_policy_id', 'summary', 'enabled'] pagination_support = True sorting_support = True def extend_list(self, data, parsed_args): for d in data: val = [] if d.get('protocol'): protocol = d['protocol'].upper() else: protocol = 'no-protocol' val.append(protocol) if 'source_ip_address' in d and 'source_port' in d: src = 'source: ' + str(d['source_ip_address']).lower() src = src + '(' + str(d['source_port']).lower() + ')' else: src = 'source: none specified' val.append(src) if 'destination_ip_address' in d and 'destination_port' in d: dst = 'dest: ' + str(d['destination_ip_address']).lower() dst = dst + '(' + str(d['destination_port']).lower() + ')' else: dst = 'dest: none specified' val.append(dst) if 'action' in d: action = d['action'] else: action = 'no-action' val.append(action) d['summary'] = ',\n '.join(val) class ShowFirewallRule(neutronv20.ShowCommand): """Show information of a given firewall rule.""" resource = 'firewall_rule' class CreateFirewallRule(neutronv20.CreateCommand): """Create a firewall rule.""" resource = 'firewall_rule' def add_known_arguments(self, parser): parser.add_argument( '--shared', action='store_true', help=_('Set shared flag for the firewall rule.'), default=argparse.SUPPRESS) _add_common_args(parser) parser.add_argument( '--ip-version', type=int, choices=[4, 6], default=4, help=_('IP version for the firewall rule (default is 4).')) def args2body(self, parsed_args): return {self.resource: common_args2body(parsed_args)} class UpdateFirewallRule(neutronv20.UpdateCommand): """Update a given firewall rule.""" resource = 'firewall_rule' def add_known_arguments(self, parser): utils.add_boolean_argument( parser, '--shared', dest='shared', help=_('Update the shared flag for the firewall rule.'), default=argparse.SUPPRESS) parser.add_argument( '--ip-version', type=int, choices=[4, 6], help=_('Update IP version for the firewall rule.')) _add_common_args(parser, is_create=False) def args2body(self, parsed_args): return {self.resource: common_args2body(parsed_args)} class DeleteFirewallRule(neutronv20.DeleteCommand): """Delete a given firewall rule.""" resource = 'firewall_rule' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/fw/firewall.py0000666000175100017510000001016613232473350025714 0ustar zuulzuul00000000000000# Copyright 2013 Big Switch Networks # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronv20 def add_common_args(parser): parser.add_argument( '--name', help=_('Name for the firewall.')) parser.add_argument( '--description', help=_('Description for the firewall.')) router = parser.add_mutually_exclusive_group() router.add_argument( '--router', dest='routers', metavar='ROUTER', action='append', help=_('ID or name of the router associated with the firewall ' '(requires FWaaS router insertion extension to be enabled). ' 'This option can be repeated.')) router.add_argument( '--no-routers', action='store_true', help=_('Associate no routers with the firewall (requires FWaaS ' 'router insertion extension).')) def parse_common_args(client, parsed_args): body = {} if parsed_args.policy: body['firewall_policy_id'] = neutronv20.find_resourceid_by_name_or_id( client, 'firewall_policy', parsed_args.policy) if parsed_args.routers: body['router_ids'] = [ neutronv20.find_resourceid_by_name_or_id(client, 'router', r) for r in parsed_args.routers] elif parsed_args.no_routers: body['router_ids'] = [] neutronv20.update_dict(parsed_args, body, ['name', 'description']) return body class ListFirewall(neutronv20.ListCommand): """List firewalls that belong to a given tenant.""" resource = 'firewall' list_columns = ['id', 'name', 'firewall_policy_id'] _formatters = {} pagination_support = True sorting_support = True class ShowFirewall(neutronv20.ShowCommand): """Show information of a given firewall.""" resource = 'firewall' class CreateFirewall(neutronv20.CreateCommand): """Create a firewall.""" resource = 'firewall' def add_known_arguments(self, parser): add_common_args(parser) parser.add_argument( 'policy', metavar='POLICY', help=_('ID or name of the firewall policy ' 'associated to this firewall.')) parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) def args2body(self, parsed_args): body = parse_common_args(self.get_client(), parsed_args) neutronv20.update_dict(parsed_args, body, ['tenant_id']) body['admin_state_up'] = parsed_args.admin_state return {self.resource: body} class UpdateFirewall(neutronv20.UpdateCommand): """Update a given firewall.""" resource = 'firewall' def add_known_arguments(self, parser): add_common_args(parser) parser.add_argument( '--policy', metavar='POLICY', help=_('ID or name of the firewall policy ' 'associated to this firewall.')) utils.add_boolean_argument( parser, '--admin-state-up', dest='admin_state_up', help=_('Update the admin state for the firewall ' '(True means UP).')) def args2body(self, parsed_args): body = parse_common_args(self.get_client(), parsed_args) neutronv20.update_dict(parsed_args, body, ['admin_state_up']) return {self.resource: body} class DeleteFirewall(neutronv20.DeleteCommand): """Delete a given firewall.""" resource = 'firewall' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/fw/firewallpolicy.py0000666000175100017510000002006613232473350027134 0ustar zuulzuul00000000000000# Copyright 2013 Big Switch Networks # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from __future__ import print_function import argparse from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronv20 def _format_firewall_rules(firewall_policy): try: output = '[' + ',\n '.join([rule for rule in firewall_policy['firewall_rules']]) + ']' return output except (TypeError, KeyError): return '' def add_common_args(parser): parser.add_argument( '--description', help=_('Description for the firewall policy.')) parser.add_argument( '--firewall-rules', type=lambda x: x.split(), help=_('Ordered list of whitespace-delimited firewall rule ' 'names or IDs; e.g., --firewall-rules \"rule1 rule2\"')) def parse_common_args(client, parsed_args): if parsed_args.firewall_rules: _firewall_rules = [] for f in parsed_args.firewall_rules: _firewall_rules.append( neutronv20.find_resourceid_by_name_or_id( client, 'firewall_rule', f)) body = {'firewall_rules': _firewall_rules} else: body = {} neutronv20.update_dict(parsed_args, body, ['name', 'description', 'shared', 'audited', 'tenant_id']) return {'firewall_policy': body} class ListFirewallPolicy(neutronv20.ListCommand): """List firewall policies that belong to a given tenant.""" resource = 'firewall_policy' list_columns = ['id', 'name', 'firewall_rules'] _formatters = {'firewall_rules': _format_firewall_rules, } pagination_support = True sorting_support = True class ShowFirewallPolicy(neutronv20.ShowCommand): """Show information of a given firewall policy.""" resource = 'firewall_policy' class CreateFirewallPolicy(neutronv20.CreateCommand): """Create a firewall policy.""" resource = 'firewall_policy' def add_known_arguments(self, parser): parser.add_argument( 'name', metavar='NAME', help=_('Name for the firewall policy.')) parser.add_argument( '--shared', action='store_true', help=_('Create a shared policy.'), default=argparse.SUPPRESS) parser.add_argument( '--audited', action='store_true', help=_('Sets audited to True.'), default=argparse.SUPPRESS) add_common_args(parser) def args2body(self, parsed_args): return parse_common_args(self.get_client(), parsed_args) class UpdateFirewallPolicy(neutronv20.UpdateCommand): """Update a given firewall policy.""" resource = 'firewall_policy' def add_known_arguments(self, parser): add_common_args(parser) parser.add_argument( '--name', help=_('Name for the firewall policy.')) utils.add_boolean_argument( parser, '--shared', help=_('Update the sharing status of the policy. ' '(True means shared).')) utils.add_boolean_argument( parser, '--audited', help=_('Update the audit status of the policy. ' '(True means auditing is enabled).')) def args2body(self, parsed_args): return parse_common_args(self.get_client(), parsed_args) class DeleteFirewallPolicy(neutronv20.DeleteCommand): """Delete a given firewall policy.""" resource = 'firewall_policy' class FirewallPolicyInsertRule(neutronv20.UpdateCommand): """Insert a rule into a given firewall policy.""" resource = 'firewall_policy' def call_api(self, neutron_client, firewall_policy_id, body): return neutron_client.firewall_policy_insert_rule(firewall_policy_id, body) def args2body(self, parsed_args): _rule = '' if parsed_args.firewall_rule_id: _rule = neutronv20.find_resourceid_by_name_or_id( self.get_client(), 'firewall_rule', parsed_args.firewall_rule_id) _insert_before = '' if 'insert_before' in parsed_args: if parsed_args.insert_before: _insert_before = neutronv20.find_resourceid_by_name_or_id( self.get_client(), 'firewall_rule', parsed_args.insert_before) _insert_after = '' if 'insert_after' in parsed_args: if parsed_args.insert_after: _insert_after = neutronv20.find_resourceid_by_name_or_id( self.get_client(), 'firewall_rule', parsed_args.insert_after) body = {'firewall_rule_id': _rule, 'insert_before': _insert_before, 'insert_after': _insert_after} return body def get_parser(self, prog_name): parser = super(FirewallPolicyInsertRule, self).get_parser(prog_name) parser.add_argument( '--insert-before', metavar='FIREWALL_RULE', help=_('Insert before this rule.')) parser.add_argument( '--insert-after', metavar='FIREWALL_RULE', help=_('Insert after this rule.')) parser.add_argument( 'firewall_rule_id', metavar='FIREWALL_RULE', help=_('New rule to insert.')) self.add_known_arguments(parser) return parser def take_action(self, parsed_args): neutron_client = self.get_client() body = self.args2body(parsed_args) _id = neutronv20.find_resourceid_by_name_or_id(neutron_client, self.resource, parsed_args.id) self.call_api(neutron_client, _id, body) print((_('Inserted firewall rule in firewall policy %(id)s') % {'id': parsed_args.id}), file=self.app.stdout) class FirewallPolicyRemoveRule(neutronv20.UpdateCommand): """Remove a rule from a given firewall policy.""" resource = 'firewall_policy' def call_api(self, neutron_client, firewall_policy_id, body): return neutron_client.firewall_policy_remove_rule(firewall_policy_id, body) def args2body(self, parsed_args): _rule = '' if parsed_args.firewall_rule_id: _rule = neutronv20.find_resourceid_by_name_or_id( self.get_client(), 'firewall_rule', parsed_args.firewall_rule_id) body = {'firewall_rule_id': _rule} return body def get_parser(self, prog_name): parser = super(FirewallPolicyRemoveRule, self).get_parser(prog_name) parser.add_argument( 'firewall_rule_id', metavar='FIREWALL_RULE', help=_('ID or name of the firewall rule to be removed ' 'from the policy.')) self.add_known_arguments(parser) return parser def take_action(self, parsed_args): neutron_client = self.get_client() body = self.args2body(parsed_args) _id = neutronv20.find_resourceid_by_name_or_id(neutron_client, self.resource, parsed_args.id) self.call_api(neutron_client, _id, body) print((_('Removed firewall rule from firewall policy %(id)s') % {'id': parsed_args.id}), file=self.app.stdout) python-neutronclient-6.7.0/neutronclient/neutron/v2_0/fw/__init__.py0000666000175100017510000000000013232473350025630 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/servicetype.py0000666000175100017510000000166213232473350026036 0ustar zuulzuul00000000000000# Copyright 2013 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 # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient.neutron import v2_0 as neutronV20 class ListServiceProvider(neutronV20.ListCommand): """List service providers.""" resource = 'service_provider' list_columns = ['service_type', 'name', 'default'] _formatters = {} pagination_support = True sorting_support = True python-neutronclient-6.7.0/neutronclient/neutron/v2_0/auto_allocated_topology.py0000666000175100017510000001063713232473350030412 0ustar zuulzuul00000000000000# Copyright 2016 IBM # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from __future__ import print_function import argparse from cliff import show from oslo_serialization import jsonutils from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.neutron import v2_0 class ShowAutoAllocatedTopology(v2_0.NeutronCommand, show.ShowOne): """Show the auto-allocated topology of a given tenant.""" resource = 'auto_allocated_topology' def get_parser(self, prog_name): parser = super(ShowAutoAllocatedTopology, self).get_parser(prog_name) parser.add_argument( '--dry-run', help=_('Validate the requirements for auto-allocated-topology. ' '(Does not return a topology.)'), action='store_true') parser.add_argument( '--tenant-id', metavar='tenant-id', help=_('The owner tenant ID.')) # Allow people to do # neutron auto-allocated-topology-show # (Only useful to users who can look at other tenants' topologies.) # We use a different name for this arg because the default will # override whatever is in the named arg otherwise. parser.add_argument( 'pos_tenant_id', help=argparse.SUPPRESS, nargs='?') return parser def take_action(self, parsed_args): client = self.get_client() extra_values = v2_0.parse_args_to_dict(self.values_specs) if extra_values: raise exceptions.CommandError( _("Invalid argument(s): --%s") % ', --'.join(extra_values)) tenant_id = parsed_args.tenant_id or parsed_args.pos_tenant_id if parsed_args.dry_run: data = client.validate_auto_allocated_topology_requirements( tenant_id) else: data = client.get_auto_allocated_topology(tenant_id) if self.resource in data: for k, v in data[self.resource].items(): if isinstance(v, list): value = "" for _item in v: if value: value += "\n" if isinstance(_item, dict): value += jsonutils.dumps(_item) else: value += str(_item) data[self.resource][k] = value elif v == "dry-run=pass": return ("dry-run",), ("pass",) elif v is None: data[self.resource][k] = '' return zip(*sorted(data[self.resource].items())) else: return None class DeleteAutoAllocatedTopology(v2_0.NeutronCommand): """Delete the auto-allocated topology of a given tenant.""" resource = 'auto_allocated_topology' def get_parser(self, prog_name): parser = super(DeleteAutoAllocatedTopology, self).get_parser(prog_name) parser.add_argument( '--tenant-id', metavar='tenant-id', help=_('The owner tenant ID.')) # Allow people to do # neutron auto-allocated-topology-delete # (Only useful to users who can look at other tenants' topologies.) # We use a different name for this arg because the default will # override whatever is in the named arg otherwise. parser.add_argument( 'pos_tenant_id', help=argparse.SUPPRESS, nargs='?') return parser def take_action(self, parsed_args): client = self.get_client() tenant_id = parsed_args.tenant_id or parsed_args.pos_tenant_id client.delete_auto_allocated_topology(tenant_id) # It tenant is None, let's be clear on what it means. tenant_id = tenant_id or 'None (i.e. yours)' print(_('Deleted topology for tenant %s.') % tenant_id, file=self.app.stdout) python-neutronclient-6.7.0/neutronclient/neutron/v2_0/subnetpool.py0000666000175100017510000001310213232473350025656 0ustar zuulzuul00000000000000# Copyright 2015 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 # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 def _format_prefixes(subnetpool): try: return '\n'.join(pool for pool in subnetpool['prefixes']) except (TypeError, KeyError): return subnetpool['prefixes'] def add_updatable_arguments(parser, for_create=False): parser.add_argument( '--description', help=_('Description of subnetpool.')) parser.add_argument( '--min-prefixlen', type=int, help=_('Subnetpool minimum prefix length.')) parser.add_argument( '--max-prefixlen', type=int, help=_('Subnetpool maximum prefix length.')) parser.add_argument( '--default-prefixlen', type=int, help=_('Subnetpool default prefix length.')) parser.add_argument( '--pool-prefix', action='append', dest='prefixes', required=for_create, help=_('Subnetpool prefixes (This option can be repeated).')) utils.add_boolean_argument( parser, '--is-default', help=_('Specify whether this should be the default subnetpool ' '(True meaning default).')) def updatable_args2body(parsed_args, body): neutronV20.update_dict(parsed_args, body, ['name', 'prefixes', 'default_prefixlen', 'min_prefixlen', 'max_prefixlen', 'is_default', 'description']) class ListSubnetPool(neutronV20.ListCommand): """List subnetpools that belong to a given tenant.""" _formatters = {'prefixes': _format_prefixes, } resource = 'subnetpool' list_columns = ['id', 'name', 'prefixes', 'default_prefixlen', 'address_scope_id', 'is_default'] pagination_support = True sorting_support = True class ShowSubnetPool(neutronV20.ShowCommand): """Show information of a given subnetpool.""" resource = 'subnetpool' class CreateSubnetPool(neutronV20.CreateCommand): """Create a subnetpool for a given tenant.""" resource = 'subnetpool' def add_known_arguments(self, parser): add_updatable_arguments(parser, for_create=True) parser.add_argument( '--shared', action='store_true', help=_('Set the subnetpool as shared.')) parser.add_argument( 'name', metavar='NAME', help=_('Name of the subnetpool to be created.')) parser.add_argument( '--address-scope', metavar='ADDRSCOPE', help=_('ID or name of the address scope with which the subnetpool ' 'is associated. Prefixes must be unique across address ' 'scopes.')) def args2body(self, parsed_args): body = {'prefixes': parsed_args.prefixes} updatable_args2body(parsed_args, body) neutronV20.update_dict(parsed_args, body, ['tenant_id']) if parsed_args.shared: body['shared'] = True # Parse and update for "address-scope" option if parsed_args.address_scope: _addrscope_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'address_scope', parsed_args.address_scope) body['address_scope_id'] = _addrscope_id return {'subnetpool': body} class DeleteSubnetPool(neutronV20.DeleteCommand): """Delete a given subnetpool.""" resource = 'subnetpool' class UpdateSubnetPool(neutronV20.UpdateCommand): """Update subnetpool's information.""" resource = 'subnetpool' def add_known_arguments(self, parser): add_updatable_arguments(parser) parser.add_argument('--name', help=_('Updated name of the subnetpool.')) addrscope_args = parser.add_mutually_exclusive_group() addrscope_args.add_argument('--address-scope', metavar='ADDRSCOPE', help=_('ID or name of the address scope ' 'with which the subnetpool is ' 'associated. Prefixes must be ' 'unique across address scopes.')) addrscope_args.add_argument('--no-address-scope', action='store_true', help=_('Detach subnetpool from the ' 'address scope.')) def args2body(self, parsed_args): body = {} updatable_args2body(parsed_args, body) # Parse and update for "address-scope" option/s if parsed_args.no_address_scope: body['address_scope_id'] = None elif parsed_args.address_scope: _addrscope_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'address_scope', parsed_args.address_scope) body['address_scope_id'] = _addrscope_id return {'subnetpool': body} python-neutronclient-6.7.0/neutronclient/neutron/v2_0/address_scope.py0000666000175100017510000000545713232473350026320 0ustar zuulzuul00000000000000# Copyright 2015 Huawei Technologies India Pvt. Ltd.. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 class ListAddressScope(neutronV20.ListCommand): """List address scopes that belong to a given tenant.""" resource = 'address_scope' list_columns = ['id', 'name', 'ip_version'] pagination_support = True sorting_support = True class ShowAddressScope(neutronV20.ShowCommand): """Show information about an address scope.""" resource = 'address_scope' class CreateAddressScope(neutronV20.CreateCommand): """Create an address scope for a given tenant.""" resource = 'address_scope' def add_known_arguments(self, parser): parser.add_argument( '--shared', action='store_true', help=_('Set the address scope as shared.')) parser.add_argument( 'name', metavar='NAME', help=_('Specify the name of the address scope.')) parser.add_argument( 'ip_version', metavar='IP_VERSION', type=int, choices=[4, 6], help=_('Specify the address family of the address scope.')) def args2body(self, parsed_args): body = {'name': parsed_args.name, 'ip_version': parsed_args.ip_version} if parsed_args.shared: body['shared'] = True neutronV20.update_dict(parsed_args, body, ['tenant_id']) return {self.resource: body} class DeleteAddressScope(neutronV20.DeleteCommand): """Delete an address scope.""" resource = 'address_scope' class UpdateAddressScope(neutronV20.UpdateCommand): """Update an address scope.""" resource = 'address_scope' def add_known_arguments(self, parser): parser.add_argument('--name', help=_('Updated name of the address scope.')) utils.add_boolean_argument( parser, '--shared', help=_('Set sharing of address scope. ' '(True means shared)')) def args2body(self, parsed_args): body = {} neutronV20.update_dict(parsed_args, body, ['name', 'shared']) return {self.resource: body} python-neutronclient-6.7.0/neutronclient/neutron/v2_0/contrib/0000775000175100017510000000000013232473710024553 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/contrib/_fox_sockets.py0000666000175100017510000000520413232473350027616 0ustar zuulzuul00000000000000# Copyright 2015 Rackspace Hosting Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import extension def _add_updatable_args(parser): parser.add_argument( 'name', help=_('Name of this fox socket.')) def _updatable_args2body(parsed_args, body, client): if parsed_args.name: body['name'] = parsed_args.name class FoxInSocket(extension.NeutronClientExtension): """Define required variables for resource operations.""" resource = 'fox_socket' resource_plural = '%ss' % resource object_path = '/%s' % resource_plural resource_path = '/%s/%%s' % resource_plural versions = ['2.0'] class FoxInSocketsList(extension.ClientExtensionList, FoxInSocket): """List fox sockets.""" shell_command = 'fox-sockets-list' list_columns = ['id', 'name'] pagination_support = True sorting_support = True class FoxInSocketsCreate(extension.ClientExtensionCreate, FoxInSocket): """Create a fox socket.""" shell_command = 'fox-sockets-create' list_columns = ['id', 'name'] def add_known_arguments(self, parser): _add_updatable_args(parser) def args2body(self, parsed_args): body = {} client = self.get_client() _updatable_args2body(parsed_args, body, client) return {'fox_socket': body} class FoxInSocketsUpdate(extension.ClientExtensionUpdate, FoxInSocket): """Update a fox socket.""" shell_command = 'fox-sockets-update' list_columns = ['id', 'name'] def add_known_arguments(self, parser): # _add_updatable_args(parser) parser.add_argument( '--name', help=_('Name of this fox socket.')) def args2body(self, parsed_args): body = {'name': parsed_args.name} return {'fox_socket': body} class FoxInSocketsDelete(extension.ClientExtensionDelete, FoxInSocket): """Delete a fox socket.""" shell_command = 'fox-sockets-delete' class FoxInSocketsShow(extension.ClientExtensionShow, FoxInSocket): """Show a fox socket.""" shell_command = 'fox-sockets-show' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/contrib/__init__.py0000666000175100017510000000000013232473350026654 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/extension.py0000666000175100017510000000170313232473350025504 0ustar zuulzuul00000000000000# 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 # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient.neutron import v2_0 as cmd_base class ListExt(cmd_base.ListCommand): """List all extensions.""" resource = 'extension' list_columns = ['alias', 'name'] class ShowExt(cmd_base.ShowCommand): """Show information of a given resource.""" resource = "extension" allow_names = False python-neutronclient-6.7.0/neutronclient/neutron/v2_0/subnet.py0000666000175100017510000002440113232473350024770 0ustar zuulzuul00000000000000# 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 # # 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 argparse from oslo_serialization import jsonutils from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 def _format_allocation_pools(subnet): try: return '\n'.join([jsonutils.dumps(pool) for pool in subnet['allocation_pools']]) except (TypeError, KeyError): return '' def _format_dns_nameservers(subnet): try: return '\n'.join([jsonutils.dumps(server) for server in subnet['dns_nameservers']]) except (TypeError, KeyError): return '' def _format_host_routes(subnet): try: return '\n'.join([jsonutils.dumps(route) for route in subnet['host_routes']]) except (TypeError, KeyError): return '' def add_updatable_arguments(parser): parser.add_argument( '--name', help=_('Name of this subnet.')) parser.add_argument( '--description', help=_('Description of this subnet.')) gateway_sg = parser.add_mutually_exclusive_group() gateway_sg.add_argument( '--gateway', metavar='GATEWAY_IP', help=_('Gateway IP of this subnet.')) gateway_sg.add_argument( '--no-gateway', action='store_true', help=_('Do not configure a gateway for this subnet.')) parser.add_argument( '--allocation-pool', metavar='start=IP_ADDR,end=IP_ADDR', action='append', dest='allocation_pools', type=utils.str2dict_type(required_keys=['start', 'end']), help=_('Allocation pool IP addresses for this subnet ' '(This option can be repeated).')) parser.add_argument( '--allocation_pool', action='append', dest='allocation_pools', type=utils.str2dict_type(required_keys=['start', 'end']), help=argparse.SUPPRESS) parser.add_argument( '--host-route', metavar='destination=CIDR,nexthop=IP_ADDR', action='append', dest='host_routes', type=utils.str2dict_type(required_keys=['destination', 'nexthop']), help=_('Additional route (This option can be repeated).')) parser.add_argument( '--dns-nameserver', metavar='DNS_NAMESERVER', action='append', dest='dns_nameservers', help=_('DNS name server for this subnet ' '(This option can be repeated).')) parser.add_argument( '--disable-dhcp', action='store_true', help=_('Disable DHCP for this subnet.')) parser.add_argument( '--enable-dhcp', action='store_true', help=_('Enable DHCP for this subnet.')) # NOTE(ihrachys): yes, that's awful, but should be left as-is for # backwards compatibility for versions <=2.3.4 that passed the # boolean values through to the server without any argument # validation. parser.add_argument( '--enable-dhcp=True', action='store_true', dest='enable_dhcp', help=argparse.SUPPRESS) parser.add_argument( '--enable-dhcp=False', action='store_true', dest='disable_dhcp', help=argparse.SUPPRESS) def updatable_args2body(parsed_args, body, for_create=True, ip_version=None): if parsed_args.disable_dhcp and parsed_args.enable_dhcp: raise exceptions.CommandError(_( "You cannot enable and disable DHCP at the same time.")) neutronV20.update_dict(parsed_args, body, ['name', 'allocation_pools', 'host_routes', 'dns_nameservers', 'description']) if parsed_args.no_gateway: body['gateway_ip'] = None elif parsed_args.gateway: body['gateway_ip'] = parsed_args.gateway if parsed_args.disable_dhcp: body['enable_dhcp'] = False if parsed_args.enable_dhcp: body['enable_dhcp'] = True if for_create and parsed_args.ipv6_ra_mode: if ip_version == 4: raise exceptions.CommandError(_("--ipv6-ra-mode is invalid " "when --ip-version is 4")) body['ipv6_ra_mode'] = parsed_args.ipv6_ra_mode if for_create and parsed_args.ipv6_address_mode: if ip_version == 4: raise exceptions.CommandError(_("--ipv6-address-mode is " "invalid when --ip-version " "is 4")) body['ipv6_address_mode'] = parsed_args.ipv6_address_mode class ListSubnet(neutronV20.ListCommand): """List subnets that belong to a given tenant.""" resource = 'subnet' _formatters = {'allocation_pools': _format_allocation_pools, 'dns_nameservers': _format_dns_nameservers, 'host_routes': _format_host_routes, } list_columns = ['id', 'name', 'cidr', 'allocation_pools'] pagination_support = True sorting_support = True class ShowSubnet(neutronV20.ShowCommand): """Show information of a given subnet.""" resource = 'subnet' class CreateSubnet(neutronV20.CreateCommand): """Create a subnet for a given tenant.""" resource = 'subnet' def add_known_arguments(self, parser): add_updatable_arguments(parser) parser.add_argument( '--ip-version', type=int, default=4, choices=[4, 6], help=_('IP version to use, default is 4. ' 'Note that when subnetpool is specified, ' 'IP version is determined from the subnetpool ' 'and this option is ignored.')) parser.add_argument( '--ip_version', type=int, choices=[4, 6], help=argparse.SUPPRESS) parser.add_argument( 'network_id', metavar='NETWORK', help=_('Network ID or name this subnet belongs to.')) parser.add_argument( 'cidr', nargs='?', metavar='CIDR', help=_('CIDR of subnet to create.')) parser.add_argument( '--ipv6-ra-mode', type=utils.convert_to_lowercase, choices=['dhcpv6-stateful', 'dhcpv6-stateless', 'slaac'], help=_('IPv6 RA (Router Advertisement) mode.')) parser.add_argument( '--ipv6-address-mode', type=utils.convert_to_lowercase, choices=['dhcpv6-stateful', 'dhcpv6-stateless', 'slaac'], help=_('IPv6 address mode.')) parser.add_argument( '--subnetpool', metavar='SUBNETPOOL', help=_('ID or name of subnetpool from which this subnet ' 'will obtain a CIDR.')) parser.add_argument( '--use-default-subnetpool', action='store_true', help=_('Use default subnetpool for ip_version, if it exists.')) parser.add_argument( '--prefixlen', metavar='PREFIX_LENGTH', help=_('Prefix length for subnet allocation from subnetpool.')) parser.add_argument( '--segment', metavar='SEGMENT', help=_('ID of segment with which this subnet will be associated.')) def args2body(self, parsed_args): _network_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'network', parsed_args.network_id) body = {'network_id': _network_id} if parsed_args.prefixlen: body['prefixlen'] = parsed_args.prefixlen ip_version = parsed_args.ip_version if parsed_args.use_default_subnetpool: body['use_default_subnetpool'] = True if parsed_args.segment: body['segment_id'] = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'segment', parsed_args.segment) if parsed_args.subnetpool: if parsed_args.subnetpool == 'None': _subnetpool_id = None else: _subnetpool = neutronV20.find_resource_by_name_or_id( self.get_client(), 'subnetpool', parsed_args.subnetpool) _subnetpool_id = _subnetpool['id'] # Now that we have the pool_id - let's just have a check on the # ip version used in the pool ip_version = _subnetpool['ip_version'] body['subnetpool_id'] = _subnetpool_id # IP version needs to be set as IP version can be # determined by subnetpool. body['ip_version'] = ip_version if parsed_args.cidr: # With subnetpool, cidr is now optional for creating subnet. cidr = parsed_args.cidr body['cidr'] = cidr unusable_cidr = '/32' if ip_version == 4 else '/128' if cidr.endswith(unusable_cidr): self.log.warning(_("An IPv%(ip)d subnet with a %(cidr)s CIDR " "will have only one usable IP address so " "the device attached to it will not have " "any IP connectivity."), {"ip": ip_version, "cidr": unusable_cidr}) updatable_args2body(parsed_args, body, ip_version=ip_version) if parsed_args.tenant_id: body['tenant_id'] = parsed_args.tenant_id return {'subnet': body} class DeleteSubnet(neutronV20.DeleteCommand): """Delete a given subnet.""" resource = 'subnet' class UpdateSubnet(neutronV20.UpdateCommand): """Update subnet's information.""" resource = 'subnet' def add_known_arguments(self, parser): add_updatable_arguments(parser) def args2body(self, parsed_args): body = {} updatable_args2body(parsed_args, body, for_create=False) return {'subnet': body} python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/0000775000175100017510000000000013232473710023510 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/vip.py0000666000175100017510000000704713232473350024672 0ustar zuulzuul00000000000000# Copyright 2013 Mirantis Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronV20 class ListVip(neutronV20.ListCommand): """List vips that belong to a given tenant.""" resource = 'vip' list_columns = ['id', 'name', 'algorithm', 'address', 'protocol', 'admin_state_up', 'status'] pagination_support = True sorting_support = True class ShowVip(neutronV20.ShowCommand): """Show information of a given vip.""" resource = 'vip' class CreateVip(neutronV20.CreateCommand): """Create a vip.""" resource = 'vip' def add_known_arguments(self, parser): parser.add_argument( 'pool_id', metavar='POOL', help=_('ID or name of the pool to which this vip belongs.')) parser.add_argument( '--address', help=_('IP address of the vip.')) parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--connection-limit', help=_('The maximum number of connections per second allowed for ' 'the vip. Valid values: a positive integer or -1 ' 'for unlimited (default).')) parser.add_argument( '--description', help=_('Description of the vip to be created.')) parser.add_argument( '--name', required=True, help=_('Name of the vip to be created.')) parser.add_argument( '--protocol-port', required=True, help=_('TCP port on which to listen for client traffic that is ' 'associated with the vip address.')) parser.add_argument( '--protocol', required=True, choices=['TCP', 'HTTP', 'HTTPS'], help=_('Protocol for balancing.')) parser.add_argument( '--subnet-id', metavar='SUBNET', required=True, help=_('The subnet on which to allocate the vip address.')) def args2body(self, parsed_args): _pool_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'pool', parsed_args.pool_id) _subnet_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'subnet', parsed_args.subnet_id) body = {'pool_id': _pool_id, 'admin_state_up': parsed_args.admin_state, 'subnet_id': _subnet_id} neutronV20.update_dict(parsed_args, body, ['address', 'connection_limit', 'description', 'name', 'protocol_port', 'protocol', 'tenant_id']) return {self.resource: body} class UpdateVip(neutronV20.UpdateCommand): """Update a given vip.""" resource = 'vip' class DeleteVip(neutronV20.DeleteCommand): """Delete a given vip.""" resource = 'vip' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/pool.py0000666000175100017510000000753113232473350025043 0ustar zuulzuul00000000000000# Copyright 2013 Mirantis Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import six from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronV20 def _format_provider(pool): return pool.get('provider') or 'N/A' class ListPool(neutronV20.ListCommand): """List pools that belong to a given tenant.""" resource = 'pool' list_columns = ['id', 'name', 'provider', 'lb_method', 'protocol', 'admin_state_up', 'status'] _formatters = {'provider': _format_provider} pagination_support = True sorting_support = True class ShowPool(neutronV20.ShowCommand): """Show information of a given pool.""" resource = 'pool' class CreatePool(neutronV20.CreateCommand): """Create a pool.""" resource = 'pool' def add_known_arguments(self, parser): parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--description', help=_('Description of the pool.')) parser.add_argument( '--lb-method', required=True, choices=['ROUND_ROBIN', 'LEAST_CONNECTIONS', 'SOURCE_IP'], help=_('The algorithm used to distribute load between the members ' 'of the pool.')) parser.add_argument( '--name', required=True, help=_('The name of the pool.')) parser.add_argument( '--protocol', required=True, choices=['HTTP', 'HTTPS', 'TCP'], help=_('Protocol for balancing.')) parser.add_argument( '--subnet-id', metavar='SUBNET', required=True, help=_('The subnet on which the members of the pool will be ' 'located.')) parser.add_argument( '--provider', help=_('Provider name of the loadbalancer service.')) def args2body(self, parsed_args): _subnet_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'subnet', parsed_args.subnet_id) body = {'admin_state_up': parsed_args.admin_state, 'subnet_id': _subnet_id} neutronV20.update_dict(parsed_args, body, ['description', 'lb_method', 'name', 'protocol', 'tenant_id', 'provider']) return {self.resource: body} class UpdatePool(neutronV20.UpdateCommand): """Update a given pool.""" resource = 'pool' class DeletePool(neutronV20.DeleteCommand): """Delete a given pool.""" resource = 'pool' class RetrievePoolStats(neutronV20.ShowCommand): """Retrieve stats for a given pool.""" resource = 'pool' def take_action(self, parsed_args): neutron_client = self.get_client() pool_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'pool', parsed_args.id) params = {} if parsed_args.fields: params = {'fields': parsed_args.fields} data = neutron_client.retrieve_pool_stats(pool_id, **params) self.format_output_data(data) stats = data['stats'] if 'stats' in data: return zip(*sorted(six.iteritems(stats))) else: return None python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/v2/0000775000175100017510000000000013232473710024037 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/v2/listener.py0000666000175100017510000001364013232473350026244 0ustar zuulzuul00000000000000# Copyright 2014 Blue Box Group, Inc. # Copyright 2015 Hewlett-Packard Development Company, L.P. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 def _get_loadbalancer_id(client, lb_id_or_name): return neutronV20.find_resourceid_by_name_or_id( client, 'loadbalancer', lb_id_or_name, cmd_resource='lbaas_loadbalancer') def _get_pool(client, pool_id_or_name): return neutronV20.find_resource_by_name_or_id( client, 'pool', pool_id_or_name, cmd_resource='lbaas_pool') def _get_pool_id(client, pool_id_or_name): return neutronV20.find_resourceid_by_name_or_id( client, 'pool', pool_id_or_name, cmd_resource='lbaas_pool') def _add_common_args(parser): parser.add_argument( '--description', help=_('Description of the listener.')) parser.add_argument( '--connection-limit', type=int, help=_('The maximum number of connections per second allowed for ' 'the listener. Positive integer or -1 ' 'for unlimited (default).')) parser.add_argument( '--default-pool', help=_('Default pool for the listener.')) def _parse_common_args(body, parsed_args, client): neutronV20.update_dict(parsed_args, body, ['name', 'description', 'connection_limit']) if parsed_args.default_pool: default_pool_id = _get_pool_id( client, parsed_args.default_pool) body['default_pool_id'] = default_pool_id class ListListener(neutronV20.ListCommand): """LBaaS v2 List listeners that belong to a given tenant.""" resource = 'listener' list_columns = ['id', 'default_pool_id', 'name', 'protocol', 'protocol_port', 'admin_state_up', 'status'] pagination_support = True sorting_support = True class ShowListener(neutronV20.ShowCommand): """LBaaS v2 Show information of a given listener.""" resource = 'listener' class CreateListener(neutronV20.CreateCommand): """LBaaS v2 Create a listener.""" resource = 'listener' def add_known_arguments(self, parser): _add_common_args(parser) parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--name', help=_('The name of the listener. At least one of --default-pool ' 'or --loadbalancer must be specified.')) parser.add_argument( '--default-tls-container-ref', dest='default_tls_container_ref', help=_('Default TLS container reference' ' to retrieve TLS information.')) parser.add_argument( '--sni-container-refs', dest='sni_container_refs', nargs='+', help=_('List of TLS container references for SNI.')) parser.add_argument( '--loadbalancer', metavar='LOADBALANCER', help=_('ID or name of the load balancer.')) parser.add_argument( '--protocol', required=True, choices=['TCP', 'HTTP', 'HTTPS', 'TERMINATED_HTTPS'], type=utils.convert_to_uppercase, help=_('Protocol for the listener.')) parser.add_argument( '--protocol-port', dest='protocol_port', required=True, metavar='PORT', help=_('Protocol port for the listener.')) def args2body(self, parsed_args): if not parsed_args.loadbalancer and not parsed_args.default_pool: message = _('Either --default-pool or --loadbalancer must be ' 'specified.') raise exceptions.CommandError(message) body = { 'protocol': parsed_args.protocol, 'protocol_port': parsed_args.protocol_port, 'admin_state_up': parsed_args.admin_state } if parsed_args.loadbalancer: loadbalancer_id = _get_loadbalancer_id( self.get_client(), parsed_args.loadbalancer) body['loadbalancer_id'] = loadbalancer_id neutronV20.update_dict(parsed_args, body, ['default_tls_container_ref', 'sni_container_refs', 'tenant_id']) _parse_common_args(body, parsed_args, self.get_client()) return {self.resource: body} class UpdateListener(neutronV20.UpdateCommand): """LBaaS v2 Update a given listener.""" resource = 'listener' def add_known_arguments(self, parser): _add_common_args(parser) parser.add_argument( '--name', help=_('Name of the listener.')) utils.add_boolean_argument( parser, '--admin-state-up', dest='admin_state_up', help=_('Specify the administrative state of the listener. ' '(True meaning "Up")')) def args2body(self, parsed_args): body = {} neutronV20.update_dict(parsed_args, body, ['admin_state_up']) _parse_common_args(body, parsed_args, self.get_client()) return {self.resource: body} class DeleteListener(neutronV20.DeleteCommand): """LBaaS v2 Delete a given listener.""" resource = 'listener' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/v2/pool.py0000666000175100017510000001542713232473350025375 0ustar zuulzuul00000000000000# Copyright 2013 Mirantis Inc. # Copyright 2014 Blue Box Group, Inc. # Copyright 2015 Hewlett-Packard Development Company, L.P. # Copyright 2015 Blue Box, an IBM Company # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 def _get_loadbalancer_id(client, lb_id_or_name): return neutronV20.find_resourceid_by_name_or_id( client, 'loadbalancer', lb_id_or_name, cmd_resource='lbaas_loadbalancer') def _get_listener(client, listener_id_or_name): return neutronV20.find_resource_by_name_or_id( client, 'listener', listener_id_or_name) def _get_listener_id(client, listener_id_or_name): return neutronV20.find_resourceid_by_name_or_id( client, 'listener', listener_id_or_name) def _add_common_args(parser, is_create=True): parser.add_argument( '--description', help=_('Description of the pool.')) parser.add_argument( '--name', help=_('The name of the pool.')) parser.add_argument( '--lb-algorithm', required=is_create, type=utils.convert_to_uppercase, choices=['ROUND_ROBIN', 'LEAST_CONNECTIONS', 'SOURCE_IP'], help=_('The algorithm used to distribute load between the members ' 'of the pool.')) def _parse_common_args(parsed_args): body = {} neutronV20.update_dict(parsed_args, body, ['description', 'lb_algorithm', 'name']) return body class ListPool(neutronV20.ListCommand): """LBaaS v2 List pools that belong to a given tenant.""" resource = 'pool' shadow_resource = 'lbaas_pool' list_columns = ['id', 'name', 'lb_algorithm', 'protocol', 'admin_state_up'] pagination_support = True sorting_support = True class ShowPool(neutronV20.ShowCommand): """LBaaS v2 Show information of a given pool.""" resource = 'pool' shadow_resource = 'lbaas_pool' def cleanup_output_data(self, data): if 'members' not in data['pool']: return [] member_info = [] for member in data['pool']['members']: member_info.append(member['id']) data['pool']['members'] = member_info class CreatePool(neutronV20.CreateCommand): """LBaaS v2 Create a pool.""" resource = 'pool' shadow_resource = 'lbaas_pool' def add_known_arguments(self, parser): _add_common_args(parser) parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--listener', help=_('Listener whose default-pool should be set to this pool. ' 'At least one of --listener or --loadbalancer must be ' 'specified.')) parser.add_argument( '--loadbalancer', help=_('Loadbalancer with which this pool should be associated. ' 'At least one of --listener or --loadbalancer must be ' 'specified.')) parser.add_argument( '--protocol', type=utils.convert_to_uppercase, required=True, choices=['HTTP', 'HTTPS', 'TCP'], help=_('Protocol for balancing.')) parser.add_argument( '--session-persistence', metavar='type=TYPE[,cookie_name=COOKIE_NAME]', type=utils.str2dict_type(required_keys=['type'], optional_keys=['cookie_name']), help=_('The type of session persistence to use and associated ' 'cookie name.')) def args2body(self, parsed_args): if not parsed_args.listener and not parsed_args.loadbalancer: message = _('At least one of --listener or --loadbalancer must be ' 'specified.') raise exceptions.CommandError(message) body = _parse_common_args(parsed_args) if parsed_args.listener: listener_id = _get_listener_id( self.get_client(), parsed_args.listener) body['listener_id'] = listener_id if parsed_args.loadbalancer: loadbalancer_id = _get_loadbalancer_id( self.get_client(), parsed_args.loadbalancer) body['loadbalancer_id'] = loadbalancer_id body['admin_state_up'] = parsed_args.admin_state neutronV20.update_dict(parsed_args, body, ['tenant_id', 'protocol', 'session_persistence']) return {self.resource: body} class UpdatePool(neutronV20.UpdateCommand): """LBaaS v2 Update a given pool.""" resource = 'pool' shadow_resource = 'lbaas_pool' def add_known_arguments(self, parser): utils.add_boolean_argument( parser, '--admin-state-up', help=_('Update the administrative state of ' 'the pool (True meaning "Up").')) session_group = parser.add_mutually_exclusive_group() session_group.add_argument( '--session-persistence', metavar='type=TYPE[,cookie_name=COOKIE_NAME]', type=utils.str2dict_type(required_keys=['type'], optional_keys=['cookie_name']), help=_('The type of session persistence to use and associated ' 'cookie name.')) session_group.add_argument( '--no-session-persistence', action='store_true', help=_('Clear session persistence for the pool.')) _add_common_args(parser, False) def args2body(self, parsed_args): body = _parse_common_args(parsed_args) if parsed_args.no_session_persistence: body['session_persistence'] = None elif parsed_args.session_persistence: body['session_persistence'] = parsed_args.session_persistence neutronV20.update_dict(parsed_args, body, ['admin_state_up']) return {self.resource: body} class DeletePool(neutronV20.DeleteCommand): """LBaaS v2 Delete a given pool.""" resource = 'pool' shadow_resource = 'lbaas_pool' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/v2/healthmonitor.py0000666000175100017510000001234613232473350027276 0ustar zuulzuul00000000000000# Copyright 2013 Mirantis Inc. # Copyright 2014 Blue Box Group, Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 def _add_common_args(parser, is_create=True): parser.add_argument( '--delay', required=is_create, help=_('The time in seconds between sending probes to members.')) parser.add_argument( '--name', help=_('Name of the health monitor.')) parser.add_argument( '--timeout', required=is_create, help=_('Maximum number of seconds for a monitor to wait for a ' 'connection to be established before it times out. The ' 'value must be less than the delay value.')) parser.add_argument( '--http-method', type=utils.convert_to_uppercase, help=_('The HTTP method used for requests by the monitor of type ' 'HTTP.')) parser.add_argument( '--url-path', help=_('The HTTP path used in the HTTP request used by the monitor ' 'to test a member health. This must be a string ' 'beginning with a / (forward slash).')) parser.add_argument( '--max-retries', required=is_create, help=_('Number of permissible connection failures before changing ' 'the member status to INACTIVE. [1..10].')) parser.add_argument( '--expected-codes', help=_('The list of HTTP status codes expected in ' 'response from the member to declare it healthy. This ' 'attribute can contain one value, ' 'or a list of values separated by comma, ' 'or a range of values (e.g. "200-299"). If this attribute ' 'is not specified, it defaults to "200".')) def _parse_common_args(body, parsed_args): neutronV20.update_dict(parsed_args, body, ['expected_codes', 'http_method', 'url_path', 'timeout', 'name', 'delay', 'max_retries']) class ListHealthMonitor(neutronV20.ListCommand): """LBaaS v2 List healthmonitors that belong to a given tenant.""" resource = 'healthmonitor' shadow_resource = 'lbaas_healthmonitor' list_columns = ['id', 'name', 'type', 'admin_state_up'] pagination_support = True sorting_support = True class ShowHealthMonitor(neutronV20.ShowCommand): """LBaaS v2 Show information of a given healthmonitor.""" resource = 'healthmonitor' shadow_resource = 'lbaas_healthmonitor' class CreateHealthMonitor(neutronV20.CreateCommand): """LBaaS v2 Create a healthmonitor.""" resource = 'healthmonitor' shadow_resource = 'lbaas_healthmonitor' def add_known_arguments(self, parser): _add_common_args(parser) parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--type', required=True, choices=['PING', 'TCP', 'HTTP', 'HTTPS'], help=_('One of the predefined health monitor types.')) parser.add_argument( '--pool', required=True, help=_('ID or name of the pool that this healthmonitor will ' 'monitor.')) def args2body(self, parsed_args): pool_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'pool', parsed_args.pool, cmd_resource='lbaas_pool') body = {'admin_state_up': parsed_args.admin_state, 'type': parsed_args.type, 'pool_id': pool_id} neutronV20.update_dict(parsed_args, body, ['tenant_id']) _parse_common_args(body, parsed_args) return {self.resource: body} class UpdateHealthMonitor(neutronV20.UpdateCommand): """LBaaS v2 Update a given healthmonitor.""" resource = 'healthmonitor' shadow_resource = 'lbaas_healthmonitor' def add_known_arguments(self, parser): _add_common_args(parser, is_create=False) utils.add_boolean_argument( parser, '--admin-state-up', help=_('Update the administrative state of ' 'the health monitor (True meaning "Up").')) def args2body(self, parsed_args): body = {} _parse_common_args(body, parsed_args) neutronV20.update_dict(parsed_args, body, ['admin_state_up']) return {self.resource: body} class DeleteHealthMonitor(neutronV20.DeleteCommand): """LBaaS v2 Delete a given healthmonitor.""" resource = 'healthmonitor' shadow_resource = 'lbaas_healthmonitor' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/v2/loadbalancer.py0000666000175100017510000001437513232473350027034 0ustar zuulzuul00000000000000# Copyright 2014 Blue Box Group, Inc. # Copyright 2015 Hewlett-Packard Development Company, L.P. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from oslo_serialization import jsonutils from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 def _add_common_args(parser): parser.add_argument( '--description', help=_('Description of the load balancer.')) parser.add_argument( '--name', metavar='NAME', help=_('Name of the load balancer.')) def _parse_common_args(body, parsed_args): neutronV20.update_dict(parsed_args, body, ['name', 'description']) class ListLoadBalancer(neutronV20.ListCommand): """LBaaS v2 List loadbalancers that belong to a given tenant.""" resource = 'loadbalancer' list_columns = ['id', 'name', 'vip_address', 'provisioning_status', 'provider'] pagination_support = True sorting_support = True class ShowLoadBalancer(neutronV20.ShowCommand): """LBaaS v2 Show information of a given loadbalancer.""" resource = 'loadbalancer' class CreateLoadBalancer(neutronV20.CreateCommand): """LBaaS v2 Create a loadbalancer.""" resource = 'loadbalancer' def add_known_arguments(self, parser): _add_common_args(parser) parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--provider', help=_('Provider name of the load balancer service.')) parser.add_argument( '--flavor', help=_('ID or name of the flavor.')) parser.add_argument( '--vip-address', help=_('VIP address for the load balancer.')) parser.add_argument( 'vip_subnet', metavar='VIP_SUBNET', help=_('Load balancer VIP subnet.')) def args2body(self, parsed_args): _subnet_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'subnet', parsed_args.vip_subnet) body = {'vip_subnet_id': _subnet_id, 'admin_state_up': parsed_args.admin_state} if parsed_args.flavor: _flavor_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'flavor', parsed_args.flavor) body['flavor_id'] = _flavor_id neutronV20.update_dict(parsed_args, body, ['provider', 'vip_address', 'tenant_id']) _parse_common_args(body, parsed_args) return {self.resource: body} class UpdateLoadBalancer(neutronV20.UpdateCommand): """LBaaS v2 Update a given loadbalancer.""" resource = 'loadbalancer' def add_known_arguments(self, parser): utils.add_boolean_argument( parser, '--admin-state-up', help=_('Update the administrative state of ' 'the load balancer (True meaning "Up").')) _add_common_args(parser) def args2body(self, parsed_args): body = {} _parse_common_args(body, parsed_args) neutronV20.update_dict(parsed_args, body, ['admin_state_up']) return {self.resource: body} class DeleteLoadBalancer(neutronV20.DeleteCommand): """LBaaS v2 Delete a given loadbalancer.""" resource = 'loadbalancer' class RetrieveLoadBalancerStats(neutronV20.ShowCommand): """Retrieve stats for a given loadbalancer.""" resource = 'loadbalancer' def take_action(self, parsed_args): neutron_client = self.get_client() loadbalancer_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'loadbalancer', parsed_args.id) params = {} if parsed_args.fields: params = {'fields': parsed_args.fields} data = neutron_client.retrieve_loadbalancer_stats(loadbalancer_id, **params) self.format_output_data(data) stats = data['stats'] if 'stats' in data: # To render the output table like: # +--------------------+-------+ # | Field | Value | # +--------------------+-------+ # | field1 | value1| # | field2 | value2| # | field3 | value3| # | ... | ... | # +--------------------+-------+ # it has two columns and the Filed column is alphabetical, # here convert the data dict to the 1-1 vector format below: # [(field1, field2, field3, ...), (value1, value2, value3, ...)] return list(zip(*sorted(stats.items()))) class RetrieveLoadBalancerStatus(neutronV20.NeutronCommand): """Retrieve status for a given loadbalancer. The only output is a formatted JSON tree, and the table format does not support this type of data. """ resource = 'loadbalancer' def get_parser(self, prog_name): parser = super(RetrieveLoadBalancerStatus, self).get_parser(prog_name) parser.add_argument( self.resource, metavar=self.resource.upper(), help=_('ID or name of %s to show.') % self.resource) return parser def take_action(self, parsed_args): self.log.debug('run(%s)', parsed_args) neutron_client = self.get_client() lb_id = neutronV20.find_resourceid_by_name_or_id( neutron_client, self.resource, parsed_args.loadbalancer) params = {} data = neutron_client.retrieve_loadbalancer_status(lb_id, **params) res = data['statuses'] if 'statuses' in data: print(jsonutils.dumps(res, indent=4)) python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/v2/member.py0000666000175100017510000001236713232473350025673 0ustar zuulzuul00000000000000# Copyright 2013 Mirantis Inc. # Copyright 2014 Blue Box Group, Inc. # Copyright 2015 Hewlett-Packard Development Company, L.P. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 def _get_pool_id(client, pool_id_or_name): return neutronV20.find_resourceid_by_name_or_id(client, 'pool', pool_id_or_name, cmd_resource='lbaas_pool') class LbaasMemberMixin(object): def set_extra_attrs(self, parsed_args): self.parent_id = _get_pool_id(self.get_client(), parsed_args.pool) def add_known_arguments(self, parser): parser.add_argument( 'pool', metavar='POOL', help=_('ID or name of the pool that this member belongs to.')) def _add_common_args(parser): parser.add_argument( '--name', help=_('Name of the member.')) parser.add_argument( '--weight', help=_('Weight of the member in the pool (default:1, [0..256]).')) def _parse_common_args(body, parsed_args): neutronV20.update_dict(parsed_args, body, ['weight', 'name']) class ListMember(LbaasMemberMixin, neutronV20.ListCommand): """LBaaS v2 List members that belong to a given pool.""" resource = 'member' shadow_resource = 'lbaas_member' list_columns = [ 'id', 'name', 'address', 'protocol_port', 'weight', 'subnet_id', 'admin_state_up', 'status' ] pagination_support = True sorting_support = True def take_action(self, parsed_args): self.parent_id = _get_pool_id(self.get_client(), parsed_args.pool) self.values_specs.append('--pool_id=%s' % self.parent_id) return super(ListMember, self).take_action(parsed_args) class ShowMember(LbaasMemberMixin, neutronV20.ShowCommand): """LBaaS v2 Show information of a given member.""" resource = 'member' shadow_resource = 'lbaas_member' class CreateMember(neutronV20.CreateCommand): """LBaaS v2 Create a member.""" resource = 'member' shadow_resource = 'lbaas_member' def add_known_arguments(self, parser): _add_common_args(parser) parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--subnet', required=True, help=_('Subnet ID or name for the member.')) parser.add_argument( '--address', required=True, help=_('IP address of the pool member in the pool.')) parser.add_argument( '--protocol-port', required=True, help=_('Port on which the pool member listens for requests or ' 'connections.')) parser.add_argument( 'pool', metavar='POOL', help=_('ID or name of the pool that this member belongs to.')) def args2body(self, parsed_args): self.parent_id = _get_pool_id(self.get_client(), parsed_args.pool) _subnet_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'subnet', parsed_args.subnet) body = {'subnet_id': _subnet_id, 'admin_state_up': parsed_args.admin_state, 'protocol_port': parsed_args.protocol_port, 'address': parsed_args.address} neutronV20.update_dict(parsed_args, body, ['subnet_id', 'tenant_id']) _parse_common_args(body, parsed_args) return {self.resource: body} class UpdateMember(neutronV20.UpdateCommand): """LBaaS v2 Update a given member.""" resource = 'member' shadow_resource = 'lbaas_member' def add_known_arguments(self, parser): parser.add_argument( 'pool', metavar='POOL', help=_('ID or name of the pool that this member belongs to.')) utils.add_boolean_argument( parser, '--admin-state-up', help=_('Update the administrative state of ' 'the member (True meaning "Up").')) _add_common_args(parser) def args2body(self, parsed_args): self.parent_id = _get_pool_id(self.get_client(), parsed_args.pool) body = {} if hasattr(parsed_args, "admin_state_up"): body['admin_state_up'] = parsed_args.admin_state_up _parse_common_args(body, parsed_args) return {self.resource: body} class DeleteMember(LbaasMemberMixin, neutronV20.DeleteCommand): """LBaaS v2 Delete a given member.""" resource = 'member' shadow_resource = 'lbaas_member' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/v2/l7rule.py0000666000175100017510000001142013232473350025623 0ustar zuulzuul00000000000000# Copyright 2016 Radware LTD. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 def _get_policy_id(client, policy_id_or_name): return neutronV20.find_resourceid_by_name_or_id( client, 'l7policy', policy_id_or_name, cmd_resource='lbaas_l7policy') class LbaasL7RuleMixin(object): def set_extra_attrs(self, parsed_args): self.parent_id = _get_policy_id(self.get_client(), parsed_args.l7policy) def add_known_arguments(self, parser): parser.add_argument( 'l7policy', metavar='L7POLICY', help=_('ID or name of L7 policy this rule belongs to.')) def _add_common_args(parser, is_create=True): parser.add_argument( '--type', required=is_create, type=utils.convert_to_uppercase, choices=['HOST_NAME', 'PATH', 'FILE_TYPE', 'HEADER', 'COOKIE'], help=_('Rule type.')) parser.add_argument( '--compare-type', required=is_create, type=utils.convert_to_uppercase, choices=['REGEX', 'STARTS_WITH', 'ENDS_WITH', 'CONTAINS', 'EQUAL_TO'], help=_('Rule compare type.')) parser.add_argument( '--invert-compare', dest='invert', action='store_true', help=_('Invert the compare type.')) parser.add_argument( '--key', help=_('Key to compare.' ' Relevant for HEADER and COOKIE types only.')) parser.add_argument( '--value', required=is_create, help=_('Value to compare.')) def _common_args2body(client, parsed_args, is_create=True): attributes = ['type', 'compare_type', 'invert', 'key', 'value', 'admin_state_up'] if is_create: attributes.append('tenant_id') body = {} neutronV20.update_dict(parsed_args, body, attributes) return {'rule': body} class ListL7Rule(LbaasL7RuleMixin, neutronV20.ListCommand): """LBaaS v2 List L7 rules that belong to a given L7 policy.""" resource = 'rule' shadow_resource = 'lbaas_l7rule' pagination_support = True sorting_support = True list_columns = [ 'id', 'type', 'compare_type', 'invert', 'key', 'value', 'admin_state_up', 'status' ] def take_action(self, parsed_args): self.parent_id = _get_policy_id(self.get_client(), parsed_args.l7policy) self.values_specs.append('--l7policy_id=%s' % self.parent_id) return super(ListL7Rule, self).take_action(parsed_args) class ShowL7Rule(LbaasL7RuleMixin, neutronV20.ShowCommand): """LBaaS v2 Show information of a given rule.""" resource = 'rule' shadow_resource = 'lbaas_l7rule' class CreateL7Rule(LbaasL7RuleMixin, neutronV20.CreateCommand): """LBaaS v2 Create L7 rule.""" resource = 'rule' shadow_resource = 'lbaas_l7rule' def add_known_arguments(self, parser): super(CreateL7Rule, self).add_known_arguments(parser) _add_common_args(parser) parser.add_argument( '--admin-state-down', dest='admin_state_up', action='store_false', help=_('Set admin state up to false')) def args2body(self, parsed_args): return _common_args2body(self.get_client(), parsed_args) class UpdateL7Rule(LbaasL7RuleMixin, neutronV20.UpdateCommand): """LBaaS v2 Update a given L7 rule.""" resource = 'rule' shadow_resource = 'lbaas_l7rule' def add_known_arguments(self, parser): super(UpdateL7Rule, self).add_known_arguments(parser) _add_common_args(parser, False) utils.add_boolean_argument( parser, '--admin-state-up', help=_('Specify the administrative state of the rule' ' (True meaning "Up").')) def args2body(self, parsed_args): return _common_args2body(self.get_client(), parsed_args, False) class DeleteL7Rule(LbaasL7RuleMixin, neutronV20.DeleteCommand): """LBaaS v2 Delete a given L7 rule.""" resource = 'rule' shadow_resource = 'lbaas_l7rule' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/v2/l7policy.py0000666000175100017510000001247013232473350026161 0ustar zuulzuul00000000000000# Copyright 2016 Radware LTD. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 def _get_listener_id(client, listener_id_or_name): return neutronV20.find_resourceid_by_name_or_id( client, 'listener', listener_id_or_name) def _get_pool_id(client, pool_id_or_name): return neutronV20.find_resourceid_by_name_or_id( client, 'pool', pool_id_or_name, cmd_resource='lbaas_pool') def _add_common_args(parser, is_create=True): parser.add_argument( '--name', help=_('Name of the policy.')) parser.add_argument( '--description', help=_('Description of the policy.')) parser.add_argument( '--action', required=is_create, metavar='ACTION', type=utils.convert_to_uppercase, choices=['REJECT', 'REDIRECT_TO_POOL', 'REDIRECT_TO_URL'], help=_('Action type of the policy.')) parser.add_argument( '--redirect-pool', help=_('ID or name of the pool for REDIRECT_TO_POOL action type.')) parser.add_argument( '--redirect-url', help=_('URL for REDIRECT_TO_URL action type. ' 'This should be a valid URL string.')) parser.add_argument( '--position', type=int, help=_('L7 policy position in ordered policies list. ' 'This must be an integer starting from 1. ' 'Not specifying the position will place the policy ' 'at the tail of existing policies list.')) def _common_args2body(client, parsed_args, is_create=True): if parsed_args.redirect_url: if parsed_args.action != 'REDIRECT_TO_URL': raise exceptions.CommandError(_('Action must be REDIRECT_TO_URL')) if parsed_args.redirect_pool: if parsed_args.action != 'REDIRECT_TO_POOL': raise exceptions.CommandError(_('Action must be REDIRECT_TO_POOL')) parsed_args.redirect_pool_id = _get_pool_id( client, parsed_args.redirect_pool) if (parsed_args.action == 'REDIRECT_TO_URL' and not parsed_args.redirect_url): raise exceptions.CommandError(_('Redirect URL must be specified')) if (parsed_args.action == 'REDIRECT_TO_POOL' and not parsed_args.redirect_pool): raise exceptions.CommandError(_('Redirect pool must be specified')) attributes = ['name', 'description', 'action', 'redirect_pool_id', 'redirect_url', 'position', 'admin_state_up'] if is_create: parsed_args.listener_id = _get_listener_id( client, parsed_args.listener) attributes.extend(['listener_id', 'tenant_id']) body = {} neutronV20.update_dict(parsed_args, body, attributes) return {'l7policy': body} class ListL7Policy(neutronV20.ListCommand): """LBaaS v2 List L7 policies that belong to a given listener.""" resource = 'l7policy' shadow_resource = 'lbaas_l7policy' pagination_support = True sorting_support = True list_columns = [ 'id', 'name', 'action', 'redirect_pool_id', 'redirect_url', 'position', 'admin_state_up', 'status' ] class ShowL7Policy(neutronV20.ShowCommand): """LBaaS v2 Show information of a given L7 policy.""" resource = 'l7policy' shadow_resource = 'lbaas_l7policy' class CreateL7Policy(neutronV20.CreateCommand): """LBaaS v2 Create L7 policy.""" resource = 'l7policy' shadow_resource = 'lbaas_l7policy' def add_known_arguments(self, parser): _add_common_args(parser) parser.add_argument( '--admin-state-down', dest='admin_state_up', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--listener', required=True, metavar='LISTENER', help=_('ID or name of the listener this policy belongs to.')) def args2body(self, parsed_args): return _common_args2body(self.get_client(), parsed_args) class UpdateL7Policy(neutronV20.UpdateCommand): """LBaaS v2 Update a given L7 policy.""" resource = 'l7policy' shadow_resource = 'lbaas_l7policy' def add_known_arguments(self, parser): _add_common_args(parser, is_create=False) utils.add_boolean_argument( parser, '--admin-state-up', help=_('Specify the administrative state of the policy' ' (True meaning "Up").')) def args2body(self, parsed_args): return _common_args2body(self.get_client(), parsed_args, False) class DeleteL7Policy(neutronV20.DeleteCommand): """LBaaS v2 Delete a given L7 policy.""" resource = 'l7policy' shadow_resource = 'lbaas_l7policy' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/v2/__init__.py0000666000175100017510000000000013232473350026140 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/healthmonitor.py0000666000175100017510000001420513232473350026743 0ustar zuulzuul00000000000000# Copyright 2013 Mirantis Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from __future__ import print_function from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronV20 class ListHealthMonitor(neutronV20.ListCommand): """List health monitors that belong to a given tenant.""" resource = 'health_monitor' list_columns = ['id', 'type', 'admin_state_up'] pagination_support = True sorting_support = True class ShowHealthMonitor(neutronV20.ShowCommand): """Show information of a given health monitor.""" resource = 'health_monitor' allow_names = False class CreateHealthMonitor(neutronV20.CreateCommand): """Create a health monitor.""" resource = 'health_monitor' def add_known_arguments(self, parser): parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--expected-codes', help=_('The list of HTTP status codes expected in ' 'response from the member to declare it healthy. This ' 'attribute can contain one value, ' 'or a list of values separated by comma, ' 'or a range of values (e.g. "200-299"). If this attribute ' 'is not specified, it defaults to "200".')) parser.add_argument( '--http-method', help=_('The HTTP method used for requests by the monitor of type ' 'HTTP.')) parser.add_argument( '--url-path', help=_('The HTTP path used in the HTTP request used by the monitor' ' to test a member health. This must be a string ' 'beginning with a / (forward slash).')) parser.add_argument( '--delay', required=True, help=_('The time in seconds between sending probes to members.')) parser.add_argument( '--max-retries', required=True, help=_('Number of permissible connection failures before changing ' 'the member status to INACTIVE. [1..10]')) parser.add_argument( '--timeout', required=True, help=_('Maximum number of seconds for a monitor to wait for a ' 'connection to be established before it times out. The ' 'value must be less than the delay value.')) parser.add_argument( '--type', required=True, choices=['PING', 'TCP', 'HTTP', 'HTTPS'], help=_('One of the predefined health monitor types.')) def args2body(self, parsed_args): body = {'admin_state_up': parsed_args.admin_state, 'delay': parsed_args.delay, 'max_retries': parsed_args.max_retries, 'timeout': parsed_args.timeout, 'type': parsed_args.type} neutronV20.update_dict(parsed_args, body, ['expected_codes', 'http_method', 'url_path', 'tenant_id']) return {self.resource: body} class UpdateHealthMonitor(neutronV20.UpdateCommand): """Update a given health monitor.""" resource = 'health_monitor' allow_names = False class DeleteHealthMonitor(neutronV20.DeleteCommand): """Delete a given health monitor.""" resource = 'health_monitor' allow_names = False class AssociateHealthMonitor(neutronV20.NeutronCommand): """Create a mapping between a health monitor and a pool.""" resource = 'health_monitor' def get_parser(self, prog_name): parser = super(AssociateHealthMonitor, self).get_parser(prog_name) parser.add_argument( 'health_monitor_id', metavar='HEALTH_MONITOR_ID', help=_('Health monitor to associate.')) parser.add_argument( 'pool_id', metavar='POOL', help=_('ID of the pool to be associated with the health monitor.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() body = {'health_monitor': {'id': parsed_args.health_monitor_id}} pool_id = neutronV20.find_resourceid_by_name_or_id( neutron_client, 'pool', parsed_args.pool_id) neutron_client.associate_health_monitor(pool_id, body) print((_('Associated health monitor ' '%s') % parsed_args.health_monitor_id), file=self.app.stdout) class DisassociateHealthMonitor(neutronV20.NeutronCommand): """Remove a mapping from a health monitor to a pool.""" resource = 'health_monitor' def get_parser(self, prog_name): parser = super(DisassociateHealthMonitor, self).get_parser(prog_name) parser.add_argument( 'health_monitor_id', metavar='HEALTH_MONITOR_ID', help=_('Health monitor to disassociate.')) parser.add_argument( 'pool_id', metavar='POOL', help=_('ID of the pool to be disassociated with the health ' 'monitor.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() pool_id = neutronV20.find_resourceid_by_name_or_id( neutron_client, 'pool', parsed_args.pool_id) neutron_client.disassociate_health_monitor(pool_id, parsed_args .health_monitor_id) print((_('Disassociated health monitor ' '%s') % parsed_args.health_monitor_id), file=self.app.stdout) python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/member.py0000666000175100017510000000525313232473350025340 0ustar zuulzuul00000000000000# Copyright 2013 Mirantis Inc. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronV20 class ListMember(neutronV20.ListCommand): """List members that belong to a given tenant.""" resource = 'member' list_columns = [ 'id', 'address', 'protocol_port', 'weight', 'admin_state_up', 'status' ] pagination_support = True sorting_support = True class ShowMember(neutronV20.ShowCommand): """Show information of a given member.""" resource = 'member' allow_names = False class CreateMember(neutronV20.CreateCommand): """Create a member.""" resource = 'member' def add_known_arguments(self, parser): parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--weight', help=_('Weight of pool member in the pool (default:1, [0..256]).')) parser.add_argument( '--address', required=True, help=_('IP address of the pool member on the pool network.')) parser.add_argument( '--protocol-port', required=True, help=_('Port on which the pool member listens for requests or ' 'connections.')) parser.add_argument( 'pool_id', metavar='POOL', help=_('ID or name of the pool this vip belongs to.')) def args2body(self, parsed_args): _pool_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'pool', parsed_args.pool_id) body = {'pool_id': _pool_id, 'admin_state_up': parsed_args.admin_state} neutronV20.update_dict( parsed_args, body, ['address', 'protocol_port', 'weight', 'tenant_id'] ) return {self.resource: body} class UpdateMember(neutronV20.UpdateCommand): """Update a given member.""" resource = 'member' class DeleteMember(neutronV20.DeleteCommand): """Delete a given member.""" resource = 'member' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/lb/__init__.py0000666000175100017510000000000013232473350025611 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/bgp/0000775000175100017510000000000013232473710023663 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/bgp/peer.py0000666000175100017510000001041613232473350025174 0ustar zuulzuul00000000000000# Copyright 2016 Huawei Technologies India Pvt. Ltd. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.common import validators from neutronclient.neutron import v2_0 as neutronv20 def get_bgp_peer_id(client, id_or_name): return neutronv20.find_resourceid_by_name_or_id(client, 'bgp_peer', id_or_name) def validate_peer_attributes(parsed_args): # Validate AS number validators.validate_int_range(parsed_args, 'remote_as', neutronv20.bgp.speaker.MIN_AS_NUM, neutronv20.bgp.speaker.MAX_AS_NUM) # Validate password if parsed_args.auth_type != 'none' and parsed_args.password is None: raise exceptions.CommandError(_('Must provide password if auth-type ' 'is specified.')) if parsed_args.auth_type == 'none' and parsed_args.password: raise exceptions.CommandError(_('Must provide auth-type if password ' 'is specified.')) class ListPeers(neutronv20.ListCommand): """List BGP peers.""" resource = 'bgp_peer' list_columns = ['id', 'name', 'peer_ip', 'remote_as'] pagination_support = True sorting_support = True class ShowPeer(neutronv20.ShowCommand): """Show information of a given BGP peer.""" resource = 'bgp_peer' class CreatePeer(neutronv20.CreateCommand): """Create a BGP Peer.""" resource = 'bgp_peer' def add_known_arguments(self, parser): parser.add_argument( 'name', metavar='NAME', help=_('Name of the BGP peer to create.')) parser.add_argument( '--peer-ip', metavar='PEER_IP_ADDRESS', required=True, help=_('Peer IP address.')) parser.add_argument( '--remote-as', required=True, metavar='PEER_REMOTE_AS', help=_('Peer AS number. (Integer in [%(min_val)s, %(max_val)s] ' 'is allowed.)') % {'min_val': neutronv20.bgp.speaker.MIN_AS_NUM, 'max_val': neutronv20.bgp.speaker.MAX_AS_NUM}) parser.add_argument( '--auth-type', metavar='PEER_AUTH_TYPE', choices=['none', 'md5'], default='none', type=utils.convert_to_lowercase, help=_('Authentication algorithm. Supported algorithms: ' 'none(default), md5')) parser.add_argument( '--password', metavar='AUTH_PASSWORD', help=_('Authentication password.')) def args2body(self, parsed_args): body = {} validate_peer_attributes(parsed_args) neutronv20.update_dict(parsed_args, body, ['name', 'peer_ip', 'remote_as', 'auth_type', 'password']) return {self.resource: body} class UpdatePeer(neutronv20.UpdateCommand): """Update BGP Peer's information.""" resource = 'bgp_peer' def add_known_arguments(self, parser): parser.add_argument( '--name', help=_('Updated name of the BGP peer.')) parser.add_argument( '--password', metavar='AUTH_PASSWORD', help=_('Updated authentication password.')) def args2body(self, parsed_args): body = {} neutronv20.update_dict(parsed_args, body, ['name', 'password']) return {self.resource: body} class DeletePeer(neutronv20.DeleteCommand): """Delete a BGP peer.""" resource = 'bgp_peer' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/bgp/speaker.py0000666000175100017510000002403713232473350025677 0ustar zuulzuul00000000000000# Copyright 2016 Huawei Technologies India Pvt. Ltd. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from __future__ import print_function from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.common import validators from neutronclient.neutron import v2_0 as neutronv20 from neutronclient.neutron.v2_0.bgp import peer as bgp_peer # Allowed BGP Autonomous number range MIN_AS_NUM = 1 MAX_AS_NUM = 65535 def get_network_id(client, id_or_name): return neutronv20.find_resourceid_by_name_or_id(client, 'network', id_or_name) def get_bgp_speaker_id(client, id_or_name): return neutronv20.find_resourceid_by_name_or_id(client, 'bgp_speaker', id_or_name) def validate_speaker_attributes(parsed_args): # Validate AS number validators.validate_int_range(parsed_args, 'local_as', MIN_AS_NUM, MAX_AS_NUM) def add_common_arguments(parser): utils.add_boolean_argument( parser, '--advertise-floating-ip-host-routes', help=_('Whether to enable or disable the advertisement ' 'of floating-ip host routes by the BGP speaker. ' 'By default floating ip host routes will be ' 'advertised by the BGP speaker.')) utils.add_boolean_argument( parser, '--advertise-tenant-networks', help=_('Whether to enable or disable the advertisement ' 'of tenant network routes by the BGP speaker. ' 'By default tenant network routes will be ' 'advertised by the BGP speaker.')) def args2body_common_arguments(body, parsed_args): neutronv20.update_dict(parsed_args, body, ['name', 'advertise_floating_ip_host_routes', 'advertise_tenant_networks']) class ListSpeakers(neutronv20.ListCommand): """List BGP speakers.""" resource = 'bgp_speaker' list_columns = ['id', 'name', 'local_as', 'ip_version'] pagination_support = True sorting_support = True class ShowSpeaker(neutronv20.ShowCommand): """Show information of a given BGP speaker.""" resource = 'bgp_speaker' class CreateSpeaker(neutronv20.CreateCommand): """Create a BGP Speaker.""" resource = 'bgp_speaker' def add_known_arguments(self, parser): parser.add_argument( 'name', metavar='NAME', help=_('Name of the BGP speaker to create.')) parser.add_argument( '--local-as', metavar='LOCAL_AS', required=True, help=_('Local AS number. (Integer in [%(min_val)s, %(max_val)s] ' 'is allowed.)') % {'min_val': MIN_AS_NUM, 'max_val': MAX_AS_NUM}) parser.add_argument( '--ip-version', type=int, choices=[4, 6], default=4, help=_('IP version for the BGP speaker (default is 4).')) add_common_arguments(parser) def args2body(self, parsed_args): body = {} validate_speaker_attributes(parsed_args) body['local_as'] = parsed_args.local_as body['ip_version'] = parsed_args.ip_version args2body_common_arguments(body, parsed_args) return {self.resource: body} class UpdateSpeaker(neutronv20.UpdateCommand): """Update BGP Speaker's information.""" resource = 'bgp_speaker' def add_known_arguments(self, parser): parser.add_argument( '--name', help=_('Name of the BGP speaker to update.')) add_common_arguments(parser) def args2body(self, parsed_args): body = {} args2body_common_arguments(body, parsed_args) return {self.resource: body} class DeleteSpeaker(neutronv20.DeleteCommand): """Delete a BGP speaker.""" resource = 'bgp_speaker' class AddPeerToSpeaker(neutronv20.NeutronCommand): """Add a peer to the BGP speaker.""" def get_parser(self, prog_name): parser = super(AddPeerToSpeaker, self).get_parser(prog_name) parser.add_argument( 'bgp_speaker', metavar='BGP_SPEAKER', help=_('ID or name of the BGP speaker.')) parser.add_argument( 'bgp_peer', metavar='BGP_PEER', help=_('ID or name of the BGP peer to add.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() _speaker_id = get_bgp_speaker_id(neutron_client, parsed_args.bgp_speaker) _peer_id = bgp_peer.get_bgp_peer_id(neutron_client, parsed_args.bgp_peer) neutron_client.add_peer_to_bgp_speaker(_speaker_id, {'bgp_peer_id': _peer_id}) print(_('Added BGP peer %(peer)s to BGP speaker %(speaker)s.') % {'peer': parsed_args.bgp_peer, 'speaker': parsed_args.bgp_speaker}, file=self.app.stdout) class RemovePeerFromSpeaker(neutronv20.NeutronCommand): """Remove a peer from the BGP speaker.""" def get_parser(self, prog_name): parser = super(RemovePeerFromSpeaker, self).get_parser(prog_name) parser.add_argument( 'bgp_speaker', metavar='BGP_SPEAKER', help=_('ID or name of the BGP speaker.')) parser.add_argument( 'bgp_peer', metavar='BGP_PEER', help=_('ID or name of the BGP peer to remove.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() _speaker_id = get_bgp_speaker_id(neutron_client, parsed_args.bgp_speaker) _peer_id = bgp_peer.get_bgp_peer_id(neutron_client, parsed_args.bgp_peer) neutron_client.remove_peer_from_bgp_speaker(_speaker_id, {'bgp_peer_id': _peer_id}) print(_('Removed BGP peer %(peer)s from BGP speaker %(speaker)s.') % {'peer': parsed_args.bgp_peer, 'speaker': parsed_args.bgp_speaker}, file=self.app.stdout) class AddNetworkToSpeaker(neutronv20.NeutronCommand): """Add a network to the BGP speaker.""" def get_parser(self, prog_name): parser = super(AddNetworkToSpeaker, self).get_parser(prog_name) parser.add_argument( 'bgp_speaker', metavar='BGP_SPEAKER', help=_('ID or name of the BGP speaker.')) parser.add_argument( 'network', metavar='NETWORK', help=_('ID or name of the network to add.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() _speaker_id = get_bgp_speaker_id(neutron_client, parsed_args.bgp_speaker) _net_id = get_network_id(neutron_client, parsed_args.network) neutron_client.add_network_to_bgp_speaker(_speaker_id, {'network_id': _net_id}) print(_('Added network %(net)s to BGP speaker %(speaker)s.') % {'net': parsed_args.network, 'speaker': parsed_args.bgp_speaker}, file=self.app.stdout) class RemoveNetworkFromSpeaker(neutronv20.NeutronCommand): """Remove a network from the BGP speaker.""" def get_parser(self, prog_name): parser = super(RemoveNetworkFromSpeaker, self).get_parser(prog_name) parser.add_argument( 'bgp_speaker', metavar='BGP_SPEAKER', help=_('ID or name of the BGP speaker.')) parser.add_argument( 'network', metavar='NETWORK', help=_('ID or name of the network to remove.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() _speaker_id = get_bgp_speaker_id(neutron_client, parsed_args.bgp_speaker) _net_id = get_network_id(neutron_client, parsed_args.network) neutron_client.remove_network_from_bgp_speaker(_speaker_id, {'network_id': _net_id}) print(_('Removed network %(net)s from BGP speaker %(speaker)s.') % {'net': parsed_args.network, 'speaker': parsed_args.bgp_speaker}, file=self.app.stdout) class ListRoutesAdvertisedBySpeaker(neutronv20.ListCommand): """List routes advertised by a given BGP speaker.""" list_columns = ['id', 'destination', 'next_hop'] resource = 'advertised_route' pagination_support = True sorting_support = True def get_parser(self, prog_name): parser = super(ListRoutesAdvertisedBySpeaker, self).get_parser(prog_name) parser.add_argument( 'bgp_speaker', metavar='BGP_SPEAKER', help=_('ID or name of the BGP speaker.')) return parser def call_server(self, neutron_client, search_opts, parsed_args): _speaker_id = get_bgp_speaker_id(neutron_client, parsed_args.bgp_speaker) data = neutron_client.list_route_advertised_from_bgp_speaker( _speaker_id, **search_opts) return data python-neutronclient-6.7.0/neutronclient/neutron/v2_0/bgp/dragentscheduler.py0000666000175100017510000001101313232473350027556 0ustar zuulzuul00000000000000# Copyright 2016 Huawei Technologies India Pvt. Ltd. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from __future__ import print_function from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronV20 from neutronclient.neutron.v2_0.bgp import speaker as bgp_speaker def add_common_args(parser): parser.add_argument('dragent_id', metavar='BGP_DRAGENT_ID', help=_('ID of the Dynamic Routing agent.')) parser.add_argument('bgp_speaker', metavar='BGP_SPEAKER', help=_('ID or name of the BGP speaker.')) class AddBGPSpeakerToDRAgent(neutronV20.NeutronCommand): """Add a BGP speaker to a Dynamic Routing agent.""" def get_parser(self, prog_name): parser = super(AddBGPSpeakerToDRAgent, self).get_parser(prog_name) add_common_args(parser) return parser def take_action(self, parsed_args): neutron_client = self.get_client() _speaker_id = bgp_speaker.get_bgp_speaker_id(neutron_client, parsed_args.bgp_speaker) neutron_client.add_bgp_speaker_to_dragent( parsed_args.dragent_id, {'bgp_speaker_id': _speaker_id}) print(_('Associated BGP speaker %s to the Dynamic Routing agent.') % parsed_args.bgp_speaker, file=self.app.stdout) class RemoveBGPSpeakerFromDRAgent(neutronV20.NeutronCommand): """Removes a BGP speaker from a Dynamic Routing agent.""" def get_parser(self, prog_name): parser = super(RemoveBGPSpeakerFromDRAgent, self).get_parser( prog_name) add_common_args(parser) return parser def take_action(self, parsed_args): neutron_client = self.get_client() _speaker_id = bgp_speaker.get_bgp_speaker_id(neutron_client, parsed_args.bgp_speaker) neutron_client.remove_bgp_speaker_from_dragent(parsed_args.dragent_id, _speaker_id) print(_('Disassociated BGP speaker %s from the ' 'Dynamic Routing agent.') % parsed_args.bgp_speaker, file=self.app.stdout) class ListBGPSpeakersOnDRAgent(neutronV20.ListCommand): """List BGP speakers hosted by a Dynamic Routing agent.""" list_columns = ['id', 'name', 'local_as', 'ip_version'] resource = 'bgp_speaker' def get_parser(self, prog_name): parser = super(ListBGPSpeakersOnDRAgent, self).get_parser(prog_name) parser.add_argument( 'dragent_id', metavar='BGP_DRAGENT_ID', help=_('ID of the Dynamic Routing agent.')) return parser def call_server(self, neutron_client, search_opts, parsed_args): data = neutron_client.list_bgp_speaker_on_dragent( parsed_args.dragent_id, **search_opts) return data class ListDRAgentsHostingBGPSpeaker(neutronV20.ListCommand): """List Dynamic Routing agents hosting a BGP speaker.""" resource = 'agent' _formatters = {} list_columns = ['id', 'host', 'admin_state_up', 'alive'] unknown_parts_flag = False def get_parser(self, prog_name): parser = super(ListDRAgentsHostingBGPSpeaker, self).get_parser(prog_name) parser.add_argument('bgp_speaker', metavar='BGP_SPEAKER', help=_('ID or name of the BGP speaker.')) return parser def extend_list(self, data, parsed_args): for agent in data: agent['alive'] = ":-)" if agent['alive'] else 'xxx' def call_server(self, neutron_client, search_opts, parsed_args): _speaker_id = bgp_speaker.get_bgp_speaker_id(neutron_client, parsed_args.bgp_speaker) search_opts['bgp_speaker'] = _speaker_id data = neutron_client.list_dragents_hosting_bgp_speaker(**search_opts) return data python-neutronclient-6.7.0/neutronclient/neutron/v2_0/bgp/__init__.py0000666000175100017510000000000013232473350025764 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/quota.py0000666000175100017510000002244413232473350024626 0ustar zuulzuul00000000000000# 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 # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from __future__ import print_function import abc import argparse from cliff import lister from cliff import show from oslo_serialization import jsonutils import six from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 def get_tenant_id(args, client): return (args.pos_tenant_id or args.tenant_id or client.get_quotas_tenant()['tenant']['tenant_id']) class DeleteQuota(neutronV20.NeutronCommand): """Delete defined quotas of a given tenant.""" resource = 'quota' def get_parser(self, prog_name): parser = super(DeleteQuota, self).get_parser(prog_name) parser.add_argument( '--tenant-id', metavar='tenant-id', help=_('The owner tenant ID.')) parser.add_argument( '--tenant_id', help=argparse.SUPPRESS) parser.add_argument( 'pos_tenant_id', help=argparse.SUPPRESS, nargs='?') return parser def take_action(self, parsed_args): neutron_client = self.get_client() tenant_id = get_tenant_id(parsed_args, neutron_client) obj_deleter = getattr(neutron_client, "delete_%s" % self.resource) obj_deleter(tenant_id) print((_('Deleted %(resource)s: %(tenant_id)s') % {'tenant_id': tenant_id, 'resource': self.resource}), file=self.app.stdout) return class ListQuota(neutronV20.NeutronCommand, lister.Lister): """List quotas of all tenants who have non-default quota values.""" resource = 'quota' def get_parser(self, prog_name): parser = super(ListQuota, self).get_parser(prog_name) return parser def take_action(self, parsed_args): neutron_client = self.get_client() search_opts = {} self.log.debug('search options: %s', search_opts) obj_lister = getattr(neutron_client, "list_%ss" % self.resource) data = obj_lister(**search_opts) info = [] collection = self.resource + "s" if collection in data: info = data[collection] _columns = len(info) > 0 and sorted(info[0].keys()) or [] return (_columns, (utils.get_item_properties(s, _columns) for s in info)) class ShowQuotaBase(neutronV20.NeutronCommand, show.ShowOne): """Base class to show quotas of a given tenant.""" resource = "quota" @abc.abstractmethod def retrieve_data(self, tenant_id, neutron_client): """Retrieve data using neutron client for the given tenant.""" def get_parser(self, prog_name): parser = super(ShowQuotaBase, self).get_parser(prog_name) parser.add_argument( '--tenant-id', metavar='tenant-id', help=_('The owner tenant ID.')) parser.add_argument( '--tenant_id', help=argparse.SUPPRESS) # allow people to do neutron quota-show . # we use a different name for this because the default will # override whatever is in the named arg otherwise. parser.add_argument( 'pos_tenant_id', help=argparse.SUPPRESS, nargs='?') return parser def take_action(self, parsed_args): neutron_client = self.get_client() tenant_id = get_tenant_id(parsed_args, neutron_client) data = self.retrieve_data(tenant_id, neutron_client) if self.resource in data: return zip(*sorted(six.iteritems(data[self.resource]))) return class ShowQuota(ShowQuotaBase): """Show quotas for a given tenant.""" def retrieve_data(self, tenant_id, neutron_client): return neutron_client.show_quota(tenant_id) class ShowQuotaDefault(ShowQuotaBase): """Show default quotas for a given tenant.""" def retrieve_data(self, tenant_id, neutron_client): return neutron_client.show_quota_default(tenant_id) class UpdateQuota(neutronV20.NeutronCommand, show.ShowOne): """Update a given tenant's quotas.""" resource = 'quota' def get_parser(self, prog_name): parser = super(UpdateQuota, self).get_parser(prog_name) parser.add_argument( '--tenant-id', metavar='tenant-id', help=_('The owner tenant ID.')) parser.add_argument( '--tenant_id', help=argparse.SUPPRESS) parser.add_argument( '--network', metavar='networks', help=_('The limit of networks.')) parser.add_argument( '--subnet', metavar='subnets', help=_('The limit of subnets.')) parser.add_argument( '--port', metavar='ports', help=_('The limit of ports.')) parser.add_argument( '--router', metavar='routers', help=_('The limit of routers.')) parser.add_argument( '--floatingip', metavar='floatingips', help=_('The limit of floating IPs.')) parser.add_argument( '--security-group', metavar='security_groups', help=_('The limit of security groups.')) parser.add_argument( '--security-group-rule', metavar='security_group_rules', help=_('The limit of security groups rules.')) parser.add_argument( '--vip', metavar='vips', help=_('The limit of vips.')) parser.add_argument( '--pool', metavar='pools', help=_('The limit of pools.')) parser.add_argument( '--member', metavar='members', help=_('The limit of pool members.')) parser.add_argument( '--health-monitor', metavar='health_monitors', dest='healthmonitor', help=_('The limit of health monitors.')) parser.add_argument( '--loadbalancer', metavar='loadbalancers', help=_('The limit of load balancers.')) parser.add_argument( '--listener', metavar='listeners', help=_('The limit of listeners.')) parser.add_argument( '--rbac-policy', metavar='rbac_policies', help=_('The limit of RBAC policies.')) parser.add_argument( 'pos_tenant_id', help=argparse.SUPPRESS, nargs='?') return parser def _validate_int(self, name, value): try: return_value = int(value) except Exception: message = (_('Quota limit for %(name)s must be an integer') % {'name': name}) raise exceptions.CommandError(message=message) return return_value def args2body(self, parsed_args): quota = {} for resource in ('network', 'subnet', 'port', 'router', 'floatingip', 'security_group', 'security_group_rule', 'vip', 'pool', 'member', 'healthmonitor', 'loadbalancer', 'listener', 'rbac_policy'): if getattr(parsed_args, resource): quota[resource] = self._validate_int( resource, getattr(parsed_args, resource)) if not quota: raise exceptions.CommandError( message=_('Must specify a valid resource with new quota ' 'value')) return {self.resource: quota} def take_action(self, parsed_args): neutron_client = self.get_client() _extra_values = neutronV20.parse_args_to_dict(self.values_specs) neutronV20._merge_args(self, parsed_args, _extra_values, self.values_specs) body = self.args2body(parsed_args) if self.resource in body: body[self.resource].update(_extra_values) else: body[self.resource] = _extra_values obj_updator = getattr(neutron_client, "update_%s" % self.resource) tenant_id = get_tenant_id(parsed_args, neutron_client) data = obj_updator(tenant_id, body) if self.resource in data: for k, v in six.iteritems(data[self.resource]): if isinstance(v, list): value = "" for _item in v: if value: value += "\n" if isinstance(_item, dict): value += jsonutils.dumps(_item) else: value += str(_item) data[self.resource][k] = value elif v is None: data[self.resource][k] = '' return zip(*sorted(six.iteritems(data[self.resource]))) else: return python-neutronclient-6.7.0/neutronclient/neutron/v2_0/router.py0000666000175100017510000002647313232473350025023 0ustar zuulzuul00000000000000# 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 # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from __future__ import print_function import argparse from oslo_serialization import jsonutils from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 from neutronclient.neutron.v2_0 import availability_zone def _format_external_gateway_info(router): try: return jsonutils.dumps(router['external_gateway_info']) except (TypeError, KeyError): return '' class ListRouter(neutronV20.ListCommand): """List routers that belong to a given tenant.""" resource = 'router' _formatters = {'external_gateway_info': _format_external_gateway_info, } list_columns = ['id', 'name', 'external_gateway_info', 'distributed', 'ha'] pagination_support = True sorting_support = True class ShowRouter(neutronV20.ShowCommand): """Show information of a given router.""" resource = 'router' class CreateRouter(neutronV20.CreateCommand): """Create a router for a given tenant.""" resource = 'router' _formatters = {'external_gateway_info': _format_external_gateway_info, } def add_known_arguments(self, parser): parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--admin_state_down', dest='admin_state', action='store_false', help=argparse.SUPPRESS) parser.add_argument( 'name', metavar='NAME', help=_('Name of the router to be created.')) parser.add_argument( '--description', help=_('Description of router.')) parser.add_argument( '--flavor', help=_('ID or name of flavor.')) utils.add_boolean_argument( parser, '--distributed', dest='distributed', help=_('Create a distributed router.')) utils.add_boolean_argument( parser, '--ha', dest='ha', help=_('Create a highly available router.')) availability_zone.add_az_hint_argument(parser, self.resource) def args2body(self, parsed_args): body = {'admin_state_up': parsed_args.admin_state} if parsed_args.flavor: _flavor_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'flavor', parsed_args.flavor) body['flavor_id'] = _flavor_id neutronV20.update_dict(parsed_args, body, ['name', 'tenant_id', 'distributed', 'ha', 'description']) availability_zone.args2body_az_hint(parsed_args, body) return {self.resource: body} class DeleteRouter(neutronV20.DeleteCommand): """Delete a given router.""" resource = 'router' class UpdateRouter(neutronV20.UpdateCommand): """Update router's information.""" resource = 'router' def add_known_arguments(self, parser): parser.add_argument( '--name', help=_('Updated name of the router.')) parser.add_argument( '--description', help=_('Description of router.')) utils.add_boolean_argument( parser, '--admin-state-up', dest='admin_state', help=_('Specify the administrative state of the router ' '(True means "Up").')) utils.add_boolean_argument( parser, '--admin_state_up', dest='admin_state', help=argparse.SUPPRESS) utils.add_boolean_argument( parser, '--distributed', dest='distributed', help=_('True means this router should operate in ' 'distributed mode.')) routes_group = parser.add_mutually_exclusive_group() routes_group.add_argument( '--route', metavar='destination=CIDR,nexthop=IP_ADDR', action='append', dest='routes', type=utils.str2dict_type(required_keys=['destination', 'nexthop']), help=_('Route to associate with the router.' ' You can repeat this option.')) routes_group.add_argument( '--no-routes', action='store_true', help=_('Remove routes associated with the router.')) def args2body(self, parsed_args): body = {} if hasattr(parsed_args, 'admin_state'): body['admin_state_up'] = parsed_args.admin_state neutronV20.update_dict(parsed_args, body, ['name', 'distributed', 'description']) if parsed_args.no_routes: body['routes'] = None elif parsed_args.routes: body['routes'] = parsed_args.routes return {self.resource: body} class RouterInterfaceCommand(neutronV20.NeutronCommand): """Based class to Add/Remove router interface.""" resource = 'router' def call_api(self, neutron_client, router_id, body): raise NotImplementedError() def success_message(self, router_id, portinfo): raise NotImplementedError() def get_parser(self, prog_name): parser = super(RouterInterfaceCommand, self).get_parser(prog_name) parser.add_argument( 'router', metavar='ROUTER', help=_('ID or name of the router.')) parser.add_argument( 'interface', metavar='INTERFACE', help=_('The format is "SUBNET|subnet=SUBNET|port=PORT". ' 'Either a subnet or port must be specified. ' 'Both ID and name are accepted as SUBNET or PORT. ' 'Note that "subnet=" can be omitted when specifying a ' 'subnet.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() if '=' in parsed_args.interface: resource, value = parsed_args.interface.split('=', 1) if resource not in ['subnet', 'port']: exceptions.CommandError(_('You must specify either subnet or ' 'port for INTERFACE parameter.')) else: resource = 'subnet' value = parsed_args.interface _router_id = neutronV20.find_resourceid_by_name_or_id( neutron_client, self.resource, parsed_args.router) _interface_id = neutronV20.find_resourceid_by_name_or_id( neutron_client, resource, value) body = {'%s_id' % resource: _interface_id} portinfo = self.call_api(neutron_client, _router_id, body) print(self.success_message(parsed_args.router, portinfo), file=self.app.stdout) class AddInterfaceRouter(RouterInterfaceCommand): """Add an internal network interface to a router.""" def call_api(self, neutron_client, router_id, body): return neutron_client.add_interface_router(router_id, body) def success_message(self, router_id, portinfo): return (_('Added interface %(port)s to router %(router)s.') % {'router': router_id, 'port': portinfo['port_id']}) class RemoveInterfaceRouter(RouterInterfaceCommand): """Remove an internal network interface from a router.""" def call_api(self, neutron_client, router_id, body): return neutron_client.remove_interface_router(router_id, body) def success_message(self, router_id, portinfo): # portinfo is not used since it is None for router-interface-delete. return _('Removed interface from router %s.') % router_id class SetGatewayRouter(neutronV20.NeutronCommand): """Set the external network gateway for a router.""" resource = 'router' def get_parser(self, prog_name): parser = super(SetGatewayRouter, self).get_parser(prog_name) parser.add_argument( 'router', metavar='ROUTER', help=_('ID or name of the router.')) parser.add_argument( 'external_network', metavar='EXTERNAL-NETWORK', help=_('ID or name of the external network for the gateway.')) parser.add_argument( '--enable-snat', action='store_true', help=_('Enable source NAT on the router gateway.')) parser.add_argument( '--disable-snat', action='store_true', help=_('Disable source NAT on the router gateway.')) parser.add_argument( '--fixed-ip', metavar='subnet_id=SUBNET,ip_address=IP_ADDR', action='append', type=utils.str2dict_type(optional_keys=['subnet_id', 'ip_address']), help=_('Desired IP and/or subnet on external network: ' 'subnet_id=,ip_address=. ' 'You can specify both of subnet_id and ip_address or ' 'specify one of them as well. ' 'You can repeat this option.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() _router_id = neutronV20.find_resourceid_by_name_or_id( neutron_client, self.resource, parsed_args.router) _ext_net_id = neutronV20.find_resourceid_by_name_or_id( neutron_client, 'network', parsed_args.external_network) router_dict = {'network_id': _ext_net_id} if parsed_args.enable_snat: router_dict['enable_snat'] = True if parsed_args.disable_snat: router_dict['enable_snat'] = False if parsed_args.fixed_ip: ips = [] for ip_spec in parsed_args.fixed_ip: subnet_name_id = ip_spec.get('subnet_id') if subnet_name_id: subnet_id = neutronV20.find_resourceid_by_name_or_id( neutron_client, 'subnet', subnet_name_id) ip_spec['subnet_id'] = subnet_id ips.append(ip_spec) router_dict['external_fixed_ips'] = ips neutron_client.add_gateway_router(_router_id, router_dict) print(_('Set gateway for router %s') % parsed_args.router, file=self.app.stdout) class RemoveGatewayRouter(neutronV20.NeutronCommand): """Remove an external network gateway from a router.""" resource = 'router' def get_parser(self, prog_name): parser = super(RemoveGatewayRouter, self).get_parser(prog_name) parser.add_argument( 'router', metavar='ROUTER', help=_('ID or name of the router.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() _router_id = neutronV20.find_resourceid_by_name_or_id( neutron_client, self.resource, parsed_args.router) neutron_client.remove_gateway_router(_router_id) print(_('Removed gateway from router %s') % parsed_args.router, file=self.app.stdout) python-neutronclient-6.7.0/neutronclient/neutron/v2_0/vpn/0000775000175100017510000000000013232473710023716 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/vpn/endpoint_group.py0000666000175100017510000000632613232473350027335 0ustar zuulzuul00000000000000# (c) Copyright 2015 Cisco Systems, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronv20 def add_known_endpoint_group_arguments(parser, is_create=True): parser.add_argument( '--name', help=_('Set a name for the endpoint group.')) parser.add_argument( '--description', help=_('Set a description for the endpoint group.')) if is_create: parser.add_argument( '--type', required=is_create, help=_('Type of endpoints in group (e.g. subnet, cidr, vlan).')) parser.add_argument( '--value', action='append', dest='endpoints', required=is_create, help=_('Endpoint(s) for the group. Must all be of the same type.')) class ListEndpointGroup(neutronv20.ListCommand): """List VPN endpoint groups that belong to a given tenant.""" resource = 'endpoint_group' list_columns = ['id', 'name', 'type', 'endpoints'] _formatters = {} pagination_support = True sorting_support = True class ShowEndpointGroup(neutronv20.ShowCommand): """Show a specific VPN endpoint group.""" resource = 'endpoint_group' class CreateEndpointGroup(neutronv20.CreateCommand): """Create a VPN endpoint group.""" resource = 'endpoint_group' def add_known_arguments(self, parser): add_known_endpoint_group_arguments(parser) def subnet_name2id(self, endpoint): return neutronv20.find_resourceid_by_name_or_id(self.get_client(), 'subnet', endpoint) def args2body(self, parsed_args): if parsed_args.type == 'subnet': endpoints = [self.subnet_name2id(ep) for ep in parsed_args.endpoints] else: endpoints = parsed_args.endpoints body = {'endpoints': endpoints} neutronv20.update_dict(parsed_args, body, ['name', 'description', 'tenant_id', 'type']) return {self.resource: body} class UpdateEndpointGroup(neutronv20.UpdateCommand): """Update a given VPN endpoint group.""" resource = 'endpoint_group' def add_known_arguments(self, parser): add_known_endpoint_group_arguments(parser, is_create=False) def args2body(self, parsed_args): body = {} neutronv20.update_dict(parsed_args, body, ['name', 'description']) return {self.resource: body} class DeleteEndpointGroup(neutronv20.DeleteCommand): """Delete a given VPN endpoint group.""" resource = 'endpoint_group' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/vpn/utils.py0000666000175100017510000001036613232473350025440 0ustar zuulzuul00000000000000# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # """VPN Utilities and helper functions.""" from neutronclient._i18n import _ from neutronclient.common import exceptions dpd_supported_actions = ['hold', 'clear', 'restart', 'restart-by-peer', 'disabled'] dpd_supported_keys = ['action', 'interval', 'timeout'] lifetime_keys = ['units', 'value'] lifetime_units = ['seconds'] def validate_dpd_dict(dpd_dict): for key, value in dpd_dict.items(): if key not in dpd_supported_keys: message = _( "DPD Dictionary KeyError: " "Reason-Invalid DPD key : " "'%(key)s' not in %(supported_key)s") % { 'key': key, 'supported_key': dpd_supported_keys} raise exceptions.CommandError(message) if key == 'action' and value not in dpd_supported_actions: message = _( "DPD Dictionary ValueError: " "Reason-Invalid DPD action : " "'%(key_value)s' not in %(supported_action)s") % { 'key_value': value, 'supported_action': dpd_supported_actions} raise exceptions.CommandError(message) if key in ('interval', 'timeout'): try: if int(value) <= 0: raise ValueError() except ValueError: message = _( "DPD Dictionary ValueError: " "Reason-Invalid positive integer value: " "'%(key)s' = %(value)s") % { 'key': key, 'value': value} raise exceptions.CommandError(message) else: dpd_dict[key] = int(value) return def validate_lifetime_dict(lifetime_dict): for key, value in lifetime_dict.items(): if key not in lifetime_keys: message = _( "Lifetime Dictionary KeyError: " "Reason-Invalid unit key : " "'%(key)s' not in %(supported_key)s") % { 'key': key, 'supported_key': lifetime_keys} raise exceptions.CommandError(message) if key == 'units' and value not in lifetime_units: message = _( "Lifetime Dictionary ValueError: " "Reason-Invalid units : " "'%(key_value)s' not in %(supported_units)s") % { 'key_value': key, 'supported_units': lifetime_units} raise exceptions.CommandError(message) if key == 'value': try: if int(value) < 60: raise ValueError() except ValueError: message = _( "Lifetime Dictionary ValueError: " "Reason-Invalid value should be at least 60:" "'%(key_value)s' = %(value)s") % { 'key_value': key, 'value': value} raise exceptions.CommandError(message) else: lifetime_dict['value'] = int(value) return def lifetime_help(policy): lifetime = _("%s lifetime attributes. " "'units'-seconds, default:seconds. " "'value'-non negative integer, default:3600.") % policy return lifetime def dpd_help(policy): dpd = _(" %s Dead Peer Detection attributes." " 'action'-hold,clear,disabled,restart,restart-by-peer." " 'interval' and 'timeout' are non negative integers. " " 'interval' should be less than 'timeout' value. " " 'action', default:hold 'interval', default:30, " " 'timeout', default:120.") % policy.capitalize() return dpd python-neutronclient-6.7.0/neutronclient/neutron/v2_0/vpn/ipsec_site_connection.py0000666000175100017510000002163213232473350030644 0ustar zuulzuul00000000000000# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import argparse from oslo_serialization import jsonutils from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronv20 from neutronclient.neutron.v2_0.vpn import utils as vpn_utils def _format_peer_cidrs(ipsec_site_connection): try: return '\n'.join([jsonutils.dumps(cidrs) for cidrs in ipsec_site_connection['peer_cidrs']]) except (TypeError, KeyError): return '' class ListIPsecSiteConnection(neutronv20.ListCommand): """List IPsec site connections that belong to a given tenant.""" resource = 'ipsec_site_connection' _formatters = {'peer_cidrs': _format_peer_cidrs} list_columns = [ 'id', 'name', 'peer_address', 'auth_mode', 'status'] pagination_support = True sorting_support = True class ShowIPsecSiteConnection(neutronv20.ShowCommand): """Show information of a given IPsec site connection.""" resource = 'ipsec_site_connection' help_resource = 'IPsec site connection' class IPsecSiteConnectionMixin(object): def add_known_arguments(self, parser, is_create=True): parser.add_argument( '--name', help=_('Set friendly name for the connection.')) parser.add_argument( '--description', help=_('Set a description for the connection.')) parser.add_argument( '--dpd', metavar="action=ACTION,interval=INTERVAL,timeout=TIMEOUT", type=utils.str2dict_type( optional_keys=['action', 'interval', 'timeout']), help=vpn_utils.dpd_help("IPsec connection.")) parser.add_argument( '--local-ep-group', help=_('Local endpoint group ID/name with subnet(s) for ' 'IPSec connection.')) parser.add_argument( '--peer-ep-group', help=_('Peer endpoint group ID/name with CIDR(s) for ' 'IPSec connection.')) parser.add_argument( '--peer-cidr', action='append', dest='peer_cidrs', help=_('[DEPRECATED in Mitaka] Remote subnet(s) in CIDR format. ' 'Cannot be specified when using endpoint groups. Only ' 'applicable, if subnet provided for VPN service.')) parser.add_argument( '--peer-id', required=is_create, help=_('Peer router identity for authentication. Can be ' 'IPv4/IPv6 address, e-mail address, key id, or FQDN.')) parser.add_argument( '--peer-address', required=is_create, help=_('Peer gateway public IPv4/IPv6 address or FQDN.')) parser.add_argument( '--psk', required=is_create, help=_('Pre-shared key string.')) parser.add_argument( '--mtu', default='1500' if is_create else argparse.SUPPRESS, help=_('MTU size for the connection, default:1500.')) parser.add_argument( '--initiator', default='bi-directional' if is_create else argparse.SUPPRESS, choices=['bi-directional', 'response-only'], help=_('Initiator state in lowercase, default:bi-directional')) def args2body(self, parsed_args, body=None): """Add in conditional args and then return all conn info.""" if body is None: body = {} if parsed_args.dpd: vpn_utils.validate_dpd_dict(parsed_args.dpd) body['dpd'] = parsed_args.dpd if parsed_args.local_ep_group: _local_epg = neutronv20.find_resourceid_by_name_or_id( self.get_client(), 'endpoint_group', parsed_args.local_ep_group) body['local_ep_group_id'] = _local_epg if parsed_args.peer_ep_group: _peer_epg = neutronv20.find_resourceid_by_name_or_id( self.get_client(), 'endpoint_group', parsed_args.peer_ep_group) body['peer_ep_group_id'] = _peer_epg if hasattr(parsed_args, 'mtu') and int(parsed_args.mtu) < 68: message = _("Invalid MTU value: MTU must be " "greater than or equal to 68.") raise exceptions.CommandError(message) # ToDo (Reedip) : Remove below check when peer-cidr is removed if parsed_args.peer_cidrs and parsed_args.local_ep_group: message = _("You cannot specify both endpoint groups and peer " "CIDR(s).") raise exceptions.CommandError(message) neutronv20.update_dict(parsed_args, body, ['peer_id', 'mtu', 'initiator', 'psk', 'peer_address', 'name', 'description', 'peer_cidrs']) return {self.resource: body} class CreateIPsecSiteConnection(IPsecSiteConnectionMixin, neutronv20.CreateCommand): """Create an IPsec site connection.""" resource = 'ipsec_site_connection' def add_known_arguments(self, parser): parser.add_argument( '--admin-state-down', default=True, action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--vpnservice-id', metavar='VPNSERVICE', required=True, help=_('VPN service instance ID associated with this connection.')) parser.add_argument( '--ikepolicy-id', metavar='IKEPOLICY', required=True, help=_('IKE policy ID associated with this connection.')) parser.add_argument( '--ipsecpolicy-id', metavar='IPSECPOLICY', required=True, help=_('IPsec policy ID associated with this connection.')) super(CreateIPsecSiteConnection, self).add_known_arguments(parser) def args2body(self, parsed_args): _vpnservice_id = neutronv20.find_resourceid_by_name_or_id( self.get_client(), 'vpnservice', parsed_args.vpnservice_id) _ikepolicy_id = neutronv20.find_resourceid_by_name_or_id( self.get_client(), 'ikepolicy', parsed_args.ikepolicy_id) _ipsecpolicy_id = neutronv20.find_resourceid_by_name_or_id( self.get_client(), 'ipsecpolicy', parsed_args.ipsecpolicy_id) body = { 'vpnservice_id': _vpnservice_id, 'ikepolicy_id': _ikepolicy_id, 'ipsecpolicy_id': _ipsecpolicy_id, 'admin_state_up': parsed_args.admin_state_down, } if parsed_args.tenant_id: body['tenant_id'] = parsed_args.tenant_id if (bool(parsed_args.local_ep_group) != bool(parsed_args.peer_ep_group)): message = _("You must specify both local and peer endpoint " "groups.") raise exceptions.CommandError(message) if not parsed_args.peer_cidrs and not parsed_args.local_ep_group: message = _("You must specify endpoint groups or peer CIDR(s).") raise exceptions.CommandError(message) return super(CreateIPsecSiteConnection, self).args2body(parsed_args, body) class UpdateIPsecSiteConnection(IPsecSiteConnectionMixin, neutronv20.UpdateCommand): """Update a given IPsec site connection.""" resource = 'ipsec_site_connection' help_resource = 'IPsec site connection' def add_known_arguments(self, parser): utils.add_boolean_argument( parser, '--admin-state-up', help=_('Update the administrative state. (True meaning "Up")')) super(UpdateIPsecSiteConnection, self).add_known_arguments(parser, False) def args2body(self, parsed_args): body = {} neutronv20.update_dict(parsed_args, body, ['admin_state_up']) return super(UpdateIPsecSiteConnection, self).args2body(parsed_args, body) class DeleteIPsecSiteConnection(neutronv20.DeleteCommand): """Delete a given IPsec site connection.""" resource = 'ipsec_site_connection' help_resource = 'IPsec site connection' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/vpn/vpnservice.py0000666000175100017510000000734313232473350026465 0ustar zuulzuul00000000000000# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronv20 def add_common_args(parser): parser.add_argument( '--name', help=_('Name for the VPN service.')) parser.add_argument( '--description', help=_('Description for the VPN service.')) def common_args2body(parsed_args, body): neutronv20.update_dict(parsed_args, body, ['name', 'description']) class ListVPNService(neutronv20.ListCommand): """List VPN service configurations that belong to a given tenant.""" resource = 'vpnservice' list_columns = [ 'id', 'name', 'router_id', 'status' ] _formatters = {} pagination_support = True sorting_support = True class ShowVPNService(neutronv20.ShowCommand): """Show information of a given VPN service.""" resource = 'vpnservice' help_resource = 'VPN service' class CreateVPNService(neutronv20.CreateCommand): """Create a VPN service.""" resource = 'vpnservice' def add_known_arguments(self, parser): parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( 'router', metavar='ROUTER', help=_('Router unique identifier for the VPN service.')) parser.add_argument( 'subnet', nargs='?', metavar='SUBNET', help=_('[DEPRECATED in Mitaka] Unique identifier for the local ' 'private subnet.')) add_common_args(parser) def args2body(self, parsed_args): if parsed_args.subnet: _subnet_id = neutronv20.find_resourceid_by_name_or_id( self.get_client(), 'subnet', parsed_args.subnet) else: _subnet_id = None _router_id = neutronv20.find_resourceid_by_name_or_id( self.get_client(), 'router', parsed_args.router) body = {'subnet_id': _subnet_id, 'router_id': _router_id, 'admin_state_up': parsed_args.admin_state} neutronv20.update_dict(parsed_args, body, ['tenant_id']) common_args2body(parsed_args, body) return {self.resource: body} class UpdateVPNService(neutronv20.UpdateCommand): """Update a given VPN service.""" resource = 'vpnservice' help_resource = 'VPN service' def add_known_arguments(self, parser): add_common_args(parser) utils.add_boolean_argument( parser, '--admin-state-up', help=_('Update the admin state for the VPN Service.' '(True means UP)')) def args2body(self, parsed_args): body = {} common_args2body(parsed_args, body) neutronv20.update_dict(parsed_args, body, ['admin_state_up']) return {self.resource: body} class DeleteVPNService(neutronv20.DeleteCommand): """Delete a given VPN service.""" resource = 'vpnservice' help_resource = 'VPN service' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/vpn/ipsecpolicy.py0000666000175100017510000001072613232473350026623 0ustar zuulzuul00000000000000# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import argparse from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronv20 from neutronclient.neutron.v2_0.vpn import utils as vpn_utils def add_common_args(parser, is_create=True): parser.add_argument( '--auth-algorithm', default='sha1' if is_create else argparse.SUPPRESS, type=utils.convert_to_lowercase, choices=['sha1', 'sha256', 'sha384', 'sha512'], help=_('Authentication algorithm for IPsec policy, default:sha1.')) parser.add_argument( '--description', help=_('Description of the IPsec policy.')) parser.add_argument( '--encapsulation-mode', default='tunnel' if is_create else argparse.SUPPRESS, choices=['tunnel', 'transport'], type=utils.convert_to_lowercase, help=_('Encapsulation mode for IPsec policy, default:tunnel.')) parser.add_argument( '--encryption-algorithm', default='aes-128' if is_create else argparse.SUPPRESS, type=utils.convert_to_lowercase, help=_('Encryption algorithm for IPsec policy, default:aes-128.')) parser.add_argument( '--lifetime', metavar="units=UNITS,value=VALUE", type=utils.str2dict_type(optional_keys=['units', 'value']), help=vpn_utils.lifetime_help("IPsec")) parser.add_argument( '--pfs', default='group5' if is_create else argparse.SUPPRESS, type=utils.convert_to_lowercase, help=_('Perfect Forward Secrecy for IPsec policy, default:group5.')) parser.add_argument( '--transform-protocol', default='esp' if is_create else argparse.SUPPRESS, type=utils.convert_to_lowercase, choices=['esp', 'ah', 'ah-esp'], help=_('Transform protocol for IPsec policy, default:esp.')) def parse_common_args2body(parsed_args, body): neutronv20.update_dict(parsed_args, body, ['auth_algorithm', 'encryption_algorithm', 'encapsulation_mode', 'transform_protocol', 'pfs', 'name', 'description', 'tenant_id']) if parsed_args.lifetime: vpn_utils.validate_lifetime_dict(parsed_args.lifetime) body['lifetime'] = parsed_args.lifetime return body class ListIPsecPolicy(neutronv20.ListCommand): """List IPsec policies that belong to a given tenant connection.""" resource = 'ipsecpolicy' list_columns = ['id', 'name', 'auth_algorithm', 'encryption_algorithm', 'pfs'] _formatters = {} pagination_support = True sorting_support = True class ShowIPsecPolicy(neutronv20.ShowCommand): """Show information of a given IPsec policy.""" resource = 'ipsecpolicy' help_resource = 'IPsec policy' class CreateIPsecPolicy(neutronv20.CreateCommand): """Create an IPsec policy.""" resource = 'ipsecpolicy' help_resource = 'IPsec policy' def add_known_arguments(self, parser): parser.add_argument( 'name', metavar='NAME', help=_('Name of the IPsec policy.')) add_common_args(parser) def args2body(self, parsed_args): return {'ipsecpolicy': parse_common_args2body(parsed_args, body={})} class UpdateIPsecPolicy(neutronv20.UpdateCommand): """Update a given IPsec policy.""" resource = 'ipsecpolicy' help_resource = 'IPsec policy' def add_known_arguments(self, parser): parser.add_argument( '--name', help=_('Updated name of the IPsec policy.')) add_common_args(parser, is_create=False) def args2body(self, parsed_args): return {'ipsecpolicy': parse_common_args2body(parsed_args, body={})} class DeleteIPsecPolicy(neutronv20.DeleteCommand): """Delete a given IPsec policy.""" resource = 'ipsecpolicy' help_resource = 'IPsec policy' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/vpn/ikepolicy.py0000666000175100017510000001043113232473350026261 0ustar zuulzuul00000000000000# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import argparse from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronv20 from neutronclient.neutron.v2_0.vpn import utils as vpn_utils def add_common_args(parser, is_create=True): parser.add_argument( '--description', help=_('Description of the IKE policy.')) parser.add_argument( '--auth-algorithm', type=utils.convert_to_lowercase, default='sha1' if is_create else argparse.SUPPRESS, choices=['sha1', 'sha256', 'sha384', 'sha512'], help=_('Authentication algorithm, default:sha1.')) parser.add_argument( '--encryption-algorithm', default='aes-128' if is_create else argparse.SUPPRESS, type=utils.convert_to_lowercase, help=_('Encryption algorithm, default:aes-128.')) parser.add_argument( '--phase1-negotiation-mode', default='main' if is_create else argparse.SUPPRESS, choices=['main'], type=utils.convert_to_lowercase, help=_('IKE Phase1 negotiation mode, default:main.')) parser.add_argument( '--ike-version', default='v1' if is_create else argparse.SUPPRESS, choices=['v1', 'v2'], type=utils.convert_to_lowercase, help=_('IKE version for the policy, default:v1.')) parser.add_argument( '--pfs', default='group5' if is_create else argparse.SUPPRESS, type=utils.convert_to_lowercase, help=_('Perfect Forward Secrecy, default:group5.')) parser.add_argument( '--lifetime', metavar="units=UNITS,value=VALUE", type=utils.str2dict_type(optional_keys=['units', 'value']), help=vpn_utils.lifetime_help("IKE")) def parse_common_args2body(parsed_args, body): neutronv20.update_dict(parsed_args, body, ['auth_algorithm', 'encryption_algorithm', 'phase1_negotiation_mode', 'ike_version', 'pfs', 'name', 'description', 'tenant_id']) if parsed_args.lifetime: vpn_utils.validate_lifetime_dict(parsed_args.lifetime) body['lifetime'] = parsed_args.lifetime return body class ListIKEPolicy(neutronv20.ListCommand): """List IKE policies that belong to a tenant.""" resource = 'ikepolicy' list_columns = ['id', 'name', 'auth_algorithm', 'encryption_algorithm', 'ike_version', 'pfs'] _formatters = {} pagination_support = True sorting_support = True class ShowIKEPolicy(neutronv20.ShowCommand): """Show information of a given IKE policy.""" resource = 'ikepolicy' help_resource = 'IKE policy' class CreateIKEPolicy(neutronv20.CreateCommand): """Create an IKE policy.""" resource = 'ikepolicy' def add_known_arguments(self, parser): parser.add_argument( 'name', metavar='NAME', help=_('Name of the IKE policy.')) add_common_args(parser) def args2body(self, parsed_args): return {'ikepolicy': parse_common_args2body(parsed_args, body={})} class UpdateIKEPolicy(neutronv20.UpdateCommand): """Update a given IKE policy.""" resource = 'ikepolicy' help_resource = 'IKE policy' def add_known_arguments(self, parser): parser.add_argument( '--name', help=_('Updated name of the IKE policy.')) add_common_args(parser, is_create=False) def args2body(self, parsed_args): return {'ikepolicy': parse_common_args2body(parsed_args, body={})} class DeleteIKEPolicy(neutronv20.DeleteCommand): """Delete a given IKE policy.""" resource = 'ikepolicy' help_resource = 'IKE policy' python-neutronclient-6.7.0/neutronclient/neutron/v2_0/vpn/__init__.py0000666000175100017510000000000013232473350026017 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/flavor/0000775000175100017510000000000013232473710024404 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/flavor/flavor_profile.py0000666000175100017510000000624513232473350030000 0ustar zuulzuul00000000000000# Copyright 2015 Hewlett-Packard Development Company, L.P. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import argparse from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 class ListFlavorProfile(neutronV20.ListCommand): """List Neutron service flavor profiles.""" resource = 'service_profile' list_columns = ['id', 'description', 'enabled', 'metainfo'] pagination_support = True sorting_support = True class ShowFlavorProfile(neutronV20.ShowCommand): """Show information about a given Neutron service flavor profile.""" resource = 'service_profile' class CreateFlavorProfile(neutronV20.CreateCommand): """Create a Neutron service flavor profile.""" resource = 'service_profile' def add_known_arguments(self, parser): parser.add_argument( '--description', help=_('Description for the flavor profile.')) parser.add_argument( '--driver', help=_('Python module path to driver.')) parser.add_argument( '--metainfo', help=_('Metainfo for the flavor profile.')) utils.add_boolean_argument( parser, '--enabled', default=argparse.SUPPRESS, help=_('Sets enabled flag.')) def args2body(self, parsed_args): body = {} neutronV20.update_dict(parsed_args, body, ['description', 'driver', 'enabled', 'metainfo']) return {self.resource: body} class DeleteFlavorProfile(neutronV20.DeleteCommand): """Delete a given Neutron service flavor profile.""" resource = 'service_profile' class UpdateFlavorProfile(neutronV20.UpdateCommand): """Update a given Neutron service flavor profile.""" resource = 'service_profile' def add_known_arguments(self, parser): parser.add_argument( '--description', help=_('Description for the flavor profile.')) parser.add_argument( '--driver', help=_('Python module path to driver.')) parser.add_argument( '--metainfo', help=_('Metainfo for the flavor profile.')) utils.add_boolean_argument( parser, '--enabled', default=argparse.SUPPRESS, help=_('Sets enabled flag.')) def args2body(self, parsed_args): body = {} neutronV20.update_dict(parsed_args, body, ['description', 'driver', 'enabled', 'metainfo']) return {self.resource: body} python-neutronclient-6.7.0/neutronclient/neutron/v2_0/flavor/flavor.py0000666000175100017510000001314113232473350026251 0ustar zuulzuul00000000000000# Copyright 2015 Hewlett-Packard Development Company, L.P. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from __future__ import print_function import argparse from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 class ListFlavor(neutronV20.ListCommand): """List Neutron service flavors.""" resource = 'flavor' list_columns = ['id', 'name', 'service_type', 'enabled'] pagination_support = True sorting_support = True class ShowFlavor(neutronV20.ShowCommand): """Show information about a given Neutron service flavor.""" resource = 'flavor' class CreateFlavor(neutronV20.CreateCommand): """Create a Neutron service flavor.""" resource = 'flavor' def add_known_arguments(self, parser): parser.add_argument( 'name', metavar='NAME', help=_('Name for the flavor.')) parser.add_argument( 'service_type', metavar='SERVICE_TYPE', help=_('Service type to which the flavor applies to: e.g. VPN. ' '(See service-provider-list for loaded examples.)')) parser.add_argument( '--description', help=_('Description for the flavor.')) utils.add_boolean_argument( parser, '--enabled', default=argparse.SUPPRESS, help=_('Sets enabled flag.')) def args2body(self, parsed_args): body = {} neutronV20.update_dict(parsed_args, body, ['name', 'description', 'service_type', 'enabled']) return {self.resource: body} class DeleteFlavor(neutronV20.DeleteCommand): """Delete a given Neutron service flavor.""" resource = 'flavor' class UpdateFlavor(neutronV20.UpdateCommand): """Update a Neutron service flavor.""" resource = 'flavor' def add_known_arguments(self, parser): parser.add_argument( '--name', help=_('Name for the flavor.')) parser.add_argument( '--description', help=_('Description for the flavor.')) utils.add_boolean_argument( parser, '--enabled', default=argparse.SUPPRESS, help=_('Sets enabled flag.')) def args2body(self, parsed_args): body = {} neutronV20.update_dict(parsed_args, body, ['name', 'description', 'enabled']) return {self.resource: body} class AssociateFlavor(neutronV20.NeutronCommand): """Associate a Neutron service flavor with a flavor profile.""" resource = 'flavor' def get_parser(self, prog_name): parser = super(AssociateFlavor, self).get_parser(prog_name) parser.add_argument( 'flavor', metavar='FLAVOR', help=_('ID or name of the flavor to associate.')) parser.add_argument( 'flavor_profile', metavar='FLAVOR_PROFILE', help=_('ID of the flavor profile to be associated with the ' 'flavor.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() flavor_id = neutronV20.find_resourceid_by_name_or_id( neutron_client, 'flavor', parsed_args.flavor) service_profile_id = neutronV20.find_resourceid_by_id( neutron_client, 'service_profile', parsed_args.flavor_profile) body = {'service_profile': {'id': service_profile_id}} neutron_client.associate_flavor(flavor_id, body) print((_('Associated flavor %(flavor)s with ' 'flavor_profile %(profile)s') % {'flavor': parsed_args.flavor, 'profile': parsed_args.flavor_profile}), file=self.app.stdout) class DisassociateFlavor(neutronV20.NeutronCommand): """Disassociate a Neutron service flavor from a flavor profile.""" resource = 'flavor' def get_parser(self, prog_name): parser = super(DisassociateFlavor, self).get_parser(prog_name) parser.add_argument( 'flavor', metavar='FLAVOR', help=_('ID or name of the flavor to be disassociated.')) parser.add_argument( 'flavor_profile', metavar='FLAVOR_PROFILE', help=_('ID of the flavor profile to be disassociated from the ' 'flavor.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() flavor_id = neutronV20.find_resourceid_by_name_or_id( neutron_client, 'flavor', parsed_args.flavor) service_profile_id = neutronV20.find_resourceid_by_id( neutron_client, 'service_profile', parsed_args.flavor_profile) neutron_client.disassociate_flavor(flavor_id, service_profile_id) print((_('Disassociated flavor %(flavor)s from ' 'flavor_profile %(profile)s') % {'flavor': parsed_args.flavor, 'profile': parsed_args.flavor_profile}), file=self.app.stdout) python-neutronclient-6.7.0/neutronclient/neutron/v2_0/flavor/__init__.py0000666000175100017510000000000013232473350026505 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/neutron/v2_0/rbac.py0000666000175100017510000000760713232473350024410 0ustar zuulzuul00000000000000# Copyright 2015 Huawei Technologies India Pvt Ltd. # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 # key=object_type: value={key=resource, value=cmd_resource} RBAC_OBJECTS = {'network': {'network': 'network'}, 'qos-policy': {'policy': 'qos_policy'}} def _get_cmd_resource(obj_type): resource = list(RBAC_OBJECTS[obj_type])[0] cmd_resource = RBAC_OBJECTS[obj_type][resource] return resource, cmd_resource def get_rbac_obj_params(client, obj_type, obj_id_or_name): resource, cmd_resource = _get_cmd_resource(obj_type) obj_id = neutronV20.find_resourceid_by_name_or_id( client=client, resource=resource, name_or_id=obj_id_or_name, cmd_resource=cmd_resource) return obj_id, cmd_resource class ListRBACPolicy(neutronV20.ListCommand): """List RBAC policies that belong to a given tenant.""" resource = 'rbac_policy' list_columns = ['id', 'object_type', 'object_id'] pagination_support = True sorting_support = True allow_names = False class ShowRBACPolicy(neutronV20.ShowCommand): """Show information of a given RBAC policy.""" resource = 'rbac_policy' allow_names = False class CreateRBACPolicy(neutronV20.CreateCommand): """Create a RBAC policy for a given tenant.""" resource = 'rbac_policy' def add_known_arguments(self, parser): parser.add_argument( 'name', metavar='RBAC_OBJECT', help=_('ID or name of the RBAC object.')) parser.add_argument( '--type', choices=RBAC_OBJECTS.keys(), required=True, type=utils.convert_to_lowercase, help=_('Type of the object that RBAC policy affects.')) parser.add_argument( '--target-tenant', default='*', help=_('ID of the tenant to which the RBAC ' 'policy will be enforced.')) parser.add_argument( '--action', choices=['access_as_external', 'access_as_shared'], type=utils.convert_to_lowercase, required=True, help=_('Action for the RBAC policy.')) def args2body(self, parsed_args): neutron_client = self.get_client() _object_id, _object_type = get_rbac_obj_params(neutron_client, parsed_args.type, parsed_args.name) body = { 'object_id': _object_id, 'object_type': _object_type, 'target_tenant': parsed_args.target_tenant, 'action': parsed_args.action, } return {self.resource: body} class UpdateRBACPolicy(neutronV20.UpdateCommand): """Update RBAC policy for given tenant.""" resource = 'rbac_policy' allow_names = False def add_known_arguments(self, parser): parser.add_argument( '--target-tenant', help=_('ID of the tenant to which the RBAC ' 'policy will be enforced.')) def args2body(self, parsed_args): body = {'target_tenant': parsed_args.target_tenant} return {self.resource: body} class DeleteRBACPolicy(neutronV20.DeleteCommand): """Delete a RBAC policy.""" resource = 'rbac_policy' allow_names = False python-neutronclient-6.7.0/neutronclient/neutron/v2_0/securitygroup.py0000666000175100017510000003337013232473350026421 0ustar zuulzuul00000000000000# 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 # # 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 argparse from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 def _get_remote(rule): if rule['remote_ip_prefix']: remote = '%s (CIDR)' % rule['remote_ip_prefix'] elif rule['remote_group_id']: remote = '%s (group)' % rule['remote_group_id'] else: remote = None return remote def _get_protocol_port(rule): proto = rule['protocol'] port_min = rule['port_range_min'] port_max = rule['port_range_max'] if proto in ('tcp', 'udp'): if (port_min and port_min == port_max): protocol_port = '%s/%s' % (port_min, proto) elif port_min: protocol_port = '%s-%s/%s' % (port_min, port_max, proto) else: protocol_port = proto elif proto == 'icmp': icmp_opts = [] if port_min is not None: icmp_opts.append('type:%s' % port_min) if port_max is not None: icmp_opts.append('code:%s' % port_max) if icmp_opts: protocol_port = 'icmp (%s)' % ', '.join(icmp_opts) else: protocol_port = 'icmp' elif proto is not None: # port_range_min/max are not recognized for protocol # other than TCP, UDP and ICMP. protocol_port = proto else: protocol_port = None return protocol_port def _format_sg_rule(rule): formatted = [] for field in ['direction', 'ethertype', ('protocol_port', _get_protocol_port), 'remote_ip_prefix', 'remote_group_id']: if isinstance(field, tuple): field, get_method = field data = get_method(rule) else: data = rule[field] if not data: continue if field in ('remote_ip_prefix', 'remote_group_id'): data = '%s: %s' % (field, data) formatted.append(data) return ', '.join(formatted) def _format_sg_rules(secgroup): try: return '\n'.join(sorted([_format_sg_rule(rule) for rule in secgroup['security_group_rules']])) except Exception: return '' def generate_default_ethertype(protocol): if protocol == 'icmpv6': return 'IPv6' return 'IPv4' class ListSecurityGroup(neutronV20.ListCommand): """List security groups that belong to a given tenant.""" resource = 'security_group' list_columns = ['id', 'name', 'security_group_rules'] _formatters = {'security_group_rules': _format_sg_rules} pagination_support = True sorting_support = True class ShowSecurityGroup(neutronV20.ShowCommand): """Show information of a given security group.""" resource = 'security_group' allow_names = True json_indent = 5 class CreateSecurityGroup(neutronV20.CreateCommand): """Create a security group.""" resource = 'security_group' def add_known_arguments(self, parser): parser.add_argument( 'name', metavar='NAME', help=_('Name of the security group to be created.')) parser.add_argument( '--description', help=_('Description of the security group to be created.')) def args2body(self, parsed_args): body = {'name': parsed_args.name} neutronV20.update_dict(parsed_args, body, ['description', 'tenant_id']) return {'security_group': body} class DeleteSecurityGroup(neutronV20.DeleteCommand): """Delete a given security group.""" resource = 'security_group' allow_names = True class UpdateSecurityGroup(neutronV20.UpdateCommand): """Update a given security group.""" resource = 'security_group' def add_known_arguments(self, parser): parser.add_argument( '--name', help=_('Updated name of the security group.')) parser.add_argument( '--description', help=_('Updated description of the security group.')) def args2body(self, parsed_args): body = {} neutronV20.update_dict(parsed_args, body, ['name', 'description']) return {'security_group': body} class ListSecurityGroupRule(neutronV20.ListCommand): """List security group rules that belong to a given tenant.""" resource = 'security_group_rule' list_columns = ['id', 'security_group_id', 'direction', 'ethertype', 'port/protocol', 'remote'] # replace_rules: key is an attribute name in Neutron API and # corresponding value is a display name shown by CLI. replace_rules = {'security_group_id': 'security_group', 'remote_group_id': 'remote_group'} digest_fields = { # The entry 'protocol/port' is left deliberately for backwards # compatibility. 'remote': { 'method': _get_remote, 'depends_on': ['remote_ip_prefix', 'remote_group_id']}, 'port/protocol': { 'method': _get_protocol_port, 'depends_on': ['protocol', 'port_range_min', 'port_range_max']}, 'protocol/port': { 'method': _get_protocol_port, 'depends_on': ['protocol', 'port_range_min', 'port_range_max']}} pagination_support = True sorting_support = True def get_parser(self, prog_name): parser = super(ListSecurityGroupRule, self).get_parser(prog_name) parser.add_argument( '--no-nameconv', action='store_true', help=_('Do not convert security group ID to its name.')) return parser @staticmethod def replace_columns(cols, rules, reverse=False): if reverse: rules = dict((rules[k], k) for k in rules.keys()) return [rules.get(col, col) for col in cols] def get_required_fields(self, fields): fields = self.replace_columns(fields, self.replace_rules, reverse=True) for field, digest_fields in self.digest_fields.items(): if field in fields: fields += digest_fields['depends_on'] fields.remove(field) return fields def retrieve_list(self, parsed_args): parsed_args.fields = self.get_required_fields(parsed_args.fields) return super(ListSecurityGroupRule, self).retrieve_list(parsed_args) def _get_sg_name_dict(self, data, page_size, no_nameconv): """Get names of security groups referred in the retrieved rules. :return: a dict from secgroup ID to secgroup name """ if no_nameconv: return {} neutron_client = self.get_client() search_opts = {'fields': ['id', 'name']} if self.pagination_support: if page_size: search_opts.update({'limit': page_size}) sec_group_ids = set() for rule in data: for key in self.replace_rules: if rule.get(key): sec_group_ids.add(rule[key]) sec_group_ids = list(sec_group_ids) def _get_sec_group_list(sec_group_ids): search_opts['id'] = sec_group_ids return neutron_client.list_security_groups( **search_opts).get('security_groups', []) try: secgroups = _get_sec_group_list(sec_group_ids) except exceptions.RequestURITooLong as uri_len_exc: # Length of a query filter on security group rule id # id=& (with len(uuid)=36) sec_group_id_filter_len = 40 # The URI is too long because of too many sec_group_id filters # Use the excess attribute of the exception to know how many # sec_group_id filters can be inserted into a single request sec_group_count = len(sec_group_ids) max_size = ((sec_group_id_filter_len * sec_group_count) - uri_len_exc.excess) chunk_size = max_size // sec_group_id_filter_len secgroups = [] for i in range(0, sec_group_count, chunk_size): secgroups.extend( _get_sec_group_list(sec_group_ids[i: i + chunk_size])) return dict([(sg['id'], sg['name']) for sg in secgroups if sg['name']]) @staticmethod def _has_fields(rule, required_fields): return all([key in rule for key in required_fields]) def extend_list(self, data, parsed_args): sg_dict = self._get_sg_name_dict(data, parsed_args.page_size, parsed_args.no_nameconv) for rule in data: # Replace security group UUID with its name. for key in self.replace_rules: if key in rule: rule[key] = sg_dict.get(rule[key], rule[key]) for field, digest_rule in self.digest_fields.items(): if self._has_fields(rule, digest_rule['depends_on']): rule[field] = digest_rule['method'](rule) or 'any' def setup_columns(self, info, parsed_args): # Translate the specified columns from the command line # into field names used in "info". parsed_args.columns = self.replace_columns(parsed_args.columns, self.replace_rules, reverse=True) # NOTE(amotoki): 2nd element of the tuple returned by setup_columns() # is a generator, so if you need to create a look using the generator # object, you need to recreate a generator to show a list expectedly. info = super(ListSecurityGroupRule, self).setup_columns(info, parsed_args) cols = info[0] if not parsed_args.no_nameconv: # Replace column names in the header line (in info[0]) cols = self.replace_columns(info[0], self.replace_rules) parsed_args.columns = cols return (cols, info[1]) class ShowSecurityGroupRule(neutronV20.ShowCommand): """Show information of a given security group rule.""" resource = 'security_group_rule' allow_names = False class CreateSecurityGroupRule(neutronV20.CreateCommand): """Create a security group rule.""" resource = 'security_group_rule' def add_known_arguments(self, parser): parser.add_argument( '--description', help=_('Description of security group rule.')) parser.add_argument( 'security_group_id', metavar='SECURITY_GROUP', help=_('ID or name of the security group to ' 'which the rule is added.')) parser.add_argument( '--direction', type=utils.convert_to_lowercase, default='ingress', choices=['ingress', 'egress'], help=_('Direction of traffic: ingress/egress.')) parser.add_argument( '--ethertype', help=_('IPv4/IPv6')) parser.add_argument( '--protocol', type=utils.convert_to_lowercase, help=_('Protocol of packet. Allowed values are ' '[icmp, icmpv6, tcp, udp] and ' 'integer representations [0-255].')) parser.add_argument( '--port-range-min', help=_('Starting port range. For ICMP it is type.')) parser.add_argument( '--port_range_min', help=argparse.SUPPRESS) parser.add_argument( '--port-range-max', help=_('Ending port range. For ICMP it is code.')) parser.add_argument( '--port_range_max', help=argparse.SUPPRESS) parser.add_argument( '--remote-ip-prefix', help=_('CIDR to match on.')) parser.add_argument( '--remote_ip_prefix', help=argparse.SUPPRESS) parser.add_argument( '--remote-group-id', metavar='REMOTE_GROUP', help=_('ID or name of the remote security group ' 'to which the rule is applied.')) parser.add_argument( '--remote_group_id', help=argparse.SUPPRESS) def args2body(self, parsed_args): _security_group_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'security_group', parsed_args.security_group_id) body = {'security_group_id': _security_group_id, 'direction': parsed_args.direction, 'ethertype': parsed_args.ethertype or generate_default_ethertype(parsed_args.protocol)} neutronV20.update_dict(parsed_args, body, ['protocol', 'port_range_min', 'port_range_max', 'remote_ip_prefix', 'tenant_id', 'description']) if parsed_args.remote_group_id: _remote_group_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'security_group', parsed_args.remote_group_id) body['remote_group_id'] = _remote_group_id return {'security_group_rule': body} class DeleteSecurityGroupRule(neutronV20.DeleteCommand): """Delete a given security group rule.""" resource = 'security_group_rule' allow_names = False python-neutronclient-6.7.0/neutronclient/neutron/v2_0/dns.py0000666000175100017510000000500313232473350024251 0ustar zuulzuul00000000000000# Copyright (c) 2016 IBM # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from neutronclient._i18n import _ def add_dns_argument_create(parser, resource, attribute): # Add dns_name and dns_domain support to network, port and floatingip # create argument = '--dns-%s' % attribute parser.add_argument( argument, help=_('Assign DNS %(attribute)s to the %(resource)s ' '(requires DNS integration ' 'extension)') % {'attribute': attribute, 'resource': resource}) def args2body_dns_create(parsed_args, resource, attribute): # Add dns_name and dns_domain support to network, port and floatingip # create destination = 'dns_%s' % attribute argument = getattr(parsed_args, destination) if argument: resource[destination] = argument def add_dns_argument_update(parser, resource, attribute): # Add dns_name and dns_domain support to network, port and floatingip # update argument = '--dns-%s' % attribute no_argument = '--no-dns-%s' % attribute dns_args = parser.add_mutually_exclusive_group() dns_args.add_argument( argument, help=_('Assign DNS %(attribute)s to the %(resource)s ' '(requires DNS integration ' 'extension.)') % {'attribute': attribute, 'resource': resource}) dns_args.add_argument( no_argument, action='store_true', help=_('Unassign DNS %(attribute)s from the %(resource)s ' '(requires DNS integration ' 'extension.)') % {'attribute': attribute, 'resource': resource}) def args2body_dns_update(parsed_args, resource, attribute): # Add dns_name and dns_domain support to network, port and floatingip # update destination = 'dns_%s' % attribute no_destination = 'no_dns_%s' % attribute argument = getattr(parsed_args, destination) no_argument = getattr(parsed_args, no_destination) if argument: resource[destination] = argument if no_argument: resource[destination] = "" python-neutronclient-6.7.0/neutronclient/neutron/v2_0/network_ip_availability.py0000666000175100017510000000522513232473350030406 0ustar zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from cliff import show import six from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronV20 class ListIpAvailability(neutronV20.ListCommand): """List IP usage of networks""" resource = 'network_ip_availability' resource_plural = 'network_ip_availabilities' list_columns = ['network_id', 'network_name', 'total_ips', 'used_ips'] paginations_support = True sorting_support = True filter_attrs = [ {'name': 'ip_version', 'help': _('Returns IP availability for the network subnets ' 'with a given IP version. Default: 4'), 'argparse_kwargs': {'type': int, 'choices': [4, 6], 'default': 4} }, {'name': 'network_id', 'help': _('Returns IP availability for the network ' 'matching a given network ID.')}, {'name': 'network_name', 'help': _('Returns IP availability for the network ' 'matching a given name.')}, {'name': 'tenant_id', 'help': _('Returns IP availability for the networks ' 'with a given tenant ID.')}, ] class ShowIpAvailability(neutronV20.NeutronCommand, show.ShowOne): """Show IP usage of specific network""" resource = 'network_ip_availability' def get_parser(self, prog_name): parser = super(ShowIpAvailability, self).get_parser(prog_name) parser.add_argument( 'network_id', metavar='NETWORK', help=_('ID or name of network to look up.')) return parser def take_action(self, parsed_args): self.log.debug('run(%s)', parsed_args) neutron_client = self.get_client() _id = neutronV20.find_resourceid_by_name_or_id( neutron_client, 'network', parsed_args.network_id) data = neutron_client.show_network_ip_availability(_id) self.format_output_data(data) resource = data[self.resource] if self.resource in data: return zip(*sorted(six.iteritems(resource))) else: return None python-neutronclient-6.7.0/neutronclient/neutron/v2_0/agent.py0000666000175100017510000000453513232473350024574 0ustar zuulzuul00000000000000# Copyright 2013 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 # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronV20 def _format_timestamp(component): try: return component['heartbeat_timestamp'].split(".", 2)[0] except (TypeError, KeyError): return '' class ListAgent(neutronV20.ListCommand): """List agents.""" resource = 'agent' list_columns = ['id', 'agent_type', 'host', 'availability_zone', 'alive', 'admin_state_up', 'binary'] _formatters = {'heartbeat_timestamp': _format_timestamp} sorting_support = True def extend_list(self, data, parsed_args): for agent in data: if 'alive' in agent: agent['alive'] = ":-)" if agent['alive'] else 'xxx' class ShowAgent(neutronV20.ShowCommand): """Show information of a given agent.""" resource = 'agent' allow_names = False json_indent = 5 class DeleteAgent(neutronV20.DeleteCommand): """Delete a given agent.""" resource = 'agent' allow_names = False class UpdateAgent(neutronV20.UpdateCommand): """Updates the admin status and description for a specified agent.""" resource = 'agent' allow_names = False def add_known_arguments(self, parser): parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up of the agent to false.')) parser.add_argument( '--description', help=_('Description for the agent.')) def args2body(self, parsed_args): body = {'admin_state_up': parsed_args.admin_state} neutronV20.update_dict(parsed_args, body, ['description']) return {self.resource: body} python-neutronclient-6.7.0/neutronclient/neutron/v2_0/metering.py0000666000175100017510000000774513232473350025316 0ustar zuulzuul00000000000000# Copyright (C) 2013 eNovance SAS # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from neutronclient._i18n import _ from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronv20 class ListMeteringLabel(neutronv20.ListCommand): """List metering labels that belong to a given tenant.""" resource = 'metering_label' list_columns = ['id', 'name', 'description', 'shared'] pagination_support = True sorting_support = True class ShowMeteringLabel(neutronv20.ShowCommand): """Show information of a given metering label.""" resource = 'metering_label' allow_names = True class CreateMeteringLabel(neutronv20.CreateCommand): """Create a metering label for a given tenant.""" resource = 'metering_label' def add_known_arguments(self, parser): parser.add_argument( 'name', metavar='NAME', help=_('Name of the metering label to be created.')) parser.add_argument( '--description', help=_('Description of the metering label to be created.')) parser.add_argument( '--shared', action='store_true', help=_('Set the label as shared.')) def args2body(self, parsed_args): body = {'name': parsed_args.name} neutronv20.update_dict(parsed_args, body, ['tenant_id', 'description', 'shared']) return {'metering_label': body} class DeleteMeteringLabel(neutronv20.DeleteCommand): """Delete a given metering label.""" resource = 'metering_label' allow_names = True class ListMeteringLabelRule(neutronv20.ListCommand): """List metering labels that belong to a given label.""" resource = 'metering_label_rule' list_columns = ['id', 'excluded', 'direction', 'remote_ip_prefix'] pagination_support = True sorting_support = True class ShowMeteringLabelRule(neutronv20.ShowCommand): """Show information of a given metering label rule.""" resource = 'metering_label_rule' allow_names = False class CreateMeteringLabelRule(neutronv20.CreateCommand): """Create a metering label rule for a given label.""" resource = 'metering_label_rule' def add_known_arguments(self, parser): parser.add_argument( 'label_id', metavar='LABEL', help=_('ID or name of the label.')) parser.add_argument( 'remote_ip_prefix', metavar='REMOTE_IP_PREFIX', help=_('CIDR to match on.')) parser.add_argument( '--direction', default='ingress', choices=['ingress', 'egress'], type=utils.convert_to_lowercase, help=_('Direction of traffic, default: ingress.')) parser.add_argument( '--excluded', action='store_true', help=_('Exclude this CIDR from the label, default: not excluded.')) def args2body(self, parsed_args): neutron_client = self.get_client() label_id = neutronv20.find_resourceid_by_name_or_id( neutron_client, 'metering_label', parsed_args.label_id) body = {'metering_label_id': label_id, 'remote_ip_prefix': parsed_args.remote_ip_prefix} neutronv20.update_dict(parsed_args, body, ['direction', 'excluded']) return {'metering_label_rule': body} class DeleteMeteringLabelRule(neutronv20.DeleteCommand): """Delete a given metering label.""" resource = 'metering_label_rule' allow_names = False python-neutronclient-6.7.0/neutronclient/neutron/v2_0/floatingip.py0000666000175100017510000001267413232473350025635 0ustar zuulzuul00000000000000# 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 # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from __future__ import print_function import argparse from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronV20 from neutronclient.neutron.v2_0 import dns class ListFloatingIP(neutronV20.ListCommand): """List floating IPs that belong to a given tenant.""" resource = 'floatingip' list_columns = ['id', 'fixed_ip_address', 'floating_ip_address', 'port_id'] pagination_support = True sorting_support = True class ShowFloatingIP(neutronV20.ShowCommand): """Show information of a given floating IP.""" resource = 'floatingip' allow_names = False class CreateFloatingIP(neutronV20.CreateCommand): """Create a floating IP for a given tenant.""" resource = 'floatingip' def add_known_arguments(self, parser): parser.add_argument( 'floating_network_id', metavar='FLOATING_NETWORK', help=_('ID or name of the network from which ' 'the floating IP is allocated.')) parser.add_argument( '--description', help=_('Description of the floating IP.')) parser.add_argument( '--port-id', help=_('ID of the port to be associated with the floating IP.')) parser.add_argument( '--port_id', help=argparse.SUPPRESS) parser.add_argument( '--fixed-ip-address', help=_('IP address on the port (only required if port has ' 'multiple IPs).')) parser.add_argument( '--fixed_ip_address', help=argparse.SUPPRESS) parser.add_argument( '--floating-ip-address', help=_('IP address of the floating IP')) parser.add_argument( '--subnet', dest='subnet_id', help=_('Subnet ID on which you want to create the floating IP.')) dns.add_dns_argument_create(parser, self.resource, 'domain') dns.add_dns_argument_create(parser, self.resource, 'name') def args2body(self, parsed_args): _network_id = neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'network', parsed_args.floating_network_id) body = {'floating_network_id': _network_id} neutronV20.update_dict(parsed_args, body, ['port_id', 'tenant_id', 'fixed_ip_address', 'description', 'floating_ip_address', 'subnet_id']) dns.args2body_dns_create(parsed_args, body, 'domain') dns.args2body_dns_create(parsed_args, body, 'name') return {self.resource: body} class DeleteFloatingIP(neutronV20.DeleteCommand): """Delete a given floating IP.""" resource = 'floatingip' allow_names = False class AssociateFloatingIP(neutronV20.NeutronCommand): """Create a mapping between a floating IP and a fixed IP.""" resource = 'floatingip' def get_parser(self, prog_name): parser = super(AssociateFloatingIP, self).get_parser(prog_name) parser.add_argument( 'floatingip_id', metavar='FLOATINGIP_ID', help=_('ID of the floating IP to associate.')) parser.add_argument( 'port_id', metavar='PORT', help=_('ID or name of the port to be associated with the ' 'floating IP.')) parser.add_argument( '--fixed-ip-address', help=_('IP address on the port (only required if port has ' 'multiple IPs).')) parser.add_argument( '--fixed_ip_address', help=argparse.SUPPRESS) return parser def take_action(self, parsed_args): neutron_client = self.get_client() update_dict = {} neutronV20.update_dict(parsed_args, update_dict, ['port_id', 'fixed_ip_address']) neutron_client.update_floatingip(parsed_args.floatingip_id, {'floatingip': update_dict}) print(_('Associated floating IP %s') % parsed_args.floatingip_id, file=self.app.stdout) class DisassociateFloatingIP(neutronV20.NeutronCommand): """Remove a mapping from a floating IP to a fixed IP.""" resource = 'floatingip' def get_parser(self, prog_name): parser = super(DisassociateFloatingIP, self).get_parser(prog_name) parser.add_argument( 'floatingip_id', metavar='FLOATINGIP_ID', help=_('ID of the floating IP to disassociate.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() neutron_client.update_floatingip(parsed_args.floatingip_id, {'floatingip': {'port_id': None}}) print(_('Disassociated floating IP %s') % parsed_args.floatingip_id, file=self.app.stdout) python-neutronclient-6.7.0/neutronclient/neutron/v2_0/port.py0000666000175100017510000003116613232473350024462 0ustar zuulzuul00000000000000# 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 # # 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 argparse from oslo_serialization import jsonutils from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 from neutronclient.neutron.v2_0 import dns from neutronclient.neutron.v2_0.qos import policy as qos_policy def _format_fixed_ips(port): try: return '\n'.join([jsonutils.dumps(ip) for ip in port['fixed_ips']]) except (TypeError, KeyError): return '' def _add_updatable_args(parser): parser.add_argument( '--name', help=_('Name of this port.')) parser.add_argument( '--description', help=_('Description of this port.')) parser.add_argument( '--fixed-ip', metavar='subnet_id=SUBNET,ip_address=IP_ADDR', action='append', type=utils.str2dict_type(optional_keys=['subnet_id', 'ip_address']), help=_('Desired IP and/or subnet for this port: ' 'subnet_id=,ip_address=. ' 'You can repeat this option.')) parser.add_argument( '--fixed_ip', action='append', help=argparse.SUPPRESS) parser.add_argument( '--device-id', help=_('Device ID of this port.')) parser.add_argument( '--device_id', help=argparse.SUPPRESS) parser.add_argument( '--device-owner', help=_('Device owner of this port.')) parser.add_argument( '--device_owner', help=argparse.SUPPRESS) def _updatable_args2body(parsed_args, body, client): neutronV20.update_dict(parsed_args, body, ['device_id', 'device_owner', 'name', 'description']) ips = [] if parsed_args.fixed_ip: for ip_spec in parsed_args.fixed_ip: if 'subnet_id' in ip_spec: subnet_name_id = ip_spec['subnet_id'] _subnet_id = neutronV20.find_resourceid_by_name_or_id( client, 'subnet', subnet_name_id) ip_spec['subnet_id'] = _subnet_id ips.append(ip_spec) if ips: body['fixed_ips'] = ips class ListPort(neutronV20.ListCommand): """List ports that belong to a given tenant.""" resource = 'port' _formatters = {'fixed_ips': _format_fixed_ips, } list_columns = ['id', 'name', 'mac_address', 'fixed_ips'] pagination_support = True sorting_support = True class ListRouterPort(neutronV20.ListCommand): """List ports that belong to a given tenant, with specified router.""" resource = 'port' _formatters = {'fixed_ips': _format_fixed_ips, } list_columns = ['id', 'name', 'mac_address', 'fixed_ips'] pagination_support = True sorting_support = True def get_parser(self, prog_name): parser = super(ListRouterPort, self).get_parser(prog_name) parser.add_argument( 'id', metavar='ROUTER', help=_('ID or name of the router to look up.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() _id = neutronV20.find_resourceid_by_name_or_id( neutron_client, 'router', parsed_args.id) self.values_specs.append('--device_id=%s' % _id) return super(ListRouterPort, self).take_action(parsed_args) class ShowPort(neutronV20.ShowCommand): """Show information of a given port.""" resource = 'port' class UpdatePortSecGroupMixin(object): def add_arguments_secgroup(self, parser): group_sg = parser.add_mutually_exclusive_group() group_sg.add_argument( '--security-group', metavar='SECURITY_GROUP', default=[], action='append', dest='security_groups', help=_('Security group associated with the port. You can ' 'repeat this option.')) group_sg.add_argument( '--no-security-groups', action='store_true', help=_('Associate no security groups with the port.')) def _resolv_sgid(self, secgroup): return neutronV20.find_resourceid_by_name_or_id( self.get_client(), 'security_group', secgroup) def args2body_secgroup(self, parsed_args, port): if parsed_args.security_groups: port['security_groups'] = [self._resolv_sgid(sg) for sg in parsed_args.security_groups] elif parsed_args.no_security_groups: port['security_groups'] = [] class UpdateExtraDhcpOptMixin(object): def add_arguments_extradhcpopt(self, parser): group_sg = parser.add_mutually_exclusive_group() group_sg.add_argument( '--extra-dhcp-opt', default=[], action='append', dest='extra_dhcp_opts', type=utils.str2dict_type( required_keys=['opt_name'], optional_keys=['opt_value', 'ip_version']), help=_('Extra dhcp options to be assigned to this port: ' 'opt_name=,opt_value=,' 'ip_version={4,6}. You can repeat this option.')) def args2body_extradhcpopt(self, parsed_args, port): ops = [] if parsed_args.extra_dhcp_opts: # the extra_dhcp_opt params (opt_name & opt_value) # must come in pairs, if there is a parm error # both must be thrown out. opt_ele = {} edo_err_msg = _("Invalid --extra-dhcp-opt option, can only be: " "opt_name=,opt_value=," "ip_version={4,6}. " "You can repeat this option.") for opt in parsed_args.extra_dhcp_opts: opt_ele.update(opt) if ('opt_name' in opt_ele and ('opt_value' in opt_ele or 'ip_version' in opt_ele)): if opt_ele.get('opt_value') == 'null': opt_ele['opt_value'] = None ops.append(opt_ele) opt_ele = {} else: raise exceptions.CommandError(edo_err_msg) if ops: port['extra_dhcp_opts'] = ops class UpdatePortAllowedAddressPair(object): """Update Port for allowed_address_pairs""" def add_arguments_allowedaddresspairs(self, parser): group_aap = parser.add_mutually_exclusive_group() group_aap.add_argument( '--allowed-address-pair', metavar='ip_address=IP_ADDR|CIDR[,mac_address=MAC_ADDR]', default=[], action='append', dest='allowed_address_pairs', type=utils.str2dict_type( required_keys=['ip_address'], optional_keys=['mac_address']), help=_('Allowed address pair associated with the port. ' '"ip_address" parameter is required. IP address or ' 'CIDR can be specified for "ip_address". ' '"mac_address" parameter is optional. ' 'You can repeat this option.')) group_aap.add_argument( '--no-allowed-address-pairs', action='store_true', help=_('Associate no allowed address pairs with the port.')) def args2body_allowedaddresspairs(self, parsed_args, port): if parsed_args.allowed_address_pairs: port['allowed_address_pairs'] = parsed_args.allowed_address_pairs elif parsed_args.no_allowed_address_pairs: port['allowed_address_pairs'] = [] class CreatePort(neutronV20.CreateCommand, UpdatePortSecGroupMixin, UpdateExtraDhcpOptMixin, qos_policy.CreateQosPolicyMixin, UpdatePortAllowedAddressPair): """Create a port for a given tenant.""" resource = 'port' def add_known_arguments(self, parser): _add_updatable_args(parser) parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--admin_state_down', dest='admin_state', action='store_false', help=argparse.SUPPRESS) parser.add_argument( '--mac-address', help=_('MAC address of this port.')) parser.add_argument( '--mac_address', help=argparse.SUPPRESS) parser.add_argument( '--vnic-type', metavar='', choices=['direct', 'direct-physical', 'macvtap', 'normal', 'baremetal'], type=utils.convert_to_lowercase, help=_('VNIC type for this port.')) parser.add_argument( '--vnic_type', choices=['direct', 'direct-physical', 'macvtap', 'normal', 'baremetal'], type=utils.convert_to_lowercase, help=argparse.SUPPRESS) parser.add_argument( '--binding-profile', help=_('Custom data to be passed as binding:profile.')) parser.add_argument( '--binding_profile', help=argparse.SUPPRESS) self.add_arguments_secgroup(parser) self.add_arguments_extradhcpopt(parser) self.add_arguments_qos_policy(parser) self.add_arguments_allowedaddresspairs(parser) parser.add_argument( 'network_id', metavar='NETWORK', help=_('ID or name of the network this port belongs to.')) dns.add_dns_argument_create(parser, self.resource, 'name') def args2body(self, parsed_args): client = self.get_client() _network_id = neutronV20.find_resourceid_by_name_or_id( client, 'network', parsed_args.network_id) body = {'admin_state_up': parsed_args.admin_state, 'network_id': _network_id, } _updatable_args2body(parsed_args, body, client) neutronV20.update_dict(parsed_args, body, ['mac_address', 'tenant_id']) if parsed_args.vnic_type: body['binding:vnic_type'] = parsed_args.vnic_type if parsed_args.binding_profile: body['binding:profile'] = jsonutils.loads( parsed_args.binding_profile) self.args2body_secgroup(parsed_args, body) self.args2body_extradhcpopt(parsed_args, body) self.args2body_qos_policy(parsed_args, body) self.args2body_allowedaddresspairs(parsed_args, body) dns.args2body_dns_create(parsed_args, body, 'name') return {'port': body} class DeletePort(neutronV20.DeleteCommand): """Delete a given port.""" resource = 'port' class UpdatePort(neutronV20.UpdateCommand, UpdatePortSecGroupMixin, UpdateExtraDhcpOptMixin, qos_policy.UpdateQosPolicyMixin, UpdatePortAllowedAddressPair): """Update port's information.""" resource = 'port' def add_known_arguments(self, parser): _add_updatable_args(parser) parser.add_argument( '--admin-state-up', choices=['True', 'False'], help=_('Set admin state up for the port.')) parser.add_argument( '--admin_state_up', choices=['True', 'False'], help=argparse.SUPPRESS) self.add_arguments_secgroup(parser) self.add_arguments_extradhcpopt(parser) self.add_arguments_qos_policy(parser) self.add_arguments_allowedaddresspairs(parser) dns.add_dns_argument_update(parser, self.resource, 'name') def args2body(self, parsed_args): body = {} client = self.get_client() _updatable_args2body(parsed_args, body, client) if parsed_args.admin_state_up: body['admin_state_up'] = parsed_args.admin_state_up self.args2body_secgroup(parsed_args, body) self.args2body_extradhcpopt(parsed_args, body) self.args2body_qos_policy(parsed_args, body) self.args2body_allowedaddresspairs(parsed_args, body) dns.args2body_dns_update(parsed_args, body, 'name') return {'port': body} python-neutronclient-6.7.0/neutronclient/neutron/v2_0/purge.py0000666000175100017510000001371213232473350024615 0ustar zuulzuul00000000000000# Copyright 2016 Cisco Systems # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronV20 class Purge(neutronV20.NeutronCommand): """Delete all resources that belong to a given tenant.""" def _pluralize(self, string): return string + 's' def _get_resources(self, neutron_client, resource_types, tenant_id): resources = [] for resource_type in resource_types: resources.append([]) resource_type_plural = self._pluralize(resource_type) opts = {'fields': ['id', 'tenant_id']} if resource_type_plural == 'ports': opts['fields'].append('device_id') opts['fields'].append('device_owner') function = getattr(neutron_client, 'list_%s' % resource_type_plural) if callable(function): returned_resources = function(**opts).get(resource_type_plural, []) for resource in returned_resources: if resource['tenant_id'] == tenant_id: index = resource_types.index(resource_type) resources[index].append(resource) self.total_resources += 1 return resources def _delete_resource(self, neutron_client, resource_type, resource): resource_id = resource['id'] if resource_type == 'port': router_interface_owners = ['network:router_interface', 'network:router_interface_distributed'] if resource.get('device_owner', '') in router_interface_owners: body = {'port_id': resource_id} neutron_client.remove_interface_router(resource['device_id'], body) return function = getattr(neutron_client, 'delete_%s' % resource_type) if callable(function): function(resource_id) def _purge_resources(self, neutron_client, resource_types, tenant_resources): deleted = {} failed = {} failures = False for resources in tenant_resources: index = tenant_resources.index(resources) resource_type = resource_types[index] failed[resource_type] = 0 deleted[resource_type] = 0 for resource in resources: try: self._delete_resource(neutron_client, resource_type, resource) deleted[resource_type] += 1 self.deleted_resources += 1 except Exception: failures = True failed[resource_type] += 1 self.total_resources -= 1 percent_complete = 100 if self.total_resources > 0: percent_complete = (self.deleted_resources / float(self.total_resources)) * 100 sys.stdout.write("\rPurging resources: %d%% complete." % percent_complete) sys.stdout.flush() return (deleted, failed, failures) def _build_message(self, deleted, failed, failures): msg = '' deleted_msg = [] for resource, value in deleted.items(): if value: if not msg: msg = 'Deleted' if not value == 1: resource = self._pluralize(resource) deleted_msg.append(" %d %s" % (value, resource)) if deleted_msg: msg += ','.join(deleted_msg) failed_msg = [] if failures: if msg: msg += '. ' msg += 'The following resources could not be deleted:' for resource, value in failed.items(): if value: if not value == 1: resource = self._pluralize(resource) failed_msg.append(" %d %s" % (value, resource)) msg += ','.join(failed_msg) if msg: msg += '.' else: msg = _('Tenant has no supported resources.') return msg def get_parser(self, prog_name): parser = super(Purge, self).get_parser(prog_name) parser.add_argument( 'tenant', metavar='TENANT', help=_('ID of Tenant owning the resources to be deleted.')) return parser def take_action(self, parsed_args): neutron_client = self.get_client() self.any_failures = False # A list of the types of resources supported in the order in which # they should be deleted. resource_types = ['floatingip', 'port', 'router', 'network', 'security_group'] deleted = {} failed = {} self.total_resources = 0 self.deleted_resources = 0 resources = self._get_resources(neutron_client, resource_types, parsed_args.tenant) deleted, failed, failures = self._purge_resources(neutron_client, resource_types, resources) print('\n%s' % self._build_message(deleted, failed, failures)) python-neutronclient-6.7.0/neutronclient/neutron/v2_0/network.py0000666000175100017510000002167613232473350025174 0ustar zuulzuul00000000000000# 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 # # 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 argparse from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 from neutronclient.neutron.v2_0 import availability_zone from neutronclient.neutron.v2_0 import dns from neutronclient.neutron.v2_0.qos import policy as qos_policy def _format_subnets(network): try: return '\n'.join([' '.join([s['id'], s.get('cidr', '')]) for s in network['subnets']]) except (TypeError, KeyError): return '' def args2body_common(body, parsed_args): neutronV20.update_dict(parsed_args, body, ['name', 'description']) class ListNetwork(neutronV20.ListCommand): """List networks that belong to a given tenant.""" # Length of a query filter on subnet id # id=& (with len(uuid)=36) subnet_id_filter_len = 40 resource = 'network' _formatters = {'subnets': _format_subnets, } list_columns = ['id', 'name', 'subnets'] pagination_support = True sorting_support = True filter_attrs = [ 'tenant_id', 'name', 'admin_state_up', {'name': 'status', 'help': _("Filter %s according to their operation status." "(For example: ACTIVE, ERROR etc)"), 'boolean': False, 'argparse_kwargs': {'type': utils.convert_to_uppercase}}, {'name': 'shared', 'help': _('Filter and list the networks which are shared.'), 'boolean': True}, {'name': 'router:external', 'help': _('Filter and list the networks which are external.'), 'boolean': True}, {'name': 'tags', 'help': _("Filter and list %s which has all given tags. " "Multiple tags can be set like --tags "), 'boolean': False, 'argparse_kwargs': {'metavar': 'TAG'}}, {'name': 'tags_any', 'help': _("Filter and list %s which has any given tags. " "Multiple tags can be set like --tags-any "), 'boolean': False, 'argparse_kwargs': {'metavar': 'TAG'}}, {'name': 'not_tags', 'help': _("Filter and list %s which does not have all given tags. " "Multiple tags can be set like --not-tags "), 'boolean': False, 'argparse_kwargs': {'metavar': 'TAG'}}, {'name': 'not_tags_any', 'help': _("Filter and list %s which does not have any given tags. " "Multiple tags can be set like --not-tags-any " ""), 'boolean': False, 'argparse_kwargs': {'metavar': 'TAG'}}, ] def extend_list(self, data, parsed_args): """Add subnet information to a network list.""" neutron_client = self.get_client() search_opts = {'fields': ['id', 'cidr']} if self.pagination_support: page_size = parsed_args.page_size if page_size: search_opts.update({'limit': page_size}) subnet_ids = [] for n in data: if 'subnets' in n: subnet_ids.extend(n['subnets']) def _get_subnet_list(sub_ids): search_opts['id'] = sub_ids return neutron_client.list_subnets( **search_opts).get('subnets', []) try: subnets = _get_subnet_list(subnet_ids) except exceptions.RequestURITooLong as uri_len_exc: # The URI is too long because of too many subnet_id filters # Use the excess attribute of the exception to know how many # subnet_id filters can be inserted into a single request subnet_count = len(subnet_ids) max_size = ((self.subnet_id_filter_len * subnet_count) - uri_len_exc.excess) chunk_size = max_size // self.subnet_id_filter_len subnets = [] for i in range(0, subnet_count, chunk_size): subnets.extend( _get_subnet_list(subnet_ids[i: i + chunk_size])) subnet_dict = dict([(s['id'], s) for s in subnets]) for n in data: if 'subnets' in n: n['subnets'] = [(subnet_dict.get(s) or {"id": s}) for s in n['subnets']] class ListExternalNetwork(ListNetwork): """List external networks that belong to a given tenant.""" pagination_support = True sorting_support = True def retrieve_list(self, parsed_args): external = '--router:external=True' if external not in self.values_specs: self.values_specs.append('--router:external=True') return super(ListExternalNetwork, self).retrieve_list(parsed_args) class ShowNetwork(neutronV20.ShowCommand): """Show information of a given network.""" resource = 'network' class CreateNetwork(neutronV20.CreateCommand, qos_policy.CreateQosPolicyMixin): """Create a network for a given tenant.""" resource = 'network' def add_known_arguments(self, parser): parser.add_argument( '--admin-state-down', dest='admin_state', action='store_false', help=_('Set admin state up to false.')) parser.add_argument( '--admin_state_down', dest='admin_state', action='store_false', help=argparse.SUPPRESS) parser.add_argument( '--shared', action='store_true', help=_('Set the network as shared.'), default=argparse.SUPPRESS) parser.add_argument( '--provider:network_type', metavar='', help=_('The physical mechanism by which the virtual network' ' is implemented.')) parser.add_argument( '--provider:physical_network', metavar='', help=_('Name of the physical network over which the virtual ' 'network is implemented.')) parser.add_argument( '--provider:segmentation_id', metavar='', help=_('VLAN ID for VLAN networks or tunnel-id for GRE/VXLAN ' 'networks.')) utils.add_boolean_argument( parser, '--vlan-transparent', default=argparse.SUPPRESS, help=_('Create a VLAN transparent network.')) parser.add_argument( 'name', metavar='NAME', help=_('Name of the network to be created.')) parser.add_argument( '--description', help=_('Description of network.')) self.add_arguments_qos_policy(parser) availability_zone.add_az_hint_argument(parser, self.resource) dns.add_dns_argument_create(parser, self.resource, 'domain') def args2body(self, parsed_args): body = {'admin_state_up': parsed_args.admin_state} args2body_common(body, parsed_args) neutronV20.update_dict(parsed_args, body, ['shared', 'tenant_id', 'vlan_transparent', 'provider:network_type', 'provider:physical_network', 'provider:segmentation_id', 'description']) self.args2body_qos_policy(parsed_args, body) availability_zone.args2body_az_hint(parsed_args, body) dns.args2body_dns_create(parsed_args, body, 'domain') return {'network': body} class DeleteNetwork(neutronV20.DeleteCommand): """Delete a given network.""" resource = 'network' class UpdateNetwork(neutronV20.UpdateCommand, qos_policy.UpdateQosPolicyMixin): """Update network's information.""" resource = 'network' def add_known_arguments(self, parser): parser.add_argument( '--name', help=_('Name of the network.')) parser.add_argument( '--description', help=_('Description of this network.')) self.add_arguments_qos_policy(parser) dns.add_dns_argument_update(parser, self.resource, 'domain') def args2body(self, parsed_args): body = {} args2body_common(body, parsed_args) self.args2body_qos_policy(parsed_args, body) dns.args2body_dns_update(parsed_args, body, 'domain') return {'network': body} python-neutronclient-6.7.0/neutronclient/neutron/v2_0/__init__.py0000666000175100017510000007372413232473350025243 0ustar zuulzuul00000000000000# 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 # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from __future__ import print_function import abc import argparse import functools import logging from cliff import command from cliff import lister from cliff import show from oslo_serialization import jsonutils import six from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils HYPHEN_OPTS = ['tags_any', 'not_tags', 'not_tags_any'] def find_resource_by_id(client, resource, resource_id, cmd_resource=None, parent_id=None, fields=None): return client.find_resource_by_id(resource, resource_id, cmd_resource, parent_id, fields) def find_resourceid_by_id(client, resource, resource_id, cmd_resource=None, parent_id=None): return find_resource_by_id(client, resource, resource_id, cmd_resource, parent_id, fields='id')['id'] def find_resource_by_name_or_id(client, resource, name_or_id, project_id=None, cmd_resource=None, parent_id=None, fields=None): return client.find_resource(resource, name_or_id, project_id, cmd_resource, parent_id, fields) def find_resourceid_by_name_or_id(client, resource, name_or_id, project_id=None, cmd_resource=None, parent_id=None): return find_resource_by_name_or_id(client, resource, name_or_id, project_id, cmd_resource, parent_id, fields='id')['id'] def add_show_list_common_argument(parser): parser.add_argument( '-D', '--show-details', help=_('Show detailed information.'), action='store_true', default=False, ) parser.add_argument( '--show_details', action='store_true', help=argparse.SUPPRESS) parser.add_argument( '--fields', help=argparse.SUPPRESS, action='append', default=[]) parser.add_argument( '-F', '--field', dest='fields', metavar='FIELD', help=_('Specify the field(s) to be returned by server. You can ' 'repeat this option.'), action='append', default=[]) def add_pagination_argument(parser): parser.add_argument( '-P', '--page-size', dest='page_size', metavar='SIZE', type=int, help=_("Specify retrieve unit of each request, then split one request " "to several requests."), default=None) def add_sorting_argument(parser): parser.add_argument( '--sort-key', dest='sort_key', metavar='FIELD', action='append', help=_("Sorts the list by the specified fields in the specified " "directions. You can repeat this option, but you must " "specify an equal number of sort_dir and sort_key values. " "Extra sort_dir options are ignored. Missing sort_dir options " "use the default asc value."), default=[]) parser.add_argument( '--sort-dir', dest='sort_dir', metavar='{asc,desc}', help=_("Sorts the list in the specified direction. You can repeat " "this option."), action='append', default=[], choices=['asc', 'desc']) def is_number(s): try: float(s) # for int, long and float except ValueError: try: complex(s) # for complex except ValueError: return False return True def _process_previous_argument(current_arg, _value_number, current_type_str, _list_flag, _values_specs, _clear_flag, values_specs): if current_arg is not None: if _value_number == 0 and (current_type_str or _list_flag): # This kind of argument should have value raise exceptions.CommandError( _("Invalid values_specs %s") % ' '.join(values_specs)) if _value_number > 1 or _list_flag or current_type_str == 'list': current_arg.update({'nargs': '+'}) elif _value_number == 0: if _clear_flag: # if we have action=clear, we use argument's default # value None for argument _values_specs.pop() else: # We assume non value argument as bool one current_arg.update({'action': 'store_true'}) def parse_args_to_dict(values_specs): """It is used to analyze the extra command options to command. Besides known options and arguments, our commands also support user to put more options to the end of command line. For example, list_nets -- --tag x y --key1 value1, where '-- --tag x y --key1 value1' is extra options to our list_nets. This feature can support V2.0 API's fields selection and filters. For example, to list networks which has name 'test4', we can have list_nets -- --name=test4. value spec is: --key type=int|bool|... value. Type is one of Python built-in types. By default, type is string. The key without value is a bool option. Key with two values will be a list option. """ # values_specs for example: '-- --tag x y --key1 type=int value1' # -- is a pseudo argument values_specs_copy = values_specs[:] if values_specs_copy and values_specs_copy[0] == '--': del values_specs_copy[0] # converted ArgumentParser arguments for each of the options _options = {} # the argument part for current option in _options current_arg = None # the string after remove meta info in values_specs # for example, '--tag x y --key1 value1' _values_specs = [] # record the count of values for an option # for example: for '--tag x y', it is 2, while for '--key1 value1', it is 1 _value_number = 0 # list=true _list_flag = False # action=clear _clear_flag = False # the current item in values_specs current_item = None # the str after 'type=' current_type_str = None for _item in values_specs_copy: if _item.startswith('--'): # Deal with previous argument if any _process_previous_argument( current_arg, _value_number, current_type_str, _list_flag, _values_specs, _clear_flag, values_specs) # Init variables for current argument current_item = _item _list_flag = False _clear_flag = False current_type_str = None if "=" in _item: _value_number = 1 _item = _item.split('=')[0] else: _value_number = 0 if _item in _options: raise exceptions.CommandError( _("Duplicated options %s") % ' '.join(values_specs)) else: _options.update({_item: {}}) current_arg = _options[_item] _item = current_item elif _item.startswith('type='): if current_arg is None: raise exceptions.CommandError( _("Invalid values_specs %s") % ' '.join(values_specs)) if 'type' not in current_arg: current_type_str = _item.split('=', 2)[1] current_arg.update({'type': eval(current_type_str)}) if current_type_str == 'bool': current_arg.update({'type': utils.str2bool}) elif current_type_str == 'dict': current_arg.update({'type': utils.str2dict}) continue elif _item == 'list=true': _list_flag = True continue elif _item == 'action=clear': _clear_flag = True continue if not _item.startswith('--'): # All others are value items # Make sure '--' occurs first and allow minus value if (not current_item or '=' in current_item or _item.startswith('-') and not is_number(_item)): raise exceptions.CommandError( _("Invalid values_specs %s") % ' '.join(values_specs)) _value_number += 1 if _item.startswith('---'): raise exceptions.CommandError( _("Invalid values_specs %s") % ' '.join(values_specs)) _values_specs.append(_item) # Deal with last one argument _process_previous_argument( current_arg, _value_number, current_type_str, _list_flag, _values_specs, _clear_flag, values_specs) # Populate the parser with arguments _parser = argparse.ArgumentParser(add_help=False) for opt, optspec in six.iteritems(_options): _parser.add_argument(opt, **optspec) _args = _parser.parse_args(_values_specs) result_dict = {} for opt in six.iterkeys(_options): _opt = opt.split('--', 2)[1] _opt = _opt.replace('-', '_') _value = getattr(_args, _opt) result_dict.update({_opt: _value}) return result_dict def _merge_args(qCmd, parsed_args, _extra_values, value_specs): """Merge arguments from _extra_values into parsed_args. If an argument value are provided in both and it is a list, the values in _extra_values will be merged into parsed_args. @param parsed_args: the parsed args from known options @param _extra_values: the other parsed arguments in unknown parts @param values_specs: the unparsed unknown parts """ temp_values = _extra_values.copy() for key, value in six.iteritems(temp_values): if hasattr(parsed_args, key): arg_value = getattr(parsed_args, key) if arg_value is not None and value is not None: if isinstance(arg_value, list): if value and isinstance(value, list): if (not arg_value or isinstance(arg_value[0], type(value[0]))): arg_value.extend(value) _extra_values.pop(key) def update_dict(obj, dict, attributes): """Update dict with fields from obj.attributes. :param obj: the object updated into dict :param dict: the result dictionary :param attributes: a list of attributes belonging to obj """ for attribute in attributes: if hasattr(obj, attribute) and getattr(obj, attribute) is not None: dict[attribute] = getattr(obj, attribute) # cliff.command.Command is abstract class so that metaclass of # subclass must be subclass of metaclass of all its base. # otherwise metaclass conflict exception is raised. class NeutronCommandMeta(abc.ABCMeta): def __new__(cls, name, bases, cls_dict): if 'log' not in cls_dict: cls_dict['log'] = logging.getLogger( cls_dict['__module__'] + '.' + name) return super(NeutronCommandMeta, cls).__new__(cls, name, bases, cls_dict) @six.add_metaclass(NeutronCommandMeta) class NeutronCommand(command.Command): values_specs = [] json_indent = None resource = None shadow_resource = None parent_id = None def run(self, parsed_args): self.log.debug('run(%s)', parsed_args) return super(NeutronCommand, self).run(parsed_args) @property def cmd_resource(self): if self.shadow_resource: return self.shadow_resource return self.resource def get_client(self): return self.app.client_manager.neutron def get_parser(self, prog_name): parser = super(NeutronCommand, self).get_parser(prog_name) parser.add_argument( '--request-format', help=argparse.SUPPRESS, default='json', choices=['json', ], ) parser.add_argument( '--request_format', choices=['json', ], help=argparse.SUPPRESS) return parser def cleanup_output_data(self, data): pass def format_output_data(self, data): # Modify data to make it more readable if self.resource in data: for k, v in six.iteritems(data[self.resource]): if isinstance(v, list): value = '\n'.join(jsonutils.dumps( i, indent=self.json_indent) if isinstance(i, dict) else str(i) for i in v) data[self.resource][k] = value elif isinstance(v, dict): value = jsonutils.dumps(v, indent=self.json_indent) data[self.resource][k] = value elif v is None: data[self.resource][k] = '' def add_known_arguments(self, parser): pass def set_extra_attrs(self, parsed_args): pass def args2body(self, parsed_args): return {} class CreateCommand(NeutronCommand, show.ShowOne): """Create a resource for a given tenant.""" log = None def get_parser(self, prog_name): parser = super(CreateCommand, self).get_parser(prog_name) parser.add_argument( '--tenant-id', metavar='TENANT_ID', help=_('The owner tenant ID.'), ) parser.add_argument( '--tenant_id', help=argparse.SUPPRESS) self.add_known_arguments(parser) return parser def take_action(self, parsed_args): self.set_extra_attrs(parsed_args) neutron_client = self.get_client() _extra_values = parse_args_to_dict(self.values_specs) _merge_args(self, parsed_args, _extra_values, self.values_specs) body = self.args2body(parsed_args) body[self.resource].update(_extra_values) obj_creator = getattr(neutron_client, "create_%s" % self.cmd_resource) if self.parent_id: data = obj_creator(self.parent_id, body) else: data = obj_creator(body) self.cleanup_output_data(data) if parsed_args.formatter == 'table': self.format_output_data(data) info = self.resource in data and data[self.resource] or None if info: if parsed_args.formatter == 'table': print(_('Created a new %s:') % self.resource, file=self.app.stdout) else: info = {'': ''} return zip(*sorted(six.iteritems(info))) class UpdateCommand(NeutronCommand): """Update resource's information.""" log = None allow_names = True help_resource = None def get_parser(self, prog_name): parser = super(UpdateCommand, self).get_parser(prog_name) if self.allow_names: help_str = _('ID or name of %s to update.') else: help_str = _('ID of %s to update.') if not self.help_resource: self.help_resource = self.resource parser.add_argument( 'id', metavar=self.resource.upper(), help=help_str % self.help_resource) self.add_known_arguments(parser) return parser def take_action(self, parsed_args): self.set_extra_attrs(parsed_args) neutron_client = self.get_client() _extra_values = parse_args_to_dict(self.values_specs) _merge_args(self, parsed_args, _extra_values, self.values_specs) body = self.args2body(parsed_args) if self.resource in body: body[self.resource].update(_extra_values) else: body[self.resource] = _extra_values if not body[self.resource]: raise exceptions.CommandError( _("Must specify new values to update %s") % self.cmd_resource) if self.allow_names: _id = find_resourceid_by_name_or_id( neutron_client, self.resource, parsed_args.id, cmd_resource=self.cmd_resource, parent_id=self.parent_id) else: _id = find_resourceid_by_id( neutron_client, self.resource, parsed_args.id, self.cmd_resource, self.parent_id) obj_updater = getattr(neutron_client, "update_%s" % self.cmd_resource) if self.parent_id: obj_updater(_id, self.parent_id, body) else: obj_updater(_id, body) print((_('Updated %(resource)s: %(id)s') % {'id': parsed_args.id, 'resource': self.resource}), file=self.app.stdout) return class DeleteCommand(NeutronCommand): """Delete a given resource.""" log = None allow_names = True help_resource = None bulk_delete = True def get_parser(self, prog_name): parser = super(DeleteCommand, self).get_parser(prog_name) if not self.help_resource: self.help_resource = self.resource if self.allow_names: help_str = _('ID(s) or name(s) of %s to delete.') else: help_str = _('ID(s) of %s to delete.') parser.add_argument( 'id', metavar=self.resource.upper(), nargs='+' if self.bulk_delete else 1, help=help_str % self.help_resource) self.add_known_arguments(parser) return parser def take_action(self, parsed_args): self.set_extra_attrs(parsed_args) neutron_client = self.get_client() obj_deleter = getattr(neutron_client, "delete_%s" % self.cmd_resource) if self.bulk_delete: self._bulk_delete(obj_deleter, neutron_client, parsed_args.id) else: self.delete_item(obj_deleter, neutron_client, parsed_args.id) print((_('Deleted %(resource)s: %(id)s') % {'id': parsed_args.id, 'resource': self.resource}), file=self.app.stdout) return def _bulk_delete(self, obj_deleter, neutron_client, parsed_args_ids): successful_delete = [] non_existent = [] multiple_ids = [] for item_id in parsed_args_ids: try: self.delete_item(obj_deleter, neutron_client, item_id) successful_delete.append(item_id) except exceptions.NotFound: non_existent.append(item_id) except exceptions.NeutronClientNoUniqueMatch: multiple_ids.append(item_id) if successful_delete: print((_('Deleted %(resource)s(s): %(id)s')) % {'id': ", ".join(successful_delete), 'resource': self.cmd_resource}, file=self.app.stdout) if non_existent or multiple_ids: err_msgs = [] if non_existent: err_msgs.append((_("Unable to find %(resource)s(s) with id(s) " "'%(id)s'.") % {'resource': self.cmd_resource, 'id': ", ".join(non_existent)})) if multiple_ids: err_msgs.append((_("Multiple %(resource)s(s) matches found " "for name(s) '%(id)s'. Please use an ID " "to be more specific.") % {'resource': self.cmd_resource, 'id': ", ".join(multiple_ids)})) raise exceptions.NeutronCLIError(message='\n'.join(err_msgs)) def delete_item(self, obj_deleter, neutron_client, item_id): if self.allow_names: params = {'cmd_resource': self.cmd_resource, 'parent_id': self.parent_id} _id = find_resourceid_by_name_or_id(neutron_client, self.resource, item_id, **params) else: _id = item_id if self.parent_id: obj_deleter(_id, self.parent_id) else: obj_deleter(_id) return class ListCommand(NeutronCommand, lister.Lister): """List resources that belong to a given tenant.""" log = None _formatters = {} list_columns = [] unknown_parts_flag = True pagination_support = False sorting_support = False resource_plural = None # A list to define arguments for filtering by attribute value # CLI arguments are shown in the order of this list. # Each element must be either of a string of an attribute name # or a dict of a full attribute definitions whose format is: # {'name': attribute name, (mandatory) # 'help': help message for CLI (mandatory) # 'boolean': boolean parameter or not. (Default: False) (optional) # 'argparse_kwargs': a dict of parameters passed to # argparse add_argument() # (Default: {}) (optional) # } # For more details, see ListNetworks.filter_attrs. filter_attrs = [] default_attr_defs = { 'name': { 'help': _("Filter %s according to their name."), 'boolean': False, }, 'tenant_id': { 'help': _('Filter %s belonging to the given tenant.'), 'boolean': False, }, 'admin_state_up': { 'help': _('Filter and list the %s whose administrative ' 'state is active'), 'boolean': True, }, } def get_parser(self, prog_name): parser = super(ListCommand, self).get_parser(prog_name) add_show_list_common_argument(parser) if self.pagination_support: add_pagination_argument(parser) if self.sorting_support: add_sorting_argument(parser) self.add_known_arguments(parser) self.add_filtering_arguments(parser) return parser def add_filtering_arguments(self, parser): if not self.filter_attrs: return group_parser = parser.add_argument_group('filtering arguments') collection = self.resource_plural or '%ss' % self.resource for attr in self.filter_attrs: if isinstance(attr, str): # Use detail defined in default_attr_defs attr_name = attr attr_defs = self.default_attr_defs[attr] else: attr_name = attr['name'] attr_defs = attr option_name = '--%s' % attr_name.replace('_', '-') params = attr_defs.get('argparse_kwargs', {}) try: help_msg = attr_defs['help'] % collection except TypeError: help_msg = attr_defs['help'] if attr_defs.get('boolean', False): add_arg_func = functools.partial(utils.add_boolean_argument, group_parser) else: add_arg_func = group_parser.add_argument add_arg_func(option_name, help=help_msg, **params) def args2search_opts(self, parsed_args): search_opts = {} fields = parsed_args.fields if parsed_args.fields: search_opts.update({'fields': fields}) if parsed_args.show_details: search_opts.update({'verbose': 'True'}) filter_attrs = [field if isinstance(field, str) else field['name'] for field in self.filter_attrs] for attr in filter_attrs: val = getattr(parsed_args, attr, None) if attr in HYPHEN_OPTS: attr = attr.replace('_', '-') if val: search_opts[attr] = val return search_opts def call_server(self, neutron_client, search_opts, parsed_args): resource_plural = neutron_client.get_resource_plural(self.cmd_resource) obj_lister = getattr(neutron_client, "list_%s" % resource_plural) if self.parent_id: data = obj_lister(self.parent_id, **search_opts) else: data = obj_lister(**search_opts) return data def retrieve_list(self, parsed_args): """Retrieve a list of resources from Neutron server.""" neutron_client = self.get_client() _extra_values = parse_args_to_dict(self.values_specs) _merge_args(self, parsed_args, _extra_values, self.values_specs) search_opts = self.args2search_opts(parsed_args) search_opts.update(_extra_values) if self.pagination_support: page_size = parsed_args.page_size if page_size: search_opts.update({'limit': page_size}) if self.sorting_support: keys = parsed_args.sort_key if keys: search_opts.update({'sort_key': keys}) dirs = parsed_args.sort_dir len_diff = len(keys) - len(dirs) if len_diff > 0: dirs += ['asc'] * len_diff elif len_diff < 0: dirs = dirs[:len(keys)] if dirs: search_opts.update({'sort_dir': dirs}) data = self.call_server(neutron_client, search_opts, parsed_args) collection = neutron_client.get_resource_plural(self.resource) return data.get(collection, []) def extend_list(self, data, parsed_args): """Update a retrieved list. This method provides a way to modify an original list returned from the neutron server. For example, you can add subnet cidr information to a network list. """ pass def setup_columns(self, info, parsed_args): _columns = len(info) > 0 and sorted(info[0].keys()) or [] if not _columns: # clean the parsed_args.columns so that cliff will not break parsed_args.columns = [] elif parsed_args.columns: _columns = [x for x in parsed_args.columns if x in _columns] elif self.list_columns: # if no -c(s) by user and list_columns, we use columns in # both list_columns and returned resource. # Also Keep their order the same as in list_columns _columns = self._setup_columns_with_tenant_id(self.list_columns, _columns) if parsed_args.formatter == 'table': formatters = self._formatters elif (parsed_args.formatter == 'csv' and hasattr(self, '_formatters_csv')): formatters = self._formatters_csv else: # For other formatters, we use raw value returned from neutron formatters = {} return (_columns, (utils.get_item_properties( s, _columns, formatters=formatters, ) for s in info), ) def _setup_columns_with_tenant_id(self, display_columns, avail_columns): _columns = [x for x in display_columns if x in avail_columns] if 'tenant_id' in display_columns: return _columns if 'tenant_id' not in avail_columns: return _columns if not self.is_admin_role(): return _columns try: pos_id = _columns.index('id') except ValueError: pos_id = 0 try: pos_name = _columns.index('name') except ValueError: pos_name = 0 _columns.insert(max(pos_id, pos_name) + 1, 'tenant_id') return _columns def is_admin_role(self): client = self.get_client() auth_ref = client.httpclient.get_auth_ref() if not auth_ref: return False return 'admin' in auth_ref.role_names def take_action(self, parsed_args): self.set_extra_attrs(parsed_args) data = self.retrieve_list(parsed_args) self.extend_list(data, parsed_args) return self.setup_columns(data, parsed_args) class ShowCommand(NeutronCommand, show.ShowOne): """Show information of a given resource.""" log = None allow_names = True help_resource = None def get_parser(self, prog_name): parser = super(ShowCommand, self).get_parser(prog_name) add_show_list_common_argument(parser) if self.allow_names: help_str = _('ID or name of %s to look up.') else: help_str = _('ID of %s to look up.') if not self.help_resource: self.help_resource = self.resource parser.add_argument( 'id', metavar=self.resource.upper(), help=help_str % self.help_resource) self.add_known_arguments(parser) return parser def take_action(self, parsed_args): self.set_extra_attrs(parsed_args) neutron_client = self.get_client() params = {} if parsed_args.show_details: params = {'verbose': 'True'} if parsed_args.fields: params = {'fields': parsed_args.fields} if self.allow_names: _id = find_resourceid_by_name_or_id(neutron_client, self.resource, parsed_args.id, cmd_resource=self.cmd_resource, parent_id=self.parent_id) else: _id = parsed_args.id obj_shower = getattr(neutron_client, "show_%s" % self.cmd_resource) if self.parent_id: data = obj_shower(_id, self.parent_id, **params) else: data = obj_shower(_id, **params) self.cleanup_output_data(data) if parsed_args.formatter == 'table': self.format_output_data(data) resource = data[self.resource] if self.resource in data: return zip(*sorted(six.iteritems(resource))) else: return None python-neutronclient-6.7.0/neutronclient/neutron/client.py0000666000175100017510000000432413232473350024202 0ustar zuulzuul00000000000000# 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 # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # from neutronclient.common import utils API_NAME = 'network' API_VERSIONS = { '2.0': 'neutronclient.v2_0.client.Client', '2': 'neutronclient.v2_0.client.Client', } def make_client(instance): """Returns an neutron client.""" neutron_client = utils.get_client_class( API_NAME, instance._api_version[API_NAME], API_VERSIONS, ) instance.initialize() url = instance._url url = url.rstrip("/") client = neutron_client(username=instance._username, project_name=instance._project_name, password=instance._password, region_name=instance._region_name, auth_url=instance._auth_url, endpoint_url=url, endpoint_type=instance._endpoint_type, token=instance._token, auth_strategy=instance._auth_strategy, insecure=instance._insecure, ca_cert=instance._ca_cert, retries=instance._retries, raise_errors=instance._raise_errors, session=instance._session, auth=instance._auth) return client def Client(api_version, *args, **kwargs): """Return an neutron client. @param api_version: only 2.0 is supported now """ neutron_client = utils.get_client_class( API_NAME, api_version, API_VERSIONS, ) return neutron_client(*args, **kwargs) python-neutronclient-6.7.0/neutronclient/neutron/__init__.py0000666000175100017510000000000013232473350024446 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/neutronclient/__init__.py0000666000175100017510000000000013232473350022754 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/.pylintrc0000666000175100017510000000255313232473350017636 0ustar zuulzuul00000000000000# The format of this file isn't really documented; just use --generate-rcfile [MASTER] # Add to the black list. It should be a base name, not a # path. You may set this option multiple times. ignore=test [Messages Control] # NOTE(justinsb): We might want to have a 2nd strict pylintrc in future # C0111: Don't require docstrings on every method # W0511: TODOs in code comments are fine. # W0142: *args and **kwargs are fine. # W0622: Redefining id is fine. disable=C0111,W0511,W0142,W0622 [Basic] # Variable names can be 1 to 31 characters long, with lowercase and underscores variable-rgx=[a-z_][a-z0-9_]{0,30}$ # Argument names can be 2 to 31 characters long, with lowercase and underscores argument-rgx=[a-z_][a-z0-9_]{1,30}$ # Method names should be at least 3 characters long # and be lowercased with underscores method-rgx=([a-z_][a-z0-9_]{2,50}|setUp|tearDown)$ # Module names matching quantum-* are ok (files in bin/) module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+)|(quantum-[a-z0-9_-]+))$ # Don't require docstrings on tests. no-docstring-rgx=((__.*__)|([tT]est.*)|setUp|tearDown)$ [Design] max-public-methods=100 min-public-methods=0 max-args=6 [Variables] # List of additional names supposed to be defined in builtins. Remember that # you should avoid to define new builtins when possible. # _ is used by our localization additional-builtins=_ python-neutronclient-6.7.0/CONTRIBUTING.rst0000666000175100017510000000107513232473350020430 0ustar zuulzuul00000000000000If you would like to contribute to the development of OpenStack, you must follow the steps documented at: http://docs.openstack.org/infra/manual/developers.html#development-workflow Once those steps have been completed, changes to OpenStack should be submitted for review via the Gerrit tool, following the workflow documented at: http://docs.openstack.org/infra/manual/developers.html#development-workflow Pull requests submitted through GitHub will be ignored. Bugs should be filed on Launchpad, not GitHub: https://bugs.launchpad.net/python-neutronclient python-neutronclient-6.7.0/ChangeLog0000664000175100017510000011474413232473706017554 0ustar zuulzuul00000000000000CHANGES ======= 6.7.0 ----- * Fix broken links * Define IpAddressAlreadyAllocated exception * Add commands to support BGP VPN route control new API extension * Updated from global requirements * VNI support in BGPVPN CLI * Updated from global requirements * Add VPNaaS commands for OSC plugin * Add Logging commands for OSC plugin * Add 'revision\_number' to update\_\* API * Pass headers to httpclient * Updated from global requirements * Updated from global requirements * Remove a workaround for osc-lib in FWaaS UT 6.6.0 ----- * Avoid tox\_install.sh for constraints support * Remove setting of version/release from releasenotes * Added 'tap\_enabled' parameter for Port-pair-group * Consume tempest CLIClient keystone v3 support * Add correlation type "nsh" to both PPs and PCs * Add Service Graphs networking-sfc resource * Dynamic routing CLIs OSC transition * SFC plugin: preserve chain order in set/unset commands * SFC plugin: fix dictionary parameters * SFC plugin: fix port chain set commands * SFC plugin: fix all list commands * Use generic $USER variable for functional tests * Updated from global requirements * Make func test work with keystone v3 only * Updated from global requirements * Updated from global requirements * Updated from global requirements * Define shell.COMMANDS explicitly to avoid random UT failure * Add missing correlation type "mpls" to port pair * Updated from global requirements * Update reno for stable/pike 6.5.0 ----- * Populate shell.COMMANDS dict not to break CLI extension UT * [FWaaS] Migrate 'public' attribute to 'shared' * SFC plugin: fix flow classifier list display 6.4.0 ----- * Updated from global requirements * Update the documentation link for doc migration * Replace uuid.uuid4() with uuidutils.generate\_uuid() * Updated from global requirements * Updated from global requirements * Add SFC cli for OSC plugin * doc: autogenerate neutron CLI reference * doc: autogenerate OSC plugin command reference * doc: Improve network CLI page * Use flake8-import-order plugin * Enable warning-is-error in doc build * Use entry points to define neutron CLI commands * doc: use new config options of openstackdocstheme * Updated from global requirements * remove explicit global\_request\_id handling from session client * move existing content into the new standard structure * switch to openstackdocstheme * Updated from global requirements * CLI implementation should raise CommandError * Call mock.patch.stopall in OSC unit tests * BGP unit test 'auth-type' errors * Updated from global requirements * Updated from global requirements 6.3.0 ----- * Allow global\_request\_id in Client constructor * Updated from global requirements * Updated from global requirements * Machine-readable output for JSON/YAML format * FWaaS UT: Fake rule should return value returned from API * Drop deprecated neutronclient.i18n wrapper * Updated from global requirements * Now empty tags are not added to Networks * Be explicit about the identity plugin required in unit tests * Supports adding tags for port, router, subnet, subnetpool * Add optional\_keys and required\_keys to --subport argument * Updated from global requirements * Fix using wrong status code in some tests * Updated from global requirements 6.2.0 ----- * Do not append .json to sending URL * FWaaS OSC plugin: Use python logging instead of oslo.log * Allow to specify tenant\_id in subnetpool-create * Fix label of allowed-address-pair ip\_address * Remove log translations * Convert gate\_hook to devstack-tools * Don't sort the fw\_rule order in OSC * Python 3.4 support is removed * Updated from global requirements * Handle log message interpolation by the logger * [Fix gate]Update test requirement * Change documentation about UpdateQuota class * doc: Patch acceptance policy after neutron CLI deprecation * doc: Fix warning * Add profiling support to neutronclient * Drop MANIFEST.in - it's not needed by pbr * Trivial Fix:fix typo in .pylintrc file * Updated from global requirements * Add BGP VPN OSC commands * Updated from global requirements * Update reno for stable/ocata 6.1.0 ----- * FWaaSv2 - Enable to specify 'any' for protocol * FWaaS - Adds an argument into find\_resource * Add plug-in summary for osc doc * x-openstack-request-id logged twice in logs * Set project\_id column header to Project * Modify key for 'qos-minimum-bandwidth-rule-list' reponse * Updated from global requirements * Replace 'os' to 'openstack' for all command example * Add documentation for FWaaS v2 OSC plugin commands * The testcase's name may be inapposite. It is better to use 'delete', instead of 'delele' * Add FWaaS V2 commands for OSC plugin * Updated from global requirements * Decode exception parameters to expand exception message properly * Add common utilities for OSC plugin implementation * Clarify how to do client-side development for repos in neutron governance * Disable VPNaaS functional tests in the neutronclient gate * Show team and repo badges on README * Fix a typo * Refactor of Network tests * Added --enable-snat option for router-gateway-set * [VPNaaS] Add support for sha2-384 and sha2-512 * Devref: Transition to OSC update * Deprecate neutron CLI * Remove unused object * Updated from global requirements * Updated from global requirements * Updated from global requirements * Add rbac\_policy to quota resources * Use method is\_valid\_cidr from oslo.utils * OSC plugin: catch up with osc-lib 1.0 interface change * Updated from global requirements * Fix Quota Support for HMs * Enable release notes translation * Return proper error code for CLI failure * Replace 'MagicMock' with 'Mock' * Handle keystoneauth exceptions in retry logic * Revert "HAProxy uses milliseconds for its timeout values." * Replace lb\_method with lb\_algorithm * Update reno for stable/newton 6.0.0 ----- * Correct DisassociatingHealthmonitor help messages * Updated from global requirements * Sync tools/tox\_install.sh * Use correct cmd\_parser * Devref: Newton mid-cycle updates for transition to OSC * Make trunk commands handle description for trunk resources * quota-update to return an error msg for 0 args * Fix the problem of "qos-bandwidth-limit-rule-show" * fix one spelling mistake * Add flavor argument to router * Add QoS egress minimum bandwidth rule to neutronclient * Make trunk commands handle timestamps for trunk resources * Provide client bindings for DELETE method of auto-allocated-topology extension * Updated from global requirements * Move advanced service functional tests to functional-adv-svcs * Drop LBaaS v1 functional tests * Clean imports in code * Remove case dependancy for user inputs * Unable to add classless-static-route in extra\_dhcp\_opt extension * Updated from global requirements * Fix prompt message for qos-bandwidth-limit-rule-create * Add possible updatable options to net-update CLI * Remove admin-state-down from lbaas-member-update * Use upper constraints for all jobs in tox.ini * Improve Help message of VPN Update CLI * Updated from global requirements * Simplify clearing session-persistence * Enable DeprecationWarning in test environments * Do not check stderr output from shell * Fix problem of RBAC command arguments * Trivial correction in variable name * Add 'shared' option to neutron address-scope-update * Update OSC transition status 5.1.0 ----- * Update docs to use Identity v3 * Add support for Bulk Delete in NeutronClient * Don't decode empty response body * Remove environment defaults * Disallow specifying name for meter-label-rule * Add Python 3.5 classifier and venv * Make find\_resourceid\_by\_id public in python binding class * Updated from global requirements * Add documentation for OSC plugin commands * Add long option to network trunk list command * Add trunk commands to openstackclient * Move find\_resource family to API binding layer * Add quota support for LB and Listeners 5.0.0 ----- * Fix string interpolation at logging call * Add client exception for HostNotCompatibleWithFixedIps * Remove discover from test-requirements * Updated from global requirements * Log request-id for each api call * Add functional test hook for fwaas command * Add support to expose default quotas for tenants * Improve help messages for NeutronClient * remove unused LOG * HAProxy uses milliseconds for its timeout values * Base OSC plugin support * Updated from global requirements * Make USER\_AGENT variable global * Modify the help of connection-limit * Trivial: missing comma in the docs * Fixed --insecure not taking effect when specified * Fix the problem of mox in test\_shell.py * Updated from global requirements * Fix the problem of "qos-dscp-marking-rule-show" * Trivial Fix: Fix typo * Add segment as an attribute to subnet in client * improve readme contents * Add no-shared option to qos-policy-update command * Updated from global requirements * Add in missing translations * Trivial: ignore openstack/common in flake8 exclude list * Update for API bindings * Remove unnecessary executable permissions * Updated from global requirements * Update tempest\_lib to tempest.lib * Constraint tox targets with upper-constraints.txt * Make purge supports dvr router's interface * Switched from fixtures.MonkeyPatch to mock.patch * tests: removed mocking for Client.get\_attr\_metadata * Update the home-page with developer documentation * Address pairs help missing space * Devref: Add dynamic routing to OSC transition * Updated from global requirements * Updated from global requirements * Support sha256 for vpn-ikepolicy and vpn-ipsecpolicy * Fixes unclear error when no --pool-prefix given * Updated from global requirements * Added missing help text for 'purge' command * Fix random failure of security group unit test * Remove the last remaining vendor code 4.2.0 ----- * Change try..except to assertRaises in UT * Update help information for lbaasv2 CLIs * Updated from global requirements * Devref: Newton updates for transition to OSC * Change --no-gateway help text * Log SHA1 hash of X-Auth-Token value * Devref Update: Transition to OpenStack Client * Fix duplicate entries in list\_columns while extending the list * Remove APIParamsCall decorator * Fix assertNotEqual parameters * organize the release notes consistently * Update reno for stable/mitaka * Add parser options for description on resources * Use raw values when non-table formatter is used * Updated from global requirements 4.1.1 ----- * Add release note of critial TypeError fix * Fix TypeError with error message * Adding DSCP marking changes to neutronclient 4.1.0 ----- * Update relnote on fix of bug 1450414 * Support dry-run option for auto-allocated-topology * fix: can't get authentication with os-token and os-url * refactor: Merge all debug logging at the beginning of take\_action * refactor: Avoid overriding run() in cliff command * Add tags support * Fixed typos in securitygroup.py * Add commands for Network IP Availability * Support cleanup of tenant resources with a single API call * Reflecting L7 content rules capability in LBaaS * LBaaS updates to reflect shared pools feature * Fixed a bunch of spacing * Misleading output when network is not found * add rbac support for qos-policies * Devref Update: Transition to OpenStack Client * Add wrapper classes for return-request-id-to-caller * BGP Dynamic Routing: neutronclient changes * Add use\_default\_subnetpool to subnet create requests * Do not print 'Created' message when using non-table formatter * Ensure to use exception per status code for all cases * Use instanceof instead of type * Add DNS integration support to the client * Improve str2dict key validation to avoid wrong keys * Updated from global requirements * Fix the exception when ID/Name not found * Fix typo in the help of net-list * Fix typos in the docstrings * Updated from global requirements * Provide argument filtering in neutron \*-list * Client bindings for Get-me-a-network * "neutron help firewall-rule-update" info updated * Show all updatable options in (fw/fw-policy)-update CLI * Allow UPPER case in protocol/action for FW Rule * Make metavar usage consistent * Update translation setup * Remove unnecessary entry from old relnotes * Fix code-block for python code in doc * Show tenant\_id in \*-list by admin * Updated from global requirements * Trivial Update on ReleaseNotes * Remove inconsistency from vpn help text * Remove argparse from requirements * Add code for load balancer status tree * Add support for default subnetpools API * Updated from global requirements * Fix typo in docstrings * refactor: Get rid of usage of get\_data in favor of take\_action * refactor: Drop meaningless 'api' attribute from NeutronCommand class * refactor: Remove usage of useless command.command.OpenStackCommand * Convert remaining use of neutronclient.i18n to \_i18n * Updated from global requirements * Remove 'u' displayed before subnetpool-list's prefixes * Add support for ip\_version on AddressScope create * Enhance the help info of "neutron router-gateway-set" 4.0.0 ----- * Adding a lowercase converter in utils.py * Updated from global requirements * Add some items to the release notes * Devref: Transition to OpenStack Client * Updated from global requirements * Use six.python\_2\_unicode\_compatible for NeutronException.\_\_str\_\_ * port: Add 'direct-physical' as a valid vnic-type * Drop unused TableFormater code * Updated from global requirements * test: fix option in port test * Support pagination listing in client extension * Add protocol value options to sg-rule-create * improve tox -e cover * Use \_i18n instead of i18n * Add method to retrieve loadbalancer stats * Support for Name field in Members and HMs * Show availability\_zone info in CLI neutron agent-list * Delete python bytecode before every test run * Updated from global requirements * Reworded nargs='?' explanation for better clarity * Drop py33 support * Fixed connection\_limit and added UT * Add help information of 'firewall-rule-create' * Allow tenant\_id positional in quota syntax * Fix H405 violations * Updated from global requirements * Deprecated tox -downloadcache option removed * Remove nuage plugin from client * Adding missing headers to the devref documents * Allow lower case protocol values * Allow passing version as '2' as well as '2.0' * Remove XML support * Add availability\_zone CLI * Updated from global requirements * Remove extra space from VPN validator exception messages * Updated from global requirements * Add CLI option guideline * Add description of extra args in CLI * Add os-client-config to CLI usage * Add more contents about CLI usage * Setup for translation * Do not include reno releasenotes in normal documentation * Add release notes for changes since 3.0.0 release * Fix a column name "protocol/port" to "port/protocol" * Remove py26 support * Reorganize documentation structure * Updated from global requirements * Trivial: Fix a typo in class ListCommand * Use sphinx-build -W in [docs] target * Updated from global requirements * Add 'baremetal' as an allowed vnic type * Add reno for release notes management * Move the old release notes to a separate file * Do not allow name lookups on RBAC policies * Add route options to neutron router-update * Revert "Revert "Remove Cisco-specific neutron client commands"" * Improve neutron-client error message output * CLI support for VPNaaS multiple local subnets * Add flavor argument to loadbalancer v2 create * Drop cliff-tablib from test-requirements.txt * Add Neutron flavor framework CLI * Create floating IP on a specific subnet ID * Documentation error in show\_bandwidth\_limit\_rule * Use os-client-config and keystoneauth1 in shell * Updated from global requirements * Adding a generate\_default\_ethertype\_function * Use clouds.yaml from devstack for functional tests * Updated from global requirements * Updated from global requirements * Updated from global requirements * Revert parent\_id and obj\_id parameter order * Updated from global requirements * Fix arg order of assertEqual and use assertTrue * Let devstack-gate handle the gate hook timeout * Ensure to decode bytes or fail * Updated from global requirements * Add allowed-address-pairs to port-update * neutron v2 command module cleanup (2) * neutron v2 command module cleanup #1 * CRUD for VPN endpoint group API * Define non\_admin\_status\_resources in each test * Fix extend\_show parameter name * Py3k compliance: check for bytes when making a string * Enable VPN test cases 3.1.0 ----- * Updated from global requirements * Change ignore-errors to ignore\_errors * Revert "Remove Cisco-specific neutron client commands" * Updated from global requirements * Remove Cisco-specific neutron client commands 3.0.0 ----- * Remove NEC plugin specific commands * Update path to subunit2html in post\_test\_hook * Updated from global requirements * Add REJECT rule on FWaaS Client * Update tls\_container\_id to tls\_container\_ref * Updated from global requirements * Support CLI changes for QoS (2/2) * Support QoS neutron-client (1/2) * Clear the extension requirement * Updated from global requirements * Make subnetpool-list show correct address scope column * Fix find\_resourceid\_by\_name call for address scopes * Add extension name to extension's command help text line * Adding registration interface for non\_admin\_status\_resources * Add document for entry point in setup.cfg * Create hooks for running functional test * Support Command line changes for Address Scope * Remove --shared option from firewall-create * Disable failing vpn tests * Support RBAC neutron-client changes * Remove newlines from request and response log * Updated from global requirements * NSX gateway extension: allow more transport type values * Updated from global requirements * Devref documentation for client command extension support * Support CLI changes for associating subnetpools and address-scopes * Remove unused AlreadyAttachedClient * Avoid overwriting parsed\_args * Determine ip version during subnet create * Call UnsetStub/VerifyAll properly for tests with exceptions * Updated from global requirements * Support for child resource extensions * Support resource plurals not ending in 's' * Updated from global requirements * Revert "Add '--router:external' option to 'net-create'" * Updated from global requirements * Updated from global requirements * Fixes indentation for bash completion script * Allow bash completion script to work with BSD sed * Add alternative login description in neutronclient docs * Updated from global requirements * Raise user-friendly exceptions in str2dict * LBaaS v2: Fix listing pool members * Fix functional tests and tox 2.0 errors 2.6.0 ----- * Updated from global requirements * Allow setting router's external ip(s) * Add missing tenant\_id to lbaas-v2 resources creation * Add InvalidIpForSubnetClient exception * Drop use of 'oslo' namespace package * Updated from global requirements * Add functional test for subnet create * Fix Python client library for Neutron * Update README to work with release tools 2.5.0 ----- * Uncap library requirements for liberty * Add --binding-profile to port-create * Fix invalid error message in neutron-cli 2.4.0 ----- * Fix one remaining E125 error and remove it from ignore list * Add basic functional tests for client library * Add Neutron subnetpool API * Revert "Remove unused AlreadyAttachedClient" * Allow passing None for subnetpool * Add Neutron subnet-create with subnetpool * Adding VLAN Transparency support to neutronclient * 'neutron port-create' missing help info for --binding:vnic-type * Support fwaasrouterinsertion extension * Prefer argparse mutual exclusion * Add HA router state to l3-agent-list-hosting-router * Make secgroup rules more readable in security-group-show * Fix E265 block comment should start with '# ' * Remove author tag * Update hacking to 0.10 * Updated from global requirements * Fix failures when calling list operations using Python binding * Updates pool session persistence options * security-group-rule-list: show all info of rules briefly * Show rules in handy format in security-group-list * Add commands from extensions to available commands * Updating lbaas cli for TLS * Copy functional tests from tempest cli * Remove unused AlreadyAttachedClient * exec permission to port\_test\_hook.sh * Reinstate Max URI length checking to V2\_0 Client * Add post\_test\_hook for functional tests * First pass at tempest-lib based functional testing * Add OS\_TEST\_PATH to testr * "neutron help router-update" help info updated * Ignore order of query parameters when compared in MyUrlComparator * Fixed pool and health monitor create bugs * Added client calls for the lbaas v2 agent scheduler * Client command extension support * Fix lbaas-loadbalancer-create with no --name * Honor allow\_names in \*-update command * Updated from global requirements * Make some auth error messages more verbose 2.3.11 ------ * Updated from global requirements * Add unit tests for agentscheduler related commands * Fix for incorrect parameter in user-id error message in shell.py * Fix CSV formatting of fixed\_ips field in port-list command * Implement LBaaS object model v2 * Fix typo in test\_cli20\_agentschedulers filename * Add ip\_version to extra dhcp opts * Skip None id when getting security\_group\_ids * Reverse order of tests to avoid incompatibility * Utility method for boolean argument * Split base function of v2\_0.Client into a separate class * Updated from global requirements * Add parser options for port-update and port-create * Add floating-ip-address to floatingip-create * Fix KeyError when filtering SG rule listing * Updated from global requirements * Remove unreachable code from test\_cli20 class * Parse provider network attributes in net\_create * Parameter support both id and name * Add '--router:external' option to 'net-create' * Fix TypeError for six.text\_type * Add Python 3 classifiers * Namespace of arguments is incorrectly used * Fix True/False to accept Camel and Lower case * Use adapter from keystoneclient * Use requests\_mock instead of mox * Updated from global requirements 2.3.10 ------ * firewall policy update for a rule is not working * subnet: allow --enable-dhcp=False/True syntax, again * Fix columns setup base on csv formatter * Correct the bash completion of CLI * Workflow documentation is now in infra-manual * Router create distributed accepts lower case * Fix issues with Unicode compatibility for Py3 * Add unit tests for agent related commands * Make help for agent-update more verbose * Use discovery fixture * Cleanup copy and pasted token * fix the firewall rule arg split error * Updated from global requirements * Change Creates to Create in help text * Disable name support for lb-healthmonitor-\* commands * Fix mixed usage of \_ * Fixes neutronclient lb-member-show command * neutron port-list -f csv outputs poorly formatted JSON strings * Updated from global requirements * Don't allow update of ipv6-ra-mode and ipv6-address-mode * Updated from global requirements * Use graduated oslo libraries * Fix E113 hacking check * Fix E129 hacking check * Updated from global requirements * Add InvalidIpForNetworkClient exception * Add missing parameters to Client's docstring * Leverage neutronclient.openstack.common.importutils import\_class * Remove extraneous vim editor configuration comments * Fix E128 hacking check * Don't get keystone session if using noauth * Bump hacking to 0.9.x series * Change "healthmonitor" to "health monitor" in help info * Correct 4xx/5xx response management in SessionClient * Change ipsecpolicies to 2 separate words: IPsec policies * handles keyboard interrupt * Use six.moves cStringIO instead of cStringIO * Updated from global requirements * Replace httpretty with requests\_mock 2.3.9 ----- 2.3.8 ----- * Fix Py3 compatibility issues * Narrow down except clause * Correct Content-Type/Accept management in HTTPClient/SessionClient * Allow to specify policy by name in firewall-update * Silence iso8601 debug messages in verbose mode * Stop using intersphinx * Updated from global requirements * Replace utils.dumps with jsonutils.dumps * Fix to ensure endpoint\_type is used by make\_client() * Add L3 HA / VRRP support to CLI * Improve help strings * Isolate tests from HTTP\_PROXY, OS\_REGION\_NAME env vars * Leverage openstack.common.jsonutils * Work toward Python 3.4 support and testing * Clean-up shell run and run\_subcommand methods 2.3.7 ----- * Updated from global requirements * Remove unnecessary get\_status\_code wrapper function * Unify doc-strings format * Small improve of str2dict function * Fix CLI support for DVR, take 2 * Refactor CreateRouter to use update\_dict * Repeat add-tenant and remove-tenant option in cli * Rename --timeout param to --http-timeout * Fix typo in cli help * neutronclient shows low-level logs in console screen * Print exception when verbose is over DEBUG\_LEVEL * Adds tty password entry for neutronclient * Remove incorrect super() call * Avoid modifying default function arguments * Fix unit tests to succeed on any PYTHONHASHSEED * Provide support for nested objects * Add keystone v3 auth support * Updated from global requirements * Fix listing security group rules * Introduce shadow resources for NeutronCommands * setup logger name of NeutronCommand automatically 2.3.6 ----- * Add option for retry number of connection attempts * Remove strict checking of encryption type * Remove "--disabled" for firewall create rule * Improve the method find\_resourceid\_by\_name\_or\_id * Add a new timeout option to set the HTTP Timeout * Python 3: compatibility of StringIO() and dict.iterkeys() * Revert "Fix CLI support for DVR" * Update theme for docs * Add a tox job for generating docs * Add MacAddressInUseClient exception handling * Create new IPv6 attributes for Subnets by client * Python 3: use six.iteritems() * Fix for CLI message of agent disassociation * Fix CLI support for DVR * Warn on tiny subnet * Some edits for help strings * Changed 'json' to 'JSON' * Add CLI Support for DVR * Add CONTRIBUTING.rst * Pass timeout parameter to requests lib call * Found a useless comment * Suppress outputs in test\_cli20\_nsx\_networkgateway * Sync with oslo * Changed 'xml' to 'XML' * Switch over to mox3 2.3.5 ----- * Improve help strings * Ensure .status\_code is defined for all NeutronClientExceptions * Silences the output in CLI for connection info * debug level logs should not be translated * Updated from global requirements * Set firewall\_rules only after appending all rules * Make neutronclient parse keystone v3 endpoints correctly * removed usage of '... can be repeated.' * added new column binary to the listing of agents * Add ability to update certain attributes in a subnet * Removed now unnecesary workaround for PyPy * Add OverQuotaClient as exception to neutronclient * Synced jsonutils from oslo-incubator * enable sorting support for agent listing * Suppress expected help messages caused by wrong CLI inputs * Updated from global requirements * Remove httplib2 requirement * Updated from global requirements * Allow user ID for authentication * Use requests module for HTTP/HTTPS * Support packet\_filter extension in NEC plugin * Python3: fix syntax issue in \_encode\_item() * Updated from global requirements * Return response status reason on error * Improvements in neutron\_test sanity tests script * Adds support for os-auth-strategy=noauth * Show the unknown auth stratey in neutron client * Rearrange neutronclient exceptions for more easy use * Suppress stdout/stderr in test\_shell * Work around pypy testing issue * Empty file shouldn't contain copyright nor license * Updated from global requirements * CLI support for NSX gateway devices * Use six.moves.urllib.parse to replace urlparse * Updated from global requirements * New exception when auth\_url is not specified * Supporting Net-Partition as extension for Nuage plugin * Print human friendly string as an error message * Python 3: fix a call to ugettext() * Enable to select specific network service type * Replace assertEqual(None, \*) with assertIsNone in tests * Adds delete of extra-dhcp-opt to the client * Unexpected response in agent-list command * Remove unused imports * Enable hacking H233 rule 2.3.4 ----- * Don't reuse 'body' for response data * Work around for httplib2 retries on timeout * Modify quota-list descripton * Extending quota support neutron LBaaS entities * Fix net-gateway-create help message * Remove vi modelines * Support building wheels (PEP-427) * Fixed get\_auth\_info() for pre-authenticated clients * Fixed a minor typo in a docstring * Add shared parameter for metering labels * Rename Nicira NVP to VMware NSX in neutronclient * session\_persistence: invalid str2dict value: u'' * update coveragerc file * Adding weight column to Neutron lb member list CLI * Combine debug and verbose commandline options * Mention --fixed-ip subnet\_id=<..> in help message * Fix description of ListSubnet 2.3.3 ----- * Make compatible with Cliff (1.5.2) * Remove an unused imported module * Remove a debugging print statement * Remove start index 0 in range() 2.3.2 ----- * Pin Sphinx to <1.2 in test-requirements * Add -U to pip install command in tox.ini * Misc typo in neutronclient * Use assertIn where appropriate * Fix neutron port-create --no-security-groups * Fix i18n messages in neutronclient * Updates .gitignore * Convert xrange to range * Ignores swap files generated during file editing * Handle IpAddressInUse with client exception * Fix lb-healthmonitor-update to work with correct object * [fwaas] Can now create disabled firewall rules * Log reason for connection failed exception * Make HACKING.rst DRYer * Fix status\_code not passed in code * Add ability to reference pool by name in lb-pool-stats command * Updated from global requirements * Fix stable/grizzly gating for Neutron (aka Quantum) * Change copyright headers from LLC to Foundation * Forcibly clear connection pool after every request * Updated from global requirements * Adds ExternalIpAddressExhaustedClient exception * Fixes the display message for the insert/remove firewall rule CLI * Adds IpAddressGenerationFailureClient exception * Update tox.ini to use new features * Update help string to match API doc 2.3.1 ----- * Client for metering extension * Update cliff version to 1.4.3 in requirements.txt * Fix cisco n1kv plugin cli option and help * Add provider attribute to lb-pool-create command * Allow 'any' option for protocol in the firewall rule 2.3.0 ----- * The "arg\_value" was not getting checked for empty list * Use assertEqual instead of assertEquals * bp:pxeboot-ports, provide pxboot on ports * Move vpn unittest code to neutronclient.tests * Add 'distributed' option to router-create command * Remove openstack.common.exception usage * Makes client always use provided endpoint\_url * Make \_test\_update\_resource honor format * Sync test-requirements with global requirements * Added support for running the tests under PyPy with tox * Fix H202 hacking check in VPN client * neutron router-gateway-set failed for non-admin users * Add multi-segment and trunk support to N1KV Neutron client * VPN as a Service (VPNaaS) Client API * Move tests back to neutronclient package * Add credentials and profile support to Neutron client * Remove status field from the list of fields of Healthmonitor * Updated from global requirements * remove useless column in list\_columns 2.2.6 ----- * Add get\_attr for EXTED\_PLURALS 2.2.5 ----- * Sync with global requirements * Improve help message of loadbalancer commands * Don't log the credentials by default * FWaaS Client and Cli * Add command for listing available service providers * Remove repeated initialisation * Add commands related to loadbalancer agent scheduling * Handle host side SSL certificates validation * raise better exception for duplicate match * let cliff install the right pyparsing * Remove commented out code * Allow tenant ID for authentication * Add --security-group option to port-update * Don't convert httplib2 exceptions to status codes * Allow user to specify None value to attributes * Renamed quantum to neutron in .gitreview 2.2.4 ----- * Rename quantumclient to neutronclient 2.2.3 ----- * python3: Introduce py33 to tox.ini * Make --version option print a more detailed client version * Fix mocking of HTTPClient.request() method * Enables H404 check (multi line docstring) in flake8 * Support router-interface-add/delete by port\_id * Allow subnet name in lb-vip-create and lb-pool-create * Remove the monkey patching of \_ into the builtins 2.2.2 ----- * update to latest pbr & remove distribute from tox * Remove class-based import in the code repo * Remove explicit distribute depend * Add metavar for --fixed-ip * Rename README to README.rst * add readme for 2.2.2 * Rename requires files to standard names * Set default columns in ext-list * Migrate to pbr * Allow the HTTPClient consumer to pass endpoint\_type * CLI support for disabling SNAT * Add update method of security group name and description * Make flake8 deps consistent with other projects * Avoid error 414 when retrieving subnet cidrs for ListNetworks * Improve unit tests for python-quantumclient * Fix a comment formatting to make pep8 test pass * Enable automatic validation of many HACKING rules * Add custom TableFormater for keep same empty list behavior as prettytable 0.6 * Change variable name of admin\_state\_down to admin\_state * Fix xml request doesn't work with unicode * Switch to flake8 from pep8 * Exclude top level 'tests dir' from packages * Add public api to get authentication info from client * Move tests to project root 2.2.1 ----- * Add AUTHOR and .testrepository to .gitignore * Update --remote-group-id metavar to REMOTE\_GROUP * Handle auth\_token and endpoint\_url if passed to the http client constructor * Don't query the agent with name * remove remainder argument Bug #1160203 * Update tools/pip-requires for prettytable * Improve unit tests for python-quantumclient * Add exception & gettextutils to openstack.common * Reordering of optional and required args in lbaas commands help * add 2.2.0 release note in index.rst file * Add a missing command line option: --insecure * Improve unit tests for python-quantumclient 2.2.0 ----- * Fix a description of floatingip-id in (dis)associate commands * Add support for security group quotas * Rename source\_(group\_id/ip\_prefix) to remote\_(group\_id/ip\_prefix) * Add pagination support for client * rename port to port\_protocol for lbaas cli * Client for agent scheduler extension 2.1.2 ----- * Update cliff dependency (1.3.1) * quantumclient.common.serializer module cleanup 2.2.0a1 ------- * CLI support for network gateway feature * Allow known options after unknown ones in list and update command * Match other python-\*client prettytable dependency * Client for agent extension * Add nvp queue support to client * Add exceptions messages for authentication 3.0.a1 ------ * Add .coveragerc * Support XML request format * Allow ability to remove security groups from ports * Stored the quantum commands list to the variable * Remove gettext.install from quantumclient.\_\_init\_\_ * Migrate from nose to testr * The change implements LBaaS CLI commands * Delete network with id in sample code using API * Remove multiple white spaces * Fix quantum client example * Exception should raise with status code * Display security group name in security-group-rule-list * Migrate from unittest to testtools * Allow known options defined after position arguments * Display subnet cidr information in net-list * Make "quantum help" to show a list of subcommands * Fix import order nits * Add file 'ChangeLog' to MANIFEST.in * Add --security-group option to port-create * bug 1091028 * Support dash-style options for security-group commands * Add --dns-nameserver, --host-route, --disable-dhcp to subnet-create * Fix a wrong substition for '-h' in bash completion * Ensures that help alignment is not hard coded * Display columns in the order of -c options * Add --router and --floatingip to quota-update options * Correct the verbose output formatting when creating routers * Convenience cmds for l3 * Fix curl command for PUT and DELETE * Fixes setup compatibility issue on Windows * Adds securitygroup implementation * Add OpenStack trove classifier for PyPI * Generate bash\_completion string so that we can use bash completion * clean the descriptions for quota cli commands 2.1 --- * fix a minor comment error * Add document for using quantum client by python or cli invocation * Support shared option in CLI * Limit list command for router and floating ip * prevent floatingip-show and floatingip-delete from querying by "name" * Send all options with CreateFloatingIP * router/floating commands support resource reference by name * update error message to make clear that we were search for a name * \*-list command shows only limited fields normally * Fix printout of dns name servers and host routes * Change '\_' to '-' in options * initial client + CLI support for routers + floating ips * Add nosehtmloutput as a test dependency * Add install\_requires in setuptools.setup() * Fix warning when creating the sdist package * Support --no-gateway option 2.0 --- * add pyparsing to pip-requires * add ext list and show commands * remove cli.app in quantum client error message * enable -h | --help after command to show the command usage * deal with -c option when the list result is empty * Add quota commands to change quota of a tenant * Refreshes keystone token if a token is expired * update mailing list, etc in setup.py * Add name or id to quantum cli commands. Bug #1030180 * Allow to retrieve objects by name * Remove quantum client codes for API v1.0 Bug #1021546 * Use -h, --help to show help messages * Support allocation pools for subnet * Make quantum cli consistent with other cli's practice 0.1.1 ----- * Add post-tag versioning 0.1.0 ----- * add --fixed-ip argument to create port * add keystone support, new command interface, API v2.0 * Add initial docs * quit and print usage when unsupported version specified * Use --debug to enable printing HTTP message(s) between client and server, besides logging verbosely * Add HACKING.rst to generated tarballs * Align tox with standards * Clean up codebase in accordance with HACKING/PEP8 * Remove server-specific functionality * bug 963155: add some missing test files to the sdist tarball * Fix quantum client exception when server returns 500 error * Open Folsom * Add retry support to the quantum client * Remove generation of quantum/vcsversion.py * add LICENSE file to sdist tarball * Adds client side functions for quantum 'detail' actions * bp/quantum-client-1.1 * Bug 921930 remove depedency on webob from python-quantumclient * bug 933125 ensure cli.py executes from the shell * Enable log output to syslog * Add "quantum" package so that \_\_init\_\_.py is included * unexecutable lib files should not contain a shebang * Additional small release needs * Initial cut at removing unneeded dependencies * Added 501 exceptions to client package * move batch\_config.py to client library * Added README * Prepare for Jenkins gating job * Split quantumclient out * Second round of packaging changes python-neutronclient-6.7.0/neutron_test.sh0000777000175100017510000001533413232473350021062 0ustar zuulzuul00000000000000#!/bin/bash set -x function die() { local exitcode=$? set +o xtrace echo $@ cleanup exit $exitcode } net_name=mynet1 subnet_name=mysubnet1 port_name=myport1 function cleanup() { echo Removing test port, subnet and net... neutron port-delete $port_name neutron subnet-delete $subnet_name neutron net-delete $net_name } noauth_tenant_id=me if [ "$1" == "noauth" ]; then NOAUTH="--tenant_id $noauth_tenant_id" else NOAUTH= fi echo "NOTE: User should be admin in order to perform all operations." sleep 3 # test the CRUD of network network=$net_name neutron net-create $NOAUTH $network || die "fail to create network $network" temp=`neutron net-list -- --name $network --fields id | wc -l` echo $temp if [ $temp -ne 5 ]; then die "networks with name $network is not unique or found" fi network_id=`neutron net-list -- --name $network --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2` echo "ID of network with name $network is $network_id" neutron net-show $network || die "fail to show network $network" neutron net-show $network_id || die "fail to show network $network_id" neutron net-update $network --admin_state_up False || die "fail to update network $network" neutron net-update $network_id --admin_state_up True || die "fail to update network $network_id" neutron net-list -c id -- --id fakeid || die "fail to list networks with column selection on empty list" # test the CRUD of subnet subnet=$subnet_name cidr=10.0.1.0/24 neutron subnet-create $NOAUTH $network $cidr --name $subnet || die "fail to create subnet $subnet" tempsubnet=`neutron subnet-list -- --name $subnet --fields id | wc -l` echo $tempsubnet if [ $tempsubnet -ne 5 ]; then die "subnets with name $subnet is not unique or found" fi subnet_id=`neutron subnet-list -- --name $subnet --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2` echo "ID of subnet with name $subnet is $subnet_id" neutron subnet-show $subnet || die "fail to show subnet $subnet" neutron subnet-show $subnet_id || die "fail to show subnet $subnet_id" neutron subnet-update $subnet --dns_nameservers list=true 1.1.1.11 1.1.1.12 || die "fail to update subnet $subnet" neutron subnet-update $subnet_id --dns_nameservers list=true 2.2.2.21 2.2.2.22 || die "fail to update subnet $subnet_id" # test the crud of ports port=$port_name neutron port-create $NOAUTH $network --name $port || die "fail to create port $port" tempport=`neutron port-list -- --name $port --fields id | wc -l` echo $tempport if [ $tempport -ne 5 ]; then die "ports with name $port is not unique or found" fi port_id=`neutron port-list -- --name $port --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2` echo "ID of port with name $port is $port_id" neutron port-show $port || die "fail to show port $port" neutron port-show $port_id || die "fail to show port $port_id" neutron port-update $port --device_id deviceid1 || die "fail to update port $port" neutron port-update $port_id --device_id deviceid2 || die "fail to update port $port_id" neutron port-update $port_id --allowed-address-pair ip_address=1.1.1.11,mac_address=10:00:00:00:00:00 --allowed-address-pair ip_address=1.1.1.12,mac_address=10:00:00:00:00:01 || die "fail to update port $port_id --allowed-address-pair" neutron port-show $port || die "fail to show port $port" neutron port-show $port_id || die "fail to show port $port_id" neutron port-update $port_id --no-allowed-address-pairs || die "fail to update port $port_id --no-allowed-address-pairs" neutron port-show $port || die "fail to show port $port" neutron port-show $port_id || die "fail to show port $port_id" neutron port-delete $port_id # test the create port with allowed-address-pairs port=$port_name neutron port-create $NOAUTH $network --name $port -- --allowed-address-pairs type=dict list=true ip_address=1.1.1.11,mac_address=10:00:00:00:00:00 ip_address=1.1.1.12,mac_address=10:00:00:00:00:01 || die "fail to create port $port" tempport=`neutron port-list -- --name $port --fields id | wc -l` echo $tempport if [ $tempport -ne 5 ]; then die "ports with name $port is not unique or found" fi port_id=`neutron port-list -- --name $port --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2` echo "ID of port with name $port is $port_id" neutron port-show $port || die "fail to show port $port" neutron port-show $port_id || die "fail to show port $port_id" neutron port-update $port_id --no-allowed-address-pairs || die "fail to update port $port_id --no-allowed-address-pairs" neutron port-show $port_id # test quota commands RUD DEFAULT_NETWORKS=10 DEFAULT_PORTS=50 tenant_id=tenant_a tenant_id_b=tenant_b neutron quota-update --tenant_id $tenant_id --network 30 || die "fail to update quota for tenant $tenant_id" neutron quota-update --tenant_id $tenant_id_b --network 20 || die "fail to update quota for tenant $tenant_id" networks=`neutron quota-list -c network -c tenant_id | grep $tenant_id | awk '{print $2}'` if [ $networks -ne 30 ]; then die "networks quota should be 30" fi networks=`neutron quota-list -c network -c tenant_id | grep $tenant_id_b | awk '{print $2}'` if [ $networks -ne 20 ]; then die "networks quota should be 20" fi networks=`neutron quota-show --tenant_id $tenant_id | grep network | awk -F'|' '{print $3}'` if [ $networks -ne 30 ]; then die "networks quota should be 30" fi neutron quota-delete --tenant_id $tenant_id || die "fail to delete quota for tenant $tenant_id" networks=`neutron quota-show --tenant_id $tenant_id | grep network | awk -F'|' '{print $3}'` if [ $networks -ne $DEFAULT_NETWORKS ]; then die "networks quota should be $DEFAULT_NETWORKS" fi # update self if [ "t$NOAUTH" = "t" ]; then # with auth neutron quota-update --port 99 || die "fail to update quota for self" ports=`neutron quota-show | grep port | awk -F'|' '{print $3}'` if [ $ports -ne 99 ]; then die "ports quota should be 99" fi ports=`neutron quota-list -c port | grep 99 | awk '{print $2}'` if [ $ports -ne 99 ]; then die "ports quota should be 99" fi neutron quota-delete || die "fail to delete quota for tenant self" ports=`neutron quota-show | grep port | awk -F'|' '{print $3}'` if [ $ports -ne $DEFAULT_PORTS ]; then die "ports quota should be $DEFAULT_PORTS" fi else # without auth neutron quota-update --port 100 if [ $? -eq 0 ]; then die "without valid context on server, quota update command should fail." fi neutron quota-show if [ $? -eq 0 ]; then die "without valid context on server, quota show command should fail." fi neutron quota-delete if [ $? -eq 0 ]; then die "without valid context on server, quota delete command should fail." fi neutron quota-list || die "fail to update quota for self" fi cleanup echo "Success! :)" python-neutronclient-6.7.0/README.rst0000666000175100017510000000277413232473350017465 0ustar zuulzuul00000000000000======================== Team and repository tags ======================== .. image:: http://governance.openstack.org/badges/python-neutronclient.svg :target: http://governance.openstack.org/reference/tags/index.html .. Change things from this point on Python bindings to the Neutron API ================================== .. image:: https://img.shields.io/pypi/v/python-neutronclient.svg :target: https://pypi.python.org/pypi/python-neutronclient/ :alt: Latest Version .. image:: https://img.shields.io/pypi/dm/python-neutronclient.svg :target: https://pypi.python.org/pypi/python-neutronclient/ :alt: Downloads This is a client library for Neutron built on the Neutron API. It provides a Python API (the ``neutronclient`` module) and a command-line tool (``neutron``). * License: Apache License, Version 2.0 * `PyPi`_ - package installation * `Online Documentation`_ * `Launchpad project`_ - release management * `Blueprints`_ - feature specifications * `Bugs`_ - issue tracking * `Source`_ * `Developer's Guide`_ .. _PyPi: https://pypi.python.org/pypi/python-neutronclient .. _Online Documentation: https://docs.openstack.org/python-neutronclient/latest/ .. _Launchpad project: https://launchpad.net/python-neutronclient .. _Blueprints: https://blueprints.launchpad.net/python-neutronclient .. _Bugs: https://bugs.launchpad.net/python-neutronclient .. _Source: https://git.openstack.org/cgit/openstack/python-neutronclient .. _Developer's Guide: http://docs.openstack.org/infra/manual/developers.html python-neutronclient-6.7.0/LICENSE0000666000175100017510000002363713232473350017004 0ustar zuulzuul00000000000000 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. python-neutronclient-6.7.0/.testr.conf0000666000175100017510000000035113232473350020051 0ustar zuulzuul00000000000000[DEFAULT] test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./neutronclient/tests/unit} $LISTOPT $IDOPTION test_id_option=--load-list $IDFILE test_list_option=--list python-neutronclient-6.7.0/tox.ini0000666000175100017510000000356213232473350017305 0ustar zuulzuul00000000000000[tox] # py3 first to avoid .testrepository incompatibility envlist = py35,py27,pypy,pep8 minversion = 1.6 skipsdist = True [testenv] setenv = VIRTUAL_ENV={envdir} LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=C PYTHONWARNINGS=default::DeprecationWarning usedevelop = True install_command = pip install {opts} {packages} deps = -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt # Delete bytecodes from normal directories before running tests. # Note that bytecodes in dot directories will not be deleted # to keep bytecodes of python modules installed into virtualenvs. commands = sh -c "find . -type d -name '.?*' -prune -o \ \( -type d -name '__pycache__' -o -type f -name '*.py[co]' \) \ -print0 | xargs -0 rm -rf" python setup.py testr --testr-args='{posargs}' whitelist_externals = sh [testenv:pep8] commands = flake8 distribute = false [testenv:venv] commands = {posargs} [testenv:functional] setenv = OS_TEST_PATH = ./neutronclient/tests/functional/core OS_NEUTRONCLIENT_EXEC_DIR = {envdir}/bin [testenv:functional-adv-svcs] setenv = OS_TEST_PATH = ./neutronclient/tests/functional/adv-svcs OS_NEUTRONCLIENT_EXEC_DIR = {envdir}/bin [testenv:cover] commands = python setup.py test --coverage --coverage-package-name=neutronclient --testr-args='{posargs}' coverage report [testenv:docs] commands = sphinx-build -W -b html doc/source doc/build/html [testenv:releasenotes] commands = sphinx-build -a -E -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html [flake8] show-source = true exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,tools import-order-style = pep8 # H904: Delay string interpolations at logging calls enable-extensions=H904 python-neutronclient-6.7.0/setup.cfg0000666000175100017510000010017213232473710017606 0ustar zuulzuul00000000000000[metadata] name = python-neutronclient summary = CLI and Client Library for OpenStack Networking description-file = README.rst author = OpenStack Networking Project author-email = openstack-dev@lists.openstack.org home-page = https://docs.openstack.org/python-neutronclient/latest/ classifier = Environment :: OpenStack Intended Audience :: Developers Intended Audience :: Information Technology Intended Audience :: System Administrators License :: OSI Approved :: Apache Software License Operating System :: POSIX :: Linux Programming Language :: Python Programming Language :: Python :: 2 Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 Programming Language :: Python :: 3.5 [files] packages = neutronclient [global] setup-hooks = pbr.hooks.setup_hook [entry_points] console_scripts = neutron = neutronclient.shell:main openstack.cli.extension = neutronclient = neutronclient.osc.plugin openstack.neutronclient.v2 = network_subport_list = neutronclient.osc.v2.trunk.network_trunk:ListNetworkSubport network_trunk_create = neutronclient.osc.v2.trunk.network_trunk:CreateNetworkTrunk network_trunk_delete = neutronclient.osc.v2.trunk.network_trunk:DeleteNetworkTrunk network_trunk_list = neutronclient.osc.v2.trunk.network_trunk:ListNetworkTrunk network_trunk_set = neutronclient.osc.v2.trunk.network_trunk:SetNetworkTrunk network_trunk_show = neutronclient.osc.v2.trunk.network_trunk:ShowNetworkTrunk network_trunk_unset = neutronclient.osc.v2.trunk.network_trunk:UnsetNetworkTrunk sfc_flow_classifier_create = neutronclient.osc.v2.sfc.sfc_flow_classifier:CreateSfcFlowClassifier sfc_flow_classifier_delete = neutronclient.osc.v2.sfc.sfc_flow_classifier:DeleteSfcFlowClassifier sfc_flow_classifier_list = neutronclient.osc.v2.sfc.sfc_flow_classifier:ListSfcFlowClassifier sfc_flow_classifier_set = neutronclient.osc.v2.sfc.sfc_flow_classifier:SetSfcFlowClassifier sfc_flow_classifier_show = neutronclient.osc.v2.sfc.sfc_flow_classifier:ShowSfcFlowClassifier sfc_port_chain_create = neutronclient.osc.v2.sfc.sfc_port_chain:CreateSfcPortChain sfc_port_chain_delete = neutronclient.osc.v2.sfc.sfc_port_chain:DeleteSfcPortChain sfc_port_chain_list = neutronclient.osc.v2.sfc.sfc_port_chain:ListSfcPortChain sfc_port_chain_set = neutronclient.osc.v2.sfc.sfc_port_chain:SetSfcPortChain sfc_port_chain_show = neutronclient.osc.v2.sfc.sfc_port_chain:ShowSfcPortChain sfc_port_chain_unset = neutronclient.osc.v2.sfc.sfc_port_chain:UnsetSfcPortChain sfc_port_pair_create = neutronclient.osc.v2.sfc.sfc_port_pair:CreateSfcPortPair sfc_port_pair_delete = neutronclient.osc.v2.sfc.sfc_port_pair:DeleteSfcPortPair sfc_port_pair_list = neutronclient.osc.v2.sfc.sfc_port_pair:ListSfcPortPair sfc_port_pair_set = neutronclient.osc.v2.sfc.sfc_port_pair:SetSfcPortPair sfc_port_pair_show = neutronclient.osc.v2.sfc.sfc_port_pair:ShowSfcPortPair sfc_port_pair_group_create = neutronclient.osc.v2.sfc.sfc_port_pair_group:CreateSfcPortPairGroup sfc_port_pair_group_delete = neutronclient.osc.v2.sfc.sfc_port_pair_group:DeleteSfcPortPairGroup sfc_port_pair_group_list = neutronclient.osc.v2.sfc.sfc_port_pair_group:ListSfcPortPairGroup sfc_port_pair_group_set = neutronclient.osc.v2.sfc.sfc_port_pair_group:SetSfcPortPairGroup sfc_port_pair_group_show = neutronclient.osc.v2.sfc.sfc_port_pair_group:ShowSfcPortPairGroup sfc_port_pair_group_unset = neutronclient.osc.v2.sfc.sfc_port_pair_group:UnsetSfcPortPairGroup sfc_service_graph_create = neutronclient.osc.v2.sfc.sfc_service_graph:CreateSfcServiceGraph sfc_service_graph_delete = neutronclient.osc.v2.sfc.sfc_service_graph:DeleteSfcServiceGraph sfc_service_graph_set = neutronclient.osc.v2.sfc.sfc_service_graph:SetSfcServiceGraph sfc_service_graph_list = neutronclient.osc.v2.sfc.sfc_service_graph:ListSfcServiceGraph sfc_service_graph_show = neutronclient.osc.v2.sfc.sfc_service_graph:ShowSfcServiceGraph bgp_dragent_add_speaker = neutronclient.osc.v2.dynamic_routing.bgp_dragent:AddBgpSpeakerToDRAgent bgp_dragent_remove_speaker = neutronclient.osc.v2.dynamic_routing.bgp_dragent:RemoveBgpSpeakerFromDRAgent bgp_peer_create = neutronclient.osc.v2.dynamic_routing.bgp_peer:CreateBgpPeer bgp_peer_delete = neutronclient.osc.v2.dynamic_routing.bgp_peer:DeleteBgpPeer bgp_peer_list = neutronclient.osc.v2.dynamic_routing.bgp_peer:ListBgpPeer bgp_peer_show = neutronclient.osc.v2.dynamic_routing.bgp_peer:ShowBgpPeer bgp_peer_set = neutronclient.osc.v2.dynamic_routing.bgp_peer:SetBgpPeer bgp_speaker_list_advertised_routes = neutronclient.osc.v2.dynamic_routing.bgp_speaker:ListRoutesAdvertisedBySpeaker bgp_speaker_create = neutronclient.osc.v2.dynamic_routing.bgp_speaker:CreateBgpSpeaker bgp_speaker_delete = neutronclient.osc.v2.dynamic_routing.bgp_speaker:DeleteBgpSpeaker bgp_speaker_list = neutronclient.osc.v2.dynamic_routing.bgp_speaker:ListBgpSpeaker bgp_speaker_add_network = neutronclient.osc.v2.dynamic_routing.bgp_speaker:AddNetworkToSpeaker bgp_speaker_remove_network = neutronclient.osc.v2.dynamic_routing.bgp_speaker:RemoveNetworkFromSpeaker bgp_speaker_add_peer = neutronclient.osc.v2.dynamic_routing.bgp_speaker:AddPeerToSpeaker bgp_speaker_remove_peer = neutronclient.osc.v2.dynamic_routing.bgp_speaker:RemovePeerFromSpeaker bgp_speaker_set = neutronclient.osc.v2.dynamic_routing.bgp_speaker:SetBgpSpeaker bgp_speaker_show = neutronclient.osc.v2.dynamic_routing.bgp_speaker:ShowBgpSpeaker bgp_speaker_show_dragents = neutronclient.osc.v2.dynamic_routing.bgp_dragent:ListDRAgentsHostingBgpSpeaker firewall_group_create = neutronclient.osc.v2.fwaas.firewallgroup:CreateFirewallGroup firewall_group_delete = neutronclient.osc.v2.fwaas.firewallgroup:DeleteFirewallGroup firewall_group_list = neutronclient.osc.v2.fwaas.firewallgroup:ListFirewallGroup firewall_group_set = neutronclient.osc.v2.fwaas.firewallgroup:SetFirewallGroup firewall_group_show = neutronclient.osc.v2.fwaas.firewallgroup:ShowFirewallGroup firewall_group_unset = neutronclient.osc.v2.fwaas.firewallgroup:UnsetFirewallGroup firewall_group_policy_create = neutronclient.osc.v2.fwaas.firewallpolicy:CreateFirewallPolicy firewall_group_policy_delete = neutronclient.osc.v2.fwaas.firewallpolicy:DeleteFirewallPolicy firewall_group_policy_add_rule = neutronclient.osc.v2.fwaas.firewallpolicy:FirewallPolicyInsertRule firewall_group_policy_list = neutronclient.osc.v2.fwaas.firewallpolicy:ListFirewallPolicy firewall_group_policy_remove_rule = neutronclient.osc.v2.fwaas.firewallpolicy:FirewallPolicyRemoveRule firewall_group_policy_set = neutronclient.osc.v2.fwaas.firewallpolicy:SetFirewallPolicy firewall_group_policy_show = neutronclient.osc.v2.fwaas.firewallpolicy:ShowFirewallPolicy firewall_group_policy_unset = neutronclient.osc.v2.fwaas.firewallpolicy:UnsetFirewallPolicy firewall_group_rule_create = neutronclient.osc.v2.fwaas.firewallrule:CreateFirewallRule firewall_group_rule_delete = neutronclient.osc.v2.fwaas.firewallrule:DeleteFirewallRule firewall_group_rule_list = neutronclient.osc.v2.fwaas.firewallrule:ListFirewallRule firewall_group_rule_set = neutronclient.osc.v2.fwaas.firewallrule:SetFirewallRule firewall_group_rule_show = neutronclient.osc.v2.fwaas.firewallrule:ShowFirewallRule firewall_group_rule_unset = neutronclient.osc.v2.fwaas.firewallrule:UnsetFirewallRule bgpvpn_create = neutronclient.osc.v2.networking_bgpvpn.bgpvpn:CreateBgpvpn bgpvpn_delete = neutronclient.osc.v2.networking_bgpvpn.bgpvpn:DeleteBgpvpn bgpvpn_list = neutronclient.osc.v2.networking_bgpvpn.bgpvpn:ListBgpvpn bgpvpn_set = neutronclient.osc.v2.networking_bgpvpn.bgpvpn:SetBgpvpn bgpvpn_show = neutronclient.osc.v2.networking_bgpvpn.bgpvpn:ShowBgpvpn bgpvpn_unset = neutronclient.osc.v2.networking_bgpvpn.bgpvpn:UnsetBgpvpn bgpvpn_network_association_create = neutronclient.osc.v2.networking_bgpvpn.network_association:CreateBgpvpnNetAssoc bgpvpn_network_association_delete = neutronclient.osc.v2.networking_bgpvpn.network_association:DeleteBgpvpnNetAssoc bgpvpn_network_association_list = neutronclient.osc.v2.networking_bgpvpn.network_association:ListBgpvpnNetAssoc bgpvpn_network_association_show = neutronclient.osc.v2.networking_bgpvpn.network_association:ShowBgpvpnNetAssoc bgpvpn_router_association_create = neutronclient.osc.v2.networking_bgpvpn.router_association:CreateBgpvpnRouterAssoc bgpvpn_router_association_delete = neutronclient.osc.v2.networking_bgpvpn.router_association:DeleteBgpvpnRouterAssoc bgpvpn_router_association_list = neutronclient.osc.v2.networking_bgpvpn.router_association:ListBgpvpnRouterAssoc bgpvpn_router_association_show = neutronclient.osc.v2.networking_bgpvpn.router_association:ShowBgpvpnRouterAssoc bgpvpn_port_association_create = neutronclient.osc.v2.networking_bgpvpn.port_association:CreateBgpvpnPortAssoc bgpvpn_port_association_set = neutronclient.osc.v2.networking_bgpvpn.port_association:SetBgpvpnPortAssoc bgpvpn_port_association_unset = neutronclient.osc.v2.networking_bgpvpn.port_association:UnsetBgpvpnPortAssoc bgpvpn_port_association_delete = neutronclient.osc.v2.networking_bgpvpn.port_association:DeleteBgpvpnPortAssoc bgpvpn_port_association_list = neutronclient.osc.v2.networking_bgpvpn.port_association:ListBgpvpnPortAssoc bgpvpn_port_association_show = neutronclient.osc.v2.networking_bgpvpn.port_association:ShowBgpvpnPortAssoc network_loggable_resources_list = neutronclient.osc.v2.logging.network_log:ListLoggableResource network_log_create = neutronclient.osc.v2.logging.network_log:CreateNetworkLog network_log_delete = neutronclient.osc.v2.logging.network_log:DeleteNetworkLog network_log_list = neutronclient.osc.v2.logging.network_log:ListNetworkLog network_log_set = neutronclient.osc.v2.logging.network_log:SetNetworkLog network_log_show = neutronclient.osc.v2.logging.network_log:ShowNetworkLog vpn_endpoint_group_create = neutronclient.osc.v2.vpnaas.endpoint_group:CreateEndpointGroup vpn_endpoint_group_delete = neutronclient.osc.v2.vpnaas.endpoint_group:DeleteEndpointGroup vpn_endpoint_group_list = neutronclient.osc.v2.vpnaas.endpoint_group:ListEndpointGroup vpn_endpoint_group_set = neutronclient.osc.v2.vpnaas.endpoint_group:SetEndpointGroup vpn_endpoint_group_show = neutronclient.osc.v2.vpnaas.endpoint_group:ShowEndpointGroup vpn_ike_policy_create = neutronclient.osc.v2.vpnaas.ikepolicy:CreateIKEPolicy vpn_ike_policy_delete = neutronclient.osc.v2.vpnaas.ikepolicy:DeleteIKEPolicy vpn_ike_policy_list = neutronclient.osc.v2.vpnaas.ikepolicy:ListIKEPolicy vpn_ike_policy_set = neutronclient.osc.v2.vpnaas.ikepolicy:SetIKEPolicy vpn_ike_policy_show = neutronclient.osc.v2.vpnaas.ikepolicy:ShowIKEPolicy vpn_ipsec_policy_create = neutronclient.osc.v2.vpnaas.ipsecpolicy:CreateIPsecPolicy vpn_ipsec_policy_delete = neutronclient.osc.v2.vpnaas.ipsecpolicy:DeleteIPsecPolicy vpn_ipsec_policy_list = neutronclient.osc.v2.vpnaas.ipsecpolicy:ListIPsecPolicy vpn_ipsec_policy_set = neutronclient.osc.v2.vpnaas.ipsecpolicy:SetIPsecPolicy vpn_ipsec_policy_show = neutronclient.osc.v2.vpnaas.ipsecpolicy:ShowIPsecPolicy vpn_service_create = neutronclient.osc.v2.vpnaas.vpnservice:CreateVPNService vpn_service_delete = neutronclient.osc.v2.vpnaas.vpnservice:DeleteVPNService vpn_service_list = neutronclient.osc.v2.vpnaas.vpnservice:ListVPNService vpn_service_set = neutronclient.osc.v2.vpnaas.vpnservice:SetVPNSercice vpn_service_show = neutronclient.osc.v2.vpnaas.vpnservice:ShowVPNService vpn_ipsec_site_connection_create = neutronclient.osc.v2.vpnaas.ipsec_site_connection:CreateIPsecSiteConnection vpn_ipsec_site_connection_delete = neutronclient.osc.v2.vpnaas.ipsec_site_connection:DeleteIPsecSiteConnection vpn_ipsec_site_connection_list = neutronclient.osc.v2.vpnaas.ipsec_site_connection:ListIPsecSiteConnection vpn_ipsec_site_connection_set = neutronclient.osc.v2.vpnaas.ipsec_site_connection:SetIPsecSiteConnection vpn_ipsec_site_connection_show = neutronclient.osc.v2.vpnaas.ipsec_site_connection:ShowIPsecSiteConnection neutron.cli.v2 = bash-completion = neutronclient.shell:BashCompletionCommand net-list = neutronclient.neutron.v2_0.network:ListNetwork net-external-list = neutronclient.neutron.v2_0.network:ListExternalNetwork net-show = neutronclient.neutron.v2_0.network:ShowNetwork net-create = neutronclient.neutron.v2_0.network:CreateNetwork net-delete = neutronclient.neutron.v2_0.network:DeleteNetwork net-update = neutronclient.neutron.v2_0.network:UpdateNetwork subnet-list = neutronclient.neutron.v2_0.subnet:ListSubnet subnet-show = neutronclient.neutron.v2_0.subnet:ShowSubnet subnet-create = neutronclient.neutron.v2_0.subnet:CreateSubnet subnet-delete = neutronclient.neutron.v2_0.subnet:DeleteSubnet subnet-update = neutronclient.neutron.v2_0.subnet:UpdateSubnet subnetpool-list = neutronclient.neutron.v2_0.subnetpool:ListSubnetPool subnetpool-show = neutronclient.neutron.v2_0.subnetpool:ShowSubnetPool subnetpool-create = neutronclient.neutron.v2_0.subnetpool:CreateSubnetPool subnetpool-delete = neutronclient.neutron.v2_0.subnetpool:DeleteSubnetPool subnetpool-update = neutronclient.neutron.v2_0.subnetpool:UpdateSubnetPool port-list = neutronclient.neutron.v2_0.port:ListPort port-show = neutronclient.neutron.v2_0.port:ShowPort port-create = neutronclient.neutron.v2_0.port:CreatePort port-delete = neutronclient.neutron.v2_0.port:DeletePort port-update = neutronclient.neutron.v2_0.port:UpdatePort purge = neutronclient.neutron.v2_0.purge:Purge quota-list = neutronclient.neutron.v2_0.quota:ListQuota quota-show = neutronclient.neutron.v2_0.quota:ShowQuota quota-default-show = neutronclient.neutron.v2_0.quota:ShowQuotaDefault quota-delete = neutronclient.neutron.v2_0.quota:DeleteQuota quota-update = neutronclient.neutron.v2_0.quota:UpdateQuota ext-list = neutronclient.neutron.v2_0.extension:ListExt ext-show = neutronclient.neutron.v2_0.extension:ShowExt router-list = neutronclient.neutron.v2_0.router:ListRouter router-port-list = neutronclient.neutron.v2_0.port:ListRouterPort router-show = neutronclient.neutron.v2_0.router:ShowRouter router-create = neutronclient.neutron.v2_0.router:CreateRouter router-delete = neutronclient.neutron.v2_0.router:DeleteRouter router-update = neutronclient.neutron.v2_0.router:UpdateRouter router-interface-add = neutronclient.neutron.v2_0.router:AddInterfaceRouter router-interface-delete = neutronclient.neutron.v2_0.router:RemoveInterfaceRouter router-gateway-set = neutronclient.neutron.v2_0.router:SetGatewayRouter router-gateway-clear = neutronclient.neutron.v2_0.router:RemoveGatewayRouter floatingip-list = neutronclient.neutron.v2_0.floatingip:ListFloatingIP floatingip-show = neutronclient.neutron.v2_0.floatingip:ShowFloatingIP floatingip-create = neutronclient.neutron.v2_0.floatingip:CreateFloatingIP floatingip-delete = neutronclient.neutron.v2_0.floatingip:DeleteFloatingIP floatingip-associate = neutronclient.neutron.v2_0.floatingip:AssociateFloatingIP floatingip-disassociate = neutronclient.neutron.v2_0.floatingip:DisassociateFloatingIP security-group-list = neutronclient.neutron.v2_0.securitygroup:ListSecurityGroup security-group-show = neutronclient.neutron.v2_0.securitygroup:ShowSecurityGroup security-group-create = neutronclient.neutron.v2_0.securitygroup:CreateSecurityGroup security-group-delete = neutronclient.neutron.v2_0.securitygroup:DeleteSecurityGroup security-group-update = neutronclient.neutron.v2_0.securitygroup:UpdateSecurityGroup security-group-rule-list = neutronclient.neutron.v2_0.securitygroup:ListSecurityGroupRule security-group-rule-show = neutronclient.neutron.v2_0.securitygroup:ShowSecurityGroupRule security-group-rule-create = neutronclient.neutron.v2_0.securitygroup:CreateSecurityGroupRule security-group-rule-delete = neutronclient.neutron.v2_0.securitygroup:DeleteSecurityGroupRule agent-list = neutronclient.neutron.v2_0.agent:ListAgent agent-show = neutronclient.neutron.v2_0.agent:ShowAgent agent-delete = neutronclient.neutron.v2_0.agent:DeleteAgent agent-update = neutronclient.neutron.v2_0.agent:UpdateAgent dhcp-agent-network-add = neutronclient.neutron.v2_0.agentscheduler:AddNetworkToDhcpAgent dhcp-agent-network-remove = neutronclient.neutron.v2_0.agentscheduler:RemoveNetworkFromDhcpAgent net-list-on-dhcp-agent = neutronclient.neutron.v2_0.agentscheduler:ListNetworksOnDhcpAgent dhcp-agent-list-hosting-net = neutronclient.neutron.v2_0.agentscheduler:ListDhcpAgentsHostingNetwork l3-agent-router-add = neutronclient.neutron.v2_0.agentscheduler:AddRouterToL3Agent l3-agent-router-remove = neutronclient.neutron.v2_0.agentscheduler:RemoveRouterFromL3Agent router-list-on-l3-agent = neutronclient.neutron.v2_0.agentscheduler:ListRoutersOnL3Agent l3-agent-list-hosting-router = neutronclient.neutron.v2_0.agentscheduler:ListL3AgentsHostingRouter lb-pool-list-on-agent = neutronclient.neutron.v2_0.agentscheduler:ListPoolsOnLbaasAgent lb-agent-hosting-pool = neutronclient.neutron.v2_0.agentscheduler:GetLbaasAgentHostingPool lbaas-loadbalancer-list-on-agent = neutronclient.neutron.v2_0.agentscheduler:ListLoadBalancersOnLbaasAgent lbaas-agent-hosting-loadbalancer = neutronclient.neutron.v2_0.agentscheduler:GetLbaasAgentHostingLoadBalancer service-provider-list = neutronclient.neutron.v2_0.servicetype:ListServiceProvider rbac-create = neutronclient.neutron.v2_0.rbac:CreateRBACPolicy rbac-update = neutronclient.neutron.v2_0.rbac:UpdateRBACPolicy rbac-list = neutronclient.neutron.v2_0.rbac:ListRBACPolicy rbac-show = neutronclient.neutron.v2_0.rbac:ShowRBACPolicy rbac-delete = neutronclient.neutron.v2_0.rbac:DeleteRBACPolicy address-scope-list = neutronclient.neutron.v2_0.address_scope:ListAddressScope address-scope-show = neutronclient.neutron.v2_0.address_scope:ShowAddressScope address-scope-create = neutronclient.neutron.v2_0.address_scope:CreateAddressScope address-scope-delete = neutronclient.neutron.v2_0.address_scope:DeleteAddressScope address-scope-update = neutronclient.neutron.v2_0.address_scope:UpdateAddressScope availability-zone-list = neutronclient.neutron.v2_0.availability_zone:ListAvailabilityZone auto-allocated-topology-show = neutronclient.neutron.v2_0.auto_allocated_topology:ShowAutoAllocatedTopology auto-allocated-topology-delete = neutronclient.neutron.v2_0.auto_allocated_topology:DeleteAutoAllocatedTopology net-ip-availability-list = neutronclient.neutron.v2_0.network_ip_availability:ListIpAvailability net-ip-availability-show = neutronclient.neutron.v2_0.network_ip_availability:ShowIpAvailability tag-add = neutronclient.neutron.v2_0.tag:AddTag tag-replace = neutronclient.neutron.v2_0.tag:ReplaceTag tag-remove = neutronclient.neutron.v2_0.tag:RemoveTag qos-policy-list = neutronclient.neutron.v2_0.qos.policy:ListQoSPolicy qos-policy-show = neutronclient.neutron.v2_0.qos.policy:ShowQoSPolicy qos-policy-create = neutronclient.neutron.v2_0.qos.policy:CreateQoSPolicy qos-policy-update = neutronclient.neutron.v2_0.qos.policy:UpdateQoSPolicy qos-policy-delete = neutronclient.neutron.v2_0.qos.policy:DeleteQoSPolicy qos-bandwidth-limit-rule-create = neutronclient.neutron.v2_0.qos.bandwidth_limit_rule:CreateQoSBandwidthLimitRule qos-bandwidth-limit-rule-show = neutronclient.neutron.v2_0.qos.bandwidth_limit_rule:ShowQoSBandwidthLimitRule qos-bandwidth-limit-rule-list = neutronclient.neutron.v2_0.qos.bandwidth_limit_rule:ListQoSBandwidthLimitRules qos-bandwidth-limit-rule-update = neutronclient.neutron.v2_0.qos.bandwidth_limit_rule:UpdateQoSBandwidthLimitRule qos-bandwidth-limit-rule-delete = neutronclient.neutron.v2_0.qos.bandwidth_limit_rule:DeleteQoSBandwidthLimitRule qos-dscp-marking-rule-create = neutronclient.neutron.v2_0.qos.dscp_marking_rule:CreateQoSDscpMarkingRule qos-dscp-marking-rule-show = neutronclient.neutron.v2_0.qos.dscp_marking_rule:ShowQoSDscpMarkingRule qos-dscp-marking-rule-list = neutronclient.neutron.v2_0.qos.dscp_marking_rule:ListQoSDscpMarkingRules qos-dscp-marking-rule-update = neutronclient.neutron.v2_0.qos.dscp_marking_rule:UpdateQoSDscpMarkingRule qos-dscp-marking-rule-delete = neutronclient.neutron.v2_0.qos.dscp_marking_rule:DeleteQoSDscpMarkingRule qos-minimum-bandwidth-rule-create = neutronclient.neutron.v2_0.qos.minimum_bandwidth_rule:CreateQoSMinimumBandwidthRule qos-minimum-bandwidth-rule-show = neutronclient.neutron.v2_0.qos.minimum_bandwidth_rule:ShowQoSMinimumBandwidthRule qos-minimum-bandwidth-rule-list = neutronclient.neutron.v2_0.qos.minimum_bandwidth_rule:ListQoSMinimumBandwidthRules qos-minimum-bandwidth-rule-update = neutronclient.neutron.v2_0.qos.minimum_bandwidth_rule:UpdateQoSMinimumBandwidthRule qos-minimum-bandwidth-rule-delete = neutronclient.neutron.v2_0.qos.minimum_bandwidth_rule:DeleteQoSMinimumBandwidthRule qos-available-rule-types = neutronclient.neutron.v2_0.qos.rule:ListQoSRuleTypes flavor-list = neutronclient.neutron.v2_0.flavor.flavor:ListFlavor flavor-show = neutronclient.neutron.v2_0.flavor.flavor:ShowFlavor flavor-create = neutronclient.neutron.v2_0.flavor.flavor:CreateFlavor flavor-delete = neutronclient.neutron.v2_0.flavor.flavor:DeleteFlavor flavor-update = neutronclient.neutron.v2_0.flavor.flavor:UpdateFlavor flavor-associate = neutronclient.neutron.v2_0.flavor.flavor:AssociateFlavor flavor-disassociate = neutronclient.neutron.v2_0.flavor.flavor:DisassociateFlavor flavor-profile-list = neutronclient.neutron.v2_0.flavor.flavor_profile:ListFlavorProfile flavor-profile-show = neutronclient.neutron.v2_0.flavor.flavor_profile:ShowFlavorProfile flavor-profile-create = neutronclient.neutron.v2_0.flavor.flavor_profile:CreateFlavorProfile flavor-profile-delete = neutronclient.neutron.v2_0.flavor.flavor_profile:DeleteFlavorProfile flavor-profile-update = neutronclient.neutron.v2_0.flavor.flavor_profile:UpdateFlavorProfile meter-label-create = neutronclient.neutron.v2_0.metering:CreateMeteringLabel meter-label-list = neutronclient.neutron.v2_0.metering:ListMeteringLabel meter-label-show = neutronclient.neutron.v2_0.metering:ShowMeteringLabel meter-label-delete = neutronclient.neutron.v2_0.metering:DeleteMeteringLabel meter-label-rule-create = neutronclient.neutron.v2_0.metering:CreateMeteringLabelRule meter-label-rule-list = neutronclient.neutron.v2_0.metering:ListMeteringLabelRule meter-label-rule-show = neutronclient.neutron.v2_0.metering:ShowMeteringLabelRule meter-label-rule-delete = neutronclient.neutron.v2_0.metering:DeleteMeteringLabelRule firewall-rule-list = neutronclient.neutron.v2_0.fw.firewallrule:ListFirewallRule firewall-rule-show = neutronclient.neutron.v2_0.fw.firewallrule:ShowFirewallRule firewall-rule-create = neutronclient.neutron.v2_0.fw.firewallrule:CreateFirewallRule firewall-rule-update = neutronclient.neutron.v2_0.fw.firewallrule:UpdateFirewallRule firewall-rule-delete = neutronclient.neutron.v2_0.fw.firewallrule:DeleteFirewallRule firewall-policy-list = neutronclient.neutron.v2_0.fw.firewallpolicy:ListFirewallPolicy firewall-policy-show = neutronclient.neutron.v2_0.fw.firewallpolicy:ShowFirewallPolicy firewall-policy-create = neutronclient.neutron.v2_0.fw.firewallpolicy:CreateFirewallPolicy firewall-policy-update = neutronclient.neutron.v2_0.fw.firewallpolicy:UpdateFirewallPolicy firewall-policy-delete = neutronclient.neutron.v2_0.fw.firewallpolicy:DeleteFirewallPolicy firewall-policy-insert-rule = neutronclient.neutron.v2_0.fw.firewallpolicy:FirewallPolicyInsertRule firewall-policy-remove-rule = neutronclient.neutron.v2_0.fw.firewallpolicy:FirewallPolicyRemoveRule firewall-list = neutronclient.neutron.v2_0.fw.firewall:ListFirewall firewall-show = neutronclient.neutron.v2_0.fw.firewall:ShowFirewall firewall-create = neutronclient.neutron.v2_0.fw.firewall:CreateFirewall firewall-update = neutronclient.neutron.v2_0.fw.firewall:UpdateFirewall firewall-delete = neutronclient.neutron.v2_0.fw.firewall:DeleteFirewall bgp-dragent-speaker-add = neutronclient.neutron.v2_0.bgp.dragentscheduler:AddBGPSpeakerToDRAgent bgp-dragent-speaker-remove = neutronclient.neutron.v2_0.bgp.dragentscheduler:RemoveBGPSpeakerFromDRAgent bgp-speaker-list-on-dragent = neutronclient.neutron.v2_0.bgp.dragentscheduler:ListBGPSpeakersOnDRAgent bgp-dragent-list-hosting-speaker = neutronclient.neutron.v2_0.bgp.dragentscheduler:ListDRAgentsHostingBGPSpeaker bgp-speaker-list = neutronclient.neutron.v2_0.bgp.speaker:ListSpeakers bgp-speaker-advertiseroute-list = neutronclient.neutron.v2_0.bgp.speaker:ListRoutesAdvertisedBySpeaker bgp-speaker-show = neutronclient.neutron.v2_0.bgp.speaker:ShowSpeaker bgp-speaker-create = neutronclient.neutron.v2_0.bgp.speaker:CreateSpeaker bgp-speaker-update = neutronclient.neutron.v2_0.bgp.speaker:UpdateSpeaker bgp-speaker-delete = neutronclient.neutron.v2_0.bgp.speaker:DeleteSpeaker bgp-speaker-peer-add = neutronclient.neutron.v2_0.bgp.speaker:AddPeerToSpeaker bgp-speaker-peer-remove = neutronclient.neutron.v2_0.bgp.speaker:RemovePeerFromSpeaker bgp-speaker-network-add = neutronclient.neutron.v2_0.bgp.speaker:AddNetworkToSpeaker bgp-speaker-network-remove = neutronclient.neutron.v2_0.bgp.speaker:RemoveNetworkFromSpeaker bgp-peer-list = neutronclient.neutron.v2_0.bgp.peer:ListPeers bgp-peer-show = neutronclient.neutron.v2_0.bgp.peer:ShowPeer bgp-peer-create = neutronclient.neutron.v2_0.bgp.peer:CreatePeer bgp-peer-update = neutronclient.neutron.v2_0.bgp.peer:UpdatePeer bgp-peer-delete = neutronclient.neutron.v2_0.bgp.peer:DeletePeer lbaas-loadbalancer-list = neutronclient.neutron.v2_0.lb.v2.loadbalancer:ListLoadBalancer lbaas-loadbalancer-show = neutronclient.neutron.v2_0.lb.v2.loadbalancer:ShowLoadBalancer lbaas-loadbalancer-create = neutronclient.neutron.v2_0.lb.v2.loadbalancer:CreateLoadBalancer lbaas-loadbalancer-update = neutronclient.neutron.v2_0.lb.v2.loadbalancer:UpdateLoadBalancer lbaas-loadbalancer-delete = neutronclient.neutron.v2_0.lb.v2.loadbalancer:DeleteLoadBalancer lbaas-loadbalancer-stats = neutronclient.neutron.v2_0.lb.v2.loadbalancer:RetrieveLoadBalancerStats lbaas-loadbalancer-status = neutronclient.neutron.v2_0.lb.v2.loadbalancer:RetrieveLoadBalancerStatus lbaas-listener-list = neutronclient.neutron.v2_0.lb.v2.listener:ListListener lbaas-listener-show = neutronclient.neutron.v2_0.lb.v2.listener:ShowListener lbaas-listener-create = neutronclient.neutron.v2_0.lb.v2.listener:CreateListener lbaas-listener-update = neutronclient.neutron.v2_0.lb.v2.listener:UpdateListener lbaas-listener-delete = neutronclient.neutron.v2_0.lb.v2.listener:DeleteListener lbaas-l7policy-list = neutronclient.neutron.v2_0.lb.v2.l7policy:ListL7Policy lbaas-l7policy-show = neutronclient.neutron.v2_0.lb.v2.l7policy:ShowL7Policy lbaas-l7policy-create = neutronclient.neutron.v2_0.lb.v2.l7policy:CreateL7Policy lbaas-l7policy-update = neutronclient.neutron.v2_0.lb.v2.l7policy:UpdateL7Policy lbaas-l7policy-delete = neutronclient.neutron.v2_0.lb.v2.l7policy:DeleteL7Policy lbaas-l7rule-list = neutronclient.neutron.v2_0.lb.v2.l7rule:ListL7Rule lbaas-l7rule-show = neutronclient.neutron.v2_0.lb.v2.l7rule:ShowL7Rule lbaas-l7rule-create = neutronclient.neutron.v2_0.lb.v2.l7rule:CreateL7Rule lbaas-l7rule-update = neutronclient.neutron.v2_0.lb.v2.l7rule:UpdateL7Rule lbaas-l7rule-delete = neutronclient.neutron.v2_0.lb.v2.l7rule:DeleteL7Rule lbaas-pool-list = neutronclient.neutron.v2_0.lb.v2.pool:ListPool lbaas-pool-show = neutronclient.neutron.v2_0.lb.v2.pool:ShowPool lbaas-pool-create = neutronclient.neutron.v2_0.lb.v2.pool:CreatePool lbaas-pool-update = neutronclient.neutron.v2_0.lb.v2.pool:UpdatePool lbaas-pool-delete = neutronclient.neutron.v2_0.lb.v2.pool:DeletePool lbaas-healthmonitor-list = neutronclient.neutron.v2_0.lb.v2.healthmonitor:ListHealthMonitor lbaas-healthmonitor-show = neutronclient.neutron.v2_0.lb.v2.healthmonitor:ShowHealthMonitor lbaas-healthmonitor-create = neutronclient.neutron.v2_0.lb.v2.healthmonitor:CreateHealthMonitor lbaas-healthmonitor-update = neutronclient.neutron.v2_0.lb.v2.healthmonitor:UpdateHealthMonitor lbaas-healthmonitor-delete = neutronclient.neutron.v2_0.lb.v2.healthmonitor:DeleteHealthMonitor lbaas-member-list = neutronclient.neutron.v2_0.lb.v2.member:ListMember lbaas-member-show = neutronclient.neutron.v2_0.lb.v2.member:ShowMember lbaas-member-create = neutronclient.neutron.v2_0.lb.v2.member:CreateMember lbaas-member-update = neutronclient.neutron.v2_0.lb.v2.member:UpdateMember lbaas-member-delete = neutronclient.neutron.v2_0.lb.v2.member:DeleteMember lb-vip-list = neutronclient.neutron.v2_0.lb.vip:ListVip lb-vip-show = neutronclient.neutron.v2_0.lb.vip:ShowVip lb-vip-create = neutronclient.neutron.v2_0.lb.vip:CreateVip lb-vip-update = neutronclient.neutron.v2_0.lb.vip:UpdateVip lb-vip-delete = neutronclient.neutron.v2_0.lb.vip:DeleteVip lb-pool-list = neutronclient.neutron.v2_0.lb.pool:ListPool lb-pool-show = neutronclient.neutron.v2_0.lb.pool:ShowPool lb-pool-create = neutronclient.neutron.v2_0.lb.pool:CreatePool lb-pool-update = neutronclient.neutron.v2_0.lb.pool:UpdatePool lb-pool-delete = neutronclient.neutron.v2_0.lb.pool:DeletePool lb-pool-stats = neutronclient.neutron.v2_0.lb.pool:RetrievePoolStats lb-member-list = neutronclient.neutron.v2_0.lb.member:ListMember lb-member-show = neutronclient.neutron.v2_0.lb.member:ShowMember lb-member-create = neutronclient.neutron.v2_0.lb.member:CreateMember lb-member-update = neutronclient.neutron.v2_0.lb.member:UpdateMember lb-member-delete = neutronclient.neutron.v2_0.lb.member:DeleteMember lb-healthmonitor-list = neutronclient.neutron.v2_0.lb.healthmonitor:ListHealthMonitor lb-healthmonitor-show = neutronclient.neutron.v2_0.lb.healthmonitor:ShowHealthMonitor lb-healthmonitor-create = neutronclient.neutron.v2_0.lb.healthmonitor:CreateHealthMonitor lb-healthmonitor-update = neutronclient.neutron.v2_0.lb.healthmonitor:UpdateHealthMonitor lb-healthmonitor-delete = neutronclient.neutron.v2_0.lb.healthmonitor:DeleteHealthMonitor lb-healthmonitor-associate = neutronclient.neutron.v2_0.lb.healthmonitor:AssociateHealthMonitor lb-healthmonitor-disassociate = neutronclient.neutron.v2_0.lb.healthmonitor:DisassociateHealthMonitor ipsec-site-connection-list = neutronclient.neutron.v2_0.vpn.ipsec_site_connection:ListIPsecSiteConnection ipsec-site-connection-show = neutronclient.neutron.v2_0.vpn.ipsec_site_connection:ShowIPsecSiteConnection ipsec-site-connection-create = neutronclient.neutron.v2_0.vpn.ipsec_site_connection:CreateIPsecSiteConnection ipsec-site-connection-update = neutronclient.neutron.v2_0.vpn.ipsec_site_connection:UpdateIPsecSiteConnection ipsec-site-connection-delete = neutronclient.neutron.v2_0.vpn.ipsec_site_connection:DeleteIPsecSiteConnection vpn-endpoint-group-list = neutronclient.neutron.v2_0.vpn.endpoint_group:ListEndpointGroup vpn-endpoint-group-show = neutronclient.neutron.v2_0.vpn.endpoint_group:ShowEndpointGroup vpn-endpoint-group-create = neutronclient.neutron.v2_0.vpn.endpoint_group:CreateEndpointGroup vpn-endpoint-group-update = neutronclient.neutron.v2_0.vpn.endpoint_group:UpdateEndpointGroup vpn-endpoint-group-delete = neutronclient.neutron.v2_0.vpn.endpoint_group:DeleteEndpointGroup vpn-service-list = neutronclient.neutron.v2_0.vpn.vpnservice:ListVPNService vpn-service-show = neutronclient.neutron.v2_0.vpn.vpnservice:ShowVPNService vpn-service-create = neutronclient.neutron.v2_0.vpn.vpnservice:CreateVPNService vpn-service-update = neutronclient.neutron.v2_0.vpn.vpnservice:UpdateVPNService vpn-service-delete = neutronclient.neutron.v2_0.vpn.vpnservice:DeleteVPNService vpn-ipsecpolicy-list = neutronclient.neutron.v2_0.vpn.ipsecpolicy:ListIPsecPolicy vpn-ipsecpolicy-show = neutronclient.neutron.v2_0.vpn.ipsecpolicy:ShowIPsecPolicy vpn-ipsecpolicy-create = neutronclient.neutron.v2_0.vpn.ipsecpolicy:CreateIPsecPolicy vpn-ipsecpolicy-update = neutronclient.neutron.v2_0.vpn.ipsecpolicy:UpdateIPsecPolicy vpn-ipsecpolicy-delete = neutronclient.neutron.v2_0.vpn.ipsecpolicy:DeleteIPsecPolicy vpn-ikepolicy-list = neutronclient.neutron.v2_0.vpn.ikepolicy:ListIKEPolicy vpn-ikepolicy-show = neutronclient.neutron.v2_0.vpn.ikepolicy:ShowIKEPolicy vpn-ikepolicy-create = neutronclient.neutron.v2_0.vpn.ikepolicy:CreateIKEPolicy vpn-ikepolicy-update = neutronclient.neutron.v2_0.vpn.ikepolicy:UpdateIKEPolicy vpn-ikepolicy-delete = neutronclient.neutron.v2_0.vpn.ikepolicy:DeleteIKEPolicy [build_sphinx] all_files = 1 build-dir = doc/build source-dir = doc/source warning-is-error = 1 [wheel] universal = 1 [extract_messages] keywords = _ gettext ngettext l_ lazy_gettext mapping_file = babel.cfg output_file = neutronclient/locale/neutronclient.pot [compile_catalog] directory = neutronclient/locale domain = neutronclient [update_catalog] domain = neutronclient output_dir = neutronclient/locale input_file = neutronclient/locale/neutronclient.pot [egg_info] tag_build = tag_date = 0 python-neutronclient-6.7.0/setup.py0000666000175100017510000000200613232473350017474 0ustar zuulzuul00000000000000# 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. # THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT import setuptools # In python < 2.7.4, a lazy loading of package `pbr` will break # setuptools if some other modules registered functions in `atexit`. # solution from: http://bugs.python.org/issue15881#msg170215 try: import multiprocessing # noqa except ImportError: pass setuptools.setup( setup_requires=['pbr>=2.0.0'], pbr=True) python-neutronclient-6.7.0/requirements.txt0000666000175100017510000000151313232473350021250 0ustar zuulzuul00000000000000# The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. pbr!=2.1.0,>=2.0.0 # Apache-2.0 cliff!=2.9.0,>=2.8.0 # Apache-2.0 debtcollector>=1.2.0 # Apache-2.0 iso8601>=0.1.11 # MIT netaddr>=0.7.18 # BSD osc-lib>=1.8.0 # Apache-2.0 oslo.i18n>=3.15.3 # Apache-2.0 oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0 oslo.utils>=3.33.0 # Apache-2.0 os-client-config>=1.28.0 # Apache-2.0 keystoneauth1>=3.3.0 # Apache-2.0 # keystoneclient is used only by neutronclient.osc.utils # TODO(amotoki): Drop this after osc.utils has no dependency on keystoneclient python-keystoneclient>=3.8.0 # Apache-2.0 requests>=2.14.2 # Apache-2.0 simplejson>=3.5.1 # MIT six>=1.10.0 # MIT Babel!=2.4.0,>=2.3.4 # BSD python-neutronclient-6.7.0/releasenotes/0000775000175100017510000000000013232473710020453 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/releasenotes/notes/0000775000175100017510000000000013232473710021603 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/releasenotes/notes/docs-improvements-17e31babe38e2962.yaml0000666000175100017510000000021313232473350030356 0ustar zuulzuul00000000000000--- other: - | Addition of CLI user documentation including output filters, extra options, and operation using os-client-config. python-neutronclient-6.7.0/releasenotes/notes/keystonev3-7f9ede9c21b30841.yaml0000666000175100017510000000031113232473350027020 0ustar zuulzuul00000000000000--- deprecations: - | Keystone v3 support for CLI * Using 'tenant_id' and 'tenant_name' arguments in API bindings is deprecated. Use 'project_id' and 'project_name' arguments instead. python-neutronclient-6.7.0/releasenotes/notes/add-lb-status-tree-723f23c09617de3b.yaml0000666000175100017510000000025713232473350030232 0ustar zuulzuul00000000000000--- features: - | CLI support for load balancer status tree. * The ``lbaas-loadbalancer-status`` command provides the status tree of a specific load balancer.python-neutronclient-6.7.0/releasenotes/notes/fix-quota-update-zero-args-d596c4169c2d2e30.yaml0000666000175100017510000000050713232473350031736 0ustar zuulzuul00000000000000--- fixes: - | Fix CLI quota-update to return an error message for no args * ``quota-update`` CLI will return an error message ``Must specify a valid resource with new quota value`` if no argument is provided while executing it. If arguments are provided with CLI, no existing behavior is changed. python-neutronclient-6.7.0/releasenotes/notes/direct-physical-vnic-port-create-736d8b2600faf22b.yaml0000666000175100017510000000036313232473350033145 0ustar zuulzuul00000000000000--- features: - Added new 'direct-physical' vnic-type option for port-create CLI command. Passing this particular value allows for a port to be create with the vnic-type used for assigning SR-IOV physical functions to instances. ././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000python-neutronclient-6.7.0/releasenotes/notes/support-vni-in-networking-bgpvpn-cli-d284b73b40b79495.yamlpython-neutronclient-6.7.0/releasenotes/notes/support-vni-in-networking-bgpvpn-cli-d284b73b40b79495.0000666000175100017510000000036613232473350033036 0ustar zuulzuul00000000000000--- features: - | CLI support for VXLAN VNI ID attribute in bgpvpn. An optional argument ``--vni`` is added to ``openstack bgpvpn`` commands to configure VXLAN Network Identifier when VXLAN encapsulation is used for the bgpvpn. python-neutronclient-6.7.0/releasenotes/notes/deprecate-cli-7be1123817969439.yaml0000666000175100017510000000060513232473350027125 0ustar zuulzuul00000000000000--- deprecations: - The neutron CLI is now deprecated. This is the signal that it is time to start using the openstack CLI. No new features will be added to the neutron CLI, though fixes to the CLI will be assessed on a case by case basis. Fixes to the API bindings, as well as development of new API bindings as well as OSC plugins are exempt from this deprecation. python-neutronclient-6.7.0/releasenotes/notes/osprofiler-support-9ba539761ae437e9.yaml0000666000175100017510000000027413232473350030544 0ustar zuulzuul00000000000000--- features: - | Add osprofiler support to the neutronclient python binding. If osprofiler is initiated, neutronclient sends a special HTTP header that contains trace info. python-neutronclient-6.7.0/releasenotes/notes/fix-rbac-create-command-dd40a474f0f092db.yaml0000666000175100017510000000046313232473350031332 0ustar zuulzuul00000000000000--- fixes: - Fix 'bug 1596750 ' that using 'rbac-create' without specifying 'target-tenant' will return 'Request Failed internal server error while processing your request'. Update the default value of the argument '--target-tenant' to '*' python-neutronclient-6.7.0/releasenotes/notes/support-vpnaas-cli-9478fb7cfe603e26.yaml0000666000175100017510000000021413232473350030471 0ustar zuulzuul00000000000000--- features: - | CLI support for the "VPN as a Service" feature, which is enhanced VPNaaS functionality, as OSC plugin commands. python-neutronclient-6.7.0/releasenotes/notes/qos_minimum_bandwidth-dc4adb23c51de30b.yaml0000666000175100017510000000017013232473350031463 0ustar zuulzuul00000000000000--- features: - New create, update, list, show, and delete commands are added for the QoS minimum bandwidth rule. python-neutronclient-6.7.0/releasenotes/notes/quota-update-for-rbac-192a8e65bf481941.yaml0000666000175100017510000000010213232473350030651 0ustar zuulzuul00000000000000--- features: - | Quota for RBAC policies can now be set. python-neutronclient-6.7.0/releasenotes/notes/global_request_id-56856a93b982a6b3.yaml0000666000175100017510000000027113232473350030246 0ustar zuulzuul00000000000000--- features: - | Adds a new ``global_request_id`` parameter to the Client constructors, which will pass that id on all requests as the ``X-OpenStack-Request-ID`` header. python-neutronclient-6.7.0/releasenotes/notes/remove-case-dependency-773ccb3237c38e81.yaml0000666000175100017510000000027013232473350031153 0ustar zuulzuul00000000000000--- other: - | This patch provides user the support to use any form of casing, thus removing the specific UPPER/lower case inputs required by different neutron CLIs. python-neutronclient-6.7.0/releasenotes/notes/log-request-id-64bef955b8292c18.yaml0000666000175100017510000000012213232473350027477 0ustar zuulzuul00000000000000--- features: - Added support to log 'x-openstack-request-id' for each api call.python-neutronclient-6.7.0/releasenotes/notes/network-ip-availability-ac9a462f42fe9db4.yaml0000666000175100017510000000042413232473350031621 0ustar zuulzuul00000000000000--- features: - | CLI support for network IP availability * The ``net-ip-availability-list`` command provides a list of IP usage statistics for all networks. * The ``net-ip-availability-show`` command provides IP usage stats for a specific network. python-neutronclient-6.7.0/releasenotes/notes/add-get-me-a-network-5ab2d60bf6f257b1.yaml0000666000175100017510000000045513232473350030574 0ustar zuulzuul00000000000000--- features: - | CLI support for the "get-me-a-network" feature, which simplifies the process for launching an instance with basic network connectivity. * The ``auto-allocated-topology-show`` command provides the network of the automatically allocated topology for a tenant. python-neutronclient-6.7.0/releasenotes/notes/availability-zone-support-8e66f55e46b7ef9a.yaml0000666000175100017510000000051113232473350032146 0ustar zuulzuul00000000000000--- features: - | CLI support for availability zones. * The ``availability-zone-list`` command provides a list of availability zones. * The ``net-create`` and ``router-create`` commands include a ``--availability-zone-hint`` option. * The ``agent-list`` command output includes availability zones. python-neutronclient-6.7.0/releasenotes/notes/bgp-dynamic-routing-b97a1c81d3007049.yaml0000666000175100017510000000022613232473350030420 0ustar zuulzuul00000000000000--- features: - | CLI support for the BGP dynamic routing functionality will help advertising neutron fixed-ips and dvr host routes via BGP.python-neutronclient-6.7.0/releasenotes/notes/dscp_qos-4a26d3c0363624b0.yaml0000666000175100017510000000026713232473350026347 0ustar zuulzuul00000000000000--- prelude: > Adding new QoS DSCP marking rule commands. features: - New create, update, list, show, and delete commands are added for QoS DSCP marking rule functionality. python-neutronclient-6.7.0/releasenotes/notes/remove-deprecated-option-b53f5d7e6a16ce95.yaml0000666000175100017510000000015713232473350031703 0ustar zuulzuul00000000000000--- deprecations: - | "admin-state-down" option was deprecated in Mitaka and has been removed in Newton. python-neutronclient-6.7.0/releasenotes/notes/add-shared-pools-support-6f79b565afad3e47.yaml0000666000175100017510000000036013232473350031642 0ustar zuulzuul00000000000000--- features: - | CLI support for Neutron-LBaaS v2 shared pools added. * Pools can be created independently from listeners. * Listeners can share the same default_pool. * Makes Layer 7 switching support much more useful. python-neutronclient-6.7.0/releasenotes/notes/drop-xml-support-41babecb1784d996.yaml0000666000175100017510000000016513232473350030250 0ustar zuulzuul00000000000000--- upgrade: - XML request format support has been removed. deprecations: - request-format option is deprecated. python-neutronclient-6.7.0/releasenotes/notes/support-bgpvpn-route-control-aeda3e698486f73b.yaml0000666000175100017510000000041013232473407032622 0ustar zuulzuul00000000000000--- features: - | Add BGP VPN `port association `_ support to the CLI, which are introduced for BGP VPN interconnections by the ``bgpvpn-routes-control`` API extension. python-neutronclient-6.7.0/releasenotes/notes/quota-update-for-LB-b21e7bc9e4a10f3e.yaml0000666000175100017510000000012313232473350030522 0ustar zuulzuul00000000000000--- features: - | Quota of Loadbalancers and listeners can now be updated. python-neutronclient-6.7.0/releasenotes/notes/add-quota-default-show-c2ab35b791dcdcbc.yaml0000666000175100017510000000030313232473350031447 0ustar zuulzuul00000000000000--- features: - | CLI support to display the default quota reserved for a tenant. * The ``quota-default-show`` command outputs the default quota of resources for a given tenant. python-neutronclient-6.7.0/releasenotes/notes/add-osc-trunk-commands-7e77283a369729c5.yaml0000666000175100017510000000053613232473350030770 0ustar zuulzuul00000000000000--- features: - | Add ``network trunk create``, ``network trunk list``, ``network trunk set``, ``network trunk unset``, ``network trunk delete`` and ``network subport list`` OSC commands for trunk resource along with client bindings. [Blueprint `vlan-aware-vms `_] python-neutronclient-6.7.0/releasenotes/notes/relnotes-from-3.0.0-d7306f5af5e3868d.yaml0000666000175100017510000000226313232473350030156 0ustar zuulzuul00000000000000--- features: - Support os-client-config. OS_CLOUD environment variable is used for selecting named cloud configuration. - Support keystoneauth1 library which brings us better kyestone v3 support. - Client command extension now supports a child resource. - New CLI for VPNaaS multiple local subnets. - New CLI for VPNaaS endpoint group API. - New CLI for flavor argument to loadbalancer v2 create. - New CLI for Neutron flavor framework. - Support creating floating IP on a specific subnet ID. - NSX gateway extension adds new transport type values (ipsec_gre and ipsec_stt). - New router-update option to update static routes (--route and --no-routes). - New allowed-address-pairs option to port-update upgrade: - Cisco-specific neutron client commands have been removed. These commands are ported to networking-cisco. - py26 support has been dropped. - py33 support has been dropped. fixes: - Name is no longer looked up on RBAC policies, RBAC policies have no name field so the name query to the server was always returning all entries since the name filter was ignored. (bug 1517818) other: - cliff-tablib has been removed from test dependencies. python-neutronclient-6.7.0/releasenotes/notes/sfc-tap-service-function-support-a05242f25f79066b.yaml0000666000175100017510000000013513232473350033074 0ustar zuulzuul00000000000000--- features: - | Add OSC support to create Port pair group for Tap service functions. python-neutronclient-6.7.0/releasenotes/notes/support-fwaasv2-cli-7f21676c551f8ae0.yaml0000666000175100017510000000021513232473350030461 0ustar zuulzuul00000000000000--- features: - CLI support for the "Firewall as a Service v2" feature, which is enhanced FWaaS functionality, as OSC plugin commands. python-neutronclient-6.7.0/releasenotes/notes/drop-nuage-commands-df10aab6ccd77ed2.yaml0000666000175100017510000000006113232473350031033 0ustar zuulzuul00000000000000--- upgrade: - Remove Nuage-specific commands. python-neutronclient-6.7.0/releasenotes/notes/add-rbac-qos-type-support-c42e31fadd7b.yaml0000666000175100017510000000031313232473350031363 0ustar zuulzuul00000000000000--- features: - | CLI support for QoS policy RBAC. * The ``rbac-create`` command include a --type qos-policy option. * The ``rbac-list`` command output includes a new 'type' column. python-neutronclient-6.7.0/releasenotes/notes/.placeholder0000666000175100017510000000000013232473350024056 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/releasenotes/notes/add-neutron-purge-a89e3d1179dce4b1.yaml0000666000175100017510000000062113232473350030330 0ustar zuulzuul00000000000000--- features: - | New command 'neutron purge ' will delete all supported resources owned by the given tenant, provided that the user has sufficient authorization and the resources in question are not shared, in use, or otherwise undeletable. Supported resources are: * Networks * Subnets * Routers * Ports * Floating IPs * Security Groups python-neutronclient-6.7.0/releasenotes/notes/support-networking-bgpvpn-cli-fdd0cc3a5b14983d.yaml0000666000175100017510000000032413232473350033001 0ustar zuulzuul00000000000000--- features: - CLI support for the "Neutron BGP VPN Interconnection" feature, which is an API extension to support inter-connection between L3VPNs/E-VPNs and Neutron resources, as OSC plugin commands. ././@LongLink0000000000000000000000000000015600000000000011217 Lustar 00000000000000python-neutronclient-6.7.0/releasenotes/notes/tag-support-subnet-port-subnetpool-router-6250ec4714ee8690.yamlpython-neutronclient-6.7.0/releasenotes/notes/tag-support-subnet-port-subnetpool-router-6250ec4714ee0000666000175100017510000000015113232473350033534 0ustar zuulzuul00000000000000--- features: - Tag operation for subnet, port, subnetpool and router resources are now supported. python-neutronclient-6.7.0/releasenotes/notes/add-sfc-commands.yaml0000666000175100017510000000042113232473350025566 0ustar zuulzuul00000000000000--- features: - | Add OSC plugin support for the “Networking Service Function Chaining” feature commands along with client bindings. [Blueprint `openstackclient-cli-porting `_]python-neutronclient-6.7.0/releasenotes/notes/add-service-graph-ce4a25b3e32d70a6.yaml0000666000175100017510000000021713232473350030240 0ustar zuulzuul00000000000000--- features: - | Added support for SFC Service Graph resource. Related RFE: https://bugs.launchpad.net/networking-sfc/+bug/1587486. ././@LongLink0000000000000000000000000000016500000000000011217 Lustar 00000000000000python-neutronclient-6.7.0/releasenotes/notes/Define-IpAddressAlreadyAllocatedClient-exception-e8600ca5ba1c7f45.yamlpython-neutronclient-6.7.0/releasenotes/notes/Define-IpAddressAlreadyAllocatedClient-exception-e86000000666000175100017510000000027113232473350033604 0ustar zuulzuul00000000000000--- other: - | Define a new exception type ``IpAddressAlreadyAllocatedClient``. Users can catch this specific exception instead of the generic ``NeutronClientException``. python-neutronclient-6.7.0/releasenotes/notes/support-logging-cli-cd02d3bb03367106.yaml0000666000175100017510000000025113232473350030507 0ustar zuulzuul00000000000000--- features: - | CLI support for 'Logging' feature, which enable to collect packet logs for specified resource. Currently, only security-group can be logged. python-neutronclient-6.7.0/releasenotes/notes/default-subnetpool-support-c0d34870e9d3e814.yaml0000666000175100017510000000043013232473350032155 0ustar zuulzuul00000000000000--- features: - | CLI support for default subnetpools. * The ``subnetpool-list`` and ``subnetpool-show`` command output includes the ``is_default`` field. * The ``subnetpool-create`` and ``subnetpool-update`` commands include a ``--is-default`` option. python-neutronclient-6.7.0/releasenotes/notes/start-using-reno-9081b3e4c1951fdb.yaml0000666000175100017510000000007113232473350030124 0ustar zuulzuul00000000000000--- other: - Start using reno to manage release notes. ././@LongLink0000000000000000000000000000014700000000000011217 Lustar 00000000000000python-neutronclient-6.7.0/releasenotes/notes/add-l7-content-policies-capability-0f17cd06f044c83c.yamlpython-neutronclient-6.7.0/releasenotes/notes/add-l7-content-policies-capability-0f17cd06f044c83c.ya0000666000175100017510000000034713232473350033017 0ustar zuulzuul00000000000000--- features: - | CLI support for Layer 7 content policies and rules. * L7 policies can be defined for listeners along with the ability to set L7 policy order. * Multiple rules can be created for an L7 policy. ././@LongLink0000000000000000000000000000014700000000000011217 Lustar 00000000000000python-neutronclient-6.7.0/releasenotes/notes/add-auto-allocated-topology-delete-aaccd60bd0f2e7b2.yamlpython-neutronclient-6.7.0/releasenotes/notes/add-auto-allocated-topology-delete-aaccd60bd0f2e7b2.ya0000666000175100017510000000017113232473350033372 0ustar zuulzuul00000000000000--- features: - The ``auto-allocated-topology-delete`` command allows users to delete the auto allocated topology. python-neutronclient-6.7.0/releasenotes/notes/bug-1676922-81341b70bc6f055a.yaml0000666000175100017510000000145213232473350026231 0ustar zuulzuul00000000000000--- deprecations: - | The ``--public`` and ``--private`` attribute of Firewall-as-a-Service v2 have been deprecated. While the ``--public`` attribute will now be replaced by ``--share``, the ``--private`` attribute will be replaced by ``--no-share``. This is because of the similarity between the behavior of ``--public`` attribute in FireWall-as-a-Service and the ``--share`` attribute used in OpenStack. This deprecation affects the following CLIs. * openstack firewall group create * openstack firewall group set * openstack firewall group unset * openstack firewall policy create * openstack firewall policy set * openstack firewall policy unset * openstack firewall rule create * openstack firewall rule set * openstack firewall rule unset python-neutronclient-6.7.0/releasenotes/notes/add-new-session-clear-option-3c0b78ebc133a10c.yaml0000666000175100017510000000031613232473350032335 0ustar zuulzuul00000000000000--- features: - | A new option ``--no-session-persistence`` has been added to the ``neutron lbaas-pool-update`` CLI to clear the session persistence with which the current pool is associated. python-neutronclient-6.7.0/releasenotes/notes/add-tag-support-bad62d60ecc7075c.yaml0000666000175100017510000000137613232473350030062 0ustar zuulzuul00000000000000--- features: - | CLI support for tag. * The ``tag-add`` command sets a tag on the network resource. It also includes ``--resource-type``, ``--resource`` and ``--tag`` options. * The ``tag-replace`` command replaces tags on the network resource. It also includes ``--resource-type``, ``--resource`` and ``--tag`` options. More than one ``--tag`` options can be set. * The ``tag-remove`` command removes tags on the network resource. It also includes ``--resource-type``, ``--resource``, ``--tag`` and ``--all`` options. The ``--all`` option allow to remove all tags on the network resource. * The ``net-list`` command includes ``--tags``, ``--tags-any``, ``--not-tags`` and ``--not-tags-any`` options.python-neutronclient-6.7.0/releasenotes/notes/bulk-delete-support-94a353db08efec8d.yaml0000666000175100017510000000036713232473350030771 0ustar zuulzuul00000000000000--- features: - | CLI support for bulk delete. * By using this feature, multiple resource can be deleted using a single command. * Example: ``neutron router-delete router_a router_b`` deletes both router_a and router_b. python-neutronclient-6.7.0/releasenotes/notes/show-tenant-id-admin-listing-dc13ee7eb889d418.yaml0000666000175100017510000000041713232473350032403 0ustar zuulzuul00000000000000--- features: - Show tenant_id when ``*-list`` command is run by admin. In neutron the list operations by admin retrieve all resources from all tenants. It is not easy to distinguish resources without tenant_id. This feature is useful for admin operations. python-neutronclient-6.7.0/releasenotes/notes/fix-token-endpoint-auth-support-26bf7ee12e4ec833.yaml0000666000175100017510000000041013232473350033157 0ustar zuulzuul00000000000000--- fixes: - Fix `bug 1450414 `_ that authentication with via ``--os-token`` and ``--os-url`` options (or corresponding environment variables) does not work after keystone v3 API support. ././@LongLink0000000000000000000000000000015600000000000011217 Lustar 00000000000000python-neutronclient-6.7.0/releasenotes/notes/add-no-shared-option-to-qos-policy-update-56ac41fb3af7e309.yamlpython-neutronclient-6.7.0/releasenotes/notes/add-no-shared-option-to-qos-policy-update-56ac41fb3af70000666000175100017510000000037413232473350033337 0ustar zuulzuul00000000000000--- fixes: - | CLI support to set QoS policy as not shared if it was shared before. The ``qos-policy-update`` command include a ``--no-shared`` option. Closes `bug 1590942 `_. python-neutronclient-6.7.0/releasenotes/notes/fix-exception-typeerror-4.1.0-b37d738146575ed5.yaml0000666000175100017510000000027613232473350032040 0ustar zuulzuul00000000000000--- critical: - Fix a critical bug that when lazy translation is enabled NeutronClientException raises a TypeError (`bug 1552760 `_). python-neutronclient-6.7.0/releasenotes/notes/return-request-id-to-caller-15b1d23a4ddc27a3.yaml0000666000175100017510000000010313232473350032216 0ustar zuulzuul00000000000000--- features: - Neutron client returns 'x-openstack-request-id'. python-neutronclient-6.7.0/releasenotes/notes/add-osc-dynamic-routing-support-11130b2f440c0ac2.yaml0000666000175100017510000000011413232473350032716 0ustar zuulzuul00000000000000--- features: - | Add OSC plugin to support "Neutron Dynamic Routing" python-neutronclient-6.7.0/releasenotes/source/0000775000175100017510000000000013232473710021753 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/releasenotes/source/newton.rst0000666000175100017510000000023213232473350024016 0ustar zuulzuul00000000000000=================================== Newton Series Release Notes =================================== .. release-notes:: :branch: origin/stable/newton python-neutronclient-6.7.0/releasenotes/source/pike.rst0000666000175100017510000000021713232473350023437 0ustar zuulzuul00000000000000=================================== Pike Series Release Notes =================================== .. release-notes:: :branch: stable/pike python-neutronclient-6.7.0/releasenotes/source/_templates/0000775000175100017510000000000013232473710024110 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/releasenotes/source/_templates/.placeholder0000666000175100017510000000000013232473350026363 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/releasenotes/source/conf.py0000666000175100017510000001507013232473350023257 0ustar zuulzuul00000000000000# -*- coding: utf-8 -*- # 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. # Neutron Client Release Notes documentation build configuration file, # created by sphinx-quickstart on Tue Nov 3 17:40:50 2015. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # sys.path.insert(0, os.path.abspath('.')) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'reno.sphinxext', 'openstackdocstheme', ] # openstackdocstheme options repository_name = 'openstack/python-neutronclient' bug_project = 'python-neutronclient' bug_tag = 'doc' html_last_updated_fmt = '%Y-%m-%d %H:%M' # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. # source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'Neutron Client Release Notes' copyright = u'2015, Neutron Developers' # Release notes are version independent. # The full version, including alpha/beta/rc tags. release = '' # The short X.Y version. version = '' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: # today = '' # Else, today_fmt is used as the format for a strftime call. # today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [] # The reST default role (used for this markup: `text`) to use for all # documents. # default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. # add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). # add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. # show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. # keep_warnings = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'openstackdocs' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. # html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". # html_title = None # A shorter title for the navigation bar. Default is the same as html_title. # html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. # html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. # html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. # html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. # html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. # html_use_smartypants = True # Custom sidebar templates, maps document names to template names. # html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. # html_additional_pages = {} # If false, no module index is generated. # html_domain_indices = True # If false, no index is generated. # html_use_index = True # If true, the index is split into individual pages for each letter. # html_split_index = False # If true, links to the reST sources are added to the pages. # html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. # html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). # html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'NeutronReleaseNotesdoc' # -- Options for Internationalization output ------------------------------ locale_dirs = ['locale/'] python-neutronclient-6.7.0/releasenotes/source/ocata.rst0000666000175100017510000000023013232473350023571 0ustar zuulzuul00000000000000=================================== Ocata Series Release Notes =================================== .. release-notes:: :branch: origin/stable/ocata python-neutronclient-6.7.0/releasenotes/source/unreleased.rst0000666000175100017510000000016013232473350024633 0ustar zuulzuul00000000000000============================== Current Series Release Notes ============================== .. release-notes:: python-neutronclient-6.7.0/releasenotes/source/old_relnotes.rst0000666000175100017510000000133413232473350025201 0ustar zuulzuul00000000000000================= Old Release Notes ================= 2.2.2 ----- * improved support for listing a large number of filtered subnets * add --endpoint-type and OS_ENDPOINT_TYPE to shell client * made the publicURL the default endpoint instead of adminURL * add ability to update security group name (requires 2013.2-Havana or later) * add flake8 and pbr support for testing and building 2.2.0 ----- * add security group commands * add Lbaas commands * allow options put after positional arguments * add NVP queue and net gateway commands * add commands for agent management extensions * add commands for DHCP and L3 agents scheduling * support XML request format * support pagination options 2.0 ----- * support Neutron API 2.0 python-neutronclient-6.7.0/releasenotes/source/index.rst0000666000175100017510000000027613232473350023623 0ustar zuulzuul00000000000000============================== Neutron Client Release Notes ============================== .. toctree:: :maxdepth: 1 unreleased pike ocata newton mitaka old_relnotes python-neutronclient-6.7.0/releasenotes/source/mitaka.rst0000666000175100017510000000023213232473350023752 0ustar zuulzuul00000000000000=================================== Mitaka Series Release Notes =================================== .. release-notes:: :branch: origin/stable/mitaka python-neutronclient-6.7.0/releasenotes/source/_static/0000775000175100017510000000000013232473710023401 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/releasenotes/source/_static/.placeholder0000666000175100017510000000000013232473350025654 0ustar zuulzuul00000000000000python-neutronclient-6.7.0/tools/0000775000175100017510000000000013232473710017122 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/tools/neutron.bash_completion0000666000175100017510000000172713232473350023715 0ustar zuulzuul00000000000000_neutron_opts="" # lazy init _neutron_flags="" # lazy init _neutron_opts_exp="" # lazy init _neutron() { local cur prev nbc cflags COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" if [ "x$_neutron_opts" == "x" ] ; then nbc="`neutron bash-completion`" _neutron_opts="`echo "$nbc" | sed -e "s/--[a-z0-9_-]*//g" -e "s/[ ][ ]*/ /g"`" _neutron_flags="`echo " $nbc" | sed -e "s/ [^-][^-][a-z0-9_-]*//g" -e "s/[ ][ ]*/ /g"`" _neutron_opts_exp="`echo "$_neutron_opts" | sed -e "s/[ ]/|/g"`" fi if [[ " ${COMP_WORDS[@]} " =~ " "($_neutron_opts_exp)" " && "$prev" != "help" ]] ; then COMPLETION_CACHE=~/.neutronclient/*/*-cache cflags="$_neutron_flags "$(cat $COMPLETION_CACHE 2> /dev/null | tr '\n' ' ') COMPREPLY=($(compgen -W "${cflags}" -- ${cur})) else COMPREPLY=($(compgen -W "${_neutron_opts}" -- ${cur})) fi return 0 } complete -F _neutron neutron python-neutronclient-6.7.0/babel.cfg0000666000175100017510000000002113232473350017503 0ustar zuulzuul00000000000000[python: **.py] python-neutronclient-6.7.0/AUTHORS0000664000175100017510000002603013232473706017040 0ustar zuulzuul00000000000000Aaron Rosen Aaron Rosen Aaron-Zhang231 Abhishek Chanda Abhishek Kekane Abhishek Raut Abhishek Raut Adrien Vergé Akihiro MOTOKI Akihiro Motoki Akihiro Motoki Alessandro Pilotti Alessio Ababilov Alex Gaynor Amir Sadoughi Anand Shanmugam Andreas Jaeger Andreas Jaeger Andres Buraschi Andy McCrae Angus Lees Anindita Das Anita Kuno Ankur Gupta Armando Migliaccio Assaf Muller AvnishPal Ben Andrews Bernard Cafarelli Bertrand Lallau Bhuvan Arumugam Bob Kukura Brad Hall Bradley Klein Brandon Logan Brandon Palm Brian Haley Brian Waldon Cao Xuan Hoang Carl Baldwin Carl Baldwin Carlos D. Garza Carlos Goncalves Cedric Brandily Chris Krelle Chris Yeoh Christian Berendt Chuck Short Ciprian Cosma Clark Boylan Clenimar Filemon Clenimar Filemon Craig Tracey Cyril Roelandt Daire Ní Chatháin Dan Prince Dan Wendlandt Danny Choi Darek Smigiel (dasm) Dariusz Smigiel Davanum Srinivas Dean Troyer Deepthi V V Dina Belova Dirk Mueller Dmitry Kulishenko Dongcan Ye Doug Fish Doug Hellmann Doug Hellmann Doug Wiegley Drew Thorstensen Duan Jiong Elena Ezhova Eugene Nikanorov Evgeny Fedoruk Fei Long Wang Feng Xi Yan Flavio Percoco Gal Sagie Gary Kotton Gary Kotton Gábor Antal Haim Daniel Hangdong Zhang He Jie Xu He Yongli Henry Gessau Henry Gessau Hideki Saito Hirofumi Ichihara Hong Hui Xiao Hongbin Lu Hongbin Lu IWAMOTO Toshihiro Igor Duarte Cardoso Ihar Hrachyshka Ilya Shakhat Inessa Vasilevskaya Ionuț Arțăriși Irina Isaku Yamahata Jakub Libosvar James Arendt James E. Blair Jamie Lennox Jason Zhang Jaspinder Jaume Devesa Jeremy Liu Jeremy Stanley Jesse Proudman Jiajun Liu Joe Gordon John Davidge John Schwarz John Trowbridge Julien Danjou Justin Hammond Jyotsna K Jonathan Harker KATO Tomoyuki KC Wang Kenji Yasui Kevin Benton Kevin Benton Koteswara Rao Kelam Kyle Mestery Kyle Mestery LIU Yulong Lokesh S Lucas H. Xu M V P Nitesh Madhav Puri Manjeet Singh Bhatia Marcos Lobo Mark McClain Mark Rawlings Maru Newby Maru Newby Matt Riedemann Matthew Treinish Michael Johnson Miguel Lavalle Ming Yang Mitsuru Kanabuchi Mohankumar Monty Taylor Na Nachi Ueno Nachi Ueno Nandini Tata Nikola Dipanov Nikolas Hermanns Oleg Bondarev Ondřej Nový OpenStack Release Bot Paul Michali Paul Michali Phil Day PhilippeJ Pritesh Kothari Qin Zhao QunyingRan Rabi Mishra Rajesh Mohan Rakesh H S Ramanjaneya Reedip Reedip Banerjee Richard Theis Robert Collins Robert Li Rodion Tikunov Rodolfo Alonso Hernandez Roman Podolyaka Rudrajit Tapadar Russell Bryant Ryan Tidwell Saksham Varma Salvatore Orlando Salvatore Orlando Salvatore Orlando Sascha Peilicke Sascha Peilicke Sean Dague Sean Winn Sergio Cazzolato Shih-Hao Li SongmingYan Sourabh Patwardhan Sridhar Gaddam Stanislav Kudriashev Stanislaw Pitucha Stephen Balukoff Stephen Ma Steve Martinelli Sudhakar Babu Gariganti Sudipta Biswas Sumit Naiksatam Sushil Kumar Swaminathan Vasudevan Swapnil Kulkarni (coolsvap) Sylvain Afchain Sławek Kapłoński Takashi NATSUME Tang Chen Tatyana Leontovich Terry Howe Thiago Morello Thierry Carrez Thomas Herve Thomas Herve Thomas Morin Tin Lam Toshiaki Higuchi Ukesh Kumar Vasudevan Vic Howard Vikash082 Vikram Hosakote Wu Wenxiang Xu Han Peng Xuhan Peng Yaguang Tang Yalei Wang YangLei Yi Zhao Yohei Matsuhashi Yong Sheng Gong Yong Sheng Gong Yushiro FURUKAWA Yuuichi Fujioka Zang MingJie ZhaoBo Zhenguo Niu ZhiQiang Fan ZhiQiang Fan Zhongcheng Lao Zhongyue Luo Zuul armando-migliaccio arosen changzhi cshahani da52700 dekehn dongwenshuai gaofei gecong1973 gong yong sheng gongysh gongysh guiyanxing hobo.kengo huangtianhua ivan-zhu ji-xuepeng jichenjc karthik s kavithahr lilintan linwwu liu-sheng liujingzte liuqing liuweicai llg8212 mathieu-rohon minwang mohankumar_n nick.zhuyj nmagnezi preeti-mirji ptoohill1 reedip ricolin ricolin ritesh.arya ronak ronak-c shenjibiao shihanzhang shreeduth-awasthi shu-mutou sridhargaddam sthakkar takanorimiyagishi venkatamahesh vikram.choudhary watanabe.isao watsalya wengjiangang xiaosheng xiewj yong sheng gong yuyangbj zengfagao zhaojingjing0067370 zheng yin zhurong Édouard Thuleau python-neutronclient-6.7.0/python_neutronclient.egg-info/0000775000175100017510000000000013232473710023746 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/python_neutronclient.egg-info/not-zip-safe0000664000175100017510000000000113232473660026200 0ustar zuulzuul00000000000000 python-neutronclient-6.7.0/python_neutronclient.egg-info/PKG-INFO0000664000175100017510000000530613232473706025054 0ustar zuulzuul00000000000000Metadata-Version: 1.1 Name: python-neutronclient Version: 6.7.0 Summary: CLI and Client Library for OpenStack Networking Home-page: https://docs.openstack.org/python-neutronclient/latest/ Author: OpenStack Networking Project Author-email: openstack-dev@lists.openstack.org License: UNKNOWN Description-Content-Type: UNKNOWN Description: ======================== Team and repository tags ======================== .. image:: http://governance.openstack.org/badges/python-neutronclient.svg :target: http://governance.openstack.org/reference/tags/index.html .. Change things from this point on Python bindings to the Neutron API ================================== .. image:: https://img.shields.io/pypi/v/python-neutronclient.svg :target: https://pypi.python.org/pypi/python-neutronclient/ :alt: Latest Version .. image:: https://img.shields.io/pypi/dm/python-neutronclient.svg :target: https://pypi.python.org/pypi/python-neutronclient/ :alt: Downloads This is a client library for Neutron built on the Neutron API. It provides a Python API (the ``neutronclient`` module) and a command-line tool (``neutron``). * License: Apache License, Version 2.0 * `PyPi`_ - package installation * `Online Documentation`_ * `Launchpad project`_ - release management * `Blueprints`_ - feature specifications * `Bugs`_ - issue tracking * `Source`_ * `Developer's Guide`_ .. _PyPi: https://pypi.python.org/pypi/python-neutronclient .. _Online Documentation: https://docs.openstack.org/python-neutronclient/latest/ .. _Launchpad project: https://launchpad.net/python-neutronclient .. _Blueprints: https://blueprints.launchpad.net/python-neutronclient .. _Bugs: https://bugs.launchpad.net/python-neutronclient .. _Source: https://git.openstack.org/cgit/openstack/python-neutronclient .. _Developer's Guide: http://docs.openstack.org/infra/manual/developers.html Platform: UNKNOWN Classifier: Environment :: OpenStack Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.5 python-neutronclient-6.7.0/python_neutronclient.egg-info/requires.txt0000664000175100017510000000050413232473706026352 0ustar zuulzuul00000000000000pbr!=2.1.0,>=2.0.0 cliff!=2.9.0,>=2.8.0 debtcollector>=1.2.0 iso8601>=0.1.11 netaddr>=0.7.18 osc-lib>=1.8.0 oslo.i18n>=3.15.3 oslo.serialization!=2.19.1,>=2.18.0 oslo.utils>=3.33.0 os-client-config>=1.28.0 keystoneauth1>=3.3.0 python-keystoneclient>=3.8.0 requests>=2.14.2 simplejson>=3.5.1 six>=1.10.0 Babel!=2.4.0,>=2.3.4 python-neutronclient-6.7.0/python_neutronclient.egg-info/SOURCES.txt0000664000175100017510000004053013232473710025634 0ustar zuulzuul00000000000000.coveragerc .pylintrc .testr.conf AUTHORS CONTRIBUTING.rst ChangeLog HACKING.rst LICENSE README.rst babel.cfg neutron_test.sh requirements.txt setup.cfg setup.py test-requirements.txt tox.ini doc/source/conf.py doc/source/index.rst doc/source/cli/index.rst doc/source/cli/neutron-reference.rst doc/source/cli/neutron.rst doc/source/cli/osc_plugins.rst doc/source/cli/osc/v2/bgp-dynamic-routing.rst doc/source/cli/osc/v2/firewall-group.rst doc/source/cli/osc/v2/firewall-policy.rst doc/source/cli/osc/v2/firewall-rule.rst doc/source/cli/osc/v2/network-log.rst doc/source/cli/osc/v2/network-trunk.rst doc/source/cli/osc/v2/networking-bgpvpn.rst doc/source/cli/osc/v2/networking-sfc.rst doc/source/cli/osc/v2/vpn-endpoint-group.rst doc/source/cli/osc/v2/vpn-ike-policy.rst doc/source/cli/osc/v2/vpn-ipsec-policy.rst doc/source/cli/osc/v2/vpn-ipsec-site-connection.rst doc/source/cli/osc/v2/vpn-service.rst doc/source/contributor/cli_option_guideline.rst doc/source/contributor/client_command_extensions.rst doc/source/contributor/index.rst doc/source/contributor/transition_to_osc.rst doc/source/reference/index.rst neutronclient/__init__.py neutronclient/_i18n.py neutronclient/client.py neutronclient/cliff_sphinxext.py neutronclient/shell.py neutronclient/version.py neutronclient/common/__init__.py neutronclient/common/clientmanager.py neutronclient/common/constants.py neutronclient/common/exceptions.py neutronclient/common/extension.py neutronclient/common/serializer.py neutronclient/common/utils.py neutronclient/common/validators.py neutronclient/neutron/__init__.py neutronclient/neutron/client.py neutronclient/neutron/v2_0/__init__.py neutronclient/neutron/v2_0/address_scope.py neutronclient/neutron/v2_0/agent.py neutronclient/neutron/v2_0/agentscheduler.py neutronclient/neutron/v2_0/auto_allocated_topology.py neutronclient/neutron/v2_0/availability_zone.py neutronclient/neutron/v2_0/dns.py neutronclient/neutron/v2_0/extension.py neutronclient/neutron/v2_0/floatingip.py neutronclient/neutron/v2_0/metering.py neutronclient/neutron/v2_0/network.py neutronclient/neutron/v2_0/network_ip_availability.py neutronclient/neutron/v2_0/port.py neutronclient/neutron/v2_0/purge.py neutronclient/neutron/v2_0/quota.py neutronclient/neutron/v2_0/rbac.py neutronclient/neutron/v2_0/router.py neutronclient/neutron/v2_0/securitygroup.py neutronclient/neutron/v2_0/servicetype.py neutronclient/neutron/v2_0/subnet.py neutronclient/neutron/v2_0/subnetpool.py neutronclient/neutron/v2_0/tag.py neutronclient/neutron/v2_0/bgp/__init__.py neutronclient/neutron/v2_0/bgp/dragentscheduler.py neutronclient/neutron/v2_0/bgp/peer.py neutronclient/neutron/v2_0/bgp/speaker.py neutronclient/neutron/v2_0/contrib/__init__.py neutronclient/neutron/v2_0/contrib/_fox_sockets.py neutronclient/neutron/v2_0/flavor/__init__.py neutronclient/neutron/v2_0/flavor/flavor.py neutronclient/neutron/v2_0/flavor/flavor_profile.py neutronclient/neutron/v2_0/fw/__init__.py neutronclient/neutron/v2_0/fw/firewall.py neutronclient/neutron/v2_0/fw/firewallpolicy.py neutronclient/neutron/v2_0/fw/firewallrule.py neutronclient/neutron/v2_0/lb/__init__.py neutronclient/neutron/v2_0/lb/healthmonitor.py neutronclient/neutron/v2_0/lb/member.py neutronclient/neutron/v2_0/lb/pool.py neutronclient/neutron/v2_0/lb/vip.py neutronclient/neutron/v2_0/lb/v2/__init__.py neutronclient/neutron/v2_0/lb/v2/healthmonitor.py neutronclient/neutron/v2_0/lb/v2/l7policy.py neutronclient/neutron/v2_0/lb/v2/l7rule.py neutronclient/neutron/v2_0/lb/v2/listener.py neutronclient/neutron/v2_0/lb/v2/loadbalancer.py neutronclient/neutron/v2_0/lb/v2/member.py neutronclient/neutron/v2_0/lb/v2/pool.py neutronclient/neutron/v2_0/qos/__init__.py neutronclient/neutron/v2_0/qos/bandwidth_limit_rule.py neutronclient/neutron/v2_0/qos/dscp_marking_rule.py neutronclient/neutron/v2_0/qos/minimum_bandwidth_rule.py neutronclient/neutron/v2_0/qos/policy.py neutronclient/neutron/v2_0/qos/rule.py neutronclient/neutron/v2_0/vpn/__init__.py neutronclient/neutron/v2_0/vpn/endpoint_group.py neutronclient/neutron/v2_0/vpn/ikepolicy.py neutronclient/neutron/v2_0/vpn/ipsec_site_connection.py neutronclient/neutron/v2_0/vpn/ipsecpolicy.py neutronclient/neutron/v2_0/vpn/utils.py neutronclient/neutron/v2_0/vpn/vpnservice.py neutronclient/osc/__init__.py neutronclient/osc/plugin.py neutronclient/osc/utils.py neutronclient/osc/v2/__init__.py neutronclient/osc/v2/utils.py neutronclient/osc/v2/dynamic_routing/__init__.py neutronclient/osc/v2/dynamic_routing/bgp_dragent.py neutronclient/osc/v2/dynamic_routing/bgp_peer.py neutronclient/osc/v2/dynamic_routing/bgp_speaker.py neutronclient/osc/v2/dynamic_routing/constants.py neutronclient/osc/v2/fwaas/__init__.py neutronclient/osc/v2/fwaas/constants.py neutronclient/osc/v2/fwaas/firewallgroup.py neutronclient/osc/v2/fwaas/firewallpolicy.py neutronclient/osc/v2/fwaas/firewallrule.py neutronclient/osc/v2/lbaas/__init__.py neutronclient/osc/v2/logging/__init__.py neutronclient/osc/v2/logging/network_log.py neutronclient/osc/v2/networking_bgpvpn/__init__.py neutronclient/osc/v2/networking_bgpvpn/bgpvpn.py neutronclient/osc/v2/networking_bgpvpn/constants.py neutronclient/osc/v2/networking_bgpvpn/network_association.py neutronclient/osc/v2/networking_bgpvpn/port_association.py neutronclient/osc/v2/networking_bgpvpn/resource_association.py neutronclient/osc/v2/networking_bgpvpn/router_association.py neutronclient/osc/v2/sfc/__init__.py neutronclient/osc/v2/sfc/sfc_flow_classifier.py neutronclient/osc/v2/sfc/sfc_port_chain.py neutronclient/osc/v2/sfc/sfc_port_pair.py neutronclient/osc/v2/sfc/sfc_port_pair_group.py neutronclient/osc/v2/sfc/sfc_service_graph.py neutronclient/osc/v2/trunk/__init__.py neutronclient/osc/v2/trunk/network_trunk.py neutronclient/osc/v2/vpnaas/__init__.py neutronclient/osc/v2/vpnaas/endpoint_group.py neutronclient/osc/v2/vpnaas/ikepolicy.py neutronclient/osc/v2/vpnaas/ipsec_site_connection.py neutronclient/osc/v2/vpnaas/ipsecpolicy.py neutronclient/osc/v2/vpnaas/utils.py neutronclient/osc/v2/vpnaas/vpnservice.py neutronclient/tests/__init__.py neutronclient/tests/functional/__init__.py neutronclient/tests/functional/base.py neutronclient/tests/functional/adv-svcs/__init__.py neutronclient/tests/functional/adv-svcs/test_readonly_neutron_fwaas.py neutronclient/tests/functional/adv-svcs/test_readonly_neutron_vpn.py neutronclient/tests/functional/core/__init__.py neutronclient/tests/functional/core/test_cli_formatter.py neutronclient/tests/functional/core/test_clientlib.py neutronclient/tests/functional/core/test_common.py neutronclient/tests/functional/core/test_purge.py neutronclient/tests/functional/core/test_readonly_neutron.py neutronclient/tests/functional/core/test_subnet_create.py neutronclient/tests/functional/hooks/fwaas neutronclient/tests/functional/hooks/gate_hook.sh neutronclient/tests/functional/hooks/post_test_hook.sh neutronclient/tests/functional/hooks/vpnaas neutronclient/tests/unit/__init__.py neutronclient/tests/unit/test_auto_allocated_topology.py neutronclient/tests/unit/test_casual_args.py neutronclient/tests/unit/test_cli20.py neutronclient/tests/unit/test_cli20_address_scope.py neutronclient/tests/unit/test_cli20_agents.py neutronclient/tests/unit/test_cli20_agentschedulers.py neutronclient/tests/unit/test_cli20_az.py neutronclient/tests/unit/test_cli20_extensions.py neutronclient/tests/unit/test_cli20_floatingips.py neutronclient/tests/unit/test_cli20_metering.py neutronclient/tests/unit/test_cli20_network.py neutronclient/tests/unit/test_cli20_network_ip_availability.py neutronclient/tests/unit/test_cli20_port.py neutronclient/tests/unit/test_cli20_purge.py neutronclient/tests/unit/test_cli20_rbac.py neutronclient/tests/unit/test_cli20_router.py neutronclient/tests/unit/test_cli20_securitygroup.py neutronclient/tests/unit/test_cli20_servicetype.py neutronclient/tests/unit/test_cli20_subnet.py neutronclient/tests/unit/test_cli20_subnetpool.py neutronclient/tests/unit/test_cli20_tag.py neutronclient/tests/unit/test_client_extension.py neutronclient/tests/unit/test_command_meta.py neutronclient/tests/unit/test_exceptions.py neutronclient/tests/unit/test_http.py neutronclient/tests/unit/test_name_or_id.py neutronclient/tests/unit/test_quota.py neutronclient/tests/unit/test_shell.py neutronclient/tests/unit/test_utils.py neutronclient/tests/unit/test_validators.py neutronclient/tests/unit/bgp/__init__.py neutronclient/tests/unit/bgp/test_cli20_dragentscheduler.py neutronclient/tests/unit/bgp/test_cli20_peer.py neutronclient/tests/unit/bgp/test_cli20_speaker.py neutronclient/tests/unit/flavor/__init__.py neutronclient/tests/unit/flavor/test_cli20_flavor.py neutronclient/tests/unit/flavor/test_cli20_flavor_profile.py neutronclient/tests/unit/fw/__init__.py neutronclient/tests/unit/fw/test_cli20_firewall.py neutronclient/tests/unit/fw/test_cli20_firewallpolicy.py neutronclient/tests/unit/fw/test_cli20_firewallrule.py neutronclient/tests/unit/lb/__init__.py neutronclient/tests/unit/lb/test_cli20_healthmonitor.py neutronclient/tests/unit/lb/test_cli20_member.py neutronclient/tests/unit/lb/test_cli20_pool.py neutronclient/tests/unit/lb/test_cli20_vip.py neutronclient/tests/unit/lb/v2/__init__.py neutronclient/tests/unit/lb/v2/test_cli20_healthmonitor.py neutronclient/tests/unit/lb/v2/test_cli20_l7policy.py neutronclient/tests/unit/lb/v2/test_cli20_l7rule.py neutronclient/tests/unit/lb/v2/test_cli20_listener.py neutronclient/tests/unit/lb/v2/test_cli20_loadbalancer.py neutronclient/tests/unit/lb/v2/test_cli20_member.py neutronclient/tests/unit/lb/v2/test_cli20_pool.py neutronclient/tests/unit/osc/__init__.py neutronclient/tests/unit/osc/test_utils.py neutronclient/tests/unit/osc/v2/__init__.py neutronclient/tests/unit/osc/v2/fakes.py neutronclient/tests/unit/osc/v2/dynamic_routing/__init__.py neutronclient/tests/unit/osc/v2/dynamic_routing/fakes.py neutronclient/tests/unit/osc/v2/dynamic_routing/test_bgp_peer.py neutronclient/tests/unit/osc/v2/dynamic_routing/test_bgp_speaker.py neutronclient/tests/unit/osc/v2/fwaas/__init__.py neutronclient/tests/unit/osc/v2/fwaas/common.py neutronclient/tests/unit/osc/v2/fwaas/fakes.py neutronclient/tests/unit/osc/v2/fwaas/test_firewallgroup.py neutronclient/tests/unit/osc/v2/fwaas/test_firewallpolicy.py neutronclient/tests/unit/osc/v2/fwaas/test_firewallrule.py neutronclient/tests/unit/osc/v2/lbaas/__init__.py neutronclient/tests/unit/osc/v2/logging/__init__.py neutronclient/tests/unit/osc/v2/logging/fakes.py neutronclient/tests/unit/osc/v2/logging/test_network_log.py neutronclient/tests/unit/osc/v2/networking_bgpvpn/__init__.py neutronclient/tests/unit/osc/v2/networking_bgpvpn/fakes.py neutronclient/tests/unit/osc/v2/networking_bgpvpn/test_bgpvpn.py neutronclient/tests/unit/osc/v2/networking_bgpvpn/test_resource_association.py neutronclient/tests/unit/osc/v2/sfc/__init__.py neutronclient/tests/unit/osc/v2/sfc/fakes.py neutronclient/tests/unit/osc/v2/sfc/test_flow_classifier.py neutronclient/tests/unit/osc/v2/sfc/test_port_chain.py neutronclient/tests/unit/osc/v2/sfc/test_port_pair.py neutronclient/tests/unit/osc/v2/sfc/test_port_pair_group.py neutronclient/tests/unit/osc/v2/sfc/test_service_graph.py neutronclient/tests/unit/osc/v2/trunk/__init__.py neutronclient/tests/unit/osc/v2/trunk/fakes.py neutronclient/tests/unit/osc/v2/trunk/test_network_trunk.py neutronclient/tests/unit/osc/v2/vpnaas/__init__.py neutronclient/tests/unit/osc/v2/vpnaas/common.py neutronclient/tests/unit/osc/v2/vpnaas/fakes.py neutronclient/tests/unit/osc/v2/vpnaas/test_endpoint_group.py neutronclient/tests/unit/osc/v2/vpnaas/test_ikepolicy.py neutronclient/tests/unit/osc/v2/vpnaas/test_ipsec_site_connection.py neutronclient/tests/unit/osc/v2/vpnaas/test_ipsecpolicy.py neutronclient/tests/unit/osc/v2/vpnaas/test_vpnservice.py neutronclient/tests/unit/qos/__init__.py neutronclient/tests/unit/qos/test_cli20_bandwidth_limit_rule.py neutronclient/tests/unit/qos/test_cli20_dscp_marking_rule.py neutronclient/tests/unit/qos/test_cli20_minimum_bandwidth_rule.py neutronclient/tests/unit/qos/test_cli20_policy.py neutronclient/tests/unit/qos/test_cli20_rule.py neutronclient/tests/unit/vpn/__init__.py neutronclient/tests/unit/vpn/test_cli20_endpoint_group.py neutronclient/tests/unit/vpn/test_cli20_ikepolicy.py neutronclient/tests/unit/vpn/test_cli20_ipsec_site_connection.py neutronclient/tests/unit/vpn/test_cli20_ipsecpolicy.py neutronclient/tests/unit/vpn/test_cli20_vpnservice.py neutronclient/tests/unit/vpn/test_utils.py neutronclient/v2_0/__init__.py neutronclient/v2_0/client.py python_neutronclient.egg-info/PKG-INFO python_neutronclient.egg-info/SOURCES.txt python_neutronclient.egg-info/dependency_links.txt python_neutronclient.egg-info/entry_points.txt python_neutronclient.egg-info/not-zip-safe python_neutronclient.egg-info/pbr.json python_neutronclient.egg-info/requires.txt python_neutronclient.egg-info/top_level.txt releasenotes/notes/.placeholder releasenotes/notes/Define-IpAddressAlreadyAllocatedClient-exception-e8600ca5ba1c7f45.yaml releasenotes/notes/add-auto-allocated-topology-delete-aaccd60bd0f2e7b2.yaml releasenotes/notes/add-get-me-a-network-5ab2d60bf6f257b1.yaml releasenotes/notes/add-l7-content-policies-capability-0f17cd06f044c83c.yaml releasenotes/notes/add-lb-status-tree-723f23c09617de3b.yaml releasenotes/notes/add-neutron-purge-a89e3d1179dce4b1.yaml releasenotes/notes/add-new-session-clear-option-3c0b78ebc133a10c.yaml releasenotes/notes/add-no-shared-option-to-qos-policy-update-56ac41fb3af7e309.yaml releasenotes/notes/add-osc-dynamic-routing-support-11130b2f440c0ac2.yaml releasenotes/notes/add-osc-trunk-commands-7e77283a369729c5.yaml releasenotes/notes/add-quota-default-show-c2ab35b791dcdcbc.yaml releasenotes/notes/add-rbac-qos-type-support-c42e31fadd7b.yaml releasenotes/notes/add-service-graph-ce4a25b3e32d70a6.yaml releasenotes/notes/add-sfc-commands.yaml releasenotes/notes/add-shared-pools-support-6f79b565afad3e47.yaml releasenotes/notes/add-tag-support-bad62d60ecc7075c.yaml releasenotes/notes/availability-zone-support-8e66f55e46b7ef9a.yaml releasenotes/notes/bgp-dynamic-routing-b97a1c81d3007049.yaml releasenotes/notes/bug-1676922-81341b70bc6f055a.yaml releasenotes/notes/bulk-delete-support-94a353db08efec8d.yaml releasenotes/notes/default-subnetpool-support-c0d34870e9d3e814.yaml releasenotes/notes/deprecate-cli-7be1123817969439.yaml releasenotes/notes/direct-physical-vnic-port-create-736d8b2600faf22b.yaml releasenotes/notes/docs-improvements-17e31babe38e2962.yaml releasenotes/notes/drop-nuage-commands-df10aab6ccd77ed2.yaml releasenotes/notes/drop-xml-support-41babecb1784d996.yaml releasenotes/notes/dscp_qos-4a26d3c0363624b0.yaml releasenotes/notes/fix-exception-typeerror-4.1.0-b37d738146575ed5.yaml releasenotes/notes/fix-quota-update-zero-args-d596c4169c2d2e30.yaml releasenotes/notes/fix-rbac-create-command-dd40a474f0f092db.yaml releasenotes/notes/fix-token-endpoint-auth-support-26bf7ee12e4ec833.yaml releasenotes/notes/global_request_id-56856a93b982a6b3.yaml releasenotes/notes/keystonev3-7f9ede9c21b30841.yaml releasenotes/notes/log-request-id-64bef955b8292c18.yaml releasenotes/notes/network-ip-availability-ac9a462f42fe9db4.yaml releasenotes/notes/osprofiler-support-9ba539761ae437e9.yaml releasenotes/notes/qos_minimum_bandwidth-dc4adb23c51de30b.yaml releasenotes/notes/quota-update-for-LB-b21e7bc9e4a10f3e.yaml releasenotes/notes/quota-update-for-rbac-192a8e65bf481941.yaml releasenotes/notes/relnotes-from-3.0.0-d7306f5af5e3868d.yaml releasenotes/notes/remove-case-dependency-773ccb3237c38e81.yaml releasenotes/notes/remove-deprecated-option-b53f5d7e6a16ce95.yaml releasenotes/notes/return-request-id-to-caller-15b1d23a4ddc27a3.yaml releasenotes/notes/sfc-tap-service-function-support-a05242f25f79066b.yaml releasenotes/notes/show-tenant-id-admin-listing-dc13ee7eb889d418.yaml releasenotes/notes/start-using-reno-9081b3e4c1951fdb.yaml releasenotes/notes/support-bgpvpn-route-control-aeda3e698486f73b.yaml releasenotes/notes/support-fwaasv2-cli-7f21676c551f8ae0.yaml releasenotes/notes/support-logging-cli-cd02d3bb03367106.yaml releasenotes/notes/support-networking-bgpvpn-cli-fdd0cc3a5b14983d.yaml releasenotes/notes/support-vni-in-networking-bgpvpn-cli-d284b73b40b79495.yaml releasenotes/notes/support-vpnaas-cli-9478fb7cfe603e26.yaml releasenotes/notes/tag-support-subnet-port-subnetpool-router-6250ec4714ee8690.yaml releasenotes/source/conf.py releasenotes/source/index.rst releasenotes/source/mitaka.rst releasenotes/source/newton.rst releasenotes/source/ocata.rst releasenotes/source/old_relnotes.rst releasenotes/source/pike.rst releasenotes/source/unreleased.rst releasenotes/source/_static/.placeholder releasenotes/source/_templates/.placeholder tools/neutron.bash_completionpython-neutronclient-6.7.0/python_neutronclient.egg-info/dependency_links.txt0000664000175100017510000000000113232473706030021 0ustar zuulzuul00000000000000 python-neutronclient-6.7.0/python_neutronclient.egg-info/top_level.txt0000664000175100017510000000001613232473706026502 0ustar zuulzuul00000000000000neutronclient python-neutronclient-6.7.0/python_neutronclient.egg-info/entry_points.txt0000664000175100017510000007472713232473706027272 0ustar zuulzuul00000000000000[console_scripts] neutron = neutronclient.shell:main [neutron.cli.v2] address-scope-create = neutronclient.neutron.v2_0.address_scope:CreateAddressScope address-scope-delete = neutronclient.neutron.v2_0.address_scope:DeleteAddressScope address-scope-list = neutronclient.neutron.v2_0.address_scope:ListAddressScope address-scope-show = neutronclient.neutron.v2_0.address_scope:ShowAddressScope address-scope-update = neutronclient.neutron.v2_0.address_scope:UpdateAddressScope agent-delete = neutronclient.neutron.v2_0.agent:DeleteAgent agent-list = neutronclient.neutron.v2_0.agent:ListAgent agent-show = neutronclient.neutron.v2_0.agent:ShowAgent agent-update = neutronclient.neutron.v2_0.agent:UpdateAgent auto-allocated-topology-delete = neutronclient.neutron.v2_0.auto_allocated_topology:DeleteAutoAllocatedTopology auto-allocated-topology-show = neutronclient.neutron.v2_0.auto_allocated_topology:ShowAutoAllocatedTopology availability-zone-list = neutronclient.neutron.v2_0.availability_zone:ListAvailabilityZone bash-completion = neutronclient.shell:BashCompletionCommand bgp-dragent-list-hosting-speaker = neutronclient.neutron.v2_0.bgp.dragentscheduler:ListDRAgentsHostingBGPSpeaker bgp-dragent-speaker-add = neutronclient.neutron.v2_0.bgp.dragentscheduler:AddBGPSpeakerToDRAgent bgp-dragent-speaker-remove = neutronclient.neutron.v2_0.bgp.dragentscheduler:RemoveBGPSpeakerFromDRAgent bgp-peer-create = neutronclient.neutron.v2_0.bgp.peer:CreatePeer bgp-peer-delete = neutronclient.neutron.v2_0.bgp.peer:DeletePeer bgp-peer-list = neutronclient.neutron.v2_0.bgp.peer:ListPeers bgp-peer-show = neutronclient.neutron.v2_0.bgp.peer:ShowPeer bgp-peer-update = neutronclient.neutron.v2_0.bgp.peer:UpdatePeer bgp-speaker-advertiseroute-list = neutronclient.neutron.v2_0.bgp.speaker:ListRoutesAdvertisedBySpeaker bgp-speaker-create = neutronclient.neutron.v2_0.bgp.speaker:CreateSpeaker bgp-speaker-delete = neutronclient.neutron.v2_0.bgp.speaker:DeleteSpeaker bgp-speaker-list = neutronclient.neutron.v2_0.bgp.speaker:ListSpeakers bgp-speaker-list-on-dragent = neutronclient.neutron.v2_0.bgp.dragentscheduler:ListBGPSpeakersOnDRAgent bgp-speaker-network-add = neutronclient.neutron.v2_0.bgp.speaker:AddNetworkToSpeaker bgp-speaker-network-remove = neutronclient.neutron.v2_0.bgp.speaker:RemoveNetworkFromSpeaker bgp-speaker-peer-add = neutronclient.neutron.v2_0.bgp.speaker:AddPeerToSpeaker bgp-speaker-peer-remove = neutronclient.neutron.v2_0.bgp.speaker:RemovePeerFromSpeaker bgp-speaker-show = neutronclient.neutron.v2_0.bgp.speaker:ShowSpeaker bgp-speaker-update = neutronclient.neutron.v2_0.bgp.speaker:UpdateSpeaker dhcp-agent-list-hosting-net = neutronclient.neutron.v2_0.agentscheduler:ListDhcpAgentsHostingNetwork dhcp-agent-network-add = neutronclient.neutron.v2_0.agentscheduler:AddNetworkToDhcpAgent dhcp-agent-network-remove = neutronclient.neutron.v2_0.agentscheduler:RemoveNetworkFromDhcpAgent ext-list = neutronclient.neutron.v2_0.extension:ListExt ext-show = neutronclient.neutron.v2_0.extension:ShowExt firewall-create = neutronclient.neutron.v2_0.fw.firewall:CreateFirewall firewall-delete = neutronclient.neutron.v2_0.fw.firewall:DeleteFirewall firewall-list = neutronclient.neutron.v2_0.fw.firewall:ListFirewall firewall-policy-create = neutronclient.neutron.v2_0.fw.firewallpolicy:CreateFirewallPolicy firewall-policy-delete = neutronclient.neutron.v2_0.fw.firewallpolicy:DeleteFirewallPolicy firewall-policy-insert-rule = neutronclient.neutron.v2_0.fw.firewallpolicy:FirewallPolicyInsertRule firewall-policy-list = neutronclient.neutron.v2_0.fw.firewallpolicy:ListFirewallPolicy firewall-policy-remove-rule = neutronclient.neutron.v2_0.fw.firewallpolicy:FirewallPolicyRemoveRule firewall-policy-show = neutronclient.neutron.v2_0.fw.firewallpolicy:ShowFirewallPolicy firewall-policy-update = neutronclient.neutron.v2_0.fw.firewallpolicy:UpdateFirewallPolicy firewall-rule-create = neutronclient.neutron.v2_0.fw.firewallrule:CreateFirewallRule firewall-rule-delete = neutronclient.neutron.v2_0.fw.firewallrule:DeleteFirewallRule firewall-rule-list = neutronclient.neutron.v2_0.fw.firewallrule:ListFirewallRule firewall-rule-show = neutronclient.neutron.v2_0.fw.firewallrule:ShowFirewallRule firewall-rule-update = neutronclient.neutron.v2_0.fw.firewallrule:UpdateFirewallRule firewall-show = neutronclient.neutron.v2_0.fw.firewall:ShowFirewall firewall-update = neutronclient.neutron.v2_0.fw.firewall:UpdateFirewall flavor-associate = neutronclient.neutron.v2_0.flavor.flavor:AssociateFlavor flavor-create = neutronclient.neutron.v2_0.flavor.flavor:CreateFlavor flavor-delete = neutronclient.neutron.v2_0.flavor.flavor:DeleteFlavor flavor-disassociate = neutronclient.neutron.v2_0.flavor.flavor:DisassociateFlavor flavor-list = neutronclient.neutron.v2_0.flavor.flavor:ListFlavor flavor-profile-create = neutronclient.neutron.v2_0.flavor.flavor_profile:CreateFlavorProfile flavor-profile-delete = neutronclient.neutron.v2_0.flavor.flavor_profile:DeleteFlavorProfile flavor-profile-list = neutronclient.neutron.v2_0.flavor.flavor_profile:ListFlavorProfile flavor-profile-show = neutronclient.neutron.v2_0.flavor.flavor_profile:ShowFlavorProfile flavor-profile-update = neutronclient.neutron.v2_0.flavor.flavor_profile:UpdateFlavorProfile flavor-show = neutronclient.neutron.v2_0.flavor.flavor:ShowFlavor flavor-update = neutronclient.neutron.v2_0.flavor.flavor:UpdateFlavor floatingip-associate = neutronclient.neutron.v2_0.floatingip:AssociateFloatingIP floatingip-create = neutronclient.neutron.v2_0.floatingip:CreateFloatingIP floatingip-delete = neutronclient.neutron.v2_0.floatingip:DeleteFloatingIP floatingip-disassociate = neutronclient.neutron.v2_0.floatingip:DisassociateFloatingIP floatingip-list = neutronclient.neutron.v2_0.floatingip:ListFloatingIP floatingip-show = neutronclient.neutron.v2_0.floatingip:ShowFloatingIP ipsec-site-connection-create = neutronclient.neutron.v2_0.vpn.ipsec_site_connection:CreateIPsecSiteConnection ipsec-site-connection-delete = neutronclient.neutron.v2_0.vpn.ipsec_site_connection:DeleteIPsecSiteConnection ipsec-site-connection-list = neutronclient.neutron.v2_0.vpn.ipsec_site_connection:ListIPsecSiteConnection ipsec-site-connection-show = neutronclient.neutron.v2_0.vpn.ipsec_site_connection:ShowIPsecSiteConnection ipsec-site-connection-update = neutronclient.neutron.v2_0.vpn.ipsec_site_connection:UpdateIPsecSiteConnection l3-agent-list-hosting-router = neutronclient.neutron.v2_0.agentscheduler:ListL3AgentsHostingRouter l3-agent-router-add = neutronclient.neutron.v2_0.agentscheduler:AddRouterToL3Agent l3-agent-router-remove = neutronclient.neutron.v2_0.agentscheduler:RemoveRouterFromL3Agent lb-agent-hosting-pool = neutronclient.neutron.v2_0.agentscheduler:GetLbaasAgentHostingPool lb-healthmonitor-associate = neutronclient.neutron.v2_0.lb.healthmonitor:AssociateHealthMonitor lb-healthmonitor-create = neutronclient.neutron.v2_0.lb.healthmonitor:CreateHealthMonitor lb-healthmonitor-delete = neutronclient.neutron.v2_0.lb.healthmonitor:DeleteHealthMonitor lb-healthmonitor-disassociate = neutronclient.neutron.v2_0.lb.healthmonitor:DisassociateHealthMonitor lb-healthmonitor-list = neutronclient.neutron.v2_0.lb.healthmonitor:ListHealthMonitor lb-healthmonitor-show = neutronclient.neutron.v2_0.lb.healthmonitor:ShowHealthMonitor lb-healthmonitor-update = neutronclient.neutron.v2_0.lb.healthmonitor:UpdateHealthMonitor lb-member-create = neutronclient.neutron.v2_0.lb.member:CreateMember lb-member-delete = neutronclient.neutron.v2_0.lb.member:DeleteMember lb-member-list = neutronclient.neutron.v2_0.lb.member:ListMember lb-member-show = neutronclient.neutron.v2_0.lb.member:ShowMember lb-member-update = neutronclient.neutron.v2_0.lb.member:UpdateMember lb-pool-create = neutronclient.neutron.v2_0.lb.pool:CreatePool lb-pool-delete = neutronclient.neutron.v2_0.lb.pool:DeletePool lb-pool-list = neutronclient.neutron.v2_0.lb.pool:ListPool lb-pool-list-on-agent = neutronclient.neutron.v2_0.agentscheduler:ListPoolsOnLbaasAgent lb-pool-show = neutronclient.neutron.v2_0.lb.pool:ShowPool lb-pool-stats = neutronclient.neutron.v2_0.lb.pool:RetrievePoolStats lb-pool-update = neutronclient.neutron.v2_0.lb.pool:UpdatePool lb-vip-create = neutronclient.neutron.v2_0.lb.vip:CreateVip lb-vip-delete = neutronclient.neutron.v2_0.lb.vip:DeleteVip lb-vip-list = neutronclient.neutron.v2_0.lb.vip:ListVip lb-vip-show = neutronclient.neutron.v2_0.lb.vip:ShowVip lb-vip-update = neutronclient.neutron.v2_0.lb.vip:UpdateVip lbaas-agent-hosting-loadbalancer = neutronclient.neutron.v2_0.agentscheduler:GetLbaasAgentHostingLoadBalancer lbaas-healthmonitor-create = neutronclient.neutron.v2_0.lb.v2.healthmonitor:CreateHealthMonitor lbaas-healthmonitor-delete = neutronclient.neutron.v2_0.lb.v2.healthmonitor:DeleteHealthMonitor lbaas-healthmonitor-list = neutronclient.neutron.v2_0.lb.v2.healthmonitor:ListHealthMonitor lbaas-healthmonitor-show = neutronclient.neutron.v2_0.lb.v2.healthmonitor:ShowHealthMonitor lbaas-healthmonitor-update = neutronclient.neutron.v2_0.lb.v2.healthmonitor:UpdateHealthMonitor lbaas-l7policy-create = neutronclient.neutron.v2_0.lb.v2.l7policy:CreateL7Policy lbaas-l7policy-delete = neutronclient.neutron.v2_0.lb.v2.l7policy:DeleteL7Policy lbaas-l7policy-list = neutronclient.neutron.v2_0.lb.v2.l7policy:ListL7Policy lbaas-l7policy-show = neutronclient.neutron.v2_0.lb.v2.l7policy:ShowL7Policy lbaas-l7policy-update = neutronclient.neutron.v2_0.lb.v2.l7policy:UpdateL7Policy lbaas-l7rule-create = neutronclient.neutron.v2_0.lb.v2.l7rule:CreateL7Rule lbaas-l7rule-delete = neutronclient.neutron.v2_0.lb.v2.l7rule:DeleteL7Rule lbaas-l7rule-list = neutronclient.neutron.v2_0.lb.v2.l7rule:ListL7Rule lbaas-l7rule-show = neutronclient.neutron.v2_0.lb.v2.l7rule:ShowL7Rule lbaas-l7rule-update = neutronclient.neutron.v2_0.lb.v2.l7rule:UpdateL7Rule lbaas-listener-create = neutronclient.neutron.v2_0.lb.v2.listener:CreateListener lbaas-listener-delete = neutronclient.neutron.v2_0.lb.v2.listener:DeleteListener lbaas-listener-list = neutronclient.neutron.v2_0.lb.v2.listener:ListListener lbaas-listener-show = neutronclient.neutron.v2_0.lb.v2.listener:ShowListener lbaas-listener-update = neutronclient.neutron.v2_0.lb.v2.listener:UpdateListener lbaas-loadbalancer-create = neutronclient.neutron.v2_0.lb.v2.loadbalancer:CreateLoadBalancer lbaas-loadbalancer-delete = neutronclient.neutron.v2_0.lb.v2.loadbalancer:DeleteLoadBalancer lbaas-loadbalancer-list = neutronclient.neutron.v2_0.lb.v2.loadbalancer:ListLoadBalancer lbaas-loadbalancer-list-on-agent = neutronclient.neutron.v2_0.agentscheduler:ListLoadBalancersOnLbaasAgent lbaas-loadbalancer-show = neutronclient.neutron.v2_0.lb.v2.loadbalancer:ShowLoadBalancer lbaas-loadbalancer-stats = neutronclient.neutron.v2_0.lb.v2.loadbalancer:RetrieveLoadBalancerStats lbaas-loadbalancer-status = neutronclient.neutron.v2_0.lb.v2.loadbalancer:RetrieveLoadBalancerStatus lbaas-loadbalancer-update = neutronclient.neutron.v2_0.lb.v2.loadbalancer:UpdateLoadBalancer lbaas-member-create = neutronclient.neutron.v2_0.lb.v2.member:CreateMember lbaas-member-delete = neutronclient.neutron.v2_0.lb.v2.member:DeleteMember lbaas-member-list = neutronclient.neutron.v2_0.lb.v2.member:ListMember lbaas-member-show = neutronclient.neutron.v2_0.lb.v2.member:ShowMember lbaas-member-update = neutronclient.neutron.v2_0.lb.v2.member:UpdateMember lbaas-pool-create = neutronclient.neutron.v2_0.lb.v2.pool:CreatePool lbaas-pool-delete = neutronclient.neutron.v2_0.lb.v2.pool:DeletePool lbaas-pool-list = neutronclient.neutron.v2_0.lb.v2.pool:ListPool lbaas-pool-show = neutronclient.neutron.v2_0.lb.v2.pool:ShowPool lbaas-pool-update = neutronclient.neutron.v2_0.lb.v2.pool:UpdatePool meter-label-create = neutronclient.neutron.v2_0.metering:CreateMeteringLabel meter-label-delete = neutronclient.neutron.v2_0.metering:DeleteMeteringLabel meter-label-list = neutronclient.neutron.v2_0.metering:ListMeteringLabel meter-label-rule-create = neutronclient.neutron.v2_0.metering:CreateMeteringLabelRule meter-label-rule-delete = neutronclient.neutron.v2_0.metering:DeleteMeteringLabelRule meter-label-rule-list = neutronclient.neutron.v2_0.metering:ListMeteringLabelRule meter-label-rule-show = neutronclient.neutron.v2_0.metering:ShowMeteringLabelRule meter-label-show = neutronclient.neutron.v2_0.metering:ShowMeteringLabel net-create = neutronclient.neutron.v2_0.network:CreateNetwork net-delete = neutronclient.neutron.v2_0.network:DeleteNetwork net-external-list = neutronclient.neutron.v2_0.network:ListExternalNetwork net-ip-availability-list = neutronclient.neutron.v2_0.network_ip_availability:ListIpAvailability net-ip-availability-show = neutronclient.neutron.v2_0.network_ip_availability:ShowIpAvailability net-list = neutronclient.neutron.v2_0.network:ListNetwork net-list-on-dhcp-agent = neutronclient.neutron.v2_0.agentscheduler:ListNetworksOnDhcpAgent net-show = neutronclient.neutron.v2_0.network:ShowNetwork net-update = neutronclient.neutron.v2_0.network:UpdateNetwork port-create = neutronclient.neutron.v2_0.port:CreatePort port-delete = neutronclient.neutron.v2_0.port:DeletePort port-list = neutronclient.neutron.v2_0.port:ListPort port-show = neutronclient.neutron.v2_0.port:ShowPort port-update = neutronclient.neutron.v2_0.port:UpdatePort purge = neutronclient.neutron.v2_0.purge:Purge qos-available-rule-types = neutronclient.neutron.v2_0.qos.rule:ListQoSRuleTypes qos-bandwidth-limit-rule-create = neutronclient.neutron.v2_0.qos.bandwidth_limit_rule:CreateQoSBandwidthLimitRule qos-bandwidth-limit-rule-delete = neutronclient.neutron.v2_0.qos.bandwidth_limit_rule:DeleteQoSBandwidthLimitRule qos-bandwidth-limit-rule-list = neutronclient.neutron.v2_0.qos.bandwidth_limit_rule:ListQoSBandwidthLimitRules qos-bandwidth-limit-rule-show = neutronclient.neutron.v2_0.qos.bandwidth_limit_rule:ShowQoSBandwidthLimitRule qos-bandwidth-limit-rule-update = neutronclient.neutron.v2_0.qos.bandwidth_limit_rule:UpdateQoSBandwidthLimitRule qos-dscp-marking-rule-create = neutronclient.neutron.v2_0.qos.dscp_marking_rule:CreateQoSDscpMarkingRule qos-dscp-marking-rule-delete = neutronclient.neutron.v2_0.qos.dscp_marking_rule:DeleteQoSDscpMarkingRule qos-dscp-marking-rule-list = neutronclient.neutron.v2_0.qos.dscp_marking_rule:ListQoSDscpMarkingRules qos-dscp-marking-rule-show = neutronclient.neutron.v2_0.qos.dscp_marking_rule:ShowQoSDscpMarkingRule qos-dscp-marking-rule-update = neutronclient.neutron.v2_0.qos.dscp_marking_rule:UpdateQoSDscpMarkingRule qos-minimum-bandwidth-rule-create = neutronclient.neutron.v2_0.qos.minimum_bandwidth_rule:CreateQoSMinimumBandwidthRule qos-minimum-bandwidth-rule-delete = neutronclient.neutron.v2_0.qos.minimum_bandwidth_rule:DeleteQoSMinimumBandwidthRule qos-minimum-bandwidth-rule-list = neutronclient.neutron.v2_0.qos.minimum_bandwidth_rule:ListQoSMinimumBandwidthRules qos-minimum-bandwidth-rule-show = neutronclient.neutron.v2_0.qos.minimum_bandwidth_rule:ShowQoSMinimumBandwidthRule qos-minimum-bandwidth-rule-update = neutronclient.neutron.v2_0.qos.minimum_bandwidth_rule:UpdateQoSMinimumBandwidthRule qos-policy-create = neutronclient.neutron.v2_0.qos.policy:CreateQoSPolicy qos-policy-delete = neutronclient.neutron.v2_0.qos.policy:DeleteQoSPolicy qos-policy-list = neutronclient.neutron.v2_0.qos.policy:ListQoSPolicy qos-policy-show = neutronclient.neutron.v2_0.qos.policy:ShowQoSPolicy qos-policy-update = neutronclient.neutron.v2_0.qos.policy:UpdateQoSPolicy quota-default-show = neutronclient.neutron.v2_0.quota:ShowQuotaDefault quota-delete = neutronclient.neutron.v2_0.quota:DeleteQuota quota-list = neutronclient.neutron.v2_0.quota:ListQuota quota-show = neutronclient.neutron.v2_0.quota:ShowQuota quota-update = neutronclient.neutron.v2_0.quota:UpdateQuota rbac-create = neutronclient.neutron.v2_0.rbac:CreateRBACPolicy rbac-delete = neutronclient.neutron.v2_0.rbac:DeleteRBACPolicy rbac-list = neutronclient.neutron.v2_0.rbac:ListRBACPolicy rbac-show = neutronclient.neutron.v2_0.rbac:ShowRBACPolicy rbac-update = neutronclient.neutron.v2_0.rbac:UpdateRBACPolicy router-create = neutronclient.neutron.v2_0.router:CreateRouter router-delete = neutronclient.neutron.v2_0.router:DeleteRouter router-gateway-clear = neutronclient.neutron.v2_0.router:RemoveGatewayRouter router-gateway-set = neutronclient.neutron.v2_0.router:SetGatewayRouter router-interface-add = neutronclient.neutron.v2_0.router:AddInterfaceRouter router-interface-delete = neutronclient.neutron.v2_0.router:RemoveInterfaceRouter router-list = neutronclient.neutron.v2_0.router:ListRouter router-list-on-l3-agent = neutronclient.neutron.v2_0.agentscheduler:ListRoutersOnL3Agent router-port-list = neutronclient.neutron.v2_0.port:ListRouterPort router-show = neutronclient.neutron.v2_0.router:ShowRouter router-update = neutronclient.neutron.v2_0.router:UpdateRouter security-group-create = neutronclient.neutron.v2_0.securitygroup:CreateSecurityGroup security-group-delete = neutronclient.neutron.v2_0.securitygroup:DeleteSecurityGroup security-group-list = neutronclient.neutron.v2_0.securitygroup:ListSecurityGroup security-group-rule-create = neutronclient.neutron.v2_0.securitygroup:CreateSecurityGroupRule security-group-rule-delete = neutronclient.neutron.v2_0.securitygroup:DeleteSecurityGroupRule security-group-rule-list = neutronclient.neutron.v2_0.securitygroup:ListSecurityGroupRule security-group-rule-show = neutronclient.neutron.v2_0.securitygroup:ShowSecurityGroupRule security-group-show = neutronclient.neutron.v2_0.securitygroup:ShowSecurityGroup security-group-update = neutronclient.neutron.v2_0.securitygroup:UpdateSecurityGroup service-provider-list = neutronclient.neutron.v2_0.servicetype:ListServiceProvider subnet-create = neutronclient.neutron.v2_0.subnet:CreateSubnet subnet-delete = neutronclient.neutron.v2_0.subnet:DeleteSubnet subnet-list = neutronclient.neutron.v2_0.subnet:ListSubnet subnet-show = neutronclient.neutron.v2_0.subnet:ShowSubnet subnet-update = neutronclient.neutron.v2_0.subnet:UpdateSubnet subnetpool-create = neutronclient.neutron.v2_0.subnetpool:CreateSubnetPool subnetpool-delete = neutronclient.neutron.v2_0.subnetpool:DeleteSubnetPool subnetpool-list = neutronclient.neutron.v2_0.subnetpool:ListSubnetPool subnetpool-show = neutronclient.neutron.v2_0.subnetpool:ShowSubnetPool subnetpool-update = neutronclient.neutron.v2_0.subnetpool:UpdateSubnetPool tag-add = neutronclient.neutron.v2_0.tag:AddTag tag-remove = neutronclient.neutron.v2_0.tag:RemoveTag tag-replace = neutronclient.neutron.v2_0.tag:ReplaceTag vpn-endpoint-group-create = neutronclient.neutron.v2_0.vpn.endpoint_group:CreateEndpointGroup vpn-endpoint-group-delete = neutronclient.neutron.v2_0.vpn.endpoint_group:DeleteEndpointGroup vpn-endpoint-group-list = neutronclient.neutron.v2_0.vpn.endpoint_group:ListEndpointGroup vpn-endpoint-group-show = neutronclient.neutron.v2_0.vpn.endpoint_group:ShowEndpointGroup vpn-endpoint-group-update = neutronclient.neutron.v2_0.vpn.endpoint_group:UpdateEndpointGroup vpn-ikepolicy-create = neutronclient.neutron.v2_0.vpn.ikepolicy:CreateIKEPolicy vpn-ikepolicy-delete = neutronclient.neutron.v2_0.vpn.ikepolicy:DeleteIKEPolicy vpn-ikepolicy-list = neutronclient.neutron.v2_0.vpn.ikepolicy:ListIKEPolicy vpn-ikepolicy-show = neutronclient.neutron.v2_0.vpn.ikepolicy:ShowIKEPolicy vpn-ikepolicy-update = neutronclient.neutron.v2_0.vpn.ikepolicy:UpdateIKEPolicy vpn-ipsecpolicy-create = neutronclient.neutron.v2_0.vpn.ipsecpolicy:CreateIPsecPolicy vpn-ipsecpolicy-delete = neutronclient.neutron.v2_0.vpn.ipsecpolicy:DeleteIPsecPolicy vpn-ipsecpolicy-list = neutronclient.neutron.v2_0.vpn.ipsecpolicy:ListIPsecPolicy vpn-ipsecpolicy-show = neutronclient.neutron.v2_0.vpn.ipsecpolicy:ShowIPsecPolicy vpn-ipsecpolicy-update = neutronclient.neutron.v2_0.vpn.ipsecpolicy:UpdateIPsecPolicy vpn-service-create = neutronclient.neutron.v2_0.vpn.vpnservice:CreateVPNService vpn-service-delete = neutronclient.neutron.v2_0.vpn.vpnservice:DeleteVPNService vpn-service-list = neutronclient.neutron.v2_0.vpn.vpnservice:ListVPNService vpn-service-show = neutronclient.neutron.v2_0.vpn.vpnservice:ShowVPNService vpn-service-update = neutronclient.neutron.v2_0.vpn.vpnservice:UpdateVPNService [openstack.cli.extension] neutronclient = neutronclient.osc.plugin [openstack.neutronclient.v2] bgp_dragent_add_speaker = neutronclient.osc.v2.dynamic_routing.bgp_dragent:AddBgpSpeakerToDRAgent bgp_dragent_remove_speaker = neutronclient.osc.v2.dynamic_routing.bgp_dragent:RemoveBgpSpeakerFromDRAgent bgp_peer_create = neutronclient.osc.v2.dynamic_routing.bgp_peer:CreateBgpPeer bgp_peer_delete = neutronclient.osc.v2.dynamic_routing.bgp_peer:DeleteBgpPeer bgp_peer_list = neutronclient.osc.v2.dynamic_routing.bgp_peer:ListBgpPeer bgp_peer_set = neutronclient.osc.v2.dynamic_routing.bgp_peer:SetBgpPeer bgp_peer_show = neutronclient.osc.v2.dynamic_routing.bgp_peer:ShowBgpPeer bgp_speaker_add_network = neutronclient.osc.v2.dynamic_routing.bgp_speaker:AddNetworkToSpeaker bgp_speaker_add_peer = neutronclient.osc.v2.dynamic_routing.bgp_speaker:AddPeerToSpeaker bgp_speaker_create = neutronclient.osc.v2.dynamic_routing.bgp_speaker:CreateBgpSpeaker bgp_speaker_delete = neutronclient.osc.v2.dynamic_routing.bgp_speaker:DeleteBgpSpeaker bgp_speaker_list = neutronclient.osc.v2.dynamic_routing.bgp_speaker:ListBgpSpeaker bgp_speaker_list_advertised_routes = neutronclient.osc.v2.dynamic_routing.bgp_speaker:ListRoutesAdvertisedBySpeaker bgp_speaker_remove_network = neutronclient.osc.v2.dynamic_routing.bgp_speaker:RemoveNetworkFromSpeaker bgp_speaker_remove_peer = neutronclient.osc.v2.dynamic_routing.bgp_speaker:RemovePeerFromSpeaker bgp_speaker_set = neutronclient.osc.v2.dynamic_routing.bgp_speaker:SetBgpSpeaker bgp_speaker_show = neutronclient.osc.v2.dynamic_routing.bgp_speaker:ShowBgpSpeaker bgp_speaker_show_dragents = neutronclient.osc.v2.dynamic_routing.bgp_dragent:ListDRAgentsHostingBgpSpeaker bgpvpn_create = neutronclient.osc.v2.networking_bgpvpn.bgpvpn:CreateBgpvpn bgpvpn_delete = neutronclient.osc.v2.networking_bgpvpn.bgpvpn:DeleteBgpvpn bgpvpn_list = neutronclient.osc.v2.networking_bgpvpn.bgpvpn:ListBgpvpn bgpvpn_network_association_create = neutronclient.osc.v2.networking_bgpvpn.network_association:CreateBgpvpnNetAssoc bgpvpn_network_association_delete = neutronclient.osc.v2.networking_bgpvpn.network_association:DeleteBgpvpnNetAssoc bgpvpn_network_association_list = neutronclient.osc.v2.networking_bgpvpn.network_association:ListBgpvpnNetAssoc bgpvpn_network_association_show = neutronclient.osc.v2.networking_bgpvpn.network_association:ShowBgpvpnNetAssoc bgpvpn_port_association_create = neutronclient.osc.v2.networking_bgpvpn.port_association:CreateBgpvpnPortAssoc bgpvpn_port_association_delete = neutronclient.osc.v2.networking_bgpvpn.port_association:DeleteBgpvpnPortAssoc bgpvpn_port_association_list = neutronclient.osc.v2.networking_bgpvpn.port_association:ListBgpvpnPortAssoc bgpvpn_port_association_set = neutronclient.osc.v2.networking_bgpvpn.port_association:SetBgpvpnPortAssoc bgpvpn_port_association_show = neutronclient.osc.v2.networking_bgpvpn.port_association:ShowBgpvpnPortAssoc bgpvpn_port_association_unset = neutronclient.osc.v2.networking_bgpvpn.port_association:UnsetBgpvpnPortAssoc bgpvpn_router_association_create = neutronclient.osc.v2.networking_bgpvpn.router_association:CreateBgpvpnRouterAssoc bgpvpn_router_association_delete = neutronclient.osc.v2.networking_bgpvpn.router_association:DeleteBgpvpnRouterAssoc bgpvpn_router_association_list = neutronclient.osc.v2.networking_bgpvpn.router_association:ListBgpvpnRouterAssoc bgpvpn_router_association_show = neutronclient.osc.v2.networking_bgpvpn.router_association:ShowBgpvpnRouterAssoc bgpvpn_set = neutronclient.osc.v2.networking_bgpvpn.bgpvpn:SetBgpvpn bgpvpn_show = neutronclient.osc.v2.networking_bgpvpn.bgpvpn:ShowBgpvpn bgpvpn_unset = neutronclient.osc.v2.networking_bgpvpn.bgpvpn:UnsetBgpvpn firewall_group_create = neutronclient.osc.v2.fwaas.firewallgroup:CreateFirewallGroup firewall_group_delete = neutronclient.osc.v2.fwaas.firewallgroup:DeleteFirewallGroup firewall_group_list = neutronclient.osc.v2.fwaas.firewallgroup:ListFirewallGroup firewall_group_policy_add_rule = neutronclient.osc.v2.fwaas.firewallpolicy:FirewallPolicyInsertRule firewall_group_policy_create = neutronclient.osc.v2.fwaas.firewallpolicy:CreateFirewallPolicy firewall_group_policy_delete = neutronclient.osc.v2.fwaas.firewallpolicy:DeleteFirewallPolicy firewall_group_policy_list = neutronclient.osc.v2.fwaas.firewallpolicy:ListFirewallPolicy firewall_group_policy_remove_rule = neutronclient.osc.v2.fwaas.firewallpolicy:FirewallPolicyRemoveRule firewall_group_policy_set = neutronclient.osc.v2.fwaas.firewallpolicy:SetFirewallPolicy firewall_group_policy_show = neutronclient.osc.v2.fwaas.firewallpolicy:ShowFirewallPolicy firewall_group_policy_unset = neutronclient.osc.v2.fwaas.firewallpolicy:UnsetFirewallPolicy firewall_group_rule_create = neutronclient.osc.v2.fwaas.firewallrule:CreateFirewallRule firewall_group_rule_delete = neutronclient.osc.v2.fwaas.firewallrule:DeleteFirewallRule firewall_group_rule_list = neutronclient.osc.v2.fwaas.firewallrule:ListFirewallRule firewall_group_rule_set = neutronclient.osc.v2.fwaas.firewallrule:SetFirewallRule firewall_group_rule_show = neutronclient.osc.v2.fwaas.firewallrule:ShowFirewallRule firewall_group_rule_unset = neutronclient.osc.v2.fwaas.firewallrule:UnsetFirewallRule firewall_group_set = neutronclient.osc.v2.fwaas.firewallgroup:SetFirewallGroup firewall_group_show = neutronclient.osc.v2.fwaas.firewallgroup:ShowFirewallGroup firewall_group_unset = neutronclient.osc.v2.fwaas.firewallgroup:UnsetFirewallGroup network_log_create = neutronclient.osc.v2.logging.network_log:CreateNetworkLog network_log_delete = neutronclient.osc.v2.logging.network_log:DeleteNetworkLog network_log_list = neutronclient.osc.v2.logging.network_log:ListNetworkLog network_log_set = neutronclient.osc.v2.logging.network_log:SetNetworkLog network_log_show = neutronclient.osc.v2.logging.network_log:ShowNetworkLog network_loggable_resources_list = neutronclient.osc.v2.logging.network_log:ListLoggableResource network_subport_list = neutronclient.osc.v2.trunk.network_trunk:ListNetworkSubport network_trunk_create = neutronclient.osc.v2.trunk.network_trunk:CreateNetworkTrunk network_trunk_delete = neutronclient.osc.v2.trunk.network_trunk:DeleteNetworkTrunk network_trunk_list = neutronclient.osc.v2.trunk.network_trunk:ListNetworkTrunk network_trunk_set = neutronclient.osc.v2.trunk.network_trunk:SetNetworkTrunk network_trunk_show = neutronclient.osc.v2.trunk.network_trunk:ShowNetworkTrunk network_trunk_unset = neutronclient.osc.v2.trunk.network_trunk:UnsetNetworkTrunk sfc_flow_classifier_create = neutronclient.osc.v2.sfc.sfc_flow_classifier:CreateSfcFlowClassifier sfc_flow_classifier_delete = neutronclient.osc.v2.sfc.sfc_flow_classifier:DeleteSfcFlowClassifier sfc_flow_classifier_list = neutronclient.osc.v2.sfc.sfc_flow_classifier:ListSfcFlowClassifier sfc_flow_classifier_set = neutronclient.osc.v2.sfc.sfc_flow_classifier:SetSfcFlowClassifier sfc_flow_classifier_show = neutronclient.osc.v2.sfc.sfc_flow_classifier:ShowSfcFlowClassifier sfc_port_chain_create = neutronclient.osc.v2.sfc.sfc_port_chain:CreateSfcPortChain sfc_port_chain_delete = neutronclient.osc.v2.sfc.sfc_port_chain:DeleteSfcPortChain sfc_port_chain_list = neutronclient.osc.v2.sfc.sfc_port_chain:ListSfcPortChain sfc_port_chain_set = neutronclient.osc.v2.sfc.sfc_port_chain:SetSfcPortChain sfc_port_chain_show = neutronclient.osc.v2.sfc.sfc_port_chain:ShowSfcPortChain sfc_port_chain_unset = neutronclient.osc.v2.sfc.sfc_port_chain:UnsetSfcPortChain sfc_port_pair_create = neutronclient.osc.v2.sfc.sfc_port_pair:CreateSfcPortPair sfc_port_pair_delete = neutronclient.osc.v2.sfc.sfc_port_pair:DeleteSfcPortPair sfc_port_pair_group_create = neutronclient.osc.v2.sfc.sfc_port_pair_group:CreateSfcPortPairGroup sfc_port_pair_group_delete = neutronclient.osc.v2.sfc.sfc_port_pair_group:DeleteSfcPortPairGroup sfc_port_pair_group_list = neutronclient.osc.v2.sfc.sfc_port_pair_group:ListSfcPortPairGroup sfc_port_pair_group_set = neutronclient.osc.v2.sfc.sfc_port_pair_group:SetSfcPortPairGroup sfc_port_pair_group_show = neutronclient.osc.v2.sfc.sfc_port_pair_group:ShowSfcPortPairGroup sfc_port_pair_group_unset = neutronclient.osc.v2.sfc.sfc_port_pair_group:UnsetSfcPortPairGroup sfc_port_pair_list = neutronclient.osc.v2.sfc.sfc_port_pair:ListSfcPortPair sfc_port_pair_set = neutronclient.osc.v2.sfc.sfc_port_pair:SetSfcPortPair sfc_port_pair_show = neutronclient.osc.v2.sfc.sfc_port_pair:ShowSfcPortPair sfc_service_graph_create = neutronclient.osc.v2.sfc.sfc_service_graph:CreateSfcServiceGraph sfc_service_graph_delete = neutronclient.osc.v2.sfc.sfc_service_graph:DeleteSfcServiceGraph sfc_service_graph_list = neutronclient.osc.v2.sfc.sfc_service_graph:ListSfcServiceGraph sfc_service_graph_set = neutronclient.osc.v2.sfc.sfc_service_graph:SetSfcServiceGraph sfc_service_graph_show = neutronclient.osc.v2.sfc.sfc_service_graph:ShowSfcServiceGraph vpn_endpoint_group_create = neutronclient.osc.v2.vpnaas.endpoint_group:CreateEndpointGroup vpn_endpoint_group_delete = neutronclient.osc.v2.vpnaas.endpoint_group:DeleteEndpointGroup vpn_endpoint_group_list = neutronclient.osc.v2.vpnaas.endpoint_group:ListEndpointGroup vpn_endpoint_group_set = neutronclient.osc.v2.vpnaas.endpoint_group:SetEndpointGroup vpn_endpoint_group_show = neutronclient.osc.v2.vpnaas.endpoint_group:ShowEndpointGroup vpn_ike_policy_create = neutronclient.osc.v2.vpnaas.ikepolicy:CreateIKEPolicy vpn_ike_policy_delete = neutronclient.osc.v2.vpnaas.ikepolicy:DeleteIKEPolicy vpn_ike_policy_list = neutronclient.osc.v2.vpnaas.ikepolicy:ListIKEPolicy vpn_ike_policy_set = neutronclient.osc.v2.vpnaas.ikepolicy:SetIKEPolicy vpn_ike_policy_show = neutronclient.osc.v2.vpnaas.ikepolicy:ShowIKEPolicy vpn_ipsec_policy_create = neutronclient.osc.v2.vpnaas.ipsecpolicy:CreateIPsecPolicy vpn_ipsec_policy_delete = neutronclient.osc.v2.vpnaas.ipsecpolicy:DeleteIPsecPolicy vpn_ipsec_policy_list = neutronclient.osc.v2.vpnaas.ipsecpolicy:ListIPsecPolicy vpn_ipsec_policy_set = neutronclient.osc.v2.vpnaas.ipsecpolicy:SetIPsecPolicy vpn_ipsec_policy_show = neutronclient.osc.v2.vpnaas.ipsecpolicy:ShowIPsecPolicy vpn_ipsec_site_connection_create = neutronclient.osc.v2.vpnaas.ipsec_site_connection:CreateIPsecSiteConnection vpn_ipsec_site_connection_delete = neutronclient.osc.v2.vpnaas.ipsec_site_connection:DeleteIPsecSiteConnection vpn_ipsec_site_connection_list = neutronclient.osc.v2.vpnaas.ipsec_site_connection:ListIPsecSiteConnection vpn_ipsec_site_connection_set = neutronclient.osc.v2.vpnaas.ipsec_site_connection:SetIPsecSiteConnection vpn_ipsec_site_connection_show = neutronclient.osc.v2.vpnaas.ipsec_site_connection:ShowIPsecSiteConnection vpn_service_create = neutronclient.osc.v2.vpnaas.vpnservice:CreateVPNService vpn_service_delete = neutronclient.osc.v2.vpnaas.vpnservice:DeleteVPNService vpn_service_list = neutronclient.osc.v2.vpnaas.vpnservice:ListVPNService vpn_service_set = neutronclient.osc.v2.vpnaas.vpnservice:SetVPNSercice vpn_service_show = neutronclient.osc.v2.vpnaas.vpnservice:ShowVPNService python-neutronclient-6.7.0/python_neutronclient.egg-info/pbr.json0000664000175100017510000000005613232473706025432 0ustar zuulzuul00000000000000{"git_version": "95d64ce", "is_release": true}python-neutronclient-6.7.0/test-requirements.txt0000666000175100017510000000143613232473350022231 0ustar zuulzuul00000000000000# The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0 coverage!=4.4,>=4.0 # Apache-2.0 fixtures>=3.0.0 # Apache-2.0/BSD flake8-import-order==0.12 # LGPLv3 mox3>=0.20.0 # Apache-2.0 mock>=2.0.0 # BSD openstackdocstheme>=1.17.0 # Apache-2.0 oslotest>=3.2.0 # Apache-2.0 osprofiler>=1.4.0 # Apache-2.0 python-openstackclient>=3.12.0 # Apache-2.0 python-subunit>=1.0.0 # Apache-2.0/BSD reno>=2.5.0 # Apache-2.0 requests-mock>=1.1.0 # Apache-2.0 sphinx!=1.6.6,>=1.6.2 # BSD testrepository>=0.0.18 # Apache-2.0/BSD testtools>=2.2.0 # MIT testscenarios>=0.4 # Apache-2.0/BSD tempest>=17.1.0 # Apache-2.0 python-neutronclient-6.7.0/doc/0000775000175100017510000000000013232473710016527 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/doc/source/0000775000175100017510000000000013232473710020027 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/doc/source/conf.py0000666000175100017510000000336113232473350021333 0ustar zuulzuul00000000000000# -*- coding: utf-8 -*- # # -- General configuration --------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ 'sphinx.ext.autodoc', 'reno.sphinxext', 'openstackdocstheme', # 'cliff.sphinxext', # TODO(amotoki): Switch to cliff.sphinxext once cliff bug is fixed. # https://bugs.launchpad.net/python-cliff/+bug/1692018 'neutronclient.cliff_sphinxext', ] # openstackdocstheme options repository_name = 'openstack/python-neutronclient' bug_project = 'python-neutronclient' bug_tag = 'doc' html_last_updated_fmt = '%Y-%m-%d %H:%M' # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The master toctree document. master_doc = 'index' # General information about the project. copyright = u'OpenStack Foundation' # If true, '()' will be appended to :func: etc. cross-reference text. add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). add_module_names = True # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # -- Options for HTML output --------------------------------------------- # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. html_theme = 'openstackdocs' # Output file base name for HTML help builder. htmlhelp_basename = 'neutronclientdoc' # -- Options for cliff.sphinxext plugin --------------------------------------- autoprogram_cliff_application = 'openstack' python-neutronclient-6.7.0/doc/source/reference/0000775000175100017510000000000013232473710021765 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/doc/source/reference/index.rst0000666000175100017510000000676013232473350023641 0ustar zuulzuul00000000000000.. 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. Convention for heading levels in Neutron devref: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 (Avoid deeper levels because they do not render well.) neutronclient Python API ======================== Basic Usage ----------- First create a client instance using a keystoneauth Session. For more information on this keystoneauth API, see `Using Sessions`_. .. _Using Sessions: https://docs.openstack.org/keystoneauth/latest/using-sessions.html .. code-block:: python >>> from keystoneauth1 import identity >>> from keystoneauth1 import session >>> from neutronclient.v2_0 import client >>> username='username' >>> password='password' >>> project_name='demo' >>> project_domain_id='default' >>> user_domain_id='default' >>> auth_url='http://auth.example.com:5000/v3' >>> auth = identity.Password(auth_url=auth_url, ... username=username, ... password=password, ... project_name=project_name, ... project_domain_id=project_domain_id, ... user_domain_id=user_domain_id) >>> sess = session.Session(auth=auth) >>> neutron = client.Client(session=sess) If you are using Identity v2.0 API (DEPRECATED), create an auth plugin using the appropriate parameters and `keystoneauth1.identity` will handle Identity API version discovery. Then you can create a Session and a Neutronclient just like the previous example. .. code-block:: python >>> auth = identity.Password(auth_url=auth_url, ... username=username, ... password=password, ... project_name=project_name) >>> # create a Session and a Neutronclient Now you can call various methods on the client instance. .. code-block:: python >>> network = {'name': 'mynetwork', 'admin_state_up': True} >>> neutron.create_network({'network':network}) >>> networks = neutron.list_networks(name='mynetwork') >>> print networks >>> network_id = networks['networks'][0]['id'] >>> neutron.delete_network(network_id) Alternatively, you can create a client instance using an auth token and a service endpoint URL directly. .. code-block:: python >>> from neutronclient.v2_0 import client >>> neutron = client.Client(endpoint_url='http://192.168.206.130:9696/', ... token='d3f9226f27774f338019aa2611112ef6') You can get ``X-Openstack-Request-Id`` as ``request_ids`` from the result. .. code-block:: python >>> network = {'name': 'mynetwork', 'admin_state_up': True} >>> neutron.create_network({'network':network}) >>> networks = neutron.list_networks(name='mynetwork') >>> print networks.request_ids ['req-978a0160-7ab0-44f0-8a93-08e9a4e785fa'] python-neutronclient-6.7.0/doc/source/contributor/0000775000175100017510000000000013232473710022401 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/doc/source/contributor/cli_option_guideline.rst0000666000175100017510000002242413232473350027325 0ustar zuulzuul00000000000000.. 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. Convention for heading levels in Neutron devref: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 (Avoid deeper levels because they do not render well.) CLI Option Guideline ==================== This document describes the conventions of neutron CLI options. General conventions ------------------- #. Option names should be delimited by a hyphen instead of a underscore. This is the common guidelines across all OpenStack CLIs. * Good: ``--ip-version`` * Not Good: ``--ip_version`` #. Use at least one required option for ``*-create`` command. If all options are optional, we typically use ``name`` field as a required option. #. When you need to specify an ID of a resource, it is better to provide another way to specify the resource like ``name`` or other reasonable field. #. If an attribute name in API is ``foo_id``, the corresponding option should be ``--foo`` instead of ``--foo-id``. * It is because we usually support ID and ``name`` to specify a resource. #. Do not use ``nargs='?'`` without a special reason. * The behavior of ``nargs='?'`` option for python argparse is bit tricky and may lead to unexpected option parsing different from the help message. The detail is described in the :ref:`Background section ` below. #. (option) Avoid using positional options as much as possible. * Positional arguments should be limited to attributes which will be required in the long future. #. We honor existing options and should keep compatibilities when adding or changing options. Options for boolean value ------------------------- Use the form of ``--option-name {True|False}``. * For a new option, it is recommended. * It is suggested to use ``common.utils.add_boolean_argument`` in an implementation. It allows ``true``/``false`` in addition to ``True``/``False``. * For existing options, migration to the recommended form is not necessarily required. All backward-compatibility should be kept without reasonable reasons. Options for dict value ---------------------- Some API attributes take a dictionary. ``--foo key1=val1,key2=val2`` is usually used. This means ``{"key1": "val1", "key2": "val2"}`` is passed in the API layer. Examples: * ``--host-route destination=CIDR,nexthop=IP_ADDR`` for a subnet * ``--fixed-ip subnet_id=SUBNET,ip_address=IP_ADDR`` for a port. Options for list value ---------------------- Some attributes take a list. In this case, we usually use: * Define an option per element (Use a singular form as an option name) * Allow to specify the option multiple times For Example, **port-create** has ``--security-group`` option. ``--security-group SG1 --security-group SG2`` generates ``{"security_groups: ["SG1", "SG2"]}`` in the API layer. This convention applies to a case of a list of dict. ``--allocation-pool`` and ``--host-route`` for a subnet are examples. Compatibility with extra arguments ---------------------------------- *extra arguments* supports various types of option specifications. At least the following patterns needs to be considered when defining a new option. For more detail, see :ref:`cli_extra_arguments`. * Normal options with value * Boolean options : ``--foo True``, ``--bar=False`` * List options : ``--bars list=true val1 val2``, ``--bars val1 val2`` * Dict options : ``--foo type=dict key1=va1,key2=val2`` * List of Dict options : ``--bars list=true type=dict key1=val1,key2=val2 key3=val3,key4=val4`` * ``action=clear`` For normal options with value, there are four patterns to specify an option as extra arguments. * ``--admin-state-up True`` (a space between option name and value) * ``--admin-state-up=True`` (= between option name and value) * ``--admin_state_up True`` (underscore is used as delimiter) * ``--admin_state_up=True`` (underscore is used as delimiter) .. _background: Background ---------- There are a lot of opinions on which form of options are better or not. This section tries to capture the reason of the current choice. Use at least one required option ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As a convention, **neutron** CLI requires one required argument. If all options are optional in the API level and we have ``name`` field, we usually use ``name`` as a required parameter. Requiring at least one argument has the following benefits: * If we run ``neutron *-create`` without a required argument, we will have a brief help message without detail option help. It is convenient. * We can avoid miss operation by just hitting ``neutron *-create``. Requiring at least one parameter is a good balance. Even though we can change this convention to allow to create a resource without ``name`` field, it will bring confusions to existing users. There may be opinion that it is inconsistent with API level requirement or Horizon behavior, but even if neutron CLI requires ``name`` field there is no bad impact on regular users. Considering possible confusion if we change it, it looks better to keep it as-is. Options for Boolean value ~~~~~~~~~~~~~~~~~~~~~~~~~ * ``--enable-foo``/``--disable-foo`` or similar patterns (including ``--admin-state-down``) is not suggested because we need two exclusive options for one attribute in REST API. It is meaningless. * It is not recommended to have an option only to specify non-default value. For example, we have ``--shared`` or ``--admin-state-down`` options for net-create. This form only works for ``*-create`` and does not work for ``*-update``. It leads to having different options for ``*-create`` and ``*-update``. * A flag option like ``--enable-dhcp`` (without value) also has a problem when considering the compatibility with *extra argument*. We can specify ``-enable-dhcp True/False`` or ``--enable-dhcp=True/False`` in the *extra argument* mechanism. If we introduce ``--enable-dhcp`` (without value), the form of ``-enable-dhcp True/False`` cannot be used now. This is another reason we don't use a flag style option for a boolean parameter. .. _background-nargs: Avoid using nargs in positional or optional arguments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The behavior of ``nargs='?'`` option for python argparse is bit tricky. When we use ``nargs='?'`` and if the order of command-line options is changed then the command-line parser may fail to parse the arguments correctly. Two examples of such failures are provided below. Example 1: This example shows how the actual behavior can differ from the provided help message. In the below block, help message at ``[5]`` says ``--bb CC`` is a valid format but the argument parsing for the same format fails at ``[7]``. .. code-block:: console In [1]: import argparse In [2]: parser = argparse.ArgumentParser() In [3]: parser.add_argument('--bb', nargs='?') In [4]: parser.add_argument('cc') In [5]: parser.print_help() usage: ipython [-h] [--bb [BB]] cc positional arguments: cc optional arguments: -h, --help show this help message and exit --bb [BB] In [6]: parser.parse_args('--bb 1 X'.split()) Out[6]: Namespace(bb='1', cc='X') In [7]: parser.parse_args('--bb X'.split()) usage: ipython [-h] [--bb [BB]] cc ipython: error: too few arguments An exception has occurred, use %tb to see the full traceback. SystemExit: 2 Example 2: This example shows how fragile ``nargs='?'`` can be when user specifies options in different order from the help message. .. code-block:: console In [1]: import argparse In [2]: parser = argparse.ArgumentParser() In [3]: parser.add_argument('--a', help='option a') In [4]: parser.add_argument('--b', help='option b') In [5]: parser.add_argument('x', help='positional arg X') In [6]: parser.add_argument('y', nargs='?', help='positional arg Y') In [7]: parser.print_help() usage: ipython [-h] [--a A] [--b B] x [y] positional arguments: x positional arg X y positional arg Y optional arguments: -h, --help show this help message and exit --a A option a --b B option b In [8]: parser.parse_args('--a 1 --b 2 X Y'.split()) Out[8]: Namespace(a='1', b='2', x='X', y='Y') In [9]: parser.parse_args('X Y --a 1 --b 2'.split()) Out[9]: Namespace(a='1', b='2', x='X', y='Y') In [10]: parser.parse_args('X --a 1 --b 2 Y'.split()) usage: ipython [-h] [--a A] [--b B] x [y] ipython: error: unrecognized arguments: Y An exception has occurred, use %tb to see the full traceback. SystemExit: 2 To exit: use 'exit', 'quit', or Ctrl-D. To exit: use 'exit', 'quit', or Ctrl-D. Note: Most CLI users don't care about the order of the command-line options. Hence, such fragile behavior should be avoided. python-neutronclient-6.7.0/doc/source/contributor/index.rst0000666000175100017510000000223613232473350024247 0ustar zuulzuul00000000000000.. 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. Convention for heading levels in Neutron devref: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 (Avoid deeper levels because they do not render well.) ================= Contributor Guide ================= In the Contributor Guide, you will find information on neutronclient's lower level programming details or APIs as well as the transition to OpenStack client. .. toctree:: :maxdepth: 2 client_command_extensions cli_option_guideline transition_to_osc python-neutronclient-6.7.0/doc/source/contributor/transition_to_osc.rst0000666000175100017510000003631213232473350026702 0ustar zuulzuul00000000000000.. 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. Convention for heading levels in Neutron devref: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 (Avoid deeper levels because they do not render well.) Transition to OpenStack Client ============================== This document details the transition roadmap for moving the neutron client's OpenStack Networking API support, both the Python library and the ``neutron`` command-line interface (CLI), to the `OpenStack Client (OSC) `_ and the `OpenStack Python SDK `_. This transition is being guided by the `Deprecate individual CLIs in favour of OSC `_ OpenStack spec. See the `Neutron RFE `_, `OSC neutron support etherpad `_ and details below for the overall progress of this transition. Overview -------- This transition will result in the neutron client's ``neutron`` CLI being deprecated and then eventually removed. The ``neutron`` CLI will be replaced by OSC's networking support available via the ``openstack`` CLI. This is similar to the deprecation and removal process for the `keystone client's `_ ``keystone`` CLI. The neutron client's Python library won't be deprecated. It will be available along side the networking support provided by the OpenStack Python SDK. Users of the neutron client's command extensions will need to transition to the `OSC plugin system `_ before the ``neutron`` CLI is removed. Such users will maintain their OSC plugin commands within their own project and will be responsible for deprecating and removing their ``neutron`` CLI extension. Transition Steps ---------------- 1. **Done:** OSC adds OpenStack Python SDK as a dependency. See the following patch set: https://review.openstack.org/#/c/138745/ 2. **Done:** OSC switches its networking support for the `network `_ command object to use the OpenStack Python SDK instead of the neutron client's Python library. See the following patch set: https://review.openstack.org/#/c/253348/ 3. **Done:** OSC removes its python-neutronclient dependency. See the following patch set: https://review.openstack.org/#/c/255545/ 4. **In Progress:** OpenStack Python SDK releases version 1.0 to guarantee backwards compatibility of its networking support and OSC updates its dependencies to include OpenStack Python SDK version 1.0 or later. See the following blueprint: https://blueprints.launchpad.net/python-openstackclient/+spec/network-command-sdk-support 5. **Done:** OSC switches its networking support for the `ip floating `_, `ip floating pool `_, `ip fixed `_, `security group `_, and `security group rule `_ command objects to use the OpenStack Python SDK instead of the nova client's Python library when neutron is enabled. When nova network is enabled, then the nova client's Python library will continue to be used. See the following OSC bugs: * **Done** `Floating IP CRUD `_ * **Done** `Port CRUD `_ * **Done** `Security Group CRUD `_ * **Done** `Security Group Rule CRUD `_ 6. **In Progress:** OSC continues enhancing its networking support. At this point and when applicable, enhancements to the ``neutron`` CLI must also be made to the ``openstack`` CLI and possibly the OpenStack Python SDK. Users of the neutron client's command extensions should start their transition to the OSC plugin system. See the developer guide section below for more information on this step. 7. **In Progress:** Deprecate the ``neutron`` CLI. Running the CLI after it has been `deprecated `_ will issue a warning message: ``neutron CLI is deprecated and will be removed in the future. Use openstack CLI instead.`` In addition, no new features will be added to the CLI, though fixes to the CLI will be assessed on a case by case basis. 8. **Not Started:** Remove the ``neutron`` CLI after two deprecation cycles once the criteria below have been met. * The networking support provide by the ``openstack`` CLI is functionally equivalent to the ``neutron`` CLI and it contains sufficient functional and unit test coverage. * `Neutron Stadium `_ projects, Neutron documentation and `DevStack `_ use ``openstack`` CLI instead of ``neutron`` CLI. * Most users of the neutron client's command extensions have transitioned to the OSC plugin system and use the ``openstack`` CLI instead of the ``neutron`` CLI. Developer Guide --------------- The ``neutron`` CLI version 6.x, without extensions, supports over 200 commands while the ``openstack`` CLI version 3.3.0 supports over 70 networking commands. Of the 70 commands, some do not have all of the options or arguments of their ``neutron`` CLI equivalent. With this large functional gap, a few critical questions for developers during this transition are "Which CLI do I change?", "Where does my CLI belong?", and "Which Python library do I change?" The answer depends on the state of a command and the state of the overall transition. Details are outlined in the tables below. Early stages of the transition will require dual maintenance. **Which CLI do I change?** +----------------------+------------------------+-------------------------------------------------+ | ``neutron`` Command | ``openstack`` Command | CLI to Change | +======================+========================+=================================================+ | Exists | Doesn't Exist | ``neutron`` | +----------------------+------------------------+-------------------------------------------------+ | Exists | In Progress | ``neutron`` and ``openstack`` | | | | (update related blueprint or bug) | +----------------------+------------------------+-------------------------------------------------+ | Exists | Exists | ``openstack`` | | | | (assumes command parity resulting in | | | | ``neutron`` being deprecated) | +----------------------+------------------------+-------------------------------------------------+ | Doesn't Exist | Doesn't Exist | ``openstack`` | +----------------------+------------------------+-------------------------------------------------+ **Where does my CLI belong?** If you are developing an API in any of the `neutron repos `_ the client-side support must be generally located in either the openstackclient or neutronclient repos. Whether the actual code goes into one or the other repo it depends on the nature of the feature, its maturity level, and/or the depth of feedback required during the development. The table below provides an idea of what goes where. Generally speaking, we consider Core anything that is L2 and L3 related or that it has been located in the neutron repo for quite sometime, e.g. QoS or Metering, or that it is available in each neutron deployment irrespective of its configuration (e.g. auto-allocated-topology). Any client feature that falls into this categorization will need to be contributed in OSC. Any other that does not, will need to go into neutronclient, assuming that its server-side is located in a neutron controlled repo. This is a general guideline, when in doubt, please reach out to a member of the neutron core team for clarifications. +---------------------------+-------------------+-------------------------------------------------+ | Networking Commands | OSC Plugin | OpenStack Project for ``openstack`` Commands | +===========================+===================+=================================================+ | Core | No | python-openstackclient | +---------------------------+-------------------+-------------------------------------------------+ | Extension | Yes | python-neutronclient | | (i.e. neutron stadium) | | (``neutronclient/osc/v2/``) | +---------------------------+-------------------+-------------------------------------------------+ | Other | Yes | Applicable project owning networking resource | +---------------------------+-------------------+-------------------------------------------------+ When a repo stops being under neutron governance, its client-side counterpart will have to go through deprecation. Bear in mind that for grandfathered extensions like FWaaS v1, VPNaaS, and LBaaS v1, this is not required as the neutronclient is already deprecated on its own. **Which Python library do I change?** +-------------------------------------------------+-----------------------------------------------+ | OpenStack Project for ``openstack`` Commands | Python Library to Change | +=================================================+===============================================+ | python-openstackclient | python-openstacksdk | +-------------------------------------------------+-----------------------------------------------+ | python-neutronclient | python-neutronclient | +-------------------------------------------------+-----------------------------------------------+ | Other | Applicable project owning network resource | +-------------------------------------------------+-----------------------------------------------+ **Important:** The actual name of the command object and/or action in OSC may differ from those used by neutron in order to follow the OSC command structure and to avoid name conflicts. The `network` prefix must be used to avoid name conflicts if the command object name is highly likely to have an ambiguous meaning. Developers should get new command objects and actions approved by the OSC team before proceeding with the implementation. The "Core" group includes network resources that provide core ``neutron`` project features (e.g. network, subnet, port, etc.) and not advanced features in the ``neutron`` project (e.g. trunk, etc.) or advanced services in separate projects (FWaaS, LBaaS, VPNaaS, dynamic routing, etc.). The "Other" group applies projects other than the core ``neutron`` project. Contact the neutron PTL or core team with questions on network resource classification. When adding or updating an ``openstack`` networking command to python-openstackclient, changes may first be required to the OpenStack Python SDK to support the underlying networking resource object, properties and/or actions. Once the OpenStack Python SDK changes are merged, the related OSC changes can be merged. The OSC changes may require an update to the OSC openstacksdk version in the `requirements.txt `_ file. When adding an ``openstack`` networking command to python-openstackclient, you can optionally propose an `OSC command spec `_ which documents the new command interface before proceeding with the implementation. Users of the neutron client's command extensions must adopt the `OSC plugin `_ system for this transition. Such users will maintain their OSC plugin within their own project and should follow the guidance in the table above to determine which command to change. Developer References -------------------- * See `OSC neutron support etherpad `_ to determine if an ``openstack`` command is in progress. * See `OSC command list `_ to determine if an ``openstack`` command exists. * See `OSC command spec list `_ to determine if an ``openstack`` command spec exists. * See `OSC plugin command list `_ to determine if an ``openstack`` plugin command exists. * See `OSC command structure `_ to determine the current ``openstack`` command objects, plugin objects and actions. * See `OSC human interface guide `_ for guidance on creating new OSC command interfaces. * See `OSC plugin `_ for information on the OSC plugin system to be used for ``neutron`` CLI extensions. * Create an OSC blueprint: https://blueprints.launchpad.net/python-openstackclient/ * Report an OSC bug: https://bugs.launchpad.net/python-openstackclient/+filebug * Report an OpenStack Python SDK bug: https://bugs.launchpad.net/python-openstacksdk/+filebug python-neutronclient-6.7.0/doc/source/contributor/client_command_extensions.rst0000666000175100017510000000725413232473350030400 0ustar zuulzuul00000000000000.. 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. Convention for heading levels in Neutron devref: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 (Avoid deeper levels because they do not render well.) Client command extension support ================================= The client command extension adds support for extending the neutron client while considering ease of creation. Extensions strongly conform to preexisting neutron commands (/neutron/v2_0/). A sample extension can be seen at: neutronclient/neutron/v2_0/contrib/_fox_sockets.py Minimum requirements from an extension -------------------------------------- * NeutronClientExtension subclasses must have a shell_command class variable if the command is to be available to the CLI (shell.py) Example: neutronclient.neutron.v2_0.contrib._fox_sockets.FoxInSocketsList Minimum requirements to use canonical neutron CRUD commands framework ---------------------------------------------------------------------- Neutron commands are cliff commands, commands in extension can use their own way to finish their tasks. But if they want to make use of the canonical neutron CRUD commands framework, the extension should: * have a class that subclasses NeutronClientExtension to provide the requisite resource name, version support, and resource collection and object paths for a resource the commands will process. Example: neutronclient.neutron.v2_0.contrib._fox_sockets.FoxInSocket * have a class that subclasses from the ClientExtensionList to provide resource object list function. This is because most commands need the list function to get object ID via neutronclient.neutron.v2_0.__init__.find_resource_by_id. Example: neutronclient.neutron.v2_0.contrib._fox_sockets.FoxInSocketsList * if needed, subclass ClientExtensionUpdate to implement update of the resource object. Example: neutronclient.neutron.v2_0.contrib._fox_sockets.FoxInSocketsUpdate * if needed, subclass ClientExtensionDelete to implement deletion of the resource object. Example: neutronclient.neutron.v2_0.contrib._fox_sockets.FoxInSocketsDelete * if needed, subclass ClientExtensionShow to get the detail of the resource object. Example: neutronclient.neutron.v2_0.contrib._fox_sockets.FoxInSocketsShow Precedence of command loading ------------------------------ * hard coded commands are loaded first * external commands (installed in the environment) are loaded then Commands that have the same name will be overwritten by commands that are loaded later. To change the execution of a command for your particular extension you only need to override the execute method. Currently this extension support is limited to top-level resources. Parent/child relationships may be added if desired. neutronclient.extension entry_point ----------------------------------- To activate the commands in a specific extension module, add an entry in setup.cfg under neutronclient.extension. For example:: [entry_points] neutronclient.extension = fox_sockets = neutronclient.neutron.v2_0.contrib._fox_sockets python-neutronclient-6.7.0/doc/source/cli/0000775000175100017510000000000013232473710020576 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/doc/source/cli/neutron.rst0000666000175100017510000004441313232473350023032 0ustar zuulzuul00000000000000.. 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. Convention for heading levels in Neutron devref: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 (Avoid deeper levels because they do not render well.) Using neutron CLI ================= The **neutron** shell utility interacts with OpenStack Networking API from the command-line. It supports the entire features of OpenStack Networking API. .. warning:: neutron CLI is now deprecated and will be removed in the future. Use openstack CLI instead. See `openstack CLI command list `__ and :doc:`its extensions for advanced networking services `. The command mapping from neutron CLI to openstack CLI is available `here `__. Basic Usage ----------- In order to use the CLI, you must provide your OpenStack username, password, project, domain information for both user and project, and auth endpoint. Use the corresponding configuration options (``--os-username``, ``--os-password``, ``--os-project-name``, ``--os-user-domain-id``, ``os-project-domain-id``, and ``--os-auth-url``), but it is easier to set them in environment variables. .. code-block:: shell export OS_USERNAME=user export OS_PASSWORD=pass export OS_PROJECT_NAME=project export OS_USER_DOMAIN_ID=default export OS_PROJECT_DOMAIN_ID=default export OS_AUTH_URL=http://auth.example.com:5000/v3 If you are using Identity v2.0 API (DEPRECATED), you don't need to pass domain information. .. code-block:: shell export OS_USERNAME=user export OS_PASSWORD=pass export OS_TENANT_NAME=tenant export OS_AUTH_URL=http://auth.example.com:5000/v2.0 Once you've configured your authentication parameters, you can run **neutron** commands. All commands take the form of: .. code-block:: none neutron [arguments...] Run **neutron help** to get a full list of all possible commands, and run **neutron help ** to get detailed help for that command. Using with os-client-config ~~~~~~~~~~~~~~~~~~~~~~~~~~~ `os-client-config `_ provides more convenient way to manage a collection of client configurations and you can easily switch multiple OpenStack-based configurations. To use os-client-config, you first need to prepare ``~/.config/openstack/clouds.yaml`` like the following. .. code-block:: yaml clouds: devstack: auth: auth_url: http://auth.example.com:5000 password: your-secret project_domain_id: default project_name: demo user_domain_id: default username: demo identity_api_version: '3' region_name: RegionOne devstack-admin: auth: auth_url: http://auth.example.com:35357 password: another-secret project_domain_id: default project_name: admin user_domain_id: default username: admin identity_api_version: '3' region_name: RegionOne Then, you need to specify a configuration name defined in the above clouds.yaml. .. code-block:: shell export OS_CLOUD=devstack For more detail information, see the `os-client-config `_ documentation. Using with keystone token ~~~~~~~~~~~~~~~~~~~~~~~~~ The command-line tool will attempt to re-authenticate using your provided credentials for every request. You can override this behavior by manually supplying an auth token using ``--os-url`` and ``--os-auth-token``. You can alternatively set these environment variables. .. code-block:: shell export OS_URL=http://neutron.example.org:9696/ export OS_TOKEN=3bcc3d3a03f44e3d8377f9247b0ad155 Using noauth mode ~~~~~~~~~~~~~~~~~ If neutron server does not require authentication, besides these two arguments or environment variables (We can use any value as token.), we need manually supply ``--os-auth-strategy`` or set the environment variable. .. code-block:: shell export OS_AUTH_STRATEGY=noauth Display options --------------- Filtering ~~~~~~~~~ Neutron API supports filtering in the listing operation. **neutron** CLI supports this feature too. To specify a filter in ``*-list`` command, you need to pass a pair of an attribute name and an expected value with the format of ``-- ``. The example below retrieves ports owned by compute instances. .. code-block:: console $ neutron port-list --device_owner network:dhcp +--------------------------------------+------+-------------------+-------------------------------------------------------------------------------------------------------------+ | id | name | mac_address | fixed_ips | +--------------------------------------+------+-------------------+-------------------------------------------------------------------------------------------------------------+ | 8953d683-29ad-4be3-b73f-060727c7849b | | fa:16:3e:4b:9e:0a | {"subnet_id": "6b832dfe-f271-443c-abad-629961414a73", "ip_address": "10.0.0.2"} | | | | | {"subnet_id": "cdcc616b-0cff-482f-96f5-06fc63d21247", "ip_address": "fd12:877c:1d66:0:f816:3eff:fe4b:9e0a"} | +--------------------------------------+------+-------------------+-------------------------------------------------------------------------------------------------------------+ You can also specify multiple filters. The example below retrieves security group rules applied to IPv4 traffic which belongs to a security group bfa493f9-2b03-46d2-8399-b9b038a53bc1. .. code-block:: console $ neutron security-group-rule-list --security-group-id bfa493f9-2b03-46d2-8399-b9b038a53bc1 --ethertype IPv4 +--------------------------------------+----------------+-----------+-----------+---------------+-----------------+ | id | security_group | direction | ethertype | protocol/port | remote | +--------------------------------------+----------------+-----------+-----------+---------------+-----------------+ | 65489805-0400-4bce-9bd9-16a81952263c | default | egress | IPv4 | any | any | | 9429f336-4947-4643-bbd9-24528cc65648 | default | ingress | IPv4 | any | default (group) | +--------------------------------------+----------------+-----------+-----------+---------------+-----------------+ .. note:: Looking up UUID from name is not supported when specifying a filter. You need to use UUID to specify a specific resource. .. note:: Filtering for dictionary or list attributes is not supported. Changing displayed columns ~~~~~~~~~~~~~~~~~~~~~~~~~~ If you want displayed columns in a list operation, ``-c`` option can be used. ``-c`` can be specified multiple times and the column order will be same as the order of ``-c`` options. .. code-block:: console $ neutron port-list -c id -c device_owner -c fixed_ips +--------------------------------------+--------------------------+-------------------------------------------------------------------------------------------------------------+ | id | device_owner | fixed_ips | +--------------------------------------+--------------------------+-------------------------------------------------------------------------------------------------------------+ | 41ca1b9b-4bbd-4aa8-bcaa-31d3d5704205 | network:router_interface | {"subnet_id": "6b832dfe-f271-443c-abad-629961414a73", "ip_address": "10.0.0.1"} | | 8953d683-29ad-4be3-b73f-060727c7849b | network:dhcp | {"subnet_id": "6b832dfe-f271-443c-abad-629961414a73", "ip_address": "10.0.0.2"} | | | | {"subnet_id": "cdcc616b-0cff-482f-96f5-06fc63d21247", "ip_address": "fd12:877c:1d66:0:f816:3eff:fe4b:9e0a"} | | a9da29f8-4504-4526-a5ce-cd3624fbd173 | neutron:LOADBALANCER | {"subnet_id": "6b832dfe-f271-443c-abad-629961414a73", "ip_address": "10.0.0.3"} | | | | {"subnet_id": "cdcc616b-0cff-482f-96f5-06fc63d21247", "ip_address": "fd12:877c:1d66:0:f816:3eff:feb1:ab71"} | | d6a1ff96-0a99-416f-a4d6-65d9614cf64e | compute:nova | {"subnet_id": "6b832dfe-f271-443c-abad-629961414a73", "ip_address": "10.0.0.4"} | | | | {"subnet_id": "cdcc616b-0cff-482f-96f5-06fc63d21247", "ip_address": "fd12:877c:1d66:0:f816:3eff:fe2c:348e"} | | f4789225-26d0-409f-8047-82d2c7a87a95 | network:router_interface | {"subnet_id": "cdcc616b-0cff-482f-96f5-06fc63d21247", "ip_address": "fd12:877c:1d66::1"} | +--------------------------------------+--------------------------+-------------------------------------------------------------------------------------------------------------+ .. _cli_extra_arguments: Extra arguments for create/update operation ------------------------------------------- **neutron** CLI has a mechanism called the *extra arguments* for ``*-create`` and ``*-update`` commands. It allows users to specify a set of *unknown options* which are not defined as options and not shown in the help text. **Unknown options MUST be placed at the end of the command line.** *unknown options* will be directly passed to the API layer. By this mechanism, you can pass an attribute which is not defined in the upstream **neutron** CLI. For example, when you are developing a new feature which add a new attribute to an existing resource, it is useful because we can test your feature without changing the existing neutron CLI. For example, if you run the following command:: neutron resource-update --key1 value1 --key2 value2 where ``resource`` is some resource name and ``--key1`` and ``--key2`` are unknown options, then the following JSON will be sent to the neutron API:: PUT /v2.0/resources/ { "resource": { "key2": "value2", "key1": "value1" } } Key interpretation ~~~~~~~~~~~~~~~~~~ This means an option name (``--key1`` in this case) must be one of valid resources of a corresponding resource. An option name ``--foo_bar`` is recognized as an attribute name ``foo_bar``. ``--foo-bar`` is also interpreted as an attribute name ``foo_bar``. Value interpretation ~~~~~~~~~~~~~~~~~~~~ By default, if the number of values is 1, the option value is interpreted as a string and is passed to the API layer as specified in a command-line. If the number of values is greater than 1, the option value is interpreted as a list and the result in the API layer will be same as when specifying a list as described below. neutron resource-update --key1 val1 val2 val3 --key2 val4 In the above example, a value of ``key1`` is interpreted as ``["val1", "val2", "val3"]`` and a value of ``key2`` is interpreted as ``val4``. The extra argument mechanism supports more complex value like a list or a dict. Specify a list value ++++++++++++++++++++ A command-line:: neutron resource-update --key list=true val1 val2 val3 will send the following in the API layer:: { "key": [ "val1", "val2", "val3" ] } .. note:: If you want to specify a list value, it is recommended to specify ``list=true``. When ``list=true`` is specified, specified values are interpreted as a list even regardless of the number of values. If ``list=true`` is not specified, specified values are interpreted depends on the number of values how. If the number of values is more than 2, the specified values are interpreted as a list. If 1, the value is interpreted as a string. Specify a dict value ++++++++++++++++++++ A command-line:: neutron resource-update --key type=dict key1=val1,key2=val2,key3=val3 will send the following in the API layer:: { "key": { "key1": "val1", "key2": "val2", "key3": "val3" } } .. note:: ``type=bool True/False`` and ``type=int 10`` are also supported. Specify a list of dicts +++++++++++++++++++++++ A command-line:: neutron resource-update --key type=dict list=true key1=val1 key2=val2 key3=val3 will send the following in the API layer:: { "key": [ {"key1": "val1"}, {"key2": "val2"}, {"key3": "val3"} ] } Passing None as a value ~~~~~~~~~~~~~~~~~~~~~~~ There is a case where we would like to pass ``None`` (``null`` in JSON) in the API layer. To do this:: neutron resource-update --key action=clear The following body will be in the API layer:: {"key": null} .. note:: If ``action=clear`` is specified, ``list=true`` or ``type=dict`` is ignored. It means when ``action=clear`` is specified ``None`` is always sent. Debugging --------- Display API-level communication ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``-v`` (or ``--verbose``, ``--debug``) option displays a detail interaction with your neutron server. It is useful to debug what happens in the API level. Here is an sample output of ``net-show`` command. The first line show what parameters are recognized by neutronclient. It is sometimes useful to check if command-line parameters you specify are recognized properly. .. code-block:: console $ neutron -v net-show mynetwork DEBUG: neutronclient.neutron.v2_0.network.ShowNetwork get_data(Namespace(columns=[], fields=[], formatter='table', id=u'mynetwork', max_width=0, noindent=False, prefix='', request_format='json', show_details=False, variables=[])) Next, neutronclient sends an authentication request to keystone to get a token which is used in further operations. .. code-block:: console DEBUG: keystoneauth.session REQ: curl -g -i -X GET http://172.16.18.47:5000 -H "Accept: application/json" -H "User-Agent: keystoneauth1" DEBUG: keystoneauth.session RESP: [300] Content-Length: 593 Vary: X-Auth-Token Keep-Alive: timeout=5, max=100 Server: Apache/2.4.7 (Ubuntu) Connection: Keep-Alive Date: Fri, 27 Nov 2015 20:10:54 GMT Content-Type: application/json RESP BODY: {"versions": {"values": [{"status": "stable", "updated": "2015-03-30T00:00:00Z", "media-types": [{"base": "application/json", "type": "application/vnd.openstack.identity-v3+json"}], "id": "v3.4", "links": [{"href": "http://172.16.18.47:5000/v3/", "rel": "self"}]}, {"status": "stable", "updated": "2014-04-17T00:00:00Z", "media-types": [{"base": "application/json", "type": "application/vnd.openstack.identity-v2.0+json"}], "id": "v2.0", "links": [{"href": "http://172.16.18.47:5000/v2.0/", "rel": "self"}, {"href": "http://docs.openstack.org/", "type": "text/html", "rel": "describedby"}]}]}} DEBUG: keystoneauth.identity.v3.base Making authentication request to http://172.16.18.47:5000/v3/auth/tokens Neutronclient looks up a network ID corresponding to a given network name. .. code-block:: console DEBUG: keystoneauth.session REQ: curl -g -i -X GET http://172.16.18.47:9696/v2.0/networks.json?fields=id&name=mynetwork -H "User-Agent: python-neutronclient" -H "Accept: application/json" -H "X-Auth-Token: {SHA1}39300e7398d53a02afd183f13cb6afaef95ec4e5" DEBUG: keystoneauth.session RESP: [200] Date: Fri, 27 Nov 2015 20:10:55 GMT Connection: keep-alive Content-Type: application/json; charset=UTF-8 Content-Length: 62 X-Openstack-Request-Id: req-ccebf6e4-4f52-4874-a1ab-5499abcba378 RESP BODY: {"networks": [{"id": "3698d3c7-d581-443e-bf86-53c4e3a738f7"}]} Finally, neutronclient retrieves a detail of a given network using the resolved ID. .. code-block:: console DEBUG: keystoneauth.session REQ: curl -g -i -X GET http://172.16.18.47:9696/v2.0/networks/3698d3c7-d581-443e-bf86-53c4e3a738f7.json -H "User-Agent: python-neutronclient" -H "Accept: application/json" -H "X-Auth-Token: {SHA1}39300e7398d53a02afd183f13cb6afaef95ec4e5" DEBUG: keystoneauth.session RESP: [200] Date: Fri, 27 Nov 2015 20:10:55 GMT Connection: keep-alive Content-Type: application/json; charset=UTF-8 Content-Length: 272 X-Openstack-Request-Id: req-261add00-d6d3-4ea7-becc-105b60ac7369 RESP BODY: {"network": {"status": "ACTIVE", "subnets": [], "name": "mynetwork", "admin_state_up": true, "tenant_id": "8f0ebf767043483a987736c8c684178d", "mtu": 0, "router:external": false, "shared": false, "port_security_enabled": true, "id": "3698d3c7-d581-443e-bf86-53c4e3a738f7"}} +-----------------------+--------------------------------------+ | Field | Value | +-----------------------+--------------------------------------+ | admin_state_up | True | | id | 3698d3c7-d581-443e-bf86-53c4e3a738f7 | | mtu | 0 | | name | mynetwork | | port_security_enabled | True | | router:external | False | | shared | False | | status | ACTIVE | | subnets | | | tenant_id | 8f0ebf767043483a987736c8c684178d | +-----------------------+--------------------------------------+ python-neutronclient-6.7.0/doc/source/cli/osc/0000775000175100017510000000000013232473710021362 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/doc/source/cli/osc/v2/0000775000175100017510000000000013232473710021711 5ustar zuulzuul00000000000000python-neutronclient-6.7.0/doc/source/cli/osc/v2/vpn-ipsec-site-connection.rst0000666000175100017510000000037313232473350027453 0ustar zuulzuul00000000000000========================= VPN IPsec Site Connection ========================= Creates a site-to-site **IPsec Site Connection** for a VPN service. Network v2 .. autoprogram-cliff:: openstack.neutronclient.v2 :command: vpn ipsec site connection * python-neutronclient-6.7.0/doc/source/cli/osc/v2/vpn-ike-policy.rst0000666000175100017510000000046313232473350025316 0ustar zuulzuul00000000000000============== VPN IKE Policy ============== The **IKE Policy** is used for phases one and two negotiation of the VPN connection. You can specify both the authentication and encryption algorithms for connections. Network v2 .. autoprogram-cliff:: openstack.neutronclient.v2 :command: vpn ike policy * python-neutronclient-6.7.0/doc/source/cli/osc/v2/bgp-dynamic-routing.rst0000666000175100017510000000273713232473350026335 0ustar zuulzuul00000000000000=================== BGP Dynamic Routing =================== BGP dynamic routing enables announcement of project subnet prefixes via BGP. Admins create BGP speakers and BGP peers. BGP peers can be associated with BGP speakers, thereby enabling peering sessions with operator infrastructure. BGP speakers can be associated with networks, which controls which routes are announced to peers. Network v2 .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgp speaker create .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgp speaker delete .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgp speaker list .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgp speaker set .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgp speaker show .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgp speaker show dragents .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgp speaker add network .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgp speaker remove network .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgp speaker add peer .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgp speaker remove peer .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgp speaker list advertised routes .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgp peer * .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgp dragent * python-neutronclient-6.7.0/doc/source/cli/osc/v2/networking-bgpvpn.rst0000666000175100017510000000206113232473407026130 0ustar zuulzuul00000000000000====== bgpvpn ====== A **bgpvpn** resource contains a set of parameters to define a BGP-based VPN. BGP-based IP VPNs networks are widely used in the industry especially for enterprises. The networking BGP VPN project aims at supporting inter-connection between L3VPNs and Neutron resources, i.e. Networks, Routers and Ports. Network v2 .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgpvpn create .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgpvpn delete .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgpvpn list .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgpvpn set .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgpvpn show .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgpvpn unset .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgpvpn network association * .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgpvpn router association * .. autoprogram-cliff:: openstack.neutronclient.v2 :command: bgpvpn port association * python-neutronclient-6.7.0/doc/source/cli/osc/v2/network-log.rst0000666000175100017510000000060413232473350024715 0ustar zuulzuul00000000000000=========== network log =========== A **network log** is a container to group security groups or ports for logging. Specified resources can be logged via these event (``ALL``, ``ACCEPT`` or ``DROP``). Network v2 .. autoprogram-cliff:: openstack.neutronclient.v2 :command: network loggable resources list .. autoprogram-cliff:: openstack.neutronclient.v2 :command: network log * python-neutronclient-6.7.0/doc/source/cli/osc/v2/vpn-service.rst0000666000175100017510000000036713232473350024714 0ustar zuulzuul00000000000000=========== VPN Service =========== The **VPN Service** is associated with a router. After you create the service, it can contain multiple VPN connections. Network v2 .. autoprogram-cliff:: openstack.neutronclient.v2 :command: vpn service * python-neutronclient-6.7.0/doc/source/cli/osc/v2/vpn-ipsec-policy.rst0000666000175100017510000000044113232473350025645 0ustar zuulzuul00000000000000================ VPN IPsec Policy ================ The **IPsec Policy** specifies the authentication and encryption algorithms and encapsulation mode to use for the established VPN connection. Network v2 .. autoprogram-cliff:: openstack.neutronclient.v2 :command: vpn ipsec policy * python-neutronclient-6.7.0/doc/source/cli/osc/v2/firewall-rule.rst0000666000175100017510000000054413232473350025222 0ustar zuulzuul00000000000000=================== firewall group rule =================== A **firewall group rule** represents a collection of attributes like ports, IP addresses which define match criteria and action (allow, or deny) that needs to be taken on the matched data traffic. Network v2 .. autoprogram-cliff:: openstack.neutronclient.v2 :command: firewall group rule * python-neutronclient-6.7.0/doc/source/cli/osc/v2/networking-sfc.rst0000666000175100017510000000251413232473350025407 0ustar zuulzuul00000000000000============== networking sfc ============== **Service Function Chaining** is a mechanism for overriding the basic destination based forwarding that is typical of IP networks. Service Function Chains consist of an ordered sequence of Service Functions (SFs). SFs are virtual machines (or potentially physical devices) that perform a network function such as firewall, content cache, packet inspection, or any other function that requires processing of packets in a flow from point A to point B even though the SFs are not literally between point A and B from a routing table perspective. Network v2 .. autoprogram-cliff:: openstack.neutronclient.v2 :command: sfc flow classifier * .. autoprogram-cliff:: openstack.neutronclient.v2 :command: sfc port chain * .. autoprogram-cliff:: openstack.neutronclient.v2 :command: sfc port pair create .. autoprogram-cliff:: openstack.neutronclient.v2 :command: sfc port pair delete .. autoprogram-cliff:: openstack.neutronclient.v2 :command: sfc port pair list .. autoprogram-cliff:: openstack.neutronclient.v2 :command: sfc port pair set .. autoprogram-cliff:: openstack.neutronclient.v2 :command: sfc port pair show .. autoprogram-cliff:: openstack.neutronclient.v2 :command: sfc port pair group * .. autoprogram-cliff:: openstack.neutronclient.v2 :command: sfc service graph * python-neutronclient-6.7.0/doc/source/cli/osc/v2/vpn-endpoint-group.rst0000666000175100017510000000037713232473350026227 0ustar zuulzuul00000000000000================== VPN Endpoint Group ================== The **Endpoint Group** is used to configure multiple local and remote subnets in vpnservice object. Network v2 .. autoprogram-cliff:: openstack.neutronclient.v2 :command: vpn endpoint group * python-neutronclient-6.7.0/doc/source/cli/osc/v2/firewall-group.rst0000666000175100017510000000153113232473350025404 0ustar zuulzuul00000000000000============== firewall group ============== A **firewall group** is a perimeter firewall management to Networking. Firewall group uses iptables to apply firewall policy to all VM ports and router ports within a project. Network v2 .. 'firewall group *' cannot be used below as it matches 'firewall group rule *' or 'firewall group policy *'. .. autoprogram-cliff:: openstack.neutronclient.v2 :command: firewall group create .. autoprogram-cliff:: openstack.neutronclient.v2 :command: firewall group delete .. autoprogram-cliff:: openstack.neutronclient.v2 :command: firewall group list .. autoprogram-cliff:: openstack.neutronclient.v2 :command: firewall group set .. autoprogram-cliff:: openstack.neutronclient.v2 :command: firewall group show .. autoprogram-cliff:: openstack.neutronclient.v2 :command: firewall group unset python-neutronclient-6.7.0/doc/source/cli/osc/v2/network-trunk.rst0000666000175100017510000000073513232473350025304 0ustar zuulzuul00000000000000============= network trunk ============= A **network trunk** is a container to group logical ports from different networks and provide a single trunked vNIC for servers. It consists of one parent port which is a regular VIF and multiple subports which allow the server to connect to more networks. Network v2 .. autoprogram-cliff:: openstack.neutronclient.v2 :command: network subport list .. autoprogram-cliff:: openstack.neutronclient.v2 :command: network trunk * python-neutronclient-6.7.0/doc/source/cli/osc/v2/firewall-policy.rst0000666000175100017510000000100013232473350025536 0ustar zuulzuul00000000000000===================== firewall group policy ===================== A **firewall group policy** is an ordered collection of firewall rules. A firewall policy can be shared across projects. Thus it can also be made part of an audit workflow wherein the firewall_policy can be audited by the relevant entity that is authorized (and can be different from the projects which create or use the firewall group policy). Network v2 .. autoprogram-cliff:: openstack.neutronclient.v2 :command: firewall group policy * python-neutronclient-6.7.0/doc/source/cli/neutron-reference.rst0000666000175100017510000000316213232473350024762 0ustar zuulzuul00000000000000.. 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. Convention for heading levels in Neutron devref: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 (Avoid deeper levels because they do not render well.) ===================== neutron CLI reference ===================== .. warning:: neutron CLI is now deprecated and will be removed in the future. Use openstack CLI instead. See `openstack CLI command list `__ and :doc:`its extensions for advanced networking services `. The command mapping from neutron CLI to openstack CLI is available `here `__. neutron usage ------------- .. cliff-app:: neutronclient.shell.NeutronShell :application: neutron :arguments: 2.0 neutron API v2.0 commands ------------------------- .. autoprogram-cliff:: neutron.cli.v2 :application: neutron python-neutronclient-6.7.0/doc/source/cli/osc_plugins.rst0000666000175100017510000000237513232473350023666 0ustar zuulzuul00000000000000.. 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. Convention for heading levels in Neutron devref: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 (Avoid deeper levels because they do not render well.) Advanced Network Commands in OpenStack Client ============================================= The following list covers the extended commands for advanced network services available in ``openstack`` command. These commands can be referenced by doing ``openstack help`` and the detail of individual command can be referred by ``openstack help ``. .. toctree:: :glob: :maxdepth: 2 osc/v2/* python-neutronclient-6.7.0/doc/source/cli/index.rst0000666000175100017510000000440513232473350022444 0ustar zuulzuul00000000000000.. 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. Convention for heading levels in Neutron devref: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 (Avoid deeper levels because they do not render well.) ========= Using CLI ========= There are two CLIs which support the Networking API: `OpenStackClient (OSC) `__ and :doc:`neutron CLI ` (deprecated). OpenStackClient --------------- OpenStackClient provides `the basic network commands `__ and python-neutronclient provides :doc:`extensions ` (aka OSC plugins) for advanced networking services. .. toctree:: :maxdepth: 1 Basic network commands Network commands for advanced networking services Mapping Guide from neutron CLI neutron CLI ----------- .. warning:: neutron CLI is now deprecated and will be removed in the future. Use openstack CLI instead. See `openstack CLI command list `__ and :doc:`its extensions for advanced networking services `. The command mapping from neutron CLI to openstack CLI is available `here `__. .. toctree:: :maxdepth: 2 neutron CLI guide neutron CLI reference python-neutronclient-6.7.0/doc/source/index.rst0000666000175100017510000000427313232473350021700 0ustar zuulzuul00000000000000.. 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. Convention for heading levels in Neutron devref: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 (Avoid deeper levels because they do not render well.) ================================== python-neutronclient documentation ================================== This is a client for OpenStack Networking API. It provides :doc:`Python API bindings ` (the neutronclient module) and :doc:`command-line interface (CLI) `. There are two CLIs which support the Networking API: :doc:`neutron CLI ` and `OpenStack Client (OSC) `__. OpenStack Client provides the basic network commands and python-neutronclient provides extensions (aka OSC plugins) for advanced networking services. User Documentation ------------------ .. toctree:: :maxdepth: 2 cli/index reference/index Contributor Guide ----------------- In the :doc:`Contributor Guide `, you will find information on neutronclient's lower level programming details or APIs as well as the transition to OpenStack client. .. toctree:: :maxdepth: 2 contributor/index .. note:: neutron CLI has been deprecated from Ocata release. We do not add, change and drop any existing commands any more. We only accept changes on OSC plugin, neutronclient python bindings and bug fixes on the deprecated CLI (``neutron`` command). History ------- Release notes is available at http://docs.openstack.org/releasenotes/python-neutronclient/.