Skip to content
Merged
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
136 changes: 136 additions & 0 deletions tests/foreman/cli/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import pytest

from robottelo.config import settings
from robottelo.constants import FOREMANCTL_PARAMETERS_FILE
from robottelo.logging import logger
from robottelo.utils.issue_handlers import is_open

pytestmark = pytest.mark.e2e

Expand Down Expand Up @@ -246,3 +248,137 @@ def test_positive_logging_from_pulp3(module_org, target_sat):
# verify pulp correlation id in message
message_log = target_sat.execute(f'cat {test_logfile} | grep {pulp_correlation_id}')
assert message_log.status == 0


@pytest.mark.foremanctl
class TestSOSReportForemanctl:
"""Tests for the foremanctl sos plugin on containerized Satellite."""

Comment on lines +254 to +256

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, this change in Foremanctl depends on the upstream SOS package, so while upstream PRT might pass, downstream tests will continue to fail until the package becomes available there.
To handle this in the interim, I think we should add a skip_if_open marker to skip these tests when running against downstream, we could try install from Packit COPR repos as a workaround until the downstream package catches up, wdyt?

@Gauravtalreja1 Gauravtalreja1 Jul 28, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a short-term workaround, we could add an autouse fixture to enable the COPR repo from the upstream SOS PR and get this merged sooner.
I think this gives us about a month before the Packit RPM expires. After that, we can switch to using a SOS upstream nightly RPM built from their main branch, that wasn't available today, so I've opened a PR upstream to add a nightly build similar to what we already do in @theforeman added by @evgeni

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added is_open to enable COPR repo from the upstream SOS PR as a short-term workaround

SOS_CMD = 'sos report -o foremanctl --batch --tmp-dir /var/tmp'
EXTRACT_DIR = '/var/tmp/sosreport-extract'

@pytest.fixture(scope="module")
def sosreport_extract(self, module_target_sat):
# Use the sos packit build until the RHEL issue is resolved
if is_open('RHEL-208899'):
assert (
module_target_sat.execute(
'dnf -y copr enable packit/sosreport-sos-4376 centos-stream-9-x86_64'
).status
== 0
)
assert (
module_target_sat.execute(
'dnf install -y sos-4.11.2-1.20260710083645300958.pr4376.22.g3fc1dc6b.el9.noarch'
).status
== 0
)

# Run sosreport and yield the extracted report directory path.
result = module_target_sat.execute(self.SOS_CMD, timeout='10m')
assert result.status == 0, f'sosreport failed:\n{result.stdout}\n{result.stderr}'

tarball = module_target_sat.execute(
'ls /var/tmp/sosreport-*.tar.xz | head -1'
).stdout.strip()
assert tarball, 'No sosreport tarball found'

module_target_sat.execute(f'mkdir -p {self.EXTRACT_DIR}')
module_target_sat.execute(f'tar xf {tarball} -C {self.EXTRACT_DIR}')

report_dir = module_target_sat.execute(
f'ls -d {self.EXTRACT_DIR}/sosreport-*'
).stdout.strip()
yield report_dir
module_target_sat.execute(f'rm -rf /var/tmp/sosreport-* {self.EXTRACT_DIR}')
Comment on lines +281 to +293

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Assert success of tar extraction and cleanup commands in the sosreport fixture

The fixture currently ignores the exit status of the tar extraction and cleanup commands, so failures (e.g., corrupt tar, permissions, disk full) would surface later as less clear test errors. Please capture the return values of these execute calls and assert status == 0 so setup failures are detected and reported immediately.

Suggested change
tarball = module_target_sat.execute(
'ls /var/tmp/sosreport-*.tar.xz | head -1'
).stdout.strip()
assert tarball, 'No sosreport tarball found'
module_target_sat.execute(f'mkdir -p {self.EXTRACT_DIR}')
module_target_sat.execute(f'tar xf {tarball} -C {self.EXTRACT_DIR}')
report_dir = module_target_sat.execute(
f'ls -d {self.EXTRACT_DIR}/sosreport-*'
).stdout.strip()
yield report_dir
module_target_sat.execute(f'rm -rf /var/tmp/sosreport-* {self.EXTRACT_DIR}')
tarball = module_target_sat.execute(
'ls /var/tmp/sosreport-*.tar.xz | head -1'
).stdout.strip()
assert tarball, 'No sosreport tarball found'
mkdir_result = module_target_sat.execute(f'mkdir -p {self.EXTRACT_DIR}')
assert mkdir_result.status == 0, (
f'Failed to create sosreport extract directory {self.EXTRACT_DIR}:\n'
f'{mkdir_result.stdout}\n{mkdir_result.stderr}'
)
tar_result = module_target_sat.execute(f'tar xf {tarball} -C {self.EXTRACT_DIR}')
assert tar_result.status == 0, (
f'Failed to extract sosreport tarball {tarball}:\n'
f'{tar_result.stdout}\n{tar_result.stderr}'
)
report_dir = module_target_sat.execute(
f'ls -d {self.EXTRACT_DIR}/sosreport-*'
).stdout.strip()
yield report_dir
cleanup_result = module_target_sat.execute(
f'rm -rf /var/tmp/sosreport-* {self.EXTRACT_DIR}'
)
assert cleanup_result.status == 0, (
f'Failed to cleanup sosreport artifacts:\n'
f'{cleanup_result.stdout}\n{cleanup_result.stderr}'
)


def test_positive_sosreport_foremanctl_collects_data(
self, module_target_sat, sosreport_extract
):
"""Verify the foremanctl sos plugin activates on a containerized
Satellite and collects expected configuration files and command output.

:id: dc91bb91-d785-49f9-b19d-b0484662ce3f

:steps:
1. Run sosreport with the foremanctl plugin
2. Verify foremanctl configuration files are collected
3. Verify foremanctl command outputs are collected

:expectedresults:
1. parameters.yaml and inventory files are present in the report
2. foremanctl features and foremanctl health output are collected
"""
report = sosreport_extract

params = module_target_sat.execute(f'test -f {report}/var/lib/foremanctl/parameters.yaml')
assert params.status == 0, 'parameters.yaml not collected'

inventory = module_target_sat.execute(f'test -f {report}/etc/foremanctl/inventory')
assert inventory.status == 0, 'foremanctl inventory not collected'

features = module_target_sat.execute(
f'test -f {report}/sos_commands/foremanctl/foremanctl_features'
)
assert features.status == 0, 'foremanctl features output not collected'

health = module_target_sat.execute(
f'test -f {report}/sos_commands/foremanctl/foremanctl_health'
)
assert health.status == 0, 'foremanctl health output not collected'

def test_positive_sosreport_foremanctl_scrub_sensitive_values(
self, module_target_sat, sosreport_extract
):
"""Verify the foremanctl sos plugin scrubs sensitive credentials
from parameters.yaml and foremanctl log files while preserving
non-sensitive values.

:id: a8bdb8f7-dd0f-44ee-9722-af4b1815aad2

:steps:
1. Verify passwords exist in the original parameters.yaml
2. Run sosreport with the foremanctl plugin
3. Check password values in parameters.yaml are scrubbed
4. Check non-sensitive values are NOT scrubbed
5. Verify foremanctl log files are collected
6. Check that sensitive values in logs are scrubbed

:expectedresults:
1. All password values in parameters.yaml are scrubbed
2. Non-sensitive values like database names remain intact
3. foremanctl log files are present in the report
4. Any lines matching sensitive value patterns in logs
have their values scrubbed'
"""
# only password exists for now on the default deploy and more can be added in future
SENSITIVE_KEYWORD = ('password',)
SCRUB_MARKER = '***'

original = module_target_sat.execute(f'grep -i password {FOREMANCTL_PARAMETERS_FILE}')
assert original.stdout.strip(), f'No password entries found in {FOREMANCTL_PARAMETERS_FILE}'

report = sosreport_extract

# Verify parameters.yaml scrubbing
collected = module_target_sat.execute(f'cat {report}/var/lib/foremanctl/parameters.yaml')
assert collected.status == 0, 'Could not read collected parameters.yaml'

for keyword in SENSITIVE_KEYWORD:
matching_lines = [
line for line in collected.stdout.splitlines() if keyword in line.lower()
]
for line in matching_lines:
assert SCRUB_MARKER in line, f'Sensitive value not scrubbed in line: {line}'

# Verify log file scrubbing
log_dir = f'{report}/var/log/foremanctl'
log_files = module_target_sat.execute(f'ls {log_dir}/foremanctl*log* 2>/dev/null')
assert log_files.status == 0, 'Failed to list foremanctl log files in sosreport'

sensitive_check = module_target_sat.execute(
f'grep -hEi "passw|cred|token|secret" {log_dir}/foremanctl*log* 2>/dev/null'
)
if sensitive_check.stdout.strip():
for line in sensitive_check.stdout.splitlines():
assert SCRUB_MARKER in line, f'Sensitive value not scrubbed in log line: {line}'