Merge "RabbitMQ TLS support"
diff --git a/README.rst b/README.rst
index ab61b71..dd23ebf 100644
--- a/README.rst
+++ b/README.rst
@@ -146,6 +146,61 @@
# Add key without value to remove line from policy.json
'compute:create:attach_network':
+
+Client-side RabbitMQ TLS configuration:
+---------------------------------------
+
+To enable TLS for oslo.messaging you need to provide the CA certificate.
+
+By default system-wide CA certs is used. Nothing should be specified except `ssl.enabled`.
+
+.. code-block:: yaml
+
+ nova:
+ controller:
+ ....
+ message_queue:
+ ssl:
+ enabled: True
+
+
+
+Use `cacert_file` option to specify the CA-cert file path explicitly:
+
+.. code-block:: yaml
+
+ nova:
+ controller:
+ ....
+ message_queue:
+ ssl:
+ enabled: True
+ cacert_file: /etc/ssl/rabbitmq-ca.pem
+
+To manage content of the `cacert_file` use the `cacert` option:
+
+.. code-block:: yaml
+
+ nova:
+ controller:
+ ....
+ message_queue:
+ ssl:
+ enabled: True
+ cacert: |
+
+ -----BEGIN CERTIFICATE-----
+ ...
+ -----END CERTIFICATE-------
+
+ cacert_file: /etc/openstack/rabbitmq-ca.pem
+
+
+Notice:
+ * The `message_queue.port` is set to **5671** (AMQPS) by default if `ssl.enabled=True`.
+ * Use `message_queue.ssl.version` if you need to specify protocol version. By default is TLSv1 for python < 2.7.9 and TLSv1_2 for version above.
+
+
Compute nodes
-------------
@@ -258,7 +313,7 @@
.. code-block:: yaml
nova:
- controller:
+ compute:
....
message_queue:
engine: rabbitmq
@@ -271,7 +326,6 @@
virtual_host: '/openstack'
....
-
Nova with ephemeral configured with Ceph
.. code-block:: yaml
diff --git a/nova/compute.sls b/nova/compute.sls
index 128c570..641305e 100644
--- a/nova/compute.sls
+++ b/nova/compute.sls
@@ -1,4 +1,4 @@
-{%- from "nova/map.jinja" import compute with context %}
+{%- from "nova/map.jinja" import compute, system_cacerts_file with context %}
{%- if compute.get('enabled') %}
@@ -75,6 +75,21 @@
- template: jinja
- require:
- pkg: nova_compute_packages
+
+{%- if compute.message_queue.get('ssl',{}).get('enabled',False) %}
+rabbitmq_ca:
+{%- if compute.message_queue.ssl.cacert is defined %}
+ file.managed:
+ - name: {{ compute.message_queue.ssl.cacert_file }}
+ - contents_pillar: nova:compute:message_queue:ssl:cacert
+ - mode: 0444
+ - makedirs: true
+{%- else %}
+ file.exists:
+ - name: {{ compute.message_queue.ssl.get('cacert_file', system_cacerts_file) }}
+{%- endif %}
+{%- endif %}
+
{%- endif %}
nova_compute_services:
@@ -83,6 +98,9 @@
- names: {{ compute.services }}
- watch:
- file: /etc/nova/nova.conf
+ {%- if compute.message_queue.get('ssl',{}).get('enabled',False) %}
+ - file: rabbitmq_ca
+ {%- endif %}
{%- set ident = compute.identity %}
diff --git a/nova/controller.sls b/nova/controller.sls
index 15531f2..f898295 100644
--- a/nova/controller.sls
+++ b/nova/controller.sls
@@ -1,4 +1,4 @@
-{% from "nova/map.jinja" import controller with context %}
+{% from "nova/map.jinja" import controller, system_cacerts_file with context %}
{%- if controller.get('enabled') %}
@@ -24,6 +24,20 @@
pkg.installed:
- names: {{ controller.pkgs }}
+{%- if controller.message_queue.get('ssl',{}).get('enabled',False) %}
+rabbitmq_ca:
+{%- if controller.message_queue.ssl.cacert is defined %}
+ file.managed:
+ - name: {{ controller.message_queue.ssl.cacert_file }}
+ - contents_pillar: nova:controller:message_queue:ssl:cacert
+ - mode: 0444
+ - makedirs: true
+{%- else %}
+ file.exists:
+ - name: {{ controller.message_queue.ssl.get('cacert_file', system_cacerts_file) }}
+{%- endif %}
+{%- endif %}
+
{%- if not salt['user.info']('nova') %}
user_nova:
user.present:
@@ -278,6 +292,9 @@
- watch:
- file: /etc/nova/nova.conf
- file: /etc/nova/api-paste.ini
+ {%- if controller.message_queue.get('ssl',{}).get('enabled',False) %}
+ - file: rabbitmq_ca
+ {%- endif %}
{%- if grains.get('virtual_subtype', None) == "Docker" %}
diff --git a/nova/files/mitaka/nova-compute.conf.Debian b/nova/files/mitaka/nova-compute.conf.Debian
index f5db5e7..bdd636c 100644
--- a/nova/files/mitaka/nova-compute.conf.Debian
+++ b/nova/files/mitaka/nova-compute.conf.Debian
@@ -1,4 +1,4 @@
-{%- from "nova/map.jinja" import compute with context %}
+{%- from "nova/map.jinja" import compute, system_cacerts_file with context %}
[DEFAULT]
logdir=/var/log/nova
@@ -167,15 +167,17 @@
memcached_servers={%- for member in compute.cache.members %}{{ member.host }}:11211{% if not loop.last %},{% endif %}{%- endfor %}
{%- endif %}
+{%- set rabbit_port = compute.message_queue.get('port', 5671 if compute.message_queue.get('ssl',{}).get('enabled', False) else 5672) %}
+
[oslo_messaging_rabbit]
{%- if compute.message_queue.members is defined %}
rabbit_hosts = {% for member in compute.message_queue.members -%}
- {{ member.host }}:{{ member.get('port', 5672) }}
+ {{ member.host }}:{{ member.get('port', rabbit_port) }}
{%- if not loop.last -%},{%- endif -%}
{%- endfor -%}
{%- else %}
rabbit_host = {{ compute.message_queue.host }}
-rabbit_port = {{ compute.message_queue.port }}
+rabbit_port = {{ rabbit_port}}
{%- endif %}
rabbit_userid = {{ compute.message_queue.user }}
@@ -185,6 +187,24 @@
rabbit_retry_interval = 1
rabbit_retry_backoff = 2
+{# rabbitmq ssl configuration #}
+{%- if compute.message_queue.get('ssl',{}).get('enabled', False) %}
+[oslo_messaging_rabbit]
+rabbit_use_ssl=true
+
+{%- if compute.message_queue.ssl.version is defined %}
+kombu_ssl_version = {{ compute.message_queue.ssl.version }}
+{%- elif salt['grains.get']('pythonversion') > [2,7,8] %}
+kombu_ssl_version = TLSv1_2
+{%- endif %}
+
+{%- if compute.message_queue.ssl.cacert_file is defined %}
+kombu_ssl_ca_certs = {{ compute.message_queue.ssl.cacert_file }}
+{%- else %}
+kombu_ssl_ca_certs={{ system_cacerts_file }}
+{%- endif %}
+{%- endif %}
+
[glance]
api_servers=http://{{ compute.image.host }}:9292
diff --git a/nova/files/mitaka/nova-controller.conf.Debian b/nova/files/mitaka/nova-controller.conf.Debian
index b808ef9..5c6f7ef 100644
--- a/nova/files/mitaka/nova-controller.conf.Debian
+++ b/nova/files/mitaka/nova-controller.conf.Debian
@@ -1,4 +1,4 @@
-{%- from "nova/map.jinja" import controller with context %}
+{%- from "nova/map.jinja" import controller, system_cacerts_file with context %}
[DEFAULT]
verbose = True
log-dir = /var/log/nova
@@ -105,15 +105,17 @@
driver=messagingv2
{%- endif %}
+{%- set rabbit_port = controller.message_queue.get('port', 5671 if controller.message_queue.get('ssl',{}).get('enabled', False) else 5672) %}
+
[oslo_messaging_rabbit]
{%- if controller.message_queue.members is defined %}
rabbit_hosts = {% for member in controller.message_queue.members -%}
- {{ member.host }}:{{ member.get('port', 5672) }}
+ {{ member.host }}:{{ member.get('port', rabbit_port) }}
{%- if not loop.last -%},{%- endif -%}
{%- endfor -%}
{%- else %}
rabbit_host = {{ controller.message_queue.host }}
-rabbit_port = {{ controller.message_queue.port }}
+rabbit_port = {{ rabbit_port }}
{%- endif %}
rabbit_userid = {{ controller.message_queue.user }}
@@ -124,6 +126,24 @@
rabbit_retry_backoff = 2
rpc_conn_pool_size = 300
+{# rabbitmq ssl configuration #}
+{%- if controller.message_queue.get('ssl',{}).get('enabled', False) %}
+[oslo_messaging_rabbit]
+rabbit_use_ssl=true
+
+{%- if controller.message_queue.ssl.version is defined %}
+kombu_ssl_version = {{ controller.message_queue.ssl.version }}
+{%- elif salt['grains.get']('pythonversion') > [2,7,8] %}
+kombu_ssl_version = TLSv1_2
+{%- endif %}
+
+{%- if controller.message_queue.ssl.cacert_file is defined %}
+kombu_ssl_ca_certs = {{ controller.message_queue.ssl.cacert_file }}
+{%- else %}
+kombu_ssl_ca_certs={{ system_cacerts_file }}
+{%- endif %}
+{%- endif %}
+
[cache]
{%- if controller.cache is defined %}
enabled = true
diff --git a/nova/files/newton/nova-compute.conf.Debian b/nova/files/newton/nova-compute.conf.Debian
index 40638c5..fb6fc85 100644
--- a/nova/files/newton/nova-compute.conf.Debian
+++ b/nova/files/newton/nova-compute.conf.Debian
@@ -1,4 +1,4 @@
-{%- from "nova/map.jinja" import compute with context %}
+{%- from "nova/map.jinja" import compute, system_cacerts_file with context %}
[DEFAULT]
logdir=/var/log/nova
@@ -71,18 +71,18 @@
resume_guests_state_on_host_boot = {{ compute.get('resume_guests_state_on_host_boot', True) }}
service_down_time = 90
+{%- set rabbit_port = compute.message_queue.get('port', 5671 if compute.message_queue.get('ssl',{}).get('enabled', False) else 5672) %}
+
{%- if compute.message_queue.members is defined %}
transport_url = rabbit://{% for member in compute.message_queue.members -%}
- {{ compute.message_queue.user }}:{{ compute.message_queue.password }}@{{ member.host }}:{{ member.get('port', 5672) }}
+ {{ compute.message_queue.user }}:{{ compute.message_queue.password }}@{{ member.host }}:{{ member.get('port', rabbit_port) }}
{%- if not loop.last -%},{%- endif -%}
{%- endfor -%}
/{{ compute.message_queue.virtual_host }}
{%- else %}
-transport_url = rabbit://{{ compute.message_queue.user }}:{{ compute.message_queue.password }}@{{ compute.message_queue.host }}:{{ controller.message_queue.port }}{{ compute.message_queue.virtual_host }}
+transport_url = rabbit://{{ compute.message_queue.user }}:{{ compute.message_queue.password }}@{{ compute.message_queue.host }}:{{ rabbit_port }}/{{ compute.message_queue.virtual_host }}
{%- endif %}
-rpc_backend=rabbit
-
{% if pillar.ceilometer is defined %}
instance_usage_audit = True
instance_usage_audit_period = hour
@@ -98,6 +98,24 @@
notify_on_state_change = vm_and_task_state
{%- endif %}
+{# rabbitmq ssl configuration #}
+{%- if compute.message_queue.get('ssl',{}).get('enabled', False) %}
+[oslo_messaging_rabbit]
+rabbit_use_ssl=true
+
+{%- if compute.message_queue.ssl.version is defined %}
+kombu_ssl_version = {{ compute.message_queue.ssl.version }}
+{%- elif salt['grains.get']('pythonversion') > [2,7,8] %}
+kombu_ssl_version = TLSv1_2
+{%- endif %}
+
+{%- if compute.message_queue.ssl.cacert_file is defined %}
+kombu_ssl_ca_certs = {{ compute.message_queue.ssl.cacert_file }}
+{%- else %}
+kombu_ssl_ca_certs={{ system_cacerts_file }}
+{%- endif %}
+{%- endif %}
+
[oslo_concurrency]
lock_path = /var/lib/nova/tmp
diff --git a/nova/files/newton/nova-controller.conf.Debian b/nova/files/newton/nova-controller.conf.Debian
index 0bb3106..0505bb6 100644
--- a/nova/files/newton/nova-controller.conf.Debian
+++ b/nova/files/newton/nova-controller.conf.Debian
@@ -1,4 +1,4 @@
-{%- from "nova/map.jinja" import controller with context %}
+{%- from "nova/map.jinja" import controller, system_cacerts_file with context %}
[DEFAULT]
verbose = True
log-dir = /var/log/nova
@@ -76,17 +76,35 @@
block_device_allocate_retries=600
block_device_allocate_retries_interval=10
+{%- set rabbit_port = controller.message_queue.get('port', 5671 if controller.message_queue.get('ssl',{}).get('enabled', False) else 5672) %}
+
{%- if controller.message_queue.members is defined %}
transport_url = rabbit://{% for member in controller.message_queue.members -%}
- {{ controller.message_queue.user }}:{{ controller.message_queue.password }}@{{ member.host }}:{{ member.get('port', 5672) }}
+ {{ controller.message_queue.user }}:{{ controller.message_queue.password }}@{{ member.host }}:{{ member.get('port', rabbit_port) }}
{%- if not loop.last -%},{%- endif -%}
{%- endfor -%}
/{{ controller.message_queue.virtual_host }}
{%- else %}
-transport_url = rabbit://{{ controller.message_queue.user }}:{{ controller.message_queue.password }}@{{ controller.message_queue.host }}:{{ controller.message_queue.port }}/{{ controller.message_queue.virtual_host }}
+transport_url = rabbit://{{ controller.message_queue.user }}:{{ controller.message_queue.password }}@{{ controller.message_queue.host }}:{{ rabbit_port }}/{{ controller.message_queue.virtual_host }}
{%- endif %}
-rpc_backend=rabbit
+{# rabbitmq ssl configuration #}
+{%- if controller.message_queue.get('ssl',{}).get('enabled', False) %}
+[oslo_messaging_rabbit]
+rabbit_use_ssl=true
+
+{%- if controller.message_queue.ssl.version is defined %}
+kombu_ssl_version = {{ controller.message_queue.ssl.version }}
+{%- elif salt['grains.get']('pythonversion') > [2,7,8] %}
+kombu_ssl_version = TLSv1_2
+{%- endif %}
+
+{%- if controller.message_queue.ssl.cacert_file is defined %}
+kombu_ssl_ca_certs = {{ controller.message_queue.ssl.cacert_file }}
+{%- else %}
+kombu_ssl_ca_certs={{ system_cacerts_file }}
+{%- endif %}
+{%- endif %}
[vnc]
enabled = true
diff --git a/nova/files/ocata/nova-compute.conf.Debian b/nova/files/ocata/nova-compute.conf.Debian
index db5357b..2e2d276 100644
--- a/nova/files/ocata/nova-compute.conf.Debian
+++ b/nova/files/ocata/nova-compute.conf.Debian
@@ -1,4 +1,4 @@
-{%- from "nova/map.jinja" import compute with context %}
+{%- from "nova/map.jinja" import compute, system_cacerts_file with context %}
[DEFAULT]
#
@@ -3066,17 +3066,18 @@
#rpc_response_timeout=60
rpc_response_timeout = 3600
+{%- set rabbit_port = compute.message_queue.get('port', 5671 if compute.message_queue.get('ssl',{}).get('enabled', False) else 5672) %}
+
{%- if compute.message_queue.members is defined %}
transport_url = rabbit://{% for member in compute.message_queue.members -%}
- {{ compute.message_queue.user }}:{{ compute.message_queue.password }}@{{ member.host }}:{{ member.get('port', 5672) }}
+ {{ compute.message_queue.user }}:{{ compute.message_queue.password }}@{{ member.host }}:{{ member.get('port', rabbit_port) }}
{%- if not loop.last -%},{%- endif -%}
{%- endfor -%}
/{{ compute.message_queue.virtual_host }}
{%- else %}
-transport_url = rabbit://{{ compute.message_queue.user }}:{{ compute.message_queue.password }}@{{ compute.message_queue.host }}:{{ compute.message_queue.port }}/{{ compute.message_queue.virtual_host }}
+transport_url = rabbit://{{ compute.message_queue.user }}:{{ compute.message_queue.password }}@{{ compute.message_queue.host }}:{{ rabbit_port}}/{{ compute.message_queue.virtual_host }}
{%- endif %}
-rpc_backend=rabbit
# DEPRECATED: The messaging driver to use, defaults to rabbit. Other drivers
# include amqp and zmq. (string value)
# This option is deprecated for removal.
@@ -7942,6 +7943,23 @@
# message (floating point value)
#rpc_retry_delay=0.25
+{# rabbitmq ssl configuration #}
+{%- if compute.message_queue.get('ssl',{}).get('enabled', False) %}
+rabbit_use_ssl=true
+
+{%- if compute.message_queue.ssl.version is defined %}
+kombu_ssl_version = {{ compute.message_queue.ssl.version }}
+{%- elif salt['grains.get']('pythonversion') > [2,7,8] %}
+kombu_ssl_version = TLSv1_2
+{%- endif %}
+
+{%- if compute.message_queue.ssl.cacert_file is defined %}
+kombu_ssl_ca_certs = {{ compute.message_queue.ssl.cacert_file }}
+{%- else %}
+kombu_ssl_ca_certs = {{ system_cacerts_file }}
+{%- endif %}
+{%- endif %}
+
[oslo_messaging_zmq]
diff --git a/nova/files/ocata/nova-controller.conf.Debian b/nova/files/ocata/nova-controller.conf.Debian
index 7a8126a..e70bf4f 100644
--- a/nova/files/ocata/nova-controller.conf.Debian
+++ b/nova/files/ocata/nova-controller.conf.Debian
@@ -1,4 +1,4 @@
-{%- from "nova/map.jinja" import controller with context %}
+{%- from "nova/map.jinja" import controller, system_cacerts_file with context %}
[DEFAULT]
#
@@ -3035,16 +3035,19 @@
#rpc_response_timeout=60
rpc_response_timeout=3600
+{%- set rabbit_port = controller.message_queue.get('port', 5671 if controller.message_queue.get('ssl',{}).get('enabled', False) else 5672) %}
+
{%- if controller.message_queue.members is defined %}
transport_url = rabbit://{% for member in controller.message_queue.members -%}
- {{ controller.message_queue.user }}:{{ controller.message_queue.password }}@{{ member.host }}:{{ member.get('port', 5672) }}
+ {{ controller.message_queue.user }}:{{ controller.message_queue.password }}@{{ member.host }}:{{ member.get('port', rabbit_port) }}
{%- if not loop.last -%},{%- endif -%}
{%- endfor -%}
/{{ controller.message_queue.virtual_host }}
{%- else %}
-transport_url = rabbit://{{ controller.message_queue.user }}:{{ controller.message_queue.password }}@{{ controller.message_queue.host }}:{{ controller.message_queue.port }}/{{ controller.message_queue.virtual_host }}
+transport_url = rabbit://{{ controller.message_queue.user }}:{{ controller.message_queue.password }}@{{ controller.message_queue.host }}:{{ rabbit_port}}/{{ controller.message_queue.virtual_host }}
{%- endif %}
+
# DEPRECATED: The messaging driver to use, defaults to rabbit. Other drivers
# include amqp and zmq. (string value)
# This option is deprecated for removal.
@@ -7931,6 +7934,22 @@
# message (floating point value)
#rpc_retry_delay=0.25
+{# rabbitmq ssl configuration #}
+{%- if controller.message_queue.get('ssl',{}).get('enabled', False) %}
+rabbit_use_ssl=true
+
+{%- if controller.message_queue.ssl.version is defined %}
+kombu_ssl_version = {{ controller.message_queue.ssl.version }}
+{%- elif salt['grains.get']('pythonversion') > [2,7,8] %}
+kombu_ssl_version = TLSv1_2
+{%- endif %}
+
+{%- if controller.message_queue.ssl.cacert_file is defined %}
+kombu_ssl_ca_certs = {{ controller.message_queue.ssl.cacert_file }}
+{%- else %}
+kombu_ssl_ca_certs = {{ system_cacerts_file }}
+{%- endif %}
+{%- endif %}
[oslo_messaging_zmq]
diff --git a/nova/map.jinja b/nova/map.jinja
index b8f51e7..f725112 100644
--- a/nova/map.jinja
+++ b/nova/map.jinja
@@ -1,3 +1,8 @@
+{%- set system_cacerts_file = salt['grains.filter_by']({
+ 'Debian': '/etc/ssl/certs/ca-certificates.crt',
+ 'RedHat': '/etc/pki/tls/certs/ca-bundle.crt'
+})%}
+
{% set compute_bind_defaults = {
'vnc_address': '10.0.0.10',
'vnc_port': '6080',
diff --git a/tests/pillar/ssl.sls b/tests/pillar/ssl.sls
new file mode 100644
index 0000000..d42f6bf
--- /dev/null
+++ b/tests/pillar/ssl.sls
@@ -0,0 +1,15 @@
+include:
+ - .compute_single
+ - .control_single
+
+nova:
+ controller:
+ message_queue:
+ port: 5671
+ ssl:
+ enabled: True
+ compute:
+ message_queue:
+ port: 5671
+ ssl:
+ enabled: True