diff --git a/CHANGES/382.feature b/CHANGES/382.feature new file mode 100644 index 000000000..02680f2c6 --- /dev/null +++ b/CHANGES/382.feature @@ -0,0 +1,2 @@ +Added commands to manage roles and their association with users and groups. +Added commands to add and remove users. diff --git a/pulpcore/cli/common/generic.py b/pulpcore/cli/common/generic.py index 8a87cd781..bba68793e 100644 --- a/pulpcore/cli/common/generic.py +++ b/pulpcore/cli/common/generic.py @@ -1,6 +1,7 @@ import gettext import json import re +from functools import lru_cache from typing import Any, Callable, Dict, Iterable, List, Mapping, Optional, Tuple, Type, TypeVar import click @@ -34,11 +35,21 @@ def __init__( self, *args: Any, allowed_with_contexts: Optional[Tuple[Type[PulpEntityContext]]] = None, + needs_plugins: Optional[List[PluginRequirement]] = None, **kwargs: Any, ): self.allowed_with_contexts = allowed_with_contexts + self.needs_plugins = needs_plugins super().__init__(*args, **kwargs) + def invoke(self, ctx: click.Context) -> Any: + if self.needs_plugins: + pulp_ctx = ctx.find_object(PulpContext) + assert pulp_ctx is not None + for plugin_requirement in self.needs_plugins: + pulp_ctx.needs_plugin(plugin_requirement) + return super().invoke(ctx) + def get_short_help_str(self, limit: int = 45) -> str: return self.short_help or "" @@ -178,23 +189,31 @@ def handle_parse_result( # Option callbacks -def _href_callback( - ctx: click.Context, param: click.Parameter, value: Optional[str] -) -> Optional[str]: - if value is not None: - entity_ctx = ctx.find_object(PulpEntityContext) - assert entity_ctx is not None - entity_ctx.pulp_href = value - return value +@lru_cache(typed=True) +def lookup_callback( + attribute: str, context_class: Type[PulpEntityContext] = PulpEntityContext +) -> Callable[[click.Context, click.Parameter, Optional[str]], Optional[str]]: + def _callback( + ctx: click.Context, param: click.Parameter, value: Optional[str] + ) -> Optional[str]: + if value is not None: + if value == "": + value = "null" + entity_ctx = ctx.find_object(context_class) + assert entity_ctx is not None + entity_ctx.entity = {attribute: value} + return value + + return _callback -def _name_callback( +def _href_callback( ctx: click.Context, param: click.Parameter, value: Optional[str] ) -> Optional[str]: if value is not None: entity_ctx = ctx.find_object(PulpEntityContext) assert entity_ctx is not None - entity_ctx.entity = {"name": value} + entity_ctx.pulp_href = value return value @@ -208,16 +227,6 @@ def _repository_href_callback( return value -def _repository_callback( - ctx: click.Context, param: click.Parameter, value: Optional[str] -) -> Optional[str]: - if value is not None: - repository_ctx = ctx.find_object(PulpRepositoryContext) - assert repository_ctx is not None - repository_ctx.entity = {"name": value} - return value - - def _version_callback( ctx: click.Context, param: click.Parameter, value: Optional[int] ) -> Optional[int]: @@ -320,6 +329,14 @@ def parse_size_callback(ctx: click.Context, param: click.Parameter, value: str) return int(float(number) * units[unit]) +def null_callback( + ctx: click.Context, param: click.Parameter, value: Optional[str] +) -> Optional[str]: + if value == "": + return "null" + return value + + ############################################################################## # Decorator common options @@ -486,7 +503,7 @@ def _type_callback(ctx: click.Context, param: click.Parameter, value: Optional[s name_option = pulp_option( "--name", help=_("Name of the {entity}"), - callback=_name_callback, + callback=lookup_callback("name"), expose_value=False, ) @@ -500,7 +517,7 @@ def _type_callback(ctx: click.Context, param: click.Parameter, value: Optional[s repository_option = click.option( "--repository", help=_("Name of the repository"), - callback=_repository_callback, + callback=lookup_callback("name", PulpRepositoryContext), expose_value=False, ) diff --git a/pulpcore/cli/common/openapi.py b/pulpcore/cli/common/openapi.py index 2c35fd900..c9caed83f 100644 --- a/pulpcore/cli/common/openapi.py +++ b/pulpcore/cli/common/openapi.py @@ -265,7 +265,7 @@ def call( self.debug_callback(1, f"{method} {request.url}") for key, value in request.headers.items(): self.debug_callback(2, f" {key}: {value}") - if request.body: + if request.body is not None: self.debug_callback(2, f"{request.body!r}") if self.safe_calls_only and method.upper() not in SAFE_METHODS: raise OpenAPIError(_("Call aborted due to safe mode")) diff --git a/pulpcore/cli/container/distribution.py b/pulpcore/cli/container/distribution.py index 515c63ed6..11ee5ad90 100644 --- a/pulpcore/cli/container/distribution.py +++ b/pulpcore/cli/container/distribution.py @@ -69,6 +69,7 @@ def distribution(ctx: click.Context, pulp_ctx: PulpContext, distribution_type: s click.option( "--version", type=int, help=_("a repository version number, leave blank for latest") ), + click.option("--private/--public", default=None), ] distribution.add_command(list_command(decorators=filter_options)) @@ -84,6 +85,7 @@ def distribution(ctx: click.Context, pulp_ctx: PulpContext, distribution_type: s @click.option("--base-path") @repository_option @click.option("--version", type=int, help=_("a repository version number, leave blank for latest")) +@click.option("--private/--public", default=None) @pass_entity_context @pass_pulp_context def update( diff --git a/pulpcore/cli/core/__init__.py b/pulpcore/cli/core/__init__.py index e8ae21040..a8e51b88e 100644 --- a/pulpcore/cli/core/__init__.py +++ b/pulpcore/cli/core/__init__.py @@ -12,6 +12,7 @@ from pulpcore.cli.core.orphan import orphan from pulpcore.cli.core.orphans import orphans from pulpcore.cli.core.repository import repository +from pulpcore.cli.core.role import role from pulpcore.cli.core.show import show from pulpcore.cli.core.signing_service import signing_service from pulpcore.cli.core.status import status @@ -34,6 +35,7 @@ main.add_command(orphan) main.add_command(orphans) # This one is deprecated main.add_command(repository) +main.add_command(role) main.add_command(show) main.add_command(signing_service) main.add_command(status) diff --git a/pulpcore/cli/core/context.py b/pulpcore/cli/core/context.py index 2d79521f8..a6909baf0 100644 --- a/pulpcore/cli/core/context.py +++ b/pulpcore/cli/core/context.py @@ -198,6 +198,26 @@ def HREF(self) -> str: # type:ignore return "groups_object_permission_href" +class PulpGroupRoleContext(PulpEntityContext): + ENTITY = _("group role") + ENTITIES = _("group roles") + HREF = "auth_groups_group_role_href" + LIST_ID = "groups_roles_list" + READ_ID = "groups_roles_read" + CREATE_ID = "groups_roles_create" + DELETE_ID = "groups_roles_delete" + NULLABLES = {"content_object"} + group_ctx: PulpGroupContext + + def __init__(self, pulp_ctx: PulpContext, group_ctx: PulpGroupContext) -> None: + super().__init__(pulp_ctx) + self.group_ctx = group_ctx + + @property + def scope(self) -> Dict[str, Any]: + return {self.group_ctx.HREF: self.group_ctx.pulp_href} + + class PulpGroupUserContext(PulpEntityContext): ENTITY = _("group user") ENTITIES = _("group users") @@ -262,6 +282,18 @@ def remove(self, href: str, users: Optional[List[str]], groups: Optional[List[st return self.pulp_ctx.call(self.REMOVE_ID, parameters={self.HREF: href}, body=body) +class PulpRoleContext(PulpEntityContext): + ENTITY = _("role") + ENTITIES = _("roles") + HREF = "role_href" + LIST_ID = "roles_list" + READ_ID = "roles_read" + CREATE_ID = "roles_create" + UPDATE_ID = "roles_partial_update" + DELETE_ID = "roles_delete" + NULLABLES = {"description"} + + class PulpSigningServiceContext(PulpEntityContext): ENTITY = _("signing service") ENTITIES = _("signing services") @@ -329,6 +361,30 @@ class PulpUserContext(PulpEntityContext): HREF = "auth_user_href" LIST_ID = "users_list" READ_ID = "users_read" + CREATE_ID = "users_create" + UPDATE_ID = "users_partial_update" + DELETE_ID = "users_delete" + NULLABLES = {"password"} + + +class PulpUserRoleContext(PulpEntityContext): + ENTITY = _("user role") + ENTITIES = _("user roles") + HREF = "auth_users_user_role_href" + LIST_ID = "users_roles_list" + READ_ID = "users_roles_read" + CREATE_ID = "users_roles_create" + DELETE_ID = "users_roles_delete" + NULLABLES = {"content_object"} + user_ctx: PulpUserContext + + def __init__(self, pulp_ctx: PulpContext, user_ctx: PulpUserContext) -> None: + super().__init__(pulp_ctx) + self.user_ctx = user_ctx + + @property + def scope(self) -> Dict[str, Any]: + return {self.user_ctx.HREF: self.user_ctx.pulp_href} class PulpWorkerContext(PulpEntityContext): diff --git a/pulpcore/cli/core/group.py b/pulpcore/cli/core/group.py index 8c8fa5414..ba5db7030 100644 --- a/pulpcore/cli/core/group.py +++ b/pulpcore/cli/core/group.py @@ -3,13 +3,20 @@ import click -from pulpcore.cli.common.context import PulpContext, pass_entity_context, pass_pulp_context +from pulpcore.cli.common.context import ( + PluginRequirement, + PulpContext, + pass_entity_context, + pass_pulp_context, +) from pulpcore.cli.common.generic import ( create_command, destroy_command, href_option, list_command, + lookup_callback, name_option, + null_callback, show_command, ) from pulpcore.cli.core.context import ( @@ -17,25 +24,12 @@ PulpGroupModelPermissionContext, PulpGroupObjectPermissionContext, PulpGroupPermissionContext, + PulpGroupRoleContext, PulpGroupUserContext, PulpUserContext, ) - -def _groupname_callback(ctx: click.Context, param: click.Parameter, value: str) -> str: - if value is not None: - entity_ctx = ctx.find_object(PulpGroupContext) - assert entity_ctx is not None - entity_ctx.entity = {"name": value} - return value - - -def _permission_callback(ctx: click.Context, param: click.Parameter, value: str) -> str: - if value is not None: - entity_ctx = ctx.find_object(PulpGroupPermissionContext) - assert entity_ctx is not None - entity_ctx.entity = {"permission": value} - return value +_ = gettext.gettext def _object_callback(ctx: click.Context, param: click.Parameter, value: str) -> str: @@ -51,9 +45,9 @@ def _object_callback(ctx: click.Context, param: click.Parameter, value: str) -> return value -groupname_option = click.option("--groupname", callback=_groupname_callback, expose_value=False) - -_ = gettext.gettext +group_option = click.option( + "--group", callback=lookup_callback("name", PulpGroupContext), expose_value=False +) @click.group(help=_("Manage user groups and their granted permissions.")) @@ -99,13 +93,13 @@ def permission( permission.add_command( list_command( - help=_("Show a list of the permissioons granted to a group."), decorators=[groupname_option] + help=_("Show a list of the permissioons granted to a group."), decorators=[group_option] ) ) @permission.command(name="add", help=_("Grant a permission to the group.")) -@groupname_option +@group_option @click.option("--permission", required=True) @click.option("--object", "obj", callback=_object_callback) @pass_entity_context @@ -123,9 +117,12 @@ def add_permission( name="remove", help=_("Revoke a permission from the group."), decorators=[ - groupname_option, + group_option, click.option( - "--permission", required=True, callback=_permission_callback, expose_value=False + "--permission", + required=True, + callback=lookup_callback("permission", PulpGroupPermissionContext), + expose_value=False, ), click.option("--object", callback=_object_callback, expose_value=False), ], @@ -141,19 +138,15 @@ def user(ctx: click.Context, pulp_ctx: PulpContext, group_ctx: PulpGroupContext) ctx.obj = PulpGroupUserContext(pulp_ctx, group_ctx) -user.add_command(list_command(decorators=[groupname_option])) - - -@user.command(name="add") -@groupname_option -@click.option("--username", required=True) -@pass_entity_context -def add_user(entity_ctx: PulpGroupUserContext, username: str) -> None: - entity_ctx.create(body={"username": username}) +user.add_command(list_command(decorators=[group_option])) +user.add_command( + create_command(decorators=[group_option, click.option("--username", required=True)]), + name="add", +) @user.command(name="remove") -@groupname_option +@group_option @click.option("--username", required=True) @pass_entity_context @pass_pulp_context @@ -162,3 +155,58 @@ def remove_user(pulp_ctx: PulpContext, entity_ctx: PulpGroupUserContext, usernam user_pk = user_href.split("/")[-2] group_user_href = f"{entity_ctx.group_ctx.pulp_href}users/{user_pk}/" entity_ctx.delete(group_user_href) + + +@group.group() +@pass_entity_context +@pass_pulp_context +@click.pass_context +def role(ctx: click.Context, pulp_ctx: PulpContext, group_ctx: PulpGroupContext) -> None: + pulp_ctx.needs_plugin(PluginRequirement("core", min="3.17.dev")) + ctx.obj = PulpGroupRoleContext(pulp_ctx, group_ctx) + + +role.add_command( + list_command( + decorators=[ + group_option, + click.option("--role"), + click.option("--role-in", "role__in"), + click.option("--role-contains", "role__contains"), + click.option("--role-icontains", "role__icontains"), + click.option("--role-startswith", "role__startswith"), + click.option("--object", "content_object", callback=null_callback), + ] + ) +) +role.add_command( + create_command( + decorators=[ + group_option, + click.option("--role", required=True), + click.option("--object", "content_object", required=True), + ] + ), + name="assign", +) +role.add_command( + destroy_command( + decorators=[ + group_option, + click.option( + "--role", + required=True, + callback=lookup_callback("role", PulpGroupRoleContext), + expose_value=False, + ), + click.option( + "--object", + "content_object", + required=True, + callback=lookup_callback("content_object", PulpGroupRoleContext), + expose_value=False, + ), + ] + ), + name="remove", +) diff --git a/pulpcore/cli/core/role.py b/pulpcore/cli/core/role.py new file mode 100644 index 000000000..2b9166923 --- /dev/null +++ b/pulpcore/cli/core/role.py @@ -0,0 +1,80 @@ +import gettext +from typing import Iterable, Optional + +import click + +from pulpcore.cli.common.context import PluginRequirement, PulpContext, pass_pulp_context +from pulpcore.cli.common.generic import ( + create_command, + destroy_command, + href_option, + list_command, + name_option, + show_command, + update_command, +) +from pulpcore.cli.core.context import PulpRoleContext + +_ = gettext.gettext +NO_PERMISSION_KEY = "pulpcore.cli.core.role.no_permission" + + +def _no_permission_callback(ctx: click.Context, param: click.Parameter, value: bool) -> bool: + ctx.meta[NO_PERMISSION_KEY] = value + return value + + +def _permission_callback( + ctx: click.Context, param: click.Parameter, value: Iterable[str] +) -> Optional[Iterable[str]]: + if ctx.meta.get(NO_PERMISSION_KEY, False): + if value: + raise click.ClickException(_("Cannot specify `--permission` and `--no-permission`.")) + return [] + return value or None + + +filters = [ + click.option("--locked/--unlocked", default=None), + click.option("--name"), + click.option("--name-in", "name__in"), + click.option("--name-contains", "name__contains"), + click.option("--name-icontains", "name__icontains"), + click.option("--name-startswith", "name__startswith"), +] +lookup_options = [href_option, name_option] +update_options = [ + click.option("--description"), + click.option( + "--no-permission", + is_eager=True, + is_flag=True, + expose_value=False, + callback=_no_permission_callback, + ), + click.option( + "--permission", + "permissions", + multiple=True, + help=_("Permission in the form '.'. Can be used multiple times."), + callback=_permission_callback, + ), +] +create_options = [ + click.option("--name", required=True, help=_("Name of the role")), +] + update_options + + +@click.group() +@pass_pulp_context +@click.pass_context +def role(ctx: click.Context, pulp_ctx: PulpContext) -> None: + pulp_ctx.needs_plugin(PluginRequirement("core", min="3.17.dev")) + ctx.obj = PulpRoleContext(pulp_ctx) + + +role.add_command(list_command(decorators=filters)) +role.add_command(show_command(decorators=lookup_options)) +role.add_command(create_command(decorators=create_options)) +role.add_command(update_command(decorators=lookup_options + update_options)) +role.add_command(destroy_command(decorators=lookup_options)) diff --git a/pulpcore/cli/core/user.py b/pulpcore/cli/core/user.py index 18cad001f..4fe5fd309 100644 --- a/pulpcore/cli/core/user.py +++ b/pulpcore/cli/core/user.py @@ -2,18 +2,56 @@ import click -from pulpcore.cli.common.context import ( +from pulpcore.cli.common.context import ( # PulpEntityContext,; pass_entity_context, + PluginRequirement, PulpContext, - PulpEntityContext, pass_entity_context, pass_pulp_context, ) -from pulpcore.cli.common.generic import list_command -from pulpcore.cli.core.context import PulpUserContext +from pulpcore.cli.common.generic import ( + create_command, + destroy_command, + href_option, + list_command, + lookup_callback, + null_callback, + pulp_option, + show_command, + update_command, +) +from pulpcore.cli.core.context import PulpUserContext, PulpUserRoleContext _ = gettext.gettext +username_option = pulp_option( + "--username", + help=_("Username of the {entity}"), + expose_value=False, + callback=lookup_callback("username", PulpUserContext), +) +lookup_options = [ + href_option, + username_option, +] +update_options = [ + click.option( + "--password", + help=_( + "Password for the user. Provide an empty string to disable password authentication." + ), + ), + click.option("--first-name"), + click.option("--last-name"), + click.option("--email"), + click.option("--staff/--no-staff", "is_staff", default=None), + click.option("--active/--inactive", "is_active", default=None), +] +create_options = update_options + [ + click.option("--username", required=True), +] + + @click.group() @pass_pulp_context @click.pass_context @@ -22,14 +60,65 @@ def user(ctx: click.Context, pulp_ctx: PulpContext) -> None: user.add_command(list_command()) +user.add_command(show_command(decorators=lookup_options)) +needs_plugins = [PluginRequirement("core", min="3.17.dev")] +user.add_command(create_command(decorators=create_options, needs_plugins=needs_plugins)) +user.add_command( + update_command(decorators=lookup_options + update_options, needs_plugins=needs_plugins) +) +user.add_command(destroy_command(decorators=lookup_options, needs_plugins=needs_plugins)) -@user.command() -@click.option("--username", required=True, help=_("Username of the entry")) +@user.group() @pass_entity_context @pass_pulp_context -def show(pulp_ctx: PulpContext, entity_ctx: PulpEntityContext, username: str) -> None: - """Shows details of an entry""" - href = entity_ctx.find(username=username)["pulp_href"] - entity = entity_ctx.show(href) - pulp_ctx.output_result(entity) +@click.pass_context +def role(ctx: click.Context, pulp_ctx: PulpContext, user_ctx: PulpUserContext) -> None: + pulp_ctx.needs_plugin(PluginRequirement("core", min="3.17.dev")) + ctx.obj = PulpUserRoleContext(pulp_ctx, user_ctx) + + +role.add_command( + list_command( + decorators=[ + username_option, + click.option("--role"), + click.option("--role-in", "role__in"), + click.option("--role-contains", "role__contains"), + click.option("--role-icontains", "role__icontains"), + click.option("--role-startswith", "role__startswith"), + click.option("--object", "content_object", callback=null_callback), + ] + ) +) +role.add_command( + create_command( + decorators=[ + username_option, + click.option("--role", required=True), + click.option("--object", "content_object", required=True), + ] + ), + name="assign", +) +role.add_command( + destroy_command( + decorators=[ + username_option, + click.option( + "--role", + required=True, + callback=lookup_callback("role", PulpUserRoleContext), + expose_value=False, + ), + click.option( + "--object", + "content_object", + required=True, + callback=lookup_callback("content_object", PulpUserRoleContext), + expose_value=False, + ), + ] + ), + name="remove", +) diff --git a/tests/scripts/config.source b/tests/scripts/config.source index 0231eaf43..635663b3f 100644 --- a/tests/scripts/config.source +++ b/tests/scripts/config.source @@ -46,4 +46,36 @@ expect_fail () { fi } +# Expects the command to report access denied +# Supresses all output, which is redirected to $OUTPUT and $ERROUTPUT +# Reports verbosely on failure +expect_deny () { + if { + "$@" + } 1>log.out 2>log.err + # TODO check for access denied message + then + echo "FAILURE [! $@]" >&3 + echo "=== STDOUT ===" >&3 + cat log.out >&3 + echo "=== STDERR ===" >&3 + cat log.err >&3 + false + else + if grep -q "You do not have permission" log.err + then + echo "SUCCESS [! $@]" >&3 + OUTPUT="$(cat log.out)" + ERROUTPUT="$(cat log.err)" + else + echo "FAILURE [! $@]" >&3 + echo "=== STDOUT ===" >&3 + cat log.out >&3 + echo "=== STDERR ===" >&3 + cat log.err >&3 + false + fi + fi +} + set -eu diff --git a/tests/scripts/pulp_ansible/test_content.sh b/tests/scripts/pulp_ansible/test_content.sh index fe009950a..d8de4273d 100755 --- a/tests/scripts/pulp_ansible/test_content.sh +++ b/tests/scripts/pulp_ansible/test_content.sh @@ -44,7 +44,7 @@ expect_succ pulp ansible repository content add --repository "cli_test_ansible_r expect_succ pulp ansible repository content list --repository "cli_test_ansible_repository" --version 2 --type "role" test "$(echo "$OUTPUT" | jq -r length)" -eq "1" -if [ "$(pulp debug has-plugin --name "core" --min-version "3.11.0")" = "true" ] +if pulp debug has-plugin --name "core" --min-version "3.11.0" then expect_succ pulp ansible repository content list --repository "cli_test_ansible_repository" --version 2 --type "all" test "$(echo "$OUTPUT" | jq -r length)" -eq "2" diff --git a/tests/scripts/pulp_ansible/test_distribution.sh b/tests/scripts/pulp_ansible/test_distribution.sh index 3c48c00fd..73844786a 100755 --- a/tests/scripts/pulp_ansible/test_distribution.sh +++ b/tests/scripts/pulp_ansible/test_distribution.sh @@ -27,7 +27,7 @@ expect_succ pulp ansible distribution list expect_succ pulp ansible distribution show --name "cli_test_ansible_distro" expect_succ pulp ansible distribution update --name "cli_test_ansible_distro" --repository "" -if [ "$(pulp debug has-plugin --name "ansible" --min-version "0.8.0.dev")" = "true" ] +if pulp debug has-plugin --name "ansible" --min-version "0.8.0.dev" then expect_succ pulp ansible distribution label set --name "cli_test_ansible_distro" --key "test" --value "success" else diff --git a/tests/scripts/pulp_file/test_distribution.sh b/tests/scripts/pulp_file/test_distribution.sh index f8688aac9..79685f932 100755 --- a/tests/scripts/pulp_file/test_distribution.sh +++ b/tests/scripts/pulp_file/test_distribution.sh @@ -37,7 +37,7 @@ expect_succ pulp file distribution update \ --base-path "cli_test_file_distro" \ --publication "$PUBLICATION_HREF" -if [ "$(pulp debug has-plugin --name "file" --min-version "1.7.0.dev")" = "true" ] +if pulp debug has-plugin --name "file" --min-version "1.7.0.dev" then expect_succ pulp file distribution update \ --name "cli_test_file_distro" \ diff --git a/tests/scripts/pulp_file/test_repository.sh b/tests/scripts/pulp_file/test_repository.sh index 0200174bc..5edcee41a 100755 --- a/tests/scripts/pulp_file/test_repository.sh +++ b/tests/scripts/pulp_file/test_repository.sh @@ -40,7 +40,7 @@ test "$(echo "$OUTPUT" | jq -r '.|length')" != "0" expect_succ pulp file repository task list --repository "cli_test_file_repo" test "$(echo "$OUTPUT" | jq -r '.|length')" = "6" -if [ "$(pulp debug has-plugin --name "file" --min-version "1.7.0")" = "true" ] +if pulp debug has-plugin --name "file" --min-version "1.7.0" then expect_succ pulp file repository update --name "cli_test_file_repo" --manifest "manifest.csv" fi diff --git a/tests/scripts/pulp_file/test_sync.sh b/tests/scripts/pulp_file/test_sync.sh index 619929c4f..7b51cf362 100755 --- a/tests/scripts/pulp_file/test_sync.sh +++ b/tests/scripts/pulp_file/test_sync.sh @@ -49,7 +49,7 @@ test "$(echo "$OUTPUT" | jq -r '.state')" = "completed" expect_succ pulp file repository version destroy --repository "cli_test_file_repository" --version 1 # Test autopublish -if [ "$(pulp debug has-plugin --name "file" --min-version "1.7.0.dev")" = "true" ] +if pulp debug has-plugin --name "file" --min-version "1.7.0.dev" then expect_succ pulp file repository create --name "$autopublish_repo" --remote "cli_test_file_remote" --autopublish expect_succ pulp file repository sync --name "$autopublish_repo" @@ -59,7 +59,7 @@ then fi # Test retained versions -if [ "$(pulp debug has-plugin --name "core" --min-version "3.13.0.dev")" = "true" ] +if pulp debug has-plugin --name "core" --min-version "3.13.0.dev" then expect_succ pulp file repository create --name "$one_version_repo" --remote "cli_test_file_remote" --retain-repo-versions 1 expect_succ pulp file repository sync --name "$one_version_repo" diff --git a/tests/scripts/pulp_python/test_remote.sh b/tests/scripts/pulp_python/test_remote.sh index f096fe6e5..b8e7ef9a3 100755 --- a/tests/scripts/pulp_python/test_remote.sh +++ b/tests/scripts/pulp_python/test_remote.sh @@ -36,7 +36,7 @@ test "$(echo "$OUTPUT" | jq -r .includes[1])" = "shelf-reader" test "$(echo "$OUTPUT" | jq -r .includes[2])" = "pulp_python" expect_succ pulp python remote list -if [ "$(pulp debug has-plugin --name "python" --min-version "3.2.0.dev")" = "true" ] +if pulp debug has-plugin --name "python" --min-version "3.2.0.dev" then expect_succ pulp python remote create --name "cli_test_complex_remote" --url "$PYTHON_REMOTE_URL" --keep-latest-packages 3 --package-types '["sdist", "bdist_wheel"]' --exclude-platforms '["windows"]' else diff --git a/tests/scripts/pulpcore/test_group.sh b/tests/scripts/pulpcore/test_group.sh index d8f4e225e..1296a4aaa 100755 --- a/tests/scripts/pulpcore/test_group.sh +++ b/tests/scripts/pulpcore/test_group.sh @@ -13,8 +13,8 @@ expect_succ pulp group create --name "cli_test_group" expect_succ pulp group show --name "cli_test_group" expect_succ pulp group list -expect_succ pulp group user add --groupname "cli_test_group" --username "admin" -expect_succ pulp group user list --groupname "cli_test_group" -expect_succ pulp group user remove --groupname "cli_test_group" --username "admin" +expect_succ pulp group user add --group "cli_test_group" --username "admin" +expect_succ pulp group user list --group "cli_test_group" +expect_succ pulp group user remove --group "cli_test_group" --username "admin" expect_succ pulp group destroy --name "cli_test_group" diff --git a/tests/scripts/pulpcore/test_group_permissions.sh b/tests/scripts/pulpcore/test_group_permissions.sh index 5256f0049..9f5977a6a 100755 --- a/tests/scripts/pulpcore/test_group_permissions.sh +++ b/tests/scripts/pulpcore/test_group_permissions.sh @@ -13,13 +13,13 @@ trap cleanup EXIT expect_succ pulp group create --name "cli_test_group" -expect_succ pulp group permission add --groupname "cli_test_group" --permission "core.view_task" -expect_succ pulp group permission add --groupname "cli_test_group" --permission "auth.view_group" -expect_succ pulp group permission list --groupname "cli_test_group" -expect_succ pulp group permission remove --groupname "cli_test_group" --permission "core.view_task" +expect_succ pulp group permission add --group "cli_test_group" --permission "core.view_task" +expect_succ pulp group permission add --group "cli_test_group" --permission "auth.view_group" +expect_succ pulp group permission list --group "cli_test_group" +expect_succ pulp group permission remove --group "cli_test_group" --permission "core.view_task" expect_succ pulp file repository create --name "cli_group_test_repository" REPO_HREF="$(echo "$OUTPUT" | jq -r '.pulp_href')" -expect_succ pulp group permission -t object add --groupname "cli_test_group" --permission "file.view_filerepository" --object "$REPO_HREF" -expect_succ pulp group permission -t object list --groupname "cli_test_group" -expect_succ pulp group permission -t object remove --groupname "cli_test_group" --permission "file.view_filerepository" --object "$REPO_HREF" +expect_succ pulp group permission -t object add --group "cli_test_group" --permission "file.view_filerepository" --object "$REPO_HREF" +expect_succ pulp group permission -t object list --group "cli_test_group" +expect_succ pulp group permission -t object remove --group "cli_test_group" --permission "file.view_filerepository" --object "$REPO_HREF" diff --git a/tests/scripts/pulpcore/test_role.sh b/tests/scripts/pulpcore/test_role.sh new file mode 100755 index 000000000..3ff0b4b48 --- /dev/null +++ b/tests/scripts/pulpcore/test_role.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# shellcheck source=tests/scripts/config.source +. "$(dirname "$(dirname "$(realpath "$0")")")"/config.source + +pulp debug has-plugin --name "core" --min-version "3.17.0.dev" || exit 3 + +USERPASS="Yeech6ba" + +cleanup() { + pulp group destroy --name "clitest" || true + pulp user destroy --username "clitest" || true + pulp role destroy --name "clitest.group_viewer" || true +} +trap cleanup EXIT + +expect_succ pulp role list +expect_succ pulp role show --name "core.task_owner" + +expect_succ pulp role create --name "clitest.group_viewer" --permission "core.view_group" +expect_succ pulp role show --name "clitest.group_viewer" + +expect_succ pulp user create --username "clitest" --password "${USERPASS}" +expect_succ pulp group create --name "clitest" +GROUP_HREF=$(jq -r '.pulp_href' <<<"${OUTPUT}") +expect_succ pulp group user add --group "clitest" --username "clitest" + +expect_succ pulp --username clitest --password "${USERPASS}" task list +test "$(echo "${OUTPUT}" | jq -r 'length' )" = "0" + +expect_fail pulp -p user group show --name "clitest" + +expect_succ pulp user role assign --username "clitest" --role "clitest.group_viewer" --object "${GROUP_HREF}" +expect_succ pulp --username clitest --password "${USERPASS}" group show --name "clitest" +expect_succ pulp user role remove --username "clitest" --role "clitest.group_viewer" --object "${GROUP_HREF}" +expect_fail pulp --username clitest --password "${USERPASS}" group show --name "clitest" + +expect_succ pulp group role assign --group "clitest" --role "clitest.group_viewer" --object "${GROUP_HREF}" +expect_succ pulp --username clitest --password "${USERPASS}" group show --name "clitest" +expect_succ pulp group role remove --group "clitest" --role "clitest.group_viewer" --object "${GROUP_HREF}" +expect_fail pulp --username clitest --password "${USERPASS}" group show --name "clitest" + +expect_succ pulp role destroy --name "clitest.group_viewer" diff --git a/tests/scripts/pulpcore/test_user.sh b/tests/scripts/pulpcore/test_user.sh new file mode 100755 index 000000000..9f962dd2d --- /dev/null +++ b/tests/scripts/pulpcore/test_user.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# shellcheck source=tests/scripts/config.source +. "$(dirname "$(dirname "$(realpath "$0")")")"/config.source + +cleanup() { + pulp user destroy --username "clitest" || true +} +trap cleanup EXIT + +expect_succ pulp user list +if pulp debug has-plugin --name "core" --min-version "3.17.0.dev" +then + expect_succ pulp user show --username admin + expect_succ pulp user create --username "clitest" --password "Yeech6ba" + expect_succ pulp user update --username "clitest" --first-name "cli" --last-name "test" +fi