Skip to content

feat: new datasources: host_key_files #4415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions insights/specs/datasources/host_key_files.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""
Custom datasources relate to `/etc/*host*_key`
"""

import os

from insights.specs import Specs
from insights.core.context import HostContext
from insights.core.filters import add_filter
from insights.core.plugins import datasource
from insights.core.exceptions import SkipComponent
from insights.core.spec_factory import DatasourceProvider

ERROR_MSG = "error: Could not load host key:"
add_filter(Specs.messages, ERROR_MSG)


@datasource(Specs.messages, HostContext)
def host_key_files(broker):
"""
This datasource reads '/var/log/messages' to check the host key path, and check
whether the corresponding file exists.

The output of this datasource looks like:
/etc/ssh/ssh_host_dsa_key 1
/etc/ssh_host_dsa_key 0

Returns:
str: Returns a multiline string in the format as ``file_path count``.

Raises:
SkipComponent: When any exception occurs.
"""
error_loadings = set()
messages = broker[Specs.messages].content
for line in messages:
if ERROR_MSG in line:
error_loadings.add(line.split(ERROR_MSG)[-1].strip())

if not error_loadings:
raise SkipComponent()

data_list = []
for key_file in [file for file in error_loadings if file.startswith('/etc/')]:
count = 0
if os.path.exists(key_file):
count = 1
data_list.append("{0} {1}".format(key_file, count))

return DatasourceProvider(
content="\n".join(data_list),
relative_path='insights_datasources/host_key_files',
)
49 changes: 49 additions & 0 deletions insights/tests/datasources/test_host_key_files.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import pytest

from mock.mock import patch, Mock
from insights.specs import Specs
from insights.core.dr import SkipComponent
from insights.core.spec_factory import DatasourceProvider
from insights.specs.datasources.host_key_files import host_key_files

VAR_LOGS = """
Mar 16 19:30:54 host sshd[10644]: error: Could not load host key: /etc/ssh/ssh_host_dsa_key
Mar 16 19:30:54 host sshd[10645]: error: New host key: /etc/ssh_host_dsa_key
Mar 16 19:30:54 host sshd[10645]: error: Could not load host key: /etc/ssh_host_dsa_key
""".strip()

RELATIVE_PATH = "insights_datasources/host_key_files"
EXPECTED_RESULT = """
/etc/ssh/ssh_host_dsa_key 1
/etc/ssh_host_dsa_key 0
""".strip()


@patch('os.path.exists')
def test_host_key_files(mock_exists):
files_dict = {
'/etc/ssh/ssh_host_dsa_key': True,
'/etc/ssh_host_dsa_key': False,
}
mock_exists.side_effect = lambda path: files_dict.get(path, False)

messages = Mock()
messages.content = VAR_LOGS.splitlines()
broker = {Specs.messages: messages}

result = host_key_files(broker)
assert result is not None

expected = DatasourceProvider(content=EXPECTED_RESULT, relative_path=RELATIVE_PATH)
assert len(result.content) == len(expected.content) == 2


@patch('os.path.exists')
def test_host_key_files_empty_log(mock_exists):
messages = Mock()
messages.content = []
broker = {Specs.messages: messages}

with pytest.raises(SkipComponent) as e:
host_key_files(broker)
assert 'SkipComponent' in str(e)
Loading