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 # Use sudo to get priviledge access
become = True become = True
# Ask for password # Use custom password request
become_ask_pass = True become_ask_pass = False
[ssh_connection] [ssh_connection]

View File

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

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
from functools import lru_cache from functools import lru_cache
from getpass import getpass
import os import os
from pathlib import Path from pathlib import Path
import subprocess import subprocess
@ -28,7 +29,7 @@ DOCUMENTATION = """
class VarsModule(BaseVarsPlugin): class VarsModule(BaseVarsPlugin):
@staticmethod @staticmethod
@lru_cache @lru_cache
def vault_passwords(): def decrypt_password(name, crans_submodule=False):
""" """
Passwords are decrypted from the local password store, then are cached. Passwords are decrypted from the local password store, then are cached.
By that way, we don't decrypt these passwords everytime. 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', password_store = Path(config.get('pass', 'password_store_dir',
fallback=os.getenv('PASSWORD_STORE_DIR', Path.home() / '.password-store'))) 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')) if crans_submodule:
full_command = ['gpg', '-d', password_store / crans_submodule / 'ansible_vault.gpg'] 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) proc = subprocess.run(full_command, capture_output=True, close_fds=True)
clear_text = proc.stdout.decode('UTF-8') clear_text = proc.stdout.decode('UTF-8')
sys.stderr.write(proc.stderr.decode('UTF-8')) sys.stderr.write(proc.stderr.decode('UTF-8'))
return clear_text 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): def get_vars(self, loader, path, entities):
""" """
Get all vars for entities, called by Ansible. Get all vars for entities, called by Ansible.
@ -63,4 +86,17 @@ class VarsModule(BaseVarsPlugin):
# It is way to much. # It is way to much.
# So we cache the data into the DataLoader (see parsing/DataLoader). # 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