Skip to content
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
66 changes: 40 additions & 26 deletions robottelo/host_helpers/satellite_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
PUPPET_COMMON_INSTALLER_OPTS,
PUPPET_SATELLITE_INSTALLER,
)
from robottelo.enums import NetworkType
from robottelo.enums import InstallMethod, NetworkType
from robottelo.exceptions import CLIReturnCodeError, NoManifestProvidedError, SatelliteHostError
from robottelo.host_helpers.api_factory import APIFactory
from robottelo.host_helpers.cli_factory import CLIFactory
Expand Down Expand Up @@ -457,7 +457,11 @@ def get_iop_image_paths():
}

def configure_iop(self):
"""Configure on prem Advisor engine on Satellite"""
"""Configure on prem Advisor engine on Satellite.

Based on install_method: foremanctl uses ``foremanctl deploy --add-feature iop``,
installer uses ``satellite-installer --enable-iop --iop-ensure present``.
"""
logger.info('Configuring Satellite with local Red Hat Lightspeed')

self.register_to_cdn()
Expand All @@ -472,30 +476,39 @@ def configure_iop(self):
iop_settings.stage_username, iop_settings.stage_token, iop_settings.stage_registry
)

# Set IPv6 podman proxy on Satellite, to pull from container registry
self.enable_ipv6_podman_proxy()

# Set up container image path overrides
if image_paths := self.get_iop_image_paths():
custom_hiera = f'{robottelo_tmp_dir}/custom-hiera.yaml'

with open(custom_hiera, 'w') as f:
yaml.dump(
image_paths,
f,
sort_keys=False,
default_flow_style=False,
if self.install_method == InstallMethod.FOREMANCTL:

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.

Jfyi, since today we use same templates for both scenario, install_method() has underlying detect_install_method() which would pass for both scenarios, so I'd suggest using settings.server.install_method instead

for service, image in settings.rh_cloud.iop.image_paths.items():
quadlet_name = f'iop-{service.replace("_", "-")}'
self.execute(
f"sed -i 's|^Image=.*|Image={image}|' "
f"/etc/containers/systemd/{quadlet_name}.image"
)
self.put(custom_hiera, '/etc/foreman-installer/custom-hiera.yaml')

command = InstallerCommand(
'enable-iop',
iop_ensure='present',
scenario='satellite',
foreman_initial_admin_password=settings.server.admin_password,
).get_command()
result = self.execute('foremanctl deploy --add-feature iop', timeout='30m')
else:
# Set up container image path overrides for satellite-installer
Comment on lines +488 to +490

@Gauravtalreja1 Gauravtalreja1 Jul 6, 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.

How and where do you override the image paths for foremanctl to deploy IOP containers, as similar to traditional installer's custom hiera?

@ColeHiggins2 ColeHiggins2 Jul 6, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I wasnt aware that we need to override the image paths for foremanctl. If that is necessary, I can add it in

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.

+1, I have the same concern about where foremanctl image overrides are handled in this path.

if image_paths := self.get_iop_image_paths():
custom_hiera = f'{robottelo_tmp_dir}/custom-hiera.yaml'

with open(custom_hiera, 'w') as f:
yaml.dump(
image_paths,
f,
sort_keys=False,
default_flow_style=False,
)
self.put(custom_hiera, '/etc/foreman-installer/custom-hiera.yaml')

command = InstallerCommand(
'enable-iop',
iop_ensure='present',
scenario='satellite',
foreman_initial_admin_password=settings.server.admin_password,
).get_command()

result = self.execute(command, timeout='30m')

result = self.execute(command, timeout='30m')
if result.status != 0:
raise SatelliteHostError(f'Failed to configure IoP: {result.stdout}')
if not self.iop_enabled:
Expand All @@ -506,11 +519,12 @@ def uninstall_iop(self):
logger.info('IoP is already disabled. Skipping uninstallation.')
return

command = InstallerCommand(
iop_ensure='absent',
).get_command()
if self.install_method == InstallMethod.FOREMANCTL:
result = self.execute('foremanctl deploy --remove-feature iop', timeout='30m')
else:
command = InstallerCommand(iop_ensure='absent').get_command()
result = self.execute(command, timeout='30m')

result = self.execute(command, timeout='30m')
if result.status != 0:
raise SatelliteHostError(f'Failed to disable IoP: {result.stdout}')
if self.iop_enabled:
Expand Down
11 changes: 6 additions & 5 deletions robottelo/hosts.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
RHSSO_USER_UPDATE,
SATELLITE_VERSION,
)
from robottelo.enums import NetworkType
from robottelo.enums import InstallMethod, NetworkType
from robottelo.exceptions import (
CapsuleHostError,
CLIFactoryError,
Expand Down Expand Up @@ -1805,7 +1805,6 @@ def detect_install_method(self):
:return: InstallMethod enum value
:rtype: InstallMethod
"""
from robottelo.enums import InstallMethod

# Runtime override
if hasattr(self, '_install_method_override'):
Expand Down Expand Up @@ -1855,7 +1854,6 @@ def get_service_names(self):
:rtype: list
"""
from robottelo.constants import InstallationServices
from robottelo.enums import InstallMethod

if self.install_method == InstallMethod.FOREMANCTL:
return InstallationServices.FOREMANCTL_SERVICES
Expand Down Expand Up @@ -2268,7 +2266,6 @@ def install_satellite(
:param foremanctl_parameters: Parameters list for foremanctl deploy
:return: Installation result
"""
from robottelo.enums import InstallMethod
from robottelo.utils.installer import InstallerCommand

# Determine method
Expand Down Expand Up @@ -3150,7 +3147,11 @@ def set_pulp_cli_safemode(self, safe):
@property
def iop_enabled(self):
"""Return boolean indicating whether IoP (local Red Hat Lightspeed) is enabled."""
return self.api.RHCloud().advisor_engine_config()['use_iop_mode']

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.

Just curious, Is this API not available on foremanctl deployment? or am I missing some update around this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Correct this endpoint should have been removed and it open here theforeman/foreman_rh_cloud#1226

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.

That's great! Could you do this cleanup in nailgun entities as well whenever you get a chance?


if self.install_method == InstallMethod.FOREMANCTL:
return 'iop' in self.list_foremanctl_features(enabled=True)
result = self.execute('systemctl is-active iop-core-engine')
return result.status == 0


class SSOHost(Host):
Expand Down
68 changes: 46 additions & 22 deletions tests/foreman/cli/test_rhcloud_iop.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import yaml

from robottelo.config import settings
from robottelo.enums import InstallMethod
from robottelo.utils.installer import InstallerCommand

IOP_SERVICES = [
Expand Down Expand Up @@ -113,24 +114,39 @@ def test_positive_install_iop_custom_certs(
)
assert result.status == 0, f'Error logging in to container registry: {result.stdout}'

# Set up container image path overrides
custom_hiera_yaml = yaml.dump(
{f'iop::{service}::image': path for service, path in iop_settings.image_paths.items()}
)
satellite.execute(f'echo "{custom_hiera_yaml}" > /etc/foreman-installer/custom-hiera.yaml')

command = InstallerCommand(
'enable-iop',
'certs-update-server',
'certs-update-server-ca',
scenario='satellite',
certs_server_cert=f'/root/{certs_data["cert_file_name"]}',
certs_server_key=f'/root/{certs_data["key_file_name"]}',
certs_server_ca_cert=f'/root/{certs_data["ca_bundle_file_name"]}',
foreman_initial_admin_password=settings.server.admin_password,
).get_command()

result = satellite.execute(command, timeout='30m')
if satellite.install_method == InstallMethod.FOREMANCTL:
for service, image in iop_settings.image_paths.items():
quadlet_name = f'iop-{service.replace("_", "-")}'
satellite.execute(
f"sed -i 's|^Image=.*|Image={image}|' /etc/containers/systemd/{quadlet_name}.image"
)
result = satellite.execute(
'foremanctl deploy --add-feature iop'
f' --certificate-source=custom_server'
f' --certificate-server-certificate /root/{certs_data["cert_file_name"]}'
f' --certificate-server-key /root/{certs_data["key_file_name"]}'
f' --certificate-server-ca-certificate /root/{certs_data["ca_bundle_file_name"]}',
timeout='30m',
)
else:
# Set up container image path overrides
custom_hiera_yaml = yaml.dump(
{f'iop::{service}::image': path for service, path in iop_settings.image_paths.items()}
)
satellite.execute(f'echo "{custom_hiera_yaml}" > /etc/foreman-installer/custom-hiera.yaml')

command = InstallerCommand(
'enable-iop',
'certs-update-server',
'certs-update-server-ca',
scenario='satellite',
certs_server_cert=f'/root/{certs_data["cert_file_name"]}',
certs_server_key=f'/root/{certs_data["key_file_name"]}',
certs_server_ca_cert=f'/root/{certs_data["ca_bundle_file_name"]}',
foreman_initial_admin_password=settings.server.admin_password,
).get_command()

result = satellite.execute(command, timeout='30m')
assert result.status == 0

result = satellite.execute('hammer ping')
Expand Down Expand Up @@ -222,8 +238,11 @@ def test_disable_enable_iop(module_satellite_iop, module_sca_manifest, rhel_cont
assert result.status == 0, 'Initial insights-client upload failed'

# Disable IoP
command = InstallerCommand(iop_ensure='absent').get_command()
result = satellite.execute(command, timeout='10m')
if satellite.install_method == InstallMethod.FOREMANCTL:
result = satellite.execute('foremanctl deploy --remove-feature iop', timeout='30m')
else:
command = InstallerCommand(iop_ensure='absent').get_command()
result = satellite.execute(command, timeout='10m')
assert result.status == 0, 'Failed to disable IoP'

result = satellite.execute('satellite-maintain service restart')
Expand Down Expand Up @@ -260,8 +279,11 @@ def test_disable_enable_iop(module_satellite_iop, module_sca_manifest, rhel_cont
assert result.status == 0, 'Failed to unregister from Red Hat Lightspeed'

# Re-enable IoP
command = InstallerCommand(iop_ensure='present').get_command()
result = satellite.execute(command, timeout='10m')
if satellite.install_method == InstallMethod.FOREMANCTL:
result = satellite.execute('foremanctl deploy --add-feature iop', timeout='30m')
else:
command = InstallerCommand(iop_ensure='present').get_command()
result = satellite.execute(command, timeout='10m')
assert result.status == 0, 'Failed to re-enable IoP'

result = satellite.execute('satellite-maintain service restart')
Expand Down Expand Up @@ -352,6 +374,7 @@ def process_iop_log_options(installer_output):
return options_dict


@pytest.mark.foreman_installer
def test_set_iop_log_level_via_installer(module_satellite_iop):
"""Set IoP log level to DEBUG using satellite-installer options.

Expand All @@ -369,6 +392,7 @@ def test_set_iop_log_level_via_installer(module_satellite_iop):

:Verifies: SAT-41750
"""

NEW_LOG_LEVEL = 'DEBUG'

# Retrieve the IoP log level settings from satellite-installer help output
Expand Down