From 1e12f28b44fb3436cd8e4a19056a44fb5690d3d8 Mon Sep 17 00:00:00 2001 From: Matthias Dellweg Date: Tue, 21 May 2024 15:43:36 +0200 Subject: [PATCH] Add composite and header content guard commands fixes #969 --- CHANGES/969.feature | 1 + CHANGES/pulp-glue/969.feature | 1 + pulp-glue/pulp_glue/core/context.py | 40 ++++++++--- pulpcore/cli/common/generic.py | 5 +- pulpcore/cli/core/content_guard.py | 69 ++++++++++++++++++- tests/scripts/pulpcore/test_content_guards.sh | 37 +++++++--- 6 files changed, 129 insertions(+), 24 deletions(-) create mode 100644 CHANGES/969.feature create mode 100644 CHANGES/pulp-glue/969.feature diff --git a/CHANGES/969.feature b/CHANGES/969.feature new file mode 100644 index 000000000..bce48dac8 --- /dev/null +++ b/CHANGES/969.feature @@ -0,0 +1 @@ +Added commands for composite and header content guards. diff --git a/CHANGES/pulp-glue/969.feature b/CHANGES/pulp-glue/969.feature new file mode 100644 index 000000000..629804ddb --- /dev/null +++ b/CHANGES/pulp-glue/969.feature @@ -0,0 +1 @@ +Added contexts for composite and header content guards. diff --git a/pulp-glue/pulp_glue/core/context.py b/pulp-glue/pulp_glue/core/context.py index 38c4bbfcf..c0f710f80 100644 --- a/pulp-glue/pulp_glue/core/context.py +++ b/pulp-glue/pulp_glue/core/context.py @@ -262,16 +262,6 @@ def scope(self) -> t.Dict[str, t.Any]: return {self.group_ctx.HREF: self.group_ctx.pulp_href} -class PulpContentRedirectContentGuardContext(PulpContentGuardContext): - PLUGIN = "core" - RESOURCE_TYPE = "content_redirect" - ENTITY = "content redirect content guard" - ENTITIES = "content redirect content guards" - HREF = "content_redirect_content_guard_href" - ID_PREFIX = "contentguards_core_content_redirect" - NEEDS_PLUGINS = [PluginRequirement("core", specifier=">=3.18.0")] - - class PulpImporterContext(PulpEntityContext): ENTITY = _("Pulp importer") ENTITIES = _("Pulp importers") @@ -298,6 +288,36 @@ def cleanup(self, body: t.Optional[t.Dict[str, t.Any]] = None) -> t.Any: return result +class PulpCompositeContentGuardContext(PulpContentGuardContext): + PLUGIN = "core" + RESOURCE_TYPE = "composite" + ENTITY = "composite content guard" + ENTITIES = "composite content guards" + HREF = "composite_content_guard_href" + ID_PREFIX = "contentguards_core_composite" + NEEDS_PLUGINS = [PluginRequirement("core", specifier=">=3.43.0")] + + +class PulpContentRedirectContentGuardContext(PulpContentGuardContext): + PLUGIN = "core" + RESOURCE_TYPE = "content_redirect" + ENTITY = "content redirect content guard" + ENTITIES = "content redirect content guards" + HREF = "content_redirect_content_guard_href" + ID_PREFIX = "contentguards_core_content_redirect" + NEEDS_PLUGINS = [PluginRequirement("core", specifier=">=3.18.0")] + + +class PulpHeaderContentGuardContext(PulpContentGuardContext): + PLUGIN = "core" + RESOURCE_TYPE = "header" + ENTITY = "header content guard" + ENTITIES = "header content guards" + HREF = "header_content_guard_href" + ID_PREFIX = "contentguards_core_header" + NEEDS_PLUGINS = [PluginRequirement("core", specifier=">=3.39.0")] + + class PulpRbacContentGuardContext(PulpContentGuardContext): PLUGIN = "core" RESOURCE_TYPE = "rbac" diff --git a/pulpcore/cli/common/generic.py b/pulpcore/cli/common/generic.py index 90b1baabb..d24ab8410 100644 --- a/pulpcore/cli/common/generic.py +++ b/pulpcore/cli/common/generic.py @@ -838,7 +838,7 @@ def _multi_option_callback( ctx: click.Context, param: click.Parameter, value: t.Iterable[t.Optional[str]] ) -> t.Iterable[EntityFieldDefinition]: if value: - return (_option_callback(ctx, param, item) for item in value) + return [_option_callback(ctx, param, item) for item in value] return tuple() if "cls" not in kwargs: @@ -851,7 +851,7 @@ def _multi_option_callback( if "help" not in kwargs: kwargs["help"] = _( "Referenced resource, in the form {plugin_form}{type_form} or by href. " - "{plugin_default}{type_default}" + "{plugin_default}{type_default}{multiple_note}" ).format( plugin_form=_("[:]") if default_plugin else _(":"), type_form=_("[:]") if default_type else _(":"), @@ -865,6 +865,7 @@ def _multi_option_callback( if default_type else "" ), + multiple_note=(_("Can be specified multiple times.") if kwargs.get("multiple") else ""), ) return click.option(*args, **kwargs) diff --git a/pulpcore/cli/core/content_guard.py b/pulpcore/cli/core/content_guard.py index 652cd4238..208006231 100644 --- a/pulpcore/cli/core/content_guard.py +++ b/pulpcore/cli/core/content_guard.py @@ -5,7 +5,9 @@ from pulp_glue.common.context import PulpContentGuardContext, PulpEntityContext from pulp_glue.common.i18n import get_translation from pulp_glue.core.context import ( + PulpCompositeContentGuardContext, PulpContentRedirectContentGuardContext, + PulpHeaderContentGuardContext, PulpRbacContentGuardContext, ) @@ -20,6 +22,7 @@ pass_entity_context, pass_pulp_context, pulp_group, + resource_option, role_command, show_command, update_command, @@ -36,13 +39,73 @@ def content_guard(ctx: click.Context, pulp_ctx: PulpCLIContext) -> None: ctx.obj = PulpContentGuardContext(pulp_ctx) -common_create_options = [click.option("--name", required=True), click.option("--description")] +common_update_options = [ + click.option("--description"), +] +common_create_options = [ + click.option("--name", required=True), +] + common_update_options filter_options = [click.option("--name")] lookup_options = [name_option, href_option] content_guard.add_command(list_command(decorators=filter_options)) +@content_guard.group() +@pass_pulp_context +@click.pass_context +def composite(ctx: click.Context, pulp_ctx: PulpCLIContext) -> None: + ctx.obj = PulpCompositeContentGuardContext(pulp_ctx) + + +composite_options = [ + resource_option( + "--guard", + "guards", + context_table=PulpContentGuardContext.TYPE_REGISTRY, + default_plugin="core", + multiple=True, + ), +] + +composite.add_command(list_command(decorators=filter_options)) +composite.add_command(create_command(decorators=common_create_options + composite_options)) +composite.add_command(show_command(decorators=lookup_options)) +composite.add_command( + update_command(decorators=lookup_options + common_update_options + composite_options) +) +composite.add_command(destroy_command(decorators=lookup_options)) +composite.add_command(role_command(decorators=lookup_options)) + + +@content_guard.group() +@pass_pulp_context +@click.pass_context +def header(ctx: click.Context, pulp_ctx: PulpCLIContext) -> None: + ctx.obj = PulpHeaderContentGuardContext(pulp_ctx) + + +header_create_options = [ + click.option("--header-name", required=True), + click.option("--header-value", required=True), + click.option("--jq-filter"), +] +header_update_options = [ + click.option("--header-name"), + click.option("--header-value"), + click.option("--jq-filter"), +] + +header.add_command(list_command(decorators=filter_options)) +header.add_command(create_command(decorators=common_create_options + header_create_options)) +header.add_command(show_command(decorators=lookup_options)) +header.add_command( + update_command(decorators=lookup_options + common_update_options + header_update_options) +) +header.add_command(destroy_command(decorators=lookup_options)) +header.add_command(role_command(decorators=lookup_options)) + + @content_guard.group() @pass_pulp_context @click.pass_context @@ -53,7 +116,7 @@ def rbac(ctx: click.Context, pulp_ctx: PulpCLIContext) -> None: rbac.add_command(list_command(decorators=filter_options)) rbac.add_command(create_command(decorators=common_create_options)) rbac.add_command(show_command(decorators=lookup_options)) -rbac.add_command(update_command(decorators=lookup_options)) +rbac.add_command(update_command(decorators=lookup_options + common_update_options)) rbac.add_command(destroy_command(decorators=lookup_options)) rbac.add_command(role_command(decorators=lookup_options)) @@ -126,7 +189,7 @@ def redirect(ctx: click.Context, pulp_ctx: PulpCLIContext) -> None: redirect.add_command(list_command(decorators=filter_options)) redirect.add_command(create_command(decorators=common_create_options)) redirect.add_command(show_command(decorators=lookup_options)) -redirect.add_command(update_command(decorators=lookup_options)) +redirect.add_command(update_command(decorators=lookup_options + common_update_options)) redirect.add_command(destroy_command(decorators=lookup_options)) redirect.add_command(role_command(decorators=lookup_options)) diff --git a/tests/scripts/pulpcore/test_content_guards.sh b/tests/scripts/pulpcore/test_content_guards.sh index 970ce2191..f290317b6 100755 --- a/tests/scripts/pulpcore/test_content_guards.sh +++ b/tests/scripts/pulpcore/test_content_guards.sh @@ -4,25 +4,44 @@ . "$(dirname "$(dirname "$(realpath "$0")")")"/config.source cleanup() { - pulp content-guard rbac destroy --name "cli_test_guard" || true + pulp content-guard composite destroy --name "cli_test_composite_guard" || true + pulp content-guard header destroy --name "cli_test_header_guard" || true + pulp content-guard rbac destroy --name "cli_test_rbac_guard" || true pulp group destroy --name "cli_test_group" || true } trap cleanup EXIT -expect_succ pulp content-guard rbac create --name "cli_test_guard" +expect_succ pulp content-guard rbac create --name "cli_test_rbac_guard" expect_succ pulp content-guard list test "$(echo "$OUTPUT" | jq -r length)" -gt "0" -expect_succ pulp content-guard rbac list --name "cli_test_guard" +expect_succ pulp content-guard rbac list --name "cli_test_rbac_guard" test "$(echo "$OUTPUT" | jq -r length)" -eq "1" -expect_succ pulp content-guard rbac show --name "cli_test_guard" +expect_succ pulp content-guard rbac show --name "cli_test_rbac_guard" expect_succ pulp group create --name "cli_test_group" -expect_succ pulp content-guard rbac assign --name "cli_test_guard" --group "cli_test_group" -expect_succ pulp content-guard rbac show --name "cli_test_guard" +expect_succ pulp content-guard rbac assign --name "cli_test_rbac_guard" --group "cli_test_group" +expect_succ pulp content-guard rbac show --name "cli_test_rbac_guard" test "$(echo "$OUTPUT" | jq -r '.groups' | jq -r length)" -eq "1" -expect_succ pulp content-guard rbac remove --name "cli_test_guard" --user "admin" --group "cli_test_group" -expect_succ pulp content-guard rbac show --name "cli_test_guard" +expect_succ pulp content-guard rbac remove --name "cli_test_rbac_guard" --user "admin" --group "cli_test_group" +expect_succ pulp content-guard rbac show --name "cli_test_rbac_guard" test "$(echo "$OUTPUT" | jq -r '.users' | jq -r length)" -eq "0" test "$(echo "$OUTPUT" | jq -r '.groups' | jq -r length)" -eq "0" -expect_succ pulp content-guard rbac destroy --name "cli_test_guard" +if pulp debug has-plugin --name "core" --specifier ">=3.39.0" +then + # Header content guard + expect_succ pulp content-guard header create --name "cli_test_header_guard" --header-name "to" --header-value "ken" + if pulp debug has-plugin --name "core" --specifier ">=3.43.0" + then + # Composite content guard + expect_succ pulp content-guard composite create --name "cli_test_composite_guard" --guard "rbac:cli_test_rbac_guard" --guard "header:cli_test_header_guard" + test "$(echo "$OUTPUT" | jq -r '.guards' | jq -r length)" -eq "2" + expect_succ pulp content-guard composite update --name "cli_test_composite_guard" --guard "rbac:cli_test_rbac_guard" --description "Updated composite guard" + expect_succ pulp content-guard composite show --name "cli_test_composite_guard" + test "$(echo "$OUTPUT" | jq -r '.guards' | jq -r length)" -eq "1" + expect_succ pulp content-guard composite destroy --name "cli_test_composite_guard" + fi + expect_succ pulp content-guard header destroy --name "cli_test_header_guard" +fi + +expect_succ pulp content-guard rbac destroy --name "cli_test_rbac_guard"