renamed to novaclient and fixed flavor tests

This commit is contained in:
Sandy Walsh 2011-02-26 05:04:40 -04:00
parent 8611fc2598
commit bd18c7e429
38 changed files with 138 additions and 101 deletions

View File

@ -1,5 +1,6 @@
Copyright (c) 2009 Jacob Kaplan-Moss - initial codebase (< v2.1)
Copyright (c) 2011 Rackspace - OpenStack extensions (>= v2.1)
All rights reserved.
Apache License

View File

@ -2,12 +2,12 @@ Python bindings to the OpenStack Nova API
==================================================
This is a client for the OpenStack Nova API. There's a Python API (the
``novatools`` module), and a command-line script (``nova``). Each
``novaclient`` module), and a command-line script (``nova``). Each
implements 100% of the OpenStack Nova API.
[PENDING] `Full documentation is available`__.
__ http://packages.python.org/python-novatools/
__ http://packages.python.org/python-novaclient/
You'll also probably want to read `Rackspace's API guide`__ (PDF) -- the first
bit, at least -- to get an idea of the concepts. Rackspace is doing the cloud
@ -18,11 +18,11 @@ __ http://docs.rackspacecloud.com/servers/api/cs-devguide-latest.pdf
Development takes place on GitHub__. Bug reports and patches may be filed there.
__ https://github.com/rackspace/python-novatools
__ https://github.com/rackspace/python-client
This code a fork of `Jacobian's python-cloudservers`__ If you need API support
for the Rackspace API soley or the BSD license, you should use that repository.
python-novatools is licensed under the Apache License like the rest of OpenStack.
python-client is licensed under the Apache License like the rest of OpenStack.
__ http://github.com/jacobian/python-cloudservers
@ -104,12 +104,12 @@ Python API
[PENDING] There's also a `complete Python API`__.
__ http://packages.python.org/python-novatools/
__ http://packages.python.org/python-novaclient/
By way of a quick-start::
>>> import novatools
>>> nt = novatools.OpenStack(USERNAME, API_KEY [, AUTH_URL])
>>> import novaclient
>>> nt = novaclient.OpenStack(USERNAME, API_KEY [, AUTH_URL])
>>> nt.flavors.list()
[...]
>>> nt.servers.list()
@ -127,4 +127,4 @@ By way of a quick-start::
What's new?
-----------
[PENDING] See `the release notes <http://packages.python.org/python-novatools/releases.html>`_.
[PENDING] See `the release notes <http://packages.python.org/python-novaclient/releases.html>`_.

View File

@ -61,9 +61,9 @@ qthelp:
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/python-novatools.qhcp"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/python-novaclient.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/python-novatools.qhc"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/python-novaclient.qhc"
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex

View File

@ -1,17 +1,17 @@
The :mod:`novatools` Python API
The :mod:`novaclient` Python API
==================================
.. module:: novatools
.. module:: novaclient
:synopsis: A client for the OpenStack Nova API.
.. currentmodule:: novatools
.. currentmodule:: novaclient
Usage
-----
First create an instance of :class:`OpenStack` with your credentials::
>>> from novatools import OpenStack
>>> from novaclient import OpenStack
>>> nova = OpenStack(USERNAME, API_KEY, AUTH_URL)
Then call methods on the :class:`OpenStack` object:

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# python-novatools documentation build configuration file, created by
# python-novaclient documentation build configuration file, created by
# sphinx-quickstart on Sun Dec 6 14:19:25 2009.
#
# This file is execfile()d with the current directory set to its containing dir.
@ -37,7 +37,7 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = u'python-novatools'
project = u'python-novaclient'
copyright = u'Rackspace, based on work by Jacob Kaplan-Moss'
# The version info for the project you're documenting, acts as replacement for
@ -45,9 +45,9 @@ copyright = u'Rackspace, based on work by Jacob Kaplan-Moss'
# built documents.
#
# The short X.Y version.
version = '2.2'
version = '2.3'
# The full version, including alpha/beta/rc tags.
release = '2.2'
release = '2.3'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@ -158,7 +158,7 @@ html_static_path = ['_static']
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'python-novatoolsdoc'
htmlhelp_basename = 'python-novaclientdoc'
# -- Options for LaTeX output --------------------------------------------------
@ -172,7 +172,7 @@ htmlhelp_basename = 'python-novatoolsdoc'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'python-novatools.tex', u'python-novatools Documentation',
('index', 'python-novaclient.tex', u'python-novaclient Documentation',
u'Rackspace - based on work by Jacob Kaplan-Moss', 'manual'),
]

View File

@ -2,7 +2,7 @@ Python bindings to the OpenStack Nova API
==================================================
This is a client for OpenStack Nova API. There's :doc:`a Python API
<api>` (the :mod:`novatools` module), and a :doc:`command-line script
<api>` (the :mod:`novaclient` module), and a :doc:`command-line script
<shell>` (installed as :program:`nova`). Each implements the entire
OpenStack Nova API.
@ -32,7 +32,7 @@ Contributing
Development takes place `on GitHub`__; please file bugs/pull requests there.
__ https://github.com/rackspace/python-novatools
__ https://github.com/rackspace/python-novaclient
Run tests with ``python setup.py test``.

View File

@ -1,11 +1,11 @@
Backup schedules
================
.. currentmodule:: cloudservers
.. currentmodule:: novaclient
Rackspace allows scheduling of weekly and/or daily backups for virtual
servers. You can access these backup schedules either off the API object as
:attr:`CloudServers.backup_schedules`, or directly off a particular
:attr:`OpenStack.backup_schedules`, or directly off a particular
:class:`Server` instance as :attr:`Server.backup_schedule`.
Classes

View File

@ -1,14 +1,14 @@
Exceptions
==========
.. currentmodule:: cloudservers
.. currentmodule:: novaclient
Exceptions
----------
Exceptions that the API might throw:
.. automodule:: cloudservers
:members: CloudServersException, BadRequest, Unauthorized, Forbidden,
.. automodule:: novaclient
:members: OpenStackException, BadRequest, Unauthorized, Forbidden,
NotFound, OverLimit

View File

@ -10,7 +10,7 @@ From Rackspace's API documentation:
Classes
-------
.. currentmodule:: cloudservers
.. currentmodule:: novaclient
.. autoclass:: FlavorManager
:members: get, list, find, findall
@ -32,4 +32,4 @@ Classes
.. attribute:: disk
The amount of disk space this flavor has, in MB
The amount of disk space this flavor has, in MB

View File

@ -1,7 +1,7 @@
Images
======
.. currentmodule:: cloudservers
.. currentmodule:: novaclient
An "image" is a snapshot from which you can create new server instances.
@ -51,4 +51,4 @@ Classes
.. attribute:: serverId
If this image was created from a :class:`Server` then this attribute
will be set to the ID of the server whence this image came.
will be set to the ID of the server whence this image came.

View File

@ -25,7 +25,7 @@ From the Rackspace API guide:
Classes
-------
.. currentmodule:: cloudservers
.. currentmodule:: novaclient
.. autoclass:: IPGroupManager
:members: get, list, find, findall, create, delete
@ -43,4 +43,4 @@ Classes
.. attribute:: servers
A list of server IDs in this group.
A list of server IDs in this group.

View File

@ -6,7 +6,7 @@ A virtual machine instance.
Classes
-------
.. currentmodule:: cloudservers
.. currentmodule:: novaclient
.. autoclass:: ServerManager
:members: get, list, find, findall, create, update, delete, share_ip,
@ -70,4 +70,4 @@ Constants
Reboot types:
.. data:: REBOOT_SOFT
.. data:: REBOOT_HARD
.. data:: REBOOT_HARD

View File

@ -2,6 +2,12 @@
Release notes
=============
2.3 (March 2, 2011)
=================
* package renamed to python-novaclient. Module to novaclient
2.2 (March 1, 2011)
=================

View File

@ -23,10 +23,15 @@ two environment variables:
Your API key.
.. envvar:: NOVA_URL
The OpenStack API server URL.
For example, in Bash you'd use::
export NOVA_USERNAME=yourname
export NOVA_API_KEY=yadayadayada
export NOVA_URL=http://...
From there, all shell commands take the form::

View File

@ -16,12 +16,12 @@
# under the License.
"""
novatools module.
novaclient module.
"""
__version__ = '2.2'
__version__ = '2.3'
from novatools.backup_schedules import (
from novaclient.backup_schedules import (
BackupSchedule, BackupScheduleManager,
BACKUP_WEEKLY_DISABLED, BACKUP_WEEKLY_SUNDAY, BACKUP_WEEKLY_MONDAY,
BACKUP_WEEKLY_TUESDAY, BACKUP_WEEKLY_WEDNESDAY,
@ -33,15 +33,15 @@ from novatools.backup_schedules import (
BACKUP_DAILY_H_1400_1600, BACKUP_DAILY_H_1600_1800,
BACKUP_DAILY_H_1800_2000, BACKUP_DAILY_H_2000_2200,
BACKUP_DAILY_H_2200_0000)
from novatools.client import OpenStackClient
from novatools.exceptions import (OpenStackException, BadRequest,
from novaclient.client import OpenStackClient
from novaclient.exceptions import (OpenStackException, BadRequest,
Unauthorized, Forbidden, NotFound, OverLimit)
from novatools.flavors import FlavorManager, Flavor
from novatools.images import ImageManager, Image
from novatools.ipgroups import IPGroupManager, IPGroup
from novatools.servers import (ServerManager, Server, REBOOT_HARD,
from novaclient.flavors import FlavorManager, Flavor
from novaclient.images import ImageManager, Image
from novaclient.ipgroups import IPGroupManager, IPGroup
from novaclient.servers import (ServerManager, Server, REBOOT_HARD,
REBOOT_SOFT)
from novatools.zones import Zone, ZoneManager
from novaclient.zones import Zone, ZoneManager
class OpenStack(object):
@ -79,7 +79,7 @@ class OpenStack(object):
Normally this is called automatically when you first access the API,
but you can call this method to force authentication right now.
Returns on success; raises :exc:`novatools.Unauthorized` if the
Returns on success; raises :exc:`novaclient.Unauthorized` if the
credentials are wrong.
"""
self.client.authenticate()

View File

@ -2,7 +2,7 @@
Backup Schedule interface.
"""
from novatools import base
from novaclient import base
BACKUP_WEEKLY_DISABLED = 'DISABLED'
BACKUP_WEEKLY_SUNDAY = 'SUNDAY'

View File

@ -2,7 +2,7 @@
Base utilities to build API operation managers and objects on top of.
"""
from novatools.exceptions import NotFound
from novaclient.exceptions import NotFound
# Python 2.4 compat
try:

View File

@ -16,13 +16,13 @@ if not hasattr(urlparse, 'parse_qsl'):
import cgi
urlparse.parse_qsl = cgi.parse_qsl
import novatools
from novatools import exceptions
import novaclient
from novaclient import exceptions
class OpenStackClient(httplib2.Http):
USER_AGENT = 'python-novatools/%s' % novatools.__version__
USER_AGENT = 'python-novaclient/%s' % novaclient.__version__
def __init__(self, user, apikey, auth_url):
super(OpenStackClient, self).__init__()

View File

@ -3,7 +3,7 @@ Flavor interface.
"""
from novatools import base
from novaclient import base
class Flavor(base.Resource):

View File

@ -2,7 +2,7 @@
Image interface.
"""
from novatools import base
from novaclient import base
class Image(base.Resource):

View File

@ -2,7 +2,7 @@
IP Group interface.
"""
from novatools import base
from novaclient import base
class IPGroup(base.Resource):

View File

@ -19,7 +19,7 @@
Server interface.
"""
from novatools import base
from novaclient import base
REBOOT_SOFT, REBOOT_HARD = 'SOFT', 'HARD'

View File

@ -20,7 +20,7 @@ Command-line interface to the OpenStack Nova API.
"""
import argparse
import novatools
import novaclient
import getpass
import httplib2
import os
@ -29,11 +29,11 @@ import sys
import textwrap
# Choices for flags.
DAY_CHOICES = [getattr(novatools, i).lower()
for i in dir(novatools)
DAY_CHOICES = [getattr(novaclient, i).lower()
for i in dir(novaclient)
if i.startswith('BACKUP_WEEKLY_')]
HOUR_CHOICES = [getattr(novatools, i).lower()
for i in dir(novatools)
HOUR_CHOICES = [getattr(novaclient, i).lower()
for i in dir(novaclient)
if i.startswith('BACKUP_DAILY_')]
@ -65,7 +65,7 @@ def env(e):
class OpenStackShell(object):
# Hook for the test suite to inject a fake server.
_api_class = novatools.OpenStack
_api_class = novaclient.OpenStack
def __init__(self):
self.parser = argparse.ArgumentParser(
@ -155,7 +155,7 @@ class OpenStackShell(object):
self.cs = self._api_class(user, apikey, url)
try:
self.cs.authenticate()
except novatools.Unauthorized:
except novaclient.Unauthorized:
raise CommandError("Invalid OpenStack Nova credentials.")
args.func(args)
@ -198,10 +198,10 @@ class OpenStackShell(object):
# If we have some flags, update the backup
backup = {}
if args.daily:
backup['daily'] = getattr(novatools, 'BACKUP_DAILY_%s' %
backup['daily'] = getattr(novaclient, 'BACKUP_DAILY_%s' %
args.daily.upper())
if args.weekly:
backup['weekly'] = getattr(novatools, 'BACKUP_WEEKLY_%s' %
backup['weekly'] = getattr(novaclient, 'BACKUP_WEEKLY_%s' %
args.weekly.upper())
if args.enabled is not None:
backup['enabled'] = args.enabled
@ -221,17 +221,17 @@ class OpenStackShell(object):
@arg('--flavor',
default=None,
metavar='<flavor>',
help="Flavor ID (see 'novatools flavors'). "\
help="Flavor ID (see 'novaclient flavors'). "\
"Defaults to 256MB RAM instance.")
@arg('--image',
default=None,
metavar='<image>',
help="Image ID (see 'novatools images'). "\
help="Image ID (see 'novaclient images'). "\
"Defaults to Ubuntu 10.04 LTS.")
@arg('--ipgroup',
default=None,
metavar='<group>',
help="IP group name or ID (see 'novatools ipgroup-list').")
help="IP group name or ID (see 'novaclient ipgroup-list').")
@arg('--meta',
metavar="<key=value>",
action='append',
@ -394,8 +394,8 @@ class OpenStackShell(object):
@arg('--hard',
dest='reboot_type',
action='store_const',
const=novatools.REBOOT_HARD,
default=novatools.REBOOT_SOFT,
const=novaclient.REBOOT_HARD,
default=novaclient.REBOOT_SOFT,
help='Perform a hard reboot (instead of a soft one).')
@arg('server', metavar='<server>', help='Name or ID of server.')
def do_reboot(self, args):
@ -572,7 +572,7 @@ class OpenStackShell(object):
"""Get a flavor by name, ID, or RAM size."""
try:
return self._find_resource(self.cs.flavors, flavor)
except novatools.NotFound:
except novaclient.NotFound:
return self.cs.flavors.find(ram=flavor)
def _find_resource(self, manager, name_or_id):
@ -582,7 +582,7 @@ class OpenStackShell(object):
return manager.get(int(name_or_id))
else:
return manager.find(name=name_or_id)
except novatools.NotFound:
except novaclient.NotFound:
raise CommandError("No %s with a name or ID of '%s' exists." %
(manager.resource_class.__name__.lower(), name_or_id))

View File

@ -19,7 +19,7 @@
Zone interface.
"""
from novatools import base
from novaclient import base
class Zone(base.Resource):

View File

@ -1,6 +1,6 @@
[nosetests]
with-coverage = true
cover-package = novatools
cover-package = novaclient
cover-html = true
cover-erase = true
cover-inclusive = true

View File

@ -10,11 +10,11 @@ if sys.version_info < (2,6):
requirements.append('simplejson')
setup(
name = "python-novatools",
version = "2.2",
name = "python-novaclient",
version = "2.3",
description = "Client library for OpenStack Nova API",
long_description = read('README.rst'),
url = 'https://github.com/rackspace/python-novatools',
url = 'https://github.com/rackspace/python-novaclient',
license = 'Apache',
author = 'Rackspace, based on work by Jacob Kaplan-Moss',
author_email = 'github@racklabs.com',
@ -34,6 +34,6 @@ setup(
test_suite = "nose.collector",
entry_points = {
'console_scripts': ['nova = novatools.shell:main']
'console_scripts': ['nova = novaclient.shell:main']
}
)

View File

@ -10,8 +10,8 @@ import httplib2
import urlparse
import urllib
from nose.tools import assert_equal
from novatools import OpenStack
from novatools.client import OpenStackClient
from novaclient import OpenStack
from novaclient.client import OpenStackClient
from utils import fail, assert_in, assert_not_in, assert_has_keys
@ -38,6 +38,29 @@ class FakeServer(OpenStack):
self.client.callstack = []
def assert_called_anytime(self, method, url, body=None):
"""
Assert than an API method was called anytime in the test.
"""
expected = (method, url)
assert self.client.callstack, \
"Expected %s %s but no calls were made." % expected
found = False
for entry in self.client.callstack:
called = entry[0:2]
if expected == entry[0:2]:
found = True
break
assert found, 'Expected %s %s; got %s' % \
(expected, self.client.callstack)
if body is not None:
assert_equal(entry[2], body)
self.client.callstack = []
def authenticate(self):
pass

View File

@ -1,11 +1,11 @@
import mock
import novatools
import novaclient
import httplib2
from nose.tools import assert_raises, assert_equal
def test_authenticate_success():
cs = novatools.OpenStack("username", "apikey")
cs = novaclient.OpenStack("username", "apikey")
auth_response = httplib2.Response({
'status': 204,
'x-server-management-url':
@ -31,19 +31,19 @@ def test_authenticate_success():
def test_authenticate_failure():
cs = novatools.OpenStack("username", "apikey")
cs = novaclient.OpenStack("username", "apikey")
auth_response = httplib2.Response({'status': 401})
mock_request = mock.Mock(return_value=(auth_response, None))
@mock.patch.object(httplib2.Http, "request", mock_request)
def test_auth_call():
assert_raises(novatools.Unauthorized, cs.client.authenticate)
assert_raises(novaclient.Unauthorized, cs.client.authenticate)
test_auth_call()
def test_auth_automatic():
client = novatools.OpenStack("username", "apikey").client
client = novaclient.OpenStack("username", "apikey").client
client.management_url = ''
mock_request = mock.Mock(return_value=(None, None))
@ -58,7 +58,7 @@ def test_auth_automatic():
def test_auth_manual():
cs = novatools.OpenStack("username", "apikey")
cs = novaclient.OpenStack("username", "apikey")
@mock.patch.object(cs.client, 'authenticate')
def test_auth_call(m):

View File

@ -1,5 +1,5 @@
from novatools.backup_schedules import *
from novaclient.backup_schedules import *
from fakeserver import FakeServer
from utils import assert_isinstance

View File

@ -1,9 +1,9 @@
import mock
import novatools.base
from novatools import Flavor
from novatools.exceptions import NotFound
from novatools.base import Resource
import novaclient.base
from novaclient import Flavor
from novaclient.exceptions import NotFound
from novaclient.base import Resource
from nose.tools import assert_equal, assert_not_equal, assert_raises
from fakeserver import FakeServer
@ -16,11 +16,11 @@ def test_resource_repr():
def test_getid():
assert_equal(novatools.base.getid(4), 4)
assert_equal(novaclient.base.getid(4), 4)
class O(object):
id = 4
assert_equal(novatools.base.getid(O), 4)
assert_equal(novaclient.base.getid(O), 4)
def test_resource_lazy_getattr():

View File

@ -1,6 +1,6 @@
import mock
import httplib2
from novatools.client import OpenStackClient
from novaclient.client import OpenStackClient
from nose.tools import assert_equal
fake_response = httplib2.Response({"status": 200})

View File

@ -1,4 +1,4 @@
from novatools import Flavor, NotFound
from novaclient import Flavor, NotFound
from fakeserver import FakeServer
from utils import assert_isinstance
from nose.tools import assert_raises, assert_equal

View File

@ -1,4 +1,4 @@
from novatools import Image
from novaclient import Image
from fakeserver import FakeServer
from utils import assert_isinstance
from nose.tools import assert_equal

View File

@ -1,4 +1,4 @@
from novatools import IPGroup
from novaclient import IPGroup
from fakeserver import FakeServer
from utils import assert_isinstance
from nose.tools import assert_equal

View File

@ -2,7 +2,7 @@ import StringIO
from nose.tools import assert_equal
from fakeserver import FakeServer
from utils import assert_isinstance
from novatools import Server
from novaclient import Server
cs = FakeServer()

View File

@ -2,7 +2,7 @@ import os
import mock
import httplib2
from nose.tools import assert_raises, assert_equal
from novatools.shell import OpenStackShell, CommandError
from novaclient.shell import OpenStackShell, CommandError
from fakeserver import FakeServer
from utils import assert_in
@ -18,10 +18,12 @@ def setup():
# 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
global shell, _shell, assert_called, assert_called_anytime
_shell = OpenStackShell()
_shell._api_class = FakeServer
assert_called = lambda m, u, b=None: _shell.cs.assert_called(m, u, b)
assert_called_anytime = lambda m, u, b=None: \
_shell.cs.assert_called_anytime(m, u, b)
shell = lambda cmd: _shell.main(cmd.split())
@ -175,7 +177,7 @@ def test_boot_ipgroup_name():
def test_flavor_list():
shell('flavor-list')
assert_called('GET', '/flavors/detail')
assert_called_anytime('GET', '/flavors/detail')
def test_image_list():

View File

@ -2,7 +2,7 @@ import StringIO
from nose.tools import assert_equal
from fakeserver import FakeServer
from utils import assert_isinstance
from novatools import Zone
from novaclient import Zone
os = FakeServer()