Merge pull request #50160 from Rylon/backport/2.7/47213
Fix an issue retrieving some types of 1Password items. (#47213)
This commit is contained in:
parent
016bc83b58
commit
41214d4426
2 changed files with 58 additions and 1 deletions
|
@ -0,0 +1,2 @@
|
|||
bugfixes:
|
||||
- onepassword_facts - Fix an issue looking up some 1Password items which have a 'password' attribute alongside the 'fields' attribute, not inside it.
|
|
@ -138,9 +138,18 @@ import os
|
|||
import re
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from ansible.module_utils._text import to_bytes, to_native
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
|
||||
class AnsibleModuleError(Exception):
|
||||
def __init__(self, results):
|
||||
self.results = results
|
||||
|
||||
def __repr__(self):
|
||||
return self.results
|
||||
|
||||
|
||||
class OnePasswordFacts(object):
|
||||
|
||||
def __init__(self):
|
||||
|
@ -149,7 +158,53 @@ class OnePasswordFacts(object):
|
|||
self.token = {}
|
||||
|
||||
terms = module.params.get('search_terms')
|
||||
self.terms = self.parse_search_terms(module.params.get('search_terms'))
|
||||
self.terms = self.parse_search_terms(terms)
|
||||
|
||||
def _run(self, args, expected_rc=0, command_input=None, ignore_errors=False):
|
||||
command = [self.cli_path] + args
|
||||
p = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
|
||||
out, err = p.communicate(input=command_input)
|
||||
rc = p.wait()
|
||||
if not ignore_errors and rc != expected_rc:
|
||||
raise AnsibleModuleError(to_native(err))
|
||||
return rc, out, err
|
||||
|
||||
def _parse_field(self, data_json, item_id, field_name, section_title=None):
|
||||
data = json.loads(data_json)
|
||||
|
||||
if ('documentAttributes' in data['details']):
|
||||
# This is actually a document, let's fetch the document data instead!
|
||||
document = self._run(["get", "document", data['overview']['title']])
|
||||
return {'document': document[0].strip()}
|
||||
|
||||
else:
|
||||
# This is not a document, let's try to find the requested field
|
||||
|
||||
# Some types of 1Password items have a 'password' field directly alongside the 'fields' attribute,
|
||||
# not inside it, so we need to check there first.
|
||||
if (field_name in data['details']):
|
||||
return {field_name: data['details'][field_name]}
|
||||
|
||||
# Otherwise we continue looking inside the 'fields' attribute for the specified field.
|
||||
else:
|
||||
if section_title is None:
|
||||
for field_data in data['details'].get('fields', []):
|
||||
if field_data.get('name').lower() == field_name.lower():
|
||||
return {field_name: field_data.get('value', '')}
|
||||
|
||||
# Not found it yet, so now lets see if there are any sections defined
|
||||
# and search through those for the field. If a section was given, we skip
|
||||
# any non-matching sections, otherwise we search them all until we find the field.
|
||||
for section_data in data['details'].get('sections', []):
|
||||
if section_title is not None and section_title.lower() != section_data['title'].lower():
|
||||
continue
|
||||
for field_data in section_data.get('fields', []):
|
||||
if field_data.get('t').lower() == field_name.lower():
|
||||
return {field_name: field_data.get('v', '')}
|
||||
|
||||
# We will get here if the field could not be found in any section and the item wasn't a document to be downloaded.
|
||||
optional_section_title = '' if section_title is None else " in the section '%s'" % section_title
|
||||
module.fail_json(msg="Unable to find an item in 1Password named '%s' with the field '%s'%s." % (item_id, field_name, optional_section_title))
|
||||
|
||||
def parse_search_terms(self, terms):
|
||||
processed_terms = []
|
||||
|
|
Loading…
Reference in a new issue