diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e4bc75019..f7e074166 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -154,6 +154,7 @@ jobs: --add-feature azure-rm \ --add-feature google \ --add-feature remote-execution \ + --add-feature bmc \ ${{ matrix.iop == 'enabled' && '--add-feature iop' || '' }} - name: Run tests run: | diff --git a/docs/user/parameters.md b/docs/user/parameters.md index 85d9c6619..dc55880ff 100644 --- a/docs/user/parameters.md +++ b/docs/user/parameters.md @@ -103,6 +103,13 @@ There are multiple use cases from the users perspective that dictate what parame ## Smart Proxy +### Mapped + +| Parameter | Description | foreman-installer Parameters | +| --------- | ----------- | ---------------------------- | +| `--bmc-ipmi-implementation` | IPMI implementation to use for BMC | `--foreman-proxy-bmc-default-provider` | +| `--bmc-redfish-verify-ssl` | Verify SSL certificates for Redfish BMC connections | `--foreman-proxy-bmc-redfish-verify-ssl` | + ### Undetermined | Installer Parameter | Description | Module | Puppet Parameter | @@ -152,8 +159,6 @@ There are multiple use cases from the users perspective that dictate what parame | `--foreman-proxy-plugin-remote-execution-script-mode` | | foreman_proxy::plugin::remote_execution_script | mode | | `--foreman-proxy-plugin-openscap-ansible-module` | | foreman_proxy::plugin::openscap | ansible_module | | `--foreman-proxy-plugin-openscap-puppet-module` | | foreman_proxy::plugin::openscap | puppet_module | -| `--foreman-proxy-bmc` | | | | -| `--foreman-proxy-bmc-default-provider` | | | | | `--foreman-proxy-content-enable-ostree` | | | | | `--foreman-proxy-content-pulpcore-additional-import-paths` | | | | | `--foreman-proxy-http` | | | | diff --git a/src/features.yaml b/src/features.yaml index 5a77a1585..f8284b019 100644 --- a/src/features.yaml +++ b/src/features.yaml @@ -44,3 +44,7 @@ iop: description: iop services dependencies: - rh-cloud +bmc: + description: Power management for bare metal hosts (IPMI, Redfish) + foreman_proxy: + plugin_name: bmc diff --git a/src/playbooks/deploy/metadata.obsah.yaml b/src/playbooks/deploy/metadata.obsah.yaml index e572ff46d..3a6e6da6f 100644 --- a/src/playbooks/deploy/metadata.obsah.yaml +++ b/src/playbooks/deploy/metadata.obsah.yaml @@ -46,6 +46,16 @@ variables: type: AbsolutePath parameter: --certificate-server-ca-certificate persist: false + foreman_proxy_bmc_ipmi_implementation: + parameter: --bmc-ipmi-implementation + help: IPMI implementation to use for BMC. + choices: + - freeipmi + - ipmitool + foreman_proxy_bmc_redfish_verify_ssl: + parameter: --bmc-redfish-verify-ssl + help: Verify SSL certificates for Redfish BMC connections. + type: Boolean constraints: required_together: diff --git a/src/roles/foreman_proxy/defaults/main.yaml b/src/roles/foreman_proxy/defaults/main.yaml index 1d48354d3..cb62496ac 100644 --- a/src/roles/foreman_proxy/defaults/main.yaml +++ b/src/roles/foreman_proxy/defaults/main.yaml @@ -19,3 +19,7 @@ foreman_proxy_available_features: "{{ [] | available_foreman_proxy_plugins }}" foreman_proxy_disabled_features: "{{ foreman_proxy_available_features | difference(foreman_proxy_features) }}" foreman_proxy_foreman_server_url: "https://{{ ansible_facts['fqdn'] }}" + +# BMC settings +foreman_proxy_bmc_ipmi_implementation: ipmitool +foreman_proxy_bmc_redfish_verify_ssl: true diff --git a/src/roles/foreman_proxy/templates/settings.d/bmc.yml.j2 b/src/roles/foreman_proxy/templates/settings.d/bmc.yml.j2 new file mode 100644 index 000000000..f54ff3918 --- /dev/null +++ b/src/roles/foreman_proxy/templates/settings.d/bmc.yml.j2 @@ -0,0 +1,4 @@ +--- +:enabled: {{ feature_enabled }} +:bmc_default_provider: {{ foreman_proxy_bmc_ipmi_implementation }} +:redfish_verify_ssl: {{ foreman_proxy_bmc_redfish_verify_ssl }} diff --git a/tests/conftest.py b/tests/conftest.py index 7f0b31df0..4883e923a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,7 +13,7 @@ from jinja2 import select_autoescape from requests.adapters import HTTPAdapter -SSH_CONFIG='./.tmp/ssh-config' +SSH_CONFIG = './.tmp/ssh-config' def pytest_addoption(parser): @@ -206,20 +206,21 @@ def wait_for_metadata_generate(foremanapi): wait_for_tasks(foremanapi, 'label = Actions::Katello::Repository::MetadataGenerate') -def is_iop_enabled(): +def enabled_features(): test_dir = os.path.dirname(os.path.abspath(__file__)) foremanctl_dir = os.path.dirname(test_dir) params_file = os.path.join(foremanctl_dir, '.var', 'lib', 'foremanctl', 'parameters.yaml') - if os.path.exists(params_file): with open(params_file, 'r') as f: - params = yaml.safe_load(f) - features = params.get('features', []) + features = yaml.safe_load(f).get('features', []) if isinstance(features, str): features = features.split() - return 'iop' in features + return features + return [] - return False + +def is_iop_enabled(): + return 'iop' in enabled_features() def pytest_configure(config): diff --git a/tests/foreman_proxy_test.py b/tests/foreman_proxy_test.py index 9ffaddc97..847a723bb 100644 --- a/tests/foreman_proxy_test.py +++ b/tests/foreman_proxy_test.py @@ -2,10 +2,26 @@ import json import pytest +from conftest import enabled_features FOREMAN_PROXY_PORT = 8443 +def is_bmc_enabled(): + return 'bmc' in enabled_features() + + +def get_proxy_v2_features(server, certificates, server_fqdn): + cmd = server.run( + f"curl --cacert {certificates['server_ca_certificate']} " + f"--cert {certificates['client_certificate']} " + f"--key {certificates['client_key']} " + f"--silent https://{server_fqdn}:{FOREMAN_PROXY_PORT}/v2/features" + ) + assert cmd.succeeded, f"Failed to query /v2/features: {cmd.stderr}" + return json.loads(cmd.stdout) + + def test_foreman_proxy_features(server, certificates, server_fqdn): cmd = server.run(f"curl --cacert {certificates['server_ca_certificate']} --silent https://{server_fqdn}:{FOREMAN_PROXY_PORT}/features") assert cmd.succeeded @@ -13,6 +29,10 @@ def test_foreman_proxy_features(server, certificates, server_fqdn): assert "logs" in features assert "script" in features assert "dynflow" in features + if is_bmc_enabled(): + assert "bmc" in features + else: + assert "bmc" not in features def test_foreman_proxy_service(server): @@ -38,3 +58,13 @@ def test_foreman_proxy_client_auth_to_foreman(server, certificates, server_fqdn) ) assert cmd.succeeded assert cmd.stdout == '201' + + +@pytest.mark.skipif("not is_bmc_enabled()") +def test_bmc_capabilities(server, certificates, server_fqdn): + features = get_proxy_v2_features(server, certificates, server_fqdn) + assert 'bmc' in features + capabilities = features['bmc'].get('capabilities', []) + assert 'ipmitool' in capabilities + assert 'freeipmi' in capabilities + assert 'redfish' in capabilities