Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New for_user option in quay_api_token (Quay 3.12) #5

Merged
merged 1 commit into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
...