Merge "TLS support for API services"
This commit is contained in:
commit
3aae442b82
@ -154,6 +154,8 @@ def cmd_install(args):
|
|||||||
install_dib='true',
|
install_dib='true',
|
||||||
network_interface=args.network_interface,
|
network_interface=args.network_interface,
|
||||||
enable_keystone=args.enable_keystone,
|
enable_keystone=args.enable_keystone,
|
||||||
|
enable_tls=args.enable_tls,
|
||||||
|
generate_tls=args.enable_tls,
|
||||||
noauth_mode='false',
|
noauth_mode='false',
|
||||||
enabled_hardware_types=args.hardware_types,
|
enabled_hardware_types=args.hardware_types,
|
||||||
cleaning_disk_erase=args.cleaning_disk_erase,
|
cleaning_disk_erase=args.cleaning_disk_erase,
|
||||||
@ -220,6 +222,8 @@ def parse_args():
|
|||||||
help='the network interface to use')
|
help='the network interface to use')
|
||||||
install.add_argument('--enable-keystone', action='store_true',
|
install.add_argument('--enable-keystone', action='store_true',
|
||||||
help='enable keystone and use authentication')
|
help='enable keystone and use authentication')
|
||||||
|
install.add_argument('--enable-tls', action='store_true',
|
||||||
|
help='enable self-signed TLS on API endpoints')
|
||||||
install.add_argument('--hardware-types',
|
install.add_argument('--hardware-types',
|
||||||
# only generic types are enabled in the simple CI
|
# only generic types are enabled in the simple CI
|
||||||
default='ipmi,redfish,manual-management',
|
default='ipmi,redfish,manual-management',
|
||||||
|
@ -222,6 +222,11 @@ Additionally, the following parameters can be useful:
|
|||||||
A comma separated list of hardware types to enable.
|
A comma separated list of hardware types to enable.
|
||||||
``--enable-keystone``
|
``--enable-keystone``
|
||||||
Whether to enable authentication with Keystone_.
|
Whether to enable authentication with Keystone_.
|
||||||
|
``--enable-tls``
|
||||||
|
Enable self-signed TLS on API endpoints.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
If using Keystone_, see :ref:`keystone-tls` for important notes.
|
||||||
|
|
||||||
See the built-in documentation for more details:
|
See the built-in documentation for more details:
|
||||||
|
|
||||||
@ -314,6 +319,30 @@ If you are running the installation behind a proxy, export the
|
|||||||
environment variables ``http_proxy``, ``https_proxy`` and ``no_proxy``
|
environment variables ``http_proxy``, ``https_proxy`` and ``no_proxy``
|
||||||
so that ansible will use these proxy settings.
|
so that ansible will use these proxy settings.
|
||||||
|
|
||||||
|
TLS support
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Bifrost supports TLS for API services with two options:
|
||||||
|
|
||||||
|
* A self-signed certificate can be generated automatically. Set
|
||||||
|
``enable_tls=true`` and ``generate_tls=true``.
|
||||||
|
|
||||||
|
.. note:: This is equivalent to the ``--enable-tls`` flag of ``bifrost-cli``.
|
||||||
|
|
||||||
|
* Certificate paths can be provided via:
|
||||||
|
|
||||||
|
``tls_certificate_path``
|
||||||
|
Path to the TLS certificate (must be world-readable).
|
||||||
|
``tls_private_key_path``
|
||||||
|
Path to the private key (must not be password protected).
|
||||||
|
``tls_csr_path``
|
||||||
|
Path to the certificate signing request file.
|
||||||
|
|
||||||
|
Set ``enable_tls=true`` and do not set ``generate_tls`` to use this option.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
If using Keystone, see :ref:`keystone-tls` for important notes.
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
============
|
============
|
||||||
|
|
||||||
|
@ -30,6 +30,25 @@ See the following files for more settings that can be overridden:
|
|||||||
* ``playbooks/roles/bifrost-ironic-install/defaults/main.yml``
|
* ``playbooks/roles/bifrost-ironic-install/defaults/main.yml``
|
||||||
* ``playbooks/roles/bifrost-keystone-install/defaults/main.yml``
|
* ``playbooks/roles/bifrost-keystone-install/defaults/main.yml``
|
||||||
|
|
||||||
|
.. _keystone-tls:
|
||||||
|
|
||||||
|
TLS notes
|
||||||
|
---------
|
||||||
|
|
||||||
|
There are two important limitations to keep in mind when using Keystone with
|
||||||
|
TLS:
|
||||||
|
|
||||||
|
* It's not possible to enable TLS on upgrade from Bifrost < 9.0 (Ussuri
|
||||||
|
and early Victoria). First do an upgrade to Bifrost >= 9.0, then enable TLS
|
||||||
|
in a separate step.
|
||||||
|
|
||||||
|
* Automatically updating from a TLS environment to a non-TLS one may not be
|
||||||
|
possible if using custom TLS certificates in a non-standard location
|
||||||
|
(``/etc/bifrost/bifrost.crt``). You need to manually change identity
|
||||||
|
endpoints in the catalog from ``https`` to ``http`` directly before
|
||||||
|
an update. The ``public`` endpoint **must** be updated **last** or you may
|
||||||
|
lock yourself out of keystone.
|
||||||
|
|
||||||
Using an existing Keystone
|
Using an existing Keystone
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
|
@ -15,3 +15,4 @@
|
|||||||
BOOT_MODE: "{{ boot_mode | default('') }}"
|
BOOT_MODE: "{{ boot_mode | default('') }}"
|
||||||
TEST_VM_NODE_DRIVER: "{{ test_driver | default('ipmi') }}"
|
TEST_VM_NODE_DRIVER: "{{ test_driver | default('ipmi') }}"
|
||||||
NOAUTH_MODE: "{{ noauth_mode | default(false) | bool | lower }}"
|
NOAUTH_MODE: "{{ noauth_mode | default(false) | bool | lower }}"
|
||||||
|
ENABLE_TLS: "{{ enable_tls | default(false) | bool | lower }}"
|
||||||
|
@ -45,6 +45,10 @@ overridden in no-auth mode.
|
|||||||
|
|
||||||
Ironic endpoint to use. If the fact is already defined, it is not overridden.
|
Ironic endpoint to use. If the fact is already defined, it is not overridden.
|
||||||
|
|
||||||
|
`tls_certificate_path`
|
||||||
|
|
||||||
|
Path to the TLS certificate. Only set if TLS is used.
|
||||||
|
|
||||||
Notes
|
Notes
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -5,5 +5,6 @@ network_interface: "virbr0"
|
|||||||
ans_network_interface: "{{ network_interface | replace('-', '_') }}"
|
ans_network_interface: "{{ network_interface | replace('-', '_') }}"
|
||||||
internal_ip: "{{ hostvars[inventory_hostname]['ansible_' + ans_network_interface]['ipv4']['address'] }}"
|
internal_ip: "{{ hostvars[inventory_hostname]['ansible_' + ans_network_interface]['ipv4']['address'] }}"
|
||||||
|
|
||||||
api_protocol: http
|
enable_tls: false
|
||||||
|
api_protocol: "{{ 'https' if enable_tls | bool else 'http' }}"
|
||||||
ironic_api_url: "{{ api_protocol }}://{{ internal_ip }}:6385"
|
ironic_api_url: "{{ api_protocol }}://{{ internal_ip }}:6385"
|
||||||
|
@ -38,6 +38,14 @@
|
|||||||
- openstack_cloud is defined
|
- openstack_cloud is defined
|
||||||
no_log: yes
|
no_log: yes
|
||||||
|
|
||||||
|
- name: "Set the TLS certificate if present"
|
||||||
|
set_fact:
|
||||||
|
tls_certificate_path: "{{ openstack_cloud.cacert }}"
|
||||||
|
when:
|
||||||
|
- tls_certificate_path is undefined
|
||||||
|
- openstack_cloud is defined
|
||||||
|
- openstack_cloud.cacert is defined
|
||||||
|
|
||||||
- name: "If in noauth mode and no clouds.yaml, unset authentication parameters."
|
- name: "If in noauth mode and no clouds.yaml, unset authentication parameters."
|
||||||
set_fact:
|
set_fact:
|
||||||
auth_type: None
|
auth_type: None
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
cloud: "{{ cloud_name | default(omit) }}"
|
cloud: "{{ cloud_name | default(omit) }}"
|
||||||
auth_type: "{{ auth_type | default(omit) }}"
|
auth_type: "{{ auth_type | default(omit) }}"
|
||||||
auth: "{{ auth | default(omit) }}"
|
auth: "{{ auth | default(omit) }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
ironic_url: "{{ ironic_url | default(omit) }}"
|
ironic_url: "{{ ironic_url | default(omit) }}"
|
||||||
uuid: "{{ uuid | default() }}"
|
uuid: "{{ uuid | default() }}"
|
||||||
name: "{{ name | default() }}"
|
name: "{{ name | default() }}"
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
cloud: "{{ cloud_name | default(omit) }}"
|
cloud: "{{ cloud_name | default(omit) }}"
|
||||||
auth_type: "{{ auth_type | default(omit) }}"
|
auth_type: "{{ auth_type | default(omit) }}"
|
||||||
auth: "{{ auth | default(omit) }}"
|
auth: "{{ auth | default(omit) }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
ironic_url: "{{ ironic_url | default(omit) }}"
|
ironic_url: "{{ ironic_url | default(omit) }}"
|
||||||
uuid: "{{ uuid }}"
|
uuid: "{{ uuid }}"
|
||||||
state: present
|
state: present
|
||||||
@ -85,6 +86,7 @@
|
|||||||
cloud: "{{ cloud_name | default(omit) }}"
|
cloud: "{{ cloud_name | default(omit) }}"
|
||||||
auth_type: "{{ auth_type | default(omit) }}"
|
auth_type: "{{ auth_type | default(omit) }}"
|
||||||
auth: "{{ auth | default(omit) }}"
|
auth: "{{ auth | default(omit) }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
ironic_url: "{{ ironic_url | default(omit) }}"
|
ironic_url: "{{ ironic_url | default(omit) }}"
|
||||||
uuid: "{{ uuid }}"
|
uuid: "{{ uuid }}"
|
||||||
state: present
|
state: present
|
||||||
|
@ -262,7 +262,7 @@ noauth_mode: true
|
|||||||
enable_keystone: false
|
enable_keystone: false
|
||||||
|
|
||||||
# Service URLs used for communication with them.
|
# Service URLs used for communication with them.
|
||||||
api_protocol: http
|
api_protocol: "{{ 'https' if enable_tls | bool else 'http' }}"
|
||||||
ironic_api_url: "{{ api_protocol }}://{{ internal_ip }}:6385"
|
ironic_api_url: "{{ api_protocol }}://{{ internal_ip }}:6385"
|
||||||
ironic_inspector_api_url: "{{ api_protocol }}://{{ internal_ip }}:5050"
|
ironic_inspector_api_url: "{{ api_protocol }}://{{ internal_ip }}:5050"
|
||||||
keystone_api_url: "{{ api_protocol }}://{{ internal_ip }}:5000/v3"
|
keystone_api_url: "{{ api_protocol }}://{{ internal_ip }}:5000/v3"
|
||||||
@ -341,3 +341,10 @@ pip_opts: "{{ lookup('env', 'PIP_OPTS') | default('') }}"
|
|||||||
|
|
||||||
# Timeout for gathering facts.
|
# Timeout for gathering facts.
|
||||||
fact_gather_timeout: "{{ lookup('config', 'DEFAULT_GATHER_TIMEOUT', on_missing='skip') | default(omit, true) }}"
|
fact_gather_timeout: "{{ lookup('config', 'DEFAULT_GATHER_TIMEOUT', on_missing='skip') | default(omit, true) }}"
|
||||||
|
|
||||||
|
# Enable TLS support.
|
||||||
|
enable_tls: false
|
||||||
|
tls_root: /etc/bifrost
|
||||||
|
tls_certificate_path: "{{ tls_root }}/bifrost.crt"
|
||||||
|
ironic_private_key_path: /etc/ironic/ironic.pem
|
||||||
|
ironic_inspector_private_key_path: /etc/ironic-inspector/inspector.pem
|
||||||
|
@ -144,6 +144,15 @@
|
|||||||
- not noauth_mode | bool
|
- not noauth_mode | bool
|
||||||
- not enable_keystone | bool
|
- not enable_keystone | bool
|
||||||
|
|
||||||
|
- name: "Generate TLS parameters"
|
||||||
|
include_role:
|
||||||
|
name: bifrost-tls
|
||||||
|
vars:
|
||||||
|
dest_private_key_path: "{{ ironic_private_key_path }}"
|
||||||
|
dest_private_key_owner: ironic
|
||||||
|
dest_private_key_group: ironic
|
||||||
|
when: enable_tls | bool
|
||||||
|
|
||||||
- name: "Populate keystone for Bifrost"
|
- name: "Populate keystone for Bifrost"
|
||||||
include: keystone_setup.yml
|
include: keystone_setup.yml
|
||||||
when:
|
when:
|
||||||
|
@ -92,6 +92,15 @@
|
|||||||
- not noauth_mode | bool
|
- not noauth_mode | bool
|
||||||
- not enable_keystone | bool
|
- not enable_keystone | bool
|
||||||
|
|
||||||
|
- name: "Generate TLS parameters"
|
||||||
|
include_role:
|
||||||
|
name: bifrost-tls
|
||||||
|
vars:
|
||||||
|
dest_private_key_path: "{{ ironic_inspector_private_key_path }}"
|
||||||
|
dest_private_key_owner: ironic
|
||||||
|
dest_private_key_group: ironic
|
||||||
|
when: enable_tls | bool
|
||||||
|
|
||||||
- name: "Populate keystone for ironic-inspector "
|
- name: "Populate keystone for ironic-inspector "
|
||||||
include: keystone_setup_inspector.yml
|
include: keystone_setup_inspector.yml
|
||||||
when: enable_keystone | bool
|
when: enable_keystone | bool
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
domain_id: "default"
|
domain_id: "default"
|
||||||
enabled: yes
|
enabled: yes
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
@ -66,6 +67,7 @@
|
|||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
update_password: always
|
update_password: always
|
||||||
wait: yes
|
wait: yes
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
@ -76,6 +78,7 @@
|
|||||||
project: "{{ ironic.service_catalog.project_name }}"
|
project: "{{ ironic.service_catalog.project_name }}"
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
wait: yes
|
wait: yes
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
@ -87,6 +90,7 @@
|
|||||||
description: OpenStack Baremetal Service
|
description: OpenStack Baremetal Service
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
wait: yes
|
wait: yes
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
register: baremetal_catalog_service
|
register: baremetal_catalog_service
|
||||||
no_log: true
|
no_log: true
|
||||||
@ -99,6 +103,7 @@
|
|||||||
url: "{{ ironic.keystone.admin_url | default(ironic_api_url) }}"
|
url: "{{ ironic.keystone.admin_url | default(ironic_api_url) }}"
|
||||||
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
|
|
||||||
@ -115,6 +120,7 @@
|
|||||||
url: "{{ ironic.keystone.public_url | default(ironic_public_url) | default(ironic_api_url) }}"
|
url: "{{ ironic.keystone.public_url | default(ironic_public_url) | default(ironic_api_url) }}"
|
||||||
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
|
|
||||||
@ -131,6 +137,7 @@
|
|||||||
url: "{{ ironic.keystone.internal_url | default(ironic_private_url) | default(ironic_api_url) }}"
|
url: "{{ ironic.keystone.internal_url | default(ironic_private_url) | default(ironic_api_url) }}"
|
||||||
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
|
|
||||||
@ -139,6 +146,7 @@
|
|||||||
name: "baremetal_admin"
|
name: "baremetal_admin"
|
||||||
state: present
|
state: present
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
@ -147,6 +155,7 @@
|
|||||||
name: "baremetal_observer"
|
name: "baremetal_observer"
|
||||||
state: present
|
state: present
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
@ -158,6 +167,7 @@
|
|||||||
domain_id: "default"
|
domain_id: "default"
|
||||||
enabled: yes
|
enabled: yes
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
@ -169,6 +179,7 @@
|
|||||||
domain: "default"
|
domain: "default"
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
wait: yes
|
wait: yes
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
@ -179,5 +190,6 @@
|
|||||||
project: "baremetal"
|
project: "baremetal"
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
wait: yes
|
wait: yes
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
default_project: "{{ ironic_inspector.service_catalog.project_name | default('service') }}"
|
default_project: "{{ ironic_inspector.service_catalog.project_name | default('service') }}"
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
wait: yes
|
wait: yes
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
@ -63,6 +64,7 @@
|
|||||||
project: "{{ ironic_inspector.service_catalog.project_name | default('service') }}"
|
project: "{{ ironic_inspector.service_catalog.project_name | default('service') }}"
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
wait: yes
|
wait: yes
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
@ -74,6 +76,7 @@
|
|||||||
description: OpenStack Baremetal Introspection Service
|
description: OpenStack Baremetal Introspection Service
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
wait: yes
|
wait: yes
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
register: introspection_catalog_service
|
register: introspection_catalog_service
|
||||||
no_log: true
|
no_log: true
|
||||||
@ -86,6 +89,7 @@
|
|||||||
url: "{{ ironic_inspector.keystone.admin_url | default(ironic_inspector_api_url) }}"
|
url: "{{ ironic_inspector.keystone.admin_url | default(ironic_inspector_api_url) }}"
|
||||||
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
|
|
||||||
@ -102,6 +106,7 @@
|
|||||||
url: "{{ ironic_inspector.keystone.public_url | default(ironic_inspector_public_url) | default(ironic_inspector_api_url) }}"
|
url: "{{ ironic_inspector.keystone.public_url | default(ironic_inspector_public_url) | default(ironic_inspector_api_url) }}"
|
||||||
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
|
|
||||||
@ -118,6 +123,7 @@
|
|||||||
url: "{{ ironic_inspector.keystone.internal_url | default(ironic_inspector_private_url) | default(ironic_inspector_api_url) }}"
|
url: "{{ ironic_inspector.keystone.internal_url | default(ironic_inspector_private_url) | default(ironic_inspector_api_url) }}"
|
||||||
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
|
|
||||||
@ -130,6 +136,7 @@
|
|||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
update_password: always
|
update_password: always
|
||||||
wait: yes
|
wait: yes
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
@ -140,5 +147,6 @@
|
|||||||
project: baremetal
|
project: baremetal
|
||||||
auth: "{{ keystone_auth }}"
|
auth: "{{ keystone_auth }}"
|
||||||
wait: yes
|
wait: yes
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
environment: "{{ bifrost_venv_env }}"
|
environment: "{{ bifrost_venv_env }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
@ -44,6 +44,11 @@
|
|||||||
- not enable_keystone | bool
|
- not enable_keystone | bool
|
||||||
no_log: yes
|
no_log: yes
|
||||||
|
|
||||||
|
- name: "Set OS_CACERT if required"
|
||||||
|
set_fact:
|
||||||
|
testing_env: "{{ testing_env | combine({'OS_CACERT': tls_certificate_path}) }}"
|
||||||
|
when: enable_tls | bool
|
||||||
|
|
||||||
- name: "Validate API access and at least one conductor"
|
- name: "Validate API access and at least one conductor"
|
||||||
command: baremetal conductor list -f value -c Hostname
|
command: baremetal conductor list -f value -c Hostname
|
||||||
environment: "{{ testing_env | combine(bifrost_venv_env) }}"
|
environment: "{{ testing_env | combine(bifrost_venv_env) }}"
|
||||||
@ -77,6 +82,11 @@
|
|||||||
- enable_inspector | bool
|
- enable_inspector | bool
|
||||||
no_log: yes
|
no_log: yes
|
||||||
|
|
||||||
|
- name: "Set OS_CACERT if required"
|
||||||
|
set_fact:
|
||||||
|
testing_env: "{{ testing_env | combine({'OS_CACERT': tls_certificate_path}) }}"
|
||||||
|
when: enable_tls | bool
|
||||||
|
|
||||||
- name: "Validate introspection API access"
|
- name: "Validate introspection API access"
|
||||||
command: baremetal introspection list
|
command: baremetal introspection list
|
||||||
environment: "{{ testing_env | combine(bifrost_venv_env) }}"
|
environment: "{{ testing_env | combine(bifrost_venv_env) }}"
|
||||||
|
@ -5,6 +5,6 @@ dhcp || reboot
|
|||||||
goto introspect
|
goto introspect
|
||||||
|
|
||||||
:introspect
|
:introspect
|
||||||
kernel {{ ipa_kernel_url }} ipa-inspection-callback-url=http://{{ internal_ip }}:5050/v1/continue {% if fast_track | bool %}ipa-api-url=http://{{ internal_ip }}:6385{% endif %} systemd.journald.forward_to_console=yes BOOTIF=${mac} nofb nomodeset vga=normal console=ttyS0 {{ inspector_extra_kernel_options | default('') }} initrd={{ ipa_ramdisk_url | basename }}
|
kernel {{ ipa_kernel_url }} ipa-inspection-callback-url={{ api_protocol }}://{{ internal_ip }}:5050/v1/continue {% if fast_track | bool %}ipa-api-url={{ api_protocol }}://{{ internal_ip }}:6385{% endif %} systemd.journald.forward_to_console=yes BOOTIF=${mac} nofb nomodeset vga=normal console=ttyS0 {{ inspector_extra_kernel_options | default('') }} ipa-insecure=1 initrd={{ ipa_ramdisk_url | basename }}
|
||||||
initrd {{ ipa_ramdisk_url }}
|
initrd {{ ipa_ramdisk_url }}
|
||||||
boot
|
boot
|
||||||
|
@ -21,6 +21,14 @@ transport_url = rabbit://ironic:{{ironic_db_password }}@{{ message_queue_host |
|
|||||||
transport_url = fake://
|
transport_url = fake://
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
use_ssl = True
|
||||||
|
|
||||||
|
[ssl]
|
||||||
|
cert_file = {{ tls_certificate_path }}
|
||||||
|
key_file = {{ ironic_inspector_private_key_path }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
connection=mysql+pymysql://{{ ironic_inspector.database.username }}:{{ ironic_inspector.database.password }}@{{ ironic_inspector.database.host }}/{{ ironic_inspector.database.name }}?charset=utf8
|
connection=mysql+pymysql://{{ ironic_inspector.database.username }}:{{ ironic_inspector.database.password }}@{{ ironic_inspector.database.host }}/{{ ironic_inspector.database.name }}?charset=utf8
|
||||||
|
|
||||||
@ -50,6 +58,9 @@ endpoint_override = {{ ironic_api_url }}
|
|||||||
username = {{ admin_username }}
|
username = {{ admin_username }}
|
||||||
password = {{ admin_password }}
|
password = {{ admin_password }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
cafile = {{ tls_certificate_path }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if enable_keystone is defined and enable_keystone | bool == true %}
|
{% if enable_keystone is defined and enable_keystone | bool == true %}
|
||||||
[keystone_authtoken]
|
[keystone_authtoken]
|
||||||
@ -60,7 +71,9 @@ password = {{ ironic_inspector.service_catalog.password }}
|
|||||||
user_domain_id = default
|
user_domain_id = default
|
||||||
project_name = service
|
project_name = service
|
||||||
project_domain_id = default
|
project_domain_id = default
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
cafile = {{ tls_certificate_path }}
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
[processing]
|
[processing]
|
||||||
|
@ -40,6 +40,15 @@ http_basic_auth_user_file = /etc/ironic/htpasswd
|
|||||||
log_dir = {{ ironic_log_dir }}
|
log_dir = {{ ironic_log_dir }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
[api]
|
||||||
|
enable_ssl_api = True
|
||||||
|
|
||||||
|
[ssl]
|
||||||
|
cert_file = {{ tls_certificate_path }}
|
||||||
|
key_file = {{ ironic_private_key_path }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
[agent]
|
[agent]
|
||||||
{% if ironic_store_ramdisk_logs | bool %}
|
{% if ironic_store_ramdisk_logs | bool %}
|
||||||
deploy_logs_collect = always
|
deploy_logs_collect = always
|
||||||
@ -50,9 +59,9 @@ deploy_logs_local_path = {{ ironic_agent_deploy_logs_local_path }}
|
|||||||
|
|
||||||
[pxe]
|
[pxe]
|
||||||
{% if testing | bool %}
|
{% if testing | bool %}
|
||||||
pxe_append_params = console=ttyS0
|
pxe_append_params = console=ttyS0 ipa-insecure=1
|
||||||
{% else %}
|
{% else %}
|
||||||
pxe_append_params = systemd.journald.forward_to_console=yes {{ extra_kernel_options | default('') }}
|
pxe_append_params = systemd.journald.forward_to_console=yes ipa-insecure=1 {{ extra_kernel_options | default('') }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
pxe_config_template = $pybasedir/drivers/modules/ipxe_config.template
|
pxe_config_template = $pybasedir/drivers/modules/ipxe_config.template
|
||||||
tftp_server = {{ internal_ip }}
|
tftp_server = {{ internal_ip }}
|
||||||
@ -108,7 +117,7 @@ use_web_server_for_images = true
|
|||||||
{% if enable_inspector | bool == true %}
|
{% if enable_inspector | bool == true %}
|
||||||
[inspector]
|
[inspector]
|
||||||
power_off = {{ power_off_after_inspection }}
|
power_off = {{ power_off_after_inspection }}
|
||||||
extra_kernel_params = {{ inspector_extra_kernel_options | default('') }}
|
extra_kernel_params = ipa-insecure=1 {{ inspector_extra_kernel_options | default('') }}
|
||||||
{% if enable_keystone | bool %}
|
{% if enable_keystone | bool %}
|
||||||
auth_type = password
|
auth_type = password
|
||||||
auth_url = {{ ironic.service_catalog.auth_url }}
|
auth_url = {{ ironic.service_catalog.auth_url }}
|
||||||
@ -118,16 +127,20 @@ user_domain_id = default
|
|||||||
project_name = {{ ironic.service_catalog.project_name }}
|
project_name = {{ ironic.service_catalog.project_name }}
|
||||||
project_domain_id = default
|
project_domain_id = default
|
||||||
region_name = {{ keystone.bootstrap.region_name | default('RegionOne')}}
|
region_name = {{ keystone.bootstrap.region_name | default('RegionOne')}}
|
||||||
callback_endpoint_override = http://{{ internal_ip }}:5050
|
# NOTE(dtantsur): this has to be on internal IP even if public IPs are used
|
||||||
|
callback_endpoint_override = {{ api_protocol }}://{{ internal_ip }}:5050
|
||||||
{% elif noauth_mode | bool %}
|
{% elif noauth_mode | bool %}
|
||||||
auth_type=none
|
auth_type=none
|
||||||
endpoint_override = http://{{ internal_ip }}:5050
|
endpoint_override = {{ ironic_inspector_api_url }}
|
||||||
{% else %}
|
{% else %}
|
||||||
auth_type = http_basic
|
auth_type = http_basic
|
||||||
endpoint_override = http://{{ internal_ip }}:5050
|
endpoint_override = {{ ironic_inspector_api_url }}
|
||||||
username = {{ admin_username }}
|
username = {{ admin_username }}
|
||||||
password = {{ admin_password }}
|
password = {{ admin_password }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
cafile = {{ tls_certificate_path }}
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if enable_keystone is defined and enable_keystone | bool == true %}
|
{% if enable_keystone is defined and enable_keystone | bool == true %}
|
||||||
@ -139,6 +152,9 @@ password = {{ ironic.service_catalog.password }}
|
|||||||
user_domain_id = default
|
user_domain_id = default
|
||||||
project_name = {{ ironic.service_catalog.project_name }}
|
project_name = {{ ironic.service_catalog.project_name }}
|
||||||
project_domain_id = default
|
project_domain_id = default
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
cafile = {{ tls_certificate_path }}
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
[service_catalog]
|
[service_catalog]
|
||||||
@ -158,9 +174,14 @@ auth_type = http_basic
|
|||||||
username = {{ admin_username }}
|
username = {{ admin_username }}
|
||||||
password = {{ admin_password }}
|
password = {{ admin_password }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
endpoint_override = http://{{ internal_ip }}:6385
|
# NOTE(dtantsur): this has to be on internal IP even if public IPs are used
|
||||||
|
endpoint_override = {{ api_protocol }}://{{ internal_ip }}:6385
|
||||||
|
|
||||||
[json_rpc]
|
[json_rpc]
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
use_ssl = True
|
||||||
|
cafile = {{ tls_certificate_path }}
|
||||||
|
{% endif %}
|
||||||
{% if enable_keystone | bool %}
|
{% if enable_keystone | bool %}
|
||||||
auth_strategy = keystone
|
auth_strategy = keystone
|
||||||
auth_url = {{ ironic.service_catalog.auth_url }}
|
auth_url = {{ ironic.service_catalog.auth_url }}
|
||||||
|
@ -4,8 +4,10 @@ network_interface: "virbr0"
|
|||||||
ans_network_interface: "{{ network_interface | replace('-', '_') }}"
|
ans_network_interface: "{{ network_interface | replace('-', '_') }}"
|
||||||
internal_ip: "{{ hostvars[inventory_hostname]['ansible_' + ans_network_interface]['ipv4']['address'] }}"
|
internal_ip: "{{ hostvars[inventory_hostname]['ansible_' + ans_network_interface]['ipv4']['address'] }}"
|
||||||
|
|
||||||
|
enable_tls: false
|
||||||
|
|
||||||
# Service URLs used for communication with them.
|
# Service URLs used for communication with them.
|
||||||
api_protocol: http
|
api_protocol: "{{ 'https' if enable_tls | bool else 'http' }}"
|
||||||
ironic_api_url: "{{ api_protocol }}://{{ internal_ip }}:6385"
|
ironic_api_url: "{{ api_protocol }}://{{ internal_ip }}:6385"
|
||||||
ironic_inspector_api_url: "{{ api_protocol }}://{{ internal_ip }}:5050"
|
ironic_inspector_api_url: "{{ api_protocol }}://{{ internal_ip }}:5050"
|
||||||
|
|
||||||
|
@ -31,6 +31,11 @@
|
|||||||
- "{{ config_region_name is defined }}"
|
- "{{ config_region_name is defined }}"
|
||||||
- "{{ config_auth_url is defined }}"
|
- "{{ config_auth_url is defined }}"
|
||||||
|
|
||||||
|
- name: "Generate TLS parameters"
|
||||||
|
include_role:
|
||||||
|
name: bifrost-tls
|
||||||
|
when: enable_tls | bool
|
||||||
|
|
||||||
- name: "Ensure the ~/.config exists"
|
- name: "Ensure the ~/.config exists"
|
||||||
file:
|
file:
|
||||||
name: "~{{ user | default('root') }}/.config"
|
name: "~{{ user | default('root') }}/.config"
|
||||||
|
@ -13,16 +13,25 @@ clouds:
|
|||||||
project_domain_id: "{{ cloud.1.config_project_domain_id | default('default') }}"
|
project_domain_id: "{{ cloud.1.config_project_domain_id | default('default') }}"
|
||||||
user_domain_id: "{{ cloud.1.config_user_domain_id | default('default') }}"
|
user_domain_id: "{{ cloud.1.config_user_domain_id | default('default') }}"
|
||||||
identity_api_version: "3"
|
identity_api_version: "3"
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
cacert: "{{ tls_certificate_path }}"
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% elif noauth_mode | default(true) | bool %}
|
{% elif noauth_mode | default(true) | bool %}
|
||||||
bifrost:
|
bifrost:
|
||||||
auth_type: "none"
|
auth_type: "none"
|
||||||
baremetal_endpoint_override: {{ ironic_api_url }}
|
baremetal_endpoint_override: {{ ironic_api_url }}
|
||||||
baremetal_introspection_endpoint_override: {{ ironic_inspector_api_url }}
|
baremetal_introspection_endpoint_override: {{ ironic_inspector_api_url }}
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
cacert: "{{ tls_certificate_path }}"
|
||||||
|
{% endif %}
|
||||||
# Deprecated
|
# Deprecated
|
||||||
bifrost-inspector:
|
bifrost-inspector:
|
||||||
auth_type: "none"
|
auth_type: "none"
|
||||||
endpoint: {{ ironic_inspector_api_url }}
|
endpoint: {{ ironic_inspector_api_url }}
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
cacert: "{{ tls_certificate_path }}"
|
||||||
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
bifrost:
|
bifrost:
|
||||||
auth_type: "http_basic"
|
auth_type: "http_basic"
|
||||||
@ -31,6 +40,9 @@ clouds:
|
|||||||
password: "{{ default_password }}"
|
password: "{{ default_password }}"
|
||||||
endpoint: {{ ironic_api_url }}
|
endpoint: {{ ironic_api_url }}
|
||||||
baremetal_introspection_endpoint_override: {{ ironic_inspector_api_url }}
|
baremetal_introspection_endpoint_override: {{ ironic_inspector_api_url }}
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
cacert: "{{ tls_certificate_path }}"
|
||||||
|
{% endif %}
|
||||||
bifrost-admin:
|
bifrost-admin:
|
||||||
auth_type: "http_basic"
|
auth_type: "http_basic"
|
||||||
auth:
|
auth:
|
||||||
@ -38,4 +50,7 @@ clouds:
|
|||||||
password: "{{ admin_password }}"
|
password: "{{ admin_password }}"
|
||||||
endpoint: {{ ironic_api_url }}
|
endpoint: {{ ironic_api_url }}
|
||||||
baremetal_introspection_endpoint_override: {{ ironic_inspector_api_url }}
|
baremetal_introspection_endpoint_override: {{ ironic_inspector_api_url }}
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
cacert: "{{ tls_certificate_path }}"
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -36,3 +36,7 @@ case "${1:-bifrost}" in
|
|||||||
*) echo -e "\nERROR unsupported or unspecified profile: $1\nMust be one of bifrost, bifrost-admin";;
|
*) echo -e "\nERROR unsupported or unspecified profile: $1\nMust be one of bifrost, bifrost-admin";;
|
||||||
esac
|
esac
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
export OS_CACERT="{{ tls_certificate_path }}"
|
||||||
|
{% endif %}
|
||||||
|
@ -35,7 +35,7 @@ network_interface: "virbr0"
|
|||||||
ans_network_interface: "{{ network_interface | replace('-', '_') }}"
|
ans_network_interface: "{{ network_interface | replace('-', '_') }}"
|
||||||
internal_ip: "{{ hostvars[inventory_hostname]['ansible_' + ans_network_interface]['ipv4']['address'] }}"
|
internal_ip: "{{ hostvars[inventory_hostname]['ansible_' + ans_network_interface]['ipv4']['address'] }}"
|
||||||
|
|
||||||
api_protocol: http
|
api_protocol: "{{ 'https' if enable_tls | bool else 'http' }}"
|
||||||
keystone_api_url: "{{ api_protocol }}://{{ internal_ip }}:5000/v3"
|
keystone_api_url: "{{ api_protocol }}://{{ internal_ip }}:5000/v3"
|
||||||
|
|
||||||
# Defaults required by this role that are normally inherited via
|
# Defaults required by this role that are normally inherited via
|
||||||
@ -85,3 +85,9 @@ keystone:
|
|||||||
host: localhost
|
host: localhost
|
||||||
|
|
||||||
pip_opts: "{{ lookup('env', 'PIP_OPTS') | default('') }}"
|
pip_opts: "{{ lookup('env', 'PIP_OPTS') | default('') }}"
|
||||||
|
|
||||||
|
# Enable TLS support.
|
||||||
|
enable_tls: false
|
||||||
|
tls_root: /etc/bifrost
|
||||||
|
tls_certificate_path: "{{ tls_root }}/bifrost.crt"
|
||||||
|
nginx_private_key_path: /etc/nginx/keystone.pem
|
||||||
|
@ -77,6 +77,15 @@
|
|||||||
login_password: "{{ mysql_password | default(None) }}"
|
login_password: "{{ mysql_password | default(None) }}"
|
||||||
when: keystone.database.host == 'localhost'
|
when: keystone.database.host == 'localhost'
|
||||||
|
|
||||||
|
- name: "Generate TLS parameters"
|
||||||
|
include_role:
|
||||||
|
name: bifrost-tls
|
||||||
|
vars:
|
||||||
|
dest_private_key_path: "{{ nginx_private_key_path }}"
|
||||||
|
dest_private_key_owner: "{{ nginx_user }}"
|
||||||
|
dest_private_key_group: "{{ nginx_user }}"
|
||||||
|
when: enable_tls | bool
|
||||||
|
|
||||||
- name: "Create an keystone service group"
|
- name: "Create an keystone service group"
|
||||||
group:
|
group:
|
||||||
name: "keystone"
|
name: "keystone"
|
||||||
|
@ -45,34 +45,15 @@
|
|||||||
- enable_keystone | bool
|
- enable_keystone | bool
|
||||||
- not skip_bootstrap | bool
|
- not skip_bootstrap | bool
|
||||||
|
|
||||||
|
- name: "Upgrade existing installation"
|
||||||
|
include: upgrade.yml
|
||||||
|
when:
|
||||||
|
- enable_keystone | bool
|
||||||
|
- not skip_bootstrap | bool
|
||||||
|
- not skip_start | bool
|
||||||
|
|
||||||
- name: "Start Keystone services"
|
- name: "Start Keystone services"
|
||||||
include: start.yml
|
include: start.yml
|
||||||
when:
|
when:
|
||||||
- enable_keystone | bool
|
- enable_keystone | bool
|
||||||
- not skip_start | bool
|
- not skip_start | bool
|
||||||
|
|
||||||
- name: "Change the bootstrap password from the static value on upgrade"
|
|
||||||
os_user:
|
|
||||||
name: "{{ keystone.bootstrap.username }}"
|
|
||||||
password: "{{ keystone.bootstrap.password }}"
|
|
||||||
update_password: always
|
|
||||||
state: present
|
|
||||||
domain: "default"
|
|
||||||
default_project: "{{ keystone.bootstrap.project_name }}"
|
|
||||||
auth:
|
|
||||||
auth_url: "{{ ironic.service_catalog.auth_url | default('http://127.0.0.1:5000/') }}"
|
|
||||||
username: "{{ keystone.bootstrap.username }}"
|
|
||||||
password: "ChangeThisPa55w0rd"
|
|
||||||
project_name: "{{ keystone.bootstrap.project_name | default('admin') }}"
|
|
||||||
project_domain_id: "default"
|
|
||||||
user_domain_id: "default"
|
|
||||||
wait: yes
|
|
||||||
environment: "{{ bifrost_venv_env }}"
|
|
||||||
no_log: true
|
|
||||||
ignore_errors: true
|
|
||||||
when:
|
|
||||||
- enable_keystone | bool
|
|
||||||
- not skip_bootstrap | bool
|
|
||||||
- test_created_keystone_db is undefined or not test_created_keystone_db.changed | bool
|
|
||||||
- keystone.bootstrap.enabled | bool
|
|
||||||
- keystone.database.host == 'localhost'
|
|
||||||
|
121
playbooks/roles/bifrost-keystone-install/tasks/upgrade.yml
Normal file
121
playbooks/roles/bifrost-keystone-install/tasks/upgrade.yml
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
# implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
---
|
||||||
|
# TODO(dtantsur): can be removed in W
|
||||||
|
- name: "Change the bootstrap password from the static value on upgrade"
|
||||||
|
openstack.cloud.identity_user:
|
||||||
|
name: "{{ keystone.bootstrap.username }}"
|
||||||
|
password: "{{ keystone.bootstrap.password }}"
|
||||||
|
update_password: always
|
||||||
|
state: present
|
||||||
|
domain: "default"
|
||||||
|
default_project: "{{ keystone.bootstrap.project_name }}"
|
||||||
|
auth:
|
||||||
|
auth_url: "{{ ironic.service_catalog.auth_url | default('http://127.0.0.1:5000/') }}"
|
||||||
|
username: "{{ keystone.bootstrap.username }}"
|
||||||
|
password: "ChangeThisPa55w0rd"
|
||||||
|
project_name: "{{ keystone.bootstrap.project_name | default('admin') }}"
|
||||||
|
project_domain_id: "default"
|
||||||
|
user_domain_id: "default"
|
||||||
|
wait: yes
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
|
environment: "{{ bifrost_venv_env }}"
|
||||||
|
no_log: true
|
||||||
|
ignore_errors: true
|
||||||
|
when:
|
||||||
|
- test_created_keystone_db is undefined or not test_created_keystone_db.changed | bool
|
||||||
|
- keystone.bootstrap.enabled | bool
|
||||||
|
- keystone.database.host == 'localhost'
|
||||||
|
|
||||||
|
# NOTE(dtantsur): these tasks are required for update from HTTP to HTTPS
|
||||||
|
|
||||||
|
- name: "Configure keystone auth with http"
|
||||||
|
set_fact:
|
||||||
|
keystone_auth:
|
||||||
|
auth_url: "{{ ironic.service_catalog.auth_url | default(keystone_api_url) | replace('https:', 'http:') }}"
|
||||||
|
username: "{{ keystone.bootstrap.username }}"
|
||||||
|
password: "{{ keystone.bootstrap.password }}"
|
||||||
|
project_name: "{{ keystone.bootstrap.project_name | default('admin') }}"
|
||||||
|
project_domain_id: "default"
|
||||||
|
user_domain_id: "default"
|
||||||
|
no_log: true
|
||||||
|
when: api_protocol == 'https'
|
||||||
|
|
||||||
|
- name: "Configure keystone auth with https"
|
||||||
|
set_fact:
|
||||||
|
keystone_auth:
|
||||||
|
auth_url: "{{ ironic.service_catalog.auth_url | default(keystone_api_url) | replace('http:', 'https:') }}"
|
||||||
|
username: "{{ keystone.bootstrap.username }}"
|
||||||
|
password: "{{ keystone.bootstrap.password }}"
|
||||||
|
project_name: "{{ keystone.bootstrap.project_name | default('admin') }}"
|
||||||
|
project_domain_id: "default"
|
||||||
|
user_domain_id: "default"
|
||||||
|
# NOTE(dtantsur): we cannot use tls_certificate_path as it won't be present
|
||||||
|
# on an upgrade to non-TLS.
|
||||||
|
keystone_ca_cert: /etc/bifrost/bifrost.crt
|
||||||
|
no_log: true
|
||||||
|
when: api_protocol == 'http'
|
||||||
|
|
||||||
|
- name: "Ensure keystone service record for keystone"
|
||||||
|
openstack.cloud.catalog_service:
|
||||||
|
state: present
|
||||||
|
name: "keystone"
|
||||||
|
service_type: "identity"
|
||||||
|
auth: "{{ keystone_auth }}"
|
||||||
|
wait: yes
|
||||||
|
ca_cert: "{{ keystone_ca_cert | default(omit) }}"
|
||||||
|
environment: "{{ bifrost_venv_env }}"
|
||||||
|
register: identity_catalog_service
|
||||||
|
ignore_errors: true
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: "Update identity internal endpoint"
|
||||||
|
openstack.cloud.endpoint:
|
||||||
|
state: present
|
||||||
|
service: "{{ identity_catalog_service.id }}"
|
||||||
|
endpoint_interface: internal
|
||||||
|
url: "{{ keystone.bootstrap.internal_url | default(keystone_private_url) | default(keystone_api_url) }}"
|
||||||
|
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
||||||
|
auth: "{{ keystone_auth }}"
|
||||||
|
ca_cert: "{{ keystone_ca_cert | default(omit) }}"
|
||||||
|
ignore_errors: true
|
||||||
|
no_log: true
|
||||||
|
when: identity_catalog_service.id is defined
|
||||||
|
|
||||||
|
- name: "Update identity admin endpoint"
|
||||||
|
openstack.cloud.endpoint:
|
||||||
|
state: present
|
||||||
|
service: "{{ identity_catalog_service.id }}"
|
||||||
|
endpoint_interface: admin
|
||||||
|
url: "{{ keystone.bootstrap.admin_url | default(keystone_api_url) }}"
|
||||||
|
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
||||||
|
auth: "{{ keystone_auth }}"
|
||||||
|
ca_cert: "{{ keystone_ca_cert | default(omit) }}"
|
||||||
|
ignore_errors: true
|
||||||
|
no_log: true
|
||||||
|
when: identity_catalog_service.id is defined
|
||||||
|
|
||||||
|
# NOTE(dtantsur): the public endpoint MUST go last, otherwise the other
|
||||||
|
# endpoints will fail to update.
|
||||||
|
- name: "Update identity public endpoint"
|
||||||
|
openstack.cloud.endpoint:
|
||||||
|
state: present
|
||||||
|
service: "{{ identity_catalog_service.id }}"
|
||||||
|
endpoint_interface: public
|
||||||
|
url: "{{ keystone.bootstrap.public_url | default(keystone_public_url) | default(keystone_api_url) }}"
|
||||||
|
region: "{{ keystone.bootstrap.region_name | default('RegionOne') }}"
|
||||||
|
auth: "{{ keystone_auth }}"
|
||||||
|
ca_cert: "{{ keystone_ca_cert | default(omit) }}"
|
||||||
|
ignore_errors: true
|
||||||
|
no_log: true
|
||||||
|
when: identity_catalog_service.id is defined
|
@ -1,6 +1,12 @@
|
|||||||
# {{ ansible_managed }}
|
# {{ ansible_managed }}
|
||||||
server {
|
server {
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
listen 5000 ssl;
|
||||||
|
ssl_certificate {{ tls_certificate_path }};
|
||||||
|
ssl_certificate_key {{ nginx_private_key_path }};
|
||||||
|
{% else %}
|
||||||
listen 5000;
|
listen 5000;
|
||||||
|
{% endif %}
|
||||||
access_log /var/log/nginx/keystone/access.log;
|
access_log /var/log/nginx/keystone/access.log;
|
||||||
error_log /var/log/nginx/keystone/error.log;
|
error_log /var/log/nginx/keystone/error.log;
|
||||||
location / {
|
location / {
|
||||||
@ -10,7 +16,13 @@ server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
server {
|
server {
|
||||||
|
{% if enable_tls | bool %}
|
||||||
|
listen 35357 ssl;
|
||||||
|
ssl_certificate {{ tls_certificate_path }};
|
||||||
|
ssl_certificate_key {{ nginx_private_key_path }};
|
||||||
|
{% else %}
|
||||||
listen 35357;
|
listen 35357;
|
||||||
|
{% endif %}
|
||||||
access_log /var/log/nginx/keystone/access.log;
|
access_log /var/log/nginx/keystone/access.log;
|
||||||
error_log /var/log/nginx/keystone/error.log;
|
error_log /var/log/nginx/keystone/error.log;
|
||||||
location / {
|
location / {
|
||||||
|
86
playbooks/roles/bifrost-tls/README.md
Normal file
86
playbooks/roles/bifrost-tls/README.md
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
bifrost-tls
|
||||||
|
===========
|
||||||
|
|
||||||
|
This role generates TLS certificates for Bifrost and copies the private key to
|
||||||
|
a predefined location.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
This role requires:
|
||||||
|
|
||||||
|
- Ansible 2.9
|
||||||
|
|
||||||
|
Role Variables
|
||||||
|
--------------
|
||||||
|
|
||||||
|
generate_tls: Whether the generate new certificates or use existing ones.
|
||||||
|
If the latter, this role only handles copying the private key,
|
||||||
|
all files have to exist. Defaults to `false` to avoid overwriting
|
||||||
|
operator's files.
|
||||||
|
|
||||||
|
network_interface: Network interface services are listening on.
|
||||||
|
|
||||||
|
tls_common_name: The common name of the certificate. Defaults to the host's
|
||||||
|
full domain name (FQDN).
|
||||||
|
|
||||||
|
tls_hosts: A list of valid IP addresses for the generated certificate. Defaults
|
||||||
|
to `public_ip` (if set), `private_ip` (if set), `internal_ip` and
|
||||||
|
127.0.0.1. The host `localhost` is always added.
|
||||||
|
|
||||||
|
tls_host_names: A list of valid host names for the generated certificate.
|
||||||
|
Defaults to the host's FQDN + `localhost`.
|
||||||
|
|
||||||
|
tls_certificate_path: Path to the TLS certificate. Can be generated.
|
||||||
|
|
||||||
|
tls_private_key_path: Path to the private key. Can be generated.
|
||||||
|
|
||||||
|
tls_csr_path: Path to the signing request. Can be generated.
|
||||||
|
|
||||||
|
tls_force_regenerate: Boolean, whether to regenerate existing certificates.
|
||||||
|
Defaults to `false`.
|
||||||
|
|
||||||
|
dest_private_key_path: Destination to copy the private key to. Defaults to
|
||||||
|
undefined (not copying).
|
||||||
|
|
||||||
|
dest_private_key_owner: Owner of the destination private key. Defaults to root.
|
||||||
|
|
||||||
|
dest_private_key_group: Group of the destination private key. Defaults to root.
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
None at this time.
|
||||||
|
|
||||||
|
Example Playbook
|
||||||
|
----------------
|
||||||
|
|
||||||
|
- hosts: localhost
|
||||||
|
connection: local
|
||||||
|
name: "Generate TLS parameters"
|
||||||
|
become: yes
|
||||||
|
gather_facts: yes
|
||||||
|
roles:
|
||||||
|
- role: bifrost-tls
|
||||||
|
generate_tls: true
|
||||||
|
tls_common_name: example.com
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
Author Information
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Ironic Developers
|
34
playbooks/roles/bifrost-tls/defaults/main.yml
Normal file
34
playbooks/roles/bifrost-tls/defaults/main.yml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
generate_tls: false
|
||||||
|
|
||||||
|
# NOTE(dtantsur): we don't want to make our generated certificates accepted
|
||||||
|
# system-wide, hence storing them here.
|
||||||
|
tls_root: /etc/bifrost
|
||||||
|
tls_certificate_path: "{{ tls_root }}/bifrost.crt"
|
||||||
|
tls_private_key_path: "{{ tls_root }}/bifrost.pem"
|
||||||
|
tls_csr_path: "{{ tls_root }}/bifrost.csr"
|
||||||
|
|
||||||
|
# Force re-generating of certificates.
|
||||||
|
tls_force_regenerate: false
|
||||||
|
|
||||||
|
# Copy the resulting key to:
|
||||||
|
#dest_private_key_path:
|
||||||
|
dest_private_key_owner: root
|
||||||
|
dest_private_key_group: root
|
||||||
|
# Don't change this unless you really know what you're doing.
|
||||||
|
dest_private_key_mode: 0600
|
||||||
|
|
||||||
|
network_interface: "virbr0"
|
||||||
|
ans_network_interface: "{{ network_interface | replace('-', '_') }}"
|
||||||
|
internal_interface: "{{ hostvars[inventory_hostname]['ansible_' + ans_network_interface]['ipv4'] }}"
|
||||||
|
internal_ip: "{{ internal_interface['address'] }}"
|
||||||
|
|
||||||
|
# Common name for the certificate.
|
||||||
|
tls_common_name: "{{ ansible_fqdn }}"
|
||||||
|
tls_hosts: >-
|
||||||
|
{{ [internal_ip, '127.0.0.1']
|
||||||
|
+ ([public_ip] if public_ip is defined else [])
|
||||||
|
+ ([private_ip] if private_ip is defined else []) }}
|
||||||
|
tls_host_names:
|
||||||
|
- localhost
|
||||||
|
- "{{ ansible_fqdn }}"
|
54
playbooks/roles/bifrost-tls/tasks/main.yml
Normal file
54
playbooks/roles/bifrost-tls/tasks/main.yml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
- name: "Ensure the certificate root directory"
|
||||||
|
file:
|
||||||
|
path: "{{ tls_root }}"
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0755
|
||||||
|
when: generate_tls | bool
|
||||||
|
|
||||||
|
- name: "Generate private key"
|
||||||
|
openssl_privatekey:
|
||||||
|
path: "{{ tls_private_key_path }}"
|
||||||
|
force: "{{ tls_force_regenerate | bool }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0600
|
||||||
|
when: generate_tls | bool
|
||||||
|
|
||||||
|
- name: "Generate certificate signing request"
|
||||||
|
openssl_csr:
|
||||||
|
path: "{{ tls_csr_path }}"
|
||||||
|
privatekey_path: "{{ tls_private_key_path }}"
|
||||||
|
force: "{{ tls_force_regenerate | bool }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0600
|
||||||
|
common_name: "{{ tls_common_name }}"
|
||||||
|
subject_alt_name: >-
|
||||||
|
{{ (tls_hosts | map('regex_replace', '^', 'IP:') | list)
|
||||||
|
+ (tls_host_names | map('regex_replace', '^', 'DNS:') | list) }}
|
||||||
|
when: generate_tls | bool
|
||||||
|
|
||||||
|
- name: "Generate self-signed TLS certificates"
|
||||||
|
openssl_certificate:
|
||||||
|
provider: selfsigned
|
||||||
|
path: "{{ tls_certificate_path }}"
|
||||||
|
privatekey_path: "{{ tls_private_key_path }}"
|
||||||
|
csr_path: "{{ tls_csr_path }}"
|
||||||
|
force: "{{ tls_force_regenerate | bool }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
when: generate_tls | bool
|
||||||
|
|
||||||
|
- name: "Copy the key to the destination"
|
||||||
|
copy:
|
||||||
|
src: "{{ tls_private_key_path }}"
|
||||||
|
dest: "{{ dest_private_key_path }}"
|
||||||
|
remote_src: yes
|
||||||
|
owner: "{{ dest_private_key_owner }}"
|
||||||
|
group: "{{ dest_private_key_group }}"
|
||||||
|
mode: "{{ dest_private_key_mode }}"
|
||||||
|
when: dest_private_key_path is defined
|
@ -20,6 +20,7 @@
|
|||||||
cloud: "{{ cloud_name | default(omit) }}"
|
cloud: "{{ cloud_name | default(omit) }}"
|
||||||
auth_type: "{{ auth_type | default(omit) }}"
|
auth_type: "{{ auth_type | default(omit) }}"
|
||||||
auth: "{{ auth | default(omit) }}"
|
auth: "{{ auth | default(omit) }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
ironic_url: "{{ ironic_url | default(omit) }}"
|
ironic_url: "{{ ironic_url | default(omit) }}"
|
||||||
uuid: "{{ uuid | default() }}"
|
uuid: "{{ uuid | default() }}"
|
||||||
name: "{{ name | default() }}"
|
name: "{{ name | default() }}"
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
cloud: "{{ cloud_name | default(omit) }}"
|
cloud: "{{ cloud_name | default(omit) }}"
|
||||||
auth_type: "{{ auth_type | default(omit) }}"
|
auth_type: "{{ auth_type | default(omit) }}"
|
||||||
auth: "{{ auth | default(omit) }}"
|
auth: "{{ auth | default(omit) }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
ironic_url: "{{ ironic_url | default(omit) }}"
|
ironic_url: "{{ ironic_url | default(omit) }}"
|
||||||
driver: ""
|
driver: ""
|
||||||
uuid: "{{ uuid | default() }}"
|
uuid: "{{ uuid | default() }}"
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
cloud: "{{ cloud_name | default(omit) }}"
|
cloud: "{{ cloud_name | default(omit) }}"
|
||||||
auth_type: "{{ auth_type | default(omit) }}"
|
auth_type: "{{ auth_type | default(omit) }}"
|
||||||
auth: "{{ auth | default(omit) }}"
|
auth: "{{ auth | default(omit) }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
ironic_url: "{{ ironic_url | default(omit) }}"
|
ironic_url: "{{ ironic_url | default(omit) }}"
|
||||||
driver: "{{ driver }}"
|
driver: "{{ driver }}"
|
||||||
uuid: "{{ uuid | default() }}"
|
uuid: "{{ uuid | default() }}"
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
cloud: "{{ cloud_name | default(omit) }}"
|
cloud: "{{ cloud_name | default(omit) }}"
|
||||||
auth_type: "{{ auth_type | default(omit) }}"
|
auth_type: "{{ auth_type | default(omit) }}"
|
||||||
auth: "{{ auth | default(omit) }}"
|
auth: "{{ auth | default(omit) }}"
|
||||||
|
ca_cert: "{{ tls_certificate_path | default(omit) }}"
|
||||||
ironic_url: "{{ ironic_url | default(omit) }}"
|
ironic_url: "{{ ironic_url | default(omit) }}"
|
||||||
uuid: "{{ uuid | default('') }}"
|
uuid: "{{ uuid | default('') }}"
|
||||||
name: "{{ name | default('') }}"
|
name: "{{ name | default('') }}"
|
||||||
|
14
releasenotes/notes/tls-988e725820bb8aca.yaml
Normal file
14
releasenotes/notes/tls-988e725820bb8aca.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Supports TLS configuration by setting ``enable_tls=true`` and, optionally,
|
||||||
|
``generate_tls=true``. The corresponding ``bifrost-cli`` argument is
|
||||||
|
``--enable-tls`` (auto-generated certificates only).
|
||||||
|
issues:
|
||||||
|
- |
|
||||||
|
When using Keystone for authentication, it may not be possible to disable
|
||||||
|
TLS after enabling it if the certificate is in a non-standard location.
|
||||||
|
- |
|
||||||
|
Due to upgrade limitations, it may not be possible to enable TLS on
|
||||||
|
upgrading from a previous version. Do an upgrade first, then enable TLS
|
||||||
|
in a separate installation step.
|
@ -13,6 +13,7 @@ ENABLE_KEYSTONE="${ENABLE_KEYSTONE:-false}"
|
|||||||
ZUUL_BRANCH=${ZUUL_BRANCH:-}
|
ZUUL_BRANCH=${ZUUL_BRANCH:-}
|
||||||
CLI_TEST=${CLI_TEST:-false}
|
CLI_TEST=${CLI_TEST:-false}
|
||||||
BOOT_MODE=${BOOT_MODE:-}
|
BOOT_MODE=${BOOT_MODE:-}
|
||||||
|
ENABLE_TLS=${ENABLE_TLS:-false}
|
||||||
|
|
||||||
# Set defaults for ansible command-line options to drive the different
|
# Set defaults for ansible command-line options to drive the different
|
||||||
# tests.
|
# tests.
|
||||||
@ -178,6 +179,8 @@ ${ANSIBLE} -vvvv \
|
|||||||
-e enable_keystone=${ENABLE_KEYSTONE} \
|
-e enable_keystone=${ENABLE_KEYSTONE} \
|
||||||
-e wait_for_node_deploy=${WAIT_FOR_DEPLOY} \
|
-e wait_for_node_deploy=${WAIT_FOR_DEPLOY} \
|
||||||
-e not_enrolled_data_file=${BAREMETAL_DATA_FILE}.rest \
|
-e not_enrolled_data_file=${BAREMETAL_DATA_FILE}.rest \
|
||||||
|
-e enable_tls=${ENABLE_TLS} \
|
||||||
|
-e generate_tls=${ENABLE_TLS} \
|
||||||
-e skip_install=${CLI_TEST} \
|
-e skip_install=${CLI_TEST} \
|
||||||
-e skip_package_install=${CLI_TEST} \
|
-e skip_package_install=${CLI_TEST} \
|
||||||
-e skip_bootstrap=${CLI_TEST} \
|
-e skip_bootstrap=${CLI_TEST} \
|
||||||
|
@ -83,6 +83,7 @@
|
|||||||
- openstack/keystone
|
- openstack/keystone
|
||||||
vars:
|
vars:
|
||||||
enable_keystone: true
|
enable_keystone: true
|
||||||
|
enable_tls: true
|
||||||
test_driver: redfish
|
test_driver: redfish
|
||||||
|
|
||||||
- job:
|
- job:
|
||||||
@ -109,6 +110,7 @@
|
|||||||
- openstack/keystone
|
- openstack/keystone
|
||||||
vars:
|
vars:
|
||||||
enable_keystone: true
|
enable_keystone: true
|
||||||
|
enable_tls: true
|
||||||
test_driver: redfish
|
test_driver: redfish
|
||||||
|
|
||||||
- job:
|
- job:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user