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 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..b8c8dc90 100644 --- a/development/roles/foreman_development/defaults/main.yaml +++ b/development/roles/foreman_development/defaults/main.yaml @@ -4,6 +4,8 @@ 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_smart_proxy_dir: "{{ foreman_development_deployment_dir }}/smart-proxy" foreman_development_ca_certificate: "{{ foreman_ca_certificate }}" foreman_development_client_certificate: "{{ foreman_client_certificate }}" @@ -16,6 +18,12 @@ 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_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" @@ -36,43 +44,106 @@ 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 + 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" manage_repo: true + hammer: + 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 + 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 + 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 + 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 + smart_proxy: + name: "theforeman/smart_proxy_dynflow" + module_config: dynflow.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 + smart_proxy: + name: "theforeman/smart_proxy_shellhooks" + module_config: shellhooks.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..6659aed3 --- /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 + chdir: "{{ foreman_development_hammer_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/hammer/plugin.yml b/development/roles/foreman_development/tasks/hammer/plugin.yml new file mode 100644 index 00000000..0e307010 --- /dev/null +++ b/development/roles/foreman_development/tasks/hammer/plugin.yml @@ -0,0 +1,59 @@ +--- +- 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 }}" + force: true + become: true + become_user: "{{ foreman_development_user }}" + when: foreman_development_plugin_manage_repo + +- 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 + 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 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', '') }}" + 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 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 }} + 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 bundler configuration for {{ foreman_development_plugin_name }}" + 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..77542b60 100644 --- a/development/roles/foreman_development/tasks/main.yaml +++ b/development/roles/foreman_development/tasks/main.yaml @@ -250,3 +250,13 @@ name: foreman-development 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: + - "'hammer' in enabled_features" 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..bfff2c9e --- /dev/null +++ b/development/roles/foreman_development/tasks/smart-proxy/main.yml @@ -0,0 +1,151 @@ +--- +- 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 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" + 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: 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 + chdir: "{{ foreman_development_smart_proxy_dir }}" + become: true + become_user: "{{ foreman_development_user }}" + 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/tasks/smart-proxy/plugin.yml b/development/roles/foreman_development/tasks/smart-proxy/plugin.yml new file mode 100644 index 00000000..92c32d7f --- /dev/null +++ b/development/roles/foreman_development/tasks/smart-proxy/plugin.yml @@ -0,0 +1,66 @@ +--- +- 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 }}" + force: true + become: true + become_user: "{{ foreman_development_user }}" + when: foreman_development_plugin_manage_repo + +- 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 + 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 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', '') }}" + 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 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 }}" + 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 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 }}' + 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 for {{ foreman_development_plugin_name }}" + 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..2ba6320c --- /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 for {{ foreman_development_plugin_name }}" + 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 for {{ foreman_development_plugin_name }}" + 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 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" + 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..c7c897cc --- /dev/null +++ b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_openscap.yml @@ -0,0 +1,4 @@ +- 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 new file mode 100644 index 00000000..287f3279 --- /dev/null +++ b/development/roles/foreman_development/tasks/smart-proxy/plugin/smart_proxy_remote_execution_ssh.yml @@ -0,0 +1,16 @@ +- name: "Ensure ~/.ssh directory exists with correct permissions for {{ foreman_development_plugin_name }}" + 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 ~/.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" + become: true + become_user: "{{ foreman_development_user }}" 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 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..79878e9a --- /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 }}/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". +# 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] 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 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