Initialize RedisAdmin with correct config command
Redis at deployment time, for security reasons will hide the 'CONFIG' command from end users by mangling its name. The mangled config command name will be written to the config file, and also applied runtime.. When it restarts, guestagent will use the default config command instead of the correct one in the configuration file, then will lead to failure. The patch will initialize RedisAdmin with the correct config command Closes-Bug: #1726341 Change-Id: I35c60d085ac53475683c993a0b9a053a07ae763f
This commit is contained in:
parent
989451ae91
commit
3a6a3b44ba
|
@ -107,8 +107,10 @@ class RedisApp(object):
|
|||
def _build_admin_client(self):
|
||||
password = self.get_configuration_property('requirepass')
|
||||
socket = self.get_configuration_property('unixsocket')
|
||||
cmd = self.get_config_command_name()
|
||||
|
||||
return RedisAdmin(password=password, unix_socket_path=socket)
|
||||
return RedisAdmin(password=password, unix_socket_path=socket,
|
||||
config_cmd=cmd)
|
||||
|
||||
def install_if_needed(self, packages):
|
||||
"""
|
||||
|
@ -406,10 +408,10 @@ class RedisAdmin(object):
|
|||
|
||||
DEFAULT_CONFIG_CMD = 'CONFIG'
|
||||
|
||||
def __init__(self, password=None, unix_socket_path=None):
|
||||
def __init__(self, password=None, unix_socket_path=None, config_cmd=None):
|
||||
self.__client = redis.StrictRedis(
|
||||
password=password, unix_socket_path=unix_socket_path)
|
||||
self.__config_cmd_name = self.DEFAULT_CONFIG_CMD
|
||||
self.__config_cmd_name = config_cmd or self.DEFAULT_CONFIG_CMD
|
||||
|
||||
def set_config_command_name(self, name):
|
||||
"""Set name of the 'CONFIG' command or None for default.
|
||||
|
|
|
@ -28,6 +28,7 @@ from trove.conductor import api as conductor_api
|
|||
from trove.guestagent.backup import backupagent
|
||||
from trove.guestagent.common import configuration
|
||||
from trove.guestagent.common.configuration import ImportOverrideStrategy
|
||||
from trove.guestagent.datastore.experimental.redis.service import RedisApp
|
||||
from trove.guestagent.strategies.backup.base import BackupRunner
|
||||
from trove.guestagent.strategies.backup.base import UnknownBackupType
|
||||
from trove.guestagent.strategies.backup.experimental import couchbase_impl
|
||||
|
@ -283,6 +284,8 @@ class BackupAgentTest(trove_testtools.TestCase):
|
|||
@patch.object(configuration.ConfigurationManager, 'parse_configuration',
|
||||
Mock(return_value={'dir': '/var/lib/redis',
|
||||
'dbfilename': 'dump.rdb'}))
|
||||
@patch.object(RedisApp, 'get_config_command_name',
|
||||
Mock(return_value='fakeconfig'))
|
||||
def test_backup_impl_RedisBackup(self, *mocks):
|
||||
netutils.get_my_ipv4 = Mock(return_value="1.1.1.1")
|
||||
redis_backup = redis_impl.RedisBackup('redisbackup', extra_opts='')
|
||||
|
|
|
@ -26,6 +26,7 @@ from trove.guestagent.datastore.experimental.cassandra import (
|
|||
)
|
||||
from trove.guestagent.datastore.experimental.db2 import (
|
||||
service as db2_service)
|
||||
from trove.guestagent.datastore.experimental.redis.service import RedisApp
|
||||
from trove.guestagent.strategies.backup import base as backupBase
|
||||
from trove.guestagent.strategies.backup.experimental import db2_impl
|
||||
from trove.guestagent.strategies.backup.experimental.postgresql_impl \
|
||||
|
@ -401,6 +402,8 @@ class GuestAgentBackupTest(trove_testtools.TestCase):
|
|||
@patch.object(configuration.ConfigurationManager, 'parse_configuration',
|
||||
mock.Mock(return_value={'dir': '/var/lib/redis',
|
||||
'dbfilename': 'dump.rdb'}))
|
||||
@patch.object(RedisApp, 'get_config_command_name',
|
||||
Mock(return_value='fakeconfig'))
|
||||
def test_backup_encrypted_redisbackup_command(self, *mocks):
|
||||
backupBase.BackupRunner.encrypt_key = CRYPTO_KEY
|
||||
RunnerClass = utils.import_class(BACKUP_REDIS_CLS)
|
||||
|
@ -414,6 +417,8 @@ class GuestAgentBackupTest(trove_testtools.TestCase):
|
|||
@patch.object(configuration.ConfigurationManager, 'parse_configuration',
|
||||
mock.Mock(return_value={'dir': '/var/lib/redis',
|
||||
'dbfilename': 'dump.rdb'}))
|
||||
@patch.object(RedisApp, 'get_config_command_name',
|
||||
Mock(return_value='fakeconfig'))
|
||||
def test_backup_not_encrypted_redisbackup_command(self, *mocks):
|
||||
backupBase.BackupRunner.is_encrypted = False
|
||||
backupBase.BackupRunner.encrypt_key = CRYPTO_KEY
|
||||
|
@ -428,6 +433,8 @@ class GuestAgentBackupTest(trove_testtools.TestCase):
|
|||
'dbfilename': 'dump.rdb'}))
|
||||
@patch.object(operating_system, 'chown')
|
||||
@patch.object(operating_system, 'create_directory')
|
||||
@patch.object(RedisApp, 'get_config_command_name',
|
||||
Mock(return_value='fakeconfig'))
|
||||
def test_restore_decrypted_redisbackup_command(self, *mocks):
|
||||
restoreBase.RestoreRunner.is_encrypted = False
|
||||
RunnerClass = utils.import_class(RESTORE_REDIS_CLS)
|
||||
|
@ -440,6 +447,8 @@ class GuestAgentBackupTest(trove_testtools.TestCase):
|
|||
'dbfilename': 'dump.rdb'}))
|
||||
@patch.object(operating_system, 'chown')
|
||||
@patch.object(operating_system, 'create_directory')
|
||||
@patch.object(RedisApp, 'get_config_command_name',
|
||||
Mock(return_value='fakeconfig'))
|
||||
def test_restore_encrypted_redisbackup_command(self, *mocks):
|
||||
restoreBase.RestoreRunner.decrypt_key = CRYPTO_KEY
|
||||
RunnerClass = utils.import_class(RESTORE_REDIS_CLS)
|
||||
|
@ -851,6 +860,8 @@ class RedisBackupTests(trove_testtools.TestCase):
|
|||
def tearDown(self):
|
||||
super(RedisBackupTests, self).tearDown()
|
||||
|
||||
@patch.object(RedisApp, 'get_config_command_name',
|
||||
Mock(return_value='fakeconfig'))
|
||||
def test_backup_success(self):
|
||||
with self.backup_runner(12345):
|
||||
pass
|
||||
|
@ -859,6 +870,8 @@ class RedisBackupTests(trove_testtools.TestCase):
|
|||
self.backup_runner_mocks['_run'].assert_called_once_with()
|
||||
self.backup_runner_mocks['_run_post_backup'].assert_called_once_with()
|
||||
|
||||
@patch.object(RedisApp, 'get_config_command_name',
|
||||
Mock(return_value='fakeconfig'))
|
||||
def test_backup_failed_due_to_run_backup(self):
|
||||
self.backup_runner_mocks['_run'].configure_mock(
|
||||
side_effect=exception.TroveError('test')
|
||||
|
@ -873,7 +886,8 @@ class RedisBackupTests(trove_testtools.TestCase):
|
|||
|
||||
|
||||
class RedisRestoreTests(trove_testtools.TestCase):
|
||||
|
||||
@patch.object(RedisApp, 'get_config_command_name',
|
||||
Mock(return_value='fakeconfig'))
|
||||
def setUp(self):
|
||||
super(RedisRestoreTests, self).setUp()
|
||||
self.conf_man_patch = patch.object(
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from mock import DEFAULT, MagicMock, patch
|
||||
from mock import DEFAULT, MagicMock, Mock, patch
|
||||
|
||||
from trove.guestagent import backup
|
||||
from trove.guestagent.common import configuration
|
||||
|
@ -177,6 +177,9 @@ class RedisGuestAgentManagerTest(DatastoreManagerTest):
|
|||
'dbfilename': 'dump.rdb'}))
|
||||
@patch.object(operating_system, 'chown')
|
||||
@patch.object(operating_system, 'create_directory')
|
||||
@patch.object(redis_service.RedisApp,
|
||||
'get_config_command_name',
|
||||
Mock(return_value='fakeconfig'))
|
||||
def test_create_backup(self, *mocks):
|
||||
backup.backup = MagicMock(return_value=None)
|
||||
RedisManager().create_backup(self.context, 'backup_id_123')
|
||||
|
|
Loading…
Reference in New Issue