Add configuration to query become password from password store

Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
certbot_on_virtu
Yohann D'ANELLO 2021-02-28 15:46:46 +01:00 committed by ynerant
parent 39441c81f5
commit 44a59d11c9
3 changed files with 49 additions and 9 deletions

View File

@ -41,8 +41,8 @@ fact_caching_timeout = 86400
# Use sudo to get priviledge access
become = True
# Ask for password
become_ask_pass = True
# Use custom password request
become_ask_pass = False
[ssh_connection]

View File

@ -1,3 +1,7 @@
[pass]
password_store_dir=/home/me/.password-store
crans_password_store_submodule=crans
# password_store_dir=/home/me/.password-store
# crans_password_store_submodule=crans
[pass_become]
# all=mdp-root
# adh_server=mdp-zamok

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python
from functools import lru_cache
from getpass import getpass
import os
from pathlib import Path
import subprocess
@ -28,7 +29,7 @@ DOCUMENTATION = """
class VarsModule(BaseVarsPlugin):
@staticmethod
@lru_cache
def vault_passwords():
def decrypt_password(name, crans_submodule=False):
"""
Passwords are decrypted from the local password store, then are cached.
By that way, we don't decrypt these passwords everytime.
@ -39,14 +40,36 @@ class VarsModule(BaseVarsPlugin):
password_store = Path(config.get('pass', 'password_store_dir',
fallback=os.getenv('PASSWORD_STORE_DIR', Path.home() / '.password-store')))
crans_submodule = config.get('pass', 'crans_password_store_submodule',
fallback=os.getenv('CRANS_PASSWORD_STORE_SUBMODULE', 'crans'))
full_command = ['gpg', '-d', password_store / crans_submodule / 'ansible_vault.gpg']
if crans_submodule:
password_store /= config.get('pass', 'crans_password_store_submodule',
fallback=os.getenv('CRANS_PASSWORD_STORE_SUBMODULE', 'crans'))
full_command = ['gpg', '-d', password_store / f'{name}.gpg']
proc = subprocess.run(full_command, capture_output=True, close_fds=True)
clear_text = proc.stdout.decode('UTF-8')
sys.stderr.write(proc.stderr.decode('UTF-8'))
return clear_text
@staticmethod
@lru_cache
def become_password(entity):
"""
Query the become password that should be used for the given entity.
If entity is the whole group that has no default password,
the become password will be prompted.
The configuration should be given in pass.ini, in the `pass_become`
group. You have only to write `group=pass-filename`.
"""
# Load config
config = configparser.ConfigParser()
config.read(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'pass.ini'))
if config.has_option('pass_become', entity.get_name()):
return VarsModule.decrypt_password(
config.get('pass_become', entity.get_name())).split('\n')[0]
if entity.get_name() == "all":
return getpass("BECOME password: ", stream=None)
return None
def get_vars(self, loader, path, entities):
"""
Get all vars for entities, called by Ansible.
@ -63,4 +86,17 @@ class VarsModule(BaseVarsPlugin):
# It is way to much.
# So we cache the data into the DataLoader (see parsing/DataLoader).
return {'vault': loader.load(VarsModule.vault_passwords())}
passwords = {}
for entity in entities:
# Load vault passwords
if entity.get_name() == 'all':
passwords['vault'] = loader.load(
VarsModule.decrypt_password('ansible_vault', True))
# Load become password
become_password = VarsModule.become_password(entity)
if become_password is not None:
passwords['ansible_become_password'] = become_password
return passwords