RootReport through Taskmanager

Reason:
- guestagent should be free from direct Trove back-end DB connection.
Changes:
- extending taskmanager provisioning flow;
- taskmanager reports about root creation;
- tests.

Closes-bug: #1257489
Change-Id: I5f2502d8b61542658682a5ff74735749e5a1ca2b
This commit is contained in:
Denis Makogon
2014-01-24 13:54:56 +02:00
parent c14553393f
commit 4fb3dd6e97
6 changed files with 37 additions and 33 deletions

View File

@@ -133,10 +133,8 @@ class Manager(periodic_task.PeriodicTasks):
if root_password and not backup_info: if root_password and not backup_info:
app.secure_root(secure_remote_root=True) app.secure_root(secure_remote_root=True)
MySqlAdmin().enable_root(root_password) MySqlAdmin().enable_root(root_password)
MySqlAdmin().report_root_enabled(context)
elif enable_root_on_restore: elif enable_root_on_restore:
app.secure_root(secure_remote_root=False) app.secure_root(secure_remote_root=False)
MySqlAdmin().report_root_enabled(context)
else: else:
app.secure_root(secure_remote_root=True) app.secure_root(secure_remote_root=True)

View File

@@ -36,7 +36,6 @@ from trove.guestagent import pkg
from trove.guestagent.datastore import service from trove.guestagent.datastore import service
from trove.openstack.common import log as logging from trove.openstack.common import log as logging
from trove.openstack.common.gettextutils import _ from trove.openstack.common.gettextutils import _
from trove.extensions.mysql.models import RootHistory
ADMIN_USER_NAME = "os_admin" ADMIN_USER_NAME = "os_admin"
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@@ -401,10 +400,6 @@ class MySqlAdmin(object):
""" """
return MySqlRootAccess.enable_root(root_password) return MySqlRootAccess.enable_root(root_password)
def report_root_enabled(self, context=None):
"""Records in the Root History that the root is enabled."""
return MySqlRootAccess.report_root_enabled(context)
def list_databases(self, limit=None, marker=None, include_marker=False): def list_databases(self, limit=None, marker=None, include_marker=False):
"""List databases the user created on this mysql instance.""" """List databases the user created on this mysql instance."""
LOG.debug(_("---Listing Databases---")) LOG.debug(_("---Listing Databases---"))
@@ -869,7 +864,3 @@ class MySqlRootAccess(object):
t = text(str(g)) t = text(str(g))
client.execute(t) client.execute(t)
return user.serialize() return user.serialize()
@classmethod
def report_root_enabled(cls, context):
return RootHistory.create(context, CONF.guest_id, 'root')

View File

@@ -33,6 +33,7 @@ from trove.common import instance as rd_instance
from trove.common.remote import create_dns_client from trove.common.remote import create_dns_client
from trove.common.remote import create_heat_client from trove.common.remote import create_heat_client
from trove.common.remote import create_cinder_client from trove.common.remote import create_cinder_client
from trove.extensions.mysql import models as mysql_models
from trove.extensions.security_group.models import SecurityGroup from trove.extensions.security_group.models import SecurityGroup
from trove.extensions.security_group.models import SecurityGroupRule from trove.extensions.security_group.models import SecurityGroupRule
from swiftclient.client import ClientException from swiftclient.client import ClientException
@@ -206,6 +207,9 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
packages, databases, users, backup_info, packages, databases, users, backup_info,
config.config_contents, root_password) config.config_contents, root_password)
if root_password:
self.report_root_enabled()
if not self.db_info.task_status.is_error: if not self.db_info.task_status.is_error:
self.update_db(task_status=inst_models.InstanceTasks.NONE) self.update_db(task_status=inst_models.InstanceTasks.NONE)
@@ -241,6 +245,9 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
LOG.debug(_("end create_instance for id: %s") % self.id) LOG.debug(_("end create_instance for id: %s") % self.id)
def report_root_enabled(self):
mysql_models.RootHistory.create(self.context, self.id, 'root')
def update_statuses_on_time_out(self): def update_statuses_on_time_out(self):
if CONF.update_status_on_fail: if CONF.update_status_on_fail:

View File

@@ -31,9 +31,6 @@ import testtools
from testtools.matchers import Is from testtools.matchers import Is
from testtools.matchers import Equals from testtools.matchers import Equals
from testtools.matchers import Not from testtools.matchers import Not
from trove.extensions.mysql.models import RootHistory
import trove
from trove.common.context import TroveContext
from trove.common import utils from trove.common import utils
from trove.common import instance as rd_instance from trove.common import instance as rd_instance
from trove.conductor import api as conductor_api from trove.conductor import api as conductor_api
@@ -866,19 +863,6 @@ class MySqlRootStatusTest(testtools.TestCase):
when(models.MySQLUser)._is_valid_user_name(any()).thenReturn(False) when(models.MySQLUser)._is_valid_user_name(any()).thenReturn(False)
self.assertRaises(ValueError, MySqlAdmin().enable_root) self.assertRaises(ValueError, MySqlAdmin().enable_root)
def test_report_root_enabled(self):
mock_db_api = mock()
when(trove.extensions.mysql.models).get_db_api().thenReturn(
mock_db_api)
when(mock_db_api).find_by(any(), id=None).thenReturn(None)
root_history = RootHistory('x', 'root')
when(mock_db_api).save(any(RootHistory)).thenReturn(root_history)
# invocation
history = MySqlRootAccess.report_root_enabled(TroveContext())
# verification
self.assertThat(history, Is(root_history))
verify(mock_db_api).save(any(RootHistory))
class MockStats: class MockStats:
f_blocks = 1024 ** 2 f_blocks = 1024 ** 2

View File

@@ -195,8 +195,6 @@ class GuestAgentManagerTest(testtools.TestCase):
when(dbaas.MySqlAdmin).is_root_enabled().thenReturn(is_root_enabled) when(dbaas.MySqlAdmin).is_root_enabled().thenReturn(is_root_enabled)
when(dbaas.MySqlAdmin).create_user().thenReturn(None) when(dbaas.MySqlAdmin).create_user().thenReturn(None)
when(dbaas.MySqlAdmin).create_database().thenReturn(None) when(dbaas.MySqlAdmin).create_database().thenReturn(None)
when(dbaas.MySqlAdmin).report_root_enabled(self.context).thenReturn(
None)
when(os.path).exists(any()).thenReturn(True) when(os.path).exists(any()).thenReturn(True)
# invocation # invocation
@@ -222,10 +220,7 @@ class GuestAgentManagerTest(testtools.TestCase):
verify(dbaas.MySqlApp).secure(any()) verify(dbaas.MySqlApp).secure(any())
verify(dbaas.MySqlAdmin, never).create_database() verify(dbaas.MySqlAdmin, never).create_database()
verify(dbaas.MySqlAdmin, never).create_user() verify(dbaas.MySqlAdmin, never).create_user()
times_report = 1 if is_root_enabled else 0
verify(dbaas.MySqlApp).secure_root(secure_remote_root=any()) verify(dbaas.MySqlApp).secure_root(secure_remote_root=any())
verify(dbaas.MySqlAdmin, times=times_report).report_root_enabled(
self.context)
class RedisGuestAgentManagerTest(testtools.TestCase): class RedisGuestAgentManagerTest(testtools.TestCase):

View File

@@ -19,11 +19,15 @@ from trove.datastore import models as datastore_models
from trove.taskmanager import models as taskmanager_models from trove.taskmanager import models as taskmanager_models
from trove.backup import models as backup_models from trove.backup import models as backup_models
from trove.common import remote from trove.common import remote
from trove.common.exception import TroveError
from trove.common.instance import ServiceStatuses from trove.common.instance import ServiceStatuses
from trove.extensions.mysql import models as mysql_models
from trove.instance.models import InstanceServiceStatus from trove.instance.models import InstanceServiceStatus
from trove.instance.models import DBInstance from trove.instance.models import DBInstance
from trove.instance.tasks import InstanceTasks from trove.instance.tasks import InstanceTasks
from trove.common.exception import TroveError
from trove.tests.unittests.util import util
from trove.common import utils
from swiftclient.client import ClientException from swiftclient.client import ClientException
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile
import os import os
@@ -334,3 +338,28 @@ class NotifyMixinTest(testtools.TestCase):
transformer = taskmanager_models.NotifyMixin() transformer = taskmanager_models.NotifyMixin()
self.assertThat(transformer._get_service_id('m0ng0', id_map), self.assertThat(transformer._get_service_id('m0ng0', id_map),
Equals('unknown-service-id-error')) Equals('unknown-service-id-error'))
class RootReportTest(testtools.TestCase):
def setUp(self):
super(RootReportTest, self).setUp()
util.init_db()
def tearDown(self):
super(RootReportTest, self).tearDown()
def test_report_root_first_time(self):
report = mysql_models.RootHistory.create(
None, utils.generate_uuid(), 'root')
self.assertIsNotNone(report)
def test_report_root_double_create(self):
uuid = utils.generate_uuid()
history = mysql_models.RootHistory(uuid, 'root').save()
mysql_models.RootHistory.load = Mock(return_value=history)
report = mysql_models.RootHistory.create(
None, uuid, 'root')
self.assertTrue(mysql_models.RootHistory.load.called)
self.assertEqual(history.user, report.user)
self.assertEqual(history.id, report.id)