From 6ec96ab74a47fabd073756ee08f9e096fb512934 Mon Sep 17 00:00:00 2001 From: Jonathan Rosser Date: Tue, 21 Mar 2023 14:38:09 +0000 Subject: [PATCH] Define individual haproxy services for each console type The current code in openstack-ansible assumes that only one console type is active at once, with a special case for when ironic is deployed to also enable serial consoles. This does not cover the case when different nova compute nodes may require different console types, such as spice/novnc for x86_64 and serialconsole for aarch64. This patch maintains the same external variables (nova_console_tpye and ironic_console_type) - but makes specific haproxy backends for each type. This is the first step required to allow multuple console types to be enabled at the same time for nova compute nodes. Depends-On: https://review.opendev.org/c/openstack/openstack-ansible/+/879069 Change-Id: Ib6f77036639568321d07e9f478c1e087bd9fee91 --- doc/source/user/security/security-headers.rst | 4 +- inventory/group_vars/all/nova.yml | 21 ++---- inventory/group_vars/haproxy/haproxy.yml | 64 +++++++++++++------ 3 files changed, 53 insertions(+), 36 deletions(-) diff --git a/doc/source/user/security/security-headers.rst b/doc/source/user/security/security-headers.rst index 9a770c872a..b7192996aa 100644 --- a/doc/source/user/security/security-headers.rst +++ b/doc/source/user/security/security-headers.rst @@ -132,6 +132,6 @@ Security Policy to allow access to your authorisation server by overriding the upgrade-insecure-requests; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; - child-src 'self' {{ external_lb_vip_address }}:{{ nova_console_port }}; - frame-src 'self' {{ external_lb_vip_address }}:{{ nova_console_port }}; + child-src 'self' {{ external_lb_vip_address }}:{{ nova_spice_html5proxy_base_port }} {{ external_lb_vip_address }}:{{ nova_novncproxy_port }} {{ external_lb_vip_address }}:{{ nova_serialconsoleproxy_port }}; + frame-src 'self' {{ external_lb_vip_address }}:{{ nova_spice_html5proxy_base_port }} {{ external_lb_vip_address }}:{{ nova_novncproxy_port }} {{ external_lb_vip_address }}:{{ nova_serialconsoleproxy_port }}; " diff --git a/inventory/group_vars/all/nova.yml b/inventory/group_vars/all/nova.yml index 6d7b09e6ff..2d58af18fa 100644 --- a/inventory/group_vars/all/nova.yml +++ b/inventory/group_vars/all/nova.yml @@ -19,20 +19,9 @@ nova_metadata_protocol: "{{ openstack_service_internaluri_proto | default('http' nova_metadata_insecure: "{{ keystone_service_internaluri_insecure | default(False) }}" # Consumed by haproxy endpoints -nova_consoles: - spice: - port: "{{ nova_spice_html5proxy_base_port | default('6082') }}" - path: "/spice_auto.html" - novnc: - port: "{{ nova_novncproxy_port | default('6080') }}" - path: "/vnc.html" - serialconsole: - port: "{{ nova_serialconsoleproxy_port | default('6083') }}" - path: "/" - disabled: - port: 0 - path: "" +nova_spice_html5proxy_base_port: 6082 +nova_novncproxy_port: 6080 +nova_serialconsoleproxy_port: 6083 -nova_console_type: "{{ (ansible_facts['architecture'] == 'aarch64') | ternary('serialconsole', 'novnc') }}" -nova_console_port: "{{ nova_consoles[nova_console_type]['port'] }}" -nova_console_path: "{{ nova_consoles[nova_console_type]['path'] }}" +# Default nova console type +nova_console_type: "{{ (ansible_facts['architecture'] == 'aarch64') | ternary('serialconsole', 'novnc') }}" \ No newline at end of file diff --git a/inventory/group_vars/haproxy/haproxy.yml b/inventory/group_vars/haproxy/haproxy.yml index b2b91f838a..a0d0d0768a 100644 --- a/inventory/group_vars/haproxy/haproxy.yml +++ b/inventory/group_vars/haproxy/haproxy.yml @@ -53,8 +53,8 @@ haproxy_security_headers_csp: > upgrade-insecure-requests; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; - child-src 'self' {{ external_lb_vip_address }}:{{ nova_console_port }}; - frame-src 'self' {{ external_lb_vip_address }}:{{ nova_console_port }}; + child-src 'self' {{ external_lb_vip_address }}:{{ nova_spice_html5proxy_base_port }} {{ external_lb_vip_address }}:{{ nova_novncproxy_port }} {{ external_lb_vip_address }}:{{ nova_serialconsoleproxy_port }}; + frame-src 'self' {{ external_lb_vip_address }}:{{ nova_spice_html5proxy_base_port }} {{ external_lb_vip_address }}:{{ nova_novncproxy_port }} {{ external_lb_vip_address }}:{{ nova_serialconsoleproxy_port }}; connect-src 'self' {{ external_lb_vip_address }}:* wss://{{ external_lb_vip_address }}:{{ ironic_console_port }}; img-src 'self' data:; worker-src blob:; @@ -412,33 +412,58 @@ haproxy_nova_api_compute_service: # on the nova console container it has to be run in TCP mode. haproxy_nova_console_http_mode: "{{ not (nova_console_user_ssl_cert is defined and nova_console_user_ssl_key is defined) }}" -haproxy_nova_console_service: - haproxy_service_name: nova_console - haproxy_backend_nodes: "{{ groups['nova_console'] | default([]) + ((ironic_console_type == nova_console_type) | ternary(groups['ironic_console'] | default([]), [])) }}" + +haproxy_nova_spice_console_service: + haproxy_service_name: nova_spice_console + haproxy_backend_nodes: "{{ groups['nova_console'] | default([]) }}" haproxy_ssl: "{{ haproxy_ssl }}" haproxy_ssl_all_vips: "{{ haproxy_ssl_all_vips }}" - haproxy_port: "{{ nova_console_port }}" + haproxy_port: "{{ nova_spice_html5proxy_base_port | default('6082') }}" haproxy_balance_type: "{{ haproxy_nova_console_http_mode | ternary('http', 'tcp') }}" haproxy_timeout_client: 60m haproxy_timeout_server: 60m haproxy_balance_alg: source - haproxy_backend_options: "{{ haproxy_nova_console_http_mode | ternary(['httpchk HEAD ' + nova_console_path + ' HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck'], []) }}" + haproxy_backend_options: "{{ haproxy_nova_console_http_mode | ternary(['httpchk HEAD /spice_auto.html HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck'], []) }}" haproxy_backend_httpcheck_options: "{{ haproxy_nova_console_http_mode | ternary(['expect status 200'], []) }}" - haproxy_service_enabled: "{{ groups['nova_console'] is defined and groups['nova_console'] | length > 0 and nova_console_type != 'disabled' }}" + haproxy_service_enabled: "{{ groups['nova_console'] is defined and groups['nova_console'] | length > 0 and nova_console_type == 'spice' }}" -# run a seperate service for the ironic nova console proxy when then console type is not the same as the one used by -# nova-compute managed virtual machines -haproxy_nova_ironic_console_service: - haproxy_service_name: nova_ironic_console - haproxy_backend_nodes: "{{ groups['ironic_console'] | default([]) }}" +haproxy_nova_serial_console_service: + haproxy_service_name: nova_serial_console + haproxy_backend_nodes: "{{ groups['nova_console'] | default([]) + ((ironic_console_type == 'serialconsole') | ternary(groups['ironic_console'] | default([]), [])) }}" haproxy_ssl: "{{ haproxy_ssl }}" haproxy_ssl_all_vips: "{{ haproxy_ssl_all_vips }}" - haproxy_port: "{{ ironic_console_port }}" - haproxy_balance_type: http + haproxy_port: "{{ nova_serialconsoleproxy_port | default('6083') }}" + haproxy_balance_type: "{{ haproxy_nova_console_http_mode | ternary('http', 'tcp') }}" + haproxy_timeout_client: 60m + haproxy_timeout_server: 60m haproxy_balance_alg: source - haproxy_timeout_client: 10m # see https://docs.openstack.org/ironic/latest/admin/console.html#configuring-ha - haproxy_timeout_server: 10m # ditto - haproxy_service_enabled: "{{ groups['ironic_console'] is defined and groups['ironic_console'] | length > 0 and ironic_console_type != nova_console_type }}" + haproxy_backend_options: "{{ haproxy_nova_console_http_mode | ternary(['httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck'], []) }}" + haproxy_backend_httpcheck_options: "{{ haproxy_nova_console_http_mode | ternary(['expect status 200'], []) }}" + haproxy_service_enabled: "{{ (groups['nova_console'] is defined and groups['nova_console'] | length > 0 and nova_console_type == 'serial') or + (groups['ironic_console'] is defined and groups['ironic_console'] | length > 0 and ironic_console_type == 'serial') }}" + +haproxy_nova_novnc_console_service: + haproxy_service_name: nova_novnc_console + haproxy_backend_nodes: "{{ groups['nova_console'] | default([]) }}" + haproxy_ssl: "{{ haproxy_ssl }}" + haproxy_ssl_all_vips: "{{ haproxy_ssl_all_vips }}" + haproxy_port: "{{ nova_novncproxy_port | default('6080') }}" + haproxy_balance_type: "{{ haproxy_nova_console_http_mode | ternary('http', 'tcp') }}" + haproxy_timeout_client: 60m + haproxy_timeout_server: 60m + haproxy_balance_alg: source + haproxy_backend_options: "{{ haproxy_nova_console_http_mode | ternary(['httpchk HEAD /vnc.html HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck'], []) }}" + haproxy_backend_httpcheck_options: "{{ haproxy_nova_console_http_mode | ternary(['expect status 200'], []) }}" + haproxy_service_enabled: "{{ groups['nova_console'] is defined and groups['nova_console'] | length > 0 and nova_console_type == 'novnc' }}" + +# NOTE(jrosser) Clean up legacy console haproxy configs from previous releases +haproxy_nova_console_service: + haproxy_service_name: nova_console + haproxy_service_enabled: False + +haproxy_nova_ironic_console_service: + haproxy_service_name: nova_ironic_console + haproxy_service_enabled: False haproxy_octavia_service: haproxy_service_name: octavia @@ -623,6 +648,9 @@ haproxy_default_services: - service: "{{ haproxy_neutron_server_service | combine(haproxy_neutron_server_service_overrides | default({})) }}" - service: "{{ haproxy_nova_api_metadata_service | combine(haproxy_nova_api_metadata_service_overrides | default({})) }}" - service: "{{ haproxy_nova_api_compute_service | combine(haproxy_nova_api_compute_service_overrides | default({})) }}" + - service: "{{ haproxy_nova_spice_console_service | combine(haproxy_nova_spice_console_service_overrides | default({})) }}" + - service: "{{ haproxy_nova_novnc_console_service | combine(haproxy_nova_novnc_console_service_overrides | default({})) }}" + - service: "{{ haproxy_nova_serial_console_service | combine(haproxy_nova_serial_console_service_overrides | default({})) }}" - service: "{{ haproxy_nova_console_service | combine(haproxy_nova_console_service_overrides | default({})) }}" - service: "{{ haproxy_nova_ironic_console_service | combine(haproxy_nova_ironic_console_service_overrides | default({})) }}" - service: "{{ haproxy_octavia_service | combine(haproxy_octavia_service_overrides | default({})) }}"