Skip to content

Commit

Permalink
Add Hashi Vault support for Kolla passwords
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ssolkhon committed Dec 21, 2022
1 parent fbf0006 commit 08bd681
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 0 deletions.
10 changes: 10 additions & 0 deletions ansible/inventory/group_vars/all/kolla
Original file line number Diff line number Diff line change
Expand Up @@ -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' }}"

Expand Down
10 changes: 10 additions & 0 deletions ansible/roles/kolla-ansible/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
93 changes: 93 additions & 0 deletions ansible/roles/kolla-ansible/library/kolla_passwords.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand Down Expand Up @@ -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:
Expand All @@ -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)

Expand Down Expand Up @@ -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:
Expand Down
8 changes: 8 additions & 0 deletions ansible/roles/kolla-ansible/tasks/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions etc/kayobe/kolla.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
Original file line number Diff line number Diff line change
@@ -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.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ selinux # MIT
oslo.config>=5.2.0 # Apache-2.0
paramiko # LGPL
jsonschema<5 # MIT
hvac>=0.10.1

0 comments on commit 08bd681

Please sign in to comment.