Merge "Add instance name as parameter to CLI"

This commit is contained in:
Jenkins
2014-12-19 11:50:33 +00:00
committed by Gerrit Code Review
10 changed files with 301 additions and 108 deletions

View File

@@ -46,6 +46,8 @@ class BackupManagerTest(testtools.TestCase):
def setUp(self): def setUp(self):
super(BackupManagerTest, self).setUp() super(BackupManagerTest, self).setUp()
self.backups = backups.Backups(mock.Mock()) self.backups = backups.Backups(mock.Mock())
self.instance_with_id = mock.Mock()
self.instance_with_id.id = 215
def tearDown(self): def tearDown(self):
super(BackupManagerTest, self).tearDown() super(BackupManagerTest, self).tearDown()
@@ -66,6 +68,14 @@ class BackupManagerTest(testtools.TestCase):
self.backups.create(**args) self.backups.create(**args)
create_mock.assert_called_with('/backups', body, 'backup') create_mock.assert_called_with('/backups', body, 'backup')
def test_create_with_instance_obj(self):
create_mock = mock.Mock()
self.backups._create = create_mock
args = {'name': 'test_backup', 'instance': self.instance_with_id.id}
body = {'backup': args}
self.backups.create('test_backup', self.instance_with_id)
create_mock.assert_called_with('/backups', body, 'backup')
def test_create_incremental(self): def test_create_incremental(self):
create_mock = mock.Mock() create_mock = mock.Mock()
self.backups._create = create_mock self.backups._create = create_mock

View File

@@ -0,0 +1,108 @@
# Copyright 2014 Tesora 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 mock
import testtools
from troveclient.v1 import databases
"""
Unit tests for databases.py
"""
class DatabaseTest(testtools.TestCase):
def setUp(self):
super(DatabaseTest, self).setUp()
self.orig__init = databases.Database.__init__
databases.Database.__init__ = mock.Mock(return_value=None)
self.database = databases.Database()
def tearDown(self):
super(DatabaseTest, self).tearDown()
databases.Database.__init__ = self.orig__init
class DatabasesTest(testtools.TestCase):
def setUp(self):
super(DatabasesTest, self).setUp()
self.orig__init = databases.Databases.__init__
databases.Databases.__init__ = mock.Mock(return_value=None)
self.databases = databases.Databases()
self.databases.api = mock.Mock()
self.databases.api.client = mock.Mock()
self.instance_with_id = mock.Mock()
self.instance_with_id.id = 215
self.fakedb1 = ['db1']
self.fakedb2 = ['db1', 'db2']
def tearDown(self):
super(DatabasesTest, self).tearDown()
databases.Databases.__init__ = self.orig__init
def _get_mock_method(self):
self._resp = mock.Mock()
self._body = None
self._url = None
def side_effect_func(url, body=None):
self._body = body
self._url = url
return (self._resp, body)
return mock.Mock(side_effect=side_effect_func)
def test_create(self):
self.databases.api.client.post = self._get_mock_method()
self._resp.status_code = 200
self.databases.create(23, self.fakedb1)
self.assertEqual('/instances/23/databases', self._url)
self.assertEqual({"databases": self.fakedb1}, self._body)
self.databases.create(23, self.fakedb2)
self.assertEqual('/instances/23/databases', self._url)
self.assertEqual({"databases": self.fakedb2}, self._body)
# test creation with the instance as an object
self.databases.create(self.instance_with_id, self.fakedb1)
self.assertEqual({"databases": self.fakedb1}, self._body)
def test_delete(self):
self.databases.api.client.delete = self._get_mock_method()
self._resp.status_code = 200
self.databases.delete(27, self.fakedb1[0])
self.assertEqual('/instances/27/databases/%s' % self.fakedb1[0],
self._url)
self.databases.delete(self.instance_with_id, self.fakedb1[0])
self.assertEqual('/instances/%s/databases/%s' %
(self.instance_with_id.id, self.fakedb1[0]),
self._url)
self._resp.status_code = 400
self.assertRaises(Exception, self.databases.delete, 34, self.fakedb1)
def test_list(self):
page_mock = mock.Mock()
self.databases._paginated = page_mock
self.databases.list('instance1')
page_mock.assert_called_with('/instances/instance1/databases',
'databases', None, None)
limit = 'test-limit'
marker = 'test-marker'
self.databases.list('instance1', limit, marker)
page_mock.assert_called_with('/instances/instance1/databases',
'databases', limit, marker)

View File

@@ -81,13 +81,12 @@ class InstancesTest(testtools.TestCase):
self.instances.api.client = mock.Mock() self.instances.api.client = mock.Mock()
self.instances.resource_class = mock.Mock(return_value="instance-1") self.instances.resource_class = mock.Mock(return_value="instance-1")
self.orig_base_getid = base.getid self.instance_with_id = mock.Mock()
base.getid = mock.Mock(return_value="instance1") self.instance_with_id.id = 215
def tearDown(self): def tearDown(self):
super(InstancesTest, self).tearDown() super(InstancesTest, self).tearDown()
instances.Instances.__init__ = self.orig__init instances.Instances.__init__ = self.orig__init
base.getid = self.orig_base_getid
def test_create(self): def test_create(self):
def side_effect_func(path, body, inst): def side_effect_func(path, body, inst):
@@ -128,7 +127,7 @@ class InstancesTest(testtools.TestCase):
self.instances._get = mock.Mock(side_effect=side_effect_func) self.instances._get = mock.Mock(side_effect=side_effect_func)
self.assertEqual(('/instances/instance1', 'instance'), self.assertEqual(('/instances/instance1', 'instance'),
self.instances.get(1)) self.instances.get('instance1'))
def test_delete(self): def test_delete(self):
resp = mock.Mock() resp = mock.Mock()
@@ -136,6 +135,7 @@ class InstancesTest(testtools.TestCase):
body = None body = None
self.instances.api.client.delete = mock.Mock(return_value=(resp, body)) self.instances.api.client.delete = mock.Mock(return_value=(resp, body))
self.instances.delete('instance1') self.instances.delete('instance1')
self.instances.delete(self.instance_with_id)
resp.status_code = 500 resp.status_code = 500
self.assertRaises(Exception, self.instances.delete, 'instance1') self.assertRaises(Exception, self.instances.delete, 'instance1')
@@ -150,32 +150,52 @@ class InstancesTest(testtools.TestCase):
self.assertIsNone(self.instances._action(1, body)) self.assertIsNone(self.instances._action(1, body))
def _set_action_mock(self): def _set_action_mock(self):
def side_effect_func(instance_id, body): def side_effect_func(instance, body):
self._instance_id = instance_id self._instance_id = base.getid(instance)
self._body = body self._body = body
self._instance_id = None self._instance_id = None
self._body = None self._body = None
self.instances._action = mock.Mock(side_effect=side_effect_func) self.instances._action = mock.Mock(side_effect=side_effect_func)
def test_resize_volume(self): def _test_resize_volume(self, instance, id):
self._set_action_mock() self._set_action_mock()
self.instances.resize_volume(152, 512) self.instances.resize_volume(instance, 1024)
self.assertEqual(152, self._instance_id) self.assertEqual(id, self._instance_id)
self.assertEqual({"resize": {"volume": {"size": 512}}}, self._body) self.assertEqual({"resize": {"volume": {"size": 1024}}}, self._body)
def test_resize_instance(self): def test_resize_volume_with_id(self):
self._test_resize_volume(152, 152)
def test_resize_volume_with_obj(self):
self._test_resize_volume(self.instance_with_id,
self.instance_with_id.id)
def _test_resize_instance(self, instance, id):
self._set_action_mock() self._set_action_mock()
self.instances.resize_instance(4725, 103) self.instances.resize_instance(instance, 103)
self.assertEqual(4725, self._instance_id) self.assertEqual(id, self._instance_id)
self.assertEqual({"resize": {"flavorRef": 103}}, self._body) self.assertEqual({"resize": {"flavorRef": 103}}, self._body)
def test_restart(self): def test_resize_instance_with_id(self):
self._test_resize_instance(4725, 4725)
def test_resize_instance_with_obj(self):
self._test_resize_instance(self.instance_with_id,
self.instance_with_id.id)
def _test_restart(self, instance, id):
self._set_action_mock() self._set_action_mock()
self.instances.restart(253) self.instances.restart(instance)
self.assertEqual(253, self._instance_id) self.assertEqual(id, self._instance_id)
self.assertEqual({'restart': {}}, self._body) self.assertEqual({'restart': {}}, self._body)
def test_restart_with_id(self):
self._test_restart(253, 253)
def test_restart_with_obj(self):
self._test_restart(self.instance_with_id, self.instance_with_id.id)
def test_modify(self): def test_modify(self):
resp = mock.Mock() resp = mock.Mock()
resp.status_code = 200 resp.status_code = 200
@@ -183,6 +203,8 @@ class InstancesTest(testtools.TestCase):
self.instances.api.client.put = mock.Mock(return_value=(resp, body)) self.instances.api.client.put = mock.Mock(return_value=(resp, body))
self.instances.modify(123) self.instances.modify(123)
self.instances.modify(123, 321) self.instances.modify(123, 321)
self.instances.modify(self.instance_with_id)
self.instances.modify(self.instance_with_id, 123)
resp.status_code = 500 resp.status_code = 500
self.assertRaises(Exception, self.instances.modify, 'instance1') self.assertRaises(Exception, self.instances.modify, 'instance1')
@@ -195,6 +217,10 @@ class InstancesTest(testtools.TestCase):
self.instances.edit(123, 321) self.instances.edit(123, 321)
self.instances.edit(123, 321, 'name-1234') self.instances.edit(123, 321, 'name-1234')
self.instances.edit(123, 321, 'name-1234', True) self.instances.edit(123, 321, 'name-1234', True)
self.instances.edit(self.instance_with_id)
self.instances.edit(self.instance_with_id, 123)
self.instances.edit(self.instance_with_id, 123, 'name-1234')
self.instances.edit(self.instance_with_id, 123, 'name-1234', True)
resp.status_code = 500 resp.status_code = 500
self.assertRaises(Exception, self.instances.edit, 'instance1') self.assertRaises(Exception, self.instances.edit, 'instance1')
@@ -204,7 +230,7 @@ class InstancesTest(testtools.TestCase):
self.instances._get = mock.Mock(side_effect=side_effect_func) self.instances._get = mock.Mock(side_effect=side_effect_func)
self.assertEqual(('/instances/instance1/configuration', 'instance'), self.assertEqual(('/instances/instance1/configuration', 'instance'),
self.instances.configuration(1)) self.instances.configuration('instance1'))
class InstanceStatusTest(testtools.TestCase): class InstanceStatusTest(testtools.TestCase):

View File

@@ -18,7 +18,6 @@
import mock import mock
import testtools import testtools
from troveclient import base
from troveclient.v1 import users from troveclient.v1 import users
""" """
@@ -51,13 +50,12 @@ class UsersTest(testtools.TestCase):
self.users.api = mock.Mock() self.users.api = mock.Mock()
self.users.api.client = mock.Mock() self.users.api.client = mock.Mock()
self.orig_base_getid = base.getid self.instance_with_id = mock.Mock()
base.getid = mock.Mock(return_value="instance1") self.instance_with_id.id = 215
def tearDown(self): def tearDown(self):
super(UsersTest, self).tearDown() super(UsersTest, self).tearDown()
users.Users.__init__ = self.orig__init users.Users.__init__ = self.orig__init
base.getid = self.orig_base_getid
def _get_mock_method(self): def _get_mock_method(self):
self._resp = mock.Mock() self._resp = mock.Mock()
@@ -102,6 +100,10 @@ class UsersTest(testtools.TestCase):
self.users.create(23, [user]) self.users.create(23, [user])
self.assertEqual({"users": [user]}, self._body) self.assertEqual({"users": [user]}, self._body)
# test creation with the instance as an object
self.users.create(self.instance_with_id, [user])
self.assertEqual({"users": [user]}, self._body)
# Make sure that response of 400 is recognized as an error. # Make sure that response of 400 is recognized as an error.
user['host'] = '%' user['host'] = '%'
self._resp.status_code = 400 self._resp.status_code = 400
@@ -112,18 +114,21 @@ class UsersTest(testtools.TestCase):
self._resp.status_code = 200 self._resp.status_code = 200
self.users.delete(27, 'user1') self.users.delete(27, 'user1')
self.assertEqual('/instances/27/users/user1', self._url) self.assertEqual('/instances/27/users/user1', self._url)
self.users.delete(self.instance_with_id, 'user1')
self.assertEqual('/instances/%s/users/user1' %
self.instance_with_id.id, self._url)
self._resp.status_code = 400 self._resp.status_code = 400
self.assertRaises(Exception, self.users.delete, 34, 'user1') self.assertRaises(Exception, self.users.delete, 34, 'user1')
def test_list(self): def test_list(self):
page_mock = mock.Mock() page_mock = mock.Mock()
self.users._paginated = page_mock self.users._paginated = page_mock
self.users.list(1) self.users.list('instance1')
page_mock.assert_called_with('/instances/instance1/users', page_mock.assert_called_with('/instances/instance1/users',
'users', None, None) 'users', None, None)
limit = 'test-limit' limit = 'test-limit'
marker = 'test-marker' marker = 'test-marker'
self.users.list(1, limit, marker) self.users.list('instance1', limit, marker)
page_mock.assert_called_with('/instances/instance1/users', page_mock.assert_called_with('/instances/instance1/users',
'users', limit, marker) 'users', limit, marker)

View File

@@ -60,7 +60,7 @@ class Backups(base.ManagerWithFind):
} }
if instance: if instance:
body['backup']['instance'] = instance body['backup']['instance'] = base.getid(instance)
if backup: if backup:
body["backup"]['backup'] = backup body["backup"]['backup'] = backup
if description: if description:

View File

@@ -32,16 +32,16 @@ class Databases(base.ManagerWithFind):
"""Manage :class:`Databases` resources.""" """Manage :class:`Databases` resources."""
resource_class = Database resource_class = Database
def create(self, instance_id, databases): def create(self, instance, databases):
"""Create new databases within the specified instance.""" """Create new databases within the specified instance."""
body = {"databases": databases} body = {"databases": databases}
url = "/instances/%s/databases" % instance_id url = "/instances/%s/databases" % base.getid(instance)
resp, body = self.api.client.post(url, body=body) resp, body = self.api.client.post(url, body=body)
common.check_for_exceptions(resp, body, url) common.check_for_exceptions(resp, body, url)
def delete(self, instance_id, dbname): def delete(self, instance, dbname):
"""Delete an existing database in the specified instance.""" """Delete an existing database in the specified instance."""
url = "/instances/%s/databases/%s" % (instance_id, dbname) url = "/instances/%s/databases/%s" % (base.getid(instance), dbname)
resp, body = self.api.client.delete(url) resp, body = self.api.client.delete(url)
common.check_for_exceptions(resp, body, url) common.check_for_exceptions(resp, body, url)

View File

@@ -80,22 +80,22 @@ class Instances(base.ManagerWithFind):
if configuration: if configuration:
body["instance"]["configuration"] = configuration body["instance"]["configuration"] = configuration
if replica_of or slave_of: if replica_of or slave_of:
body["instance"]["replica_of"] = replica_of or slave_of body["instance"]["replica_of"] = base.getid(replica_of) or slave_of
return self._create("/instances", body, "instance") return self._create("/instances", body, "instance")
def modify(self, instance_id, configuration=None): def modify(self, instance, configuration=None):
body = { body = {
"instance": { "instance": {
} }
} }
if configuration is not None: if configuration is not None:
body["instance"]["configuration"] = configuration body["instance"]["configuration"] = configuration
url = "/instances/%s" % instance_id url = "/instances/%s" % base.getid(instance)
resp, body = self.api.client.put(url, body=body) resp, body = self.api.client.put(url, body=body)
common.check_for_exceptions(resp, body, url) common.check_for_exceptions(resp, body, url)
def edit(self, instance_id, configuration=None, name=None, def edit(self, instance, configuration=None, name=None,
detach_replica_source=False, remove_configuration=False): detach_replica_source=False, remove_configuration=False):
body = { body = {
"instance": { "instance": {
@@ -116,7 +116,7 @@ class Instances(base.ManagerWithFind):
body["instance"]["slave_of"] = None body["instance"]["slave_of"] = None
body["instance"]["replica_of"] = None body["instance"]["replica_of"] = None
url = "/instances/%s" % instance_id url = "/instances/%s" % base.getid(instance)
resp, body = self.api.client.patch(url, body=body) resp, body = self.api.client.patch(url, body=body)
common.check_for_exceptions(resp, body, url) common.check_for_exceptions(resp, body, url)
@@ -147,38 +147,39 @@ class Instances(base.ManagerWithFind):
def delete(self, instance): def delete(self, instance):
"""Delete the specified instance. """Delete the specified instance.
:param instance_id: The instance id to delete :param instance: A reference to the instance to delete
""" """
url = "/instances/%s" % base.getid(instance) url = "/instances/%s" % base.getid(instance)
resp, body = self.api.client.delete(url) resp, body = self.api.client.delete(url)
common.check_for_exceptions(resp, body, url) common.check_for_exceptions(resp, body, url)
def _action(self, instance_id, body): def _action(self, instance, body):
"""Perform a server "action" -- reboot/rebuild/resize/etc.""" """Perform a server "action" -- reboot/rebuild/resize/etc."""
url = "/instances/%s/action" % instance_id url = "/instances/%s/action" % base.getid(instance)
resp, body = self.api.client.post(url, body=body) resp, body = self.api.client.post(url, body=body)
common.check_for_exceptions(resp, body, url) common.check_for_exceptions(resp, body, url)
if body: if body:
return self.resource_class(self, body, loaded=True) return self.resource_class(self, body, loaded=True)
return body return body
def resize_volume(self, instance_id, volume_size): def resize_volume(self, instance, volume_size):
"""Resize the volume on an existing instances.""" """Resize the volume on an existing instances."""
body = {"resize": {"volume": {"size": volume_size}}} body = {"resize": {"volume": {"size": volume_size}}}
self._action(instance_id, body) self._action(instance, body)
def resize_instance(self, instance_id, flavor_id): def resize_instance(self, instance, flavor_id):
"""Resizes an instance with a new flavor.""" """Resizes an instance with a new flavor."""
body = {"resize": {"flavorRef": flavor_id}} body = {"resize": {"flavorRef": flavor_id}}
self._action(instance_id, body) self._action(instance, body)
def restart(self, instance_id): def restart(self, instance):
"""Restart the database instance. """Restart the database instance.
:param instance_id: The :class:`Instance` (or its ID) to share onto. :param instance: The :class:`Instance` (or its ID) of the database
instance to restart.
""" """
body = {'restart': {}} body = {'restart': {}}
self._action(instance_id, body) self._action(instance, body)
def configuration(self, instance): def configuration(self, instance):
"""Get a configuration on instances. """Get a configuration on instances.

View File

@@ -24,19 +24,19 @@ class Root(base.ManagerWithFind):
resource_class = users.User resource_class = users.User
url = "/instances/%s/root" url = "/instances/%s/root"
def create(self, instance_id): def create(self, instance):
"""Implements root-enable API. """Implements root-enable API.
Enable the root user and return the root password for the Enable the root user and return the root password for the
specified db instance. specified db instance.
""" """
resp, body = self.api.client.post(self.url % instance_id) resp, body = self.api.client.post(self.url % base.getid(instance))
common.check_for_exceptions(resp, body, self.url) common.check_for_exceptions(resp, body, self.url)
return body['user']['name'], body['user']['password'] return body['user']['name'], body['user']['password']
def is_root_enabled(self, instance_id): def is_root_enabled(self, instance):
"""Return whether root is enabled for the instance.""" """Return whether root is enabled for the instance."""
resp, body = self.api.client.get(self.url % instance_id) resp, body = self.api.client.get(self.url % base.getid(instance))
common.check_for_exceptions(resp, body, self.url) common.check_for_exceptions(resp, body, self.url)
return self.resource_class(self, body, loaded=True) return self.resource_class(self, body, loaded=True)

View File

@@ -234,11 +234,13 @@ def do_cluster_instances(cs, args):
obj_is_dict=True) obj_is_dict=True)
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.service_type('database') @utils.service_type('database')
def do_delete(cs, args): def do_delete(cs, args):
"""Deletes an instance.""" """Deletes an instance."""
cs.instances.delete(args.instance) instance = _find_instance(cs, args.instance)
cs.instances.delete(instance)
@utils.arg('cluster', metavar='<cluster>', help='ID of the cluster.') @utils.arg('cluster', metavar='<cluster>', help='ID of the cluster.')
@@ -251,7 +253,7 @@ def do_cluster_delete(cs, args):
@utils.arg('instance', @utils.arg('instance',
metavar='<instance>', metavar='<instance>',
type=str, type=str,
help='UUID of the instance.') help='ID or name of the instance.')
@utils.arg('--name', @utils.arg('--name',
metavar='<name>', metavar='<name>',
type=str, type=str,
@@ -275,7 +277,8 @@ def do_cluster_delete(cs, args):
@utils.service_type('database') @utils.service_type('database')
def do_update(cs, args): def do_update(cs, args):
"""Updates an instance: Edits name, configuration, or replica source.""" """Updates an instance: Edits name, configuration, or replica source."""
cs.instances.edit(args.instance, args.configuration, args.name, instance = _find_instance(cs, args.instance)
cs.instances.edit(instance, args.configuration, args.name,
args.detach_replica_source, args.remove_configuration) args.detach_replica_source, args.remove_configuration)
@@ -331,18 +334,21 @@ def do_update(cs, args):
default=None, default=None,
help='ID of the configuration group to attach to the instance.') help='ID of the configuration group to attach to the instance.')
@utils.arg('--replica_of', @utils.arg('--replica_of',
metavar='<source_id>', metavar='<source_instance>',
default=None, default=None,
help='ID of an existing instance to replicate from.') help='ID or name of an existing instance to replicate from.')
@utils.service_type('database') @utils.service_type('database')
def do_create(cs, args): def do_create(cs, args):
"""Creates a new instance.""" """Creates a new instance."""
volume = None volume = None
replica_of_instance = None
if args.size: if args.size:
volume = {"size": args.size} volume = {"size": args.size}
restore_point = None restore_point = None
if args.backup: if args.backup:
restore_point = {"backupRef": args.backup} restore_point = {"backupRef": args.backup}
if args.replica_of:
replica_of_instance = _find_instance(cs, args.replica_of)
databases = [{'name': value} for value in args.databases] databases = [{'name': value} for value in args.databases]
users = [{'name': n, 'password': p, 'databases': databases} for (n, p) in users = [{'name': n, 'password': p, 'databases': databases} for (n, p) in
[z.split(':')[:2] for z in args.users]] [z.split(':')[:2] for z in args.users]]
@@ -368,7 +374,7 @@ def do_create(cs, args):
datastore_version=args.datastore_version, datastore_version=args.datastore_version,
nics=nics, nics=nics,
configuration=args.configuration, configuration=args.configuration,
replica_of=args.replica_of) replica_of=replica_of_instance)
_print_instance(instance) _print_instance(instance)
@@ -425,7 +431,7 @@ def do_cluster_create(cs, args):
@utils.arg('instance', @utils.arg('instance',
metavar='<instance>', metavar='<instance>',
type=str, type=str,
help='ID of the instance.') help='ID or name of the instance.')
@utils.arg('flavor_id', @utils.arg('flavor_id',
metavar='<flavor_id>', metavar='<flavor_id>',
help='New flavor of the instance.') help='New flavor of the instance.')
@@ -438,20 +444,21 @@ def do_resize_flavor(cs, args):
@utils.arg('instance', @utils.arg('instance',
metavar='<instance>', metavar='<instance>',
type=str, type=str,
help='ID of the instance.') help='ID or name of the instance.')
@utils.arg('flavor_id', @utils.arg('flavor_id',
metavar='<flavor_id>', metavar='<flavor_id>',
help='New flavor of the instance.') help='New flavor of the instance.')
@utils.service_type('database') @utils.service_type('database')
def do_resize_instance(cs, args): def do_resize_instance(cs, args):
"""Resizes an instance with a new flavor.""" """Resizes an instance with a new flavor."""
cs.instances.resize_instance(args.instance, args.flavor_id) instance = _find_instance(cs, args.instance)
cs.instances.resize_instance(instance, args.flavor_id)
@utils.arg('instance', @utils.arg('instance',
metavar='<instance>', metavar='<instance>',
type=str, type=str,
help='ID of the instance.') help='ID or name of the instance.')
@utils.arg('size', @utils.arg('size',
metavar='<size>', metavar='<size>',
type=int, type=int,
@@ -460,26 +467,29 @@ def do_resize_instance(cs, args):
@utils.service_type('database') @utils.service_type('database')
def do_resize_volume(cs, args): def do_resize_volume(cs, args):
"""Resizes the volume size of an instance.""" """Resizes the volume size of an instance."""
cs.instances.resize_volume(args.instance, args.size) instance = _find_instance(cs, args.instance)
cs.instances.resize_volume(instance, args.size)
@utils.arg('instance', @utils.arg('instance',
metavar='<instance>', metavar='<instance>',
type=str, type=str,
help='ID of the instance.') help='ID or name of the instance.')
@utils.service_type('database') @utils.service_type('database')
def do_restart(cs, args): def do_restart(cs, args):
"""Restarts an instance.""" """Restarts an instance."""
cs.instances.restart(args.instance) instance = _find_instance(cs, args.instance)
cs.instances.restart(instance)
@utils.arg('instance', @utils.arg('instance',
metavar='<instance>', metavar='<instance>',
type=str, type=str,
help='ID of the instance.') help='ID or name of the instance.')
def do_detach_replica(cs, args): def do_detach_replica(cs, args):
"""Detaches a replica instance from its replication source.""" """Detaches a replica instance from its replication source."""
cs.instances.edit(args.instance, detach_replica_source=True) instance = _find_instance(cs, args.instance)
cs.instances.edit(instance, detach_replica_source=True)
# Backup related commands # Backup related commands
@@ -492,17 +502,19 @@ def do_backup_show(cs, args):
_print_object(backup) _print_object(backup)
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.arg('--limit', metavar='<limit>', @utils.arg('--limit', metavar='<limit>',
default=None, default=None,
help='Return up to N number of the most recent backups.') help='Return up to N number of the most recent backups.')
@utils.service_type('database') @utils.service_type('database')
def do_backup_list_instance(cs, args): def do_backup_list_instance(cs, args):
"""Lists available backups for an instance.""" """Lists available backups for an instance."""
wrapper = cs.instances.backups(args.instance, limit=args.limit) instance = _find_instance(cs, args.instance)
wrapper = cs.instances.backups(instance, limit=args.limit)
backups = wrapper.items backups = wrapper.items
while wrapper.next and not args.limit: while wrapper.next and not args.limit:
wrapper = cs.instances.backups(args.instance, marker=wrapper.next) wrapper = cs.instances.backups(instance, marker=wrapper.next)
backups += wrapper.items backups += wrapper.items
utils.print_list(backups, ['id', 'name', 'status', utils.print_list(backups, ['id', 'name', 'status',
'parent_id', 'updated'], 'parent_id', 'updated'],
@@ -535,7 +547,8 @@ def do_backup_delete(cs, args):
cs.backups.delete(args.backup) cs.backups.delete(args.backup)
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.arg('name', metavar='<name>', help='Name of the backup.') @utils.arg('name', metavar='<name>', help='Name of the backup.')
@utils.arg('--description', metavar='<description>', @utils.arg('--description', metavar='<description>',
default=None, default=None,
@@ -546,7 +559,8 @@ def do_backup_delete(cs, args):
@utils.service_type('database') @utils.service_type('database')
def do_backup_create(cs, args): def do_backup_create(cs, args):
"""Creates a backup of an instance.""" """Creates a backup of an instance."""
backup = cs.backups.create(args.name, args.instance, instance = _find_instance(cs, args.instance)
backup = cs.backups.create(args.name, instance,
description=args.description, description=args.description,
parent_id=args.parent) parent_id=args.parent)
_print_object(backup) _print_object(backup)
@@ -578,7 +592,8 @@ def do_backup_copy(cs, args):
# Database related actions # Database related actions
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.arg('name', metavar='<name>', help='Name of the database.') @utils.arg('name', metavar='<name>', help='Name of the database.')
@utils.arg('--character_set', metavar='<character_set>', @utils.arg('--character_set', metavar='<character_set>',
default=None, default=None,
@@ -588,39 +603,45 @@ def do_backup_copy(cs, args):
@utils.service_type('database') @utils.service_type('database')
def do_database_create(cs, args): def do_database_create(cs, args):
"""Creates a database on an instance.""" """Creates a database on an instance."""
instance = _find_instance(cs, args.instance)
database_dict = {'name': args.name} database_dict = {'name': args.name}
if args.collate: if args.collate:
database_dict['collate'] = args.collate database_dict['collate'] = args.collate
if args.character_set: if args.character_set:
database_dict['character_set'] = args.character_set database_dict['character_set'] = args.character_set
cs.databases.create(args.instance, cs.databases.create(instance,
[database_dict]) [database_dict])
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.service_type('database') @utils.service_type('database')
def do_database_list(cs, args): def do_database_list(cs, args):
"""Lists available databases on an instance.""" """Lists available databases on an instance."""
wrapper = cs.databases.list(args.instance) instance = _find_instance(cs, args.instance)
wrapper = cs.databases.list(instance)
databases = wrapper.items databases = wrapper.items
while (wrapper.next): while (wrapper.next):
wrapper = cs.databases.list(args.instance, marker=wrapper.next) wrapper = cs.databases.list(instance, marker=wrapper.next)
databases += wrapper.items databases += wrapper.items
utils.print_list(databases, ['name']) utils.print_list(databases, ['name'])
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.arg('database', metavar='<database>', help='Name of the database.') @utils.arg('database', metavar='<database>', help='Name of the database.')
@utils.service_type('database') @utils.service_type('database')
def do_database_delete(cs, args): def do_database_delete(cs, args):
"""Deletes a database from an instance.""" """Deletes a database from an instance."""
cs.databases.delete(args.instance, args.database) instance = _find_instance(cs, args.instance)
cs.databases.delete(instance, args.database)
# User related actions # User related actions
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.arg('name', metavar='<name>', help='Name of user.') @utils.arg('name', metavar='<name>', help='Name of user.')
@utils.arg('password', metavar='<password>', help='Password of user.') @utils.arg('password', metavar='<password>', help='Password of user.')
@utils.arg('--host', metavar='<host>', default=None, @utils.arg('--host', metavar='<host>', default=None,
@@ -631,22 +652,25 @@ def do_database_delete(cs, args):
@utils.service_type('database') @utils.service_type('database')
def do_user_create(cs, args): def do_user_create(cs, args):
"""Creates a user on an instance.""" """Creates a user on an instance."""
instance = _find_instance(cs, args.instance)
databases = [{'name': value} for value in args.databases] databases = [{'name': value} for value in args.databases]
user = {'name': args.name, 'password': args.password, user = {'name': args.name, 'password': args.password,
'databases': databases} 'databases': databases}
if args.host: if args.host:
user['host'] = args.host user['host'] = args.host
cs.users.create(args.instance, [user]) cs.users.create(instance, [user])
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.service_type('database') @utils.service_type('database')
def do_user_list(cs, args): def do_user_list(cs, args):
"""Lists the users for an instance.""" """Lists the users for an instance."""
wrapper = cs.users.list(args.instance) instance = _find_instance(cs, args.instance)
wrapper = cs.users.list(instance)
users = wrapper.items users = wrapper.items
while (wrapper.next): while (wrapper.next):
wrapper = cs.users.list(args.instance, marker=wrapper.next) wrapper = cs.users.list(instance, marker=wrapper.next)
users += wrapper.items users += wrapper.items
for user in users: for user in users:
db_names = [db['name'] for db in user.databases] db_names = [db['name'] for db in user.databases]
@@ -654,39 +678,46 @@ def do_user_list(cs, args):
utils.print_list(users, ['name', 'host', 'databases']) utils.print_list(users, ['name', 'host', 'databases'])
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.arg('name', metavar='<name>', help='Name of user.') @utils.arg('name', metavar='<name>', help='Name of user.')
@utils.arg('--host', metavar='<host>', default=None, @utils.arg('--host', metavar='<host>', default=None,
help='Optional host of user.') help='Optional host of user.')
@utils.service_type('database') @utils.service_type('database')
def do_user_delete(cs, args): def do_user_delete(cs, args):
"""Deletes a user from an instance.""" """Deletes a user from an instance."""
cs.users.delete(args.instance, args.name, hostname=args.host) instance = _find_instance(cs, args.instance)
cs.users.delete(instance, args.name, hostname=args.host)
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.arg('name', metavar='<name>', help='Name of user.') @utils.arg('name', metavar='<name>', help='Name of user.')
@utils.arg('--host', metavar='<host>', default=None, @utils.arg('--host', metavar='<host>', default=None,
help='Optional host of user.') help='Optional host of user.')
@utils.service_type('database') @utils.service_type('database')
def do_user_show(cs, args): def do_user_show(cs, args):
"""Shows details of a user of an instance.""" """Shows details of a user of an instance."""
user = cs.users.get(args.instance, args.name, hostname=args.host) instance = _find_instance(cs, args.instance)
user = cs.users.get(instance, args.name, hostname=args.host)
_print_object(user) _print_object(user)
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.arg('name', metavar='<name>', help='Name of user.') @utils.arg('name', metavar='<name>', help='Name of user.')
@utils.arg('--host', metavar='<host>', default=None, @utils.arg('--host', metavar='<host>', default=None,
help='Optional host of user.') help='Optional host of user.')
@utils.service_type('database') @utils.service_type('database')
def do_user_show_access(cs, args): def do_user_show_access(cs, args):
"""Shows access details of a user of an instance.""" """Shows access details of a user of an instance."""
access = cs.users.list_access(args.instance, args.name, hostname=args.host) instance = _find_instance(cs, args.instance)
access = cs.users.list_access(instance, args.name, hostname=args.host)
utils.print_list(access, ['name']) utils.print_list(access, ['name'])
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.arg('name', metavar='<name>', help='Name of user.') @utils.arg('name', metavar='<name>', help='Name of user.')
@utils.arg('--host', metavar='<host>', default=None, @utils.arg('--host', metavar='<host>', default=None,
help='Optional host of user.') help='Optional host of user.')
@@ -701,6 +732,7 @@ def do_user_update_attributes(cs, args):
"""Updates a user's attributes on an instance. """Updates a user's attributes on an instance.
At least one optional argument must be provided. At least one optional argument must be provided.
""" """
instance = _find_instance(cs, args.instance)
new_attrs = {} new_attrs = {}
if args.new_name: if args.new_name:
new_attrs['name'] = args.new_name new_attrs['name'] = args.new_name
@@ -708,11 +740,12 @@ def do_user_update_attributes(cs, args):
new_attrs['password'] = args.new_password new_attrs['password'] = args.new_password
if args.new_host: if args.new_host:
new_attrs['host'] = args.new_host new_attrs['host'] = args.new_host
cs.users.update_attributes(args.instance, args.name, cs.users.update_attributes(instance, args.name,
newuserattr=new_attrs, hostname=args.host) newuserattr=new_attrs, hostname=args.host)
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.arg('name', metavar='<name>', help='Name of user.') @utils.arg('name', metavar='<name>', help='Name of user.')
@utils.arg('--host', metavar='<host>', default=None, @utils.arg('--host', metavar='<host>', default=None,
help='Optional host of user.') help='Optional host of user.')
@@ -722,11 +755,13 @@ def do_user_update_attributes(cs, args):
@utils.service_type('database') @utils.service_type('database')
def do_user_grant_access(cs, args): def do_user_grant_access(cs, args):
"""Grants access to a database(s) for a user.""" """Grants access to a database(s) for a user."""
cs.users.grant(args.instance, args.name, instance = _find_instance(cs, args.instance)
cs.users.grant(instance, args.name,
args.databases, hostname=args.host) args.databases, hostname=args.host)
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.arg('name', metavar='<name>', help='Name of user.') @utils.arg('name', metavar='<name>', help='Name of user.')
@utils.arg('database', metavar='<database>', help='A single database.') @utils.arg('database', metavar='<database>', help='A single database.')
@utils.arg('--host', metavar='<host>', default=None, @utils.arg('--host', metavar='<host>', default=None,
@@ -734,7 +769,8 @@ def do_user_grant_access(cs, args):
@utils.service_type('database') @utils.service_type('database')
def do_user_revoke_access(cs, args): def do_user_revoke_access(cs, args):
"""Revokes access to a database for a user.""" """Revokes access to a database for a user."""
cs.users.revoke(args.instance, args.name, instance = _find_instance(cs, args.instance)
cs.users.revoke(instance, args.name,
args.database, hostname=args.host) args.database, hostname=args.host)
@@ -752,19 +788,23 @@ def do_limit_list(cs, args):
# Root related commands # Root related commands
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.service_type('database') @utils.service_type('database')
def do_root_enable(cs, args): def do_root_enable(cs, args):
"""Enables root for an instance and resets if already exists.""" """Enables root for an instance and resets if already exists."""
root = cs.root.create(args.instance) instance = _find_instance(cs, args.instance)
root = cs.root.create(instance)
utils.print_dict({'name': root[0], 'password': root[1]}) utils.print_dict({'name': root[0], 'password': root[1]})
@utils.arg('instance', metavar='<instance>', help='ID of the instance.') @utils.arg('instance', metavar='<instance>',
help='ID or name of the instance.')
@utils.service_type('database') @utils.service_type('database')
def do_root_show(cs, args): def do_root_show(cs, args):
"""Gets status if root was ever enabled for an instance.""" """Gets status if root was ever enabled for an instance."""
root = cs.root.is_root_enabled(args.instance) instance = _find_instance(cs, args.instance)
root = cs.root.is_root_enabled(instance)
utils.print_dict({'is_root_enabled': root.rootEnabled}) utils.print_dict({'is_root_enabled': root.rootEnabled})
@@ -881,7 +921,7 @@ def do_datastore_version_show(cs, args):
@utils.arg('instance', @utils.arg('instance',
metavar='<instance>', metavar='<instance>',
type=str, type=str,
help='ID of the instance.') help='ID or name of the instance.')
@utils.arg('configuration', @utils.arg('configuration',
metavar='<configuration>', metavar='<configuration>',
type=str, type=str,
@@ -889,7 +929,8 @@ def do_datastore_version_show(cs, args):
@utils.service_type('database') @utils.service_type('database')
def do_configuration_attach(cs, args): def do_configuration_attach(cs, args):
"""Attaches a configuration group to an instance.""" """Attaches a configuration group to an instance."""
cs.instances.modify(args.instance, args.configuration) instance = _find_instance(cs, args.instance)
cs.instances.modify(instance, args.configuration)
@utils.arg('name', metavar='<name>', help='Name of the configuration group.') @utils.arg('name', metavar='<name>', help='Name of the configuration group.')
@@ -918,11 +959,12 @@ def do_configuration_create(cs, args):
@utils.arg('instance', @utils.arg('instance',
metavar='<instance>', metavar='<instance>',
type=str, type=str,
help='ID of the instance.') help='ID or name of the instance.')
@utils.service_type('database') @utils.service_type('database')
def do_configuration_default(cs, args): def do_configuration_default(cs, args):
"""Shows the default configuration of an instance.""" """Shows the default configuration of an instance."""
configs = cs.instances.configuration(args.instance) instance = _find_instance(cs, args.instance)
configs = cs.instances.configuration(instance)
utils.print_dict(configs._info['configuration']) utils.print_dict(configs._info['configuration'])
@@ -937,11 +979,12 @@ def do_configuration_delete(cs, args):
@utils.arg('instance', @utils.arg('instance',
metavar='<instance>', metavar='<instance>',
type=str, type=str,
help='ID of the instance.') help='ID or name of the instance.')
@utils.service_type('database') @utils.service_type('database')
def do_configuration_detach(cs, args): def do_configuration_detach(cs, args):
"""Detaches a configuration group from an instance.""" """Detaches a configuration group from an instance."""
cs.instances.modify(args.instance) instance = _find_instance(cs, args.instance)
cs.instances.modify(instance)
@utils.arg('--datastore', metavar='<datastore>', @utils.arg('--datastore', metavar='<datastore>',

View File

@@ -29,17 +29,17 @@ class Users(base.ManagerWithFind):
"""Manage :class:`Users` resources.""" """Manage :class:`Users` resources."""
resource_class = User resource_class = User
def create(self, instance_id, users): def create(self, instance, users):
"""Create users with permissions to the specified databases.""" """Create users with permissions to the specified databases."""
body = {"users": users} body = {"users": users}
url = "/instances/%s/users" % instance_id url = "/instances/%s/users" % base.getid(instance)
resp, body = self.api.client.post(url, body=body) resp, body = self.api.client.post(url, body=body)
common.check_for_exceptions(resp, body, url) common.check_for_exceptions(resp, body, url)
def delete(self, instance_id, username, hostname=None): def delete(self, instance, username, hostname=None):
"""Delete an existing user in the specified instance.""" """Delete an existing user in the specified instance."""
user = common.quote_user_host(username, hostname) user = common.quote_user_host(username, hostname)
url = "/instances/%s/users/%s" % (instance_id, user) url = "/instances/%s/users/%s" % (base.getid(instance), user)
resp, body = self.api.client.delete(url) resp, body = self.api.client.delete(url)
common.check_for_exceptions(resp, body, url) common.check_for_exceptions(resp, body, url)
@@ -51,13 +51,13 @@ class Users(base.ManagerWithFind):
url = "/instances/%s/users" % base.getid(instance) url = "/instances/%s/users" % base.getid(instance)
return self._paginated(url, "users", limit, marker) return self._paginated(url, "users", limit, marker)
def get(self, instance_id, username, hostname=None): def get(self, instance, username, hostname=None):
"""Get a single User from the instance's Database. """Get a single User from the instance's Database.
:rtype: :class:`User`. :rtype: :class:`User`.
""" """
user = common.quote_user_host(username, hostname) user = common.quote_user_host(username, hostname)
url = "/instances/%s/users/%s" % (instance_id, user) url = "/instances/%s/users/%s" % (base.getid(instance), user)
return self._get(url, "user") return self._get(url, "user")
def update_attributes(self, instance, username, newuserattr=None, def update_attributes(self, instance, username, newuserattr=None,