summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuk Loi <duk@tesora.com>2015-06-09 14:07:46 -0400
committerDuk Loi <duk@tesora.com>2015-12-10 11:23:53 -0500
commite776382c93c2eb9abcf6e6f5f84d43e97f9ca642 (patch)
tree9b4d067a745a5ce12b410c5a8653588c3e681314
parentd820a44e3495959455548b8182929d2adbb1ea5d (diff)
downloadpython-troveclient-e776382c93c2eb9abcf6e6f5f84d43e97f9ca642.tar.gz
Add root-disable api
Add api entry points for root-disable to the Trove client. Added unit tests. Change-Id: I27831eb361c2b219a9623f152b9def73a2865d67 Partially implements: blueprint root-disable DocImpact: added new root-disable CLI command
-rw-r--r--troveclient/compat/cli.py5
-rw-r--r--troveclient/tests/fakes.py3
-rw-r--r--troveclient/tests/test_root.py56
-rw-r--r--troveclient/tests/test_v1_shell.py4
-rw-r--r--troveclient/v1/root.py15
-rw-r--r--troveclient/v1/shell.py9
6 files changed, 92 insertions, 0 deletions
diff --git a/troveclient/compat/cli.py b/troveclient/compat/cli.py
index 5064c87..86b3109 100644
--- a/troveclient/compat/cli.py
+++ b/troveclient/compat/cli.py
@@ -268,6 +268,11 @@ class RootCommands(common.AuthedCommandsBase):
except Exception:
print(sys.exc_info()[1])
+ def delete(self):
+ """Disable the instance's root user."""
+ self._require('id')
+ print(self.dbaas.root.delete(self.id))
+
def enabled(self):
"""Check the instance for root access."""
self._require('id')
diff --git a/troveclient/tests/fakes.py b/troveclient/tests/fakes.py
index 76cb222..820a433 100644
--- a/troveclient/tests/fakes.py
+++ b/troveclient/tests/fakes.py
@@ -508,6 +508,9 @@ class FakeHTTPClient(base_client.HTTPClient):
def post_clusters_cls_1234_root(self, **kw):
return (202, {}, {"user": {"password": "password", "name": "root"}})
+ def delete_instances_1234_root(self, **kw):
+ return (202, {}, None)
+
def get_instances_1234_root(self, **kw):
return (200, {}, {"rootEnabled": 'True'})
diff --git a/troveclient/tests/test_root.py b/troveclient/tests/test_root.py
new file mode 100644
index 0000000..a4e9f38
--- /dev/null
+++ b/troveclient/tests/test_root.py
@@ -0,0 +1,56 @@
+# Copyright 2015 Tesora Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import mock
+import testtools
+
+from troveclient.v1 import root
+
+"""
+Unit tests for root.py
+"""
+
+
+class RootTest(testtools.TestCase):
+ def setUp(self):
+ super(RootTest, self).setUp()
+ self.orig__init = root.Root.__init__
+ root.Root.__init__ = mock.Mock(return_value=None)
+ self.root = root.Root()
+ self.root.api = mock.Mock()
+ self.root.api.client = mock.Mock()
+
+ def tearDown(self):
+ super(RootTest, self).tearDown()
+ root.Root.__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_delete(self):
+ self.root.api.client.delete = self._get_mock_method()
+ self._resp.status_code = 200
+ self.root.delete(1234)
+ self.assertEqual('/instances/1234/root', self._url)
+ self._resp.status_code = 400
+ self.assertRaises(Exception, self.root.delete, 1234)
diff --git a/troveclient/tests/test_v1_shell.py b/troveclient/tests/test_v1_shell.py
index b4a1007..161a308 100644
--- a/troveclient/tests/test_v1_shell.py
+++ b/troveclient/tests/test_v1_shell.py
@@ -539,6 +539,10 @@ class ShellTest(utils.TestCase):
self.run_command_clusters('root-enable cls-1234')
self.assert_called_anytime('POST', '/clusters/cls-1234/root')
+ def test_root_disable_instance(self):
+ self.run_command('root-disable 1234')
+ self.assert_called_anytime('DELETE', '/instances/1234/root')
+
def test_root_show_instance(self):
self.run_command('root-show 1234')
self.assert_called('GET', '/instances/1234/root')
diff --git a/troveclient/v1/root.py b/troveclient/v1/root.py
index 99c6672..47acd19 100644
--- a/troveclient/v1/root.py
+++ b/troveclient/v1/root.py
@@ -55,6 +55,21 @@ class Root(base.ManagerWithFind):
common.check_for_exceptions(resp, body, uri)
return body['user']['name'], body['user']['password']
+ def delete(self, instance):
+ """Implements root-disable API.
+ Disables access to the root user for the specified db instance.
+ :param instance: The instance on which the root user is enabled
+ """
+ self.disable_instance_root(instance)
+
+ def disable_instance_root(self, instance):
+ """Implements root-disable for instances."""
+ self._disable_root(self.instances_url % base.getid(instance))
+
+ def _disable_root(self, url):
+ resp, body = self.api.client.delete(url)
+ common.check_for_exceptions(resp, body, url)
+
def is_root_enabled(self, instance):
"""Return whether root is enabled for the instance."""
return self.is_instance_root_enabled(instance)
diff --git a/troveclient/v1/shell.py b/troveclient/v1/shell.py
index 7a64f17..3eb17c1 100644
--- a/troveclient/v1/shell.py
+++ b/troveclient/v1/shell.py
@@ -1024,6 +1024,15 @@ def do_root_enable(cs, args):
utils.print_dict({'name': root[0], 'password': root[1]})
+@utils.arg('instance', metavar='<instance>',
+ help='ID or name of the instance.')
+@utils.service_type('database')
+def do_root_disable(cs, args):
+ """Disables root for an instance."""
+ instance = _find_instance(cs, args.instance)
+ cs.root.disable_instance_root(instance)
+
+
@utils.arg('instance_or_cluster', metavar='<instance_or_cluster>',
help='ID or name of the instance or cluster.')
@utils.service_type('database')