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:
parent
f56a3aa809
commit
cf26770465
@ -398,7 +398,9 @@ class LogPackageHandler(BaseHandler):
|
|||||||
try:
|
try:
|
||||||
conf = jsonutils.loads(web.data()) if web.data() else None
|
conf = jsonutils.loads(web.data()) if web.data() else None
|
||||||
task_manager = DumpTaskManager()
|
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:
|
except Exception as exc:
|
||||||
logger.warn(u'DumpTask: error while execution '
|
logger.warn(u'DumpTask: error while execution '
|
||||||
'dump environment task: {0}'.format(str(exc)))
|
'dump environment task: {0}'.format(str(exc)))
|
||||||
|
@ -1167,7 +1167,7 @@ class ClusterDeletionManager(TaskManager):
|
|||||||
|
|
||||||
class DumpTaskManager(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")
|
logger.info("Trying to start dump_environment task")
|
||||||
self.check_running_task(consts.TASK_NAMES.dump)
|
self.check_running_task(consts.TASK_NAMES.dump)
|
||||||
|
|
||||||
@ -1177,7 +1177,8 @@ class DumpTaskManager(TaskManager):
|
|||||||
self._call_silently(
|
self._call_silently(
|
||||||
task,
|
task,
|
||||||
tasks.DumpTask,
|
tasks.DumpTask,
|
||||||
conf=conf
|
conf=conf,
|
||||||
|
auth_token=auth_token
|
||||||
)
|
)
|
||||||
return task
|
return task
|
||||||
|
|
||||||
|
@ -1879,7 +1879,7 @@ class CheckBeforeDeploymentTask(object):
|
|||||||
|
|
||||||
class DumpTask(object):
|
class DumpTask(object):
|
||||||
@classmethod
|
@classmethod
|
||||||
def conf(cls):
|
def conf(cls, auth_token=None):
|
||||||
logger.debug("Preparing config for snapshot")
|
logger.debug("Preparing config for snapshot")
|
||||||
nodes = db().query(Node).filter(
|
nodes = db().query(Node).filter(
|
||||||
Node.status.in_(['ready', 'provisioned', 'deploying',
|
Node.status.in_(['ready', 'provisioned', 'deploying',
|
||||||
@ -1887,6 +1887,8 @@ class DumpTask(object):
|
|||||||
).all()
|
).all()
|
||||||
|
|
||||||
dump_conf = deepcopy(settings.DUMP)
|
dump_conf = deepcopy(settings.DUMP)
|
||||||
|
if auth_token:
|
||||||
|
dump_conf['auth-token'] = auth_token
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
if node.cluster is None:
|
if node.cluster is None:
|
||||||
logger.info("Node {id} is not assigned to an environment, "
|
logger.info("Node {id} is not assigned to an environment, "
|
||||||
@ -1951,14 +1953,14 @@ class DumpTask(object):
|
|||||||
return dump_conf
|
return dump_conf
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def execute(cls, task, conf=None):
|
def execute(cls, task, conf=None, auth_token=None):
|
||||||
logger.debug("DumpTask: task={0}".format(task.uuid))
|
logger.debug("DumpTask: task={0}".format(task.uuid))
|
||||||
message = make_astute_message(
|
message = make_astute_message(
|
||||||
task,
|
task,
|
||||||
'dump_environment',
|
'dump_environment',
|
||||||
'dump_environment_resp',
|
'dump_environment_resp',
|
||||||
{
|
{
|
||||||
'settings': conf or cls.conf()
|
'settings': conf or cls.conf(auth_token)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
db().commit()
|
db().commit()
|
||||||
|
@ -382,71 +382,12 @@ class TestLogs(BaseIntegrationTest):
|
|||||||
f.write(self._format_log_entry(log_entry))
|
f.write(self._format_log_entry(log_entry))
|
||||||
f.flush()
|
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',
|
@mock.patch.dict('nailgun.task.task.settings.DUMP',
|
||||||
{'lastdump': 'LASTDUMP'})
|
{'lastdump': 'LASTDUMP'})
|
||||||
@fake_tasks(fake_rpc=False, mock_rpc=False)
|
@fake_tasks(fake_rpc=False, mock_rpc=False)
|
||||||
@mock.patch('nailgun.rpc.cast')
|
@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')
|
task = self.env.create_task(name='dump')
|
||||||
DumpTask.execute(task)
|
DumpTask.execute(task)
|
||||||
message = {
|
message = {
|
||||||
@ -467,7 +408,7 @@ class TestLogs(BaseIntegrationTest):
|
|||||||
m = mock.Mock(return_value=None)
|
m = mock.Mock(return_value=None)
|
||||||
tm._call_silently = m
|
tm._call_silently = m
|
||||||
task = tm.execute()
|
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):
|
def test_snapshot_task_manager_already_running(self):
|
||||||
self.env.create_task(name="dump")
|
self.env.create_task(name="dump")
|
||||||
|
@ -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'])
|
|
Loading…
Reference in New Issue
Block a user