Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to distinguish between different backends of the passwordstore lookup plugin #4779

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions plugins/lookup/passwordstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,8 @@ def parse_params(self, term):
if os.path.isdir(self.paramvals['directory']):
self.env['PASSWORD_STORE_DIR'] = self.paramvals['directory']
else:
raise AnsibleError('Passwordstore directory \'{0}\' does not exist'.format(self.paramvals['directory']))
if self.backend == 'pass':
raise AnsibleError('Passwordstore directory \'{0}\' does not exist'.format(self.paramvals['directory']))

# Set PASSWORD_STORE_UMASK if umask is set
if 'umask' in self.paramvals:
Expand All @@ -287,8 +288,11 @@ def parse_params(self, term):

def check_pass(self):
try:
pass_show = ["pass", "show", self.passname]
if self.backend == 'gopass':
pass_show = ["pass", "show", "--password", self.passname]
self.passoutput = to_text(
check_output2(["pass", "show", self.passname], env=self.env),
check_output2(pass_show, env=self.env),
errors='surrogate_or_strict'
).splitlines()
self.password = self.passoutput[0]
Expand All @@ -302,9 +306,13 @@ def check_pass(self):
if ':' in line:
name, value = line.split(':', 1)
self.passdict[name.strip()] = value.strip()
if os.path.isfile(os.path.join(self.paramvals['directory'], self.passname + ".gpg")):
# Only accept password as found, if there a .gpg file for it (might be a tree node otherwise)
if self.backend == 'pass':
if os.path.isfile(os.path.join(self.paramvals['directory'], self.passname + ".gpg")):
# Only accept password as found, if there a .gpg file for it (might be a tree node otherwise)
return True
else:
return True

except (subprocess.CalledProcessError) as e:
# 'not in password store' is the expected error if a password wasn't found
if 'not in the password store' not in e.output:
Expand Down Expand Up @@ -379,6 +387,16 @@ def opt_lock(self, type):
else:
yield

def setup_backend(self):
try:
pass_version = to_text(
check_output2(['pass', '--version']))
except (subprocess.CalledProcessError) as e:
raise AnsibleError(e)
self.backend = 'pass'
if 'gopass' in pass_version:
self.backend = 'gopass'

def setup(self, variables):
self.locked = None
timeout = self.get_option('locktimeout')
Expand All @@ -403,6 +421,7 @@ def setup(self, variables):

def run(self, terms, variables, **kwargs):
self.setup(variables)
self.setup_backend()
result = []

for term in terms:
Expand Down