Skip to content

Commit

Permalink
Refactor code
Browse files Browse the repository at this point in the history
  • Loading branch information
Hervé Quatremain committed Nov 24, 2024
1 parent f7af5c0 commit ab65042
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 194 deletions.
66 changes: 66 additions & 0 deletions plugins/module_utils/api_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,72 @@ def get_namespace(self, namespace, exit_on_error=True):
return user_details
return None

def split_name(self, parameter_name, value, state, separator="/"):
"""Split the namespace and the base name from a full name.
:param parameter_name: The name of the parameter being parsed. Used
only to display in the error message.
:type parameter_name: str
:param value: The value to split. Usually a namespace and a repository
(``production/smallimage`` for example), or a robot
account (``production+myrobot`` for example)
:type value: str
:param state: Whether it is a create/update (``present``) operation, or
a delete (``absent``) operation.
:type state: str
:param separator: The separator character between the namespace and the
object.
:type separator: str
:return: A list. The first item is the namespace, which can be a
personal namespace. The second item in the object name in the
namespace (usually a repository name or a robot account name).
The last item is a Boolean that indicates if the namespace is
an organization (``True``), or a personal namespace
(``False``).
:rtype: list
"""
# Extract namespace and name from the parameter
my_name = self.who_am_i()
try:
namespace, shortname = value.split(separator, 1)
except ValueError:
# No namespace part in the name. Therefore, use the user's personal
# namespace
if my_name:
namespace = my_name
shortname = value
else:
self.fail_json(
msg=(
"The `{param}' parameter must include the"
" organization: <organization>{sep}{name}."
).format(param=parameter_name, sep=separator, name=value)
)

# Check whether namespace exists (organization or user account)
namespace_details = self.get_namespace(namespace)
if not namespace_details:
if state == "absent":
self.exit_json(changed=False)
self.fail_json(
msg="The {namespace} namespace does not exist.".format(namespace=namespace)
)
# Make sure that the current user is the owner of that namespace
if (
not namespace_details.get("is_organization")
and namespace_details.get("name") != my_name
):
if my_name:
msg = "You ({user}) are not the owner of {namespace}'s namespace.".format(
user=my_name, namespace=namespace
)
else:
msg = "You cannot access {namespace}'s namespace.".format(namespace=namespace)
self.fail_json(msg=msg)

return (namespace, shortname, namespace_details.get("is_organization", False))

def get_tags(self, namespace, repository, tag=None, digest=None, only_active_tags=True):
"""Return the list of tags for the given repository.
Expand Down
40 changes: 1 addition & 39 deletions plugins/modules/quay_notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,45 +430,7 @@ def main():
vulnerability_level = module.params.get("vulnerability_level")
image_expiry_days = module.params.get("image_expiry_days")

# Extract namespace and repository from the repository parameter
my_name = module.who_am_i()
try:
namespace, repo_shortname = repository.split("/", 1)
except ValueError:
# No namespace part in the repository name. Therefore, the repository
# is in the user's personal namespace
if my_name:
namespace = my_name
repo_shortname = repository
else:
module.fail_json(
msg=(
"The `repository' parameter must include the"
" organization: <organization>/{name}."
).format(name=repository)
)

# Check whether namespace exists (organization or user account)
namespace_details = module.get_namespace(namespace)
if not namespace_details:
if state == "absent":
module.exit_json(changed=False)
module.fail_json(
msg="The {namespace} namespace does not exist.".format(namespace=namespace)
)
# Make sure that the current user is the owner of that namespace
if (
not namespace_details.get("is_organization")
and namespace_details.get("name") != my_name
):
if my_name:
msg = "You ({user}) are not the owner of {namespace}'s namespace.".format(
user=my_name, namespace=namespace
)
else:
msg = "You cannot access {namespace}'s namespace.".format(namespace=namespace)
module.fail_json(msg=msg)

namespace, repo_shortname, _not_used = module.split_name("repository", repository, state)
full_repo_name = "{namespace}/{repository}".format(
namespace=namespace, repository=repo_shortname
)
Expand Down
39 changes: 1 addition & 38 deletions plugins/modules/quay_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,44 +312,7 @@ def main():
)
auto_prune_value = value

my_name = module.who_am_i()
try:
namespace, repo_shortname = name.split("/", 1)
except ValueError:
# No namespace part in the repository name. Therefore, the repository
# is in the user's personal namespace
if my_name:
namespace = my_name
repo_shortname = name
else:
module.fail_json(
msg=(
"The `name' parameter must include the"
" organization: <organization>/{name}."
).format(name=name)
)

# Check whether namespace exists (organization or user account)
namespace_details = module.get_namespace(namespace)
if not namespace_details:
if state == "absent":
module.exit_json(changed=False)
module.fail_json(
msg="The {namespace} namespace does not exist.".format(namespace=namespace)
)
# Make sure that the current user is the owner of that namespace
if (
not namespace_details.get("is_organization")
and namespace_details.get("name") != my_name
):
if my_name:
msg = "You ({user}) are not the owner of {namespace}'s namespace.".format(
user=my_name, namespace=namespace
)
else:
msg = "You cannot access {namespace}'s namespace.".format(namespace=namespace)
module.fail_json(msg=msg)

namespace, repo_shortname, _not_used = module.split_name("name", name, state)
full_repo_name = "{namespace}/{repository}".format(
namespace=namespace, repository=repo_shortname
)
Expand Down
37 changes: 1 addition & 36 deletions plugins/modules/quay_repository_mirror.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,42 +227,7 @@ def main():
else 86400
)

my_name = module.who_am_i()
try:
namespace, repo_shortname = name.split("/", 1)
except ValueError:
# No namespace part in the repository name. Therefore, the repository
# is in the user's personal namespace
if my_name:
namespace = my_name
repo_shortname = name
else:
module.fail_json(
msg=(
"The `name' parameter must include the"
" organization: <organization>/{name}."
).format(name=name)
)

# Check whether namespace exists (organization or user account)
namespace_details = module.get_namespace(namespace)
if not namespace_details:
module.fail_json(
msg="The {namespace} namespace does not exist.".format(namespace=namespace)
)
# Make sure that the current user is the owner of that namespace
if (
not namespace_details.get("is_organization")
and namespace_details.get("name") != my_name
):
if my_name:
msg = "You ({user}) are not the owner of {namespace}'s namespace.".format(
user=my_name, namespace=namespace
)
else:
msg = "You cannot access {namespace}'s namespace.".format(namespace=namespace)
module.fail_json(msg=msg)

namespace, repo_shortname, _not_used = module.split_name("name", name, "present")
full_repo_name = "{namespace}/{repository}".format(
namespace=namespace, repository=repo_shortname
)
Expand Down
40 changes: 1 addition & 39 deletions plugins/modules/quay_repository_prune.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,45 +170,7 @@ def main():
# Convert the parameters to a dictionary that can be used with the API
data = module.process_prune_parameters(method, value, tag_pattern, tag_pattern_matches)

# Extract namespace and repository from the repository parameter
my_name = module.who_am_i()
try:
namespace, repo_shortname = repository.split("/", 1)
except ValueError:
# No namespace part in the repository name. Therefore, the repository
# is in the user's personal namespace
if my_name:
namespace = my_name
repo_shortname = repository
else:
module.fail_json(
msg=(
"The `repository' parameter must include the"
" organization: <organization>/{name}."
).format(name=repository)
)

# Check whether namespace exists (organization or user account)
namespace_details = module.get_namespace(namespace)
if not namespace_details:
if state == "absent":
module.exit_json(changed=False)
module.fail_json(
msg="The {namespace} namespace does not exist.".format(namespace=namespace)
)
# Make sure that the current user is the owner of that namespace
if (
not namespace_details.get("is_organization")
and namespace_details.get("name") != my_name
):
if my_name:
msg = "You ({user}) are not the owner of {namespace}'s namespace.".format(
user=my_name, namespace=namespace
)
else:
msg = "You cannot access {namespace}'s namespace.".format(namespace=namespace)
module.fail_json(msg=msg)

namespace, repo_shortname, _not_used = module.split_name("repository", repository, state)
full_repo_name = "{namespace}/{repository}".format(
namespace=namespace, repository=repo_shortname
)
Expand Down
40 changes: 2 additions & 38 deletions plugins/modules/quay_robot.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,46 +169,10 @@ def main():
description = module.params.get("description")
state = module.params.get("state")

my_name = module.who_am_i()
try:
namespace, robot_shortname = name.split("+", 1)
except ValueError:
# No namespace part in the robot account name. Therefore, the robot
# account is in the user's personal namespace
if my_name:
namespace = my_name
robot_shortname = name
else:
module.fail_json(
msg=(
"The `name' parameter must include the"
" organization: <organization>+{name}."
).format(name=name)
)

# Check whether namespace exists (organization or user account)
namespace_details = module.get_namespace(namespace)
if not namespace_details:
if state == "absent":
module.exit_json(changed=False)
module.fail_json(
msg="The {namespace} namespace does not exist.".format(namespace=namespace)
)
# Make sure that the current user is the owner of that namespace
if (
not namespace_details.get("is_organization")
and namespace_details.get("name") != my_name
):
if my_name:
msg = "You ({user}) are not the owner of {namespace}'s namespace.".format(
user=my_name, namespace=namespace
)
else:
msg = "You cannot access {namespace}'s namespace.".format(namespace=namespace)
module.fail_json(msg=msg)
namespace, robot_shortname, is_org = module.split_name("name", name, state, separator="+")

# Build the API URL to access the robot object.
if namespace_details.get("is_organization"):
if is_org:
path_url = "organization/{orgname}/robots/{robot_shortname}".format(
orgname=namespace, robot_shortname=robot_shortname
)
Expand Down
2 changes: 1 addition & 1 deletion roles/quay_org/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Example Playbook
quay_org_email: [email protected]
# Proxy cache
quay_org_cache_registry: quay.io/sclorg
quay_org_cache_expiration: 259200
quay_org_cache_expiration: 3d
# Quota
quay_org_quota: 1.5 TiB
quay_org_warning_pct: 90
Expand Down
5 changes: 4 additions & 1 deletion roles/quay_org/meta/argument_specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,11 @@ argument_specs:
quay_org_cache_expiration:
description:
- Tag expiration in seconds for cached images.
- The O(quay_org_cache_expiration) parameter accepts a time unit as a
suffix; C(s) for seconds, C(m) for minutes, C(h) for hours, C(d)
for days, and C(w) for weeks. For example, C(8h) for eight hours.
- 86400 (one day) by default.
type: int
type: str
default: 86400
quay_org_quota:
description:
Expand Down
2 changes: 1 addition & 1 deletion roles/quay_org/tests/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
quay_org_name: production
quay_org_email: [email protected]
quay_org_cache_registry: public.ecr.aws/nginx
quay_org_cache_expiration: 345600
quay_org_cache_expiration: 4d
quay_org_quota: 500 GiB
quay_org_warning_pct: 80
quay_org_reject_pct: 90
Expand Down
15 changes: 15 additions & 0 deletions tests/integration/targets/quay_repository/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@
that: result['failed']
fail_msg: The preceding task should have failed (not allowed)

- name: ERROR EXPECTED Nonexisting namespace
infra.quay_configuration.quay_repository:
name: doesnotexist/ansibletestrepo1
state: present
quay_host: "{{ quay_url }}"
quay_token: "{{ quay_token }}"
validate_certs: false
ignore_errors: true
register: result

- name: Ensure that the task failed
ansible.builtin.assert:
that: result['failed']
fail_msg: The preceding task should have failed (nonexisting namespace)

- name: Ensure repository ansibletestrepo1 exists
infra.quay_configuration.quay_repository:
name: ansibletestorg/ansibletestrepo1
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/targets/role_quay_org/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
quay_org_name: testorg
quay_org_email: [email protected]
quay_org_cache_registry: public.ecr.aws/nginx
quay_org_cache_expiration: 345600
quay_org_cache_expiration: 4d
quay_org_cache_insecure: true
quay_org_quota: 1.5 TiB
quay_org_warning_pct: 90
Expand Down

0 comments on commit ab65042

Please sign in to comment.