Skip to content

Add foreman_ansible#444

Open
ehelms wants to merge 1 commit intotheforeman:masterfrom
ehelms:add-foreman-ansible
Open

Add foreman_ansible#444
ehelms wants to merge 1 commit intotheforeman:masterfrom
ehelms:add-foreman-ansible

Conversation

@ehelms
Copy link
Copy Markdown
Member

@ehelms ehelms commented Apr 2, 2026

No description provided.

Comment thread src/features.yaml
plugin_name: ansible
hammer: foreman_ansible
dependencies:
- dynflow
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.

I see remote_execution as dependecy of smart proxy ansible plugin too. https://github.com/theforeman/smart_proxy_ansible/blob/master/smart_proxy_ansible.gemspec#L32C31-L32C63, so by the metadata defination, should we add

remote-execution:
  internal: true
  foreman_proxy:
    plugin_name: remote_execution_ssh

here?

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.

remote-execution is defined already at line 23 and isn't an internal feature. The question is whether we need those dependencies at this level defined in order to orchestrate the right pieces. Let me add some tests for this first and see what that tells me.

Copy link
Copy Markdown
Contributor

@arvind4501 arvind4501 Apr 6, 2026

Choose a reason for hiding this comment

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

Sure, i was thinking about the scenario where remote-execution is not enabled(or explictely disabled via --remove-feature remote-execution), so which wil leave /etc/foreman-proxy/settings.d/remote_execution_ssh.yml not deployed(or deployed as enabled: false ) and remote execution being not available, in that case we might have a broker ansible feature

@ehelms ehelms force-pushed the add-foreman-ansible branch from 64e0224 to e06a7f9 Compare April 6, 2026 20:12
@ehelms
Copy link
Copy Markdown
Member Author

ehelms commented Apr 6, 2026

This relies on theforeman/foreman-oci-images#25 first

Comment on lines 232 to +237
- name: Add optional features - azure-rm, google and remote-execution
run: |
./foremanctl deploy --add-feature azure-rm --add-feature google --add-feature remote-execution
- name: Add optional feature - foreman-ansible
run: |
./foremanctl deploy --add-feature foreman-ansible
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can we combine this 2 steps and enable foreman-ansible feature along with others?

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.

Yes - I can do that for efficiency.

@ehelms
Copy link
Copy Markdown
Member Author

ehelms commented Apr 8, 2026

I started adding this to help ensure the IoP use-case could work out of the box by having ansible support for remediation. There is more nuance and testing for this feature that needs to happen to be complete.

When I test this locally with the updated containers built locally, I run into the hammer sync failing with no clear reason why. That will need investigation, i.e.:

hammer ansible roles sync

Comment on lines +55 to +83
def test_run_ansible_role(ansible_role, foremanapi, server, server_fqdn):
assign = server.run(f"hammer host ansible-roles assign --name {server_fqdn} --ansible-roles {ansible_role}")
assert assign.succeeded
assert 'Ansible roles were assigned to the host' in assign.stdout

play = server.run(f"hammer host ansible-roles play --name {server_fqdn}")
assert play.succeeded
assert 'Ansible roles are being played.' in play.stdout

tasks = foremanapi.list('foreman_tasks', search='label = Actions::RemoteExecution::RunHostsJob')
for task in tasks:
foremanapi.wait_for_task(task)

report = server.run(f"hammer --output csv --no-headers config-report list --search 'host={server_fqdn} origin=Ansible'")
assert report.succeeded
assert server_fqdn in report.stdout
assert 'Ansible' in report.stdout


def test_run_command_via_ansible(foremanapi, server_fqdn):
templates = foremanapi.list('job_templates', search='name = "Run Command - Ansible Default"')
job = foremanapi.create('job_invocations', {
'job_template_id': templates[0]['id'],
'inputs': {'command': 'uptime'},
'search_query': f'name = {server_fqdn}',
'targeting_type': 'static_query',
})
task = foremanapi.wait_for_task(job['task'])
assert task['result'] == 'success'
Copy link
Copy Markdown
Member

@evgeni evgeni Apr 14, 2026

Choose a reason for hiding this comment

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

these need to go to tests/client_test.py (well, it doesn't have to, but so far all client-related tests are there) and executed on the client, not the server. the server does not exist in Foreman as an entity and even if it would it would not have the ssh keys set up.

see

def test_foreman_rex(client_environment, activation_key, organization, foremanapi, client, client_fqdn):
client.run('dnf install -y subscription-manager')
rcmd = foremanapi.create('registration_commands', {'organization_id': organization['id'], 'insecure': True, 'activation_keys': [activation_key['name']], 'force': True})
client.run_test(rcmd['registration_command'])
job = foremanapi.create('job_invocations', {'feature': 'run_script', 'inputs': {'command': 'uptime'}, 'search_query': f'name = {client_fqdn}', 'targeting_type': 'static_query'})
task = foremanapi.wait_for_task(job['task'])
assert task['result'] == 'success'
foremanapi.delete('hosts', {'id': client_fqdn})



@pytest.fixture(scope="module")
def ansible_role(server, foremanapi, ansible_proxy_id):
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.

this needs to run in a way that the result ends up inside the proxy container, otherwise ansible will never see the roles

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants