Skip to content

Commit

Permalink
New for_user option in quay_api_token (Quay 3.12) (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
herve4m authored Aug 5, 2024
1 parent 94dc8f5 commit 2d18565
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 19 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ Quay Container Registry Collection Release Notes

.. contents:: Topics

v2.2.0
======

Release Summary
---------------

Support creating OAuth access tokens for other users.

Minor Changes
-------------

- Add the ``for_user`` option to the ``infra.quay_configuration.quay_api_token`` module. With this option you can assign OAuth API tokens to other users (Quay 3.12 and later).

v2.1.0
======

Expand Down
10 changes: 10 additions & 0 deletions changelogs/changelog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -244,3 +244,13 @@ releases:
fragments:
- PR2-v2.1.0-summary.yml
release_date: '2024-07-29'
2.2.0:
changes:
minor_changes:
- Add the ``for_user`` option to the ``infra.quay_configuration.quay_api_token``
module. With this option you can assign OAuth API tokens to other users (Quay
3.12 and later).
release_summary: Support creating OAuth access tokens for other users.
fragments:
- PR5-v2.2.0-summary.yml
release_date: '2024-08-05'
2 changes: 1 addition & 1 deletion galaxy.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
namespace: infra
name: quay_configuration
version: 2.1.0
version: 2.2.0
readme: README.md
authors:
- Hervé Quatremain <[email protected]>
Expand Down
74 changes: 63 additions & 11 deletions plugins/modules/quay_api_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,23 @@
- user:read
- all
default: repo:read
for_user:
description:
- The username to generate an OAuth access token for.
- The user receives a notification in the web interface, which enables
the user to retrieve the token.
- When you use this option, the module does not return the token.
- Requires Quay version 3.12 or later.
type: str
required: false
notes:
- Supports C(check_mode).
- I(for_user) requires Quay version 3.12 or later.
- Your Quay administrator must enable the OAuth assignment capability
of your Quay installation (C(FEATURE_ASSIGN_OAUTH_TOKEN) in C(config.yaml))
to use the I(for_user) option in Quay version 3.12 or later.
- The generated OAuth access token acts on behalf of the user account you use
with the module (in I(quay_username)).
with the module (in I(for_user) if set, otherwise in I(quay_username)).
- The user must have admin rights to the application's organization, by being
the creator of this organization, or by belonging to a team with admin
rights.
Expand All @@ -97,9 +110,21 @@
register: token_details
- name: Display the new OAuth access token
debug:
ansible.builtin.debug:
msg: "The OAuth access token is: {{ token_details['access_token'] }}"
- name: Generate an OAuth access token for dwilde
infra.quay_configuration.quay_api_token:
quay_username: lvasquez
quay_password: vs9mrD55NP
# A notification in the web interface informs dwilde of the new OAuth
# access token.
for_user: dwilde
client_id: PZ6F80R1LCVPGYNZGSZQ
rights:
- repo:admin
quay_host: https://quay.example.com
# The following example creates an organization, an OAuth application, a user
# account, and a team, and then generates an OAuth access token for this user
# account.
Expand Down Expand Up @@ -154,14 +179,14 @@
register: token_details
- name: Display the new OAuth access token
debug:
ansible.builtin.debug:
msg: "The OAuth access token is: {{ token_details['access_token'] }}"
"""

RETURN = r"""
access_token:
description: The OAuth access token.
returned: always
returned: only when I(for_user) is not set
type: str
sample: CywbRGkh1ttYkRRy9VL0Aw0yU9q7J62vIeo7WCFw
"""
Expand Down Expand Up @@ -194,6 +219,7 @@ def main():
rights=dict(
type="list", elements="str", choices=allowed_rights, default=["repo:read"]
),
for_user=dict(),
)

# Create a module for ourselves
Expand All @@ -209,25 +235,51 @@ def main():
rights.remove("all")
else:
rights = set(rights)
for_user = module.params.get("for_user")

# Generate the OAuth access token
headers = {
"Accept": "*/*",
"Content-Type": "application/x-www-form-urlencoded",
}
redirect_url = module.host_url._replace(path="/oauth/localapp")
data = {
"response_type": "token",
"client_id": client_id,
"redirect_uri": redirect_url.geturl(),
"scope": " ".join(rights),
"_csrf_token": module.token,
}
url = module.host_url._replace(path="/oauth/authorizeapp")

# Generate an OAuth token for another user
if for_user is not None:
if module.check_mode:
module.exit_json(changed=True)
data["username"] = for_user
# The data is provided as URL query parameters
url = module.host_url._replace(path="/oauth/authorize/assignuser")._replace(
query=urlencode(data)
)
try:
response = module.make_raw_request("POST", url)
except APIModuleError as e:
module.fail_json(msg=str(e))

if response["status_code"] != 200:
module.fail_json(
msg=(
"Cannot create the OAuth access token for {user}: "
"Maybe the user does not exist."
).format(user=for_user)
)

module.exit_json(changed=True)

# Generate an OAuth token for the current user
if module.check_mode:
module.exit_json(
changed=True, access_token="NotValidCheckModeNotValidCheckModeNotVal"
)
data["_csrf_token"] = module.token
headers = {
"Accept": "*/*",
"Content-Type": "application/x-www-form-urlencoded",
}
url = module.host_url._replace(path="/oauth/authorizeapp")
try:
response = module.make_raw_request(
"POST",
Expand Down
2 changes: 1 addition & 1 deletion plugins/modules/quay_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
quay_token: vgfH9zH5q6eV16Con7SvDQYSr0KPYQimMHVehZv7
register: app_details
- debug:
- ansible.builtin.debug:
msg: "Client secret: {{ app_details['client_secret'] }}"
- name: Ensure the application is renamed
Expand Down
2 changes: 1 addition & 1 deletion plugins/modules/quay_first_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
quay_host: https://quay.example.com
register: result
- debug:
- ansible.builtin.debug:
msg: "Access token: {{ result['access_token'] }}"
"""

Expand Down
4 changes: 2 additions & 2 deletions plugins/modules/quay_robot.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@
quay_token: vgfH9zH5q6eV16Con7SvDQYSr0KPYQimMHVehZv7
register: robot_details
- debug:
- ansible.builtin.debug:
msg: "Robot token: {{ robot_details['token'] }}"
- debug:
- ansible.builtin.debug:
msg: "Docker configuration (Base64): {{ robot_details['name']
| infra.quay_configuration.quay_docker_config(robot_details['token'],
'https://quay.example.com') }}"
Expand Down
4 changes: 2 additions & 2 deletions plugins/modules/quay_tag_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@
- The module only returns expired tags when the I(only_active_tags)
parameter is C(no).
type: int
returned: only when an expiration date has been explicitly assigned.
returned: only when an expiration date has been explicitly assigned
sample: 1640336040
expiration:
description: Expiration date and time in a human readable format.
type: str
returned: only when an expiration date has been explicitly assigned.
returned: only when an expiration date has been explicitly assigned
sample: Fri, 24 Dec 2021 08:54:00 -0000
sample: [
{
Expand Down
19 changes: 18 additions & 1 deletion tests/integration/targets/quay_api_token/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
validate_certs: false
register: app_details

- name: Generate an OAuth access token for the user
- name: Generate an OAuth access token for the current user
infra.quay_configuration.quay_api_token:
quay_username: testuser1
quay_password: vs9mrD55NP
Expand All @@ -50,6 +50,23 @@
that: "'access_token' in result"
fail_msg: The result should have the access_token key

- name: Generate an OAuth access token for ansibletestuser1
infra.quay_configuration.quay_api_token:
for_user: ansibletestuser1
quay_username: testuser1
quay_password: vs9mrD55NP
client_id: "{{ app_details['client_id'] }}"
rights:
- org:admin
- repo:admin
- repo:create
- repo:read
- repo:write
- user:admin
- user:read
quay_host: "{{ quay_url }}"
validate_certs: false

- name: Ensure testteam1 team is removed
infra.quay_configuration.quay_team:
name: testteam1
Expand Down
5 changes: 5 additions & 0 deletions tests/integration/targets/setup_organization/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@
# To speed up the tests, only create the user accounts, robots, and teams
# when the organization does not already exist.
notify: Create resources in organization

# Ensure the user accounts, robots, and teams are created before the roles that
# might use them.
- name: Ensure the handlers run just after the role execution
ansible.builtin.meta: flush_handlers
...

0 comments on commit 2d18565

Please sign in to comment.