From ce6e24bb86de1360de930491ab226079dd84ce33 Mon Sep 17 00:00:00 2001 From: Ramashri Umale Date: Sun, 9 Mar 2014 17:54:06 -0700 Subject: [PATCH] Root_on_create per datastore Reason: Not each datastore has root user entity; Changes: root_on_create flag per datastore. fixed test case root_on_create; Change-Id: I5b2f665cfdb36e9f88d57d04b5e9470085b3362a Closes-Bug: #1276858 --- etc/trove/trove.conf.sample | 6 ++- trove/common/cfg.py | 15 ++++-- trove/instance/models.py | 15 +++++- trove/tests/api/root_on_create.py | 51 +++++++++++++++---- .../instance/test_instance_models.py | 5 ++ 5 files changed, 74 insertions(+), 18 deletions(-) diff --git a/etc/trove/trove.conf.sample b/etc/trove/trove.conf.sample index 0381a12ece..810e76c5be 100644 --- a/etc/trove/trove.conf.sample +++ b/etc/trove/trove.conf.sample @@ -93,8 +93,6 @@ taskmanager_queue = taskmanager # Auth admin_roles = admin -root_on_create = False - # Users to ignore for user create/list/delete operations ignore_users = os_admin, root ignore_dbs = lost+found, mysql, information_schema @@ -140,3 +138,7 @@ control_exchange = trove #key_file = /path/to/server.key #optional: #ca_file = /path/to/ca_file + +[mysql] + +root_on_create = False diff --git a/trove/common/cfg.py b/trove/common/cfg.py index e9a5831db7..4e26c05a95 100644 --- a/trove/common/cfg.py +++ b/trove/common/cfg.py @@ -131,11 +131,6 @@ common_opts = [ cfg.IntOpt('dns_time_out', default=60 * 2), cfg.IntOpt('resize_time_out', default=60 * 10), cfg.IntOpt('revert_time_out', default=60 * 10), - cfg.BoolOpt('root_on_create', default=False, - help='Enable the automatic creation of the root user for the ' - 'service during instance-create. The generated password for ' - 'the root user is immediately returned in the response of ' - "instance-create as the 'password' field."), cfg.ListOpt('root_grant', default=['ALL']), cfg.BoolOpt('root_grant_option', default=True), cfg.IntOpt('default_password_length', default=36), @@ -286,6 +281,11 @@ mysql_opts = [ cfg.StrOpt('mount_point', default='/var/lib/mysql', help="Filesystem path for mounting " "volumes if volume support is enabled"), + cfg.BoolOpt('root_on_create', default=False, + help='Enable the automatic creation of the root user for the ' + 'service during instance-create. The generated password for ' + 'the root user is immediately returned in the response of ' + "instance-create as the 'password' field."), ] # Percona @@ -306,6 +306,11 @@ percona_opts = [ cfg.StrOpt('mount_point', default='/var/lib/mysql', help="Filesystem path for mounting " "volumes if volume support is enabled"), + cfg.BoolOpt('root_on_create', default=False, + help='Enable the automatic creation of the root user for the ' + 'service during instance-create. The generated password for ' + 'the root user is immediately returned in the response of ' + "instance-create as the 'password' field."), ] # Redis diff --git a/trove/instance/models.py b/trove/instance/models.py index ceffc807f3..78be3caa30 100644 --- a/trove/instance/models.py +++ b/trove/instance/models.py @@ -19,6 +19,7 @@ import re from datetime import datetime from novaclient import exceptions as nova_exceptions +from oslo.config.cfg import NoSuchOptError from trove.common import cfg from trove.common import exception from trove.common import template @@ -499,6 +500,17 @@ class Instance(BuiltInstance): """ + @classmethod + def get_root_on_create(cls, datastore_manager): + try: + root_on_create = CONF.get(datastore_manager).root_on_create + return root_on_create + except NoSuchOptError: + LOG.debug(_("root_on_create not configured for %s" + " hence defaulting the value to False") + % datastore_manager) + return False + @classmethod def create(cls, context, name, flavor_id, image_id, databases, users, datastore, datastore_version, volume_size, backup_id, @@ -567,7 +579,8 @@ class Instance(BuiltInstance): db_info.save() root_password = None - if CONF.root_on_create and not backup_id: + if cls.get_root_on_create( + datastore_version.manager) and not backup_id: root_password = utils.generate_random_password() task_api.API(context).create_instance(db_info.id, name, flavor, diff --git a/trove/tests/api/root_on_create.py b/trove/tests/api/root_on_create.py index 15c0f5e84a..6d794034bd 100644 --- a/trove/tests/api/root_on_create.py +++ b/trove/tests/api/root_on_create.py @@ -11,7 +11,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -from trove.common import cfg from proboscis import before_class from proboscis import after_class @@ -21,9 +20,11 @@ from proboscis.asserts import assert_not_equal from proboscis.asserts import assert_true from trove import tests +from trove.common import cfg +from trove.common.utils import poll_until +from trove.tests import util from trove.tests.api.users import TestUsers from trove.tests.api.instances import instance_info -from trove.tests import util from trove.tests.api.databases import TestMysqlAccess CONF = cfg.CONF @@ -40,31 +41,61 @@ class TestRootOnCreate(object): """ root_enabled_timestamp = 'Never' + instance_id = None + + def create_instance(self): + result = self.dbaas.instances.create( + instance_info.name, + instance_info.dbaas_flavor_href, + instance_info.volume, + instance_info.databases, + instance_info.users, + availability_zone="nova", + datastore=instance_info.dbaas_datastore, + datastore_version=instance_info.dbaas_datastore_version) + assert_equal(200, self.dbaas.last_http_code) + new_id = result.id + + def result_is_active(): + instance = self.dbaas.instances.get(new_id) + if instance.status == "ACTIVE": + return True + else: + assert_equal("BUILD", instance.status) + poll_until(result_is_active) + if 'password' in result._info: + self.dbaas.root.create(new_id) + return new_id @before_class def setUp(self): - self.orig_conf_value = CONF.root_on_create - CONF.root_on_create = True + self.orig_conf_value = CONF.get( + instance_info.dbaas_datastore).root_on_create + CONF.get(instance_info.dbaas_datastore).root_on_create = True self.dbaas = util.create_dbaas_client(instance_info.user) self.dbaas_admin = util.create_dbaas_client(instance_info.admin_user) self.history = self.dbaas_admin.management.root_enabled_history self.enabled = self.dbaas.root.is_root_enabled + self.instance_id = self.create_instance() @after_class def tearDown(self): - CONF.root_on_create = self.orig_conf_value + CONF.get(instance_info. + dbaas_datastore).root_on_create = self.orig_conf_value + instance = self.dbaas.instances.get(self.instance_id) + instance.delete() @test def test_root_on_create(self): """Test that root is enabled after instance creation""" - enabled = self.enabled(instance_info.id).rootEnabled + enabled = self.enabled(self.instance_id).rootEnabled assert_equal(200, self.dbaas.last_http_code) assert_true(enabled) @test(depends_on=[test_root_on_create]) def test_history_after_root_on_create(self): """Test that the timestamp in the root enabled history is set""" - self.root_enabled_timestamp = self.history(instance_info.id).enabled + self.root_enabled_timestamp = self.history(self.instance_id).enabled assert_equal(200, self.dbaas.last_http_code) assert_not_equal(self.root_enabled_timestamp, 'Never') @@ -72,15 +103,15 @@ class TestRootOnCreate(object): def test_reset_root(self): """Test that root reset does not alter the timestamp""" orig_timestamp = self.root_enabled_timestamp - self.dbaas.root.create(instance_info.id) + self.dbaas.root.create(self.instance_id) assert_equal(200, self.dbaas.last_http_code) - self.root_enabled_timestamp = self.history(instance_info.id).enabled + self.root_enabled_timestamp = self.history(self.instance_id).enabled assert_equal(200, self.dbaas.last_http_code) assert_equal(orig_timestamp, self.root_enabled_timestamp) @test(depends_on=[test_reset_root]) def test_root_still_enabled(self): """Test that after root was reset, it's still enabled.""" - enabled = self.enabled(instance_info.id).rootEnabled + enabled = self.enabled(self.instance_id).rootEnabled assert_equal(200, self.dbaas.last_http_code) assert_true(enabled) diff --git a/trove/tests/unittests/instance/test_instance_models.py b/trove/tests/unittests/instance/test_instance_models.py index ce9631ef95..a918498ea2 100644 --- a/trove/tests/unittests/instance/test_instance_models.py +++ b/trove/tests/unittests/instance/test_instance_models.py @@ -17,6 +17,7 @@ from testtools import TestCase from trove.common import cfg from trove.instance.models import filter_ips from trove.instance.models import DBInstance +from trove.instance.models import Instance from trove.instance.models import SimpleInstance from trove.instance.tasks import InstanceTasks @@ -42,6 +43,10 @@ class SimpleInstanceTest(TestCase): CONF.ip_start = None CONF.ip_regex = self.orig_ip_regex + def test_get_root_on_create(self): + root_on_create_val = Instance.get_root_on_create('redis') + self.assertFalse(root_on_create_val) + def test_filter_ips(self): CONF.network_label_regex = '.*' CONF.ip_regex = '^(15.|123.)'