Add Hashi Vault support for Kolla passwords

This commit adds the necessary changes needed to support
reading and writing Kolla passwords to a Hashicorp Vault server
using Kolla-Ansible commands `kolla-readpwd` and `kolla-writepwd`.

This follows the support that was added into Kolla-Ansible in
the Change-Id Icf0eaf7544fcbdf7b83f697cc711446f47118a4d.

Change-Id: I732988e6160cc64d663d6ef8179f04d3e1226537
This commit is contained in:
Scott Solkhon 2022-09-02 15:45:18 +01:00
parent fbf0006895
commit 08bd6815bd
7 changed files with 140 additions and 0 deletions

View File

@ -456,6 +456,16 @@ kolla_ansible_target_venv: "{{ virtualenv_path ~ '/kolla-ansible' }}"
# Password to use to encrypt the kolla-ansible passwords.yml file.
kolla_ansible_vault_password: "{{ lookup('env', 'KAYOBE_VAULT_PASSWORD') | default }}"
# Hashi Vault
kolla_ansible_vault_addr: "{{ lookup('env', 'KAYOBE_VAULT_ADDR') | default }}"
kolla_ansible_vault_mount_point: "{{ lookup('env', 'KAYOBE_VAULT_MOUNT_POINT') | default }}"
kolla_ansible_vault_kv_path: "{{ lookup('env', 'KAYOBE_VAULT_KV_PATH') | default }}"
kolla_ansible_vault_namespace: "{{ lookup('env', 'KAYOBE_VAULT_NAMESPACE') | default }}"
kolla_ansible_vault_role_id: "{{ lookup('env', 'KAYOBE_VAULT_ROLE_ID') | default }}"
kolla_ansible_vault_secret_id: "{{ lookup('env', 'KAYOBE_VAULT_SECRET_ID') | default }}"
kolla_ansible_vault_token: "{{ lookup('env', 'KAYOBE_VAULT_TOKEN') | default }}"
kolla_ansible_vault_cacert: "{{ lookup('env', 'KAYOBE_VAULT_CACERT') | default }}"
# Whether TLS is enabled for the external API endpoints.
kolla_enable_tls_external: "{{ kolla_enable_tls_internal if public_net_name == internal_net_name else 'no' }}"

View File

@ -43,6 +43,16 @@ kolla_ansible_install_epel: false
# Password to use to encrypt the passwords.yml file.
kolla_ansible_vault_password:
# Hashi Vault
kolla_ansible_vault_addr:
kolla_ansible_vault_mount_point:
kolla_ansible_vault_kv_path:
kolla_ansible_vault_namespace:
kolla_ansible_vault_role_id:
kolla_ansible_vault_secret_id:
kolla_ansible_vault_token:
kolla_ansible_vault_cacert:
# Directory where Kolla config files will be installed.
kolla_config_path:

View File

@ -51,6 +51,49 @@ def kolla_mergepwd(module, old_path, new_path, final_path):
module.run_command(cmd, check_rc=True,
path_prefix=virtualenv_path_prefix(module))
def kolla_readpwd(module, file_path, vault_addr="", vault_mount_point="", vault_kv_path="",
vault_namespace="", vault_role_id=None, vault_secret_id=None,
vault_token=None, vault_cacert=""):
"""Run the kolla-readpwd command."""
if vault_role_id and vault_secret_id:
vault_auth = ["--vault-role-id", vault_role_id,
"--vault-secret-id", vault_secret_id]
else:
vault_auth = ["--vault-token", vault_token]
cmd = ["kolla-readpwd",
"--passwords", file_path,
"--vault-addr", vault_addr,
"--vault-mount-point", vault_mount_point,
"--vault-kv-path", vault_kv_path,
"--vault-namespace", vault_namespace,
"--vault-cacert", vault_cacert] + vault_auth
module.run_command(cmd, check_rc=True,
path_prefix=virtualenv_path_prefix(module))
def kolla_writepwd(module, file_path, vault_addr="", vault_mount_point="", vault_kv_path="",
vault_namespace="", vault_role_id=None, vault_secret_id=None,
vault_token=None, vault_cacert=""):
"""Run the kolla-writepwd command."""
if vault_role_id and vault_secret_id:
vault_auth = ["--vault-role-id", vault_role_id,
"--vault-secret-id", vault_secret_id, ]
else:
vault_auth = ["--vault-token", vault_token, ]
cmd = ["kolla-writepwd",
"--passwords", file_path,
"--vault-addr", vault_addr,
"--vault-mount-point", vault_mount_point,
"--vault-kv-path", vault_kv_path,
"--vault-namespace", vault_namespace,
"--vault-cacert", vault_cacert] + vault_auth
module.run_command(cmd, check_rc=True,
path_prefix=virtualenv_path_prefix(module))
def create_vault_password_file(module):
"""Create a vault password file."""
@ -128,6 +171,33 @@ def kolla_passwords(module):
finally:
os.unlink(src_path)
if module.params['vault_addr']:
src_path = create_named_tempfile()
try:
shutil.copyfile(module.params['src'], src_path)
kolla_readpwd(module, src_path,
module.params['vault_addr'],
module.params['vault_mount_point'],
module.params['vault_kv_path'],
module.params['vault_namespace'],
module.params['vault_role_id'],
module.params['vault_secret_id'],
module.params['vault_token'],
module.params['vault_cacert'])
kolla_mergepwd(module, src_path, temp_file_path, temp_file_path)
kolla_genpwd(module, temp_file_path)
kolla_writepwd(module, temp_file_path,
module.params['vault_addr'],
module.params['vault_mount_point'],
module.params['vault_kv_path'],
module.params['vault_namespace'],
module.params['vault_role_id'],
module.params['vault_secret_id'],
module.params['vault_token'],
module.params['vault_cacert'])
finally:
os.unlink(src_path)
# Merge in overrides.
if module.params['overrides']:
with tempfile.NamedTemporaryFile(delete=False) as f:
@ -137,6 +207,16 @@ def kolla_passwords(module):
overrides_path = f.name
try:
kolla_mergepwd(module, overrides_path, temp_file_path, temp_file_path)
if module.params['vault_addr']:
kolla_writepwd(module, temp_file_path,
module.params['vault_addr'],
module.params['vault_mount_point'],
module.params['vault_kv_path'],
module.params['vault_namespace'],
module.params['vault_role_id'],
module.params['vault_secret_id'],
module.params['vault_token'],
module.params['vault_cacert'])
finally:
os.unlink(overrides_path)
@ -189,10 +269,23 @@ def main():
sample=dict(default='/usr/share/kolla-ansible/etc_examples/kolla/passwords.yml', type='str'),
src=dict(default='/etc/kolla/passwords.yml', type='str'),
vault_password=dict(type='str', no_log=True),
vault_addr=dict(type='str', no_log=False),
vault_mount_point=dict(type='str', no_log=False),
vault_kv_path=dict(type='str', no_log=False),
vault_namespace=dict(type='str', no_log=False),
vault_role_id=dict(type='str', no_log=True),
vault_secret_id=dict(type='str', no_log=True),
vault_token=dict(type='str', no_log=True),
vault_cacert=dict(type='str', no_log=False),
virtualenv=dict(type='str'),
),
add_file_common_args=True,
supports_check_mode=True,
required_together=[['vault_mount_point', 'vault_addr'],
['vault_role_id', 'vault_secret_id'],
['vault_mount_point','vault_kv_path']],
mutually_exclusive=[['vault_token', 'vault_role_id'],
['vault_token', 'vault_secret_id']]
)
if IMPORT_ERRORS:

View File

@ -98,6 +98,14 @@
sample: "{{ kolla_ansible_install_dir }}/etc_examples/kolla/passwords.yml"
overrides: "{{ kolla_ansible_custom_passwords }}"
vault_password: "{{ kolla_ansible_vault_password }}"
vault_addr: "{{ kolla_ansible_vault_addr }}"
vault_mount_point: "{{ kolla_ansible_vault_mount_point }}"
vault_kv_path: "{{ kolla_ansible_vault_kv_path }}"
vault_namespace: "{{ kolla_ansible_vault_namespace }}"
vault_role_id: "{{ kolla_ansible_vault_role_id or omit }}"
vault_secret_id: "{{ kolla_ansible_vault_secret_id or omit }}"
vault_token: "{{ kolla_ansible_vault_token or omit }}"
vault_cacert: "{{ kolla_ansible_vault_cacert }}"
virtualenv: "{{ kolla_ansible_venv or omit }}"
- name: Ensure the Kolla passwords file is copied into place

View File

@ -235,6 +235,19 @@
# remotely on the target nodes. If None, no virtualenv will be used.
#kolla_ansible_target_venv:
# Password to use to encrypt the kolla-ansible passwords.yml file.
#kolla_ansible_vault_password:
# Hashi Vault
#kolla_ansible_vault_addr:
#kolla_ansible_vault_mount_point:
#kolla_ansible_vault_kv_path:
#kolla_ansible_vault_namespace:
#kolla_ansible_vault_role_id:
#kolla_ansible_vault_secret_id:
#kolla_ansible_vault_token:
#kolla_ansible_vault_cacert:
# Whether TLS is enabled for the external API endpoints. Default is 'no'.
#kolla_enable_tls_external:

View File

@ -0,0 +1,5 @@
---
features:
- |
Adds functionality into the kolla_passwords module to allow passwords that
are generated for Kolla Ansible to be stored in Hashicorp Vault.

View File

@ -9,3 +9,4 @@ selinux # MIT
oslo.config>=5.2.0 # Apache-2.0
paramiko # LGPL
jsonschema<5 # MIT
hvac>=0.10.1