Allow getting CA key from a mine
In cases when a service whants to generate and sign a certificate
it requires a CA key along with a CA cert itself.
For example, Octavia needs it for signing a certificate it generates
for a newly spawned amphora.
This change add sending a CA key to the mine from where it can be
extracted in the cert.sls state.
Also allow managing permissions for a CA cert and key retrieved
from the mine.
Related PROD: PROD-11933
Change-Id: I911effb4a63ae048e348ed04b7aca33998e359aa
diff --git a/salt/minion/ca.sls b/salt/minion/ca.sls
index f2b3e22..bdf96c4 100644
--- a/salt/minion/ca.sls
+++ b/salt/minion/ca.sls
@@ -55,6 +55,16 @@
- require:
- x509: /etc/pki/ca/{{ ca_name }}/ca.crt
+salt_system_ca_mine_send_ca_key_{{ ca_name }}:
+ module.run:
+ - name: mine.send
+ - func: x509_get_private_key
+ - kwargs:
+ mine_function: x509.get_pem_entries
+ glob_path: /etc/pki/ca/{{ ca_name }}/ca.key
+ - require:
+ - x509: /etc/pki/ca/{{ ca_name }}/ca.key
+
{%- endfor %}
{%- endif %}
diff --git a/salt/minion/cert.sls b/salt/minion/cert.sls
index 416c036..017c115 100644
--- a/salt/minion/cert.sls
+++ b/salt/minion/cert.sls
@@ -11,6 +11,7 @@
{%- if minion.cert is defined %}
{%- set created_ca_files = [] %}
+{%- set created_ca_key_files = [] %}
{%- for cert_name,cert in minion.get('cert', {}).iteritems() %}
{%- set rowloop = loop %}
@@ -18,9 +19,11 @@
{%- set key_file = cert.get('key_file', '/etc/ssl/private/' + cert.common_name + '.key') %}
{%- set cert_file = cert.get('cert_file', '/etc/ssl/certs/' + cert.common_name + '.crt') %}
{%- set ca_file = cert.get('ca_file', '/etc/ssl/certs/ca-' + cert.authority + '.crt') %}
+{%- set ca_key_file = cert.get('ca_key_file', '/etc/ssl/certs/ca-' + cert.authority + '.key') %}
{%- set key_dir = salt['file.dirname'](key_file) %}
{%- set cert_dir = salt['file.dirname'](cert_file) %}
{%- set ca_dir = salt['file.dirname'](ca_file) %}
+{%- set ca_key_dir = salt['file.dirname'](ca_key_file) %}
{# Only ensure directories exists, don't touch permissions, etc. #}
salt_minion_cert_{{ cert_name }}_dirs:
@@ -29,6 +32,7 @@
- {{ key_dir }}
- {{ cert_dir }}
- {{ ca_dir }}
+ - {{ ca_key_dir }}
- makedirs: true
- replace: false
@@ -125,15 +129,54 @@
file.managed:
- name: {{ ca_file }}
- mode: 0644
+ {%- if salt['user.info'](cert.get("user", "root")) %}
+ - user: {{ cert.get("user", "root") }}
+ {%- endif %}
+ {%- if salt['group.info'](cert.get("group", "root")) %}
+ - group: {{ cert.get("group", "root") }}
+ {%- endif %}
- watch:
- x509: {{ ca_file }}
{%- endif %}
{%- endfor %}
+
{%- do created_ca_files.append(ca_file) %}
{%- endif %}
+{%- if cert.host is defined and ca_key_file not in created_ca_key_files %}
+{%- for ca_key_path,ca_key in salt['mine.get'](cert.host, 'x509_get_private_key').get(cert.host, {}).iteritems() %}
+
+{%- if '/etc/pki/ca/'+cert.authority in ca_key_path %}
+
+{{ ca_key_file }}:
+ x509.pem_managed:
+ - name: {{ ca_key_file }}
+ - text: {{ ca_key|replace('\n', '') }}
+ - watch:
+ - x509: {{ cert_file }}
+
+{{ ca_key_file }}_cert_permissions:
+ file.managed:
+ - name: {{ ca_key_file }}
+ - mode: 0644
+ {%- if salt['user.info'](cert.get("user", "root")) %}
+ - user: {{ cert.get("user", "root") }}
+ {%- endif %}
+ {%- if salt['group.info'](cert.get("group", "root")) %}
+ - group: {{ cert.get("group", "root") }}
+ {%- endif %}
+ - watch:
+ - x509: {{ ca_key_file }}
+
+{%- endif %}
+
+{%- endfor %}
+
+{%- do created_ca_key_files.append(ca_key_file) %}
+{%- endif %}
+
{%- if cert.all_file is defined %}
salt_minion_cert_{{ cert_name }}_all: