From 02cf04b81ac04f449a1a11dcede7b6a4e4333a41 Mon Sep 17 00:00:00 2001 From: Menno van Leeuwen Date: Tue, 11 Mar 2025 22:03:06 +0100 Subject: [PATCH] feat: migrate 1Password lookup plugin to community.general.onepassword and remove deprecated files --- config/ansible/ansible.cfg | 1 - config/ansible/plugins/lookup/README.md | 52 ------------- config/ansible/plugins/lookup/my_1password.py | 78 ------------------- .../services/golink/docker-compose.yml.j2 | 2 +- .../tasks/servers/services/hoarder/dotenv.j2 | 6 +- config/ansible/tasks/servers/sshfs.yml | 11 +-- .../ansible/tests/test-onepassword-lookup.yml | 21 ----- 7 files changed, 7 insertions(+), 164 deletions(-) delete mode 100644 config/ansible/plugins/lookup/README.md delete mode 100644 config/ansible/plugins/lookup/my_1password.py delete mode 100644 config/ansible/tests/test-onepassword-lookup.yml diff --git a/config/ansible/ansible.cfg b/config/ansible/ansible.cfg index 3deeaac..4c9be68 100644 --- a/config/ansible/ansible.cfg +++ b/config/ansible/ansible.cfg @@ -2,5 +2,4 @@ inventory = inventory roles_path = roles collections_paths = collections -lookup_plugins = /home/menno/.dotfiles/config/ansible/plugins/lookup retry_files_enabled = False \ No newline at end of file diff --git a/config/ansible/plugins/lookup/README.md b/config/ansible/plugins/lookup/README.md deleted file mode 100644 index a90ed51..0000000 --- a/config/ansible/plugins/lookup/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# OnePassword Lookup Plugin - -This Ansible lookup plugin allows you to securely fetch secrets from 1Password using the 1Password CLI. - -## Requirements - -- 1Password CLI (`op`) must be installed and available in your PATH -- You must be signed in to 1Password CLI (`op signin`) - -## Usage - -The lookup plugin accepts a 1Password reference string in the format `op://vault/item/field`. - -```yaml -- name: Fetch a secret from 1Password - debug: - msg: "{{ lookup('my_1password', 'op://vault/item/password') }}" -``` - -## Examples - -### Fetch a password - -```yaml -- name: Fetch API key - debug: - msg: "{{ lookup('my_1password', 'op://My Vault/API Credentials/token') }}" -``` - -### Using with templates - -```yaml -# In your template file (e.g., config.j2) -api_key: "{{ lookup('my_1password', 'op://My Vault/API Credentials/token') }}" -``` - -### Multiple secrets - -```yaml -- name: Fetch multiple secrets - debug: - msg: - - "{{ lookup('my_1password', 'op://vault/item1/field') }}" - - "{{ lookup('my_1password', 'op://vault/item2/field') }}" -``` - -## Error Handling - -The plugin will raise an error if: -- The reference doesn't start with `op://` -- The secret is not found in 1Password -- There's an error executing the 1Password CLI diff --git a/config/ansible/plugins/lookup/my_1password.py b/config/ansible/plugins/lookup/my_1password.py deleted file mode 100644 index 9b8bf2e..0000000 --- a/config/ansible/plugins/lookup/my_1password.py +++ /dev/null @@ -1,78 +0,0 @@ -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -DOCUMENTATION = """ - name: my_1password - author: Menno - version_added: "1.0" - short_description: fetch secrets from 1Password - description: - - Uses the 1Password CLI to fetch secrets from 1Password using the op read command - options: - _terms: - description: 1Password reference string (op://vault/item/field) - required: true -""" - -EXAMPLES = """ -- name: fetch password using 1Password reference - debug: - msg: "{{ lookup('my_1password', 'op://vault/item/password') }}" - -- name: fetch username from item - debug: - msg: "{{ lookup('my_1password', 'op://vault/item/username') }}" - -- name: fetch custom field - debug: - msg: "{{ lookup('my_1password', 'op://vault/item/custom_field') }}" -""" - -RETURN = """ - _raw: - description: field data requested -""" - -from ansible.errors import AnsibleError -from ansible.plugins.lookup import LookupBase -from ansible.utils.display import Display -import subprocess - -display = Display() - -class LookupModule(LookupBase): - def run(self, terms, variables=None, **kwargs): - result = [] - - for term in terms: - if not term.startswith('op://'): - raise AnsibleError(f"1Password reference must start with 'op://', got: {term}") - - cmd = ['op', 'read', term] - display.vvv(f"Executing command: {' '.join(cmd)}") - - try: - process = subprocess.run( - cmd, - capture_output=True, - text=True, - check=True - ) - output = process.stdout.strip() - display.vvv(f"1Password output for '{term}': '{output}'") - - if not output: - display.warning(f"1Password returned empty output for '{term}'") - - result.append(output) - except subprocess.CalledProcessError as e: - error_msg = e.stderr.strip() - display.warning(f"Error executing 1Password CLI: {error_msg}") - display.warning(f"Command used: {' '.join(cmd)}") - - if "not found" in error_msg: - raise AnsibleError(f"Secret referenced by '{term}' not found in 1Password") - - raise AnsibleError(f"Error fetching from 1Password: {error_msg}") - - return result diff --git a/config/ansible/tasks/servers/services/golink/docker-compose.yml.j2 b/config/ansible/tasks/servers/services/golink/docker-compose.yml.j2 index f5a1e82..e498b1b 100644 --- a/config/ansible/tasks/servers/services/golink/docker-compose.yml.j2 +++ b/config/ansible/tasks/servers/services/golink/docker-compose.yml.j2 @@ -4,7 +4,7 @@ services: image: ghcr.io/tailscale/golink:main user: root environment: - - TS_AUTHKEY={{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/GoLink/TS_AUTHKEY') }} + - TS_AUTHKEY={{ lookup('community.general.onepassword', '4gsgavajnxfpcrjvbkqhoc4drm', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='TS_AUTHKEY') }} volumes: - {{ golink_data_dir }}:/home/nonroot restart: "unless-stopped" diff --git a/config/ansible/tasks/servers/services/hoarder/dotenv.j2 b/config/ansible/tasks/servers/services/hoarder/dotenv.j2 index b661468..7e2cd46 100644 --- a/config/ansible/tasks/servers/services/hoarder/dotenv.j2 +++ b/config/ansible/tasks/servers/services/hoarder/dotenv.j2 @@ -7,6 +7,6 @@ NEXTAUTH_URL=http://localhost:3000 DATA_DIR=/data -NEXTAUTH_SECRET="{{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/Hoarder/NEXTAUTH_SECRET') }}" -MEILI_MASTER_KEY="{{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/Hoarder/MEILI_MASTER_KEY') }}" -OPENAI_API_KEY="{{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/Hoarder/OPENAI_API_KEY') }}" +NEXTAUTH_SECRET="{{ lookup('community.general.onepassword', 'osnzlfidxonvetmomdgn7vxu5a', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='NEXTAUTH_SECRET') }}" +MEILI_MASTER_KEY="{{ lookup('community.general.onepassword', 'osnzlfidxonvetmomdgn7vxu5a', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='MEILI_MASTER_KEY') }}" +OPENAI_API_KEY="{{ lookup('community.general.onepassword', 'osnzlfidxonvetmomdgn7vxu5a', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='OPENAI_API_KEY') }}" diff --git a/config/ansible/tasks/servers/sshfs.yml b/config/ansible/tasks/servers/sshfs.yml index e0e0bf2..75f55f8 100644 --- a/config/ansible/tasks/servers/sshfs.yml +++ b/config/ansible/tasks/servers/sshfs.yml @@ -1,16 +1,11 @@ ---- - name: Configure SSHFS block: - - name: Debug which plugin is being used - ansible.builtin.debug: - msg: "Using lookup plugins from: {{ lookup('pipe', 'ansible-config dump | grep DEFAULT_LOOKUP_PLUGIN_PATH') }}" - - name: Get SSHFS credentials via local lookup delegate_to: localhost ansible.builtin.set_fact: - sshfs_user: "{{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/5j5y5axfjr3f3sn5nixb6htg4y/username') }}" - sshfs_pass: "{{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/5j5y5axfjr3f3sn5nixb6htg4y/new_password') }}" - sshfs_host: "{{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/5j5y5axfjr3f3sn5nixb6htg4y/host') }}" + sshfs_user: "{{ lookup('community.general.onepassword', '5j5y5axfjr3f3sn5nixb6htg4y', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='username') }}" + sshfs_pass: "{{ lookup('community.general.onepassword', '5j5y5axfjr3f3sn5nixb6htg4y', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='password') }}" + sshfs_host: "{{ lookup('community.general.onepassword', '5j5y5axfjr3f3sn5nixb6htg4y', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='host') }}" sshfs_port: 23 remote_path: /mnt/storage-box diff --git a/config/ansible/tests/test-onepassword-lookup.yml b/config/ansible/tests/test-onepassword-lookup.yml deleted file mode 100644 index 8f3ec66..0000000 --- a/config/ansible/tests/test-onepassword-lookup.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- -- name: Test 1Password Lookup Plugin - hosts: localhost - connection: local - gather_facts: false - vars: - hoarder_data_dir: /mnt/storage-box/services/hoarder - tasks: - - name: Test lookup with direct reference - ansible.builtin.debug: - msg: "{{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/5j5y5axfjr3f3sn5nixb6htg4y/host') }}" - - - name: Template with lookup - ansible.builtin.template: - src: ../tasks/servers/services/hoarder/dotenv.j2 - dest: /tmp/.env - register: op_direct - - - name: Print out the templated file - ansible.builtin.debug: - msg: "{{ lookup('file', '/tmp/.env') }}"