Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 63 additions & 8 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ jobs:
matrix:
certificate_source:
- default
- installer
security:
- none
database:
Expand All @@ -51,9 +50,6 @@ jobs:
- centos/stream10
iop:
- enabled
exclude:
- certificate_source: installer
box: centos/stream10
include:
- certificate_source: default
security: fapolicyd
Expand Down Expand Up @@ -97,10 +93,6 @@ jobs:
- name: Configure repositories
run: |
./forge setup-repositories
- name: Create installer certificates
if: contains(matrix.certificate_source, 'installer')
run: |
./forge installer-certs
- name: Create custom certificates
if: matrix.certificate_source == 'custom_server'
run: |
Expand Down Expand Up @@ -278,13 +270,76 @@ jobs:
## If no one connects after 5 minutes, shut down server.
wait-timeout-minutes: 5

migration:
strategy:
fail-fast: false
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.12'
- name: Setup libvirt for Vagrant
uses: voxpupuli/setup-vagrant@v0
- name: Install Ansible
run: pip install --upgrade ansible-core
- name: Setup environment
run: ./setup-environment
- name: Start VMs
run: |
./forge vms start --vms "quadlet client"
- name: Configure repositories
run: |
./forge setup-repositories
- name: Create installer certificates
run: |
./forge installer-certs
- name: Run image pull
run: |
./foremanctl pull-images
- name: Run migration
run: |
./foremanctl migrate --output /var/lib/foremanctl/parameters.yaml
- name: Run deployment
run: |
./foremanctl deploy --foreman-initial-admin-password=changeme --initial-organization "Foreman CI" --initial-location "Internet" --tuning development
- name: Run tests
run: |
./forge test --pytest-args="--certificate-source=default"
- name: Run smoker
run: |
./forge smoker
- name: Archive smoker report
if: ${{ always() }}
uses: actions/upload-artifact@v7
with:
name: smoker-migration
path: "/home/runner/smoker/report/"
- name: Generate sos reports
if: ${{ always() }}
run: ./forge sos
- name: Archive sos reports
if: ${{ always() }}
uses: actions/upload-artifact@v7
with:
name: sosreport-migration
path: sos/
- name: Setup upterm session
if: ${{ failure() }}
uses: owenthereal/action-upterm@v1
with:
limit-access-to-actor: true
wait-timeout-minutes: 5

# A dummy job that you can mark as a required check instead of each individual test
test-suite:
if: always()
needs:
- tests
- devel-tests
- upgrade
- migration
- ansible-lint
runs-on: ubuntu-latest
name: Test suite
Expand Down
2 changes: 1 addition & 1 deletion development/playbooks/deploy-dev/deploy-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
vars_files:
- "../../../src/vars/defaults.yml"
- "../../../src/vars/flavors/{{ flavor }}.yml"
- "../../../src/vars/{{ certificates_source }}_certificates.yml"
- "../../../src/vars/certificates.yml"
- "../../../src/vars/images.yml"
- "../../../src/vars/database.yml"
- "../../../src/vars/foreman.yml"
Expand Down
38 changes: 13 additions & 25 deletions docs/user/certificates.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This document describes how certificate generation and management works in forem

### Certificate Sources

foremanctl supports three certificate sources that determine how certificates are obtained:
foremanctl supports two certificate sources that determine how certificates are obtained:

**Default Source (`certificate_source: default`)**
- Automatically generates self-signed certificates during deployment
Expand All @@ -19,11 +19,6 @@ foremanctl supports three certificate sources that determine how certificates ar
- Server certificate, key, and CA bundle are copied to `/root/certificates/`
- Certificate source persists across deployments; original files only needed on first deploy or when updating certificates

**Installer Source (`certificate_source: installer`)**
- Uses existing certificates from a previous `foreman-installer` deployment
- Useful for migration scenarios where certificates already exist
- Certificate files must be present at expected foreman-installer paths

### Usage

#### Using Auto-Generated Certificates (Default)
Expand Down Expand Up @@ -59,13 +54,17 @@ foremanctl deploy \
foremanctl deploy --certificate-source=default
```

#### Using Existing Installer Certificates
#### Migrating from foreman-installer

When migrating from a `foreman-installer` deployment, use the `migrate` command to normalize existing certificates into foremanctl's canonical structure:

```bash
# Use certificates from previous foreman-installer
foremanctl deploy --certificate-source=installer
foremanctl migrate --output /var/lib/foremanctl/parameters.yaml
foremanctl deploy
```

The `migrate` command copies certificates from `/root/ssl-build/` into `/root/certificates/`, persists the CA passphrase so foremanctl can issue new certificates, and backs up the original directory to `/root/ssl-build.bak/`. See the [migration guide](../migration-guide.md) for full details.

### Certificate Locations

After deployment, certificates are available at:
Expand All @@ -81,10 +80,9 @@ After deployment, certificates are available at:
- Server CA Certificate: `/root/certificates/certs/server-ca.crt` (custom CA that signed server cert)
- Client Certificate: `/root/certificates/certs/<hostname>-client.crt` (generated by internal CA)

**Installer Source:**
- CA Certificate: `/root/ssl-build/katello-default-ca.crt`
- Server Certificate: `/root/ssl-build/<hostname>/<hostname>-apache.crt`
- Client Certificate: `/root/ssl-build/<hostname>/<hostname>-foreman-client.crt`
**After Migration:**
- Certificates from `foreman-installer` are normalized into the same paths as the Default Source above
- Original directory is backed up to `/root/ssl-build.bak/`

### CNAME Support

Expand Down Expand Up @@ -131,7 +129,6 @@ The `--certificate-renew` flag is **not persisted** in foremanctl’s answers fi

- Uses the same lifetime for both client and server certificates
- Limited certificate customization options
- Custom server certificates cannot be combined with `certificate_source: installer`
- CNAMEs are only applied to certificates generated by the internal CA

## Internal Design
Expand Down Expand Up @@ -174,10 +171,9 @@ For `certificate_source: custom_server`:
2. **Custom Server Certificates**: Copy the custom server cert, key, and CA bundle from user-provided paths to `/root/certificates/` (only when certificate paths are provided)
3. **Host Certificate Issuance**: Generate client certificate and localhost certificate signed by the internal CA (server cert for FQDN is skipped)

For `certificate_source: installer`:
#### Migration from foreman-installer

- Uses existing certificates from `/root/ssl-build/` generated by foreman-installer
- No certificate generation performed; files must already exist
The `foremanctl migrate` command includes a `migrate_foreman_installer` role that normalizes `foreman-installer` certificates into the canonical `/root/certificates/` structure. It also reads the CA passphrase from the installer's password file and persists it into foremanctl's configuration so that subsequent deploys can issue new certificates using the original CA.

#### Variable System

Expand All @@ -197,14 +193,6 @@ client_certificate: "{{ certificates_ca_directory }}/certs/{{ ansible_facts['fqd
- The `server_ca_certificate` points to the custom CA that signed the server certificate
- The `ca_bundle` contains both the internal CA and custom server CA

**Installer Source (`src/vars/installer_certificates.yml`):**
```yaml
ca_certificate: "/root/ssl-build/katello-default-ca.crt"
server_certificate: "/root/ssl-build/{{ ansible_facts['fqdn'] }}/{{ ansible_facts['fqdn'] }}-apache.crt"
server_ca_certificate: "/root/ssl-build/katello-server-ca.crt"
client_certificate: "/root/ssl-build/{{ ansible_facts['fqdn'] }}/{{ ansible_facts['fqdn'] }}-foreman-client.crt"
```

#### Integration with Deployment

In `src/playbooks/deploy/deploy.yaml`:
Expand Down
3 changes: 1 addition & 2 deletions src/playbooks/_certificate_source/metadata.obsah.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
---
variables:
certificates_source:
help: Where certificates are coming from. Currently default Ansible role, the foreman-installer, or custom server certificates.
help: Where certificates are coming from. Currently default Ansible role or custom server certificates.
parameter: --certificate-source
choices:
- default
- installer
- custom_server
2 changes: 1 addition & 1 deletion src/playbooks/deploy/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
vars_files:
- "../../vars/defaults.yml"
- "../../vars/flavors/{{ flavor }}.yml"
- "../../vars/{{ certificates_source }}_certificates.yml"
- "../../vars/certificates.yml"
- "../../vars/images.yml"
- "../../vars/tuning/{{ tuning }}.yml"
- "../../vars/database.yml"
Expand Down
3 changes: 0 additions & 3 deletions src/playbooks/deploy/metadata.obsah.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ variables:
constraints:
required_together:
- [certificates_custom_server_certificate, certificates_custom_server_key, certificates_custom_server_ca_certificate]
forbidden_if:
- [certificates_source, installer, [certificates_custom_server_certificate, certificates_custom_server_key, certificates_custom_server_ca_certificate]]

include:
- _certificate_source
- _certificate_validity
Expand Down
7 changes: 7 additions & 0 deletions src/playbooks/migrate/migrate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,10 @@
vars:
_unmappable_warning: "Warning: {{ migration_result.unmappable | length }} parameter(s) could not be mapped - see warnings above"
_output_file_msg: "Output written to: {{ migration_result.output_file }}"

- name: Migrate foreman-installer certificates
hosts:
- quadlet
become: true
roles:
- role: migrate_foreman_installer
8 changes: 4 additions & 4 deletions src/plugins/modules/migrate_answers.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ def cast_database_mode(value):
('foreman', 'initial_admin_username'): 'foreman_initial_admin_username',
('foreman', 'initial_admin_password'): 'foreman_initial_admin_password',

# Certificate configuration
('foreman', 'server_ssl_cert'): 'server_certificate',
('foreman', 'server_ssl_key'): 'server_key',
('foreman', 'server_ssl_ca'): 'ca_certificate',
# Certificate paths are handled by the migrate_foreman_installer role
('foreman', 'server_ssl_cert'): 'IGNORE',
('foreman', 'server_ssl_key'): 'IGNORE',
('foreman', 'server_ssl_ca'): 'IGNORE',

# TODO: Add more mappings as discovered
}
Expand Down
2 changes: 2 additions & 0 deletions src/roles/migrate_foreman_installer/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
migrate_foreman_installer_ca_directory: /root/certificates
Loading
Loading