feat: migrate 1Password lookup plugin to community.general.onepassword and remove deprecated files
Some checks failed
Nix Format Check / check-format (push) Failing after 43s
Some checks failed
Nix Format Check / check-format (push) Failing after 43s
This commit is contained in:
parent
94a2b35770
commit
02cf04b81a
@ -2,5 +2,4 @@
|
|||||||
inventory = inventory
|
inventory = inventory
|
||||||
roles_path = roles
|
roles_path = roles
|
||||||
collections_paths = collections
|
collections_paths = collections
|
||||||
lookup_plugins = /home/menno/.dotfiles/config/ansible/plugins/lookup
|
|
||||||
retry_files_enabled = False
|
retry_files_enabled = False
|
@ -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
|
|
@ -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
|
|
@ -4,7 +4,7 @@ services:
|
|||||||
image: ghcr.io/tailscale/golink:main
|
image: ghcr.io/tailscale/golink:main
|
||||||
user: root
|
user: root
|
||||||
environment:
|
environment:
|
||||||
- TS_AUTHKEY={{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/GoLink/TS_AUTHKEY') }}
|
- TS_AUTHKEY={{ lookup('community.general.onepassword', '4gsgavajnxfpcrjvbkqhoc4drm', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='TS_AUTHKEY') }}
|
||||||
volumes:
|
volumes:
|
||||||
- {{ golink_data_dir }}:/home/nonroot
|
- {{ golink_data_dir }}:/home/nonroot
|
||||||
restart: "unless-stopped"
|
restart: "unless-stopped"
|
||||||
|
@ -7,6 +7,6 @@ NEXTAUTH_URL=http://localhost:3000
|
|||||||
|
|
||||||
DATA_DIR=/data
|
DATA_DIR=/data
|
||||||
|
|
||||||
NEXTAUTH_SECRET="{{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/Hoarder/NEXTAUTH_SECRET') }}"
|
NEXTAUTH_SECRET="{{ lookup('community.general.onepassword', 'osnzlfidxonvetmomdgn7vxu5a', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='NEXTAUTH_SECRET') }}"
|
||||||
MEILI_MASTER_KEY="{{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/Hoarder/MEILI_MASTER_KEY') }}"
|
MEILI_MASTER_KEY="{{ lookup('community.general.onepassword', 'osnzlfidxonvetmomdgn7vxu5a', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='MEILI_MASTER_KEY') }}"
|
||||||
OPENAI_API_KEY="{{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/Hoarder/OPENAI_API_KEY') }}"
|
OPENAI_API_KEY="{{ lookup('community.general.onepassword', 'osnzlfidxonvetmomdgn7vxu5a', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='OPENAI_API_KEY') }}"
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
---
|
|
||||||
- name: Configure SSHFS
|
- name: Configure SSHFS
|
||||||
block:
|
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
|
- name: Get SSHFS credentials via local lookup
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
sshfs_user: "{{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/5j5y5axfjr3f3sn5nixb6htg4y/username') }}"
|
sshfs_user: "{{ lookup('community.general.onepassword', '5j5y5axfjr3f3sn5nixb6htg4y', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='username') }}"
|
||||||
sshfs_pass: "{{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/5j5y5axfjr3f3sn5nixb6htg4y/new_password') }}"
|
sshfs_pass: "{{ lookup('community.general.onepassword', '5j5y5axfjr3f3sn5nixb6htg4y', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='password') }}"
|
||||||
sshfs_host: "{{ lookup('my_1password', 'op://j7nmhqlsjmp2r6umly5t75hzb4/5j5y5axfjr3f3sn5nixb6htg4y/host') }}"
|
sshfs_host: "{{ lookup('community.general.onepassword', '5j5y5axfjr3f3sn5nixb6htg4y', vault='j7nmhqlsjmp2r6umly5t75hzb4', field='host') }}"
|
||||||
sshfs_port: 23
|
sshfs_port: 23
|
||||||
remote_path: /mnt/storage-box
|
remote_path: /mnt/storage-box
|
||||||
|
|
||||||
|
@ -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') }}"
|
|
Loading…
x
Reference in New Issue
Block a user