Pass auth token to diagnostic snapshot dumper

Since Timmy is selfsufficient utility it requires auth token to login to
Fuel to get nodes to dump.
Also getting rid of snapshot configuration unit tests since Timmy
doesn't use most of it.

Change-Id: I559776a701c76bf9f9153550d2989d939d30eb3f
Partial-Bug: #1618965
This commit is contained in:
Georgy Kibardin 2016-09-05 15:16:45 +03:00
parent f56a3aa809
commit cf26770465
5 changed files with 14 additions and 226 deletions

View File

@ -398,7 +398,9 @@ class LogPackageHandler(BaseHandler):
try:
conf = jsonutils.loads(web.data()) if web.data() else None
task_manager = DumpTaskManager()
task = task_manager.execute(conf=conf)
task = task_manager.execute(
conf=conf,
auth_token=web.ctx.env.get('HTTP_X_AUTH_TOKEN'))
except Exception as exc:
logger.warn(u'DumpTask: error while execution '
'dump environment task: {0}'.format(str(exc)))

View File

@ -1167,7 +1167,7 @@ class ClusterDeletionManager(TaskManager):
class DumpTaskManager(TaskManager):
def execute(self, conf=None, **kwargs):
def execute(self, conf=None, auth_token=None, **kwargs):
logger.info("Trying to start dump_environment task")
self.check_running_task(consts.TASK_NAMES.dump)
@ -1177,7 +1177,8 @@ class DumpTaskManager(TaskManager):
self._call_silently(
task,
tasks.DumpTask,
conf=conf
conf=conf,
auth_token=auth_token
)
return task

View File

@ -1879,7 +1879,7 @@ class CheckBeforeDeploymentTask(object):
class DumpTask(object):
@classmethod
def conf(cls):
def conf(cls, auth_token=None):
logger.debug("Preparing config for snapshot")
nodes = db().query(Node).filter(
Node.status.in_(['ready', 'provisioned', 'deploying',
@ -1887,6 +1887,8 @@ class DumpTask(object):
).all()
dump_conf = deepcopy(settings.DUMP)
if auth_token:
dump_conf['auth-token'] = auth_token
for node in nodes:
if node.cluster is None:
logger.info("Node {id} is not assigned to an environment, "
@ -1951,14 +1953,14 @@ class DumpTask(object):
return dump_conf
@classmethod
def execute(cls, task, conf=None):
def execute(cls, task, conf=None, auth_token=None):
logger.debug("DumpTask: task={0}".format(task.uuid))
message = make_astute_message(
task,
'dump_environment',
'dump_environment_resp',
{
'settings': conf or cls.conf()
'settings': conf or cls.conf(auth_token)
}
)
db().commit()

View File

@ -382,71 +382,12 @@ class TestLogs(BaseIntegrationTest):
f.write(self._format_log_entry(log_entry))
f.flush()
@mock.patch.dict('nailgun.task.task.settings.DUMP', {
'dump': {
'local': {
'hosts': [],
'objects': [],
},
'master': {
'hosts': [],
'objects': [{
'type': 'dir',
'path': '/var/log/remote',
}],
},
'slave': {
'hosts': [],
'objects': [],
}
},
'target': '/path/to/save',
'lastdump': '/path/to/latest',
'timestamp': True,
'compression_level': 3,
'timeout': 60})
def test_snapshot_conf(self):
self.env.create_node(
status='ready',
hostname='node111',
ip='10.109.0.2',
)
conf = {
'dump': {
'local': {
'hosts': [],
'objects': [],
},
'master': {
'hosts': [],
'objects': [{
'type': 'dir',
'path': '/var/log/remote',
}],
},
'slave': {
'hosts': [{
'hostname': 'node111',
'address': '10.109.0.2',
'ssh-key': '/root/.ssh/id_rsa',
'ssh-user': 'root',
}],
'objects': [],
},
},
'target': '/path/to/save',
'lastdump': '/path/to/latest',
'timestamp': True,
'compression_level': 3,
'timeout': 60,
}
self.datadiff(DumpTask.conf(), conf)
@mock.patch.dict('nailgun.task.task.settings.DUMP',
{'lastdump': 'LASTDUMP'})
@fake_tasks(fake_rpc=False, mock_rpc=False)
@mock.patch('nailgun.rpc.cast')
def test_snapshot_cast(self, mocked_rpc):
@mock.patch('web.ctx')
def test_snapshot_cast(self, mocked_rpc, _):
task = self.env.create_task(name='dump')
DumpTask.execute(task)
message = {
@ -467,7 +408,7 @@ class TestLogs(BaseIntegrationTest):
m = mock.Mock(return_value=None)
tm._call_silently = m
task = tm.execute()
m.assert_called_once_with(task, DumpTask, conf=None)
m.assert_called_once_with(task, DumpTask, conf=None, auth_token=None)
def test_snapshot_task_manager_already_running(self):
self.env.create_task(name="dump")

View File

@ -1,158 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2014 Mirantis, 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
from nailgun.test import base
from nailgun.settings import settings
from nailgun.task import task
class TestSnapshotConf(base.TestCase):
def test_must_have_roles(self):
conf = task.DumpTask.conf()
self.assertIn('local', conf['dump'])
self.assertIn('master', conf['dump'])
self.assertNotIn('slave', conf['dump'])
self.assertNotIn('controller', conf['dump'])
def test_local_host(self):
conf = task.DumpTask.conf()
# local role is abstract, but we have to make sure that it's
# real localhost and there's only one host
self.assertFalse(len(conf['dump']['local']['hosts']))
def test_postgres_injection(self):
conf = task.DumpTask.conf()
for object_ in conf['dump']['local']['objects']:
if object_['type'] == 'postgres':
self.assertEqual(
object_['dbhost'], settings.DATABASE['host'])
self.assertEqual(
object_['dbname'], settings.DATABASE['name'])
self.assertEqual(
object_['username'], settings.DATABASE['user'])
self.assertEqual(
object_['password'], settings.DATABASE['passwd'])
break
else:
self.fail("A `postgres` object MUST BE in `local` objects!")
@mock.patch('nailgun.task.task.db')
@mock.patch('nailgun.task.task.objects.Cluster')
def test_slave_generating(self, mock_cluster, mock_db):
(
mock_db.return_value.query.return_value.filter.return_value.
all.return_value
) = [
mock.Mock(hostname='node1', ip="10.109.0.2", roles=[]),
mock.Mock(hostname='node2', ip="10.109.0.5", roles=[]),
]
mock_cluster.get_editable_attributes.return_value = {
'service_user': {
'name': {
'value': 'fuel',
'type': 'hidden'
}
}
}
conf = task.DumpTask.conf()
self.assertIn({
'hostname': 'node1',
'address': '10.109.0.2',
'ssh-user': 'fuel',
'ssh-key': settings.SHOTGUN_SSH_KEY,
}, conf['dump']['slave']['hosts'])
self.assertIn({
'hostname': 'node2',
'address': '10.109.0.5',
'ssh-user': 'fuel',
'ssh-key': settings.SHOTGUN_SSH_KEY,
}, conf['dump']['slave']['hosts'])
@mock.patch('nailgun.task.task.db')
@mock.patch('nailgun.task.task.objects.Cluster')
def test_controller_generating(self, mock_cluster, mock_db):
(
mock_db.return_value.query.return_value.filter.return_value.
all.return_value
) = [
mock.Mock(hostname='node1', ip='10.109.0.1', roles=['controller',
'cinder']),
mock.Mock(hostname='node2', roles=['compute']),
]
mock_cluster.get_editable_attributes.return_value = {
'service_user': {
'name': {
'value': 'fuel',
'type': 'hidden'
}
}
}
conf = task.DumpTask.conf()
self.assertIn({
'hostname': 'node1',
'address': '10.109.0.1',
'ssh-user': 'fuel',
'ssh-key': settings.SHOTGUN_SSH_KEY,
}, conf['dump']['controller']['hosts'])
self.assertNotIn({
'hostname': 'node2',
'ssh-user': 'fuel',
'ssh-key': settings.SHOTGUN_SSH_KEY,
}, conf['dump']['controller']['hosts'])
@mock.patch('nailgun.task.task.db')
@mock.patch('nailgun.task.task.objects.Cluster')
def test_falling_back_to_root_ssh(self, mock_cluster, mock_db):
(
mock_db.return_value.query.return_value.filter.return_value.
all.return_value
) = [
mock.Mock(hostname='node1', ip="10.109.0.2", roles=[]),
mock.Mock(hostname='node2', ip="10.109.0.5", roles=[]),
]
mock_cluster.get_editable_attributes.return_value = {
'editable': {}
}
conf = task.DumpTask.conf()
self.assertIn({
'hostname': 'node1',
'address': '10.109.0.2',
'ssh-user': 'root',
'ssh-key': settings.SHOTGUN_SSH_KEY,
}, conf['dump']['slave']['hosts'])
self.assertIn({
'hostname': 'node2',
'address': '10.109.0.5',
'ssh-user': 'root',
'ssh-key': settings.SHOTGUN_SSH_KEY,
}, conf['dump']['slave']['hosts'])