summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark McClain <mark.mcclain@dreamhost.com>2013-09-25 19:13:38 -0400
committerMark McClain <mark.mcclain@dreamhost.com>2013-09-25 19:38:14 -0400
commitcbb83121c09f95b00720f494ab5f424612ac207d (patch)
tree93469b001e083681d2229804db29476e05fd4ead
parent8ed38707b12ae6e77480ae8d8542712d63b7fc70 (diff)
downloadpython-neutronclient-2.2.4.1.tar.gz
Remove quantumclient and proxy to neutronclient2.2.4.1
Change-Id: I95a351071e68dfc2d67f3895c87f45ad2221767f
-rw-r--r--README.rst3
-rw-r--r--doc/source/index.rst5
-rw-r--r--openstack-common.conf7
-rwxr-xr-xquantum_test.sh128
-rw-r--r--quantumclient/client.py250
-rw-r--r--quantumclient/common/__init__.py8
-rw-r--r--quantumclient/common/clientmanager.py87
-rw-r--r--quantumclient/common/command.py41
-rw-r--r--quantumclient/common/constants.py43
-rw-r--r--quantumclient/common/exceptions.py153
-rw-r--r--quantumclient/common/serializer.py410
-rw-r--r--quantumclient/common/utils.py188
-rw-r--r--quantumclient/openstack/__init__.py0
-rw-r--r--quantumclient/openstack/common/__init__.py0
-rw-r--r--quantumclient/openstack/common/exception.py142
-rw-r--r--quantumclient/openstack/common/gettextutils.py33
-rw-r--r--quantumclient/openstack/common/jsonutils.py148
-rw-r--r--quantumclient/openstack/common/strutils.py133
-rw-r--r--quantumclient/openstack/common/timeutils.py164
-rw-r--r--quantumclient/quantum/client.py64
-rw-r--r--quantumclient/quantum/v2_0/__init__.py574
-rw-r--r--quantumclient/quantum/v2_0/agent.py65
-rw-r--r--quantumclient/quantum/v2_0/agentscheduler.py234
-rw-r--r--quantumclient/quantum/v2_0/extension.py44
-rw-r--r--quantumclient/quantum/v2_0/floatingip.py151
-rw-r--r--quantumclient/quantum/v2_0/lb/__init__.py16
-rw-r--r--quantumclient/quantum/v2_0/lb/healthmonitor.py174
-rw-r--r--quantumclient/quantum/v2_0/lb/member.py99
-rw-r--r--quantumclient/quantum/v2_0/lb/pool.py124
-rw-r--r--quantumclient/quantum/v2_0/lb/vip.py115
-rw-r--r--quantumclient/quantum/v2_0/network.py152
-rw-r--r--quantumclient/quantum/v2_0/nvp_qos_queue.py89
-rw-r--r--quantumclient/quantum/v2_0/nvpnetworkgateway.py159
-rw-r--r--quantumclient/quantum/v2_0/port.py170
-rw-r--r--quantumclient/quantum/v2_0/quota.py232
-rw-r--r--quantumclient/quantum/v2_0/router.py230
-rw-r--r--quantumclient/quantum/v2_0/securitygroup.py259
-rw-r--r--quantumclient/quantum/v2_0/subnet.py168
-rw-r--r--quantumclient/shell.py633
-rw-r--r--quantumclient/tests/unit/test_utils.py45
-rw-r--r--quantumclient/v2_0/client.py864
-rw-r--r--requirements.txt11
-rw-r--r--setup.py4
-rw-r--r--test-requirements.txt16
-rw-r--r--tests/unit/__init__.py16
-rw-r--r--tests/unit/lb/__init__.py16
-rw-r--r--tests/unit/lb/test_cli20_healthmonitor.py219
-rw-r--r--tests/unit/lb/test_cli20_member.py134
-rw-r--r--tests/unit/lb/test_cli20_pool.py171
-rw-r--r--tests/unit/lb/test_cli20_vip.py214
-rw-r--r--tests/unit/test_auth.py320
-rw-r--r--tests/unit/test_casual_args.py99
-rw-r--r--tests/unit/test_cli20.py504
-rw-r--r--tests/unit/test_cli20_extensions.py49
-rw-r--r--tests/unit/test_cli20_floatingips.py139
-rw-r--r--tests/unit/test_cli20_network.py533
-rw-r--r--tests/unit/test_cli20_nvp_queue.py88
-rw-r--r--tests/unit/test_cli20_nvpnetworkgateway.py114
-rw-r--r--tests/unit/test_cli20_port.py304
-rw-r--r--tests/unit/test_cli20_router.py197
-rw-r--r--tests/unit/test_cli20_securitygroup.py333
-rw-r--r--tests/unit/test_cli20_subnet.py402
-rw-r--r--tests/unit/test_name_or_id.py132
-rw-r--r--tests/unit/test_quota.py45
-rw-r--r--tests/unit/test_shell.py173
-rw-r--r--tests/unit/test_utils.py190
66 files changed, 35 insertions, 10992 deletions
diff --git a/README.rst b/README.rst
index 20b7a89..9ab0b8e 100644
--- a/README.rst
+++ b/README.rst
@@ -1 +1,2 @@
-This is the client API library for Quantum.
+This package provides a compatibility layer for code that was built to require
+the old Quantum API Client. New code should use the neutronclient module.
diff --git a/doc/source/index.rst b/doc/source/index.rst
index f68f1e1..1405b9c 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -61,3 +61,8 @@ Release Notes
* 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.4
+-----
+* add compatibility layer to proxy neutronclient
+* removes all quantumclient code
diff --git a/openstack-common.conf b/openstack-common.conf
deleted file mode 100644
index cff7a3d..0000000
--- a/openstack-common.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-[DEFAULT]
-
-# The list of modules to copy from openstack-common
-modules=exception,gettextutils,jsonutils,strutils,timeutils
-
-# The base module to hold the copy of openstack.common
-base=quantumclient
diff --git a/quantum_test.sh b/quantum_test.sh
deleted file mode 100755
index b42299b..0000000
--- a/quantum_test.sh
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/bin/bash
-set -x
-function die() {
- local exitcode=$?
- set +o xtrace
- echo $@
- exit $exitcode
-}
-
-noauth_tenant_id=me
-if [ $1 == 'noauth' ]; then
- NOAUTH="--tenant_id $noauth_tenant_id"
-else
- NOAUTH=
-fi
-
-FORMAT=" --request-format xml"
-
-# test the CRUD of network
-network=mynet1
-quantum net-create $FORMAT $NOAUTH $network || die "fail to create network $network"
-temp=`quantum net-list $FORMAT -- --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=`quantum 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"
-
-quantum net-show $FORMAT $network || die "fail to show network $network"
-quantum net-show $FORMAT $network_id || die "fail to show network $network_id"
-
-quantum net-update $FORMAT $network --admin_state_up False || die "fail to update network $network"
-quantum net-update $FORMAT $network_id --admin_state_up True || die "fail to update network $network_id"
-
-quantum net-list $FORMAT -c id -- --id fakeid || die "fail to list networks with column selection on empty list"
-
-# test the CRUD of subnet
-subnet=mysubnet1
-cidr=10.0.1.3/24
-quantum subnet-create $FORMAT $NOAUTH $network $cidr --name $subnet || die "fail to create subnet $subnet"
-tempsubnet=`quantum subnet-list $FORMAT -- --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=`quantum subnet-list $FORMAT -- --name $subnet --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
-echo "ID of subnet with name $subnet is $subnet_id"
-quantum subnet-show $FORMAT $subnet || die "fail to show subnet $subnet"
-quantum subnet-show $FORMAT $subnet_id || die "fail to show subnet $subnet_id"
-
-quantum subnet-update $FORMAT $subnet --dns_namesevers host1 || die "fail to update subnet $subnet"
-quantum subnet-update $FORMAT $subnet_id --dns_namesevers host2 || die "fail to update subnet $subnet_id"
-
-# test the crud of ports
-port=myport1
-quantum port-create $FORMAT $NOAUTH $network --name $port || die "fail to create port $port"
-tempport=`quantum port-list $FORMAT -- --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=`quantum port-list $FORMAT -- --name $port --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
-echo "ID of port with name $port is $port_id"
-quantum port-show $FORMAT $port || die "fail to show port $port"
-quantum port-show $FORMAT $port_id || die "fail to show port $port_id"
-
-quantum port-update $FORMAT $port --device_id deviceid1 || die "fail to update port $port"
-quantum port-update $FORMAT $port_id --device_id deviceid2 || die "fail to update port $port_id"
-
-# test quota commands RUD
-DEFAULT_NETWORKS=10
-DEFAULT_PORTS=50
-tenant_id=tenant_a
-tenant_id_b=tenant_b
-quantum quota-update $FORMAT --tenant_id $tenant_id --network 30 || die "fail to update quota for tenant $tenant_id"
-quantum quota-update $FORMAT --tenant_id $tenant_id_b --network 20 || die "fail to update quota for tenant $tenant_id"
-networks=`quantum quota-list $FORMAT -c network -c tenant_id | grep $tenant_id | awk '{print $2}'`
-if [ $networks -ne 30 ]; then
- die "networks quota should be 30"
-fi
-networks=`quantum quota-list $FORMAT -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=`quantum quota-show $FORMAT --tenant_id $tenant_id | grep network | awk -F'|' '{print $3}'`
-if [ $networks -ne 30 ]; then
- die "networks quota should be 30"
-fi
-quantum quota-delete $FORMAT --tenant_id $tenant_id || die "fail to delete quota for tenant $tenant_id"
-networks=`quantum quota-show $FORMAT --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
- quantum quota-update $FORMAT --port 99 || die "fail to update quota for self"
- ports=`quantum quota-show $FORMAT | grep port | awk -F'|' '{print $3}'`
- if [ $ports -ne 99 ]; then
- die "ports quota should be 99"
- fi
-
- ports=`quantum quota-list $FORMAT -c port | grep 99 | awk '{print $2}'`
- if [ $ports -ne 99 ]; then
- die "ports quota should be 99"
- fi
- quantum quota-delete $FORMAT || die "fail to delete quota for tenant self"
- ports=`quantum quota-show $FORMAT | grep port | awk -F'|' '{print $3}'`
- if [ $ports -ne $DEFAULT_PORTS ]; then
- die "ports quota should be $DEFAULT_PORTS"
- fi
-else
- # without auth
- quantum quota-update $FORMAT --port 100
- if [ $? -eq 0 ]; then
- die "without valid context on server, quota update command should fail."
- fi
- quantum quota-show $FORMAT
- if [ $? -eq 0 ]; then
- die "without valid context on server, quota show command should fail."
- fi
- quantum quota-delete $FORMAT
- if [ $? -eq 0 ]; then
- die "without valid context on server, quota delete command should fail."
- fi
- quantum quota-list $FORMAT || die "fail to update quota for self"
-fi
diff --git a/quantumclient/client.py b/quantumclient/client.py
index a4669c4..b816bee 100644
--- a/quantumclient/client.py
+++ b/quantumclient/client.py
@@ -1,249 +1,3 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
+from neutronclient import client
-try:
- import json
-except ImportError:
- import simplejson as json
-import logging
-import os
-import urlparse
-# Python 2.5 compat fix
-if not hasattr(urlparse, 'parse_qsl'):
- import cgi
- urlparse.parse_qsl = cgi.parse_qsl
-
-import httplib2
-
-from quantumclient.common import exceptions
-from quantumclient.common import utils
-
-_logger = logging.getLogger(__name__)
-
-if 'QUANTUMCLIENT_DEBUG' in os.environ and os.environ['QUANTUMCLIENT_DEBUG']:
- ch = logging.StreamHandler()
- _logger.setLevel(logging.DEBUG)
- _logger.addHandler(ch)
-
-
-class ServiceCatalog(object):
- """Helper methods for dealing with a Keystone Service Catalog."""
-
- def __init__(self, resource_dict):
- self.catalog = resource_dict
-
- def get_token(self):
- """Fetch token details fron service catalog."""
- token = {'id': self.catalog['access']['token']['id'],
- 'expires': self.catalog['access']['token']['expires'], }
- try:
- token['user_id'] = self.catalog['access']['user']['id']
- token['tenant_id'] = (
- self.catalog['access']['token']['tenant']['id'])
- except Exception:
- # just leave the tenant and user out if it doesn't exist
- pass
- return token
-
- def url_for(self, attr=None, filter_value=None,
- service_type='network', endpoint_type='publicURL'):
- """Fetch the URL from the Quantum service for
- a particular endpoint type. If none given, return
- publicURL.
- """
-
- catalog = self.catalog['access'].get('serviceCatalog', [])
- matching_endpoints = []
- for service in catalog:
- if service['type'] != service_type:
- continue
-
- endpoints = service['endpoints']
- for endpoint in endpoints:
- if not filter_value or endpoint.get(attr) == filter_value:
- matching_endpoints.append(endpoint)
-
- if not matching_endpoints:
- raise exceptions.EndpointNotFound()
- elif len(matching_endpoints) > 1:
- raise exceptions.AmbiguousEndpoints(message=matching_endpoints)
- else:
- if endpoint_type not in matching_endpoints[0]:
- raise exceptions.EndpointTypeNotFound(message=endpoint_type)
-
- return matching_endpoints[0][endpoint_type]
-
-
-class HTTPClient(httplib2.Http):
- """Handles the REST calls and responses, include authn."""
-
- USER_AGENT = 'python-quantumclient'
-
- def __init__(self, username=None, tenant_name=None,
- password=None, auth_url=None,
- token=None, region_name=None, timeout=None,
- endpoint_url=None, insecure=False,
- endpoint_type='publicURL',
- auth_strategy='keystone', **kwargs):
- super(HTTPClient, self).__init__(timeout=timeout)
- self.username = username
- self.tenant_name = tenant_name
- self.password = password
- self.auth_url = auth_url.rstrip('/') if auth_url else None
- self.endpoint_type = endpoint_type
- self.region_name = region_name
- self.auth_token = token
- self.content_type = 'application/json'
- self.endpoint_url = endpoint_url
- self.auth_strategy = auth_strategy
- # httplib2 overrides
- self.force_exception_to_status_code = True
- self.disable_ssl_certificate_validation = insecure
-
- def _cs_request(self, *args, **kwargs):
- kargs = {}
- kargs.setdefault('headers', kwargs.get('headers', {}))
- kargs['headers']['User-Agent'] = self.USER_AGENT
-
- if 'content_type' in kwargs:
- kargs['headers']['Content-Type'] = kwargs['content_type']
- kargs['headers']['Accept'] = kwargs['content_type']
- else:
- kargs['headers']['Content-Type'] = self.content_type
- kargs['headers']['Accept'] = self.content_type
-
- if 'body' in kwargs:
- kargs['body'] = kwargs['body']
- args = utils.safe_encode_list(args)
- kargs = utils.safe_encode_dict(kargs)
- utils.http_log_req(_logger, args, kargs)
- resp, body = self.request(*args, **kargs)
- utils.http_log_resp(_logger, resp, body)
- status_code = self.get_status_code(resp)
- if status_code == 401:
- raise exceptions.Unauthorized(message=body)
- elif status_code == 403:
- raise exceptions.Forbidden(message=body)
- return resp, body
-
- 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 do_request(self, url, method, **kwargs):
- self.authenticate_and_fetch_endpoint_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.setdefault('headers', {})
- 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.setdefault('headers', {})
- 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.service_catalog = ServiceCatalog(body)
- try:
- sc = self.service_catalog.get_token()
- self.auth_token = sc['id']
- self.auth_tenant_id = sc.get('tenant_id')
- self.auth_user_id = sc.get('user_id')
- except KeyError:
- raise exceptions.Unauthorized()
- self.endpoint_url = self.service_catalog.url_for(
- attr='region', filter_value=self.region_name,
- endpoint_type=self.endpoint_type)
-
- def authenticate(self):
- if self.auth_strategy != 'keystone':
- raise exceptions.Unauthorized(message='unknown auth strategy')
- body = {'auth': {'passwordCredentials':
- {'username': self.username,
- 'password': self.password, },
- 'tenantName': self.tenant_name, }, }
-
- token_url = self.auth_url + "/tokens"
-
- # Make sure we follow redirects when trying to reach Keystone
- tmp_follow_all_redirects = self.follow_all_redirects
- self.follow_all_redirects = True
- try:
- resp, body = self._cs_request(token_url, "POST",
- body=json.dumps(body),
- content_type="application/json")
- finally:
- self.follow_all_redirects = tmp_follow_all_redirects
- status_code = self.get_status_code(resp)
- if status_code != 200:
- raise exceptions.Unauthorized(message=body)
- if body:
- try:
- body = json.loads(body)
- except ValueError:
- pass
- else:
- body = None
- self._extract_service_catalog(body)
-
- def _get_endpoint_url(self):
- 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 quantum 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(
- message=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_status_code(self, response):
- """Returns the integer status code from the response.
-
- Either a Webob.Response (used in testing) or httplib.Response
- is returned.
- """
- if hasattr(response, 'status_int'):
- return response.status_int
- else:
- return response.status
+HTTPClient = client.HTTPClient
diff --git a/quantumclient/common/__init__.py b/quantumclient/common/__init__.py
index 1415c50..7e695ff 100644
--- a/quantumclient/common/__init__.py
+++ b/quantumclient/common/__init__.py
@@ -14,11 +14,3 @@
# License for the specific language governing permissions and limitations
# under the License.
# @author: Somik Behera, Nicira Networks, Inc.
-
-import gettext
-
-t = gettext.translation('quantumclient', fallback=True)
-
-
-def _(msg):
- return t.ugettext(msg)
diff --git a/quantumclient/common/clientmanager.py b/quantumclient/common/clientmanager.py
deleted file mode 100644
index 4d219e4..0000000
--- a/quantumclient/common/clientmanager.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-"""Manage access to the clients, including authenticating when needed.
-"""
-
-import logging
-
-from quantumclient import client
-from quantumclient.quantum import client as quantum_client
-
-
-LOG = logging.getLogger(__name__)
-
-
-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.
- """
- quantum = ClientCache(quantum_client.make_client)
-
- def __init__(self, token=None, url=None,
- auth_url=None,
- endpoint_type=None,
- tenant_name=None, tenant_id=None,
- username=None, password=None,
- region_name=None,
- api_version=None,
- auth_strategy=None,
- insecure=False
- ):
- self._token = token
- self._url = url
- self._auth_url = auth_url
- self._endpoint_type = endpoint_type
- self._tenant_name = tenant_name
- self._tenant_id = tenant_id
- self._username = username
- 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
- return
-
- def initialize(self):
- if not self._url:
- httpclient = client.HTTPClient(username=self._username,
- tenant_name=self._tenant_name,
- password=self._password,
- region_name=self._region_name,
- auth_url=self._auth_url,
- endpoint_type=self._endpoint_type,
- insecure=self._insecure)
- httpclient.authenticate()
- # Populate other password flow attributes
- self._token = httpclient.auth_token
- self._url = httpclient.endpoint_url
diff --git a/quantumclient/common/command.py b/quantumclient/common/command.py
deleted file mode 100644
index 7191436..0000000
--- a/quantumclient/common/command.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-"""
-OpenStack base command
-"""
-
-from cliff import command
-
-
-class OpenStackCommand(command.Command):
- """Base class for OpenStack commands
- """
-
- api = None
-
- def run(self, parsed_args):
- if not self.api:
- return
- else:
- return super(OpenStackCommand, self).run(parsed_args)
-
- def get_data(self, parsed_args):
- pass
-
- def take_action(self, parsed_args):
- return self.get_data(parsed_args)
diff --git a/quantumclient/common/constants.py b/quantumclient/common/constants.py
deleted file mode 100644
index a8e8276..0000000
--- a/quantumclient/common/constants.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (c) 2012 OpenStack, LLC.
-#
-# 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.
-
-
-EXT_NS = '_extension_ns'
-XML_NS_V20 = 'http://openstack.org/quantum/api/v2.0'
-XSI_NAMESPACE = "http://www.w3.org/2001/XMLSchema-instance"
-XSI_ATTR = "xsi:nil"
-XSI_NIL_ATTR = "xmlns:xsi"
-TYPE_XMLNS = "xmlns:quantum"
-TYPE_ATTR = "quantum:type"
-VIRTUAL_ROOT_KEY = "_v_root"
-ATOM_NAMESPACE = "http://www.w3.org/2005/Atom"
-ATOM_XMLNS = "xmlns:atom"
-ATOM_LINK_NOTATION = "{%s}link" % ATOM_NAMESPACE
-
-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',
- 'dns_nameservers': 'dns_nameserver',
- 'host_routes': 'host_route',
- 'allocation_pools': 'allocation_pool',
- 'fixed_ips': 'fixed_ip',
- 'extensions': 'extension'}
diff --git a/quantumclient/common/exceptions.py b/quantumclient/common/exceptions.py
index ee33ef7..ab22951 100644
--- a/quantumclient/common/exceptions.py
+++ b/quantumclient/common/exceptions.py
@@ -15,155 +15,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from quantumclient.common import _
+from neutronclient.common.exceptions import * # noqa
-"""
-Quantum base exception handling.
-"""
-
-
-class QuantumException(Exception):
- """Base Quantum Exception
-
- Taken from nova.exception.NovaException
- 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, **kwargs):
- try:
- self._error_string = self.message % 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 NotFound(QuantumException):
- pass
-
-
-class QuantumClientException(QuantumException):
-
- def __init__(self, **kwargs):
- message = kwargs.get('message')
- self.status_code = kwargs.get('status_code', 0)
- if message:
- self.message = message
- super(QuantumClientException, self).__init__(**kwargs)
-
-
-# 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
-class NetworkNotFoundClient(QuantumClientException):
- pass
-
-
-class PortNotFoundClient(QuantumClientException):
- pass
-
-
-class MalformedResponseBody(QuantumException):
- message = _("Malformed response body: %(reason)s")
-
-
-class StateInvalidClient(QuantumClientException):
- pass
-
-
-class NetworkInUseClient(QuantumClientException):
- pass
-
-
-class PortInUseClient(QuantumClientException):
- pass
-
-
-class AlreadyAttachedClient(QuantumClientException):
- pass
-
-
-class Unauthorized(QuantumClientException):
- message = _("Unauthorized: bad credentials.")
-
-
-class Forbidden(QuantumClientException):
- message = _("Forbidden: your credentials don't give you access to this "
- "resource.")
-
-
-class EndpointNotFound(QuantumClientException):
- """Could not find Service or Region in Service Catalog."""
- message = _("Could not find Service or Region in Service Catalog.")
-
-
-class EndpointTypeNotFound(QuantumClientException):
- """Could not find endpoint type in Service Catalog."""
-
- def __str__(self):
- msg = "Could not find endpoint type %s in Service Catalog."
- return msg % repr(self.message)
-
-
-class AmbiguousEndpoints(QuantumClientException):
- """Found more than one matching endpoint in Service Catalog."""
-
- def __str__(self):
- return "AmbiguousEndpoints: %s" % repr(self.message)
-
-
-class QuantumCLIError(QuantumClientException):
- """Exception raised when command line parsing fails."""
- pass
-
-
-class RequestURITooLong(QuantumClientException):
- """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(QuantumClientException):
- message = _("Connection to quantum failed: %(reason)s")
-
-
-class BadInputError(Exception):
- """Error resulting from a client sending bad input to a server."""
- pass
-
-
-class Error(Exception):
- def __init__(self, message=None):
- super(Error, self).__init__(message)
-
-
-class MalformedRequestBody(QuantumException):
- message = _("Malformed request body: %(reason)s")
-
-
-class Invalid(Error):
- pass
-
-
-class InvalidContentType(Invalid):
- message = _("Invalid content type %(content_type)s.")
-
-
-class UnsupportedVersion(Exception):
- """Indicates that the user is trying to use an unsupported
- version of the API
- """
- pass
-
-
-class CommandError(Exception):
- pass
+QuantumException = NeutronException
diff --git a/quantumclient/common/serializer.py b/quantumclient/common/serializer.py
deleted file mode 100644
index 9c595e4..0000000
--- a/quantumclient/common/serializer.py
+++ /dev/null
@@ -1,410 +0,0 @@
-# Copyright 2013 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-###
-### Codes from quantum wsgi
-###
-
-import logging
-
-from xml.etree import ElementTree as etree
-from xml.parsers import expat
-
-from quantumclient.common import constants
-from quantumclient.common import exceptions as exception
-from quantumclient.openstack.common.gettextutils import _
-from quantumclient.openstack.common import jsonutils
-
-LOG = logging.getLogger(__name__)
-
-
-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 unicode(obj)
- return jsonutils.dumps(data, default=sanitizer)
-
-
-class XMLDictSerializer(DictSerializer):
-
- def __init__(self, metadata=None, xmlns=None):
- """XMLDictSerializer constructor.
-
- :param metadata: information needed to deserialize xml into
- a dictionary.
- :param xmlns: XML namespace to include with serialized xml
- """
- super(XMLDictSerializer, self).__init__()
- self.metadata = metadata or {}
- if not xmlns:
- xmlns = self.metadata.get('xmlns')
- if not xmlns:
- xmlns = constants.XML_NS_V20
- self.xmlns = xmlns
-
- def default(self, data):
- """Default serializer of XMLDictSerializer.
-
- :param data: expect data to contain a single key as XML root, or
- contain another '*_links' key as atom links. Other
- case will use 'VIRTUAL_ROOT_KEY' as XML root.
- """
- try:
- links = None
- has_atom = False
- if data is None:
- root_key = constants.VIRTUAL_ROOT_KEY
- root_value = None
- else:
- link_keys = [k for k in data.iterkeys() or []
- if k.endswith('_links')]
- if link_keys:
- links = data.pop(link_keys[0], None)
- has_atom = True
- root_key = (len(data) == 1 and
- data.keys()[0] or constants.VIRTUAL_ROOT_KEY)
- root_value = data.get(root_key, data)
- doc = etree.Element("_temp_root")
- used_prefixes = []
- self._to_xml_node(doc, self.metadata, root_key,
- root_value, used_prefixes)
- if links:
- self._create_link_nodes(list(doc)[0], links)
- return self.to_xml_string(list(doc)[0], used_prefixes, has_atom)
- except AttributeError as e:
- LOG.exception(str(e))
- return ''
-
- def __call__(self, data):
- # Provides a migration path to a cleaner WSGI layer, this
- # "default" stuff and extreme extensibility isn't being used
- # like originally intended
- return self.default(data)
-
- def to_xml_string(self, node, used_prefixes, has_atom=False):
- self._add_xmlns(node, used_prefixes, has_atom)
- return etree.tostring(node, encoding='UTF-8')
-
- #NOTE (ameade): the has_atom should be removed after all of the
- # xml serializers and view builders have been updated to the current
- # spec that required all responses include the xmlns:atom, the has_atom
- # flag is to prevent current tests from breaking
- def _add_xmlns(self, node, used_prefixes, has_atom=False):
- node.set('xmlns', self.xmlns)
- node.set(constants.TYPE_XMLNS, self.xmlns)
- if has_atom:
- node.set(constants.ATOM_XMLNS, constants.ATOM_NAMESPACE)
- node.set(constants.XSI_NIL_ATTR, constants.XSI_NAMESPACE)
- ext_ns = self.metadata.get(constants.EXT_NS, {})
- for prefix in used_prefixes:
- if prefix in ext_ns:
- node.set('xmlns:' + prefix, ext_ns[prefix])
-
- def _to_xml_node(self, parent, metadata, nodename, data, used_prefixes):
- """Recursive method to convert data members to XML nodes."""
- result = etree.SubElement(parent, nodename)
- if ":" in nodename:
- used_prefixes.append(nodename.split(":", 1)[0])
- #TODO(bcwaldon): accomplish this without a type-check
- if isinstance(data, list):
- if not data:
- result.set(
- constants.TYPE_ATTR,
- constants.TYPE_LIST)
- return result
- singular = metadata.get('plurals', {}).get(nodename, None)
- if singular is None:
- if nodename.endswith('s'):
- singular = nodename[:-1]
- else:
- singular = 'item'
- for item in data:
- self._to_xml_node(result, metadata, singular, item,
- used_prefixes)
- #TODO(bcwaldon): accomplish this without a type-check
- elif isinstance(data, dict):
- if not data:
- result.set(
- constants.TYPE_ATTR,
- constants.TYPE_DICT)
- return result
- attrs = metadata.get('attributes', {}).get(nodename, {})
- for k, v in data.items():
- if k in attrs:
- result.set(k, str(v))
- else:
- self._to_xml_node(result, metadata, k, v,
- used_prefixes)
- elif data is None:
- result.set(constants.XSI_ATTR, 'true')
- else:
- if isinstance(data, bool):
- result.set(
- constants.TYPE_ATTR,
- constants.TYPE_BOOL)
- elif isinstance(data, int):
- result.set(
- constants.TYPE_ATTR,
- constants.TYPE_INT)
- elif isinstance(data, long):
- result.set(
- constants.TYPE_ATTR,
- constants.TYPE_LONG)
- elif isinstance(data, float):
- result.set(
- constants.TYPE_ATTR,
- constants.TYPE_FLOAT)
- LOG.debug(_("Data %(data)s type is %(type)s"),
- {'data': data,
- 'type': type(data)})
- if isinstance(data, str):
- result.text = unicode(data, 'utf-8')
- else:
- result.text = unicode(data)
- return result
-
- def _create_link_nodes(self, xml_doc, links):
- for link in links:
- link_node = etree.SubElement(xml_doc, 'atom:link')
- link_node.set('rel', link['rel'])
- link_node.set('href', link['href'])
-
-
-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.MalformedRequestBody(reason=msg)
-
- def default(self, datastring):
- return {'body': self._from_json(datastring)}
-
-
-class XMLDeserializer(TextDeserializer):
-
- def __init__(self, metadata=None):
- """XMLDeserializer constructor.
-
- :param metadata: information needed to deserialize xml into
- a dictionary.
- """
- super(XMLDeserializer, self).__init__()
- self.metadata = metadata or {}
- xmlns = self.metadata.get('xmlns')
- if not xmlns:
- xmlns = constants.XML_NS_V20
- self.xmlns = xmlns
-
- def _get_key(self, tag):
- tags = tag.split("}", 1)
- if len(tags) == 2:
- ns = tags[0][1:]
- bare_tag = tags[1]
- ext_ns = self.metadata.get(constants.EXT_NS, {})
- if ns == self.xmlns:
- return bare_tag
- for prefix, _ns in ext_ns.items():
- if ns == _ns:
- return prefix + ":" + bare_tag
- else:
- return tag
-
- def _get_links(self, root_tag, node):
- link_nodes = node.findall(constants.ATOM_LINK_NOTATION)
- root_tag = self._get_key(node.tag)
- link_key = "%s_links" % root_tag
- link_list = []
- for link in link_nodes:
- link_list.append({'rel': link.get('rel'),
- 'href': link.get('href')})
- # Remove link node in order to avoid link node being
- # processed as an item in _from_xml_node
- node.remove(link)
- return link_list and {link_key: link_list} or {}
-
- def _from_xml(self, datastring):
- if datastring is None:
- return None
- plurals = set(self.metadata.get('plurals', {}))
- try:
- node = etree.fromstring(datastring)
- root_tag = self._get_key(node.tag)
- links = self._get_links(root_tag, node)
- result = self._from_xml_node(node, plurals)
- # There is no case where root_tag = constants.VIRTUAL_ROOT_KEY
- # and links is not None because of the way data are serialized
- if root_tag == constants.VIRTUAL_ROOT_KEY:
- return result
- return dict({root_tag: result}, **links)
- except Exception as e:
- parseError = False
- # Python2.7
- if (hasattr(etree, 'ParseError') and
- isinstance(e, getattr(etree, 'ParseError'))):
- parseError = True
- # Python2.6
- elif isinstance(e, expat.ExpatError):
- parseError = True
- if parseError:
- msg = _("Cannot understand XML")
- raise exception.MalformedRequestBody(reason=msg)
- else:
- raise
-
- def _from_xml_node(self, node, listnames):
- """Convert a minidom node to a simple Python type.
-
- :param listnames: list of XML node names whose subnodes should
- be considered list items.
-
- """
- attrNil = node.get(str(etree.QName(constants.XSI_NAMESPACE, "nil")))
- attrType = node.get(str(etree.QName(
- self.metadata.get('xmlns'), "type")))
- if (attrNil and attrNil.lower() == 'true'):
- return None
- elif not len(node) and not node.text:
- if (attrType and attrType == constants.TYPE_DICT):
- return {}
- elif (attrType and attrType == constants.TYPE_LIST):
- return []
- else:
- return ''
- elif (len(node) == 0 and node.text):
- converters = {constants.TYPE_BOOL:
- lambda x: x.lower() == 'true',
- constants.TYPE_INT:
- lambda x: int(x),
- constants.TYPE_LONG:
- lambda x: long(x),
- constants.TYPE_FLOAT:
- lambda x: float(x)}
- if attrType and attrType in converters:
- return converters[attrType](node.text)
- else:
- return node.text
- elif self._get_key(node.tag) in listnames:
- return [self._from_xml_node(n, listnames) for n in node]
- else:
- result = dict()
- for attr in node.keys():
- if (attr == 'xmlns' or
- attr.startswith('xmlns:') or
- attr == constants.XSI_ATTR or
- attr == constants.TYPE_ATTR):
- continue
- result[self._get_key(attr)] = node.get(attr)
- children = list(node)
- for child in children:
- result[self._get_key(child.tag)] = self._from_xml_node(
- child, listnames)
- return result
-
- def default(self, datastring):
- return {'body': self._from_xml(datastring)}
-
- def __call__(self, datastring):
- # Adding a migration path to allow us to remove unncessary classes
- return self.default(datastring)
-
-
-# NOTE(maru): this class is duplicated from quantum.wsgi
-class Serializer(object):
- """Serializes and deserializes dictionaries to certain MIME types."""
-
- def __init__(self, metadata=None, default_xmlns=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 {}
- self.default_xmlns = default_xmlns
-
- def _get_serialize_handler(self, content_type):
- handlers = {
- 'application/json': JSONDictSerializer(),
- 'application/xml': XMLDictSerializer(self.metadata),
- }
-
- try:
- return handlers[content_type]
- except Exception:
- raise exception.InvalidContentType(content_type=content_type)
-
- def serialize(self, data, content_type):
- """Serialize a dictionary into the specified content type."""
- return self._get_serialize_handler(content_type).serialize(data)
-
- def deserialize(self, datastring, content_type):
- """Deserialize a string to a dictionary.
-
- The string must be in the format of a supported MIME type.
-
- """
- return self.get_deserialize_handler(content_type).deserialize(
- datastring)
-
- def get_deserialize_handler(self, content_type):
- handlers = {
- 'application/json': JSONDeserializer(),
- 'application/xml': XMLDeserializer(self.metadata),
- }
-
- try:
- return handlers[content_type]
- except Exception:
- raise exception.InvalidContentType(content_type=content_type)
diff --git a/quantumclient/common/utils.py b/quantumclient/common/utils.py
index 192b46f..01a0442 100644
--- a/quantumclient/common/utils.py
+++ b/quantumclient/common/utils.py
@@ -1,6 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011, Nicira Networks, Inc.
+# Copyright 2011 Nicira 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
@@ -13,188 +14,5 @@
# 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.
-# @author: Somik Behera, Nicira Networks, Inc.
-
-"""Utilities and helper functions."""
-
-import datetime
-import json
-import logging
-import os
-import sys
-
-from quantumclient.common import exceptions
-from quantumclient.openstack.common import strutils
-
-
-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 to_primitive(value):
- if isinstance(value, list) or isinstance(value, tuple):
- o = []
- for v in value:
- o.append(to_primitive(v))
- return o
- elif isinstance(value, dict):
- o = {}
- for k, v in value.iteritems():
- o[k] = to_primitive(v)
- return o
- elif isinstance(value, datetime.datetime):
- return str(value)
- elif hasattr(value, 'iteritems'):
- return to_primitive(dict(value.iteritems()))
- elif hasattr(value, '__iter__'):
- return to_primitive(list(value))
- else:
- return value
-
-
-def dumps(value, indent=None):
- try:
- return json.dumps(value, indent=indent)
- except TypeError:
- pass
- return json.dumps(to_primitive(value))
-
-
-def loads(s):
- return json.loads(s)
-
-
-def import_class(import_str):
- """Returns a class from a string including module and class.
-
- :param import_str: a string representation of the class name
- :rtype: the requested class
- """
- mod_str, _sep, class_str = import_str.rpartition('.')
- __import__(mod_str)
- return getattr(sys.modules[mod_str], class_str)
-
-
-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 %s client version '%s'. must be one of: %s" % (
- (api_name, version, ', '.join(version_map.keys())))
- raise exceptions.UnsupportedVersion(msg)
-
- return import_class(client_path)
-
-
-def get_item_properties(item, fields, mixed_case_fields=[], formatters={}):
- """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
- """
- 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
- else:
- return strbool.lower() == 'true'
-
-
-def str2dict(strdict):
- '''Convert key1=value1,key2=value2,... string into dictionary.
-
- :param strdict: key1=value1,key2=value2
- '''
- _info = {}
- for kv_str in strdict.split(","):
- k, v = kv_str.split("=", 1)
- _info.update({k: v})
- return _info
-
-
-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 element in kwargs['headers']:
- header = ' -H "%s: %s"' % (element, kwargs['headers'][element])
- string_parts.append(header)
-
- if 'body' in kwargs and kwargs['body']:
- string_parts.append(" -d '%s'" % (kwargs['body']))
- string_parts = safe_encode_list(string_parts)
- _logger.debug("\nREQ: %s\n" % "".join(string_parts))
-
-
-def http_log_resp(_logger, resp, body):
- if not _logger.isEnabledFor(logging.DEBUG):
- return
- _logger.debug("RESP:%s %s\n", resp, body)
-
-
-def _safe_encode_without_obj(data):
- if isinstance(data, basestring):
- return strutils.safe_encode(data)
- return data
-
-
-def safe_encode_list(data):
- return map(_safe_encode_without_obj, data)
-
-
-def safe_encode_dict(data):
- def _encode_item((k, v)):
- 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(map(_encode_item, data.items()))
+from neutronclient.common.utils import * # noqa
diff --git a/quantumclient/openstack/__init__.py b/quantumclient/openstack/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/quantumclient/openstack/__init__.py
+++ /dev/null
diff --git a/quantumclient/openstack/common/__init__.py b/quantumclient/openstack/common/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/quantumclient/openstack/common/__init__.py
+++ /dev/null
diff --git a/quantumclient/openstack/common/exception.py b/quantumclient/openstack/common/exception.py
deleted file mode 100644
index d7dddf3..0000000
--- a/quantumclient/openstack/common/exception.py
+++ /dev/null
@@ -1,142 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 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.
-
-"""
-Exceptions common to OpenStack projects
-"""
-
-import logging
-
-from quantumclient.openstack.common.gettextutils import _
-
-_FATAL_EXCEPTION_FORMAT_ERRORS = False
-
-
-class Error(Exception):
- def __init__(self, message=None):
- super(Error, self).__init__(message)
-
-
-class ApiError(Error):
- def __init__(self, message='Unknown', code='Unknown'):
- self.message = message
- self.code = code
- super(ApiError, self).__init__('%s: %s' % (code, message))
-
-
-class NotFound(Error):
- pass
-
-
-class UnknownScheme(Error):
-
- msg = "Unknown scheme '%s' found in URI"
-
- def __init__(self, scheme):
- msg = self.__class__.msg % scheme
- super(UnknownScheme, self).__init__(msg)
-
-
-class BadStoreUri(Error):
-
- msg = "The Store URI %s was malformed. Reason: %s"
-
- def __init__(self, uri, reason):
- msg = self.__class__.msg % (uri, reason)
- super(BadStoreUri, self).__init__(msg)
-
-
-class Duplicate(Error):
- pass
-
-
-class NotAuthorized(Error):
- pass
-
-
-class NotEmpty(Error):
- pass
-
-
-class Invalid(Error):
- pass
-
-
-class BadInputError(Exception):
- """Error resulting from a client sending bad input to a server"""
- pass
-
-
-class MissingArgumentError(Error):
- pass
-
-
-class DatabaseMigrationError(Error):
- pass
-
-
-class ClientConnectionError(Exception):
- """Error resulting from a client connecting to a server"""
- pass
-
-
-def wrap_exception(f):
- def _wrap(*args, **kw):
- try:
- return f(*args, **kw)
- except Exception, e:
- if not isinstance(e, Error):
- #exc_type, exc_value, exc_traceback = sys.exc_info()
- logging.exception(_('Uncaught exception'))
- #logging.error(traceback.extract_stack(exc_traceback))
- raise Error(str(e))
- raise
- _wrap.func_name = f.func_name
- return _wrap
-
-
-class OpenstackException(Exception):
- """
- Base 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, **kwargs):
- try:
- self._error_string = self.message % kwargs
-
- except Exception as e:
- if _FATAL_EXCEPTION_FORMAT_ERRORS:
- raise e
- else:
- # at least get the core message out if something happened
- self._error_string = self.message
-
- def __str__(self):
- return self._error_string
-
-
-class MalformedRequestBody(OpenstackException):
- message = "Malformed message body: %(reason)s"
-
-
-class InvalidContentType(OpenstackException):
- message = "Invalid content type %(content_type)s"
diff --git a/quantumclient/openstack/common/gettextutils.py b/quantumclient/openstack/common/gettextutils.py
deleted file mode 100644
index 490f194..0000000
--- a/quantumclient/openstack/common/gettextutils.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Red Hat, 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.
-
-"""
-gettext for openstack-common modules.
-
-Usual usage in an openstack.common module:
-
- from quantumclient.openstack.common.gettextutils import _
-"""
-
-import gettext
-
-
-t = gettext.translation('openstack-common', 'locale', fallback=True)
-
-
-def _(msg):
- return t.ugettext(msg)
diff --git a/quantumclient/openstack/common/jsonutils.py b/quantumclient/openstack/common/jsonutils.py
deleted file mode 100644
index ad76e06..0000000
--- a/quantumclient/openstack/common/jsonutils.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# Copyright 2011 Justin Santa Barbara
-# 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.
-
-'''
-JSON related utilities.
-
-This module provides a few things:
-
- 1) A handy function for getting an object down to something that can be
- JSON serialized. See to_primitive().
-
- 2) Wrappers around loads() and dumps(). The dumps() wrapper will
- automatically use to_primitive() for you if needed.
-
- 3) This sets up anyjson to use the loads() and dumps() wrappers if anyjson
- is available.
-'''
-
-
-import datetime
-import inspect
-import itertools
-import json
-import xmlrpclib
-
-from quantumclient.openstack.common import timeutils
-
-
-def to_primitive(value, convert_instances=False, level=0):
- """Convert a complex object into primitives.
-
- Handy for JSON serialization. We can optionally handle instances,
- but since this is a recursive function, we could have cyclical
- data structures.
-
- To handle cyclical data structures we could track the actual objects
- visited in a set, but not all objects are hashable. Instead we just
- track the depth of the object inspections and don't go too deep.
-
- Therefore, convert_instances=True is lossy ... be aware.
-
- """
- nasty = [inspect.ismodule, inspect.isclass, inspect.ismethod,
- inspect.isfunction, inspect.isgeneratorfunction,
- inspect.isgenerator, inspect.istraceback, inspect.isframe,
- inspect.iscode, inspect.isbuiltin, inspect.isroutine,
- inspect.isabstract]
- for test in nasty:
- if test(value):
- return unicode(value)
-
- # value of itertools.count doesn't get caught by inspects
- # above and results in infinite loop when list(value) is called.
- if type(value) == itertools.count:
- return unicode(value)
-
- # FIXME(vish): Workaround for LP bug 852095. Without this workaround,
- # tests that raise an exception in a mocked method that
- # has a @wrap_exception with a notifier will fail. If
- # we up the dependency to 0.5.4 (when it is released) we
- # can remove this workaround.
- if getattr(value, '__module__', None) == 'mox':
- return 'mock'
-
- if level > 3:
- return '?'
-
- # The try block may not be necessary after the class check above,
- # but just in case ...
- try:
- # It's not clear why xmlrpclib created their own DateTime type, but
- # for our purposes, make it a datetime type which is explicitly
- # handled
- if isinstance(value, xmlrpclib.DateTime):
- value = datetime.datetime(*tuple(value.timetuple())[:6])
-
- if isinstance(value, (list, tuple)):
- o = []
- for v in value:
- o.append(to_primitive(v, convert_instances=convert_instances,
- level=level))
- return o
- elif isinstance(value, dict):
- o = {}
- for k, v in value.iteritems():
- o[k] = to_primitive(v, convert_instances=convert_instances,
- level=level)
- return o
- elif isinstance(value, datetime.datetime):
- return timeutils.strtime(value)
- elif hasattr(value, 'iteritems'):
- return to_primitive(dict(value.iteritems()),
- convert_instances=convert_instances,
- level=level + 1)
- elif hasattr(value, '__iter__'):
- return to_primitive(list(value),
- convert_instances=convert_instances,
- level=level)
- elif convert_instances and hasattr(value, '__dict__'):
- # Likely an instance of something. Watch for cycles.
- # Ignore class member vars.
- return to_primitive(value.__dict__,
- convert_instances=convert_instances,
- level=level + 1)
- else:
- return value
- except TypeError:
- # Class objects are tricky since they may define something like
- # __iter__ defined but it isn't callable as list().
- return unicode(value)
-
-
-def dumps(value, default=to_primitive, **kwargs):
- return json.dumps(value, default=default, **kwargs)
-
-
-def loads(s):
- return json.loads(s)
-
-
-def load(s):
- return json.load(s)
-
-
-try:
- import anyjson
-except ImportError:
- pass
-else:
- anyjson._modules.append((__name__, 'dumps', TypeError,
- 'loads', ValueError, 'load'))
- anyjson.force_implementation(__name__)
diff --git a/quantumclient/openstack/common/strutils.py b/quantumclient/openstack/common/strutils.py
deleted file mode 100644
index ecf3cfd..0000000
--- a/quantumclient/openstack/common/strutils.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 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.
-
-"""
-System-level utilities and helper functions.
-"""
-
-import logging
-import sys
-
-LOG = logging.getLogger(__name__)
-
-
-def int_from_bool_as_string(subject):
- """
- Interpret a string as a boolean and return either 1 or 0.
-
- Any string value in:
-
- ('True', 'true', 'On', 'on', '1')
-
- is interpreted as a boolean True.
-
- Useful for JSON-decoded stuff and config file parsing
- """
- return bool_from_string(subject) and 1 or 0
-
-
-def bool_from_string(subject):
- """
- Interpret a string as a boolean.
-
- Any string value in:
-
- ('True', 'true', 'On', 'on', 'Yes', 'yes', '1')
-
- is interpreted as a boolean True.
-
- Useful for JSON-decoded stuff and config file parsing
- """
- if isinstance(subject, bool):
- return subject
- if isinstance(subject, basestring):
- if subject.strip().lower() in ('true', 'on', 'yes', '1'):
- return True
- return False
-
-
-def safe_decode(text, incoming=None, errors='strict'):
- """
- Decodes incoming str using `incoming` if they're
- not already unicode.
-
- :param incoming: Text's current encoding
- :param errors: Errors handling policy. See here for valid
- values http://docs.python.org/2/library/codecs.html
- :returns: text or a unicode `incoming` encoded
- representation of it.
- :raises TypeError: If text is not an isntance of basestring
- """
- if not isinstance(text, basestring):
- raise TypeError("%s can't be decoded" % type(text))
-
- if isinstance(text, unicode):
- return text
-
- if not incoming:
- incoming = (sys.stdin.encoding or
- sys.getdefaultencoding())
-
- try:
- return text.decode(incoming, errors)
- except UnicodeDecodeError:
- # Note(flaper87) If we get here, it means that
- # sys.stdin.encoding / sys.getdefaultencoding
- # didn't return a suitable encoding to decode
- # text. This happens mostly when global LANG
- # var is not set correctly and there's no
- # default encoding. In this case, most likely
- # python will use ASCII or ANSI encoders as
- # default encodings but they won't be capable
- # of decoding non-ASCII characters.
- #
- # Also, UTF-8 is being used since it's an ASCII
- # extension.
- return text.decode('utf-8', errors)
-
-
-def safe_encode(text, incoming=None,
- encoding='utf-8', errors='strict'):
- """
- Encodes incoming str/unicode using `encoding`. If
- incoming is not specified, text is expected to
- be encoded with current python's default encoding.
- (`sys.getdefaultencoding`)
-
- :param incoming: Text's current encoding
- :param encoding: Expected encoding for text (Default UTF-8)
- :param errors: Errors handling policy. See here for valid
- values http://docs.python.org/2/library/codecs.html
- :returns: text or a bytestring `encoding` encoded
- representation of it.
- :raises TypeError: If text is not an isntance of basestring
- """
- if not isinstance(text, basestring):
- raise TypeError("%s can't be encoded" % type(text))
-
- if not incoming:
- incoming = (sys.stdin.encoding or
- sys.getdefaultencoding())
-
- if isinstance(text, unicode):
- return text.encode(encoding, errors)
- elif text and encoding != incoming:
- # Decode text before encoding it with `encoding`
- text = safe_decode(text, incoming, errors)
- return text.encode(encoding, errors)
-
- return text
diff --git a/quantumclient/openstack/common/timeutils.py b/quantumclient/openstack/common/timeutils.py
deleted file mode 100644
index 0f34608..0000000
--- a/quantumclient/openstack/common/timeutils.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 OpenStack LLC.
-# 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.
-
-"""
-Time related utilities and helper functions.
-"""
-
-import calendar
-import datetime
-
-import iso8601
-
-
-TIME_FORMAT = "%Y-%m-%dT%H:%M:%S"
-PERFECT_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f"
-
-
-def isotime(at=None):
- """Stringify time in ISO 8601 format"""
- if not at:
- at = utcnow()
- str = at.strftime(TIME_FORMAT)
- tz = at.tzinfo.tzname(None) if at.tzinfo else 'UTC'
- str += ('Z' if tz == 'UTC' else tz)
- return str
-
-
-def parse_isotime(timestr):
- """Parse time from ISO 8601 format"""
- try:
- return iso8601.parse_date(timestr)
- except iso8601.ParseError as e:
- raise ValueError(e.message)
- except TypeError as e:
- raise ValueError(e.message)
-
-
-def strtime(at=None, fmt=PERFECT_TIME_FORMAT):
- """Returns formatted utcnow."""
- if not at:
- at = utcnow()
- return at.strftime(fmt)
-
-
-def parse_strtime(timestr, fmt=PERFECT_TIME_FORMAT):
- """Turn a formatted time back into a datetime."""
- return datetime.datetime.strptime(timestr, fmt)
-
-
-def normalize_time(timestamp):
- """Normalize time in arbitrary timezone to UTC naive object"""
- offset = timestamp.utcoffset()
- if offset is None:
- return timestamp
- return timestamp.replace(tzinfo=None) - offset
-
-
-def is_older_than(before, seconds):
- """Return True if before is older than seconds."""
- if isinstance(before, basestring):
- before = parse_strtime(before).replace(tzinfo=None)
- return utcnow() - before > datetime.timedelta(seconds=seconds)
-
-
-def is_newer_than(after, seconds):
- """Return True if after is newer than seconds."""
- if isinstance(after, basestring):
- after = parse_strtime(after).replace(tzinfo=None)
- return after - utcnow() > datetime.timedelta(seconds=seconds)
-
-
-def utcnow_ts():
- """Timestamp version of our utcnow function."""
- return calendar.timegm(utcnow().timetuple())
-
-
-def utcnow():
- """Overridable version of utils.utcnow."""
- if utcnow.override_time:
- try:
- return utcnow.override_time.pop(0)
- except AttributeError:
- return utcnow.override_time
- return datetime.datetime.utcnow()
-
-
-utcnow.override_time = None
-
-
-def set_time_override(override_time=datetime.datetime.utcnow()):
- """
- Override utils.utcnow to return a constant time or a list thereof,
- one at a time.
- """
- utcnow.override_time = override_time
-
-
-def advance_time_delta(timedelta):
- """Advance overridden time using a datetime.timedelta."""
- assert(not utcnow.override_time is None)
- try:
- for dt in utcnow.override_time:
- dt += timedelta
- except TypeError:
- utcnow.override_time += timedelta
-
-
-def advance_time_seconds(seconds):
- """Advance overridden time by seconds."""
- advance_time_delta(datetime.timedelta(0, seconds))
-
-
-def clear_time_override():
- """Remove the overridden time."""
- utcnow.override_time = None
-
-
-def marshall_now(now=None):
- """Make an rpc-safe datetime with microseconds.
-
- Note: tzinfo is stripped, but not required for relative times."""
- if not now:
- now = utcnow()
- return dict(day=now.day, month=now.month, year=now.year, hour=now.hour,
- minute=now.minute, second=now.second,
- microsecond=now.microsecond)
-
-
-def unmarshall_time(tyme):
- """Unmarshall a datetime dict."""
- return datetime.datetime(day=tyme['day'],
- month=tyme['month'],
- year=tyme['year'],
- hour=tyme['hour'],
- minute=tyme['minute'],
- second=tyme['second'],
- microsecond=tyme['microsecond'])
-
-
-def delta_seconds(before, after):
- """
- Compute the difference in seconds between two date, time, or
- datetime objects (as a float, to microsecond resolution).
- """
- delta = after - before
- try:
- return delta.total_seconds()
- except AttributeError:
- return ((delta.days * 24 * 3600) + delta.seconds +
- float(delta.microseconds) / (10 ** 6))
diff --git a/quantumclient/quantum/client.py b/quantumclient/quantum/client.py
deleted file mode 100644
index 1661a63..0000000
--- a/quantumclient/quantum/client.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-from quantumclient.common import exceptions
-from quantumclient.common import utils
-
-
-API_NAME = 'network'
-API_VERSIONS = {
- '2.0': 'quantumclient.v2_0.client.Client',
-}
-
-
-def make_client(instance):
- """Returns an quantum client.
- """
- quantum_client = utils.get_client_class(
- API_NAME,
- instance._api_version[API_NAME],
- API_VERSIONS,
- )
- instance.initialize()
- url = instance._url
- url = url.rstrip("/")
- if '2.0' == instance._api_version[API_NAME]:
- client = quantum_client(username=instance._username,
- tenant_name=instance._tenant_name,
- password=instance._password,
- region_name=instance._region_name,
- auth_url=instance._auth_url,
- endpoint_url=url,
- token=instance._token,
- auth_strategy=instance._auth_strategy,
- insecure=instance._insecure)
- return client
- else:
- raise exceptions.UnsupportedVersion("API version %s is not supported" %
- instance._api_version[API_NAME])
-
-
-def Client(api_version, *args, **kwargs):
- """Return an quantum client.
- @param api_version: only 2.0 is supported now
- """
- quantum_client = utils.get_client_class(
- API_NAME,
- api_version,
- API_VERSIONS,
- )
- return quantum_client(*args, **kwargs)
diff --git a/quantumclient/quantum/v2_0/__init__.py b/quantumclient/quantum/v2_0/__init__.py
index 1be1d29..38e43ab 100644
--- a/quantumclient/quantum/v2_0/__init__.py
+++ b/quantumclient/quantum/v2_0/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2013 OpenStack Foundation.
# All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -15,574 +15,6 @@
#
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-import argparse
-import logging
-import re
+from neutronclient.neutron.v2_0 import NeutronCommand
-from cliff.formatters import table
-from cliff import lister
-from cliff import show
-
-from quantumclient.common import command
-from quantumclient.common import exceptions
-from quantumclient.common import utils
-from quantumclient.openstack.common.gettextutils import _
-
-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 find_resourceid_by_name_or_id(client, resource, name_or_id):
- obj_lister = getattr(client, "list_%ss" % resource)
- # perform search by id only if we are passing a valid UUID
- match = re.match(UUID_PATTERN, name_or_id)
- collection = resource + "s"
- if match:
- data = obj_lister(id=name_or_id, fields='id')
- if data and data[collection]:
- return data[collection][0]['id']
- return _find_resourceid_by_name(client, resource, name_or_id)
-
-
-def _find_resourceid_by_name(client, resource, name):
- obj_lister = getattr(client, "list_%ss" % resource)
- data = obj_lister(name=name, fields='id')
- collection = resource + "s"
- info = data[collection]
- if len(info) > 1:
- msg = (_("Multiple %(resource)s matches found for name '%(name)s',"
- " use an ID to be more specific.") %
- {'resource': resource, 'name': name})
- raise exceptions.QuantumClientException(
- message=msg)
- elif len(info) == 0:
- not_found_message = (_("Unable to find %(resource)s with name "
- "'%(name)s'") %
- {'resource': resource, 'name': name})
- # 404 is used to simulate server side behavior
- raise exceptions.QuantumClientException(
- message=not_found_message, status_code=404)
- else:
- return info[0]['id']
-
-
-def add_show_list_common_argument(parser):
- parser.add_argument(
- '-D', '--show-details',
- help='show detailed info',
- 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,'
- ' can be repeated',
- 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=("sort list by specified fields (This option can be repeated), "
- "The number of sort_dir and sort_key should match each other, "
- "more sort_dir specified will be omitted, less will be filled "
- "with asc as default direction "),
- default=[])
- parser.add_argument(
- '--sort-dir',
- dest='sort_dir', metavar='{asc,desc}',
- help=("sort list in specified directions "
- "(This option can be repeated)"),
- 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 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.
-
- '''
- # -- is a pseudo argument
- values_specs_copy = values_specs[:]
- if values_specs_copy and values_specs_copy[0] == '--':
- del values_specs_copy[0]
- _options = {}
- current_arg = None
- _values_specs = []
- _value_number = 0
- _list_flag = False
- current_item = None
- for _item in values_specs_copy:
- if _item.startswith('--'):
- if current_arg is not None:
- if _value_number > 1 or _list_flag:
- current_arg.update({'nargs': '+'})
- elif _value_number == 0:
- current_arg.update({'action': 'store_true'})
- _temp = _item
- if "=" in _item:
- _item = _item.split('=')[0]
- if _item in _options:
- raise exceptions.CommandError(
- "duplicated options %s" % ' '.join(values_specs))
- else:
- _options.update({_item: {}})
- current_arg = _options[_item]
- _item = _temp
- 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:
- _type_str = _item.split('=', 2)[1]
- current_arg.update({'type': eval(_type_str)})
- if _type_str == 'bool':
- current_arg.update({'type': utils.str2bool})
- elif _type_str == 'dict':
- current_arg.update({'type': utils.str2dict})
- continue
- elif _item == 'list=true':
- _list_flag = True
- continue
- if not _item.startswith('--'):
- 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
- elif _item.startswith('--'):
- current_item = _item
- if '=' in current_item:
- _value_number = 1
- else:
- _value_number = 0
- _list_flag = False
- _values_specs.append(_item)
- if current_arg is not None:
- if _value_number > 1 or _list_flag:
- current_arg.update({'nargs': '+'})
- elif _value_number == 0:
- current_arg.update({'action': 'store_true'})
- _args = None
- if _values_specs:
- _parser = argparse.ArgumentParser(add_help=False)
- for opt, optspec in _options.iteritems():
- _parser.add_argument(opt, **optspec)
- _args = _parser.parse_args(_values_specs)
- result_dict = {}
- if _args:
- for opt in _options.iterkeys():
- _opt = opt.split('--', 2)[1]
- _opt = _opt.replace('-', '_')
- _value = getattr(_args, _opt)
- if _value is not None:
- 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 temp_values.iteritems():
- 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 type(arg_value[0]) == type(value[0]):
- arg_value.extend(value)
- _extra_values.pop(key)
-
-
-def update_dict(obj, dict, attributes):
- for attribute in attributes:
- if hasattr(obj, attribute) and getattr(obj, attribute):
- dict[attribute] = getattr(obj, attribute)
-
-
-class TableFormater(table.TableFormatter):
- """This class is used to keep consistency with prettytable 0.6.
-
- https://bugs.launchpad.net/python-quantumclient/+bug/1165962
- """
- def emit_list(self, column_names, data, stdout, parsed_args):
- if column_names:
- super(TableFormater, self).emit_list(column_names, data, stdout,
- parsed_args)
- else:
- stdout.write('\n')
-
-
-class QuantumCommand(command.OpenStackCommand):
- api = 'network'
- log = logging.getLogger(__name__ + '.QuantumCommand')
- values_specs = []
- json_indent = None
-
- def __init__(self, app, app_args):
- super(QuantumCommand, self).__init__(app, app_args)
- if hasattr(self, 'formatters'):
- self.formatters['table'] = TableFormater()
-
- def get_client(self):
- return self.app.client_manager.quantum
-
- def get_parser(self, prog_name):
- parser = super(QuantumCommand, self).get_parser(prog_name)
- parser.add_argument(
- '--request-format',
- help=_('the xml or json request format'),
- default='json',
- choices=['json', 'xml', ], )
- parser.add_argument(
- '--request_format',
- choices=['json', 'xml', ],
- help=argparse.SUPPRESS)
-
- return parser
-
- def format_output_data(self, data):
- # Modify data to make it more readable
- if self.resource in data:
- for k, v in data[self.resource].iteritems():
- if isinstance(v, list):
- value = '\n'.join(utils.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 = utils.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 args2body(self, parsed_args):
- return {}
-
-
-class CreateCommand(QuantumCommand, show.ShowOne):
- """Create a resource for a given tenant
-
- """
-
- api = 'network'
- resource = None
- 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 get_data(self, parsed_args):
- self.log.debug('get_data(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- _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(quantum_client,
- "create_%s" % self.resource)
- data = obj_creator(body)
- self.format_output_data(data)
- # {u'network': {u'id': u'e9424a76-6db4-4c93-97b6-ec311cd51f19'}}
- info = self.resource in data and data[self.resource] or None
- if info:
- print >>self.app.stdout, _('Created a new %s:') % self.resource
- else:
- info = {'': ''}
- return zip(*sorted(info.iteritems()))
-
-
-class UpdateCommand(QuantumCommand):
- """Update resource's information
- """
-
- api = 'network'
- resource = None
- log = None
-
- def get_parser(self, prog_name):
- parser = super(UpdateCommand, self).get_parser(prog_name)
- parser.add_argument(
- 'id', metavar=self.resource.upper(),
- help='ID or name of %s to update' % self.resource)
- self.add_known_arguments(parser)
- return parser
-
- def run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- _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.resource)
- _id = find_resourceid_by_name_or_id(quantum_client,
- self.resource,
- parsed_args.id)
- obj_updator = getattr(quantum_client,
- "update_%s" % self.resource)
- obj_updator(_id, body)
- print >>self.app.stdout, (
- _('Updated %(resource)s: %(id)s') %
- {'id': parsed_args.id, 'resource': self.resource})
- return
-
-
-class DeleteCommand(QuantumCommand):
- """Delete a given resource
-
- """
-
- api = 'network'
- resource = None
- log = None
- allow_names = True
-
- def get_parser(self, prog_name):
- parser = super(DeleteCommand, self).get_parser(prog_name)
- if self.allow_names:
- help_str = 'ID or name of %s to delete'
- else:
- help_str = 'ID of %s to delete'
- parser.add_argument(
- 'id', metavar=self.resource.upper(),
- help=help_str % self.resource)
- return parser
-
- def run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- obj_deleter = getattr(quantum_client,
- "delete_%s" % self.resource)
- if self.allow_names:
- _id = find_resourceid_by_name_or_id(quantum_client, self.resource,
- parsed_args.id)
- else:
- _id = parsed_args.id
- obj_deleter(_id)
- print >>self.app.stdout, (_('Deleted %(resource)s: %(id)s')
- % {'id': parsed_args.id,
- 'resource': self.resource})
- return
-
-
-class ListCommand(QuantumCommand, lister.Lister):
- """List resources that belong to a given tenant
-
- """
-
- api = 'network'
- resource = None
- log = None
- _formatters = {}
- list_columns = []
- unknown_parts_flag = True
- pagination_support = False
- sorting_support = False
-
- 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)
- return parser
-
- 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'})
- return search_opts
-
- def call_server(self, quantum_client, search_opts, parsed_args):
- obj_lister = getattr(quantum_client,
- "list_%ss" % self.resource)
- data = obj_lister(**search_opts)
- return data
-
- def retrieve_list(self, parsed_args):
- """Retrieve a list of resources from Quantum server"""
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- _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(quantum_client, search_opts, parsed_args)
- collection = self.resource + "s"
- return data.get(collection, [])
-
- def extend_list(self, data, parsed_args):
- """Update a retrieved list.
-
- This method provides a way to modify a original list returned from
- the quantum server. For example, you can add subnet cidr information
- to a list network.
- """
- 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 = [x for x in self.list_columns if x in _columns]
- return (_columns, (utils.get_item_properties(
- s, _columns, formatters=self._formatters, )
- for s in info), )
-
- def get_data(self, parsed_args):
- self.log.debug('get_data(%s)' % parsed_args)
- data = self.retrieve_list(parsed_args)
- self.extend_list(data, parsed_args)
- return self.setup_columns(data, parsed_args)
-
-
-class ShowCommand(QuantumCommand, show.ShowOne):
- """Show information of a given resource
-
- """
-
- api = 'network'
- resource = None
- log = None
- allow_names = True
-
- 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'
- parser.add_argument(
- 'id', metavar=self.resource.upper(),
- help=help_str % self.resource)
- return parser
-
- def get_data(self, parsed_args):
- self.log.debug('get_data(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
-
- 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(quantum_client, self.resource,
- parsed_args.id)
- else:
- _id = parsed_args.id
-
- obj_shower = getattr(quantum_client, "show_%s" % self.resource)
- data = obj_shower(_id, **params)
- self.format_output_data(data)
- resource = data[self.resource]
- if self.resource in data:
- return zip(*sorted(resource.iteritems()))
- else:
- return None
+QuantumCommand = NeutronCommand
diff --git a/quantumclient/quantum/v2_0/agent.py b/quantumclient/quantum/v2_0/agent.py
deleted file mode 100644
index 67bf87e..0000000
--- a/quantumclient/quantum/v2_0/agent.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2013 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import logging
-
-from quantumclient.quantum import v2_0 as quantumV20
-
-
-def _format_timestamp(component):
- try:
- return component['heartbeat_timestamp'].split(".", 2)[0]
- except Exception:
- return ''
-
-
-class ListAgent(quantumV20.ListCommand):
- """List agents."""
-
- resource = 'agent'
- log = logging.getLogger(__name__ + '.ListAgent')
- list_columns = ['id', 'agent_type', 'host', 'alive', 'admin_state_up']
- _formatters = {'heartbeat_timestamp': _format_timestamp}
-
- def extend_list(self, data, parsed_args):
- for agent in data:
- agent['alive'] = ":-)" if agent['alive'] else 'xxx'
-
-
-class ShowAgent(quantumV20.ShowCommand):
- """Show information of a given agent."""
-
- resource = 'agent'
- log = logging.getLogger(__name__ + '.ShowAgent')
- allow_names = False
- json_indent = 5
-
-
-class DeleteAgent(quantumV20.DeleteCommand):
- """Delete a given agent."""
-
- log = logging.getLogger(__name__ + '.DeleteAgent')
- resource = 'agent'
- allow_names = False
-
-
-class UpdateAgent(quantumV20.UpdateCommand):
- """Update a given agent."""
-
- log = logging.getLogger(__name__ + '.UpdateAgent')
- resource = 'agent'
- allow_names = False
diff --git a/quantumclient/quantum/v2_0/agentscheduler.py b/quantumclient/quantum/v2_0/agentscheduler.py
deleted file mode 100644
index 8e41376..0000000
--- a/quantumclient/quantum/v2_0/agentscheduler.py
+++ /dev/null
@@ -1,234 +0,0 @@
-# Copyright 2013 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import logging
-
-from quantumclient.openstack.common.gettextutils import _
-from quantumclient.quantum import v2_0 as quantumV20
-from quantumclient.quantum.v2_0 import network
-from quantumclient.quantum.v2_0 import router
-PERFECT_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f"
-
-
-class AddNetworkToDhcpAgent(quantumV20.QuantumCommand):
- """Add a network to a DHCP agent."""
-
- log = logging.getLogger(__name__ + '.AddNetworkToDhcpAgent')
-
- def get_parser(self, prog_name):
- parser = super(AddNetworkToDhcpAgent, self).get_parser(prog_name)
- parser.add_argument(
- 'dhcp_agent',
- help='ID of the DHCP agent')
- parser.add_argument(
- 'network',
- help='network to add')
- return parser
-
- def run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- _net_id = quantumV20.find_resourceid_by_name_or_id(
- quantum_client, 'network', parsed_args.network)
- quantum_client.add_network_to_dhcp_agent(parsed_args.dhcp_agent,
- {'network_id': _net_id})
- print >>self.app.stdout, (
- _('Added network %s to DHCP agent') % parsed_args.network)
-
-
-class RemoveNetworkFromDhcpAgent(quantumV20.QuantumCommand):
- """Remove a network from a DHCP agent."""
- log = logging.getLogger(__name__ + '.RemoveNetworkFromDhcpAgent')
-
- def get_parser(self, prog_name):
- parser = super(RemoveNetworkFromDhcpAgent, self).get_parser(prog_name)
- parser.add_argument(
- 'dhcp_agent',
- help='ID of the DHCP agent')
- parser.add_argument(
- 'network',
- help='network to remove')
- return parser
-
- def run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- _net_id = quantumV20.find_resourceid_by_name_or_id(
- quantum_client, 'network', parsed_args.network)
- quantum_client.remove_network_from_dhcp_agent(
- parsed_args.dhcp_agent, _net_id)
- print >>self.app.stdout, (
- _('Removed network %s to DHCP agent') % parsed_args.network)
-
-
-class ListNetworksOnDhcpAgent(network.ListNetwork):
- """List the networks on a DHCP agent."""
-
- log = logging.getLogger(__name__ + '.ListNetworksOnDhcpAgent')
- unknown_parts_flag = False
-
- def get_parser(self, prog_name):
- parser = super(ListNetworksOnDhcpAgent,
- self).get_parser(prog_name)
- parser.add_argument(
- 'dhcp_agent',
- help='ID of the DHCP agent')
- return parser
-
- def call_server(self, quantum_client, search_opts, parsed_args):
- data = quantum_client.list_networks_on_dhcp_agent(
- parsed_args.dhcp_agent, **search_opts)
- return data
-
-
-class ListDhcpAgentsHostingNetwork(quantumV20.ListCommand):
- """List DHCP agents hosting a network."""
-
- resource = 'agent'
- _formatters = {}
- log = logging.getLogger(__name__ + '.ListDhcpAgentsHostingNetwork')
- 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',
- 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, quantum_client, search_opts, parsed_args):
- _id = quantumV20.find_resourceid_by_name_or_id(quantum_client,
- 'network',
- parsed_args.network)
- search_opts['network'] = _id
- data = quantum_client.list_dhcp_agent_hosting_networks(**search_opts)
- return data
-
-
-class AddRouterToL3Agent(quantumV20.QuantumCommand):
- """Add a router to a L3 agent."""
-
- log = logging.getLogger(__name__ + '.AddRouterToL3Agent')
-
- def get_parser(self, prog_name):
- parser = super(AddRouterToL3Agent, self).get_parser(prog_name)
- parser.add_argument(
- 'l3_agent',
- help='ID of the L3 agent')
- parser.add_argument(
- 'router',
- help='router to add')
- return parser
-
- def run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- _id = quantumV20.find_resourceid_by_name_or_id(
- quantum_client, 'router', parsed_args.router)
- quantum_client.add_router_to_l3_agent(parsed_args.l3_agent,
- {'router_id': _id})
- print >>self.app.stdout, (
- _('Added router %s to L3 agent') % parsed_args.router)
-
-
-class RemoveRouterFromL3Agent(quantumV20.QuantumCommand):
- """Remove a router from a L3 agent."""
-
- log = logging.getLogger(__name__ + '.RemoveRouterFromL3Agent')
-
- def get_parser(self, prog_name):
- parser = super(RemoveRouterFromL3Agent, self).get_parser(prog_name)
- parser.add_argument(
- 'l3_agent',
- help='ID of the L3 agent')
- parser.add_argument(
- 'router',
- help='router to remove')
- return parser
-
- def run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- _id = quantumV20.find_resourceid_by_name_or_id(
- quantum_client, 'router', parsed_args.router)
- quantum_client.remove_router_from_l3_agent(
- parsed_args.l3_agent, _id)
- print >>self.app.stdout, (
- _('Removed Router %s to L3 agent') % parsed_args.router)
-
-
-class ListRoutersOnL3Agent(quantumV20.ListCommand):
- """List the routers on a L3 agent."""
-
- log = logging.getLogger(__name__ + '.ListRoutersOnL3Agent')
- _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',
- help='ID of the L3 agent to query')
- return parser
-
- def call_server(self, quantum_client, search_opts, parsed_args):
- data = quantum_client.list_routers_on_l3_agent(
- parsed_args.l3_agent, **search_opts)
- return data
-
-
-class ListL3AgentsHostingRouter(quantumV20.ListCommand):
- """List L3 agents hosting a router."""
-
- resource = 'agent'
- _formatters = {}
- log = logging.getLogger(__name__ + '.ListL3AgentsHostingRouter')
- list_columns = ['id', 'host', 'admin_state_up', 'alive', 'default']
- unknown_parts_flag = False
-
- def get_parser(self, prog_name):
- parser = super(ListL3AgentsHostingRouter,
- self).get_parser(prog_name)
- parser.add_argument('router',
- help='router 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, quantum_client, search_opts, parsed_args):
- _id = quantumV20.find_resourceid_by_name_or_id(quantum_client,
- 'router',
- parsed_args.router)
- search_opts['router'] = _id
- data = quantum_client.list_l3_agent_hosting_routers(**search_opts)
- return data
diff --git a/quantumclient/quantum/v2_0/extension.py b/quantumclient/quantum/v2_0/extension.py
deleted file mode 100644
index 1ebea6f..0000000
--- a/quantumclient/quantum/v2_0/extension.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import logging
-
-from quantumclient.quantum import v2_0 as cmd_base
-
-
-class ListExt(cmd_base.ListCommand):
- """List all extensions."""
-
- resource = 'extension'
- log = logging.getLogger(__name__ + '.ListExt')
- list_columns = ['alias', 'name']
-
-
-class ShowExt(cmd_base.ShowCommand):
- """Show information of a given resource."""
-
- resource = "extension"
- log = logging.getLogger(__name__ + '.ShowExt')
- allow_names = False
-
- def get_parser(self, prog_name):
- parser = super(cmd_base.ShowCommand, self).get_parser(prog_name)
- cmd_base.add_show_list_common_argument(parser)
- parser.add_argument(
- 'id', metavar='EXT-ALIAS',
- help='the extension alias')
- return parser
diff --git a/quantumclient/quantum/v2_0/floatingip.py b/quantumclient/quantum/v2_0/floatingip.py
deleted file mode 100644
index 1d82444..0000000
--- a/quantumclient/quantum/v2_0/floatingip.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import argparse
-import logging
-
-from quantumclient.openstack.common.gettextutils import _
-from quantumclient.quantum import v2_0 as quantumv20
-
-
-class ListFloatingIP(quantumv20.ListCommand):
- """List floating ips that belong to a given tenant."""
-
- resource = 'floatingip'
- log = logging.getLogger(__name__ + '.ListFloatingIP')
- list_columns = ['id', 'fixed_ip_address', 'floating_ip_address',
- 'port_id']
- pagination_support = True
- sorting_support = True
-
-
-class ShowFloatingIP(quantumv20.ShowCommand):
- """Show information of a given floating ip."""
-
- resource = 'floatingip'
- log = logging.getLogger(__name__ + '.ShowFloatingIP')
- allow_names = False
-
-
-class CreateFloatingIP(quantumv20.CreateCommand):
- """Create a floating ip for a given tenant."""
-
- resource = 'floatingip'
- log = logging.getLogger(__name__ + '.CreateFloatingIP')
-
- def add_known_arguments(self, parser):
- parser.add_argument(
- 'floating_network_id', metavar='FLOATING_NETWORK',
- help='Network name or id to allocate floating IP from')
- parser.add_argument(
- '--port-id',
- help='ID of the port to be associated with the floatingip')
- 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)
-
- def args2body(self, parsed_args):
- _network_id = quantumv20.find_resourceid_by_name_or_id(
- self.get_client(), 'network', parsed_args.floating_network_id)
- body = {self.resource: {'floating_network_id': _network_id}}
- if parsed_args.port_id:
- body[self.resource].update({'port_id': parsed_args.port_id})
- if parsed_args.tenant_id:
- body[self.resource].update({'tenant_id': parsed_args.tenant_id})
- if parsed_args.fixed_ip_address:
- body[self.resource].update({'fixed_ip_address':
- parsed_args.fixed_ip_address})
- return body
-
-
-class DeleteFloatingIP(quantumv20.DeleteCommand):
- """Delete a given floating ip."""
-
- log = logging.getLogger(__name__ + '.DeleteFloatingIP')
- resource = 'floatingip'
- allow_names = False
-
-
-class AssociateFloatingIP(quantumv20.QuantumCommand):
- """Create a mapping between a floating ip and a fixed ip."""
-
- api = 'network'
- log = logging.getLogger(__name__ + '.AssociateFloatingIP')
- 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 floatingip')
- 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 run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- update_dict = {}
- if parsed_args.port_id:
- update_dict['port_id'] = parsed_args.port_id
- if parsed_args.fixed_ip_address:
- update_dict['fixed_ip_address'] = parsed_args.fixed_ip_address
- quantum_client.update_floatingip(parsed_args.floatingip_id,
- {'floatingip': update_dict})
- print >>self.app.stdout, (
- _('Associated floatingip %s') % parsed_args.floatingip_id)
-
-
-class DisassociateFloatingIP(quantumv20.QuantumCommand):
- """Remove a mapping from a floating ip to a fixed ip.
- """
-
- api = 'network'
- log = logging.getLogger(__name__ + '.DisassociateFloatingIP')
- 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 associate')
- return parser
-
- def run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- quantum_client.update_floatingip(parsed_args.floatingip_id,
- {'floatingip': {'port_id': None}})
- print >>self.app.stdout, (
- _('Disassociated floatingip %s') % parsed_args.floatingip_id)
diff --git a/quantumclient/quantum/v2_0/lb/__init__.py b/quantumclient/quantum/v2_0/lb/__init__.py
deleted file mode 100644
index 1668497..0000000
--- a/quantumclient/quantum/v2_0/lb/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2013 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
diff --git a/quantumclient/quantum/v2_0/lb/healthmonitor.py b/quantumclient/quantum/v2_0/lb/healthmonitor.py
deleted file mode 100644
index f0a828b..0000000
--- a/quantumclient/quantum/v2_0/lb/healthmonitor.py
+++ /dev/null
@@ -1,174 +0,0 @@
-# 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.
-#
-# @author: Ilya Shakhat, Mirantis Inc.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import logging
-
-from quantumclient.openstack.common.gettextutils import _
-from quantumclient.quantum import v2_0 as quantumv20
-
-
-class ListHealthMonitor(quantumv20.ListCommand):
- """List healthmonitors that belong to a given tenant."""
-
- resource = 'health_monitor'
- log = logging.getLogger(__name__ + '.ListHealthMonitor')
- list_columns = ['id', 'type', 'admin_state_up', 'status']
- pagination_support = True
- sorting_support = True
-
-
-class ShowHealthMonitor(quantumv20.ShowCommand):
- """Show information of a given healthmonitor."""
-
- resource = 'health_monitor'
- log = logging.getLogger(__name__ + '.ShowHealthMonitor')
-
-
-class CreateHealthMonitor(quantumv20.CreateCommand):
- """Create a healthmonitor."""
-
- resource = 'health_monitor'
- log = logging.getLogger(__name__ + '.CreateHealthMonitor')
-
- 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 minimum time in seconds between regular connections '
- 'of the member.')
- parser.add_argument(
- '--max-retries',
- required=True,
- help='number of permissible connection failures before changing '
- 'the member status to INACTIVE.')
- 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,
- help='one of predefined health monitor types, e.g. RoundRobin')
-
- def args2body(self, parsed_args):
- body = {
- self.resource: {
- '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,
- },
- }
- quantumv20.update_dict(parsed_args, body[self.resource],
- ['expected_codes', 'http_method', 'url_path',
- 'tenant_id'])
- return body
-
-
-class UpdateHealthMonitor(quantumv20.UpdateCommand):
- """Update a given healthmonitor."""
-
- resource = 'health_monitor'
- log = logging.getLogger(__name__ + '.UpdateHealthMonitor')
-
-
-class DeleteHealthMonitor(quantumv20.DeleteCommand):
- """Delete a given healthmonitor."""
-
- resource = 'health_monitor'
- log = logging.getLogger(__name__ + '.DeleteHealthMonitor')
-
-
-class AssociateHealthMonitor(quantumv20.QuantumCommand):
- """Create a mapping between a health monitor and a pool."""
-
- log = logging.getLogger(__name__ + '.AssociateHealthMonitor')
- resource = 'health_monitor'
-
- def get_parser(self, prog_name):
- parser = super(AssociateHealthMonitor, self).get_parser(prog_name)
- parser.add_argument(
- 'health_monitor_id',
- help='Health monitor to associate')
- parser.add_argument(
- 'pool_id',
- help='ID of the pool to be associated with the health monitor')
- return parser
-
- def run(self, parsed_args):
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- body = {'health_monitor': {'id': parsed_args.health_monitor_id}}
- pool_id = quantumv20.find_resourceid_by_name_or_id(
- quantum_client, 'pool', parsed_args.pool_id)
- quantum_client.associate_health_monitor(pool_id, body)
- print >>self.app.stdout, (_('Associated health monitor '
- '%s') % parsed_args.health_monitor_id)
-
-
-class DisassociateHealthMonitor(quantumv20.QuantumCommand):
- """Remove a mapping from a health monitor to a pool."""
-
- log = logging.getLogger(__name__ + '.DisassociateHealthMonitor')
- resource = 'health_monitor'
-
- def get_parser(self, prog_name):
- parser = super(DisassociateHealthMonitor, self).get_parser(prog_name)
- parser.add_argument(
- 'health_monitor_id',
- help='Health monitor to associate')
- parser.add_argument(
- 'pool_id',
- help='ID of the pool to be associated with the health monitor')
- return parser
-
- def run(self, parsed_args):
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- pool_id = quantumv20.find_resourceid_by_name_or_id(
- quantum_client, 'pool', parsed_args.pool_id)
- quantum_client.disassociate_health_monitor(pool_id,
- parsed_args
- .health_monitor_id)
- print >>self.app.stdout, (_('Disassociated health monitor '
- '%s') % parsed_args.health_monitor_id)
diff --git a/quantumclient/quantum/v2_0/lb/member.py b/quantumclient/quantum/v2_0/lb/member.py
deleted file mode 100644
index 05fb430..0000000
--- a/quantumclient/quantum/v2_0/lb/member.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# 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.
-#
-# @author: Ilya Shakhat, Mirantis Inc.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import logging
-
-from quantumclient.quantum import v2_0 as quantumv20
-
-
-class ListMember(quantumv20.ListCommand):
- """List members that belong to a given tenant."""
-
- resource = 'member'
- log = logging.getLogger(__name__ + '.ListMember')
- list_columns = [
- 'id', 'address', 'protocol_port', 'admin_state_up', 'status'
- ]
- pagination_support = True
- sorting_support = True
-
-
-class ShowMember(quantumv20.ShowCommand):
- """Show information of a given member."""
-
- resource = 'member'
- log = logging.getLogger(__name__ + '.ShowMember')
-
-
-class CreateMember(quantumv20.CreateCommand):
- """Create a member."""
-
- resource = 'member'
- log = logging.getLogger(__name__ + '.CreateMember')
-
- def add_known_arguments(self, parser):
- parser.add_argument(
- 'pool_id', metavar='pool',
- help='Pool id or name this vip belongs to')
- 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')
- 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. ')
-
- def args2body(self, parsed_args):
- _pool_id = quantumv20.find_resourceid_by_name_or_id(
- self.get_client(), 'pool', parsed_args.pool_id)
- body = {
- self.resource: {
- 'pool_id': _pool_id,
- 'admin_state_up': parsed_args.admin_state,
- },
- }
- quantumv20.update_dict(
- parsed_args,
- body[self.resource],
- ['address', 'protocol_port', 'weight', 'tenant_id']
- )
- return body
-
-
-class UpdateMember(quantumv20.UpdateCommand):
- """Update a given member."""
-
- resource = 'member'
- log = logging.getLogger(__name__ + '.UpdateMember')
-
-
-class DeleteMember(quantumv20.DeleteCommand):
- """Delete a given member."""
-
- resource = 'member'
- log = logging.getLogger(__name__ + '.DeleteMember')
diff --git a/quantumclient/quantum/v2_0/lb/pool.py b/quantumclient/quantum/v2_0/lb/pool.py
deleted file mode 100644
index 869cf7a..0000000
--- a/quantumclient/quantum/v2_0/lb/pool.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# 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.
-#
-# @author: Ilya Shakhat, Mirantis Inc.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import logging
-
-from quantumclient.quantum import v2_0 as quantumv20
-
-
-class ListPool(quantumv20.ListCommand):
- """List pools that belong to a given tenant."""
-
- resource = 'pool'
- log = logging.getLogger(__name__ + '.ListPool')
- list_columns = ['id', 'name', 'lb_method', 'protocol',
- 'admin_state_up', 'status']
- pagination_support = True
- sorting_support = True
-
-
-class ShowPool(quantumv20.ShowCommand):
- """Show information of a given pool."""
-
- resource = 'pool'
- log = logging.getLogger(__name__ + '.ShowPool')
-
-
-class CreatePool(quantumv20.CreateCommand):
- """Create a pool."""
-
- resource = 'pool'
- log = logging.getLogger(__name__ + '.CreatePool')
-
- 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,
- 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,
- help='protocol for balancing')
- parser.add_argument(
- '--subnet-id',
- required=True,
- help='the subnet on which the members of the pool will be located')
-
- def args2body(self, parsed_args):
- _subnet_id = quantumv20.find_resourceid_by_name_or_id(
- self.get_client(), 'subnet', parsed_args.subnet_id)
- body = {
- self.resource: {
- 'admin_state_up': parsed_args.admin_state,
- 'subnet_id': _subnet_id,
- },
- }
- quantumv20.update_dict(parsed_args, body[self.resource],
- ['description', 'lb_method', 'name',
- 'protocol', 'tenant_id'])
- return body
-
-
-class UpdatePool(quantumv20.UpdateCommand):
- """Update a given pool."""
-
- resource = 'pool'
- log = logging.getLogger(__name__ + '.UpdatePool')
-
-
-class DeletePool(quantumv20.DeleteCommand):
- """Delete a given pool."""
-
- resource = 'pool'
- log = logging.getLogger(__name__ + '.DeletePool')
-
-
-class RetrievePoolStats(quantumv20.ShowCommand):
- """Retrieve stats for a given pool."""
-
- resource = 'pool'
- log = logging.getLogger(__name__ + '.RetrievePoolStats')
-
- def get_data(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- params = {}
- if parsed_args.fields:
- params = {'fields': parsed_args.fields}
-
- data = quantum_client.retrieve_pool_stats(parsed_args.id, **params)
- self.format_output_data(data)
- stats = data['stats']
- if 'stats' in data:
- return zip(*sorted(stats.iteritems()))
- else:
- return None
diff --git a/quantumclient/quantum/v2_0/lb/vip.py b/quantumclient/quantum/v2_0/lb/vip.py
deleted file mode 100644
index ced5b20..0000000
--- a/quantumclient/quantum/v2_0/lb/vip.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# 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.
-#
-# @author: Ilya Shakhat, Mirantis Inc.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import logging
-
-from quantumclient.quantum import v2_0 as quantumv20
-
-
-class ListVip(quantumv20.ListCommand):
- """List vips that belong to a given tenant."""
-
- resource = 'vip'
- log = logging.getLogger(__name__ + '.ListVip')
- list_columns = ['id', 'name', 'algorithm', 'address', 'protocol',
- 'admin_state_up', 'status']
- pagination_support = True
- sorting_support = True
-
-
-class ShowVip(quantumv20.ShowCommand):
- """Show information of a given vip."""
-
- resource = 'vip'
- log = logging.getLogger(__name__ + '.ShowVip')
-
-
-class CreateVip(quantumv20.CreateCommand):
- """Create a vip."""
-
- resource = 'vip'
- log = logging.getLogger(__name__ + '.CreateVip')
-
- def add_known_arguments(self, parser):
- parser.add_argument(
- 'pool_id', metavar='pool',
- help='Pool id or name this vip belongs to')
- 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')
- parser.add_argument(
- '--description',
- help='description of the vip')
- parser.add_argument(
- '--name',
- required=True,
- help='name of the vip')
- 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,
- help='protocol for balancing')
- parser.add_argument(
- '--subnet-id',
- required=True,
- help='the subnet on which to allocate the vip address')
-
- def args2body(self, parsed_args):
- _pool_id = quantumv20.find_resourceid_by_name_or_id(
- self.get_client(), 'pool', parsed_args.pool_id)
- _subnet_id = quantumv20.find_resourceid_by_name_or_id(
- self.get_client(), 'subnet', parsed_args.subnet_id)
- body = {
- self.resource: {
- 'pool_id': _pool_id,
- 'admin_state_up': parsed_args.admin_state,
- 'subnet_id': _subnet_id,
- },
- }
- quantumv20.update_dict(parsed_args, body[self.resource],
- ['address', 'connection_limit', 'description',
- 'name', 'protocol_port', 'protocol',
- 'tenant_id'])
- return body
-
-
-class UpdateVip(quantumv20.UpdateCommand):
- """Update a given vip."""
-
- resource = 'vip'
- log = logging.getLogger(__name__ + '.UpdateVip')
-
-
-class DeleteVip(quantumv20.DeleteCommand):
- """Delete a given vip."""
-
- resource = 'vip'
- log = logging.getLogger(__name__ + '.DeleteVip')
diff --git a/quantumclient/quantum/v2_0/network.py b/quantumclient/quantum/v2_0/network.py
deleted file mode 100644
index 31e621f..0000000
--- a/quantumclient/quantum/v2_0/network.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import argparse
-import logging
-
-from quantumclient.common import exceptions
-from quantumclient.quantum import v2_0 as quantumv20
-
-
-def _format_subnets(network):
- try:
- return '\n'.join([' '.join([s['id'], s.get('cidr', '')])
- for s in network['subnets']])
- except Exception:
- return ''
-
-
-class ListNetwork(quantumv20.ListCommand):
- """List networks that belong to a given tenant."""
-
- # Length of a query filter on subnet id
- # id=<uuid>& (with len(uuid)=36)
- subnet_id_filter_len = 40
- resource = 'network'
- log = logging.getLogger(__name__ + '.ListNetwork')
- _formatters = {'subnets': _format_subnets, }
- list_columns = ['id', 'name', 'subnets']
- pagination_support = True
- sorting_support = True
-
- def extend_list(self, data, parsed_args):
- """Add subnet information to a network list."""
- quantum_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 quantum_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 xrange(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."""
-
- log = logging.getLogger(__name__ + '.ListExternalNetwork')
- 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(quantumv20.ShowCommand):
- """Show information of a given network."""
-
- resource = 'network'
- log = logging.getLogger(__name__ + '.ShowNetwork')
-
-
-class CreateNetwork(quantumv20.CreateCommand):
- """Create a network for a given tenant."""
-
- resource = 'network'
- log = logging.getLogger(__name__ + '.CreateNetwork')
-
- 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')
- parser.add_argument(
- 'name', metavar='NAME',
- help='Name of network to create')
-
- def args2body(self, parsed_args):
- body = {'network': {
- 'name': parsed_args.name,
- 'admin_state_up': parsed_args.admin_state}, }
- if parsed_args.tenant_id:
- body['network'].update({'tenant_id': parsed_args.tenant_id})
- if parsed_args.shared:
- body['network'].update({'shared': parsed_args.shared})
- return body
-
-
-class DeleteNetwork(quantumv20.DeleteCommand):
- """Delete a given network."""
-
- log = logging.getLogger(__name__ + '.DeleteNetwork')
- resource = 'network'
-
-
-class UpdateNetwork(quantumv20.UpdateCommand):
- """Update network's information."""
-
- log = logging.getLogger(__name__ + '.UpdateNetwork')
- resource = 'network'
diff --git a/quantumclient/quantum/v2_0/nvp_qos_queue.py b/quantumclient/quantum/v2_0/nvp_qos_queue.py
deleted file mode 100644
index 386b887..0000000
--- a/quantumclient/quantum/v2_0/nvp_qos_queue.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Nicira 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 quantumclient.quantum import v2_0 as quantumv20
-
-
-class ListQoSQueue(quantumv20.ListCommand):
- """List queues that belong to a given tenant."""
-
- resource = 'qos_queue'
- log = logging.getLogger(__name__ + '.ListQoSQueue')
- list_columns = ['id', 'name', 'min', 'max',
- 'qos_marking', 'dscp', 'default']
-
-
-class ShowQoSQueue(quantumv20.ShowCommand):
- """Show information of a given queue."""
-
- resource = 'qos_queue'
- log = logging.getLogger(__name__ + '.ShowQoSQueue')
- allow_names = True
-
-
-class CreateQoSQueue(quantumv20.CreateCommand):
- """Create a queue."""
-
- resource = 'qos_queue'
- log = logging.getLogger(__name__ + '.CreateQoSQueue')
-
- def add_known_arguments(self, parser):
- parser.add_argument(
- 'name', metavar='NAME',
- help='Name of queue')
- parser.add_argument(
- '--min',
- help='min-rate'),
- parser.add_argument(
- '--max',
- help='max-rate'),
- parser.add_argument(
- '--qos-marking',
- help='qos marking untrusted/trusted'),
- parser.add_argument(
- '--default',
- default=False,
- help=('If true all ports created with be the size of this queue'
- ' if queue is not specified')),
- parser.add_argument(
- '--dscp',
- help='Differentiated Services Code Point'),
-
- def args2body(self, parsed_args):
- params = {'name': parsed_args.name,
- 'default': parsed_args.default}
- if parsed_args.min:
- params['min'] = parsed_args.min
- if parsed_args.max:
- params['max'] = parsed_args.max
- if parsed_args.qos_marking:
- params['qos_marking'] = parsed_args.qos_marking
- if parsed_args.dscp:
- params['dscp'] = parsed_args.dscp
- if parsed_args.tenant_id:
- params['tenant_id'] = parsed_args.tenant_id
- return {'qos_queue': params}
-
-
-class DeleteQoSQueue(quantumv20.DeleteCommand):
- """Delete a given queue."""
-
- log = logging.getLogger(__name__ + '.DeleteQoSQueue')
- resource = 'qos_queue'
- allow_names = True
diff --git a/quantumclient/quantum/v2_0/nvpnetworkgateway.py b/quantumclient/quantum/v2_0/nvpnetworkgateway.py
deleted file mode 100644
index 1823b6f..0000000
--- a/quantumclient/quantum/v2_0/nvpnetworkgateway.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# Copyright 2013 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import logging
-
-from quantumclient.common import utils
-from quantumclient.openstack.common.gettextutils import _
-from quantumclient.quantum import v2_0 as quantumv20
-
-RESOURCE = 'network_gateway'
-
-
-class ListNetworkGateway(quantumv20.ListCommand):
- """List network gateways for a given tenant."""
-
- resource = RESOURCE
- log = logging.getLogger(__name__ + '.ListNetworkGateway')
- list_columns = ['id', 'name']
-
-
-class ShowNetworkGateway(quantumv20.ShowCommand):
- """Show information of a given network gateway."""
-
- resource = RESOURCE
- log = logging.getLogger(__name__ + '.ShowNetworkGateway')
-
-
-class CreateNetworkGateway(quantumv20.CreateCommand):
- """Create a network gateway."""
-
- resource = RESOURCE
- log = logging.getLogger(__name__ + '.CreateNetworkGateway')
-
- def add_known_arguments(self, parser):
- parser.add_argument(
- 'name', metavar='NAME',
- help='Name of network gateway to create')
- parser.add_argument(
- '--device',
- action='append',
- help='device info for this gateway '
- 'device_id=<device identifier>,'
- 'interface_name=<name_or_identifier> '
- 'It can be repeated for multiple devices for HA gateways')
-
- def args2body(self, parsed_args):
- body = {self.resource: {
- 'name': parsed_args.name}}
- devices = []
- if parsed_args.device:
- for device in parsed_args.device:
- devices.append(utils.str2dict(device))
- if devices:
- body[self.resource].update({'devices': devices})
- if parsed_args.tenant_id:
- body[self.resource].update({'tenant_id': parsed_args.tenant_id})
- return body
-
-
-class DeleteNetworkGateway(quantumv20.DeleteCommand):
- """Delete a given network gateway."""
-
- resource = RESOURCE
- log = logging.getLogger(__name__ + '.DeleteNetworkGateway')
-
-
-class UpdateNetworkGateway(quantumv20.UpdateCommand):
- """Update the name for a network gateway."""
-
- resource = RESOURCE
- log = logging.getLogger(__name__ + '.UpdateNetworkGateway')
-
-
-class NetworkGatewayInterfaceCommand(quantumv20.QuantumCommand):
- """Base class for connecting/disconnecting networks to/from a gateway."""
-
- resource = RESOURCE
-
- def get_parser(self, prog_name):
- parser = super(NetworkGatewayInterfaceCommand,
- self).get_parser(prog_name)
- parser.add_argument(
- 'net_gateway_id', metavar='NET-GATEWAY-ID',
- help='ID of the network gateway')
- parser.add_argument(
- 'network_id', metavar='NETWORK-ID',
- help='ID of the internal network to connect on the gateway')
- parser.add_argument(
- '--segmentation-type',
- help=('L2 segmentation strategy on the external side of '
- 'the gateway (e.g.: VLAN, FLAT)'))
- parser.add_argument(
- '--segmentation-id',
- help=('Identifier for the L2 segment on the external side '
- 'of the gateway'))
- return parser
-
- def retrieve_ids(self, client, args):
- gateway_id = quantumv20.find_resourceid_by_name_or_id(
- client, self.resource, args.net_gateway_id)
- network_id = quantumv20.find_resourceid_by_name_or_id(
- client, 'network', args.network_id)
- return (gateway_id, network_id)
-
-
-class ConnectNetworkGateway(NetworkGatewayInterfaceCommand):
- """Add an internal network interface to a router."""
-
- log = logging.getLogger(__name__ + '.ConnectNetworkGateway')
-
- def run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- (gateway_id, network_id) = self.retrieve_ids(quantum_client,
- parsed_args)
- quantum_client.connect_network_gateway(
- gateway_id, {'network_id': network_id,
- 'segmentation_type': parsed_args.segmentation_type,
- 'segmentation_id': parsed_args.segmentation_id})
- # TODO(Salvatore-Orlando): Do output formatting as
- # any other command
- print >>self.app.stdout, (
- _('Connected network to gateway %s') % gateway_id)
-
-
-class DisconnectNetworkGateway(NetworkGatewayInterfaceCommand):
- """Remove a network from a network gateway."""
-
- log = logging.getLogger(__name__ + '.DisconnectNetworkGateway')
-
- def run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- (gateway_id, network_id) = self.retrieve_ids(quantum_client,
- parsed_args)
- quantum_client.disconnect_network_gateway(
- gateway_id, {'network_id': network_id,
- 'segmentation_type': parsed_args.segmentation_type,
- 'segmentation_id': parsed_args.segmentation_id})
- # TODO(Salvatore-Orlando): Do output formatting as
- # any other command
- print >>self.app.stdout, (
- _('Disconnected network from gateway %s') % gateway_id)
diff --git a/quantumclient/quantum/v2_0/port.py b/quantumclient/quantum/v2_0/port.py
index 0d6af60..55b39e9 100644
--- a/quantumclient/quantum/v2_0/port.py
+++ b/quantumclient/quantum/v2_0/port.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenStack LLC.
+# Copyright 2013 OpenStack Foundation.
# All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -15,170 +15,4 @@
#
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-import argparse
-import logging
-
-from quantumclient.common import utils
-from quantumclient.quantum import v2_0 as quantumv20
-
-
-def _format_fixed_ips(port):
- try:
- return '\n'.join([utils.dumps(ip) for ip in port['fixed_ips']])
- except Exception:
- return ''
-
-
-class ListPort(quantumv20.ListCommand):
- """List ports that belong to a given tenant."""
-
- resource = 'port'
- log = logging.getLogger(__name__ + '.ListPort')
- _formatters = {'fixed_ips': _format_fixed_ips, }
- list_columns = ['id', 'name', 'mac_address', 'fixed_ips']
- pagination_support = True
- sorting_support = True
-
-
-class ListRouterPort(quantumv20.ListCommand):
- """List ports that belong to a given tenant, with specified router."""
-
- resource = 'port'
- log = logging.getLogger(__name__ + '.ListRouterPort')
- _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 router to look up')
- return parser
-
- def get_data(self, parsed_args):
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- _id = quantumv20.find_resourceid_by_name_or_id(
- quantum_client, 'router', parsed_args.id)
- self.values_specs.append('--device_id=%s' % _id)
- return super(ListRouterPort, self).get_data(parsed_args)
-
-
-class ShowPort(quantumv20.ShowCommand):
- """Show information of a given port."""
-
- resource = 'port'
- log = logging.getLogger(__name__ + '.ShowPort')
-
-
-class CreatePort(quantumv20.CreateCommand):
- """Create a port for a given tenant."""
-
- resource = 'port'
- log = logging.getLogger(__name__ + '.CreatePort')
-
- def add_known_arguments(self, parser):
- parser.add_argument(
- '--name',
- help='name of this port')
- 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(
- '--device-id',
- help='device id of this port')
- parser.add_argument(
- '--device_id',
- help=argparse.SUPPRESS)
- parser.add_argument(
- '--fixed-ip', metavar='ip_address=IP_ADDR',
- action='append',
- help='desired IP for this port: '
- 'subnet_id=<name_or_id>,ip_address=<ip>, '
- '(This option can be repeated.)')
- parser.add_argument(
- '--fixed_ip',
- action='append',
- help=argparse.SUPPRESS)
- parser.add_argument(
- '--security-group', metavar='SECURITY_GROUP',
- default=[], action='append', dest='security_groups',
- help='security group associated with the port '
- '(This option can be repeated)')
- parser.add_argument(
- 'network_id', metavar='NETWORK',
- help='Network id or name this port belongs to')
-
- def args2body(self, parsed_args):
- _network_id = quantumv20.find_resourceid_by_name_or_id(
- self.get_client(), 'network', parsed_args.network_id)
- body = {'port': {'admin_state_up': parsed_args.admin_state,
- 'network_id': _network_id, }, }
- if parsed_args.mac_address:
- body['port'].update({'mac_address': parsed_args.mac_address})
- if parsed_args.device_id:
- body['port'].update({'device_id': parsed_args.device_id})
- if parsed_args.tenant_id:
- body['port'].update({'tenant_id': parsed_args.tenant_id})
- if parsed_args.name:
- body['port'].update({'name': parsed_args.name})
- ips = []
- if parsed_args.fixed_ip:
- for ip_spec in parsed_args.fixed_ip:
- ip_dict = utils.str2dict(ip_spec)
- if 'subnet_id' in ip_dict:
- subnet_name_id = ip_dict['subnet_id']
- _subnet_id = quantumv20.find_resourceid_by_name_or_id(
- self.get_client(), 'subnet', subnet_name_id)
- ip_dict['subnet_id'] = _subnet_id
- ips.append(ip_dict)
- if ips:
- body['port'].update({'fixed_ips': ips})
-
- _sgids = []
- for sg in parsed_args.security_groups:
- _sgids.append(quantumv20.find_resourceid_by_name_or_id(
- self.get_client(), 'security_group', sg))
- if _sgids:
- body['port']['security_groups'] = _sgids
-
- return body
-
-
-class DeletePort(quantumv20.DeleteCommand):
- """Delete a given port."""
-
- resource = 'port'
- log = logging.getLogger(__name__ + '.DeletePort')
-
-
-class UpdatePort(quantumv20.UpdateCommand):
- """Update port's information."""
-
- resource = 'port'
- log = logging.getLogger(__name__ + '.UpdatePort')
-
- def add_known_arguments(self, parser):
- parser.add_argument(
- '--no-security-groups',
- action='store_true',
- help='remove security groups from port')
-
- def args2body(self, parsed_args):
- body = {'port': {}}
- if parsed_args.no_security_groups:
- body['port'].update({'security_groups': None})
- return body
+from neutronclient.neutron.v2_0.port import _format_fixed_ips # noqa
diff --git a/quantumclient/quantum/v2_0/quota.py b/quantumclient/quantum/v2_0/quota.py
deleted file mode 100644
index 1c15192..0000000
--- a/quantumclient/quantum/v2_0/quota.py
+++ /dev/null
@@ -1,232 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import argparse
-import logging
-
-from cliff import lister
-from cliff import show
-
-from quantumclient.common import exceptions
-from quantumclient.common import utils
-from quantumclient.openstack.common.gettextutils import _
-from quantumclient.quantum import v2_0 as quantumv20
-
-
-def get_tenant_id(tenant_id, client):
- return (tenant_id if tenant_id else
- client.get_quotas_tenant()['tenant']['tenant_id'])
-
-
-class DeleteQuota(quantumv20.QuantumCommand):
- """Delete defined quotas of a given tenant."""
-
- api = 'network'
- resource = 'quota'
- log = logging.getLogger(__name__ + '.DeleteQuota')
-
- 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)
- return parser
-
- def run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- tenant_id = get_tenant_id(parsed_args.tenant_id,
- quantum_client)
- obj_deleter = getattr(quantum_client,
- "delete_%s" % self.resource)
- obj_deleter(tenant_id)
- print >>self.app.stdout, (_('Deleted %(resource)s: %(tenant_id)s')
- % {'tenant_id': tenant_id,
- 'resource': self.resource})
- return
-
-
-class ListQuota(quantumv20.QuantumCommand, lister.Lister):
- """List defined quotas of all tenants."""
-
- api = 'network'
- resource = 'quota'
- log = logging.getLogger(__name__ + '.ListQuota')
-
- def get_parser(self, prog_name):
- parser = super(ListQuota, self).get_parser(prog_name)
- return parser
-
- def get_data(self, parsed_args):
- self.log.debug('get_data(%s)' % parsed_args)
- quantum_client = self.get_client()
- search_opts = {}
- self.log.debug('search options: %s', search_opts)
- quantum_client.format = parsed_args.request_format
- obj_lister = getattr(quantum_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 ShowQuota(quantumv20.QuantumCommand, show.ShowOne):
- """Show quotas of a given tenant
-
- """
- api = 'network'
- resource = "quota"
- log = logging.getLogger(__name__ + '.ShowQuota')
-
- def get_parser(self, prog_name):
- parser = super(ShowQuota, 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)
- return parser
-
- def get_data(self, parsed_args):
- self.log.debug('get_data(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- tenant_id = get_tenant_id(parsed_args.tenant_id,
- quantum_client)
- params = {}
- obj_shower = getattr(quantum_client,
- "show_%s" % self.resource)
- data = obj_shower(tenant_id, **params)
- if self.resource in data:
- for k, v in data[self.resource].iteritems():
- if isinstance(v, list):
- value = ""
- for _item in v:
- if value:
- value += "\n"
- if isinstance(_item, dict):
- value += utils.dumps(_item)
- else:
- value += str(_item)
- data[self.resource][k] = value
- elif v is None:
- data[self.resource][k] = ''
- return zip(*sorted(data[self.resource].iteritems()))
- else:
- return None
-
-
-class UpdateQuota(quantumv20.QuantumCommand, show.ShowOne):
- """Define tenant's quotas not to use defaults."""
-
- resource = 'quota'
- log = logging.getLogger(__name__ + '.UpdateQuota')
-
- 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')
- 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.QuantumClientException(message=message)
- return return_value
-
- def args2body(self, parsed_args):
- quota = {}
- for resource in ('network', 'subnet', 'port', 'router', 'floatingip',
- 'security_group', 'security_group_rule'):
- if getattr(parsed_args, resource):
- quota[resource] = self._validate_int(
- resource,
- getattr(parsed_args, resource))
- return {self.resource: quota}
-
- def get_data(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- _extra_values = quantumv20.parse_args_to_dict(self.values_specs)
- quantumv20._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(quantum_client,
- "update_%s" % self.resource)
- tenant_id = get_tenant_id(parsed_args.tenant_id,
- quantum_client)
- data = obj_updator(tenant_id, body)
- if self.resource in data:
- for k, v in data[self.resource].iteritems():
- if isinstance(v, list):
- value = ""
- for _item in v:
- if value:
- value += "\n"
- if isinstance(_item, dict):
- value += utils.dumps(_item)
- else:
- value += str(_item)
- data[self.resource][k] = value
- elif v is None:
- data[self.resource][k] = ''
- return zip(*sorted(data[self.resource].iteritems()))
- else:
- return None
diff --git a/quantumclient/quantum/v2_0/router.py b/quantumclient/quantum/v2_0/router.py
deleted file mode 100644
index c5b1570..0000000
--- a/quantumclient/quantum/v2_0/router.py
+++ /dev/null
@@ -1,230 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import argparse
-import logging
-
-from quantumclient.common import exceptions
-from quantumclient.common import utils
-from quantumclient.openstack.common.gettextutils import _
-from quantumclient.quantum import v2_0 as quantumv20
-
-
-def _format_external_gateway_info(router):
- try:
- return utils.dumps(router['external_gateway_info'])
- except Exception:
- return ''
-
-
-class ListRouter(quantumv20.ListCommand):
- """List routers that belong to a given tenant."""
-
- resource = 'router'
- log = logging.getLogger(__name__ + '.ListRouter')
- _formatters = {'external_gateway_info': _format_external_gateway_info, }
- list_columns = ['id', 'name', 'external_gateway_info']
- pagination_support = True
- sorting_support = True
-
-
-class ShowRouter(quantumv20.ShowCommand):
- """Show information of a given router."""
-
- resource = 'router'
- log = logging.getLogger(__name__ + '.ShowRouter')
-
-
-class CreateRouter(quantumv20.CreateCommand):
- """Create a router for a given tenant."""
-
- resource = 'router'
- log = logging.getLogger(__name__ + '.CreateRouter')
- _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 router to create')
-
- def args2body(self, parsed_args):
- body = {'router': {
- 'name': parsed_args.name,
- 'admin_state_up': parsed_args.admin_state, }, }
- if parsed_args.tenant_id:
- body['router'].update({'tenant_id': parsed_args.tenant_id})
- return body
-
-
-class DeleteRouter(quantumv20.DeleteCommand):
- """Delete a given router."""
-
- log = logging.getLogger(__name__ + '.DeleteRouter')
- resource = 'router'
-
-
-class UpdateRouter(quantumv20.UpdateCommand):
- """Update router's information."""
-
- log = logging.getLogger(__name__ + '.UpdateRouter')
- resource = 'router'
-
-
-class RouterInterfaceCommand(quantumv20.QuantumCommand):
- """Based class to Add/Remove router interface."""
-
- api = 'network'
- resource = 'router'
-
- def call_api(self, quantum_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_id', metavar='router-id',
- help='ID 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 subnet.')
- return parser
-
- def run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
-
- 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 = quantumv20.find_resourceid_by_name_or_id(
- quantum_client, self.resource, parsed_args.router_id)
-
- _interface_id = quantumv20.find_resourceid_by_name_or_id(
- quantum_client, resource, value)
- body = {'%s_id' % resource: _interface_id}
-
- portinfo = self.call_api(quantum_client, _router_id, body)
- print >>self.app.stdout, self.success_message(parsed_args.router_id,
- portinfo)
-
-
-class AddInterfaceRouter(RouterInterfaceCommand):
- """Add an internal network interface to a router."""
-
- log = logging.getLogger(__name__ + '.AddInterfaceRouter')
-
- def call_api(self, quantum_client, router_id, body):
- return quantum_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."""
-
- log = logging.getLogger(__name__ + '.RemoveInterfaceRouter')
-
- def call_api(self, quantum_client, router_id, body):
- return quantum_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(quantumv20.QuantumCommand):
- """Set the external network gateway for a router."""
-
- log = logging.getLogger(__name__ + '.SetGatewayRouter')
- api = 'network'
- resource = 'router'
-
- def get_parser(self, prog_name):
- parser = super(SetGatewayRouter, self).get_parser(prog_name)
- parser.add_argument(
- 'router_id', metavar='router-id',
- help='ID of the router')
- parser.add_argument(
- 'external_network_id', metavar='external-network-id',
- help='ID of the external network for the gateway')
- parser.add_argument(
- '--disable-snat', action='store_false', dest='enable_snat',
- help='Disable Source NAT on the router gateway')
- return parser
-
- def run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- _router_id = quantumv20.find_resourceid_by_name_or_id(
- quantum_client, self.resource, parsed_args.router_id)
- _ext_net_id = quantumv20.find_resourceid_by_name_or_id(
- quantum_client, 'network', parsed_args.external_network_id)
- quantum_client.add_gateway_router(
- _router_id,
- {'network_id': _ext_net_id,
- 'enable_snat': parsed_args.enable_snat})
- print >>self.app.stdout, (
- _('Set gateway for router %s') % parsed_args.router_id)
-
-
-class RemoveGatewayRouter(quantumv20.QuantumCommand):
- """Remove an external network gateway from a router."""
-
- log = logging.getLogger(__name__ + '.RemoveGatewayRouter')
- api = 'network'
- resource = 'router'
-
- def get_parser(self, prog_name):
- parser = super(RemoveGatewayRouter, self).get_parser(prog_name)
- parser.add_argument(
- 'router_id', metavar='router-id',
- help='ID of the router')
- return parser
-
- def run(self, parsed_args):
- self.log.debug('run(%s)' % parsed_args)
- quantum_client = self.get_client()
- quantum_client.format = parsed_args.request_format
- _router_id = quantumv20.find_resourceid_by_name_or_id(
- quantum_client, self.resource, parsed_args.router_id)
- quantum_client.remove_gateway_router(_router_id)
- print >>self.app.stdout, (
- _('Removed gateway from router %s') % parsed_args.router_id)
diff --git a/quantumclient/quantum/v2_0/securitygroup.py b/quantumclient/quantum/v2_0/securitygroup.py
deleted file mode 100644
index 5fa899c..0000000
--- a/quantumclient/quantum/v2_0/securitygroup.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import argparse
-import logging
-
-from quantumclient.quantum import v2_0 as quantumv20
-
-
-class ListSecurityGroup(quantumv20.ListCommand):
- """List security groups that belong to a given tenant."""
-
- resource = 'security_group'
- log = logging.getLogger(__name__ + '.ListSecurityGroup')
- list_columns = ['id', 'name', 'description']
- pagination_support = True
- sorting_support = True
-
-
-class ShowSecurityGroup(quantumv20.ShowCommand):
- """Show information of a given security group."""
-
- resource = 'security_group'
- log = logging.getLogger(__name__ + '.ShowSecurityGroup')
- allow_names = True
-
-
-class CreateSecurityGroup(quantumv20.CreateCommand):
- """Create a security group."""
-
- resource = 'security_group'
- log = logging.getLogger(__name__ + '.CreateSecurityGroup')
-
- def add_known_arguments(self, parser):
- parser.add_argument(
- 'name', metavar='NAME',
- help='Name of security group')
- parser.add_argument(
- '--description',
- help='description of security group')
-
- def args2body(self, parsed_args):
- body = {'security_group': {
- 'name': parsed_args.name}}
- if parsed_args.description:
- body['security_group'].update(
- {'description': parsed_args.description})
- if parsed_args.tenant_id:
- body['security_group'].update({'tenant_id': parsed_args.tenant_id})
- return body
-
-
-class DeleteSecurityGroup(quantumv20.DeleteCommand):
- """Delete a given security group."""
-
- log = logging.getLogger(__name__ + '.DeleteSecurityGroup')
- resource = 'security_group'
- allow_names = True
-
-
-class UpdateSecurityGroup(quantumv20.UpdateCommand):
- """Update a given security group."""
-
- log = logging.getLogger(__name__ + '.UpdateSecurityGroup')
- resource = 'security_group'
-
- def add_known_arguments(self, parser):
- parser.add_argument(
- '--name',
- help='Name of security group')
- parser.add_argument(
- '--description',
- help='description of security group')
-
- def args2body(self, parsed_args):
- body = {'security_group': {}}
- if parsed_args.name:
- body['security_group'].update(
- {'name': parsed_args.name})
- if parsed_args.description:
- body['security_group'].update(
- {'description': parsed_args.description})
- return body
-
-
-class ListSecurityGroupRule(quantumv20.ListCommand):
- """List security group rules that belong to a given tenant."""
-
- resource = 'security_group_rule'
- log = logging.getLogger(__name__ + '.ListSecurityGroupRule')
- list_columns = ['id', 'security_group_id', 'direction', 'protocol',
- 'remote_ip_prefix', 'remote_group_id']
- replace_rules = {'security_group_id': 'security_group',
- 'remote_group_id': 'remote_group'}
- 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 retrieve_list(self, parsed_args):
- parsed_args.fields = self.replace_columns(parsed_args.fields,
- self.replace_rules,
- reverse=True)
- return super(ListSecurityGroupRule, self).retrieve_list(parsed_args)
-
- def extend_list(self, data, parsed_args):
- if parsed_args.no_nameconv:
- return
- quantum_client = self.get_client()
- search_opts = {'fields': ['id', 'name']}
- if self.pagination_support:
- page_size = parsed_args.page_size
- if page_size:
- search_opts.update({'limit': page_size})
- sec_group_ids = set()
- for rule in data:
- for key in self.replace_rules:
- sec_group_ids.add(rule[key])
- search_opts.update({"id": sec_group_ids})
- secgroups = quantum_client.list_security_groups(**search_opts)
- secgroups = secgroups.get('security_groups', [])
- sg_dict = dict([(sg['id'], sg['name'])
- for sg in secgroups if sg['name']])
- for rule in data:
- for key in self.replace_rules:
- rule[key] = sg_dict.get(rule[key], rule[key])
-
- def setup_columns(self, info, parsed_args):
- 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:
- cols = self.replace_columns(info[0], self.replace_rules)
- parsed_args.columns = cols
- return (cols, info[1])
-
-
-class ShowSecurityGroupRule(quantumv20.ShowCommand):
- """Show information of a given security group rule."""
-
- resource = 'security_group_rule'
- log = logging.getLogger(__name__ + '.ShowSecurityGroupRule')
- allow_names = False
-
-
-class CreateSecurityGroupRule(quantumv20.CreateCommand):
- """Create a security group rule."""
-
- resource = 'security_group_rule'
- log = logging.getLogger(__name__ + '.CreateSecurityGroupRule')
-
- def add_known_arguments(self, parser):
- parser.add_argument(
- 'security_group_id', metavar='SECURITY_GROUP',
- help='Security group name or id to add rule.')
- parser.add_argument(
- '--direction',
- default='ingress', choices=['ingress', 'egress'],
- help='direction of traffic: ingress/egress')
- parser.add_argument(
- '--ethertype',
- default='IPv4',
- help='IPv4/IPv6')
- parser.add_argument(
- '--protocol',
- help='protocol of packet')
- parser.add_argument(
- '--port-range-min',
- help='starting port range')
- parser.add_argument(
- '--port_range_min',
- help=argparse.SUPPRESS)
- parser.add_argument(
- '--port-range-max',
- help='ending port range')
- 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='remote security group name or id to apply rule')
- parser.add_argument(
- '--remote_group_id',
- help=argparse.SUPPRESS)
-
- def args2body(self, parsed_args):
- _security_group_id = quantumv20.find_resourceid_by_name_or_id(
- self.get_client(), 'security_group', parsed_args.security_group_id)
- body = {'security_group_rule': {
- 'security_group_id': _security_group_id,
- 'direction': parsed_args.direction,
- 'ethertype': parsed_args.ethertype}}
- if parsed_args.protocol:
- body['security_group_rule'].update(
- {'protocol': parsed_args.protocol})
- if parsed_args.port_range_min:
- body['security_group_rule'].update(
- {'port_range_min': parsed_args.port_range_min})
- if parsed_args.port_range_max:
- body['security_group_rule'].update(
- {'port_range_max': parsed_args.port_range_max})
- if parsed_args.remote_ip_prefix:
- body['security_group_rule'].update(
- {'remote_ip_prefix': parsed_args.remote_ip_prefix})
- if parsed_args.remote_group_id:
- _remote_group_id = quantumv20.find_resourceid_by_name_or_id(
- self.get_client(), 'security_group',
- parsed_args.remote_group_id)
- body['security_group_rule'].update(
- {'remote_group_id': _remote_group_id})
- if parsed_args.tenant_id:
- body['security_group_rule'].update(
- {'tenant_id': parsed_args.tenant_id})
- return body
-
-
-class DeleteSecurityGroupRule(quantumv20.DeleteCommand):
- """Delete a given security group rule."""
-
- log = logging.getLogger(__name__ + '.DeleteSecurityGroupRule')
- resource = 'security_group_rule'
- allow_names = False
diff --git a/quantumclient/quantum/v2_0/subnet.py b/quantumclient/quantum/v2_0/subnet.py
deleted file mode 100644
index e79cdc0..0000000
--- a/quantumclient/quantum/v2_0/subnet.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import argparse
-import logging
-
-from quantumclient.common import exceptions
-from quantumclient.common import utils
-from quantumclient.quantum import v2_0 as quantumv20
-
-
-def _format_allocation_pools(subnet):
- try:
- return '\n'.join([utils.dumps(pool) for pool in
- subnet['allocation_pools']])
- except Exception:
- return ''
-
-
-def _format_dns_nameservers(subnet):
- try:
- return '\n'.join([utils.dumps(server) for server in
- subnet['dns_nameservers']])
- except Exception:
- return ''
-
-
-def _format_host_routes(subnet):
- try:
- return '\n'.join([utils.dumps(route) for route in
- subnet['host_routes']])
- except Exception:
- return ''
-
-
-class ListSubnet(quantumv20.ListCommand):
- """List networks that belong to a given tenant."""
-
- resource = 'subnet'
- log = logging.getLogger(__name__ + '.ListSubnet')
- _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(quantumv20.ShowCommand):
- """Show information of a given subnet."""
-
- resource = 'subnet'
- log = logging.getLogger(__name__ + '.ShowSubnet')
-
-
-class CreateSubnet(quantumv20.CreateCommand):
- """Create a subnet for a given tenant."""
-
- resource = 'subnet'
- log = logging.getLogger(__name__ + '.CreateSubnet')
-
- def add_known_arguments(self, parser):
- parser.add_argument(
- '--name',
- help='name of this subnet')
- parser.add_argument(
- '--ip-version',
- type=int,
- default=4, choices=[4, 6],
- help='IP version with default 4')
- parser.add_argument(
- '--ip_version',
- type=int,
- choices=[4, 6],
- help=argparse.SUPPRESS)
- parser.add_argument(
- '--gateway', metavar='GATEWAY_IP',
- help='gateway ip of this subnet')
- parser.add_argument(
- '--no-gateway',
- action='store_true',
- help='No distribution of gateway')
- parser.add_argument(
- '--allocation-pool', metavar='start=IP_ADDR,end=IP_ADDR',
- action='append', dest='allocation_pools', type=utils.str2dict,
- 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,
- help=argparse.SUPPRESS)
- parser.add_argument(
- '--host-route', metavar='destination=CIDR,nexthop=IP_ADDR',
- action='append', dest='host_routes', type=utils.str2dict,
- 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(
- 'network_id', metavar='NETWORK',
- help='network id or name this subnet belongs to')
- parser.add_argument(
- 'cidr', metavar='CIDR',
- help='cidr of subnet to create')
-
- def args2body(self, parsed_args):
- _network_id = quantumv20.find_resourceid_by_name_or_id(
- self.get_client(), 'network', parsed_args.network_id)
- body = {'subnet': {'cidr': parsed_args.cidr,
- 'network_id': _network_id,
- 'ip_version': parsed_args.ip_version, }, }
-
- if parsed_args.gateway and parsed_args.no_gateway:
- raise exceptions.CommandError("--gateway option and "
- "--no-gateway option can "
- "not be used same time")
- if parsed_args.no_gateway:
- body['subnet'].update({'gateway_ip': None})
- if parsed_args.gateway:
- body['subnet'].update({'gateway_ip': parsed_args.gateway})
- if parsed_args.tenant_id:
- body['subnet'].update({'tenant_id': parsed_args.tenant_id})
- if parsed_args.name:
- body['subnet'].update({'name': parsed_args.name})
- if parsed_args.disable_dhcp:
- body['subnet'].update({'enable_dhcp': False})
- if parsed_args.allocation_pools:
- body['subnet']['allocation_pools'] = parsed_args.allocation_pools
- if parsed_args.host_routes:
- body['subnet']['host_routes'] = parsed_args.host_routes
- if parsed_args.dns_nameservers:
- body['subnet']['dns_nameservers'] = parsed_args.dns_nameservers
-
- return body
-
-
-class DeleteSubnet(quantumv20.DeleteCommand):
- """Delete a given subnet."""
-
- resource = 'subnet'
- log = logging.getLogger(__name__ + '.DeleteSubnet')
-
-
-class UpdateSubnet(quantumv20.UpdateCommand):
- """Update subnet's information."""
-
- resource = 'subnet'
- log = logging.getLogger(__name__ + '.UpdateSubnet')
diff --git a/quantumclient/shell.py b/quantumclient/shell.py
index 29c56f0..ce7647d 100644
--- a/quantumclient/shell.py
+++ b/quantumclient/shell.py
@@ -19,637 +19,14 @@
Command-line interface to the Quantum APIs
"""
-import argparse
-import logging
-import os
import sys
-from cliff import app
-from cliff import commandmanager
-
-from quantumclient.common import clientmanager
-from quantumclient.common import exceptions as exc
-from quantumclient.common import utils
-from quantumclient.openstack.common import strutils
-from quantumclient.version import __version__
-
-
-VERSION = '2.0'
-QUANTUM_API_VERSION = '2.0'
-
-
-def run_command(cmd, cmd_parser, sub_argv):
- _argv = sub_argv
- index = -1
- values_specs = []
- if '--' in sub_argv:
- index = sub_argv.index('--')
- _argv = sub_argv[:index]
- values_specs = sub_argv[index:]
- known_args, _values_specs = cmd_parser.parse_known_args(_argv)
- cmd.values_specs = (index == -1 and _values_specs or values_specs)
- return cmd.run(known_args)
-
-
-def env(*_vars, **kwargs):
- """Search for the first defined of possibly many env vars
-
- Returns the first environment variable defined in vars, or
- returns the default defined in kwargs.
-
- """
- for v in _vars:
- value = os.environ.get(v, None)
- if value:
- return value
- return kwargs.get('default', '')
-
-
-COMMAND_V2 = {
- 'net-list': utils.import_class(
- 'quantumclient.quantum.v2_0.network.ListNetwork'),
- 'net-external-list': utils.import_class(
- 'quantumclient.quantum.v2_0.network.ListExternalNetwork'),
- 'net-show': utils.import_class(
- 'quantumclient.quantum.v2_0.network.ShowNetwork'),
- 'net-create': utils.import_class(
- 'quantumclient.quantum.v2_0.network.CreateNetwork'),
- 'net-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.network.DeleteNetwork'),
- 'net-update': utils.import_class(
- 'quantumclient.quantum.v2_0.network.UpdateNetwork'),
- 'subnet-list': utils.import_class(
- 'quantumclient.quantum.v2_0.subnet.ListSubnet'),
- 'subnet-show': utils.import_class(
- 'quantumclient.quantum.v2_0.subnet.ShowSubnet'),
- 'subnet-create': utils.import_class(
- 'quantumclient.quantum.v2_0.subnet.CreateSubnet'),
- 'subnet-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.subnet.DeleteSubnet'),
- 'subnet-update': utils.import_class(
- 'quantumclient.quantum.v2_0.subnet.UpdateSubnet'),
- 'port-list': utils.import_class(
- 'quantumclient.quantum.v2_0.port.ListPort'),
- 'port-show': utils.import_class(
- 'quantumclient.quantum.v2_0.port.ShowPort'),
- 'port-create': utils.import_class(
- 'quantumclient.quantum.v2_0.port.CreatePort'),
- 'port-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.port.DeletePort'),
- 'port-update': utils.import_class(
- 'quantumclient.quantum.v2_0.port.UpdatePort'),
- 'quota-list': utils.import_class(
- 'quantumclient.quantum.v2_0.quota.ListQuota'),
- 'quota-show': utils.import_class(
- 'quantumclient.quantum.v2_0.quota.ShowQuota'),
- 'quota-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.quota.DeleteQuota'),
- 'quota-update': utils.import_class(
- 'quantumclient.quantum.v2_0.quota.UpdateQuota'),
- 'ext-list': utils.import_class(
- 'quantumclient.quantum.v2_0.extension.ListExt'),
- 'ext-show': utils.import_class(
- 'quantumclient.quantum.v2_0.extension.ShowExt'),
- 'router-list': utils.import_class(
- 'quantumclient.quantum.v2_0.router.ListRouter'),
- 'router-port-list': utils.import_class(
- 'quantumclient.quantum.v2_0.port.ListRouterPort'),
- 'router-show': utils.import_class(
- 'quantumclient.quantum.v2_0.router.ShowRouter'),
- 'router-create': utils.import_class(
- 'quantumclient.quantum.v2_0.router.CreateRouter'),
- 'router-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.router.DeleteRouter'),
- 'router-update': utils.import_class(
- 'quantumclient.quantum.v2_0.router.UpdateRouter'),
- 'router-interface-add': utils.import_class(
- 'quantumclient.quantum.v2_0.router.AddInterfaceRouter'),
- 'router-interface-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.router.RemoveInterfaceRouter'),
- 'router-gateway-set': utils.import_class(
- 'quantumclient.quantum.v2_0.router.SetGatewayRouter'),
- 'router-gateway-clear': utils.import_class(
- 'quantumclient.quantum.v2_0.router.RemoveGatewayRouter'),
- 'floatingip-list': utils.import_class(
- 'quantumclient.quantum.v2_0.floatingip.ListFloatingIP'),
- 'floatingip-show': utils.import_class(
- 'quantumclient.quantum.v2_0.floatingip.ShowFloatingIP'),
- 'floatingip-create': utils.import_class(
- 'quantumclient.quantum.v2_0.floatingip.CreateFloatingIP'),
- 'floatingip-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.floatingip.DeleteFloatingIP'),
- 'floatingip-associate': utils.import_class(
- 'quantumclient.quantum.v2_0.floatingip.AssociateFloatingIP'),
- 'floatingip-disassociate': utils.import_class(
- 'quantumclient.quantum.v2_0.floatingip.DisassociateFloatingIP'),
- 'security-group-list': utils.import_class(
- 'quantumclient.quantum.v2_0.securitygroup.ListSecurityGroup'),
- 'security-group-show': utils.import_class(
- 'quantumclient.quantum.v2_0.securitygroup.ShowSecurityGroup'),
- 'security-group-create': utils.import_class(
- 'quantumclient.quantum.v2_0.securitygroup.CreateSecurityGroup'),
- 'security-group-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.securitygroup.DeleteSecurityGroup'),
- 'security-group-update': utils.import_class(
- 'quantumclient.quantum.v2_0.securitygroup.UpdateSecurityGroup'),
- 'security-group-rule-list': utils.import_class(
- 'quantumclient.quantum.v2_0.securitygroup.ListSecurityGroupRule'),
- 'security-group-rule-show': utils.import_class(
- 'quantumclient.quantum.v2_0.securitygroup.ShowSecurityGroupRule'),
- 'security-group-rule-create': utils.import_class(
- 'quantumclient.quantum.v2_0.securitygroup.CreateSecurityGroupRule'),
- 'security-group-rule-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.securitygroup.DeleteSecurityGroupRule'),
- 'lb-vip-list': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.vip.ListVip'),
- 'lb-vip-show': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.vip.ShowVip'),
- 'lb-vip-create': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.vip.CreateVip'),
- 'lb-vip-update': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.vip.UpdateVip'),
- 'lb-vip-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.vip.DeleteVip'),
- 'lb-pool-list': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.pool.ListPool'),
- 'lb-pool-show': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.pool.ShowPool'),
- 'lb-pool-create': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.pool.CreatePool'),
- 'lb-pool-update': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.pool.UpdatePool'),
- 'lb-pool-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.pool.DeletePool'),
- 'lb-pool-stats': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.pool.RetrievePoolStats'),
- 'lb-member-list': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.member.ListMember'),
- 'lb-member-show': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.member.ShowMember'),
- 'lb-member-create': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.member.CreateMember'),
- 'lb-member-update': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.member.UpdateMember'),
- 'lb-member-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.member.DeleteMember'),
- 'lb-healthmonitor-list': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.healthmonitor.ListHealthMonitor'),
- 'lb-healthmonitor-show': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.healthmonitor.ShowHealthMonitor'),
- 'lb-healthmonitor-create': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.healthmonitor.CreateHealthMonitor'),
- 'lb-healthmonitor-update': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.healthmonitor.UpdateHealthMonitor'),
- 'lb-healthmonitor-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.healthmonitor.DeleteHealthMonitor'),
- 'lb-healthmonitor-associate': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.healthmonitor.AssociateHealthMonitor'),
- 'lb-healthmonitor-disassociate': utils.import_class(
- 'quantumclient.quantum.v2_0.lb.healthmonitor'
- '.DisassociateHealthMonitor'),
- 'queue-create': utils.import_class(
- 'quantumclient.quantum.v2_0.nvp_qos_queue.CreateQoSQueue'),
- 'queue-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.nvp_qos_queue.DeleteQoSQueue'),
- 'queue-show': utils.import_class(
- 'quantumclient.quantum.v2_0.nvp_qos_queue.ShowQoSQueue'),
- 'queue-list': utils.import_class(
- 'quantumclient.quantum.v2_0.nvp_qos_queue.ListQoSQueue'),
- 'agent-list': utils.import_class(
- 'quantumclient.quantum.v2_0.agent.ListAgent'),
- 'agent-show': utils.import_class(
- 'quantumclient.quantum.v2_0.agent.ShowAgent'),
- 'agent-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.agent.DeleteAgent'),
- 'agent-update': utils.import_class(
- 'quantumclient.quantum.v2_0.agent.UpdateAgent'),
- 'net-gateway-create': utils.import_class(
- 'quantumclient.quantum.v2_0.nvpnetworkgateway.CreateNetworkGateway'),
- 'net-gateway-update': utils.import_class(
- 'quantumclient.quantum.v2_0.nvpnetworkgateway.UpdateNetworkGateway'),
- 'net-gateway-delete': utils.import_class(
- 'quantumclient.quantum.v2_0.nvpnetworkgateway.DeleteNetworkGateway'),
- 'net-gateway-show': utils.import_class(
- 'quantumclient.quantum.v2_0.nvpnetworkgateway.ShowNetworkGateway'),
- 'net-gateway-list': utils.import_class(
- 'quantumclient.quantum.v2_0.nvpnetworkgateway.ListNetworkGateway'),
- 'net-gateway-connect': utils.import_class(
- 'quantumclient.quantum.v2_0.nvpnetworkgateway.ConnectNetworkGateway'),
- 'net-gateway-disconnect': utils.import_class(
- 'quantumclient.quantum.v2_0.nvpnetworkgateway.'
- 'DisconnectNetworkGateway'),
- 'dhcp-agent-network-add': utils.import_class(
- 'quantumclient.quantum.v2_0.agentscheduler.AddNetworkToDhcpAgent'),
- 'dhcp-agent-network-remove': utils.import_class(
- 'quantumclient.quantum.v2_0.agentscheduler.'
- 'RemoveNetworkFromDhcpAgent'),
- 'net-list-on-dhcp-agent': utils.import_class(
- 'quantumclient.quantum.v2_0.agentscheduler.'
- 'ListNetworksOnDhcpAgent'),
- 'dhcp-agent-list-hosting-net': utils.import_class(
- 'quantumclient.quantum.v2_0.agentscheduler.'
- 'ListDhcpAgentsHostingNetwork'),
- 'l3-agent-router-add': utils.import_class(
- 'quantumclient.quantum.v2_0.agentscheduler.AddRouterToL3Agent'),
- 'l3-agent-router-remove': utils.import_class(
- 'quantumclient.quantum.v2_0.agentscheduler.RemoveRouterFromL3Agent'),
- 'router-list-on-l3-agent': utils.import_class(
- 'quantumclient.quantum.v2_0.agentscheduler.ListRoutersOnL3Agent'),
- 'l3-agent-list-hosting-router': utils.import_class(
- 'quantumclient.quantum.v2_0.agentscheduler.ListL3AgentsHostingRouter'),
-}
-
-COMMANDS = {'2.0': COMMAND_V2}
-
-
-class HelpAction(argparse.Action):
- """Provide a custom action so the -h and --help options
- to the main app will print a list of the commands.
-
- The commands are determined by checking the CommandManager
- instance, passed in as the "default" value for the action.
- """
- def __call__(self, parser, namespace, values, option_string=None):
- outputs = []
- max_len = 0
- app = self.default
- parser.print_help(app.stdout)
- app.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 QuantumShell(app.App):
-
- CONSOLE_MESSAGE_FORMAT = '%(message)s'
- DEBUG_MESSAGE_FORMAT = '%(levelname)s: %(name)s %(message)s'
- log = logging.getLogger(__name__)
-
- def __init__(self, apiversion):
- super(QuantumShell, self).__init__(
- description=__doc__.strip(),
- version=VERSION,
- command_manager=commandmanager.CommandManager('quantum.cli'), )
- self.commands = COMMANDS
- for k, v in self.commands[apiversion].items():
- self.command_manager.add_command(k, v)
-
- # This is instantiated in initialize_app() only when using
- # password flow auth
- self.auth_client = None
- self.api_version = apiversion
-
- def build_option_parser(self, description, version):
- """Return an argparse option parser for this application.
-
- Subclasses may override this method to extend
- the parser with more global options.
-
- :param description: full description of the application
- :paramtype description: str
- :param version: version number for the application
- :paramtype version: str
- """
- parser = argparse.ArgumentParser(
- description=description,
- add_help=False, )
- parser.add_argument(
- '--version',
- action='version',
- version=__version__, )
- parser.add_argument(
- '-v', '--verbose',
- action='count',
- dest='verbose_level',
- default=self.DEFAULT_VERBOSE_LEVEL,
- help='Increase verbosity of output. Can be repeated.', )
- 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(
- '--debug',
- default=False,
- action='store_true',
- help='show tracebacks on errors', )
- # Global arguments
- parser.add_argument(
- '--os-auth-strategy', metavar='<auth-strategy>',
- default=env('OS_AUTH_STRATEGY', default='keystone'),
- help='Authentication strategy (Env: OS_AUTH_STRATEGY'
- ', default keystone). For now, any other value will'
- ' disable the authentication')
- parser.add_argument(
- '--os_auth_strategy',
- help=argparse.SUPPRESS)
-
- parser.add_argument(
- '--os-auth-url', metavar='<auth-url>',
- default=env('OS_AUTH_URL'),
- help='Authentication URL (Env: OS_AUTH_URL)')
- parser.add_argument(
- '--os_auth_url',
- help=argparse.SUPPRESS)
-
- parser.add_argument(
- '--os-tenant-name', metavar='<auth-tenant-name>',
- default=env('OS_TENANT_NAME'),
- help='Authentication tenant name (Env: OS_TENANT_NAME)')
- parser.add_argument(
- '--os_tenant_name',
- help=argparse.SUPPRESS)
-
- parser.add_argument(
- '--os-username', metavar='<auth-username>',
- default=utils.env('OS_USERNAME'),
- help='Authentication username (Env: OS_USERNAME)')
- parser.add_argument(
- '--os_username',
- help=argparse.SUPPRESS)
-
- parser.add_argument(
- '--os-password', metavar='<auth-password>',
- default=utils.env('OS_PASSWORD'),
- help='Authentication password (Env: OS_PASSWORD)')
- parser.add_argument(
- '--os_password',
- help=argparse.SUPPRESS)
-
- parser.add_argument(
- '--os-region-name', metavar='<auth-region-name>',
- default=env('OS_REGION_NAME'),
- help='Authentication region name (Env: OS_REGION_NAME)')
- parser.add_argument(
- '--os_region_name',
- help=argparse.SUPPRESS)
-
- parser.add_argument(
- '--os-token', metavar='<token>',
- default=env('OS_TOKEN'),
- help='Defaults to env[OS_TOKEN]')
- parser.add_argument(
- '--os_token',
- help=argparse.SUPPRESS)
-
- parser.add_argument(
- '--endpoint-type', metavar='<endpoint-type>',
- default=env('OS_ENDPOINT_TYPE', default='publicURL'),
- help='Defaults to env[OS_ENDPOINT_TYPE] or publicURL.')
-
- parser.add_argument(
- '--os-url', metavar='<url>',
- default=env('OS_URL'),
- help='Defaults to env[OS_URL]')
- parser.add_argument(
- '--os_url',
- help=argparse.SUPPRESS)
-
- parser.add_argument(
- '--insecure',
- action='store_true',
- default=env('QUANTUMCLIENT_INSECURE', default=False),
- help="Explicitly allow quantumclient 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.")
-
- return parser
-
- def _bash_completion(self):
- """Prints all of the commands and options for bash-completion."""
- commands = set()
- options = set()
- for option, _action in self.parser._option_string_actions.items():
- options.add(option)
- for command_name, command in self.command_manager:
- commands.add(command_name)
- cmd_factory = command.load()
- cmd = cmd_factory(self, None)
- cmd_parser = cmd.get_parser('')
- for option, _action in cmd_parser._option_string_actions.items():
- options.add(option)
- print ' '.join(commands | options)
-
- def run(self, argv):
- """Equivalent to the main program for the application.
-
- :param argv: input arguments and options
- :paramtype argv: list of str
- """
- try:
- index = 0
- command_pos = -1
- help_pos = -1
- help_command_pos = -1
- for arg in argv:
- if arg == 'bash-completion':
- self._bash_completion()
- return 0
- if arg in self.commands[self.api_version]:
- if command_pos == -1:
- command_pos = index
- elif arg in ('-h', '--help'):
- if help_pos == -1:
- help_pos = index
- elif arg == 'help':
- if help_command_pos == -1:
- help_command_pos = index
- index = index + 1
- if command_pos > -1 and help_pos > command_pos:
- argv = ['help', argv[command_pos]]
- if help_command_pos > -1 and command_pos == -1:
- argv[help_command_pos] = '--help'
- self.options, remainder = self.parser.parse_known_args(argv)
- self.configure_logging()
- self.interactive_mode = not remainder
- self.initialize_app(remainder)
- except Exception as err:
- if self.options.debug:
- self.log.exception(unicode(err))
- raise
- else:
- self.log.error(unicode(err))
- return 1
- result = 1
- if self.interactive_mode:
- _argv = [sys.argv[0]]
- sys.argv = _argv
- result = self.interact()
- else:
- result = self.run_subcommand(remainder)
- return result
-
- def run_subcommand(self, argv):
- subcommand = self.command_manager.find_command(argv)
- cmd_factory, cmd_name, sub_argv = subcommand
- cmd = cmd_factory(self, self.options)
- err = None
- result = 1
- try:
- self.prepare_to_run_command(cmd)
- full_name = (cmd_name
- if self.interactive_mode
- else ' '.join([self.NAME, cmd_name])
- )
- cmd_parser = cmd.get_parser(full_name)
- return run_command(cmd, cmd_parser, sub_argv)
- except Exception as err:
- if self.options.debug:
- self.log.exception(unicode(err))
- else:
- self.log.error(unicode(err))
- try:
- self.clean_up(cmd, result, err)
- except Exception as err2:
- if self.options.debug:
- self.log.exception(unicode(err2))
- else:
- self.log.error('Could not clean up: %s', unicode(err2))
- if self.options.debug:
- raise
- else:
- try:
- self.clean_up(cmd, result, None)
- except Exception as err3:
- if self.options.debug:
- self.log.exception(unicode(err3))
- else:
- self.log.error('Could not clean up: %s', unicode(err3))
- return result
-
- def authenticate_user(self):
- """Make sure the user has provided all of the authentication
- info we need.
- """
- if self.options.os_auth_strategy == 'keystone':
- if self.options.os_token or self.options.os_url:
- # Token flow auth takes priority
- if not self.options.os_token:
- raise exc.CommandError(
- "You must provide a token via"
- " either --os-token or env[OS_TOKEN]")
-
- if not self.options.os_url:
- raise exc.CommandError(
- "You must provide a service URL via"
- " either --os-url or env[OS_URL]")
-
- else:
- # Validate password flow auth
- if not self.options.os_username:
- raise exc.CommandError(
- "You must provide a username via"
- " either --os-username or env[OS_USERNAME]")
-
- if not self.options.os_password:
- raise exc.CommandError(
- "You must provide a password via"
- " either --os-password or env[OS_PASSWORD]")
-
- if not (self.options.os_tenant_name):
- raise exc.CommandError(
- "You must provide a tenant_name via"
- " either --os-tenant-name or via env[OS_TENANT_NAME]")
-
- if not self.options.os_auth_url:
- raise exc.CommandError(
- "You must provide an auth url via"
- " either --os-auth-url or via env[OS_AUTH_URL]")
- else: # not keystone
- if not self.options.os_url:
- raise exc.CommandError(
- "You must provide a service URL via"
- " either --os-url or env[OS_URL]")
-
- self.client_manager = clientmanager.ClientManager(
- token=self.options.os_token,
- url=self.options.os_url,
- auth_url=self.options.os_auth_url,
- tenant_name=self.options.os_tenant_name,
- username=self.options.os_username,
- password=self.options.os_password,
- region_name=self.options.os_region_name,
- api_version=self.api_version,
- auth_strategy=self.options.os_auth_strategy,
- endpoint_type=self.options.endpoint_type,
- insecure=self.options.insecure, )
- return
-
- def initialize_app(self, argv):
- """Global app init bits:
-
- * set up API versions
- * validate authentication info
- """
-
- super(QuantumShell, self).initialize_app(argv)
-
- self.api_version = {'network': self.api_version}
-
- # If the user is not asking for help, make sure they
- # have given us auth.
- cmd_name = None
- if argv:
- cmd_info = self.command_manager.find_command(argv)
- cmd_factory, cmd_name, sub_argv = cmd_info
- if self.interactive_mode or cmd_name != 'help':
- self.authenticate_user()
-
- def clean_up(self, cmd, result, err):
- self.log.debug('clean_up %s', cmd.__class__.__name__)
- if err:
- self.log.debug('got an error: %s', unicode(err))
-
- def configure_logging(self):
- """Create logging handlers for any log output.
- """
- root_logger = logging.getLogger('')
-
- # Set up logging to a file
- root_logger.setLevel(logging.DEBUG)
-
- # Send higher-level messages to the console via stderr
- console = logging.StreamHandler(self.stderr)
- console_level = {0: logging.WARNING,
- 1: logging.INFO,
- 2: logging.DEBUG,
- }.get(self.options.verbose_level, logging.DEBUG)
- console.setLevel(console_level)
- if logging.DEBUG == console_level:
- formatter = logging.Formatter(self.DEBUG_MESSAGE_FORMAT)
- else:
- formatter = logging.Formatter(self.CONSOLE_MESSAGE_FORMAT)
- console.setFormatter(formatter)
- root_logger.addHandler(console)
- return
+from neutronclient import shell
def main(argv=sys.argv[1:]):
- try:
- return QuantumShell(QUANTUM_API_VERSION).run(map(strutils.safe_decode,
- argv))
- except exc.QuantumClientException:
- return 1
- except Exception as e:
- print unicode(e)
- return 1
-
+ shell.main(argv)
-if __name__ == "__main__":
- sys.exit(main(sys.argv[1:]))
+env = shell.env
+QuantumShell = shell.NeutronShell
+QUANTUM_API_VERSION = shell.NEUTRON_API_VERSION
diff --git a/quantumclient/tests/unit/test_utils.py b/quantumclient/tests/unit/test_utils.py
deleted file mode 100644
index 69ecf6d..0000000
--- a/quantumclient/tests/unit/test_utils.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2013 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import testtools
-
-from quantumclient.common import utils
-
-
-class UtilsTest(testtools.TestCase):
- def test_safe_encode_list(self):
- o = object()
- unicode_text = u'\u7f51\u7edc'
- l = ['abc', unicode_text, unicode_text.encode('utf-8'), o]
- expected = ['abc', unicode_text.encode('utf-8'),
- unicode_text.encode('utf-8'), o]
- self.assertEqual(utils.safe_encode_list(l), expected)
-
- def test_safe_encode_dict(self):
- o = object()
- unicode_text = u'\u7f51\u7edc'
- d = {'test1': unicode_text,
- 'test2': [unicode_text, o],
- 'test3': o,
- 'test4': {'test5': unicode_text},
- 'test6': unicode_text.encode('utf-8')}
- expected = {'test1': unicode_text.encode('utf-8'),
- 'test2': [unicode_text.encode('utf-8'), o],
- 'test3': o,
- 'test4': {'test5': unicode_text.encode('utf-8')},
- 'test6': unicode_text.encode('utf-8')}
- self.assertEqual(utils.safe_encode_dict(d), expected)
diff --git a/quantumclient/v2_0/client.py b/quantumclient/v2_0/client.py
index 93539df..08a455b 100644
--- a/quantumclient/v2_0/client.py
+++ b/quantumclient/v2_0/client.py
@@ -15,866 +15,6 @@
#
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-import httplib
-import logging
-import time
-import urllib
-import urlparse
+from neutronclient.v2_0 import client
-from quantumclient import client
-from quantumclient.common import _
-from quantumclient.common import constants
-from quantumclient.common import exceptions
-from quantumclient.common import serializer
-from quantumclient.common import utils
-
-
-_logger = logging.getLogger(__name__)
-
-
-def exception_handler_v20(status_code, error_content):
- """Exception handler for API v2.0 client
-
- This routine generates the appropriate
- Quantum exception according to the contents of the
- response body
-
- :param status_code: HTTP error status code
- :param error_content: deserialized body of error response
- """
-
- quantum_errors = {
- 'NetworkNotFound': exceptions.NetworkNotFoundClient,
- 'NetworkInUse': exceptions.NetworkInUseClient,
- 'PortNotFound': exceptions.PortNotFoundClient,
- 'RequestedStateInvalid': exceptions.StateInvalidClient,
- 'PortInUse': exceptions.PortInUseClient,
- 'AlreadyAttached': exceptions.AlreadyAttachedClient, }
-
- error_dict = None
- if isinstance(error_content, dict):
- error_dict = error_content.get('QuantumError')
- # Find real error type
- bad_quantum_error_flag = False
- if error_dict:
- # If QuantumError key is found, it will definitely contain
- # a 'message' and 'type' keys?
- try:
- error_type = error_dict['type']
- error_message = (error_dict['message'] + "\n" +
- error_dict['detail'])
- except Exception:
- bad_quantum_error_flag = True
- if not bad_quantum_error_flag:
- ex = None
- try:
- # raise the appropriate error!
- ex = quantum_errors[error_type](message=error_message)
- ex.args = ([dict(status_code=status_code,
- message=error_message)], )
- except Exception:
- pass
- if ex:
- raise ex
- else:
- raise exceptions.QuantumClientException(status_code=status_code,
- message=error_dict)
- else:
- message = None
- if isinstance(error_content, dict):
- message = error_content.get('message', None)
- if message:
- raise exceptions.QuantumClientException(status_code=status_code,
- message=message)
-
- # If we end up here the exception was not a quantum error
- msg = "%s-%s" % (status_code, error_content)
- raise exceptions.QuantumClientException(status_code=status_code,
- message=msg)
-
-
-class APIParamsCall(object):
- """A Decorator to add support for format and tenant overriding
- and filters
- """
- def __init__(self, function):
- self.function = function
-
- def __get__(self, instance, owner):
- def with_params(*args, **kwargs):
- _format = instance.format
- if 'format' in kwargs:
- instance.format = kwargs['format']
- ret = self.function(instance, *args, **kwargs)
- instance.format = _format
- return ret
- return with_params
-
-
-class Client(object):
- """Client for the OpenStack Quantum v2.0 API.
-
- :param string username: Username for authentication. (optional)
- :param string password: Password for authentication. (optional)
- :param string token: Token for authentication. (optional)
- :param string tenant_name: Tenant name. (optional)
- :param string auth_url: Keystone service endpoint for authorization.
- :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 quantum
- 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 insecure: ssl certificate validation. (optional)
-
- Example::
-
- from quantumclient.v2_0 import client
- quantum = client.Client(username=USER,
- password=PASS,
- tenant_name=TENANT_NAME,
- auth_url=KEYSTONE_URL)
-
- nets = quantum.list_networks()
- ...
-
- """
-
- networks_path = "/networks"
- network_path = "/networks/%s"
- ports_path = "/ports"
- port_path = "/ports/%s"
- subnets_path = "/subnets"
- subnet_path = "/subnets/%s"
- quotas_path = "/quotas"
- quota_path = "/quotas/%s"
- 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"
- 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"
-
- DHCP_NETS = '/dhcp-networks'
- DHCP_AGENTS = '/dhcp-agents'
- L3_ROUTERS = '/l3-routers'
- L3_AGENTS = '/l3-agents'
- # 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',
- 'vips': 'vip',
- 'pools': 'pool',
- 'members': 'member',
- 'health_monitors': 'health_monitor',
- 'quotas': 'quota',
- }
- # 8192 Is the default max URI len for eventlet.wsgi.server
- MAX_URI_LEN = 8192
-
- def get_attr_metadata(self):
- if self.format == 'json':
- return {}
- old_request_format = self.format
- self.format = 'json'
- exts = self.list_extensions()['extensions']
- self.format = old_request_format
- ns = dict([(ext['alias'], ext['namespace']) for ext in exts])
- self.EXTED_PLURALS.update(constants.PLURALS)
- return {'plurals': self.EXTED_PLURALS,
- 'xmlns': constants.XML_NS_V20,
- constants.EXT_NS: ns}
-
- @APIParamsCall
- def get_quotas_tenant(self, **_params):
- """Fetch tenant info in server's context for
- following quota operation.
- """
- return self.get(self.quota_path % 'tenant', params=_params)
-
- @APIParamsCall
- def list_quotas(self, **_params):
- """Fetch all tenants' quotas."""
- return self.get(self.quotas_path, params=_params)
-
- @APIParamsCall
- def show_quota(self, tenant_id, **_params):
- """Fetch information of a certain tenant's quotas."""
- return self.get(self.quota_path % (tenant_id), params=_params)
-
- @APIParamsCall
- def update_quota(self, tenant_id, body=None):
- """Update a tenant's quotas."""
- return self.put(self.quota_path % (tenant_id), body=body)
-
- @APIParamsCall
- def delete_quota(self, tenant_id):
- """Delete the specified tenant's quota values."""
- return self.delete(self.quota_path % (tenant_id))
-
- @APIParamsCall
- def list_extensions(self, **_params):
- """Fetch a list of all exts on server side."""
- return self.get(self.extensions_path, params=_params)
-
- @APIParamsCall
- def show_extension(self, ext_alias, **_params):
- """Fetch a list of all exts on server side."""
- return self.get(self.extension_path % ext_alias, params=_params)
-
- @APIParamsCall
- def list_ports(self, retrieve_all=True, **_params):
- """Fetches a list of all networks for a tenant."""
- # Pass filters in "params" argument to do_request
- return self.list('ports', self.ports_path, retrieve_all,
- **_params)
-
- @APIParamsCall
- def show_port(self, port, **_params):
- """Fetches information of a certain network."""
- return self.get(self.port_path % (port), params=_params)
-
- @APIParamsCall
- def create_port(self, body=None):
- """Creates a new port."""
- return self.post(self.ports_path, body=body)
-
- @APIParamsCall
- def update_port(self, port, body=None):
- """Updates a port."""
- return self.put(self.port_path % (port), body=body)
-
- @APIParamsCall
- def delete_port(self, port):
- """Deletes the specified port."""
- return self.delete(self.port_path % (port))
-
- @APIParamsCall
- def list_networks(self, retrieve_all=True, **_params):
- """Fetches a list of all networks for a tenant."""
- # Pass filters in "params" argument to do_request
- return self.list('networks', self.networks_path, retrieve_all,
- **_params)
-
- @APIParamsCall
- def show_network(self, network, **_params):
- """Fetches information of a certain network."""
- return self.get(self.network_path % (network), params=_params)
-
- @APIParamsCall
- def create_network(self, body=None):
- """Creates a new network."""
- return self.post(self.networks_path, body=body)
-
- @APIParamsCall
- def update_network(self, network, body=None):
- """Updates a network."""
- return self.put(self.network_path % (network), body=body)
-
- @APIParamsCall
- def delete_network(self, network):
- """Deletes the specified network."""
- return self.delete(self.network_path % (network))
-
- @APIParamsCall
- def list_subnets(self, retrieve_all=True, **_params):
- """Fetches a list of all networks for a tenant."""
- return self.list('subnets', self.subnets_path, retrieve_all,
- **_params)
-
- @APIParamsCall
- def show_subnet(self, subnet, **_params):
- """Fetches information of a certain subnet."""
- return self.get(self.subnet_path % (subnet), params=_params)
-
- @APIParamsCall
- def create_subnet(self, body=None):
- """Creates a new subnet."""
- return self.post(self.subnets_path, body=body)
-
- @APIParamsCall
- def update_subnet(self, subnet, body=None):
- """Updates a subnet."""
- return self.put(self.subnet_path % (subnet), body=body)
-
- @APIParamsCall
- def delete_subnet(self, subnet):
- """Deletes the specified subnet."""
- return self.delete(self.subnet_path % (subnet))
-
- @APIParamsCall
- def list_routers(self, retrieve_all=True, **_params):
- """Fetches a list of all routers for a tenant."""
- # Pass filters in "params" argument to do_request
- return self.list('routers', self.routers_path, retrieve_all,
- **_params)
-
- @APIParamsCall
- def show_router(self, router, **_params):
- """Fetches information of a certain router."""
- return self.get(self.router_path % (router), params=_params)
-
- @APIParamsCall
- def create_router(self, body=None):
- """Creates a new router."""
- return self.post(self.routers_path, body=body)
-
- @APIParamsCall
- def update_router(self, router, body=None):
- """Updates a router."""
- return self.put(self.router_path % (router), body=body)
-
- @APIParamsCall
- def delete_router(self, router):
- """Deletes the specified router."""
- return self.delete(self.router_path % (router))
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- 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}})
-
- @APIParamsCall
- 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': {}}})
-
- @APIParamsCall
- def list_floatingips(self, retrieve_all=True, **_params):
- """Fetches a list of all floatingips for a tenant."""
- # Pass filters in "params" argument to do_request
- return self.list('floatingips', self.floatingips_path, retrieve_all,
- **_params)
-
- @APIParamsCall
- def show_floatingip(self, floatingip, **_params):
- """Fetches information of a certain floatingip."""
- return self.get(self.floatingip_path % (floatingip), params=_params)
-
- @APIParamsCall
- def create_floatingip(self, body=None):
- """Creates a new floatingip."""
- return self.post(self.floatingips_path, body=body)
-
- @APIParamsCall
- def update_floatingip(self, floatingip, body=None):
- """Updates a floatingip."""
- return self.put(self.floatingip_path % (floatingip), body=body)
-
- @APIParamsCall
- def delete_floatingip(self, floatingip):
- """Deletes the specified floatingip."""
- return self.delete(self.floatingip_path % (floatingip))
-
- @APIParamsCall
- def create_security_group(self, body=None):
- """Creates a new security group."""
- return self.post(self.security_groups_path, body=body)
-
- @APIParamsCall
- def update_security_group(self, security_group, body=None):
- """Updates a security group."""
- return self.put(self.security_group_path %
- security_group, body=body)
-
- @APIParamsCall
- def list_security_groups(self, retrieve_all=True, **_params):
- """Fetches a list of all security groups for a tenant."""
- return self.list('security_groups', self.security_groups_path,
- retrieve_all, **_params)
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- def delete_security_group(self, security_group):
- """Deletes the specified security group."""
- return self.delete(self.security_group_path % (security_group))
-
- @APIParamsCall
- def create_security_group_rule(self, body=None):
- """Creates a new security group rule."""
- return self.post(self.security_group_rules_path, body=body)
-
- @APIParamsCall
- 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))
-
- @APIParamsCall
- def list_security_group_rules(self, retrieve_all=True, **_params):
- """Fetches a list of all security group rules for a tenant."""
- return self.list('security_group_rules',
- self.security_group_rules_path,
- retrieve_all, **_params)
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- def list_vips(self, retrieve_all=True, **_params):
- """Fetches a list of all load balancer vips for a tenant."""
- # Pass filters in "params" argument to do_request
- return self.list('vips', self.vips_path, retrieve_all,
- **_params)
-
- @APIParamsCall
- def show_vip(self, vip, **_params):
- """Fetches information of a certain load balancer vip."""
- return self.get(self.vip_path % (vip), params=_params)
-
- @APIParamsCall
- def create_vip(self, body=None):
- """Creates a new load balancer vip."""
- return self.post(self.vips_path, body=body)
-
- @APIParamsCall
- def update_vip(self, vip, body=None):
- """Updates a load balancer vip."""
- return self.put(self.vip_path % (vip), body=body)
-
- @APIParamsCall
- def delete_vip(self, vip):
- """Deletes the specified load balancer vip."""
- return self.delete(self.vip_path % (vip))
-
- @APIParamsCall
- def list_pools(self, retrieve_all=True, **_params):
- """Fetches a list of all load balancer pools for a tenant."""
- # Pass filters in "params" argument to do_request
- return self.list('pools', self.pools_path, retrieve_all,
- **_params)
-
- @APIParamsCall
- def show_pool(self, pool, **_params):
- """Fetches information of a certain load balancer pool."""
- return self.get(self.pool_path % (pool), params=_params)
-
- @APIParamsCall
- def create_pool(self, body=None):
- """Creates a new load balancer pool."""
- return self.post(self.pools_path, body=body)
-
- @APIParamsCall
- def update_pool(self, pool, body=None):
- """Updates a load balancer pool."""
- return self.put(self.pool_path % (pool), body=body)
-
- @APIParamsCall
- def delete_pool(self, pool):
- """Deletes the specified load balancer pool."""
- return self.delete(self.pool_path % (pool))
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- def list_members(self, retrieve_all=True, **_params):
- """Fetches a list of all load balancer members for a tenant."""
- # Pass filters in "params" argument to do_request
- return self.list('members', self.members_path, retrieve_all,
- **_params)
-
- @APIParamsCall
- def show_member(self, member, **_params):
- """Fetches information of a certain load balancer member."""
- return self.get(self.member_path % (member), params=_params)
-
- @APIParamsCall
- def create_member(self, body=None):
- """Creates a new load balancer member."""
- return self.post(self.members_path, body=body)
-
- @APIParamsCall
- def update_member(self, member, body=None):
- """Updates a load balancer member."""
- return self.put(self.member_path % (member), body=body)
-
- @APIParamsCall
- def delete_member(self, member):
- """Deletes the specified load balancer member."""
- return self.delete(self.member_path % (member))
-
- @APIParamsCall
- def list_health_monitors(self, retrieve_all=True, **_params):
- """Fetches a list of all load balancer health monitors for a tenant."""
- # Pass filters in "params" argument to do_request
- return self.list('health_monitors', self.health_monitors_path,
- retrieve_all, **_params)
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- def create_health_monitor(self, body=None):
- """Creates a new load balancer health monitor."""
- return self.post(self.health_monitors_path, body=body)
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- def delete_health_monitor(self, health_monitor):
- """Deletes the specified load balancer health monitor."""
- return self.delete(self.health_monitor_path % (health_monitor))
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- def create_qos_queue(self, body=None):
- """Creates a new queue."""
- return self.post(self.qos_queues_path, body=body)
-
- @APIParamsCall
- def list_qos_queues(self, **_params):
- """Fetches a list of all queues for a tenant."""
- return self.get(self.qos_queues_path, params=_params)
-
- @APIParamsCall
- def show_qos_queue(self, queue, **_params):
- """Fetches information of a certain queue."""
- return self.get(self.qos_queue_path % (queue),
- params=_params)
-
- @APIParamsCall
- def delete_qos_queue(self, queue):
- """Deletes the specified queue."""
- return self.delete(self.qos_queue_path % (queue))
-
- @APIParamsCall
- def list_agents(self, **_params):
- """Fetches agents."""
- # Pass filters in "params" argument to do_request
- return self.get(self.agents_path, params=_params)
-
- @APIParamsCall
- def show_agent(self, agent, **_params):
- """Fetches information of a certain agent."""
- return self.get(self.agent_path % (agent), params=_params)
-
- @APIParamsCall
- def update_agent(self, agent, body=None):
- """Updates an agent."""
- return self.put(self.agent_path % (agent), body=body)
-
- @APIParamsCall
- def delete_agent(self, agent):
- """Deletes the specified agent."""
- return self.delete(self.agent_path % (agent))
-
- @APIParamsCall
- def list_network_gateways(self, **_params):
- """Retrieve network gateways."""
- return self.get(self.network_gateways_path, params=_params)
-
- @APIParamsCall
- def show_network_gateway(self, gateway_id, **_params):
- """Fetch a network gateway."""
- return self.get(self.network_gateway_path % gateway_id, params=_params)
-
- @APIParamsCall
- def create_network_gateway(self, body=None):
- """Create a new network gateway."""
- return self.post(self.network_gateways_path, body=body)
-
- @APIParamsCall
- def update_network_gateway(self, gateway_id, body=None):
- """Update a network gateway."""
- return self.put(self.network_gateway_path % gateway_id, body=body)
-
- @APIParamsCall
- def delete_network_gateway(self, gateway_id):
- """Delete the specified network gateway."""
- return self.delete(self.network_gateway_path % gateway_id)
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- 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))
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- 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)
-
- @APIParamsCall
- 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 __init__(self, **kwargs):
- """Initialize a new client for the Quantum v2.0 API."""
- super(Client, self).__init__()
- self.httpclient = client.HTTPClient(**kwargs)
- self.version = '2.0'
- self.format = 'json'
- self.action_prefix = "/v%s" % (self.version)
- self.retries = 0
- self.retry_interval = 1
-
- def _handle_fault_response(self, status_code, response_body):
- # Create exception with HTTP status code and message
- _logger.debug("Error message: %s", response_body)
- # Add deserialized error message to exception arguments
- try:
- des_error_body = self.deserialize(response_body, status_code)
- except Exception:
- # If unable to deserialized body it is probably not a
- # Quantum error
- des_error_body = {'message': response_body}
- # Raise the appropriate exception
- exception_handler_v20(status_code, des_error_body)
-
- def _check_uri_length(self, action):
- uri_len = len(self.httpclient.endpoint_url) + len(action)
- if uri_len > self.MAX_URI_LEN:
- raise exceptions.RequestURITooLong(
- excess=uri_len - self.MAX_URI_LEN)
-
- def do_request(self, method, action, body=None, headers=None, params=None):
- # Add format and tenant_id
- action += ".%s" % self.format
- action = self.action_prefix + action
- if type(params) is dict and params:
- params = utils.safe_encode_dict(params)
- action += '?' + urllib.urlencode(params, doseq=1)
- # Ensure client always has correct uri - do not guesstimate anything
- self.httpclient.authenticate_and_fetch_endpoint_url()
- self._check_uri_length(action)
-
- if body:
- body = self.serialize(body)
- self.httpclient.content_type = self.content_type()
- resp, replybody = self.httpclient.do_request(action, method, body=body)
- status_code = self.get_status_code(resp)
- if status_code in (httplib.OK,
- httplib.CREATED,
- httplib.ACCEPTED,
- httplib.NO_CONTENT):
- return self.deserialize(replybody, status_code)
- else:
- self._handle_fault_response(status_code, replybody)
-
- def get_auth_info(self):
- return self.httpclient.get_auth_info()
-
- def get_status_code(self, response):
- """Returns the integer status code from the response.
-
- Either a Webob.Response (used in testing) or httplib.Response
- is returned.
- """
- if hasattr(response, 'status_int'):
- return response.status_int
- else:
- return response.status
-
- def serialize(self, data):
- """Serializes a dictionary into either xml or json.
-
- A dictionary with a single key can be passed and
- it can contain any structure.
- """
- if data is None:
- return None
- elif type(data) is dict:
- return serializer.Serializer(
- self.get_attr_metadata()).serialize(data, self.content_type())
- else:
- raise Exception("unable to serialize object of type = '%s'" %
- type(data))
-
- def deserialize(self, data, status_code):
- """Deserializes an xml or json string into a dictionary."""
- if status_code == 204:
- return data
- return serializer.Serializer(self.get_attr_metadata()).deserialize(
- data, self.content_type())['body']
-
- def content_type(self, _format=None):
- """Returns the mime-type for either 'xml' or 'json'.
-
- Defaults to the currently set format.
- """
- _format = _format or self.format
- return "application/%s" % (_format)
-
- def retry_request(self, method, action, body=None,
- headers=None, params=None):
- """Call do_request with the default retry configuration.
-
- Only idempotent requests should retry failed connection attempts.
- :raises: ConnectionFailed if the maximum # of retries is exceeded
- """
- max_attempts = self.retries + 1
- for i in xrange(max_attempts):
- try:
- return self.do_request(method, action, body=body,
- headers=headers, params=params)
- except exceptions.ConnectionFailed:
- # Exception has already been logged by do_request()
- if i < self.retries:
- _logger.debug(_('Retrying connection to quantum service'))
- time.sleep(self.retry_interval)
-
- raise exceptions.ConnectionFailed(reason=_("Maximum attempts reached"))
-
- def delete(self, action, body=None, headers=None, params=None):
- return self.retry_request("DELETE", action, body=body,
- headers=headers, params=params)
-
- def get(self, action, body=None, headers=None, params=None):
- return self.retry_request("GET", action, body=body,
- headers=headers, params=params)
-
- def post(self, action, body=None, headers=None, params=None):
- # Do not retry POST requests to avoid the orphan objects problem.
- return self.do_request("POST", action, body=body,
- headers=headers, params=params)
-
- def put(self, action, body=None, headers=None, params=None):
- return self.retry_request("PUT", action, body=body,
- headers=headers, params=params)
-
- def list(self, collection, path, retrieve_all=True, **params):
- if retrieve_all:
- res = []
- for r in self._pagination(collection, path, **params):
- res.extend(r[collection])
- return {collection: res}
- else:
- return self._pagination(collection, path, **params)
-
- def _pagination(self, collection, path, **params):
- if params.get('page_reverse', False):
- linkrel = 'previous'
- else:
- linkrel = 'next'
- next = True
- while next:
- res = self.get(path, params=params)
- yield res
- next = False
- try:
- for link in res['%s_links' % collection]:
- if link['rel'] == linkrel:
- query_str = urlparse.urlparse(link['href']).query
- params = urlparse.parse_qs(query_str)
- next = True
- break
- except KeyError:
- break
+Client = client.Client
diff --git a/requirements.txt b/requirements.txt
index 1eabc6f..12e8b5a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,9 +1,2 @@
-d2to1>=0.2.10,<0.3
-pbr>=0.5.16,<0.6
-argparse
-cliff>=1.4
-httplib2
-iso8601
-prettytable>=0.6,<0.8
-pyparsing>=1.5.6,<2.0
-simplejson
+pbr>=0.5.21,<1.0
+python-neutronclient>=2.3.0,<3
diff --git a/setup.py b/setup.py
index 80b6834..e5dcfc2 100644
--- a/setup.py
+++ b/setup.py
@@ -19,5 +19,5 @@
import setuptools
setuptools.setup(
- setup_requires=['d2to1>=0.2.10,<0.3', 'pbr>=0.5.10,<0.6'],
- d2to1=True)
+ setup_requires=['pbr>=0.5.21,<1.0'],
+ pbr=True)
diff --git a/test-requirements.txt b/test-requirements.txt
index 34b353c..6523547 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,15 +1,9 @@
-# Install bounded pep8/pyflakes first, then let flake8 install
-pep8==1.4.5
-pyflakes==0.7.2
-flake8==2.0
-hacking>=0.5.3,<0.6
+hacking>=0.5.6,<0.8
-cliff-tablib>=1.0
-coverage
+coverage>=3.6
discover
-fixtures>=0.3.12
-mox
+fixtures>=0.3.14
python-subunit
sphinx>=1.1.2
-testrepository>=0.0.13
-testtools>=0.9.22
+testrepository>=0.0.17
+testtools>=0.9.32
diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py
deleted file mode 100644
index 1668497..0000000
--- a/tests/unit/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2013 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
diff --git a/tests/unit/lb/__init__.py b/tests/unit/lb/__init__.py
deleted file mode 100644
index 1668497..0000000
--- a/tests/unit/lb/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2013 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
diff --git a/tests/unit/lb/test_cli20_healthmonitor.py b/tests/unit/lb/test_cli20_healthmonitor.py
deleted file mode 100644
index 0b87ff9..0000000
--- a/tests/unit/lb/test_cli20_healthmonitor.py
+++ /dev/null
@@ -1,219 +0,0 @@
-# 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.
-#
-# @author: Ilya Shakhat, Mirantis Inc.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import sys
-
-import mox
-
-from quantumclient.quantum.v2_0.lb import healthmonitor
-from 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_show_healthmonitor_id_name(self):
- """lb-healthmonitor-show."""
- resource = 'health_monitor'
- 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'])
-
- 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()
-
-
-class CLITestV20LbHealthmonitorXML(CLITestV20LbHealthmonitorJSON):
- format = 'xml'
diff --git a/tests/unit/lb/test_cli20_member.py b/tests/unit/lb/test_cli20_member.py
deleted file mode 100644
index 9b75367..0000000
--- a/tests/unit/lb/test_cli20_member.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# 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.
-#
-# @author: Ilya Shakhat, Mirantis Inc.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import sys
-
-from quantumclient.quantum.v2_0.lb import member
-from 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_show_member_id_name(self):
- """lb-member-show."""
- resource = 'member'
- cmd = member.ShowMember(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_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)
-
-
-class CLITestV20LbMemberXML(CLITestV20LbMemberJSON):
- format = 'xml'
diff --git a/tests/unit/lb/test_cli20_pool.py b/tests/unit/lb/test_cli20_pool.py
deleted file mode 100644
index 709c3d1..0000000
--- a/tests/unit/lb/test_cli20_pool.py
+++ /dev/null
@@ -1,171 +0,0 @@
-# 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.
-#
-# @author: Ilya Shakhat, Mirantis Inc.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import sys
-
-import mox
-
-from quantumclient.quantum.v2_0.lb import pool
-from 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'
- args = ['--admin-state-down',
- '--description', description,
- '--lb-method', lb_method,
- '--name', name,
- '--protocol', protocol,
- '--subnet-id', subnet_id,
- '--tenant-id', tenant_id]
- position_names = ['admin_state_up', 'description', 'lb_method', 'name',
- 'protocol', 'subnet_id', 'tenant_id']
- position_values = [False, description, lb_method, name,
- protocol, subnet_id, tenant_id]
- 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.assertTrue('bytes_in' in _str)
- self.assertTrue('bytes_out' in _str)
-
-
-class CLITestV20LbPoolXML(CLITestV20LbPoolJSON):
- format = 'xml'
diff --git a/tests/unit/lb/test_cli20_vip.py b/tests/unit/lb/test_cli20_vip.py
deleted file mode 100644
index 4358cfb..0000000
--- a/tests/unit/lb/test_cli20_vip.py
+++ /dev/null
@@ -1,214 +0,0 @@
-# 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.
-#
-# @author: Ilya Shakhat, Mirantis Inc.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import sys
-
-from quantumclient.quantum.v2_0.lb import vip
-from 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)
-
-
-class CLITestV20LbVipXML(CLITestV20LbVipJSON):
- format = 'xml'
diff --git a/tests/unit/test_auth.py b/tests/unit/test_auth.py
deleted file mode 100644
index 06cc2de..0000000
--- a/tests/unit/test_auth.py
+++ /dev/null
@@ -1,320 +0,0 @@
-# Copyright 2012 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import copy
-import httplib2
-import json
-import uuid
-
-import mox
-import testtools
-
-from quantumclient import client
-from quantumclient.common import exceptions
-
-
-USERNAME = 'testuser'
-TENANT_NAME = 'testtenant'
-PASSWORD = 'password'
-AUTH_URL = 'authurl'
-ENDPOINT_URL = 'localurl'
-TOKEN = 'tokentoken'
-REGION = 'RegionTest'
-
-KS_TOKEN_RESULT = {
- 'access': {
- 'token': {'id': TOKEN,
- 'expires': '2012-08-11T07:49:01Z',
- 'tenant': {'id': str(uuid.uuid1())}},
- 'user': {'id': str(uuid.uuid1())},
- 'serviceCatalog': [
- {'endpoints_links': [],
- 'endpoints': [{'adminURL': ENDPOINT_URL,
- 'internalURL': ENDPOINT_URL,
- 'publicURL': ENDPOINT_URL,
- 'region': REGION}],
- 'type': 'network',
- 'name': 'Quantum Service'}
- ]
- }
-}
-
-ENDPOINTS_RESULT = {
- 'endpoints': [{
- 'type': 'network',
- 'name': 'Quantum Service',
- 'region': REGION,
- 'adminURL': ENDPOINT_URL,
- 'internalURL': ENDPOINT_URL,
- 'publicURL': ENDPOINT_URL
- }]
-}
-
-
-class CLITestAuthKeystone(testtools.TestCase):
-
- def setUp(self):
- """Prepare the test environment."""
- super(CLITestAuthKeystone, self).setUp()
- self.mox = mox.Mox()
- self.client = client.HTTPClient(username=USERNAME,
- tenant_name=TENANT_NAME,
- password=PASSWORD,
- auth_url=AUTH_URL,
- region_name=REGION)
- self.addCleanup(self.mox.VerifyAll)
- self.addCleanup(self.mox.UnsetStubs)
-
- def test_get_token(self):
- self.mox.StubOutWithMock(self.client, "request")
-
- res200 = self.mox.CreateMock(httplib2.Response)
- res200.status = 200
-
- self.client.request(
- AUTH_URL + '/tokens', 'POST',
- body=mox.IsA(str), headers=mox.IsA(dict)
- ).AndReturn((res200, json.dumps(KS_TOKEN_RESULT)))
- self.client.request(
- mox.StrContains(ENDPOINT_URL + '/resource'), 'GET',
- headers=mox.ContainsKeyValue('X-Auth-Token', TOKEN)
- ).AndReturn((res200, ''))
- self.mox.ReplayAll()
-
- self.client.do_request('/resource', 'GET')
- self.assertEqual(self.client.endpoint_url, ENDPOINT_URL)
- self.assertEqual(self.client.auth_token, TOKEN)
-
- def test_refresh_token(self):
- self.mox.StubOutWithMock(self.client, "request")
-
- self.client.auth_token = TOKEN
- self.client.endpoint_url = ENDPOINT_URL
-
- res200 = self.mox.CreateMock(httplib2.Response)
- res200.status = 200
- res401 = self.mox.CreateMock(httplib2.Response)
- res401.status = 401
-
- # If a token is expired, quantum server retruns 401
- self.client.request(
- mox.StrContains(ENDPOINT_URL + '/resource'), 'GET',
- headers=mox.ContainsKeyValue('X-Auth-Token', TOKEN)
- ).AndReturn((res401, ''))
- self.client.request(
- AUTH_URL + '/tokens', 'POST',
- body=mox.IsA(str), headers=mox.IsA(dict)
- ).AndReturn((res200, json.dumps(KS_TOKEN_RESULT)))
- self.client.request(
- mox.StrContains(ENDPOINT_URL + '/resource'), 'GET',
- headers=mox.ContainsKeyValue('X-Auth-Token', TOKEN)
- ).AndReturn((res200, ''))
- self.mox.ReplayAll()
- self.client.do_request('/resource', 'GET')
-
- def test_get_endpoint_url(self):
- self.mox.StubOutWithMock(self.client, "request")
-
- self.client.auth_token = TOKEN
-
- res200 = self.mox.CreateMock(httplib2.Response)
- res200.status = 200
-
- self.client.request(
- mox.StrContains(AUTH_URL + '/tokens/%s/endpoints' % TOKEN), 'GET',
- headers=mox.IsA(dict)
- ).AndReturn((res200, json.dumps(ENDPOINTS_RESULT)))
- self.client.request(
- mox.StrContains(ENDPOINT_URL + '/resource'), 'GET',
- headers=mox.ContainsKeyValue('X-Auth-Token', TOKEN)
- ).AndReturn((res200, ''))
- self.mox.ReplayAll()
- self.client.do_request('/resource', 'GET')
-
- def test_get_endpoint_url_other(self):
- self.client = client.HTTPClient(
- username=USERNAME, tenant_name=TENANT_NAME, password=PASSWORD,
- auth_url=AUTH_URL, region_name=REGION, endpoint_type='otherURL')
- self.mox.StubOutWithMock(self.client, "request")
-
- self.client.auth_token = TOKEN
-
- res200 = self.mox.CreateMock(httplib2.Response)
- res200.status = 200
-
- self.client.request(
- mox.StrContains(AUTH_URL + '/tokens/%s/endpoints' % TOKEN), 'GET',
- headers=mox.IsA(dict)
- ).AndReturn((res200, json.dumps(ENDPOINTS_RESULT)))
- self.mox.ReplayAll()
- self.assertRaises(exceptions.EndpointTypeNotFound,
- self.client.do_request,
- '/resource',
- 'GET')
-
- def test_get_endpoint_url_failed(self):
- self.mox.StubOutWithMock(self.client, "request")
-
- self.client.auth_token = TOKEN
-
- res200 = self.mox.CreateMock(httplib2.Response)
- res200.status = 200
- res401 = self.mox.CreateMock(httplib2.Response)
- res401.status = 401
-
- self.client.request(
- mox.StrContains(AUTH_URL + '/tokens/%s/endpoints' % TOKEN), 'GET',
- headers=mox.IsA(dict)
- ).AndReturn((res401, ''))
- self.client.request(
- AUTH_URL + '/tokens', 'POST',
- body=mox.IsA(str), headers=mox.IsA(dict)
- ).AndReturn((res200, json.dumps(KS_TOKEN_RESULT)))
- self.client.request(
- mox.StrContains(ENDPOINT_URL + '/resource'), 'GET',
- headers=mox.ContainsKeyValue('X-Auth-Token', TOKEN)
- ).AndReturn((res200, ''))
- self.mox.ReplayAll()
- self.client.do_request('/resource', 'GET')
-
- def test_url_for(self):
- resources = copy.deepcopy(KS_TOKEN_RESULT)
-
- endpoints = resources['access']['serviceCatalog'][0]['endpoints'][0]
- endpoints['publicURL'] = 'public'
- endpoints['internalURL'] = 'internal'
- endpoints['adminURL'] = 'admin'
- catalog = client.ServiceCatalog(resources)
-
- # endpoint_type not specified
- url = catalog.url_for(attr='region',
- filter_value=REGION)
- self.assertEqual('public', url)
-
- # endpoint type specified (3 cases)
- url = catalog.url_for(attr='region',
- filter_value=REGION,
- endpoint_type='adminURL')
- self.assertEqual('admin', url)
-
- url = catalog.url_for(attr='region',
- filter_value=REGION,
- endpoint_type='publicURL')
- self.assertEqual('public', url)
-
- url = catalog.url_for(attr='region',
- filter_value=REGION,
- endpoint_type='internalURL')
- self.assertEqual('internal', url)
-
- # endpoint_type requested does not exist.
- self.assertRaises(exceptions.EndpointTypeNotFound,
- catalog.url_for,
- attr='region',
- filter_value=REGION,
- endpoint_type='privateURL')
-
- # Test scenario with url_for when the service catalog only has publicURL.
- def test_url_for_only_public_url(self):
- resources = copy.deepcopy(KS_TOKEN_RESULT)
- catalog = client.ServiceCatalog(resources)
-
- # Remove endpoints from the catalog.
- endpoints = resources['access']['serviceCatalog'][0]['endpoints'][0]
- del endpoints['internalURL']
- del endpoints['adminURL']
- endpoints['publicURL'] = 'public'
-
- # Use publicURL when specified explicitly.
- url = catalog.url_for(attr='region',
- filter_value=REGION,
- endpoint_type='publicURL')
- self.assertEqual('public', url)
-
- # Use publicURL when specified explicitly.
- url = catalog.url_for(attr='region',
- filter_value=REGION)
- self.assertEqual('public', url)
-
- # Test scenario with url_for when the service catalog only has adminURL.
- def test_url_for_only_admin_url(self):
- resources = copy.deepcopy(KS_TOKEN_RESULT)
- catalog = client.ServiceCatalog(resources)
- endpoints = resources['access']['serviceCatalog'][0]['endpoints'][0]
- del endpoints['internalURL']
- del endpoints['publicURL']
- endpoints['adminURL'] = 'admin'
-
- # Use publicURL when specified explicitly.
- url = catalog.url_for(attr='region',
- filter_value=REGION,
- endpoint_type='adminURL')
- self.assertEqual('admin', url)
-
- # But not when nothing is specified.
- self.assertRaises(exceptions.EndpointTypeNotFound,
- catalog.url_for,
- attr='region',
- filter_value=REGION)
-
- def test_endpoint_type(self):
- resources = copy.deepcopy(KS_TOKEN_RESULT)
- endpoints = resources['access']['serviceCatalog'][0]['endpoints'][0]
- endpoints['internalURL'] = 'internal'
- endpoints['adminURL'] = 'admin'
- endpoints['publicURL'] = 'public'
-
- # Test default behavior is to choose public.
- self.client = client.HTTPClient(
- username=USERNAME, tenant_name=TENANT_NAME, password=PASSWORD,
- auth_url=AUTH_URL, region_name=REGION)
-
- self.client._extract_service_catalog(resources)
- self.assertEqual(self.client.endpoint_url, 'public')
-
- # Test admin url
- self.client = client.HTTPClient(
- username=USERNAME, tenant_name=TENANT_NAME, password=PASSWORD,
- auth_url=AUTH_URL, region_name=REGION, endpoint_type='adminURL')
-
- self.client._extract_service_catalog(resources)
- self.assertEqual(self.client.endpoint_url, 'admin')
-
- # Test public url
- self.client = client.HTTPClient(
- username=USERNAME, tenant_name=TENANT_NAME, password=PASSWORD,
- auth_url=AUTH_URL, region_name=REGION, endpoint_type='publicURL')
-
- self.client._extract_service_catalog(resources)
- self.assertEqual(self.client.endpoint_url, 'public')
-
- # Test internal url
- self.client = client.HTTPClient(
- username=USERNAME, tenant_name=TENANT_NAME, password=PASSWORD,
- auth_url=AUTH_URL, region_name=REGION, endpoint_type='internalURL')
-
- self.client._extract_service_catalog(resources)
- self.assertEqual(self.client.endpoint_url, 'internal')
-
- # Test url that isn't found in the service catalog
- self.client = client.HTTPClient(
- username=USERNAME, tenant_name=TENANT_NAME, password=PASSWORD,
- auth_url=AUTH_URL, region_name=REGION, endpoint_type='privateURL')
-
- self.assertRaises(exceptions.EndpointTypeNotFound,
- self.client._extract_service_catalog,
- resources)
diff --git a/tests/unit/test_casual_args.py b/tests/unit/test_casual_args.py
deleted file mode 100644
index fcfff93..0000000
--- a/tests/unit/test_casual_args.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import testtools
-
-from quantumclient.common import exceptions
-from quantumclient.quantum import v2_0 as quantumV20
-
-
-class CLITestArgs(testtools.TestCase):
-
- def test_empty(self):
- _mydict = quantumV20.parse_args_to_dict([])
- self.assertEqual({}, _mydict)
-
- def test_default_bool(self):
- _specs = ['--my_bool', '--arg1', 'value1']
- _mydict = quantumV20.parse_args_to_dict(_specs)
- self.assertTrue(_mydict['my_bool'])
-
- def test_bool_true(self):
- _specs = ['--my-bool', 'type=bool', 'true', '--arg1', 'value1']
- _mydict = quantumV20.parse_args_to_dict(_specs)
- self.assertTrue(_mydict['my_bool'])
-
- def test_bool_false(self):
- _specs = ['--my_bool', 'type=bool', 'false', '--arg1', 'value1']
- _mydict = quantumV20.parse_args_to_dict(_specs)
- self.assertFalse(_mydict['my_bool'])
-
- def test_nargs(self):
- _specs = ['--tag', 'x', 'y', '--arg1', 'value1']
- _mydict = quantumV20.parse_args_to_dict(_specs)
- self.assertTrue('x' in _mydict['tag'])
- self.assertTrue('y' in _mydict['tag'])
-
- def test_badarg(self):
- _specs = ['--tag=t', 'x', 'y', '--arg1', 'value1']
- self.assertRaises(exceptions.CommandError,
- quantumV20.parse_args_to_dict, _specs)
-
- def test_badarg_with_minus(self):
- _specs = ['--arg1', 'value1', '-D']
- self.assertRaises(exceptions.CommandError,
- quantumV20.parse_args_to_dict, _specs)
-
- def test_goodarg_with_minus_number(self):
- _specs = ['--arg1', 'value1', '-1', '-1.0']
- _mydict = quantumV20.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,
- quantumV20.parse_args_to_dict, _specs)
-
- def test_badarg_early_type_specification(self):
- _specs = ['type=dict', 'key=value']
- self.assertRaises(exceptions.CommandError,
- quantumV20.parse_args_to_dict, _specs)
-
- def test_arg(self):
- _specs = ['--tag=t', '--arg1', 'value1']
- self.assertEqual('value1',
- quantumV20.parse_args_to_dict(_specs)['arg1'])
-
- def test_dict_arg(self):
- _specs = ['--tag=t', '--arg1', 'type=dict', 'key1=value1,key2=value2']
- arg1 = quantumV20.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 = quantumV20.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 = quantumV20.parse_args_to_dict(_specs)['arg1']
- self.assertEqual('value1', arg1[0]['key1'])
- self.assertEqual('value2', arg1[0]['key2'])
diff --git a/tests/unit/test_cli20.py b/tests/unit/test_cli20.py
deleted file mode 100644
index c89cdfa..0000000
--- a/tests/unit/test_cli20.py
+++ /dev/null
@@ -1,504 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import urllib
-
-import fixtures
-import mox
-import testtools
-
-from quantumclient.common import constants
-from quantumclient import shell
-from quantumclient.v2_0 import client
-
-
-API_VERSION = "2.0"
-FORMAT = 'json'
-TOKEN = 'testtoken'
-ENDURL = 'localurl'
-
-
-class FakeStdout:
-
- def __init__(self):
- self.content = []
-
- def write(self, text):
- self.content.append(text)
-
- def make_string(self):
- result = ''
- for line in self.content:
- result = result + line
- return result
-
-
-class MyResp(object):
- def __init__(self, status):
- self.status = status
-
-
-class MyApp(object):
- def __init__(self, _stdout):
- self.stdout = _stdout
-
-
-def end_url(path, query=None, format=FORMAT):
- _url_str = ENDURL + "/v" + API_VERSION + path + "." + format
- return query and _url_str + "?" + query or _url_str
-
-
-class MyUrlComparator(mox.Comparator):
- def __init__(self, lhs, client):
- self.lhs = lhs
- self.client = client
-
- def equals(self, rhs):
- return str(self) == rhs
-
- def __str__(self):
- if self.client and self.client.format != FORMAT:
- lhs_parts = self.lhs.split("?", 1)
- if len(lhs_parts) == 2:
- lhs = ("%s.%s?%s" % (lhs_parts[0][:-4],
- self.client.format,
- lhs_parts[1]))
- else:
- lhs = ("%s.%s" % (lhs_parts[0][:-4],
- self.client.format))
- return lhs
- return self.lhs
-
- def __repr__(self):
- return str(self)
-
-
-class MyComparator(mox.Comparator):
- def __init__(self, lhs, client):
- self.lhs = lhs
- self.client = client
-
- def _com_dict(self, lhs, rhs):
- if len(lhs) != len(rhs):
- return False
- for key, value in lhs.iteritems():
- 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(testtools.TestCase):
-
- format = 'json'
- test_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
- id_field = 'id'
-
- def _find_resourceid(self, client, resource, name_or_id):
- return name_or_id
-
- def _get_attr_metadata(self):
- return self.metadata
- client.Client.EXTED_PLURALS.update(constants.PLURALS)
- client.Client.EXTED_PLURALS.update({'tags': 'tag'})
- return {'plurals': client.Client.EXTED_PLURALS,
- 'xmlns': constants.XML_NS_V20,
- constants.EXT_NS: {'prefix': 'http://xxxx.yy.com'}}
-
- def setUp(self, plurals={}):
- """Prepare the test environment."""
- super(CLITestV20Base, self).setUp()
- client.Client.EXTED_PLURALS.update(constants.PLURALS)
- client.Client.EXTED_PLURALS.update(plurals)
- self.metadata = {'plurals': client.Client.EXTED_PLURALS,
- 'xmlns': constants.XML_NS_V20,
- constants.EXT_NS: {'prefix':
- 'http://xxxx.yy.com'}}
- self.mox = mox.Mox()
- self.endurl = ENDURL
- self.fake_stdout = FakeStdout()
- self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.fake_stdout))
- self.useFixture(fixtures.MonkeyPatch(
- 'quantumclient.quantum.v2_0.find_resourceid_by_name_or_id',
- self._find_resourceid))
- self.useFixture(fixtures.MonkeyPatch(
- 'quantumclient.v2_0.client.Client.get_attr_metadata',
- self._get_attr_metadata))
- self.client = client.Client(token=TOKEN, endpoint_url=self.endurl)
-
- def _test_create_resource(self, resource, cmd,
- name, myid, args,
- position_names, position_values, tenant_id=None,
- tags=None, admin_state_up=True, shared=False,
- extra_body=None, **kwargs):
- self.mox.StubOutWithMock(cmd, "get_client")
- self.mox.StubOutWithMock(self.client.httpclient, "request")
- cmd.get_client().MultipleTimes().AndReturn(self.client)
- non_admin_status_resources = ['subnet', 'floatingip', 'security_group',
- 'security_group_rule', 'qos_queue',
- 'network_gateway']
- if (resource in 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 shared:
- body[resource].update({'shared': shared})
- if extra_body:
- body[resource].update(extra_body)
- body[resource].update(kwargs)
-
- for i in xrange(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})
- self.client.format = self.format
- resstr = self.client.serialize(ress)
- # url method body
- path = getattr(self.client, resource + "s_path")
- self.client.httpclient.request(
- end_url(path, format=self.format), 'POST',
- body=MyComparator(body, self.client),
- headers=mox.ContainsKeyValue(
- 'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr))
- args.extend(['--request-format', self.format])
- self.mox.ReplayAll()
- cmd_parser = cmd.get_parser('create_' + resource)
- shell.run_command(cmd, cmd_parser, args)
- self.mox.VerifyAll()
- self.mox.UnsetStubs()
- _str = self.fake_stdout.make_string()
- self.assertTrue(myid in _str)
- if name:
- self.assertTrue(name in _str)
-
- def _test_list_columns(self, cmd, resources_collection,
- resources_out, args=['-f', 'json']):
- self.mox.StubOutWithMock(cmd, "get_client")
- self.mox.StubOutWithMock(self.client.httpclient, "request")
- cmd.get_client().MultipleTimes().AndReturn(self.client)
- self.client.format = self.format
- resstr = self.client.serialize(resources_out)
-
- path = getattr(self.client, resources_collection + "_path")
- self.client.httpclient.request(
- end_url(path, format=self.format), 'GET',
- body=None,
- headers=mox.ContainsKeyValue(
- 'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr))
- args.extend(['--request-format', self.format])
- self.mox.ReplayAll()
- cmd_parser = cmd.get_parser("list_" + resources_collection)
- 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):
- self.mox.StubOutWithMock(cmd, "get_client")
- self.mox.StubOutWithMock(self.client.httpclient, "request")
- cmd.get_client().MultipleTimes().AndReturn(self.client)
- if response_contents is None:
- contents = [{self.id_field: 'myid1', },
- {self.id_field: 'myid2', }, ]
- else:
- contents = response_contents
- reses = {resources: contents}
- self.client.format = self.format
- resstr = self.client.serialize(reses)
- # url method body
- query = ""
- args = detail and ['-D', ] or []
- args.extend(['--request-format', self.format])
- if fields_1:
- for field in fields_1:
- args.append('--fields')
- args.append(field)
-
- if tags:
- args.append('--')
- args.append("--tag")
- for tag in tags:
- args.append(tag)
- if isinstance(tag, unicode):
- tag = urllib.quote(tag.encode('utf-8'))
- if query:
- query += "&tag=" + tag
- else:
- query = "tag=" + tag
- if (not tags) and fields_2:
- args.append('--')
- if fields_2:
- args.append("--fields")
- for field in fields_2:
- args.append(field)
- if detail:
- query = query and query + '&verbose=True' or 'verbose=True'
- fields_1.extend(fields_2)
- for field in fields_1:
- 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 += ['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
- path = getattr(self.client, resources + "_path")
- self.client.httpclient.request(
- MyUrlComparator(end_url(path, query, format=self.format),
- self.client),
- 'GET',
- body=None,
- headers=mox.ContainsKeyValue(
- 'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr))
- self.mox.ReplayAll()
- cmd_parser = cmd.get_parser("list_" + 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.assertTrue('myid1' in _str)
- return _str
-
- def _test_list_resources_with_pagination(self, resources, cmd):
- 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")
- fake_query = "marker=myid2&limit=2"
- reses1 = {resources: [{'id': 'myid1', },
- {'id': 'myid2', }],
- '%s_links' % resources: [{'href': end_url(path, fake_query),
- 'rel': 'next'}]}
- reses2 = {resources: [{'id': 'myid3', },
- {'id': 'myid4', }]}
- self.client.format = self.format
- resstr1 = self.client.serialize(reses1)
- resstr2 = self.client.serialize(reses2)
- self.client.httpclient.request(
- end_url(path, "", format=self.format), 'GET',
- body=None,
- headers=mox.ContainsKeyValue(
- 'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr1))
- self.client.httpclient.request(
- end_url(path, fake_query, format=self.format), 'GET',
- body=None,
- headers=mox.ContainsKeyValue(
- 'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr2))
- self.mox.ReplayAll()
- cmd_parser = cmd.get_parser("list_" + resources)
- args = ['--request-format', self.format]
- shell.run_command(cmd, cmd_parser, args)
- #parsed_args = cmd_parser.parse_args("")
- #cmd.run(parsed_args)
- self.mox.VerifyAll()
- self.mox.UnsetStubs()
-
- def _test_update_resource(self, resource, cmd, myid, args, extrafields):
- self.mox.StubOutWithMock(cmd, "get_client")
- self.mox.StubOutWithMock(self.client.httpclient, "request")
- cmd.get_client().MultipleTimes().AndReturn(self.client)
- body = {resource: extrafields}
- path = getattr(self.client, resource + "_path")
- self.client.httpclient.request(
- MyUrlComparator(end_url(path % myid, format=self.format),
- self.client),
- 'PUT',
- body=MyComparator(body, self.client),
- headers=mox.ContainsKeyValue(
- 'X-Auth-Token', TOKEN)).AndReturn((MyResp(204), None))
- args.extend(['--request-format', self.format])
- self.mox.ReplayAll()
- cmd_parser = cmd.get_parser("update_" + resource)
- shell.run_command(cmd, cmd_parser, args)
- self.mox.VerifyAll()
- self.mox.UnsetStubs()
- _str = self.fake_stdout.make_string()
- self.assertTrue(myid in _str)
-
- def _test_show_resource(self, resource, cmd, myid, args, fields=[]):
- 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 = {resource:
- {self.id_field: myid,
- 'name': 'myname', }, }
- self.client.format = self.format
- resstr = self.client.serialize(expected_res)
- path = getattr(self.client, resource + "_path")
- self.client.httpclient.request(
- end_url(path % myid, query, format=self.format), 'GET',
- body=None,
- headers=mox.ContainsKeyValue(
- 'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr))
- args.extend(['--request-format', self.format])
- self.mox.ReplayAll()
- cmd_parser = cmd.get_parser("show_" + resource)
- shell.run_command(cmd, cmd_parser, args)
- self.mox.VerifyAll()
- self.mox.UnsetStubs()
- _str = self.fake_stdout.make_string()
- self.assertTrue(myid in _str)
- self.assertTrue('myname' in _str)
-
- def _test_delete_resource(self, resource, cmd, myid, args):
- self.mox.StubOutWithMock(cmd, "get_client")
- self.mox.StubOutWithMock(self.client.httpclient, "request")
- cmd.get_client().MultipleTimes().AndReturn(self.client)
- path = getattr(self.client, resource + "_path")
- self.client.httpclient.request(
- end_url(path % myid, format=self.format), 'DELETE',
- body=None,
- headers=mox.ContainsKeyValue(
- 'X-Auth-Token', TOKEN)).AndReturn((MyResp(204), None))
- args.extend(['--request-format', self.format])
- self.mox.ReplayAll()
- cmd_parser = cmd.get_parser("delete_" + resource)
- shell.run_command(cmd, cmd_parser, args)
- self.mox.VerifyAll()
- self.mox.UnsetStubs()
- _str = self.fake_stdout.make_string()
- self.assertTrue(myid in _str)
-
- def _test_update_resource_action(self, resource, cmd, myid, action, args,
- body, retval=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, resource + "_path")
- path_action = '%s/%s' % (myid, action)
- self.client.httpclient.request(
- end_url(path % path_action, format=self.format), 'PUT',
- body=MyComparator(body, self.client),
- headers=mox.ContainsKeyValue(
- 'X-Auth-Token', TOKEN)).AndReturn((MyResp(204), retval))
- args.extend(['--request-format', self.format])
- self.mox.ReplayAll()
- cmd_parser = cmd.get_parser("delete_" + resource)
- shell.run_command(cmd, cmd_parser, args)
- self.mox.VerifyAll()
- self.mox.UnsetStubs()
- _str = self.fake_stdout.make_string()
- self.assertTrue(myid in _str)
-
-
-class ClientV2UnicodeTestJson(CLITestV20Base):
- def test_do_request(self):
- self.client.format = self.format
- self.mox.StubOutWithMock(self.client.httpclient, "request")
- unicode_text = u'\u7f51\u7edc'
- # url with unicode
- action = u'/test'
- expected_action = action.encode('utf-8')
- # query string with unicode
- params = {'test': unicode_text}
- expect_query = urllib.urlencode({'test':
- unicode_text.encode('utf-8')})
- # request body with unicode
- body = params
- expect_body = self.client.serialize(body)
- # headers with unicode
- self.client.httpclient.auth_token = unicode_text
- expected_auth_token = unicode_text.encode('utf-8')
-
- self.client.httpclient.request(
- end_url(expected_action, query=expect_query, format=self.format),
- 'PUT', body=expect_body,
- headers=mox.ContainsKeyValue(
- 'X-Auth-Token',
- expected_auth_token)).AndReturn((MyResp(200), expect_body))
-
- self.mox.ReplayAll()
- res_body = self.client.do_request('PUT', action, body=body,
- params=params)
- self.mox.VerifyAll()
- self.mox.UnsetStubs()
-
- # test response with unicode
- self.assertEqual(res_body, body)
-
-
-class ClientV2UnicodeTestXML(ClientV2UnicodeTestJson):
- format = 'xml'
diff --git a/tests/unit/test_cli20_extensions.py b/tests/unit/test_cli20_extensions.py
deleted file mode 100644
index 874de77..0000000
--- a/tests/unit/test_cli20_extensions.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# 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 quantumclient.quantum.v2_0.extension import ListExt
-from quantumclient.quantum.v2_0.extension import ShowExt
-from tests.unit.test_cli20 import CLITestV20Base
-from tests.unit.test_cli20 import MyApp
-
-
-class CLITestV20Extension(CLITestV20Base):
- id_field = 'alias'
-
- def test_list_extensions(self):
- resources = 'extensions'
- cmd = ListExt(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.assertTrue('name' in ret_words)
- self.assertTrue('alias' in ret_words)
- self.assertFalse('other' in 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 = ShowExt(MyApp(sys.stdout), None)
- args = [self.test_id]
- ext_alias = self.test_id
- self._test_show_resource(resource, cmd, ext_alias, args, fields=[])
diff --git a/tests/unit/test_cli20_floatingips.py b/tests/unit/test_cli20_floatingips.py
deleted file mode 100644
index b640112..0000000
--- a/tests/unit/test_cli20_floatingips.py
+++ /dev/null
@@ -1,139 +0,0 @@
-#!/usr/bin/env python
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# 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 quantumclient.quantum.v2_0 import floatingip as fip
-from tests.unit import test_cli20
-
-
-class CLITestV20FloatingIpsJSON(test_cli20.CLITestV20Base):
- 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]
- position_names = ['floating_network_id']
- position_values = [name]
- self._test_create_resource(resource, cmd, name, myid, args,
- position_names, position_values)
-
- 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_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"}
- )
-
-
-class CLITestV20FloatingIpsXML(CLITestV20FloatingIpsJSON):
- format = 'xml'
diff --git a/tests/unit/test_cli20_network.py b/tests/unit/test_cli20_network.py
deleted file mode 100644
index 7df54ff..0000000
--- a/tests/unit/test_cli20_network.py
+++ /dev/null
@@ -1,533 +0,0 @@
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import sys
-
-import mox
-
-from quantumclient.common import exceptions
-from quantumclient.common import utils
-from quantumclient.quantum.v2_0 import network
-from quantumclient import shell
-from tests.unit import test_cli20
-
-
-class CLITestV20NetworkJSON(test_cli20.CLITestV20Base):
- def setUp(self):
- super(CLITestV20NetworkJSON, self).setUp(plurals={'tags': 'tag'})
-
- def test_create_network(self):
- """Create net: myname."""
- resource = 'network'
- cmd = network.CreateNetwork(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_create_network_with_unicode(self):
- """Create net: u'\u7f51\u7edc'."""
- resource = 'network'
- cmd = network.CreateNetwork(test_cli20.MyApp(sys.stdout), None)
- name = u'\u7f51\u7edc'
- 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_network_tenant(self):
- """Create net: --tenant_id tenantid myname."""
- resource = 'network'
- cmd = network.CreateNetwork(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')
-
- # Test dashed options
- args = ['--tenant-id', 'tenantid', name]
- self._test_create_resource(resource, cmd, name, myid, args,
- position_names, position_values,
- tenant_id='tenantid')
-
- def test_create_network_tags(self):
- """Create net: myname --tags a b."""
- resource = 'network'
- cmd = network.CreateNetwork(test_cli20.MyApp(sys.stdout), None)
- name = 'myname'
- myid = 'myid'
- args = [name, '--tags', 'a', 'b']
- position_names = ['name', ]
- position_values = [name, ]
- self._test_create_resource(resource, cmd, name, myid, args,
- position_names, position_values,
- tags=['a', 'b'])
-
- def test_create_network_state(self):
- """Create net: --admin_state_down myname."""
- resource = 'network'
- cmd = network.CreateNetwork(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)
-
- # Test dashed options
- args = ['--admin-state-down', name, ]
- self._test_create_resource(resource, cmd, name, myid, args,
- position_names, position_values,
- admin_state_up=False)
-
- 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.end_url(path, query), '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.assertEquals('\n', _str)
-
- def _test_list_networks(self, cmd, detail=False, tags=[],
- fields_1=[], fields_2=[], page_size=None,
- sort_key=[], sort_dir=[]):
- 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)
-
- 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.end_url(path, query), '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().AndReturn(self.client)
- setup_list_stub('networks', data, '')
- cmd.get_client().AndReturn(self.client)
- 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.get_data(parsed_args)
- self.mox.VerifyAll()
- self.mox.UnsetStubs()
- _result = [x for x in result[1]]
- self.assertEqual(len(_result), len(expected))
- for res, exp in zip(_result, expected):
- self.assertEqual(len(res), len(exp))
- for a, b in zip(res, exp):
- self.assertEqual(a, b)
-
- 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 = utils.loads(_str)
- self.assertEquals(1, len(returned_networks))
- net = returned_networks[0]
- self.assertEquals(1, len(net))
- self.assertEquals("id", net.keys()[0])
-
- 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 = utils.loads(_str)
- self.assertEquals(1, len(returned_networks))
- net = returned_networks[0]
- self.assertEquals(3, len(net))
- self.assertEquals(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.end_url(path, query), '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.assertEquals('\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)
- fields_1.extend(fields_2)
- for field in fields_1:
- 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.end_url(path, query), '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.assertTrue('myid1' in _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_externel_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_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'],
- {'name': 'myname', 'tags': ['a', 'b'], }
- )
-
- 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_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'])
-
- 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_extend_list(self, mox_calls):
- data = [{'id': 'netid%d' % i, 'name': 'net%d' % i,
- 'subnets': ['mysubid%d' % i]}
- for i in range(0, 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.end_url(path, 'fields=id&fields=cidr' + filters),
- '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, "_check_uri_length")
- self.client._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._check_uri_length(mox.IgnoreArg()).AndReturn(None)
- self.client.httpclient.request(
- test_cli20.end_url(path,
- 'fields=id&fields=cidr%s' % filters),
- 'GET',
- body=None,
- headers=mox.ContainsKeyValue(
- 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(response)
-
- self._test_extend_list(mox_calls)
-
-
-class CLITestV20NetworkXML(CLITestV20NetworkJSON):
- format = 'xml'
diff --git a/tests/unit/test_cli20_nvp_queue.py b/tests/unit/test_cli20_nvp_queue.py
deleted file mode 100644
index d84d9df..0000000
--- a/tests/unit/test_cli20_nvp_queue.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env python
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Nicira 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 quantumclient.quantum.v2_0 import nvp_qos_queue as qos
-from tests.unit import test_cli20
-
-
-class CLITestV20NvpQosQueueJSON(test_cli20.CLITestV20Base):
- def setUp(self):
- super(CLITestV20NvpQosQueueJSON, self).setUp(
- plurals={'qos_queues': 'qos_queue'})
-
- def test_create_qos_queue(self):
- """Create a qos queue."""
- resource = 'qos_queue'
- cmd = qos.CreateQoSQueue(
- test_cli20.MyApp(sys.stdout), None)
- myid = 'myid'
- name = 'my_queue'
- default = False
- args = ['--default', default, name]
- position_names = ['name', 'default']
- position_values = [name, default]
- self._test_create_resource(resource, cmd, name, myid, args,
- position_names, position_values)
-
- def test_create_qos_queue_all_values(self):
- """Create a qos queue."""
- resource = 'qos_queue'
- cmd = qos.CreateQoSQueue(
- test_cli20.MyApp(sys.stdout), None)
- myid = 'myid'
- name = 'my_queue'
- default = False
- min = '10'
- max = '40'
- qos_marking = 'untrusted'
- dscp = '0'
- args = ['--default', default, '--min', min, '--max', max,
- '--qos-marking', qos_marking, '--dscp', dscp, name]
- position_names = ['name', 'default', 'min', 'max', 'qos_marking',
- 'dscp']
- position_values = [name, default, min, max, qos_marking, dscp]
- self._test_create_resource(resource, cmd, name, myid, args,
- position_names, position_values)
-
- def test_list_qos_queue(self):
- resources = "qos_queues"
- cmd = qos.ListQoSQueue(
- test_cli20.MyApp(sys.stdout), None)
- self._test_list_resources(resources, cmd, True)
-
- def test_show_qos_queue_id(self):
- resource = 'qos_queue'
- cmd = qos.ShowQoSQueue(
- 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_delete_qos_queue(self):
- resource = 'qos_queue'
- cmd = qos.DeleteQoSQueue(
- test_cli20.MyApp(sys.stdout), None)
- myid = 'myid'
- args = [myid]
- self._test_delete_resource(resource, cmd, myid, args)
-
-
-class CLITestV20NvpQosQueueXML(CLITestV20NvpQosQueueJSON):
- format = 'xml'
diff --git a/tests/unit/test_cli20_nvpnetworkgateway.py b/tests/unit/test_cli20_nvpnetworkgateway.py
deleted file mode 100644
index ebf730a..0000000
--- a/tests/unit/test_cli20_nvpnetworkgateway.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Copyright 2012 Nicira, 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import sys
-
-from quantumclient.quantum.v2_0 import nvpnetworkgateway as nwgw
-from tests.unit import test_cli20
-
-
-class CLITestV20NetworkGatewayJSON(test_cli20.CLITestV20Base):
-
- resource = "network_gateway"
-
- def setUp(self):
- super(CLITestV20NetworkGatewayJSON, self).setUp(
- plurals={'devices': 'device',
- 'network_gateways': 'network_gateway'})
-
- def test_create_gateway(self):
- cmd = nwgw.CreateNetworkGateway(test_cli20.MyApp(sys.stdout), None)
- name = 'gw-test'
- myid = 'myid'
- args = [name, ]
- position_names = ['name', ]
- position_values = [name, ]
- self._test_create_resource(self.resource, cmd, name, myid, args,
- position_names, position_values)
-
- def test_create_gateway_with_tenant(self):
- cmd = nwgw.CreateNetworkGateway(test_cli20.MyApp(sys.stdout), None)
- name = 'gw-test'
- myid = 'myid'
- args = ['--tenant_id', 'tenantid', name]
- position_names = ['name', ]
- position_values = [name, ]
- self._test_create_resource(self.resource, cmd, name, myid, args,
- position_names, position_values,
- tenant_id='tenantid')
-
- def test_create_gateway_with_device(self):
- cmd = nwgw.CreateNetworkGateway(test_cli20.MyApp(sys.stdout), None)
- name = 'gw-test'
- myid = 'myid'
- args = ['--device', 'device_id=test', name, ]
- position_names = ['name', ]
- position_values = [name, ]
- self._test_create_resource(self.resource, cmd, name, myid, args,
- position_names, position_values,
- devices=[{'device_id': 'test'}])
-
- def test_list_gateways(self):
- resources = '%ss' % self.resource
- cmd = nwgw.ListNetworkGateway(test_cli20.MyApp(sys.stdout), None)
- self._test_list_resources(resources, cmd, True)
-
- def test_update_gateway(self):
- cmd = nwgw.UpdateNetworkGateway(test_cli20.MyApp(sys.stdout), None)
- self._test_update_resource(self.resource, cmd, 'myid',
- ['myid', '--name', 'cavani'],
- {'name': 'cavani'})
-
- def test_delete_gateway(self):
- cmd = nwgw.DeleteNetworkGateway(test_cli20.MyApp(sys.stdout), None)
- myid = 'myid'
- args = [myid]
- self._test_delete_resource(self.resource, cmd, myid, args)
-
- def test_show_gateway(self):
- cmd = nwgw.ShowNetworkGateway(test_cli20.MyApp(sys.stdout), None)
- args = ['--fields', 'id', '--fields', 'name', self.test_id]
- self._test_show_resource(self.resource, cmd, self.test_id, args,
- ['id', 'name'])
-
- def test_connect_network_to_gateway(self):
- cmd = nwgw.ConnectNetworkGateway(test_cli20.MyApp(sys.stdout), None)
- args = ['gw_id', 'net_id',
- '--segmentation-type', 'edi',
- '--segmentation-id', '7']
- self._test_update_resource_action(self.resource, cmd, 'gw_id',
- 'connect_network',
- args,
- {'network_id': 'net_id',
- 'segmentation_type': 'edi',
- 'segmentation_id': '7'})
-
- def test_disconnect_network_from_gateway(self):
- cmd = nwgw.DisconnectNetworkGateway(test_cli20.MyApp(sys.stdout), None)
- args = ['gw_id', 'net_id',
- '--segmentation-type', 'edi',
- '--segmentation-id', '7']
- self._test_update_resource_action(self.resource, cmd, 'gw_id',
- 'disconnect_network',
- args,
- {'network_id': 'net_id',
- 'segmentation_type': 'edi',
- 'segmentation_id': '7'})
-
-
-class CLITestV20NetworkGatewayXML(CLITestV20NetworkGatewayJSON):
- format = 'xml'
diff --git a/tests/unit/test_cli20_port.py b/tests/unit/test_cli20_port.py
deleted file mode 100644
index 545f35b..0000000
--- a/tests/unit/test_cli20_port.py
+++ /dev/null
@@ -1,304 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import sys
-
-import mox
-
-from quantumclient.quantum.v2_0 import port
-from quantumclient import shell
-from 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]
- position_names = ['network_id']
- position_values = []
- 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_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: <security_groups> netid
-
- The <security_groups> 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_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_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)
- fields_1.extend(fields_2)
- for field in fields_1:
- 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.end_url(path, query % myid), '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.assertTrue('myid1' in _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 --tags a b."""
- resource = 'port'
- cmd = port.UpdatePort(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_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': None})
-
- 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)
-
-
-class CLITestV20PortXML(CLITestV20PortJSON):
- format = 'xml'
diff --git a/tests/unit/test_cli20_router.py b/tests/unit/test_cli20_router.py
deleted file mode 100644
index 35ac577..0000000
--- a/tests/unit/test_cli20_router.py
+++ /dev/null
@@ -1,197 +0,0 @@
-# Copyright 2012 Nicira, 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import sys
-
-from quantumclient.common import exceptions
-from quantumclient.quantum.v2_0 import router
-from 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, ]
- position_names = ['name', ]
- position_values = [name, ]
- self._test_create_resource(resource, cmd, name, myid, args,
- position_names, position_values)
-
- 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 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'],
- {'name': 'myname'}
- )
-
- 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'}
- else:
- retval = None
- self._test_update_resource_action(resource, cmd, 'myid',
- subcmd, args,
- body, 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",
- "enable_snat": True}}
- )
-
- 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": {}}
- )
-
-
-class CLITestV20RouterXML(CLITestV20RouterJSON):
- format = 'xml'
diff --git a/tests/unit/test_cli20_securitygroup.py b/tests/unit/test_cli20_securitygroup.py
deleted file mode 100644
index 4302093..0000000
--- a/tests/unit/test_cli20_securitygroup.py
+++ /dev/null
@@ -1,333 +0,0 @@
-#!/usr/bin/env python
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# 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
-
-import mox
-
-from quantumclient.quantum.v2_0 import securitygroup
-from tests.unit import test_cli20
-
-
-class CLITestV20SecurityGroupsJSON(test_cli20.CLITestV20Base):
- 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]
- 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_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, data=None, expected=None,
- args=[], conv=True,
- query_field=False):
- 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.end_url(path, query), 'GET',
- body=None,
- headers=mox.ContainsKeyValue(
- 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(resp)
-
- # Setup the default data
- _data = {'cols': ['id', 'security_group_id', 'remote_group_id'],
- 'data': [('ruleid1', 'myid1', 'myid1'),
- ('ruleid2', 'myid2', 'myid3'),
- ('ruleid3', 'myid2', 'myid2')]}
- _expected = {'cols': ['id', 'security_group', 'remote_group'],
- 'data': [('ruleid1', 'group1', 'group1'),
- ('ruleid2', 'group2', 'group3'),
- ('ruleid3', 'group2', 'group2')]}
- if data is None:
- data = _data
- list_data = [dict(zip(data['cols'], d)) for d in data['data']]
- if expected is None:
- expected = {}
- expected['cols'] = expected.get('cols', _expected['cols'])
- expected['data'] = expected.get('data', _expected['data'])
-
- 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().AndReturn(self.client)
- query = ''
- if query_field:
- query = '&'.join(['fields=' + f for f in data['cols']])
- setup_list_stub('security_group_rules', list_data, query)
- if conv:
- cmd.get_client().AndReturn(self.client)
- sec_ids = set()
- for n in data['data']:
- sec_ids.add(n[1])
- sec_ids.add(n[2])
- 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.get_data(parsed_args)
- self.mox.VerifyAll()
- self.mox.UnsetStubs()
- # Check columns
- self.assertEqual(result[0], expected['cols'])
- # Check data
- _result = [x for x in result[1]]
- self.assertEqual(len(_result), len(expected['data']))
- for res, exp in zip(_result, expected['data']):
- self.assertEqual(len(res), len(exp))
- self.assertEqual(res, exp)
-
- def test_list_security_group_rules_extend_source_id(self):
- self._test_list_security_group_rules_extend()
-
- def test_list_security_group_rules_extend_no_nameconv(self):
- expected = {'cols': ['id', 'security_group_id', 'remote_group_id'],
- 'data': [('ruleid1', 'myid1', 'myid1'),
- ('ruleid2', 'myid2', 'myid3'),
- ('ruleid3', 'myid2', 'myid2')]}
- args = ['--no-nameconv']
- self._test_list_security_group_rules_extend(expected=expected,
- args=args, conv=False)
-
- def test_list_security_group_rules_extend_with_columns(self):
- args = '-c id -c security_group_id -c remote_group_id'.split()
- self._test_list_security_group_rules_extend(args=args)
-
- def test_list_security_group_rules_extend_with_columns_no_id(self):
- args = '-c id -c security_group -c remote_group'.split()
- self._test_list_security_group_rules_extend(args=args)
-
- def test_list_security_group_rules_extend_with_fields(self):
- args = '-F id -F security_group_id -F remote_group_id'.split()
- self._test_list_security_group_rules_extend(args=args,
- query_field=True)
-
- def test_list_security_group_rules_extend_with_fields_no_id(self):
- args = '-F id -F security_group -F remote_group'.split()
- self._test_list_security_group_rules_extend(args=args,
- query_field=True)
-
-
-class CLITestV20SecurityGroupsXML(CLITestV20SecurityGroupsJSON):
- format = 'xml'
diff --git a/tests/unit/test_cli20_subnet.py b/tests/unit/test_cli20_subnet.py
deleted file mode 100644
index 5c048a6..0000000
--- a/tests/unit/test_cli20_subnet.py
+++ /dev/null
@@ -1,402 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import sys
-
-from quantumclient.quantum.v2_0 import subnet
-from tests.unit import test_cli20
-
-
-class CLITestV20SubnetJSON(test_cli20.CLITestV20Base):
- 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 = 'cidrvalue'
- gateway = 'gatewayvalue'
- args = ['--gateway', gateway, netid, 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_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]
- try:
- self._test_create_resource(resource, cmd, name, myid, args,
- position_names, position_values)
- except Exception:
- return
- self.fail('No exception for bad gateway option')
-
- 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 <allocation_pool> netid cidr.
- The <allocation_pool> 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 <pools> netid cidr.
- The <pools> 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 <host_route> netid cidr.
- The <host_route> 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 <host_routes> netid cidr.
- The <host_routes> 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 <dns-nameservers> netid cidr.
- The <dns-nameservers> 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_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_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_known_option_after_unknown(self):
- """List subnets: -- --tags a b --request-format xml."""
- 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',
- '--tags', 'a', 'b'],
- {'name': 'myname', 'tags': ['a', 'b'], }
- )
-
- def test_update_subnet_known_option_before_id(self):
- """Update subnet: --request-format json myid --name myname."""
- # --request-format xml is known option
- resource = 'subnet'
- cmd = subnet.UpdateSubnet(test_cli20.MyApp(sys.stdout), None)
- self._test_update_resource(resource, cmd, 'myid',
- ['--request-format', 'json',
- 'myid', '--name', 'myname'],
- {'name': 'myname', }
- )
-
- def test_update_subnet_known_option_after_id(self):
- """Update subnet: myid --name myname --request-format json."""
- # --request-format xml is known option
- resource = 'subnet'
- cmd = subnet.UpdateSubnet(test_cli20.MyApp(sys.stdout), None)
- self._test_update_resource(resource, cmd, 'myid',
- ['myid', '--name', 'myname',
- '--request-format', 'json'],
- {'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)
-
-
-class CLITestV20SubnetXML(CLITestV20SubnetJSON):
- format = 'xml'
diff --git a/tests/unit/test_name_or_id.py b/tests/unit/test_name_or_id.py
deleted file mode 100644
index fc3bdac..0000000
--- a/tests/unit/test_name_or_id.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# Copyright 2012 OpenStack LLC.
-# 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.
-#
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import uuid
-
-import mox
-import testtools
-
-from quantumclient.common import exceptions
-from quantumclient.quantum import v2_0 as quantumv20
-from quantumclient.v2_0 import client
-from tests.unit import test_cli20
-
-
-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 = str(uuid.uuid4())
- 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.end_url(path, "fields=id&id=" + _id), 'GET',
- body=None,
- headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN)
- ).AndReturn((test_cli20.MyResp(200), resstr))
- self.mox.ReplayAll()
- returned_id = quantumv20.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 = str(uuid.uuid4())
- 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.end_url(path, "fields=id&id=" + _id), 'GET',
- body=None,
- headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN)
- ).AndReturn((test_cli20.MyResp(200), resstr1))
- self.client.httpclient.request(
- test_cli20.end_url(path, "fields=id&name=" + _id), 'GET',
- body=None,
- headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN)
- ).AndReturn((test_cli20.MyResp(200), resstr))
- self.mox.ReplayAll()
- returned_id = quantumv20.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 = str(uuid.uuid4())
- 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.end_url(path, "fields=id&name=" + name), 'GET',
- body=None,
- headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN)
- ).AndReturn((test_cli20.MyResp(200), resstr))
- self.mox.ReplayAll()
- returned_id = quantumv20.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': str(uuid.uuid4())},
- {'id': str(uuid.uuid4())}]}
- resstr = self.client.serialize(reses)
- self.mox.StubOutWithMock(self.client.httpclient, "request")
- path = getattr(self.client, "networks_path")
- self.client.httpclient.request(
- test_cli20.end_url(path, "fields=id&name=" + name), 'GET',
- body=None,
- headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN)
- ).AndReturn((test_cli20.MyResp(200), resstr))
- self.mox.ReplayAll()
- try:
- quantumv20.find_resourceid_by_name_or_id(
- self.client, 'network', name)
- except exceptions.QuantumClientException as ex:
- self.assertTrue('Multiple' in ex.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.end_url(path, "fields=id&name=" + name), 'GET',
- body=None,
- headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN)
- ).AndReturn((test_cli20.MyResp(200), resstr))
- self.mox.ReplayAll()
- try:
- quantumv20.find_resourceid_by_name_or_id(
- self.client, 'network', name)
- except exceptions.QuantumClientException as ex:
- self.assertTrue('Unable to find' in ex.message)
- self.assertEqual(404, ex.status_code)
diff --git a/tests/unit/test_quota.py b/tests/unit/test_quota.py
deleted file mode 100644
index 633ff62..0000000
--- a/tests/unit/test_quota.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/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.
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import sys
-
-from quantumclient.common import exceptions
-from quantumclient.quantum.v2_0 import quota as test_quota
-from 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.QuantumClientException, 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)
diff --git a/tests/unit/test_shell.py b/tests/unit/test_shell.py
deleted file mode 100644
index b6a8e14..0000000
--- a/tests/unit/test_shell.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# 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.
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import argparse
-import cStringIO
-import os
-import re
-import sys
-
-import fixtures
-import mox
-import testtools
-from testtools import matchers
-
-from quantumclient.common import exceptions
-from quantumclient 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/'
-
-
-class NoExitArgumentParser(argparse.ArgumentParser):
- def error(self, message):
- raise exceptions.CommandError(message)
-
-
-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}
-
- def _tolerant_shell(self, cmd):
- t_shell = openstack_shell.QuantumShell('2.0')
- t_shell.run(cmd.split())
-
- # Patch os.environ to avoid required auth info.
- def setUp(self):
- super(ShellTest, self).setUp()
- self.mox = mox.Mox()
- for var in self.FAKE_ENV:
- self.useFixture(
- fixtures.EnvironmentVariable(
- var, self.FAKE_ENV[var]))
-
- # Make a fake shell object, a helping wrapper to call it, and a quick
- # way of asserting that certain API calls were made.
- global shell, _shell, assert_called, assert_called_anytime
- _shell = openstack_shell.QuantumShell('2.0')
- shell = lambda cmd: _shell.run(cmd.split())
-
- def shell(self, argstr):
- orig = sys.stdout
- clean_env = {}
- _old_env, os.environ = os.environ, clean_env.copy()
- try:
- sys.stdout = cStringIO.StringIO()
- _shell = openstack_shell.QuantumShell('2.0')
- _shell.run(argstr.split())
- except SystemExit:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.assertEqual(exc_value.code, 0)
- finally:
- out = sys.stdout.getvalue()
- sys.stdout.close()
- sys.stdout = orig
- os.environ = _old_env
- return out
-
- def test_run_unknown_command(self):
- openstack_shell.QuantumShell('2.0').run('fake')
-
- def test_help(self):
- required = 'usage:'
- help_text = self.shell('help')
- self.assertThat(
- help_text,
- matchers.MatchesRegex(required))
-
- def test_help_on_subcommand(self):
- required = [
- '.*?^usage: .* quota-list']
- stdout = 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 = self.shell('help network-create')
- self.assertThat(
- help_text,
- matchers.MatchesRegex(required))
-
- def test_unknown_auth_strategy(self):
- self.shell('--os-auth-strategy fake quota-list')
-
- def test_auth(self):
- self.shell(' --os-username test'
- ' --os-password test'
- ' --os-tenant-name test'
- ' --os-auth-url http://127.0.0.1:5000/'
- ' --os-auth-strategy keystone quota-list')
-
- def test_build_option_parser(self):
- quant_shell = openstack_shell.QuantumShell('2.0')
- result = quant_shell.build_option_parser('descr', '2.0')
- self.assertEqual(True, isinstance(result, argparse.ArgumentParser))
-
- def test_main_with_unicode(self):
- self.mox.StubOutClassWithMocks(openstack_shell, 'QuantumShell')
- qshell_mock = openstack_shell.QuantumShell('2.0')
- #self.mox.StubOutWithMock(qshell_mock, 'run')
- unicode_text = u'\u7f51\u7edc'
- argv = ['net-list', unicode_text, unicode_text.encode('utf-8')]
- qshell_mock.run([u'net-list', unicode_text,
- unicode_text]).AndReturn(0)
- self.mox.ReplayAll()
- ret = openstack_shell.main(argv=argv)
- self.mox.VerifyAll()
- self.mox.UnsetStubs()
- self.assertEqual(ret, 0)
-
- def test_endpoint_option(self):
- shell = openstack_shell.QuantumShell('2.0')
- parser = shell.build_option_parser('descr', '2.0')
-
- # Neither $OS_ENDPOINT_TYPE nor --endpoint-type
- namespace = parser.parse_args([])
- self.assertEqual('publicURL', namespace.endpoint_type)
-
- # --endpoint-type but not $OS_ENDPOINT_TYPE
- namespace = parser.parse_args(['--endpoint-type=admin'])
- self.assertEqual('admin', namespace.endpoint_type)
-
- def test_endpoint_environment_variable(self):
- fixture = fixtures.EnvironmentVariable("OS_ENDPOINT_TYPE",
- "public")
- self.useFixture(fixture)
-
- shell = openstack_shell.QuantumShell('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.endpoint_type)
-
- # --endpoint-type and $OS_ENDPOINT_TYPE
- namespace = parser.parse_args(['--endpoint-type=admin'])
- self.assertEqual('admin', namespace.endpoint_type)
diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py
deleted file mode 100644
index d7d1520..0000000
--- a/tests/unit/test_utils.py
+++ /dev/null
@@ -1,190 +0,0 @@
-# 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.
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-import datetime
-import sys
-
-import testtools
-
-from quantumclient.common import exceptions
-from quantumclient.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_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)
-
-
-class JSONUtilsTestCase(testtools.TestCase):
- def test_dumps(self):
- self.assertEqual(utils.dumps({'a': 'b'}), '{"a": "b"}')
-
- def test_dumps_dict_with_date_value(self):
- x = datetime.datetime(1920, 2, 3, 4, 5, 6, 7)
- res = utils.dumps({1: 'a', 2: x})
- expected = '{"1": "a", "2": "1920-02-03 04:05:06.000007"}'
- self.assertEqual(expected, res)
-
- def test_dumps_dict_with_spaces(self):
- x = datetime.datetime(1920, 2, 3, 4, 5, 6, 7)
- res = utils.dumps({1: 'a ', 2: x})
- expected = '{"1": "a ", "2": "1920-02-03 04:05:06.000007"}'
- self.assertEqual(expected, res)
-
- def test_loads(self):
- self.assertEqual(utils.loads('{"a": "b"}'), {'a': 'b'})
-
-
-class ToPrimitiveTestCase(testtools.TestCase):
- def test_list(self):
- self.assertEqual(utils.to_primitive([1, 2, 3]), [1, 2, 3])
-
- def test_empty_list(self):
- self.assertEqual(utils.to_primitive([]), [])
-
- def test_tuple(self):
- self.assertEqual(utils.to_primitive((1, 2, 3)), [1, 2, 3])
-
- def test_empty_tuple(self):
- self.assertEqual(utils.to_primitive(()), [])
-
- def test_dict(self):
- self.assertEqual(
- utils.to_primitive(dict(a=1, b=2, c=3)),
- dict(a=1, b=2, c=3))
-
- def test_empty_dict(self):
- self.assertEqual(utils.to_primitive({}), {})
-
- def test_datetime(self):
- x = datetime.datetime(1920, 2, 3, 4, 5, 6, 7)
- self.assertEqual(
- utils.to_primitive(x),
- '1920-02-03 04:05:06.000007')
-
- def test_iter(self):
- x = xrange(1, 6)
- self.assertEqual(utils.to_primitive(x), [1, 2, 3, 4, 5])
-
- def test_iteritems(self):
- d = {'a': 1, 'b': 2, 'c': 3}
-
- class IterItemsClass(object):
- def iteritems(self):
- return d.iteritems()
-
- x = IterItemsClass()
- p = utils.to_primitive(x)
- self.assertEqual(p, {'a': 1, 'b': 2, 'c': 3})
-
- def test_nasties(self):
- def foo():
- pass
- x = [datetime, foo, dir]
- ret = utils.to_primitive(x)
- self.assertEqual(len(ret), 3)
-
- def test_to_primitive_dict_with_date_value(self):
- x = datetime.datetime(1920, 2, 3, 4, 5, 6, 7)
- res = utils.to_primitive({'a': x})
- self.assertEqual({'a': '1920-02-03 04:05:06.000007'}, res)
-
-
-class ImportClassTestCase(testtools.TestCase):
- def test_import_class(self):
- dt = utils.import_class('datetime.datetime')
- self.assertTrue(sys.modules['datetime'].datetime is dt)
-
- def test_import_bad_class(self):
- self.assertRaises(
- ImportError, utils.import_class,
- 'lol.u_mad.brah')
-
- def test_get_client_class_invalid_version(self):
- self.assertRaises(
- exceptions.UnsupportedVersion,
- utils.get_client_class, 'image', '2', {'image': '2'})