Skip to content

Commit

Permalink
Add commands to manage roles
Browse files Browse the repository at this point in the history
[noissue]
  • Loading branch information
mdellweg committed Dec 8, 2021
1 parent 4add01e commit 3a0738d
Show file tree
Hide file tree
Showing 20 changed files with 472 additions and 84 deletions.
2 changes: 2 additions & 0 deletions CHANGES/382.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Added commands to manage roles and their association with users and groups.
Added commands to add and remove users.
61 changes: 39 additions & 22 deletions pulpcore/cli/common/generic.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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 ""

Expand Down Expand Up @@ -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


Expand All @@ -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]:
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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,
)

Expand All @@ -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,
)

Expand Down
2 changes: 1 addition & 1 deletion pulpcore/cli/common/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand Down
2 changes: 2 additions & 0 deletions pulpcore/cli/container/distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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(
Expand Down
2 changes: 2 additions & 0 deletions pulpcore/cli/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
56 changes: 56 additions & 0 deletions pulpcore/cli/core/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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):
Expand Down
Loading

0 comments on commit 3a0738d

Please sign in to comment.