From 74364268f6f32d7bd8205d92d55613e2a83d7469 Mon Sep 17 00:00:00 2001 From: Adam Ruzicka Date: Thu, 12 Feb 2026 12:28:30 +0100 Subject: [PATCH 01/10] Deploy hammer for development --- development/playbooks/_flavor_features | 1 + .../playbooks/deploy-dev/metadata.obsah.yaml | 3 + .../foreman_development/defaults/main.yaml | 49 +++++++++++++++ .../foreman_development/tasks/hammer/main.yml | 56 ++++++++++++++++++ .../tasks/hammer/plugin.yml | 59 +++++++++++++++++++ .../roles/foreman_development/tasks/main.yaml | 5 ++ .../templates/hammer/foreman.yml.j2 | 55 +++++++++++++++++ 7 files changed, 228 insertions(+) create mode 100644 development/playbooks/_flavor_features create mode 100644 development/roles/foreman_development/tasks/hammer/main.yml create mode 100644 development/roles/foreman_development/tasks/hammer/plugin.yml create mode 100644 development/roles/foreman_development/templates/hammer/foreman.yml.j2 diff --git a/development/playbooks/_flavor_features b/development/playbooks/_flavor_features new file mode 100644 index 00000000..151fa7f5 --- /dev/null +++ b/development/playbooks/_flavor_features @@ -0,0 +1 @@ +../../src/playbooks/_flavor_features \ No newline at end of file diff --git a/development/playbooks/deploy-dev/metadata.obsah.yaml b/development/playbooks/deploy-dev/metadata.obsah.yaml index 3dd8c925..6ad314b3 100644 --- a/development/playbooks/deploy-dev/metadata.obsah.yaml +++ b/development/playbooks/deploy-dev/metadata.obsah.yaml @@ -29,3 +29,6 @@ variables: foreman_development_github_username: help: GitHub username to add as additional remote for git checkouts action: store + +include: + - _flavor_features diff --git a/development/roles/foreman_development/defaults/main.yaml b/development/roles/foreman_development/defaults/main.yaml index da02111e..9a24f037 100644 --- a/development/roles/foreman_development/defaults/main.yaml +++ b/development/roles/foreman_development/defaults/main.yaml @@ -4,6 +4,7 @@ foreman_development_group: "{{ foreman_development_user }}" foreman_development_deployment_dir: "/home/{{ foreman_development_user }}" foreman_development_foreman_dir: "{{ foreman_development_deployment_dir }}/foreman" foreman_development_cert_dir: "{{ foreman_development_deployment_dir }}/foreman-certs" +foreman_development_hammer_dir: "{{ foreman_development_deployment_dir }}/hammer-cli" foreman_development_ca_certificate: "{{ foreman_ca_certificate }}" foreman_development_client_certificate: "{{ foreman_client_certificate }}" @@ -16,6 +17,9 @@ foreman_development_git_repo: "https://github.com/theforeman/foreman.git" foreman_development_git_revision: "develop" foreman_development_github_username: "" +foreman_development_hammer_git_repo: "https://github.com/theforeman/hammer-cli.git" +foreman_development_hammer_git_revision: "master" + foreman_development_rails_port: 3000 foreman_development_rails_command: "puma -w 2 -p {{ foreman_development_rails_port }} --preload -b tcp://0.0.0.0" @@ -36,43 +40,88 @@ foreman_development_plugin_registry: manage_repo: true extra_gemfiles: - "gemfile.d/test.rb" + hammer: + gem: hammer_cli_katello + name: "Katello/hammer-cli-katello" + module_config: katello.yml foreman_remote_execution: name: "theforeman/foreman_remote_execution" manage_repo: true + hammer: + name: "theforeman/hammer_cli_foreman_remote_execution" + module_config: foreman_remote_execution.yml foreman_ansible: name: "theforeman/foreman_ansible" settings_template: "foreman_ansible.yaml.j2" manage_repo: true + hammer: + gem: hammer_cli_foreman_ansible + name: "theforeman/hammer-cli-foreman-ansible" + module_config: foreman_ansible.yml foreman_rh_cloud: name: "theforeman/foreman_rh_cloud" manage_repo: true + hammer: + gem: hammer_cli_foreman_rh_cloud + name: "theforeman/hammer-cli-foreman-rh-cloud" + module_config: foreman_rh_cloud.yml foreman_discovery: name: "theforeman/foreman_discovery" manage_repo: true + hammer: + gem: hammer_cli_foreman_discovery + name: "theforeman/hammer-cli-foreman-discovery" + module_config: foreman_discovery.yml foreman_openscap: name: "theforeman/foreman_openscap" manage_repo: true + hammer: + name: "theforeman/hammer_cli_foreman_openscap" + module_config: foreman_openscap.yml foreman_bootdisk: name: "theforeman/foreman_bootdisk" manage_repo: true + hammer: + name: "theforeman/hammer_cli_foreman_bootdisk" + module_config: foreman_bootdisk.yml foreman_theme_satellite: name: "redhatsatellite/foreman_theme_satellite" manage_repo: true foreman_tasks: name: "theforeman/foreman-tasks" manage_repo: true + hammer: + gem: hammer_cli_foreman_tasks + name: "theforeman/hammer-cli-foreman-tasks" + module_config: foreman_tasks.yml foreman_webhooks: name: "theforeman/foreman_webhooks" manage_repo: true + hammer: + gem: hammer_cli_foreman_webhooks + name: "theforeman/hammer-cli-foreman-webhooks" + module_config: foreman_webhooks.yml foreman_templates: name: "theforeman/foreman_templates" manage_repo: true + hammer: + gem: hammer_cli_foreman_templates + name: "theforeman/hammer-cli-foreman-templates" + module_config: foreman_templates.yml foreman_leapp: name: "theforeman/foreman_leapp" manage_repo: true + hammer: + gem: hammer_cli_foreman_leapp + name: "theforeman/hammer-cli-foreman-leapp" + module_config: foreman_leapp.yml foreman_puppet: name: "theforeman/foreman_puppet" manage_repo: true + hammer: + gem: hammer_cli_foreman_puppet + name: "theforeman/hammer-cli-foreman-puppet" + module_config: foreman_puppet.yml foreman_development_default_plugins: - katello diff --git a/development/roles/foreman_development/tasks/hammer/main.yml b/development/roles/foreman_development/tasks/hammer/main.yml new file mode 100644 index 00000000..0c0c7ccb --- /dev/null +++ b/development/roles/foreman_development/tasks/hammer/main.yml @@ -0,0 +1,56 @@ +- name: Clone Hammer repository + ansible.builtin.git: + repo: "{{ foreman_development_hammer_git_repo }}" + dest: "{{ foreman_development_hammer_dir }}" + version: "{{ foreman_development_hammer_git_revision }}" + force: true + become: true + become_user: "{{ foreman_development_user }}" + +- name: Add GitHub username as additional remote for Foreman + community.general.git_config: + name: "remote.{{ foreman_development_github_username }}.url" + scope: local + repo: "{{ foreman_development_hammer_dir }}" + value: "git@github.com:{{ foreman_development_github_username }}/hammer-cli.git" + state: present + become: true + become_user: "{{ foreman_development_user }}" + when: foreman_development_github_username != "" + +- name: Setup hammer-cli-foreman + ansible.builtin.include_tasks: hammer/plugin.yml + vars: + foreman_development_plugin_name: "hammer_cli_foreman" + foreman_development_plugin_org: "theforeman" + foreman_development_plugin_repo_url: "https://github.com/theforeman/hammer-cli-foreman.git" + foreman_development_plugin_manage_repo: true + foreman_development_plugin_settings_template: "hammer/foreman.yml.j2" + foreman_development_plugin_extra_gemfiles: [] + +- name: Setup plugins + ansible.builtin.include_tasks: hammer/plugin.yml + vars: + foreman_development_plugin_config: "{{ (foreman_development_plugin_registry[plugin_item] | default({})).hammer | default({}) }}" + foreman_development_plugin_name: "{{ foreman_development_plugin_config.name.split('/')[1] }}" + foreman_development_plugin_gem: "{{ foreman_development_plugin_config.gem }}" + foreman_development_plugin_org: "{{ foreman_development_plugin_config.name.split('/')[0] }}" + foreman_development_plugin_repo_url: "https://github.com/{{ foreman_development_plugin_config.name }}.git" + foreman_development_plugin_manage_repo: "{{ foreman_development_plugin_config.manage_repo | default(true) }}" + foreman_development_plugin_settings_template: "{{ foreman_development_plugin_config.settings_template | default('') }}" + foreman_development_plugin_module_config: "{{ foreman_development_plugin_config.module_config | default('') }}" + foreman_development_plugin_extra_gemfiles: [] + when: foreman_development_plugin_config != {} + loop: "{{ foreman_development_default_plugins + foreman_development_enabled_plugins }}" + loop_control: + loop_var: plugin_item + +- name: Install Ruby dependencies + ansible.builtin.command: + cmd: bundle install --path .vendor --jobs 3 --without "libvirt:journald" + chdir: "{{ foreman_development_foreman_dir }}" + become: true + become_user: "{{ foreman_development_hammer_dir }}" + environment: + PATH: "/usr/bin:/bin:/usr/local/bin" + changed_when: true diff --git a/development/roles/foreman_development/tasks/hammer/plugin.yml b/development/roles/foreman_development/tasks/hammer/plugin.yml new file mode 100644 index 00000000..e758b063 --- /dev/null +++ b/development/roles/foreman_development/tasks/hammer/plugin.yml @@ -0,0 +1,59 @@ +--- +- name: Clone plugin repository # noqa latest[git] + ansible.builtin.git: + repo: "{{ foreman_development_plugin_repo_url }}" + dest: "{{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}" + force: true + become: true + become_user: "{{ foreman_development_user }}" + when: foreman_development_plugin_manage_repo + +- name: Add GitHub username as additional remote for plugin + community.general.git_config: + name: "remote.{{ foreman_development_github_username }}.url" + scope: local + repo: "{{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}" + value: "git@github.com:{{ foreman_development_github_username }}/{{ foreman_development_plugin_name }}.git" + state: present + become: true + become_user: "{{ foreman_development_user }}" + when: + - foreman_development_plugin_manage_repo + - foreman_development_github_username != "" + +- name: Create plugin settings file + ansible.builtin.template: + src: "{{ foreman_development_plugin_settings_template }}" + dest: "{{ foreman_development_hammer_dir }}/config/cli.modules.d/{{ foreman_development_plugin_settings_template.split('/')[1] | replace('.j2', '') }}" + owner: "{{ foreman_development_user }}" + group: "{{ foreman_development_group }}" + mode: "0644" + become: true + become_user: "{{ foreman_development_user }}" + when: foreman_development_plugin_settings_template != "" + +- name: Copy module config file + ansible.builtin.shell: | + cp {{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}/config/{{ foreman_development_plugin_module_config }} \ + {{ foreman_development_hammer_dir }}/config/cli.modules.d/{{ foreman_development_plugin_module_config }} + args: + creates: "{{ foreman_development_hammer_dir }}/config/cli.modules.d/{{ foreman_development_plugin_module_config }}" + become: true + become_user: "{{ foreman_development_user }}" + when: + - foreman_development_plugin_settings_template == "" + - foreman_development_plugin_module_config | default("") != "" + +- name: Create plugin bundler configuration + ansible.builtin.lineinfile: + line: >- + gem '{{ foreman_development_plugin_gem | default(foreman_development_plugin_name) }}', + path: '{{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}' + path: "{{ foreman_development_hammer_dir }}/Gemfile.local.rb" + create: true + state: present + regexp: "^\\s*gem '{{ foreman_development_plugin_name }}'" + mode: "0644" + become: true + become_user: "{{ foreman_development_user }}" + when: foreman_development_plugin_name != "" diff --git a/development/roles/foreman_development/tasks/main.yaml b/development/roles/foreman_development/tasks/main.yaml index 340185ed..46327ac7 100644 --- a/development/roles/foreman_development/tasks/main.yaml +++ b/development/roles/foreman_development/tasks/main.yaml @@ -250,3 +250,8 @@ name: foreman-development state: stopped enabled: false + +- name: Configure hammer for development + ansible.builtin.include_tasks: hammer/main.yml + when: + - "'hammer' in enabled_features" diff --git a/development/roles/foreman_development/templates/hammer/foreman.yml.j2 b/development/roles/foreman_development/templates/hammer/foreman.yml.j2 new file mode 100644 index 00000000..71c1efab --- /dev/null +++ b/development/roles/foreman_development/templates/hammer/foreman.yml.j2 @@ -0,0 +1,55 @@ +:foreman: + # Enable/disable foreman commands + :enable_module: true + + # Your foreman server address + # For development try using http with the fully domain name. + :host: '{{ ansible_facts['fqdn'] }}' + + # Credentials. You'll be asked for them interactively if you leave them blank here + # Possible values: + + # Basic Auth: + #:default_auth_type: 'Basic_Auth' + :username: '{{ foreman_development_admin_user }}' + :password: '{{ foreman_development_admin_password }}' + + # Basic Auth External: + #:default_auth_type: 'Basic_Auth_External' + #:username: 'admin' + #:password: 'example' + + # Oauth using the Password Grant Flow: + # This authentication method requires sessions to be enabled, uncomment the following + # lines to use this authentication method. + #:default_auth_type: 'Oauth_Password_Grant' + #:oidc_token_endpoint: https://keycloak.example.com/token + #:oidc_client_id: example-client-id + + # Oauth using Authentication Code Flow(Two Factor): + # This authentication method requires sessions to be enabled, uncomment the following + # lines to use this authentication method. + #:default_auth_type: 'Oauth_Authentication_Code_Grant' + #:oidc_token_endpoint: https://keycloak.example.com/token + #:oidc_authorization_endpoint: https://keycloak.example.com/auth + #:oidc_client_id: example-client-id + #:oidc_redirect_uri: urn:ietf:wg:oauth:2.0:oob + + # Negotiate (Kerberos) Auth: + # User needs to run kinit before using hammer (or initiate kerberos keyring in another way). + #:default_auth_type: 'Negotiate_Auth' + + # Enable using sessions + # When sessions are enabled, hammer ignores credentials stored in the config file + # and asks for them interactively at the begining of each session. + :use_sessions: false + + # Check API documentation cache status on each request + #:refresh_cache: false + + # API request timeout. Set to -1 for no timeout + #:request_timeout: 120 #seconds + + # Follow API redirects. One of :never, :default, :always + # Value :default means RestClient default behaviour - follow only in GET and HEAD requests + #:follow_redirects: :never From 327e959531340751338b2aa2d3efd629dff70224 Mon Sep 17 00:00:00 2001 From: Adam Ruzicka Date: Fri, 13 Feb 2026 13:12:57 +0100 Subject: [PATCH 02/10] Deploy smart-proxy for development --- .../foreman_development/defaults/main.yaml | 22 +++++ .../roles/foreman_development/tasks/main.yaml | 5 ++ .../tasks/smart-proxy/main.yml | 58 +++++++++++++ .../tasks/smart-proxy/plugin.yml | 66 +++++++++++++++ .../plugin/smart_proxy_ansible.yml | 28 +++++++ .../plugin/smart_proxy_openscap.yml | 4 + .../smart_proxy_remote_execution_ssh.yml | 6 ++ .../templates/smart-proxy/settings.yml.j2 | 84 +++++++++++++++++++ 8 files changed, 273 insertions(+) create mode 100644 development/roles/foreman_development/tasks/smart-proxy/main.yml create mode 100644 development/roles/foreman_development/tasks/smart-proxy/plugin.yml create mode 100644 development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_ansible.yml create mode 100644 development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_openscap.yml create mode 100644 development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_remote_execution_ssh.yml create mode 100644 development/roles/foreman_development/templates/smart-proxy/settings.yml.j2 diff --git a/development/roles/foreman_development/defaults/main.yaml b/development/roles/foreman_development/defaults/main.yaml index 9a24f037..b8c8dc90 100644 --- a/development/roles/foreman_development/defaults/main.yaml +++ b/development/roles/foreman_development/defaults/main.yaml @@ -5,6 +5,7 @@ foreman_development_deployment_dir: "/home/{{ foreman_development_user }}" foreman_development_foreman_dir: "{{ foreman_development_deployment_dir }}/foreman" foreman_development_cert_dir: "{{ foreman_development_deployment_dir }}/foreman-certs" foreman_development_hammer_dir: "{{ foreman_development_deployment_dir }}/hammer-cli" +foreman_development_smart_proxy_dir: "{{ foreman_development_deployment_dir }}/smart-proxy" foreman_development_ca_certificate: "{{ foreman_ca_certificate }}" foreman_development_client_certificate: "{{ foreman_client_certificate }}" @@ -20,6 +21,9 @@ foreman_development_github_username: "" foreman_development_hammer_git_repo: "https://github.com/theforeman/hammer-cli.git" foreman_development_hammer_git_revision: "master" +foreman_development_smart_proxy_git_repo: "https://github.com/theforeman/smart-proxy.git" +foreman_development_smart_proxy_git_revision: "develop" + foreman_development_rails_port: 3000 foreman_development_rails_command: "puma -w 2 -p {{ foreman_development_rails_port }} --preload -b tcp://0.0.0.0" @@ -50,6 +54,9 @@ foreman_development_plugin_registry: hammer: name: "theforeman/hammer_cli_foreman_remote_execution" module_config: foreman_remote_execution.yml + smart_proxy: + name: "theforeman/smart_proxy_remote_execution_ssh" + module_config: remote_execution_ssh.yml foreman_ansible: name: "theforeman/foreman_ansible" settings_template: "foreman_ansible.yaml.j2" @@ -58,6 +65,9 @@ foreman_development_plugin_registry: gem: hammer_cli_foreman_ansible name: "theforeman/hammer-cli-foreman-ansible" module_config: foreman_ansible.yml + smart_proxy: + name: "theforeman/smart_proxy_ansible" + module_config: ansible.yml foreman_rh_cloud: name: "theforeman/foreman_rh_cloud" manage_repo: true @@ -72,12 +82,18 @@ foreman_development_plugin_registry: gem: hammer_cli_foreman_discovery name: "theforeman/hammer-cli-foreman-discovery" module_config: foreman_discovery.yml + smart_proxy: + name: "theforeman/smart_proxy_discovery" + module_config: discovery.yml foreman_openscap: name: "theforeman/foreman_openscap" manage_repo: true hammer: name: "theforeman/hammer_cli_foreman_openscap" module_config: foreman_openscap.yml + smart_proxy: + name: "theforeman/smart_proxy_openscap" + module_config: openscap.yml foreman_bootdisk: name: "theforeman/foreman_bootdisk" manage_repo: true @@ -94,6 +110,9 @@ foreman_development_plugin_registry: gem: hammer_cli_foreman_tasks name: "theforeman/hammer-cli-foreman-tasks" module_config: foreman_tasks.yml + smart_proxy: + name: "theforeman/smart_proxy_dynflow" + module_config: dynflow.yml foreman_webhooks: name: "theforeman/foreman_webhooks" manage_repo: true @@ -101,6 +120,9 @@ foreman_development_plugin_registry: gem: hammer_cli_foreman_webhooks name: "theforeman/hammer-cli-foreman-webhooks" module_config: foreman_webhooks.yml + smart_proxy: + name: "theforeman/smart_proxy_shellhooks" + module_config: shellhooks.yml foreman_templates: name: "theforeman/foreman_templates" manage_repo: true diff --git a/development/roles/foreman_development/tasks/main.yaml b/development/roles/foreman_development/tasks/main.yaml index 46327ac7..77542b60 100644 --- a/development/roles/foreman_development/tasks/main.yaml +++ b/development/roles/foreman_development/tasks/main.yaml @@ -251,6 +251,11 @@ state: stopped enabled: false +- name: Configure smart-proxy for development + ansible.builtin.include_tasks: smart-proxy/main.yml + when: + - "'foreman-proxy' in enabled_features" + - name: Configure hammer for development ansible.builtin.include_tasks: hammer/main.yml when: diff --git a/development/roles/foreman_development/tasks/smart-proxy/main.yml b/development/roles/foreman_development/tasks/smart-proxy/main.yml new file mode 100644 index 00000000..1250e76f --- /dev/null +++ b/development/roles/foreman_development/tasks/smart-proxy/main.yml @@ -0,0 +1,58 @@ +--- +- name: Clone smart-proxy repository + ansible.builtin.git: + repo: "{{ foreman_development_smart_proxy_git_repo }}" + dest: "{{ foreman_development_smart_proxy_dir }}" + version: "{{ foreman_development_smart_proxy_git_revision }}" + force: true + become: true + become_user: "{{ foreman_development_user }}" + +- name: Add GitHub username as additional remote for smart-proxy + community.general.git_config: + name: "remote.{{ foreman_development_github_username }}.url" + scope: local + repo: "{{ foreman_development_smart_proxy_dir }}" + value: "git@github.com:{{ foreman_development_github_username }}/smart-proxy.git" + state: present + become: true + become_user: "{{ foreman_development_user }}" + when: foreman_development_github_username != "" + +- name: Create smart-proxy settings.d file from template + ansible.builtin.template: + src: "smart-proxy/settings.yml.j2" + dest: "{{ foreman_development_smart_proxy_dir }}/config/settings.yml" + owner: "{{ foreman_development_user }}" + group: "{{ foreman_development_group }}" + mode: "0644" + become: true + become_user: "{{ foreman_development_user }}" + +- name: Setup smart-proxy plugins + ansible.builtin.include_tasks: smart-proxy/plugin.yml + vars: + foreman_development_plugin_config: "{{ (foreman_development_plugin_registry[plugin_item] | default({})).smart_proxy | default({}) }}" + foreman_development_plugin_name: "{{ foreman_development_plugin_config.name.split('/')[1] }}" + foreman_development_plugin_gem: "{{ foreman_development_plugin_config.gem | default(foreman_development_plugin_config.name.split('/')[1]) }}" + foreman_development_plugin_org: "{{ foreman_development_plugin_config.name.split('/')[0] }}" + foreman_development_plugin_repo_url: "https://github.com/{{ foreman_development_plugin_config.name }}.git" + foreman_development_plugin_manage_repo: "{{ foreman_development_plugin_config.manage_repo | default(true) }}" + foreman_development_plugin_settings_template: "{{ foreman_development_plugin_config.settings_template | default('') }}" + foreman_development_plugin_module_config: "{{ foreman_development_plugin_config.module_config | default('') }}" + foreman_development_plugin_bundler_path_prefix: "../../" + foreman_development_plugin_extra_gemfiles: [] + when: foreman_development_plugin_config != {} + loop: "{{ foreman_development_default_plugins + foreman_development_enabled_plugins }}" + loop_control: + loop_var: plugin_item + +- name: Install smart-proxy Ruby dependencies + ansible.builtin.command: + cmd: bundle install --path .vendor --jobs 3 + chdir: "{{ foreman_development_smart_proxy_dir }}" + become: true + become_user: "{{ foreman_development_user }}" + environment: + PATH: "/usr/bin:/bin:/usr/local/bin" + changed_when: true diff --git a/development/roles/foreman_development/tasks/smart-proxy/plugin.yml b/development/roles/foreman_development/tasks/smart-proxy/plugin.yml new file mode 100644 index 00000000..f32de0e3 --- /dev/null +++ b/development/roles/foreman_development/tasks/smart-proxy/plugin.yml @@ -0,0 +1,66 @@ +--- +- name: Clone smart-proxy plugin repository # noqa latest[git] + ansible.builtin.git: + repo: "{{ foreman_development_plugin_repo_url }}" + dest: "{{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}" + force: true + become: true + become_user: "{{ foreman_development_user }}" + when: foreman_development_plugin_manage_repo + +- name: Add GitHub username as additional remote for smart-proxy plugin + community.general.git_config: + name: "remote.{{ foreman_development_github_username }}.url" + scope: local + repo: "{{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}" + value: "git@github.com:{{ foreman_development_github_username }}/{{ foreman_development_plugin_name }}.git" + state: present + become: true + become_user: "{{ foreman_development_user }}" + when: + - foreman_development_plugin_manage_repo + - foreman_development_github_username != "" + +- name: Create smart-proxy plugin settings file from template + ansible.builtin.template: + src: "{{ foreman_development_plugin_settings_template }}" + dest: "{{ foreman_development_smart_proxy_dir }}/config/settings.d/{{ foreman_development_plugin_settings_template.split('/')[-1] | replace('.j2', '') }}" + owner: "{{ foreman_development_user }}" + group: "{{ foreman_development_group }}" + mode: "0644" + become: true + become_user: "{{ foreman_development_user }}" + when: foreman_development_plugin_settings_template != "" + +- name: Copy smart-proxy plugin settings from repository settings.d + ansible.builtin.copy: + src: "{{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}/settings.d/{{ foreman_development_plugin_module_config }}.example" + dest: "{{ foreman_development_smart_proxy_dir }}/config/settings.d/{{ foreman_development_plugin_module_config }}" + remote_src: true + owner: "{{ foreman_development_user }}" + group: "{{ foreman_development_group }}" + mode: "0644" + become: true + become_user: "{{ foreman_development_user }}" + when: + - foreman_development_plugin_settings_template == "" + - foreman_development_plugin_module_config != "" + +- name: Create smart-proxy plugin bundler configuration + ansible.builtin.copy: + content: | + gem '{{ foreman_development_plugin_gem }}', path: '{{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}' + dest: "{{ foreman_development_smart_proxy_dir }}/bundler.d/{{ foreman_development_plugin_name }}.local.rb" + owner: "{{ foreman_development_user }}" + group: "{{ foreman_development_group }}" + mode: "0644" + become: true + become_user: "{{ foreman_development_user }}" + when: foreman_development_plugin_name != "" + +- name: Run plugin-specific tasks + ansible.builtin.include_tasks: "{{ item }}" + with_fileglob: + - "smart-proxy/plugin/{{ foreman_development_plugin_name }}.yml" + when: + - foreman_development_plugin_name != "" diff --git a/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_ansible.yml b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_ansible.yml new file mode 100644 index 00000000..72816a77 --- /dev/null +++ b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_ansible.yml @@ -0,0 +1,28 @@ +- name: Ensure ~/.foreman-ansible directory exists + ansible.builtin.file: + path: "{{ foreman_development_deployment_dir }}/.foreman-ansible" + state: directory + owner: "{{ foreman_development_user }}" + group: "{{ foreman_development_group }}" + mode: "0750" + +- name: Ensure /usr/libexec/foreman-proxy directory exists + ansible.builtin.file: + path: /usr/libexec/foreman-proxy + state: directory + owner: "{{ foreman_development_user }}" + group: "{{ foreman_development_group }}" + mode: "0755" + +- name: Copy ansible-runner-environment + ansible.builtin.copy: + src: "{{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}/bin/ansible-runner-environment.sh" + dest: "/usr/libexec/foreman-proxy/ansible-runner-environment" + remote_src: true + owner: "{{ foreman_development_user }}" + group: "{{ foreman_development_group }}" + mode: "0555" + +# To make config reports from ansible to work: +# TODO: Deploy ansible.env somewhere, see https://github.com/theforeman/puppet-foreman_proxy/blob/master/templates/plugin/ansible.env.erb for reference +# TODO: Adjust ansible.yml to point to the deployed ansible.env diff --git a/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_openscap.yml b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_openscap.yml new file mode 100644 index 00000000..a75976b5 --- /dev/null +++ b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_openscap.yml @@ -0,0 +1,4 @@ +- name: Install openscap-scanner + ansible.builtin.package: + name: openscap-scanner + state: present diff --git a/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_remote_execution_ssh.yml b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_remote_execution_ssh.yml new file mode 100644 index 00000000..b3ee833d --- /dev/null +++ b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_remote_execution_ssh.yml @@ -0,0 +1,6 @@ +- name: Run ssh keygen to generate ~/.ssh/id_rsa_foreman_proxy unless it exists + ansible.builtin.command: + cmd: ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_foreman_proxy -N '' + creates: "{{ foreman_development_deployment_dir }}/.ssh/id_rsa_foreman_proxy" + become: true + become_user: "{{ foreman_development_user }}" diff --git a/development/roles/foreman_development/templates/smart-proxy/settings.yml.j2 b/development/roles/foreman_development/templates/smart-proxy/settings.yml.j2 new file mode 100644 index 00000000..475256b3 --- /dev/null +++ b/development/roles/foreman_development/templates/smart-proxy/settings.yml.j2 @@ -0,0 +1,84 @@ +--- +# SSL Setup +# If enabled, all communication would be verified via SSL +# NOTE that both certificates need to be signed by the same CA in order for this to work +# see http://theforeman.org/projects/smart-proxy/wiki/SSL for more information +:ssl_certificate: {{ foreman_development_cert_dir }}/client_cert.pem +:ssl_ca_file: {{ foreman_development_cert_dir }}/proxy_ca.pem +:ssl_private_key: {{ foreman_development_cert_dir }}/client_key.pem + +# Use this option only if you need to disable certain cipher suites. +# Note: we use the OpenSSL suite name, such as "RC4-MD5". +# The complete list of cipher suite names can be found at: +# https://www.openssl.org/docs/manmaster/man1/ciphers.html#CIPHER-SUITE-NAMES +#:ssl_disabled_ciphers: [CIPHER-SUITE-1, CIPHER-SUITE-2] + +# Use this option only if you need to strictly specify TLS versions to be +# disabled. SSLv3 and TLS v1.0 are always disabled and cannot be configured. +# Specify versions like: '1.1', or '1.2' +#:tls_disabled_versions: [] + +# Hosts which the proxy accepts connections from +# commenting the following lines would mean every verified SSL connection allowed +# HTTPS: test the certificate CN +# HTTP: test the reverse DNS entry of the remote IP +#:trusted_hosts: +#- foreman.prod.domain +#- foreman.dev.domain +#to deny access to all hosts use: +#:trusted_hosts: [] + +# verify a DNS reverse lookup against it's forward lookup +# 1.1.1.1 -> foreman.mycompany.com -> 1.1.1.1 +# (default: true) +#:forward_verify: true + +#:foreman_url: http://127.0.0.1:3000 + +:foreman_url: https://{{ ansible_facts['fqdn'] }} + +# SSL settings for client authentication against Foreman. If undefined, the values +# from general SSL options are used instead. Mainly useful when Foreman uses +# different certificates for its web UI and for smart-proxy requests. +#:foreman_ssl_ca: ssl/certs/ca.pem +#:foreman_ssl_cert: ssl/certs/fqdn.pem +#:foreman_ssl_key: ssl/private_keys/fqdn.pem + +# host and ports configuration +# an array of interfaces to bind ports to (possible values: *, localhost, 0.0.0.0) +#:bind_host: ['*'] +# http is disabled by default. To enable, uncomment 'http_port' setting +:http_port: 8000 +# https is enabled if certificate, CA certificate, and private key are present in locations specifed by +# ssl_certificate, ssl_ca_file, and ssl_private_key correspondingly +# default values for https_port is 8443 +:https_port: 8443 + +# Log configuration +# Uncomment and modify if you want to change the location of the log file or use STDOUT, SYSLOG or JOURNAL values +#:log_file: /var/log/foreman-proxy/proxy.log +# Uncomment and modify if you want to change the log level +# WARN, DEBUG, ERROR, FATAL, INFO, UNKNOWN +#:log_level: INFO +# The maximum size of a log file before it's rolled (in MiB) or zero to use external log rotation (default) +#:file_rolling_size: 0 +# The maximum age of a log file before it's rolled (in seconds). Also accepts 'daily', 'weekly', or 'monthly'. +#:file_rolling_age: weekly +# Number of log files to keep +#:file_rolling_keep: 6 +# Logging pattern for file-based loging +#:file_logging_pattern: '%d %.8X{request} [%.1l] %m' +# Logging pattern for syslog or journal loging +#:system_logging_pattern: '%m' + +# Log buffer size and extra buffer size (for errors). Defaults to 3000 messages in total, +# which is about 500 kB request. +#:log_buffer: 2000 +#:log_buffer_errors: 1000 + +# DNS resolver timeout(s). This may be a single positive number +# or an array of positive numbers representing timeouts in seconds. +# If an array is specified, a DNS request will retry and wait for +# each successive interval in the array until a successful response +# is received. See Ruby Resolv#timeouts documentation for more info. +#:dns_resolv_timeouts: [5, 8, 13] From 92ae16dd350560658eb751c827594c54c965740b Mon Sep 17 00:00:00 2001 From: Adam Ruzicka Date: Fri, 13 Feb 2026 17:15:46 +0100 Subject: [PATCH 03/10] Replace symlink with reduced copy --- development/playbooks/_flavor_features | 1 - development/playbooks/_flavor_features/metadata.obsah.yaml | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) delete mode 100644 development/playbooks/_flavor_features create mode 100644 development/playbooks/_flavor_features/metadata.obsah.yaml diff --git a/development/playbooks/_flavor_features b/development/playbooks/_flavor_features deleted file mode 100644 index 151fa7f5..00000000 --- a/development/playbooks/_flavor_features +++ /dev/null @@ -1 +0,0 @@ -../../src/playbooks/_flavor_features \ No newline at end of file diff --git a/development/playbooks/_flavor_features/metadata.obsah.yaml b/development/playbooks/_flavor_features/metadata.obsah.yaml new file mode 100644 index 00000000..d40913a1 --- /dev/null +++ b/development/playbooks/_flavor_features/metadata.obsah.yaml @@ -0,0 +1,6 @@ +--- +variables: + features: + parameter: --add-feature + help: Additional features to enable in this deployment. + action: append_unique From bb54d9fdc37768c3f09b896ee255157f5f88363d Mon Sep 17 00:00:00 2001 From: Adam Ruzicka Date: Mon, 16 Feb 2026 14:16:59 +0100 Subject: [PATCH 04/10] Address comments - drop --without for hammer when installing ruby dependencies - pull in development headers --- .../foreman_development/tasks/hammer/main.yml | 2 +- .../foreman_development/tasks/smart-proxy/main.yml | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/development/roles/foreman_development/tasks/hammer/main.yml b/development/roles/foreman_development/tasks/hammer/main.yml index 0c0c7ccb..c38742d4 100644 --- a/development/roles/foreman_development/tasks/hammer/main.yml +++ b/development/roles/foreman_development/tasks/hammer/main.yml @@ -47,7 +47,7 @@ - name: Install Ruby dependencies ansible.builtin.command: - cmd: bundle install --path .vendor --jobs 3 --without "libvirt:journald" + cmd: bundle install --path .vendor --jobs 3 chdir: "{{ foreman_development_foreman_dir }}" become: true become_user: "{{ foreman_development_hammer_dir }}" diff --git a/development/roles/foreman_development/tasks/smart-proxy/main.yml b/development/roles/foreman_development/tasks/smart-proxy/main.yml index 1250e76f..08e9f0c6 100644 --- a/development/roles/foreman_development/tasks/smart-proxy/main.yml +++ b/development/roles/foreman_development/tasks/smart-proxy/main.yml @@ -47,6 +47,20 @@ loop_control: loop_var: plugin_item +- name: Ensure the crb repository is enabled + community.general.dnf_config_manager: + name: crb + state: enabled + +- name: Install smart-proxy dependencies + ansible.builtin.package: + name: + - libvirt-devel + - krb5-devel + - libyaml-devel + - systemd-devel + state: present + - name: Install smart-proxy Ruby dependencies ansible.builtin.command: cmd: bundle install --path .vendor --jobs 3 From 1877167fe5026aa2099254ca6e9d95369576f46a Mon Sep 17 00:00:00 2001 From: Adam Ruzicka Date: Mon, 16 Feb 2026 17:15:03 +0100 Subject: [PATCH 05/10] Deploy right certs with right permissions --- .../tasks/smart-proxy/main.yml | 22 +++++++++++++++++++ .../templates/smart-proxy/settings.yml.j2 | 6 ++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/development/roles/foreman_development/tasks/smart-proxy/main.yml b/development/roles/foreman_development/tasks/smart-proxy/main.yml index 08e9f0c6..c82b9523 100644 --- a/development/roles/foreman_development/tasks/smart-proxy/main.yml +++ b/development/roles/foreman_development/tasks/smart-proxy/main.yml @@ -19,6 +19,28 @@ become_user: "{{ foreman_development_user }}" when: foreman_development_github_username != "" +- name: Create cert directories + ansible.builtin.file: + path: "{{ foreman_development_cert_dir }}/smart-proxy" + state: directory + mode: "0750" + owner: "{{ foreman_development_user }}" + +- name: Deploy certificates + ansible.builtin.copy: + src: "{{ item.src }}" + dest: "{{ foreman_development_cert_dir }}/smart-proxy/{{ item.dest }}" + remote_src: true + mode: "0640" + owner: "{{ foreman_development_user }}" + loop: + - src: "{{ httpd_server_ca_certificate }}" + dest: "ca.crt" + - src: "{{ httpd_server_certificate }}" + dest: "proxy.crt" + - src: "{{ httpd_server_key }}" + dest: "proxy.key" + - name: Create smart-proxy settings.d file from template ansible.builtin.template: src: "smart-proxy/settings.yml.j2" diff --git a/development/roles/foreman_development/templates/smart-proxy/settings.yml.j2 b/development/roles/foreman_development/templates/smart-proxy/settings.yml.j2 index 475256b3..79878e9a 100644 --- a/development/roles/foreman_development/templates/smart-proxy/settings.yml.j2 +++ b/development/roles/foreman_development/templates/smart-proxy/settings.yml.j2 @@ -3,9 +3,9 @@ # If enabled, all communication would be verified via SSL # NOTE that both certificates need to be signed by the same CA in order for this to work # see http://theforeman.org/projects/smart-proxy/wiki/SSL for more information -:ssl_certificate: {{ foreman_development_cert_dir }}/client_cert.pem -:ssl_ca_file: {{ foreman_development_cert_dir }}/proxy_ca.pem -:ssl_private_key: {{ foreman_development_cert_dir }}/client_key.pem +:ssl_certificate: {{ foreman_development_cert_dir }}/smart-proxy/proxy.crt +:ssl_ca_file: {{ foreman_development_cert_dir }}/smart-proxy/ca.crt +:ssl_private_key: {{ foreman_development_cert_dir }}/smart-proxy/proxy.key # Use this option only if you need to disable certain cipher suites. # Note: we use the OpenSSL suite name, such as "RC4-MD5". From f00e832c8c324dbace7b321b8f6740115e286cff Mon Sep 17 00:00:00 2001 From: Adam Ruzicka Date: Tue, 17 Feb 2026 14:26:29 +0100 Subject: [PATCH 06/10] Fix dir and user for hammer bundle --- development/roles/foreman_development/tasks/hammer/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/development/roles/foreman_development/tasks/hammer/main.yml b/development/roles/foreman_development/tasks/hammer/main.yml index c38742d4..6659aed3 100644 --- a/development/roles/foreman_development/tasks/hammer/main.yml +++ b/development/roles/foreman_development/tasks/hammer/main.yml @@ -48,9 +48,9 @@ - name: Install Ruby dependencies ansible.builtin.command: cmd: bundle install --path .vendor --jobs 3 - chdir: "{{ foreman_development_foreman_dir }}" + chdir: "{{ foreman_development_hammer_dir }}" become: true - become_user: "{{ foreman_development_hammer_dir }}" + become_user: "{{ foreman_development_user }}" environment: PATH: "/usr/bin:/bin:/usr/local/bin" changed_when: true From 123fd20c48e3068d352a1cfd17512c7c959b4df9 Mon Sep 17 00:00:00 2001 From: Adam Ruzicka Date: Wed, 18 Feb 2026 11:07:20 +0100 Subject: [PATCH 07/10] Fix rex key generation in some odd cases --- .../plugin/smart_proxy_remote_execution_ssh.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_remote_execution_ssh.yml b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_remote_execution_ssh.yml index b3ee833d..6ae25ab2 100644 --- a/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_remote_execution_ssh.yml +++ b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_remote_execution_ssh.yml @@ -1,6 +1,17 @@ -- name: Run ssh keygen to generate ~/.ssh/id_rsa_foreman_proxy unless it exists +- name: Ensure {{ foreman_development_deployment_dir }}/.ssh directory exists with correct permissions + ansible.builtin.file: + path: "{{ foreman_development_deployment_dir }}/.ssh" + state: directory + owner: "{{ foreman_development_user }}" + group: "{{ foreman_development_group }}" + mode: "0700" + become: true + become_user: "{{ foreman_development_user }}" + + +- name: Run ssh keygen to generate {{ foreman_development_deployment_dir }}/.ssh/id_rsa_foreman_proxy unless it exists ansible.builtin.command: - cmd: ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_foreman_proxy -N '' + cmd: ssh-keygen -t rsa -b 4096 -f {{ foreman_development_deployment_dir }}//.ssh/id_rsa_foreman_proxy -N '' creates: "{{ foreman_development_deployment_dir }}/.ssh/id_rsa_foreman_proxy" become: true become_user: "{{ foreman_development_user }}" From 4fe65d7ee6bc9c63a1867167c775fddd2222474d Mon Sep 17 00:00:00 2001 From: Adam Ruzicka Date: Wed, 18 Feb 2026 11:14:02 +0100 Subject: [PATCH 08/10] Indicate what plugin is being set up --- .../foreman_development/tasks/hammer/plugin.yml | 10 +++++----- .../foreman_development/tasks/smart-proxy/plugin.yml | 12 ++++++------ .../tasks/smart-proxy/plugin/smart_proxy_ansible.yml | 6 +++--- .../smart-proxy/plugin/smart_proxy_openscap.yml | 2 +- .../plugin/smart_proxy_remote_execution_ssh.yml | 5 ++--- 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/development/roles/foreman_development/tasks/hammer/plugin.yml b/development/roles/foreman_development/tasks/hammer/plugin.yml index e758b063..0e307010 100644 --- a/development/roles/foreman_development/tasks/hammer/plugin.yml +++ b/development/roles/foreman_development/tasks/hammer/plugin.yml @@ -1,5 +1,5 @@ --- -- name: Clone plugin repository # noqa latest[git] +- name: "Clone plugin repository for {{ foreman_development_plugin_name }}" # noqa latest[git] ansible.builtin.git: repo: "{{ foreman_development_plugin_repo_url }}" dest: "{{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}" @@ -8,7 +8,7 @@ become_user: "{{ foreman_development_user }}" when: foreman_development_plugin_manage_repo -- name: Add GitHub username as additional remote for plugin +- name: "Add GitHub username as additional remote for {{ foreman_development_plugin_name }}" community.general.git_config: name: "remote.{{ foreman_development_github_username }}.url" scope: local @@ -21,7 +21,7 @@ - foreman_development_plugin_manage_repo - foreman_development_github_username != "" -- name: Create plugin settings file +- name: "Create settings file for {{ foreman_development_plugin_name }}" ansible.builtin.template: src: "{{ foreman_development_plugin_settings_template }}" dest: "{{ foreman_development_hammer_dir }}/config/cli.modules.d/{{ foreman_development_plugin_settings_template.split('/')[1] | replace('.j2', '') }}" @@ -32,7 +32,7 @@ become_user: "{{ foreman_development_user }}" when: foreman_development_plugin_settings_template != "" -- name: Copy module config file +- name: "Copy module config file for {{ foreman_development_plugin_name }}" ansible.builtin.shell: | cp {{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}/config/{{ foreman_development_plugin_module_config }} \ {{ foreman_development_hammer_dir }}/config/cli.modules.d/{{ foreman_development_plugin_module_config }} @@ -44,7 +44,7 @@ - foreman_development_plugin_settings_template == "" - foreman_development_plugin_module_config | default("") != "" -- name: Create plugin bundler configuration +- name: "Create bundler configuration for {{ foreman_development_plugin_name }}" ansible.builtin.lineinfile: line: >- gem '{{ foreman_development_plugin_gem | default(foreman_development_plugin_name) }}', diff --git a/development/roles/foreman_development/tasks/smart-proxy/plugin.yml b/development/roles/foreman_development/tasks/smart-proxy/plugin.yml index f32de0e3..92c32d7f 100644 --- a/development/roles/foreman_development/tasks/smart-proxy/plugin.yml +++ b/development/roles/foreman_development/tasks/smart-proxy/plugin.yml @@ -1,5 +1,5 @@ --- -- name: Clone smart-proxy plugin repository # noqa latest[git] +- name: "Clone smart-proxy plugin repository for {{ foreman_development_plugin_name }}" # noqa latest[git] ansible.builtin.git: repo: "{{ foreman_development_plugin_repo_url }}" dest: "{{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}" @@ -8,7 +8,7 @@ become_user: "{{ foreman_development_user }}" when: foreman_development_plugin_manage_repo -- name: Add GitHub username as additional remote for smart-proxy plugin +- name: "Add GitHub username as additional remote for {{ foreman_development_plugin_name }}" community.general.git_config: name: "remote.{{ foreman_development_github_username }}.url" scope: local @@ -21,7 +21,7 @@ - foreman_development_plugin_manage_repo - foreman_development_github_username != "" -- name: Create smart-proxy plugin settings file from template +- name: "Create settings file for {{ foreman_development_plugin_name }}" ansible.builtin.template: src: "{{ foreman_development_plugin_settings_template }}" dest: "{{ foreman_development_smart_proxy_dir }}/config/settings.d/{{ foreman_development_plugin_settings_template.split('/')[-1] | replace('.j2', '') }}" @@ -32,7 +32,7 @@ become_user: "{{ foreman_development_user }}" when: foreman_development_plugin_settings_template != "" -- name: Copy smart-proxy plugin settings from repository settings.d +- name: "Copy smart-proxy plugin settings from repository settings.d for {{ foreman_development_plugin_name }}" ansible.builtin.copy: src: "{{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}/settings.d/{{ foreman_development_plugin_module_config }}.example" dest: "{{ foreman_development_smart_proxy_dir }}/config/settings.d/{{ foreman_development_plugin_module_config }}" @@ -46,7 +46,7 @@ - foreman_development_plugin_settings_template == "" - foreman_development_plugin_module_config != "" -- name: Create smart-proxy plugin bundler configuration +- name: "Create bundler configuration for {{ foreman_development_plugin_name }}" ansible.builtin.copy: content: | gem '{{ foreman_development_plugin_gem }}', path: '{{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}' @@ -58,7 +58,7 @@ become_user: "{{ foreman_development_user }}" when: foreman_development_plugin_name != "" -- name: Run plugin-specific tasks +- name: "Run plugin-specific tasks for {{ foreman_development_plugin_name }}" ansible.builtin.include_tasks: "{{ item }}" with_fileglob: - "smart-proxy/plugin/{{ foreman_development_plugin_name }}.yml" diff --git a/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_ansible.yml b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_ansible.yml index 72816a77..2ba6320c 100644 --- a/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_ansible.yml +++ b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_ansible.yml @@ -1,4 +1,4 @@ -- name: Ensure ~/.foreman-ansible directory exists +- name: "Ensure ~/.foreman-ansible directory exists for {{ foreman_development_plugin_name }}" ansible.builtin.file: path: "{{ foreman_development_deployment_dir }}/.foreman-ansible" state: directory @@ -6,7 +6,7 @@ group: "{{ foreman_development_group }}" mode: "0750" -- name: Ensure /usr/libexec/foreman-proxy directory exists +- name: "Ensure /usr/libexec/foreman-proxy directory exists for {{ foreman_development_plugin_name }}" ansible.builtin.file: path: /usr/libexec/foreman-proxy state: directory @@ -14,7 +14,7 @@ group: "{{ foreman_development_group }}" mode: "0755" -- name: Copy ansible-runner-environment +- name: "Copy ansible-runner-environment for {{ foreman_development_plugin_name }}" ansible.builtin.copy: src: "{{ foreman_development_deployment_dir }}/{{ foreman_development_plugin_name }}/bin/ansible-runner-environment.sh" dest: "/usr/libexec/foreman-proxy/ansible-runner-environment" diff --git a/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_openscap.yml b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_openscap.yml index a75976b5..c7c897cc 100644 --- a/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_openscap.yml +++ b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_openscap.yml @@ -1,4 +1,4 @@ -- name: Install openscap-scanner +- name: "Install openscap-scanner for {{ foreman_development_plugin_name }}" ansible.builtin.package: name: openscap-scanner state: present diff --git a/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_remote_execution_ssh.yml b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_remote_execution_ssh.yml index 6ae25ab2..287f3279 100644 --- a/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_remote_execution_ssh.yml +++ b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_remote_execution_ssh.yml @@ -1,4 +1,4 @@ -- name: Ensure {{ foreman_development_deployment_dir }}/.ssh directory exists with correct permissions +- name: "Ensure ~/.ssh directory exists with correct permissions for {{ foreman_development_plugin_name }}" ansible.builtin.file: path: "{{ foreman_development_deployment_dir }}/.ssh" state: directory @@ -8,8 +8,7 @@ become: true become_user: "{{ foreman_development_user }}" - -- name: Run ssh keygen to generate {{ foreman_development_deployment_dir }}/.ssh/id_rsa_foreman_proxy unless it exists +- name: "Run ssh keygen to generate ~/.ssh/id_rsa_foreman_proxy unless it exists for {{ foreman_development_plugin_name }}" ansible.builtin.command: cmd: ssh-keygen -t rsa -b 4096 -f {{ foreman_development_deployment_dir }}//.ssh/id_rsa_foreman_proxy -N '' creates: "{{ foreman_development_deployment_dir }}/.ssh/id_rsa_foreman_proxy" From 3eccf1a9ce0d4ddb4c58c938562a819b49bc51d9 Mon Sep 17 00:00:00 2001 From: Adam Ruzicka Date: Wed, 18 Feb 2026 11:14:58 +0100 Subject: [PATCH 09/10] Register the development smart proxy --- .../tasks/smart-proxy/main.yml | 57 +++++++++++++++++++ .../smart-proxy-development.service.j2 | 14 +++++ 2 files changed, 71 insertions(+) create mode 100644 development/roles/foreman_development/templates/smart-proxy/smart-proxy-development.service.j2 diff --git a/development/roles/foreman_development/tasks/smart-proxy/main.yml b/development/roles/foreman_development/tasks/smart-proxy/main.yml index c82b9523..bfff2c9e 100644 --- a/development/roles/foreman_development/tasks/smart-proxy/main.yml +++ b/development/roles/foreman_development/tasks/smart-proxy/main.yml @@ -92,3 +92,60 @@ environment: PATH: "/usr/bin:/bin:/usr/local/bin" changed_when: true + +- name: Create smart-proxy development systemd service + ansible.builtin.template: + src: smart-proxy/smart-proxy-development.service.j2 + dest: /etc/systemd/system/smart-proxy-development.service + owner: root + group: root + mode: "0644" + +- name: Reload systemd daemon + ansible.builtin.systemd: + daemon_reload: true + +- name: Enable and start smart-proxy development service + ansible.builtin.systemd: + name: smart-proxy-development + enabled: true + state: started + +- name: Wait for smart-proxy development server to be accessible + ansible.builtin.uri: + url: "http://{{ ansible_facts['fqdn'] }}:8000/features" + validate_certs: false + until: foreman_development_smart_proxy_status.status == 200 + retries: 30 + delay: 5 + register: foreman_development_smart_proxy_status + +- name: Enable and start Foreman development service + ansible.builtin.systemd: + name: foreman-development + enabled: true + state: started + +- name: Wait for Foreman development server to be accessible + ansible.builtin.uri: + url: '{{ foreman_development_url }}/api/v2/ping' + validate_certs: false + until: foreman_development_status.status == 200 + retries: 30 + delay: 5 + register: foreman_development_status + +- name: Configure smart-proxy for development + theforeman.foreman.smart_proxy: + name: "{{ ansible_facts['fqdn'] }}-dev" + url: "https://{{ ansible_facts['fqdn'] }}:8443" + server_url: "{{ foreman_development_url }}" + username: "{{ foreman_development_admin_user }}" + password: "{{ foreman_development_admin_password }}" + validate_certs: false + +- name: Stop smart-proxy development service after smart proxy registration + ansible.builtin.systemd: + name: smart-proxy-development + state: stopped + enabled: false diff --git a/development/roles/foreman_development/templates/smart-proxy/smart-proxy-development.service.j2 b/development/roles/foreman_development/templates/smart-proxy/smart-proxy-development.service.j2 new file mode 100644 index 00000000..31b34361 --- /dev/null +++ b/development/roles/foreman_development/templates/smart-proxy/smart-proxy-development.service.j2 @@ -0,0 +1,14 @@ +[Unit] +Description=Smart Proxy Development Server + +[Service] +Type=simple +User={{ foreman_development_user }} +Group={{ foreman_development_group }} +WorkingDirectory={{ foreman_development_smart_proxy_dir }} +Environment=PATH=/usr/bin:/bin:/usr/local/bin +Environment=BUNDLE_PATH={{ foreman_development_smart_proxy_dir }}/.vendor +ExecStart=/usr/bin/bundle exec ruby bin/smart-proxy + +[Install] +WantedBy=multi-user.target From dd77a834e4ca139bf5ca3b47a3006eaffe66b3bc Mon Sep 17 00:00:00 2001 From: Adam Ruzicka Date: Thu, 19 Feb 2026 16:33:14 +0100 Subject: [PATCH 10/10] Update development docs --- docs/development-environment.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/development-environment.md b/docs/development-environment.md index b7406a5e..8b491690 100644 --- a/docs/development-environment.md +++ b/docs/development-environment.md @@ -57,6 +57,12 @@ When deploying to remote hosts that require SSH password authentication: ANSIBLE_ASK_PASS=true ./forge deploy-dev --target-host=192.168.1.100 ``` +## Feature Management + +Similarly to production deployments with `foremanctl`, using `forge` there is support for enabling `hammer` and `foreman-proxy` as features. Features can be enabled with `--enable-feature=$feature`, which can be used multiple times. + +By default `hammer` feature will set up `hammer-cli` and `hammer-cli-foreman`, `foreman-proxy` will set up `smart-proxy` itself. If any plugins are enabled, they're respective hammer or smart-proxy plugins will be set up as well. + ## Plugin Management ### Enabled Plugins (Default) @@ -74,6 +80,13 @@ The system includes a plugin registry with predefined configurations: - `foreman_discovery` - Host discovery - `foreman_openscap` - OpenSCAP compliance - `foreman_bootdisk` - Boot disk creation +- `foreman_openscap` - Foreman plug-in for displaying OpenSCAP audit reports +- `foreman_theme_satellite` - Branding for Satellite +- `foreman_tasks` - Tasks management engine and plugin for Foreman +- `foreman_webhooks` - Call external webhooks from Foreman +- `foreman_templates` - A plugin for Foreman to sync provisioning templates from an external source +- `foreman_leapp` - A plugin that allows to run inplace upgrades for RHEL hosts in Foreman using Leapp tool. +- `foreman_puppet` - A plugin that adds Puppet External node classification functionality to Foreman. ### Enabling Additional Plugins @@ -102,6 +115,10 @@ After deployment, the environment includes: - Database migrations and seeding - Plugin repositories and configurations - Development-specific settings +- if `hammer` feature was enabled, `hammer-cli` and its plugins +- if `foreman-proxy` feature was enabled + - `smart-proxy` and its plugins + - the development smart proxy registered into Foreman ## Architecture @@ -112,6 +129,8 @@ The development environment integrates: - **Backend Services**: All services (PostgreSQL, Redis, Candlepin, Pulp) run in containers - **Rails Development Server**: Runs directly on the VM for live debugging and development - **Pulp Smart Proxy Registration**: Automatically configures Pulp integration during deployment +- **Hammer CLI**: Automatically sets up hammer for development, if `hammer` feature was enabled +- **Smart Proxy**: Automatically set up a smart proxy for development and registers it into Foreman, if `foreman-proxy` feature was enabled ### Certificates