community.general icon indicating copy to clipboard operation
community.general copied to clipboard

onepassword - Support v2

Open samdoran opened this issue 2 years ago • 18 comments

SUMMARY

Fixes #4396. Closes #4415.

The interface and data schema for op version two changed significantly. Create a base class defining the common interface then define version specific classes.

The appropriate class will be used based on the discovered op version.

The lookups/module will fail gracefully for unsupported versions.

ISSUE TYPE
  • Bugfix Pull Request
COMPONENT NAME

plugins/lookup/onepassword.py

ADDITIONAL INFORMATION

Still a work in progress. Open to feedback.

samdoran avatar May 24 '22 21:05 samdoran

cc @azenk @scottsb click here for bot help

ansibullbot avatar May 24 '22 21:05 ansibullbot

Still working on this, just as time allows.

samdoran avatar May 31 '22 19:05 samdoran

Making some good progress. It's mostly working (only the full login is not). I need to do some more polishing and update the tests.

samdoran avatar Jun 21 '22 17:06 samdoran

The test ansible-test sanity --test pep8 [explain] failed with 1 error:

tests/unit/plugins/lookup/test_onepassword.py:104:1: E302: expected 2 blank lines, found 1

The test ansible-test sanity --test pep8 [explain] failed with 1 error:

tests/unit/plugins/lookup/test_onepassword.py:104:1: E302: expected 2 blank lines, found 1

The test ansible-test sanity --test pep8 [explain] failed with 1 error:

tests/unit/plugins/lookup/test_onepassword.py:104:1: E302: expected 2 blank lines, found 1

The test ansible-test sanity --test pep8 [explain] failed with 1 error:

tests/unit/plugins/lookup/test_onepassword.py:104:1: E302: expected 2 blank lines, found 1

click here for bot help

ansibullbot avatar Jul 08 '22 22:07 ansibullbot

The test ansible-test sanity --test pep8 [explain] failed with 11 errors:

tests/unit/plugins/lookup/test_onepassword.py:113:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:117:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:134:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:138:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:147:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:164:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:173:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:184:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:184:40: E231: missing whitespace after ','
tests/unit/plugins/lookup/test_onepassword.py:197:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:205:1: E302: expected 2 blank lines, found 1

The test ansible-test sanity --test pep8 [explain] failed with 11 errors:

tests/unit/plugins/lookup/test_onepassword.py:113:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:117:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:134:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:138:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:147:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:164:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:173:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:184:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:184:40: E231: missing whitespace after ','
tests/unit/plugins/lookup/test_onepassword.py:197:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:205:1: E302: expected 2 blank lines, found 1

The test ansible-test sanity --test pep8 [explain] failed with 11 errors:

tests/unit/plugins/lookup/test_onepassword.py:113:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:117:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:134:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:138:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:147:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:164:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:173:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:184:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:184:40: E231: missing whitespace after ','
tests/unit/plugins/lookup/test_onepassword.py:197:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:205:1: E302: expected 2 blank lines, found 1

The test ansible-test sanity --test pep8 [explain] failed with 11 errors:

tests/unit/plugins/lookup/test_onepassword.py:113:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:117:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:134:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:138:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:147:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:164:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:173:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:184:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:184:40: E231: missing whitespace after ','
tests/unit/plugins/lookup/test_onepassword.py:197:1: E302: expected 2 blank lines, found 1
tests/unit/plugins/lookup/test_onepassword.py:205:1: E302: expected 2 blank lines, found 1

click here for bot help

ansibullbot avatar Jul 20 '22 22:07 ansibullbot

The test ansible-test sanity --test metaclass-boilerplate [explain] failed with 1 error:

tests/unit/plugins/lookup/onepassword/conftest.py:0:0: missing: __metaclass__ = type

The test ansible-test sanity --test future-import-boilerplate [explain] failed with 1 error:

tests/unit/plugins/lookup/onepassword/conftest.py:0:0: missing: from __future__ import (absolute_import, division, print_function)

click here for bot help

ansibullbot avatar Jul 22 '22 20:07 ansibullbot

Hi @samdoran, thanks for working on this! I am eagerly waiting for this PR to be merged. As per your message in #4415 I just tested the current implementation and have some feedback. I only tested the v2 implementation. I'd be happy to help with the implementation if needed.

Items in Sections

Currently specifying a section breaks lookups with a 'NoneType' object is not iterable. error. This is because data.get(section) does not work for the v2 JSON schema.

https://github.com/samdoran/community.general/blob/c979d31dd156588743fd16841685885ce7480e5f/plugins/lookup/onepassword.py#L446-L447

This isn't such a huge problem because fields are looked up by their unique ID anyways. I think there are two possible ways to deal with this (I'd prefer the second option):

  • Remove the section field for the v2 lookup completely and require the field to be the unique ID of an item's field.
  • Lookup fields by their ID or their label. If a section is specified (by ID or by label) only consider items whose section is set to this value (ID or label). If multiple or no matches are found, raise an error. As far as I can tell this mirrors the behavior of the op item get command. This could be enhanced by matching an empty section value "" against items in the default section (and treating the None section as any section).

Handling of missing fields

Currently if a field is not found in an item an empty string is returned. I feel like this is prone to errors (e.g. accidentally setting an empty password because of a typo). I would expect an error message in a case like this.

https://github.com/samdoran/community.general/blob/c979d31dd156588743fd16841685885ce7480e5f/plugins/lookup/onepassword.py#L456

Field Selection

Currently the requested field is matched against the field's ID as well as the keys of the item's JSON representation. I don't see an application for this. Moreover this makes it impossibly to query the value of a field whose ID matches one of those keys. Maybe it also makes sense to also match against the field label in v2 (the op item get --field command does this and errors out if there are multiple results)…

https://github.com/samdoran/community.general/blob/c979d31dd156588743fd16841685885ce7480e5f/plugins/lookup/onepassword.py#L448-L450

For example: I created an API_CREDENTIAL item and set its type to "bearer". However lookup('community.general.onepassword', 'Test', field='type') returns "STRING". If the application here is to be able to query other properties of fields (such as their labels), I think this this would better be done via a dedicated argument such as lookup('community.general.onepassword', 'Test', field='type', subfield='label'). The subfield could be set to "value" by default.

Documentation

The v1 version of the plugin did lookups based on a field's label (or rather I think there wasn't really a difference between labels and IDs). The v2 version looks up fields by their ids. I think this behavior should be documented, especially since it doesn't seem possible to view IDs via the 1Password Apps (only via the CLI).

https://github.com/samdoran/community.general/blob/c979d31dd156588743fd16841685885ce7480e5f/plugins/lookup/onepassword.py#L27-L28

Also as a side node the docs still say Tested with op version 0.5.3.

Additional suggestions

  • Maybe a useful addition might be to allow the selection of a value via the 1Password secret reference format: op://<vault>/<item>/<section>/<field>, or op://<vault>/<item>/<field>. This might improve convenience a little but apart from that provides little value.
  • It might also be useful to allow filtering fields by field type using an additional type argument. However this is probably most useful if the user wants to retrieve all fields of a specific type, not just a single field.

codello avatar Sep 02 '22 09:09 codello

@codello This is excellent feedback. Give me a bit to read through and respond.

samdoran avatar Sep 02 '22 13:09 samdoran

Currently specifying a section breaks lookups with a 'NoneType' object is not iterable. error. This is because data.get(section) does not work for the v2 JSON schema.

Great catch. The simple fix would be to default to en empty list instead of None. Also, we need a test case for that.

Currently if a field is not found in an item an empty string is returned.

I'm in favor of matching on ID or label. Looking through some items, ID and label are the same sometimes, but not always. ID seems to be a GUID most of the time whereas label is the human-visible field. It might make sense to prefer label as the primary match and fall back to ID.

If multiple or no matches are found, raise an error. Currently if a field is not found in an item an empty string is returned.

I would have to think more about what to do in this case. This would be a breaking change and should be addressed in a separate PR.

Currently the requested field is matched against the field's ID as well as the keys of the item's JSON representation. I don't see an application for this.

Yeah, that seems a bit greedy. The matching should be on label first and fall back to ID.

Also as a side node the docs still say Tested with op version 0.5.3

I'll fix that.

samdoran avatar Sep 02 '22 14:09 samdoran

Looking the v2 schema for sections, there is no value field, so I'm not sure it makes sense to allow sections in the v2 CLI. Maybe we could warn for that?

samdoran avatar Sep 02 '22 18:09 samdoran

Docs Build 📝

Thank you for contribution!✨

This PR has been merged and your docs changes will be incorporated when they are next published.

github-actions[bot] avatar Sep 02 '22 19:09 github-actions[bot]

Looking the v2 schema for sections, there is no value field, so I'm not sure it makes sense to allow sections in the v2 CLI. Maybe we could warn for that?

I am not sure if I completely understand. Completely removing support for sections would not be my preferred solution, mostly because I tend to re-use the same field labels (like Username or Password) in different sections. When accessing fields via ID this is not a problem but when accessing fields by their label this would probably cause problems. In general I'd expect the lookup to work like this:

  • If a field is specified by ID, the field should be returned. I think for this to work IDs should be prioritized over labels during the lookup. Below is an example where this might be necessary.
  • If a field is specified by label and that label is unique the field should be returned.
  • If a field is specified by name and is not unique, I expect an error. As you said this might be considered a breaking change and might need to be addressed separately.
  • If a section is identified by label or ID I'd expect any resulting field to be in that section.

There is one edge case that is not quite clear to me: If a field is specified by ID and that field exists but in a different section than the user specified I am not sure which case takes priority. I think in this case the result should be empty (or preferably an error) because even though the item is uniquely identified it does not match the expected section so clearly something is wrong. This also matches the behavior of op item get.

I tried to put this behavior into some pseudo-code. I did not test this but hopefully it makes my though process clear:

def _parse_field(self, data_json, field_name, section_title=None):
    data = json.loads(data_json)
    
    matches = []
    
    for field in data.get("fields", []):
        if section_title == "" and "section" in field:
            # Treat the empty string as the default section. If a field belongs
            # to a section but we requested the default section, this is not a match.
            continue
        if section_title is not None:
            if "section" not in field:
                # We requested a section but the field does not belong to one.
                # This is not a match.
                continue
            if (
                field["section"].get("id") != section_title
                and field["section"].get("label") != section_title
            ):
                # We requested a section but neither the id nor the label of this
                # item's section match. This is not a match.
                continue
        
        if field.get("id") == field_name:
            # We might want to prioritize IDs and bail out here to be able to
            # guarantee that each field can be addressed.
            return field
        if field.get("label") == field_name:
            matches.append(field)
    
    
    if len(matches) == 0:
        raise NotFoundError
    if len(matches) > 1:
        raise TooManyMatchesError
    return matches[0]

Here is a (slightly redacted) JSON of an item in my 1Password vault for reference:

{
  "id": "4fym...",
  "title": "Test",
  "version": 3,
  "vault": {
    "id": "dkov...",
    "name": "Personal"
  },
  "category": "API_CREDENTIAL",
  "last_edited_by": "N43H...",
  "created_at": "2022-09-03T20:32:29Z",
  "updated_at": "2022-09-03T21:04:36Z",
  "additional_information": "bearer",
  "sections": [
    {
      "id": "ver6dax344cakdckoq4clvbgg4",
      "label": "Database"
    },
    {
      "id": "js566w4t4wagh7yjivlujneiem",
      "label": "SMTP"
    }
  ],
  "fields": [
    {
      "id": "notesPlain",
      "type": "STRING",
      "purpose": "NOTES",
      "label": "notesPlain",
      "reference": "op://Personal/Test/notesPlain"
    },
    {
      "id": "username",
      "type": "STRING",
      "label": "Benutzername",
      "value": "some name",
      "reference": "op://Personal/Test/Benutzername"
    },
    {
      "id": "credential",
      "type": "CONCEALED",
      "label": "Anmeldedaten",
      "value": "some password",
      "reference": "op://Personal/Test/Anmeldedaten"
    },
    {
      "id": "type",
      "type": "MENU",
      "label": "Typ",
      "value": "bearer",
      "reference": "op://Personal/Test/Typ"
    },
    {
      "id": "q3wjz2pdkjb3axohgbrmtvql2e",
      "type": "STRING",
      "label": "type",
      "value": "MyType",
      "reference": "op://Personal/Test/type"
    },
    {
      "id": "qeoer3o33xufkrgiywiqaymgha",
      "section": {
        "id": "ver6dax344cakdckoq4clvbgg4",
        "label": "Database"
      },
      "type": "STRING",
      "label": "user",
      "value": "my-db-user",
      "reference": "op://Personal/Test/Database/user"
    },
    {
      "id": "6ryw2k4sdkeg7phmdzuacbmoiq",
      "section": {
        "id": "js566w4t4wagh7yjivlujneiem",
        "label": "SMTP"
      },
      "type": "STRING",
      "label": "user",
      "value": "my-smpt-user",
      "reference": "op://Personal/Test/SMTP/user"
    }
  ]
}

Here the preference of IDs over labels is important. A lookup of the field type should imo return a unique result "bearer", even though the field with the label type might also be a match. This is analogous to the op item get --field command.

codello avatar Sep 03 '22 21:09 codello

I am not sure if I completely understand.

I meant that the value of sections doesn't contain any values:

  "sections": [
    {
      "id": "ver6dax344cakdckoq4clvbgg4",
      "label": "Database"
    },
    {
      "id": "js566w4t4wagh7yjivlujneiem",
      "label": "SMTP"
    }
  ],

I think my understanding of the "section" parameter was a bit off. "section" doesn't iterate through "sections" in the output but should match on fields[item]["section"]["label"]. Does that sound correct?

samdoran avatar Sep 13 '22 20:09 samdoran

The test licenses failed with 10 errors:

tests/unit/plugins/lookup/onepassword/files/v2_out_01.json:0:0: found no copyright notice
tests/unit/plugins/lookup/onepassword/files/v2_out_01.json:0:0: must have at least one license
tests/unit/plugins/lookup/onepassword/files/v1_out_02.json:0:0: found no copyright notice
tests/unit/plugins/lookup/onepassword/files/v1_out_02.json:0:0: must have at least one license
tests/unit/plugins/lookup/onepassword/files/v1_out_01.json:0:0: found no copyright notice
tests/unit/plugins/lookup/onepassword/files/v1_out_01.json:0:0: must have at least one license
tests/unit/plugins/lookup/onepassword/files/v1_out_03.json:0:0: found no copyright notice
tests/unit/plugins/lookup/onepassword/files/v1_out_03.json:0:0: must have at least one license
tests/unit/plugins/lookup/onepassword/files/v2_out_02.json:0:0: found no copyright notice
tests/unit/plugins/lookup/onepassword/files/v2_out_02.json:0:0: must have at least one license

click here for bot help

ansibullbot avatar Sep 13 '22 21:09 ansibullbot

I meant that the value of sections doesn't contain any values

Ah ok, now I got it. Thanks!

"section" doesn't iterate through "sections" in the output but should match on fields[item]["section"]["label"]. Does that sound correct?

Yes, pretty much. I think the sections array in the JSON is only there to be able to order the sections the same way 1Password does. For the purpose of finding a field the fields array contains all the information needed and fields[i]["section"]["label"] and fields[i]["section"]["id"] contain the label and ID of the section respectively. If a field belongs to the default section fields[I]["section"] does not exist.

codello avatar Sep 14 '22 19:09 codello

The test ansible-test sanity --test pep8 [explain] failed with 1 error:

plugins/lookup/onepassword_raw.py:90:9: E303: too many blank lines (2)

The test ansible-test sanity --test pep8 [explain] failed with 1 error:

plugins/lookup/onepassword_raw.py:90:9: E303: too many blank lines (2)

The test ansible-test sanity --test pep8 [explain] failed with 1 error:

plugins/lookup/onepassword_raw.py:90:9: E303: too many blank lines (2)

The test ansible-test sanity --test pep8 [explain] failed with 1 error:

plugins/lookup/onepassword_raw.py:90:9: E303: too many blank lines (2)

click here for bot help

ansibullbot avatar Sep 16 '22 16:09 ansibullbot

I've tested it here locally with both op versions (2.7.1 and 1.12.4). Both works for me.
This is a very valuable PR. @samdoran can you add a changelog fragment please?

markuman avatar Oct 08 '22 17:10 markuman

Will do. I have few minor things left to finalize and want to add more test scenarios, but I'm feeling good about where it is currently.

samdoran avatar Oct 10 '22 02:10 samdoran

Please note that the community.general 6.0.0 release is in two weeks (November 7th), I think it would be great if this PR could make it into that one.

felixfontein avatar Oct 25 '22 06:10 felixfontein

Eek. Thanks for the push. I started a new job and have been focused that. I will do my best to get this over the line.

samdoran avatar Oct 25 '22 13:10 samdoran

The test ansible-test sanity --test import --python 3.9 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.8 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.7 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.6 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.5 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.11 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.10 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 2.7 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test pylint [explain] failed with 1 error:

plugins/module_utils/onepassword.py:14:0: ansible-bad-module-import: Import external package or ansible.module_utils not ansible.errors

The test ansible-test sanity --test import --python 3.9 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.8 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.7 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.6 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.5 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.10 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 2.7 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.9 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.8 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.7 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.6 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.5 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.10 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 2.7 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 2.6 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.9 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.8 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.7 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.6 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.5 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.11 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.10 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 2.7 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test pylint [explain] failed with 1 error:

plugins/module_utils/onepassword.py:14:0: ansible-bad-module-import: Import external package or ansible.module_utils not ansible.errors

The test ansible-test sanity --test pylint [explain] failed with 1 error:

plugins/module_utils/onepassword.py:14:0: ansible-bad-module-import: Import external package or ansible.module_utils not ansible.errors

The test ansible-test sanity --test import --python 3.9 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.8 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.7 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.6 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 3.5 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 2.7 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test import --python 2.6 [explain] failed with 2 errors:

plugins/module_utils/onepassword.py:14:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context
plugins/modules/onepassword_info.py:169:0: traceback: ImportError: import of "ansible.errors" is not allowed in this context (at plugins/module_utils/onepassword.py:14:0)

The test ansible-test sanity --test pylint [explain] failed with 1 error:

plugins/module_utils/onepassword.py:14:0: ansible-bad-module-import: Import external package or ansible.module_utils not ansible.errors

The test ansible-test sanity --test pylint [explain] failed with 1 error:

plugins/module_utils/onepassword.py:14:0: ansible-bad-module-import: Import external package or ansible.module_utils not ansible.errors

click here for bot help

ansibullbot avatar Nov 04 '22 16:11 ansibullbot

The test ansible-test sanity --test compile --python 3.5 [explain] failed with 1 error:

tests/unit/plugins/lookup/onepassword/test_onepassword.py:165:44: SyntaxError: f"v{cls.supports_version}_{idx + 1}" for cls in MOCK_ENTRIES

The test ansible-test sanity --test compile --python 2.7 [explain] failed with 1 error:

tests/unit/plugins/lookup/onepassword/test_onepassword.py:165:44: SyntaxError: f"v{cls.supports_version}_{idx + 1}" for cls in MOCK_ENTRIES

The test ansible-test sanity --test compile --python 2.6 [explain] failed with 1 error:

tests/unit/plugins/lookup/onepassword/test_onepassword.py:165:44: SyntaxError: f"v{cls.supports_version}_{idx + 1}" for cls in MOCK_ENTRIES

click here for bot help

ansibullbot avatar Nov 04 '22 20:11 ansibullbot

This is good to merge now.

samdoran avatar Nov 04 '22 20:11 samdoran

Thanks for all the feedback and patience, everyone.

samdoran avatar Nov 04 '22 21:11 samdoran

@samdoran thanks a lot for your contribution! @ahussey-redhat @codello @markuman thanks for reviewing and giving feedback!

felixfontein avatar Nov 06 '22 10:11 felixfontein