ansible-collections / community.digitalocean

This Ansible collection contains modules for assisting in the automation of the DigitalOcean cloud.
https://galaxy.ansible.com/community/digitalocean/
GNU General Public License v3.0
140 stars 57 forks source link

Release 1.24.0 broke using DO_API_TOKEN env variable #315

Closed gizero closed 1 year ago

gizero commented 1 year ago
SUMMARY

I'm using the dynamic inventory plugin. After upgrading the collection from 1.23.0 to 1.24.0 I got several CI pipelines failing with HTTP Error 401: Unauthorized. After rolling back to 1.23.0 everything went back to normal. All these scenarios expect the token to be provided via DO_API_TOKEN env variable, which is still supported as far as latest documentation suggests. Neither oauth_token nor api_token is set within the plugin configuration file.

To me it looks like https://github.com/ansible-collections/community.digitalocean/pull/301 somehow broke the expected behaviour of falling back to reading default env variables. Explicitly setting either oauth_token or api_token properties within config with something like '{{ lookup("ansible.builtin.env", "DO_API_TOKEN") }}' is an easy fix, but I believe this is unexpected and to be considered a bug.

ISSUE TYPE
COMPONENT NAME

Dynamic inventory plugin

ANSIBLE VERSION
# ansible --version
ansible [core 2.14.4]
  config file = /ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.10/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0] (/usr/bin/python3)
  jinja version = 3.1.2
  libyaml = True
COLLECTION VERSION
# ansible-galaxy collection list community.digitalocean

# /root/.ansible/collections/ansible_collections
Collection             Version
---------------------- -------
community.digitalocean 1.24.0
CONFIGURATION
# ansible-config dump --only-changed
CONFIG_FILE() = /ansible/ansible.cfg
DEFAULT_HOST_LIST(/ansible/ansible.cfg) = ['/ansible/inventory']
DEFAULT_REMOTE_USER(/ansible/ansible.cfg) = root
DEFAULT_ROLES_PATH(/ansible/ansible.cfg) = ['/root/.ansible/roles', '/ansible/roles']
HOST_KEY_CHECKING(/ansible/ansible.cfg) = False
HOST_PATTERN_MISMATCH(/ansible/ansible.cfg) = error
INTERPRETER_PYTHON(/ansible/ansible.cfg) = /usr/bin/python3
INVENTORY_ANY_UNPARSED_IS_FAILED(/ansible/ansible.cfg) = True
OS / ENVIRONMENT
# uname -a
Linux 007162c07c8e 5.15.49-linuxkit-pr #1 SMP Thu May 25 07:17:40 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
STEPS TO REPRODUCE
export DO_API_TOKEN=your-token
ansible-galaxy collection install community.digitalocean:=1.23
ansible-inventory --list  # (successfully returns my inventory)
ansible-galaxy collection install community.digitalocean:=1.24
ansible-inventory --list  # (fails with [Errno 13] Permission denied)
gizero commented 1 year ago

Looks like the problem was with completely dropping either oauth_token or api_token from DOCUMENTATION here.

mamercad commented 1 year ago

Thanks for filing this, I'm taking a look.

I haven't been able to reproduce it (yet):

❯ pwd
/Users/mark/src/github.com/ansible-collections/ansible_collections/community/digitalocean

❯ ansible-galaxy collection list | grep -E '^#|community.digitalocean'
# /Users/mark/.ansible/collections/ansible_collections
# /Users/mark/src/github.com/ansible-collections/ansible_collections
community.digitalocean   1.24.0 

❯ grep -v ^# digitalocean.yml
plugin: community.digitalocean.digitalocean
oauth_token: "{{ lookup('ansible.builtin.env', 'DO_API_TOKEN') }}"

❯ git checkout 1.23.0
Previous HEAD position was 090b5d8 Release 1.24.0 (#313)
HEAD is now at 0ef9c31 Release 1.23.0 (#298)

❯ ansible-inventory -i digitalocean.yml --graph | head -3
@all:
  |--@ungrouped:
  |  |--redacted

❯ git checkout 1.24.0
Previous HEAD position was 0ef9c31 Release 1.23.0 (#298)
HEAD is now at 090b5d8 Release 1.24.0 (#313)

❯ ansible-inventory -i digitalocean.yml --graph | head -3
@all:
  |--@ungrouped:
  |  |--redacted
mamercad commented 1 year ago

@gizero what does your (redacted) inventory file look like?

mamercad commented 1 year ago

Explicitly setting either oauth_token or api_token properties within config with something like '{{ lookup("ansible.builtin.env", "DO_API_TOKEN") }}' is an easy fix, but I believe this is unexpected and to be considered a bug.

Ah, I missed this (and now I can reproduce).

mamercad commented 1 year ago

@gizero What about this instead?

❯ git --no-pager diff
diff --git a/plugins/doc_fragments/digital_ocean.py b/plugins/doc_fragments/digital_ocean.py
index a82255b..736ffbd 100644
--- a/plugins/doc_fragments/digital_ocean.py
+++ b/plugins/doc_fragments/digital_ocean.py
@@ -25,6 +25,11 @@ options:
       - "i.e., - 'DO_API_TOKEN', 'DO_API_KEY', 'DO_OAUTH_TOKEN' and 'OAUTH_TOKEN'"
     type: str
     aliases: [ api_token ]
+    env:
+      - name: DO_API_TOKEN
+      - name: DO_API_KEY
+      - name: DO_OAUTH_TOKEN
+      - name: OAUTH_TOKEN
   timeout:
     description:
     - The timeout in seconds used for polling DigitalOcean's API.
gizero commented 1 year ago

@mamercad Thanks looking into it. I partially missed the intent of your original change. The common doc fragment is definitely the place to fix this! I updated #316 content and commit message accordingly to your suggestion and tested sourcing the token from all supported envs. It worked as expected!