Skip to content
Open
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
266 changes: 266 additions & 0 deletions tests/foreman/ui/test_rhcloud_insights_vulnerability.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

from robottelo import constants
from robottelo.constants import OPENSSH_RECOMMENDATION
from robottelo.utils.datafactory import gen_string


def _safe_ui_call(fn, *fn_args):
Expand Down Expand Up @@ -1342,3 +1343,268 @@ def _has_restored_vulnerabilities():
assert status['Red Hat Lightspeed']['Status'] == 'Reporting', (
'Host should be reporting to Red Hat Lightspeed after re-registration'
)


@pytest.mark.no_containers
@pytest.mark.rhel_ver_match('10')
@pytest.mark.parametrize('module_target_sat_insights', [False], ids=['local'], indirect=True)
def test_positive_iop_services_with_alternate_hostname_fact(
rhel_contenthost,
rhcloud_manifest_org,
module_target_sat_insights,
rhcloud_activation_key,
setup_content_for_iop,
):
"""Verify IoP Advisor and Vulnerability services work correctly when using alternate hostname fact.

This test validates that when Satellite and Insights are configured to use
the same alternate display name (via custom RHSM fact), the host registration,
IoP services, and re-registration all function correctly without creating
duplicate host records.

:id: a1b2c3d4-e5f6-7890-abcd-ef1234567890

:steps:
1. Configure Satellite to use alternate hostname fact (network.hostname-override)
2. Create custom RHSM fact on the client with alternate hostname
3. Configure Insights to use the same alternate display name
4. Verify the alternate hostname is resolvable from Satellite
5. Register the host using global registration with setup_insights=true
6. Verify the host appears in Satellite using the alternate display name
7. Verify the host appears in Insights using the alternate display name
8. Verify successful IoP registration
9. Create vulnerabilities and recommendations on the host
10. Verify Vulnerability service displays data correctly
11. Verify Advisor service shows recommendations correctly
12. Force re-register using global registration with force=true
13. Verify the host continues to use the alternate display name
14. Verify successful IoP registration after re-registration
15. Re-verify Vulnerability and Advisor services
16. Verify no duplicate host records were created
17. Verify no stale IoP entries exist

:expectedresults:
1. Satellite accepts and uses the alternate hostname fact
2. Host registers successfully with alternate display name
3. IoP services (Vulnerability and Advisor) work correctly with alternate hostname
4. Re-registration maintains the alternate hostname without duplicates
5. No stale IoP entries are left after re-registration

:customerscenario: true

:Verifies: SAT-44011
"""
satellite = module_target_sat_insights
client = rhel_contenthost
org = rhcloud_manifest_org

# Define the alternate hostname with a meaningful prefix and random suffix
hostname_prefix = f'alt-insights-{gen_string("alpha", 6).lower()}'
alternate_hostname = f'{hostname_prefix}.{client.hostname.split(".", 1)[-1]}'

# Step 1: Configure Satellite to use alternate hostname fact
result = satellite.execute(
'hammer settings set --name register_hostname_fact --value network.hostname-override'
)
assert result.status == 0, f'Failed to configure Satellite hostname fact: {result.stderr}'

# Step 2: Create custom RHSM fact on the client with alternate hostname
rhsm_fact_content = f'{{"network.hostname-override":"{alternate_hostname}"}}'
assert client.execute('mkdir -p /etc/rhsm/facts').status == 0
result = client.execute(f'echo \'{rhsm_fact_content}\' > /etc/rhsm/facts/hostname.facts')
assert result.status == 0, f'Failed to create RHSM fact file: {result.stderr}'

# Step 3: Configure Insights to use the same alternate display name
result = client.execute(
f'echo "display_name={alternate_hostname}" >> /etc/insights-client/insights-client.conf'
)
assert result.status == 0, f'Failed to configure Insights display name: {result.stderr}'

# Step 4: Verify the alternate hostname is resolvable from Satellite
# Add entry to /etc/hosts for resolution
client_ip = client.execute('hostname -I | awk \'{print $1}\'').stdout.strip()
result = satellite.execute(f'echo "{client_ip} {alternate_hostname}" >> /etc/hosts')
assert result.status == 0, f'Failed to add hosts entry on Satellite: {result.stderr}'

# Verify resolution
result = satellite.execute(f'ping -c 1 {alternate_hostname}')
assert result.status == 0, (
f'Alternate hostname {alternate_hostname} is not resolvable from Satellite'
)
Comment thread
jnagare-redhat marked this conversation as resolved.

# Step 5: Register the host using global registration with setup_insights=true
result = client.register(
org=org,
loc=None,
activation_keys=[rhcloud_activation_key.name],
target=satellite,
setup_insights=True,
)
assert result.status == 0, f'Failed to register host with global registration: {result.stderr}'

# Step 6-7: Verify the host appears in Satellite and Insights using alternate display name
with satellite.ui_session() as session:
session.organization.select(org_name=org.name)

# Search for host by alternate hostname
search_result = session.host_new.search(alternate_hostname)
assert search_result, f'Host not found with alternate hostname {alternate_hostname}'
assert len(search_result) > 0, (
f'Search returned empty results for alternate hostname {alternate_hostname}'
)
assert alternate_hostname in search_result[0]['Name'], (
f'Host name does not match alternate hostname. '
f'Expected: {alternate_hostname}, Got: {search_result[0]["Name"]}'
)

# Step 8: Verify successful IoP registration
status = session.host_new.get_host_statuses(alternate_hostname)
assert status['Red Hat Lightspeed']['Status'] == 'Reporting', (
'IoP registration failed - Red Hat Lightspeed status is not Reporting'
)

# Step 9: Create recommendations on the host (lightweight, no package operations)
# Add permission misconfiguration to trigger recommendation
assert client.execute('chmod 777 /etc/shadow').status == 0
Comment thread
jnagare-redhat marked this conversation as resolved.

# Run insights-client to report recommendations
result = client.execute('insights-client')
assert result.status == 0, f'insights-client failed: {result.stdout}'

# Step 10: Verify Vulnerability service displays data correctly
# Check for any vulnerabilities (natural CVEs from base system packages)
def _has_vulnerabilities():
session.browser.refresh()
vulns = session.host_new.get_vulnerabilities(alternate_hostname)
return bool(vulns)

has_vulns, _ = wait_for(
_has_vulnerabilities,
timeout=600,
delay=30,
handle_exception=True,
)
assert has_vulns, (
f'No vulnerabilities found for host with alternate hostname {alternate_hostname}'
)

vulnerabilities = session.host_new.get_vulnerabilities(alternate_hostname)
# Verify we have vulnerability data (checking for any CVE, not a specific one)
assert len(vulnerabilities) > 0, 'Vulnerabilities list should not be empty'
assert any(vuln.get('CVE ID') for vuln in vulnerabilities), (
'No CVE IDs found in vulnerabilities'
)

# Step 11: Verify Advisor service shows recommendations correctly
def _has_recommendations():
session.browser.refresh()
recs = session.host_new.get_recommendations(alternate_hostname)
return bool(recs)

has_recs, _ = wait_for(
_has_recommendations,
timeout=600,
delay=30,
handle_exception=True,
)
assert has_recs, (
f'No recommendations found for host with alternate hostname {alternate_hostname}'
)

# Step 12: Force re-register using global registration with force=true
result = client.register(
org=org,
loc=None,
activation_keys=[rhcloud_activation_key.name],
target=satellite,
setup_insights=True,
force=True,
)
assert result.status == 0, f'Failed to force re-register host: {result.stderr}'

# Step 13: Verify the host continues to use the alternate display name
session.browser.refresh()
search_result = session.host_new.search(alternate_hostname)
assert search_result, (
f'Host not found with alternate hostname {alternate_hostname} after re-registration'
)
assert len(search_result) > 0, (
f'Search returned empty results for alternate hostname {alternate_hostname} after re-registration'
)
assert alternate_hostname in search_result[0]['Name'], (
f'Host name changed after re-registration. '
f'Expected: {alternate_hostname}, Got: {search_result[0]["Name"]}'
)

# Step 14: Verify successful IoP registration after re-registration
status = session.host_new.get_host_statuses(alternate_hostname)
assert status['Red Hat Lightspeed']['Status'] == 'Reporting', (
'IoP registration failed after re-registration'
)

# Step 15: Re-verify Vulnerability and Advisor services
# Run insights-client to refresh data
result = client.execute('insights-client')
assert result.status == 0, f'insights-client failed after re-registration: {result.stdout}'

# Verify vulnerabilities still show
def _has_vulnerabilities_after_rereg():
session.browser.refresh()
vulns = session.host_new.get_vulnerabilities(alternate_hostname)
return bool(vulns)

has_vulns_after, _ = wait_for(
_has_vulnerabilities_after_rereg,
timeout=600,
delay=30,
handle_exception=True,
)
assert has_vulns_after, (
'Vulnerabilities missing after re-registration with alternate hostname'
)

# Verify recommendations still show
def _has_recommendations_after_rereg():
session.browser.refresh()
recs = session.host_new.get_recommendations(alternate_hostname)
return bool(recs)

has_recs_after, _ = wait_for(
_has_recommendations_after_rereg,
timeout=600,
delay=30,
handle_exception=True,
)
assert has_recs_after, (
'Recommendations missing after re-registration with alternate hostname'
)

# Step 16: Verify no duplicate host records were created
# Search by domain to find all hosts that might match (original or alternate)
domain = client.hostname.split('.', 1)[-1] if '.' in client.hostname else ''
all_hosts_with_domain = session.host_new.search(domain) if domain else []

# Filter for hosts that match either original or alternate hostname
matching_hosts = [
host
for host in all_hosts_with_domain
if client.hostname in host.get('Name', '') or alternate_hostname in host.get('Name', '')
]

# Should only find one host (with the alternate hostname)
assert len(matching_hosts) == 1, (
f'Expected 1 host, found {len(matching_hosts)}. '
f'Possible duplicate or missing host. Matching hosts: {[h["Name"] for h in matching_hosts]}'
)

assert alternate_hostname in matching_hosts[0]['Name'], (
f'Host should use alternate hostname {alternate_hostname}, '
f'but found {matching_hosts[0]["Name"]}'
)

# Step 17: Verify no stale IoP entries exist
# Verify that vulnerabilities are still associated with the alternate hostname
vulnerabilities_final = session.host_new.get_vulnerabilities(alternate_hostname)
assert len(vulnerabilities_final) > 0, (
'Vulnerabilities should still be present after re-registration with alternate hostname'
)