Skip to content

Warn about unrecognized smart proxy features - #554

Merged
ehelms merged 11 commits into
theforeman:masterfrom
adamruzicka:unknown-proxy-features
Jul 9, 2026
Merged

Warn about unrecognized smart proxy features#554
ehelms merged 11 commits into
theforeman:masterfrom
adamruzicka:unknown-proxy-features

Conversation

@adamruzicka

Copy link
Copy Markdown
Contributor

Companion to theforeman/foreman#11017

Why are you introducing these changes? (Problem description, related links)

Currently if the proxy offers more features than Foreman knows, those would go silently ignored (unless all of the proxy's features are unknown to Foreman), which makes it hard to spot misconfigured deployments.

What are the changes introduced in this pull request?

After registering a proxy, fctl will check if all the proxy's features are recognized by Foreman and warn if not.

How to test this pull request

Steps to reproduce:

  1. Somehow force a deployment where the proxy has features which Foreman doesn't know
  2. See the warning

Checklist

  • Tests added/updated (if applicable)
    • figure out how to do this
  • Documentation updated (if applicable)
    • this doesn't really need docs

@adamruzicka

Copy link
Copy Markdown
Contributor Author

figure out how to do this [tests]

This would require a test that would intentionally break things just to check that this would then emit a warning. I'm open to idea, but at this point I'm leaning towards not having tests for this here.

Comment thread src/roles/foreman_proxy/tasks/main.yaml Outdated
msg: >-
Proxy {{ foreman_proxy_name }} has features not recognized by Foreman:
{{ _foreman_proxy_registration.entity.smart_proxies[0].unrecognized_features | join(', ') }}.
If these features come from a Smart Proxy plugin, make sure Foreman has the plugin installed too.

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.

I don't think a user can act on this cleanly. Plugins are not a thing we expose here in foremanctl. We present the user with features. I like the general idea of where you are going with this, but it feels like a post_install check that should happen once at the end of deploy.

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.

Done. The only thing I'm not exactly happy about is that right now it checks all the proxies, not just those that were registered (or affected) during this installation run. Probably not a problem right now, but it could become somewhat confusing later

Comment thread src/roles/post_install/tasks/smart_proxy_features_check.yaml Outdated
Comment thread src/roles/post_install/tasks/smart_proxy_features_check.yaml Outdated
@adamruzicka
adamruzicka force-pushed the unknown-proxy-features branch 2 times, most recently from f234c85 to fd35f7b Compare June 17, 2026 09:41
@ehelms

ehelms commented Jun 30, 2026

Copy link
Copy Markdown
Member

Generally looks good now, you'll have to deal with the variables that are not scoped to the role name.

@adamruzicka
adamruzicka force-pushed the unknown-proxy-features branch from b04015b to 0362373 Compare June 30, 2026 12:12
@adamruzicka
adamruzicka marked this pull request as ready for review June 30, 2026 13:59
@adamruzicka

Copy link
Copy Markdown
Contributor Author

🍏

server_url: "{{ foreman_server_url }}"
oauth1_consumer_key: "{{ foreman_oauth_consumer_key }}"
oauth1_consumer_secret: "{{ foreman_oauth_consumer_secret }}"
ca_path: "{{ foreman_ca_path }}"

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.

To follow our rules, all of the variables in this role need to be role scoped (e.g. post_intsall_foreman_ca_path). Yes, I realize that creates a lot of overhead for this particular case, however, thems the rules currently.

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.

I was under the impression there was a lint that was enforcing this? Anyway, added

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.

I think it's enforcing role variables being namespaced but not the use of variables which I realize might sound like the same thing but it's not.

@adamruzicka
adamruzicka force-pushed the unknown-proxy-features branch from 6d7ff5b to 04b7a6a Compare July 2, 2026 08:38
Comment thread src/roles/post_install/tasks/main.yaml Outdated
- name: Check for unrecognized Smart Proxy features
ansible.builtin.include_tasks: smart_proxy_features_check.yaml
vars:
post_install_foreman_server_url: "{{ foreman_url }}"

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 is effectively the same issue -- these are variables not scoped to the current role. These would need to be passed into post_install role when it's declared in the deploy playbook for example.

Would we benefit from global variables? Perhaps. I think that should be a broader discussion.

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.

So the use of foreman_url on L8 is also wrong?

@adamruzicka
adamruzicka force-pushed the unknown-proxy-features branch from 0e8e74e to 4057e10 Compare July 2, 2026 11:59
Comment thread src/roles/post_install/tasks/main.yaml Outdated
_post_install_url_msg: "Foreman is running at {{ foreman_url }}"
_post_install_cred_msg: "Admin credentials: {{ foreman_initial_admin_username }}:{{ foreman_initial_admin_password }}"
_post_install_url_msg: "Foreman is running at {{ post_install_foreman_server_url }}"
_post_install_cred_msg: "Admin credentials: {{ post_install_foreman_initial_admin_username }}:{{ post_install_foreman_initial_admin_password }}"

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.

Thanks for handling those!

@ehelms

ehelms commented Jul 2, 2026

Copy link
Copy Markdown
Member

@adamruzicka rebase needed -- I merged a big set of changes with the deploy-proxy command

@adamruzicka
adamruzicka force-pushed the unknown-proxy-features branch 2 times, most recently from 8123cec to cc2b8e3 Compare July 3, 2026 09:49
Comment thread src/roles/foreman/tasks/main.yaml Outdated
@adamruzicka
adamruzicka force-pushed the unknown-proxy-features branch 2 times, most recently from 617576a to 1efd7f0 Compare July 7, 2026 07:18
adamruzicka and others added 5 commits July 9, 2026 10:06
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Previously, warnings about unrecognized Smart Proxy features were
displayed inline during installation as each proxy was registered.

Production deployments now check all Smart Proxies in the post_install
role using resource_info to query for unrecognized_features.

Development deployments check Smart Proxies in a post_task in the
deploy-dev playbook.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
In production deployments, move the Smart Proxy feature check from inline
(immediately after registration) to post-deployment checks. This provides
a comprehensive view of all proxy features across all registered proxies.

For development deployments, keep the inline checks since the Foreman
server is stopped before post-deployment tasks run.

The post-deployment check uses OAuth authentication to query the Foreman
API, fetching all registered Smart Proxies and checking for unrecognized
features in a single consolidated check.
Reword the warning to use foremanctl terminology and provide both
resolution paths: enable matching features in foremanctl or disable
them on the proxy.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Variables used in smart_proxy_features_check.yaml must follow the
role-scoped naming convention (post_install_*) per project rules.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@adamruzicka
adamruzicka force-pushed the unknown-proxy-features branch from 1efd7f0 to 2ea41cf Compare July 9, 2026 08:06
adamruzicka and others added 2 commits July 9, 2026 11:23
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@adamruzicka
adamruzicka force-pushed the unknown-proxy-features branch from 255023a to 07a7388 Compare July 9, 2026 12:14
@ehelms
ehelms merged commit 99670e3 into theforeman:master Jul 9, 2026
16 checks passed
@adamruzicka
adamruzicka deleted the unknown-proxy-features branch July 9, 2026 13:42
@evgeni

evgeni commented Jul 9, 2026

Copy link
Copy Markdown
Member

This now creates a rather huge skipped block at the end of every run:

TASK [post_install : Warn about unrecognized Smart Proxy features] ********************************************************************************************************************************************************************
skipping: [proxy] => (item={'created_at': '2026-07-09 15:08:02 UTC', 'updated_at': '2026-07-09 15:08:02 UTC', 'hosts_count': 0, 'unrecognized_features': [], 'name': 'proxy.example.com', 'id': 3, 'url': 'https://proxy.example.com:8443', 'remote_execution_pubkey': None, 'remote_execution_ca_pubkey': None, 'download_policy': 'on_demand', 'supported_pulp_types': [], 'lifecycle_environments': [], 'features': [{'capabilities': [], 'name': 'Logs', 'id': 13}], 'locations': [{'id': 2, 'name': 'Default Location', 'title': 'Default Location', 'description': None}], 'organizations': [{'id': 1, 'name': 'Default Organization', 'title': 'Default Organization', 'description': None}]}) 
skipping: [proxy] => (item={'created_at': '2026-07-09 15:07:32 UTC', 'updated_at': '2026-07-09 15:07:32 UTC', 'hosts_count': 0, 'unrecognized_features': [], 'name': 'proxy.example.com-pulp', 'id': 2, 'url': 'https://proxy.example.com/pulp/api/v3/smart_proxy', 'remote_execution_pubkey': None, 'remote_execution_ca_pubkey': None, 'download_policy': 'on_demand', 'supported_pulp_types': ['ansible_collection', 'deb', 'docker', 'file', 'python', 'yum'], 'lifecycle_environments': [], 'features': [{'capabilities': ['core', 'certguard', 'file', 'ansible', 'python', 'deb', 'smart_proxy', 'container', 'rpm'], 'name': 'Pulpcore', 'id': 3}], 'locations': [{'id': 2, 'name': 'Default Location', 'title': 'Default Location', 'description': None}], 'organizations': [{'id': 1, 'name': 'Default Organization', 'title': 'Default Organization', 'description': None}]}) 
skipping: [proxy] => (item={'created_at': '2026-07-09 14:56:46 UTC', 'updated_at': '2026-07-09 14:56:46 UTC', 'hosts_count': 0, 'unrecognized_features': [], 'name': 'quadlet.example.com-pulp', 'id': 1, 'url': 'https://quadlet.example.com/pulp/api/v3/smart_proxy', 'remote_execution_pubkey': None, 'remote_execution_ca_pubkey': None, 'download_policy': 'on_demand', 'supported_pulp_types': ['ansible_collection', 'deb', 'docker', 'file', 'python', 'yum'], 'lifecycle_environments': [{'id': 1, 'name': 'Library', 'description': None, 'library': True, 'organization_id': 1, 'created_at': '2026-07-09 14:53:46 UTC', 'updated_at': '2026-07-09 14:53:46 UTC', 'label': 'Library', 'registry_name_pattern': None, 'registry_unauthenticated_pull': False, 'prior': None, 'prior_id': None, 'organization': 'Default Organization'}], 'features': [{'capabilities': ['core', 'certguard', 'file', 'ansible', 'python', 'deb', 'smart_proxy', 'container', 'rpm'], 'name': 'Pulpcore', 'id': 3}], 'locations': [{'id': 2, 'name': 'Default Location', 'title': 'Default Location', 'description': None}], 'organizations': [{'id': 1, 'name': 'Default Organization', 'title': 'Default Organization', 'description': None}]}) 
skipping: [proxy]

especially: it makes the post_install message we have not the last thing printed.

TASK [post_install : Admin credentials] **********************************************
ok: [quadlet] => 
    msg:
    - Foreman is running at https://quadlet.example.com

Could Claude come up with a better solution for our users?

@ehelms

ehelms commented Jul 9, 2026

Copy link
Copy Markdown
Member

This now creates a rather huge skipped block at the end of every run:

How does one avoid this with Ansible?

especially: it makes the post_install message we have not the last thing printed.

That's fair, it was not obvious from the code that the "message" part is tied into the flavor element. We could make that code more obvious.

@ehelms

ehelms commented Jul 9, 2026

Copy link
Copy Markdown
Member

I took a shot at both through a re-factor of the post_install role: #641

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