Skip to content

Commit

Permalink
quay_robot - keyless authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
Hervé Quatremain committed Nov 26, 2024
1 parent 48ffc94 commit 083d0db
Show file tree
Hide file tree
Showing 7 changed files with 279 additions and 9 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.5.0
======

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

Support configuring keyless authentications with robot accounts.

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

- Add the ``federations`` option to the ``infra.quay_configuration.quay_robot`` module. With this option, you can configure keyless authentications with robot accounts (Quay 3.13 and later)

v2.4.0
======

Expand Down
10 changes: 10 additions & 0 deletions changelogs/changelog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,13 @@ releases:
name: quay_repository_prune
namespace: ''
release_date: '2024-11-23'
2.5.0:
changes:
minor_changes:
- Add the ``federations`` option to the ``infra.quay_configuration.quay_robot``
module. With this option, you can configure keyless authentications with robot
accounts (Quay 3.13 and later)
release_summary: Support configuring keyless authentications with robot accounts.
fragments:
- 17-v2.5.0-summary.yml
release_date: '2024-11-26'
4 changes: 2 additions & 2 deletions plugins/modules/quay_repository_mirror.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
description:
- Path to the remote container repository to synchronize, such as
quay.io/projectquay/quay for example.
- That parameter is required when creating the mirroring configuration.
- This parameter is required when creating the mirroring configuration.
type: str
external_registry_username:
description:
Expand Down Expand Up @@ -83,7 +83,7 @@
robot_username:
description:
- Username of the robot account that is used for synchronization.
- That parameter is required when creating the mirroring configuration.
- This parameter is required when creating the mirroring configuration.
type: str
image_tags:
description:
Expand Down
104 changes: 101 additions & 3 deletions plugins/modules/quay_robot.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,34 @@
- Description of the robot account. You cannot update the description
of existing robot accounts.
type: str
federations:
description:
- Federation configurations, which enable keyless authentication with
robot accounts.
- Robot account federations require Quay version 3.13 or later.
type: list
elements: dict
suboptions:
issuer:
description:
- OpenID Connect (OIDC) issuer URL.
required: true
type: str
subject:
description:
- OpenID Connect (OIDC) subject.
required: true
type: str
append:
description:
- If V(true), then add the robot account federation configurations
defined in O(federations).
- If V(false), then the module sets the federation configurations
specified in O(federations), removing all others federation
configurations.
- Robot account federations require Quay version 3.13 or later.
type: bool
default: true
state:
description:
- If V(absent), then the module deletes the robot account.
Expand All @@ -68,6 +96,8 @@
notes:
- The token that you provide in O(quay_token) must have the "Administer
Organization" and "Administer User" permissions.
- The O(federations) and O(append) parameters require Quay version 3.13 or
later.
attributes:
check_mode:
support: full
Expand Down Expand Up @@ -113,6 +143,18 @@
state: absent
quay_host: https://quay.example.com
quay_token: vgfH9zH5q6eV16Con7SvDQYSr0KPYQimMHVehZv7
# Robot account federations require Quay version 3.13 or later
- name: Ensure the robot account production+robotprod2 exists, with federation
infra.quay_configuration.quay_robot:
name: production+robotprod2
description: Second robot account for production
federations:
- issuer: https://keycloak-auth-realm.quayadmin.org/realms/quayrealm
subject: 449e14f8-9eb5-4d59-a63e-b7a77c75f770
state: present
quay_host: https://quay.example.com
quay_token: vgfH9zH5q6eV16Con7SvDQYSr0KPYQimMHVehZv7
"""

RETURN = r"""
Expand All @@ -132,6 +174,8 @@
sample: IWG3K5EW92KZLPP42PMOKM5CJ2DEAQMSCU33A35NR7MNL21004NKVP3BECOWSQP2
"""

import json

from ..module_utils.api_module import APIModule


Expand All @@ -158,6 +202,15 @@ def main():
argument_spec = dict(
name=dict(required=True),
description=dict(),
federations=dict(
type="list",
elements="dict",
options=dict(
issuer=dict(required=True),
subject=dict(required=True),
),
),
append=dict(type="bool", default=True),
state=dict(choices=["present", "absent"], default="present"),
)

Expand All @@ -167,6 +220,8 @@ def main():
# Extract our parameters
name = module.params.get("name")
description = module.params.get("description")
federations = module.params.get("federations")
append = module.params.get("append")
state = module.params.get("state")

namespace, robot_shortname, is_org = module.split_name("name", name, state, separator="+")
Expand All @@ -179,6 +234,13 @@ def main():
else:
path_url = "user/robots/{robot_shortname}".format(robot_shortname=robot_shortname)

fed_url = "{url}/federation".format(url=path_url)
fed_req_set = (
set([(f.get("issuer"), f.get("subject")) for f in federations])
if federations
else set()
)

# Get the robot account details.
#
# For robot accounts in organizations:
Expand Down Expand Up @@ -211,15 +273,51 @@ def main():
module.delete(robot_details, "robot account", name, path_url)

if robot_details:
exit_module(module, False, robot_details)
# GET /api/v1/organization/{orgname}/robots/{robot_shortname}/federation
# [
# {
# "issuer": "https://keycloak-realm.quayadmin.org/realms/quayrealm",
# "subject": "449e14f8-9eb5-4d59-a63e-b7a77c75f770"
# }
# ]
fed_details = module.get_object_path(fed_url)
fed_curr_set = (
set([(f.get("issuer"), f.get("subject")) for f in fed_details])
if fed_details
else set()
)
fed_to_add = fed_req_set - fed_curr_set

if federations is None or fed_req_set == fed_curr_set or (append and not fed_to_add):
exit_module(module, False, robot_details)

if append:
new_fields = [
{"issuer": f[0], "subject": f[1], "isExpanded": False}
for f in fed_req_set | fed_curr_set
]
else:
new_fields = [
{"issuer": f[0], "subject": f[1], "isExpanded": False} for f in fed_req_set
]
data = json.dumps(new_fields).encode()
module.create("robot account federation", name, fed_url, data, auto_exit=False)
exit_module(module, True, robot_details)

# Prepare the data that gets set for create
new_fields = {}
if description:
new_fields["description"] = description

data = module.unconditional_update("robot account", name, path_url, new_fields)
exit_module(module, True, data)
robot_data = module.unconditional_update("robot account", name, path_url, new_fields)
if federations:
new_fields = [
{"issuer": f.get("issuer"), "subject": f.get("subject"), "isExpanded": False}
for f in federations
]
data = json.dumps(new_fields).encode()
module.create("robot account federation", name, fed_url, data, auto_exit=False)
exit_module(module, True, robot_data)


if __name__ == "__main__":
Expand Down
4 changes: 2 additions & 2 deletions plugins/modules/quay_team_ldap.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
name:
description:
- Name of the team to synchronize or unsynchronize with an LDAP group.
That team must exist (see the M(infra.quay_configuration.quay_team) module to
create it).
This team must exist (see the M(infra.quay_configuration.quay_team)
module to create it).
required: true
type: str
organization:
Expand Down
4 changes: 2 additions & 2 deletions plugins/modules/quay_team_oidc.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
name:
description:
- Name of the team to synchronize or unsynchronize with an OIDC group.
That team must exist (see the M(infra.quay_configuration.quay_team) module to
create it).
This team must exist (see the M(infra.quay_configuration.quay_team)
module to create it).
required: true
type: str
organization:
Expand Down
Loading

0 comments on commit 083d0db

Please sign in to comment.