Skip to content

Commit

Permalink
Add the groups endpoint (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
ekouts authored Mar 1, 2024
1 parent 95dbf08 commit f1644d9
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 1 deletion.
16 changes: 16 additions & 0 deletions firecrest/AsyncClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,22 @@ async def whoami(self, machine=None) -> Optional[str]:
# Invalid token, cannot retrieve username
return None

async def groups(self, machine) -> t.UserId:
"""Returns the output of the `id` command, user and group ids.
:calls: GET `/utilities/whoami`
.. warning:: This is available only for FirecREST>=1.15.0
"""
resp = await self._get_request(
endpoint="/utilities/whoami",
additional_headers={"X-Machine-Name": machine},
params={
"groups": True
}
)
return self._json_response([resp], 200)["output"]

# Compute
async def submit(
self,
Expand Down
16 changes: 16 additions & 0 deletions firecrest/BasicClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,22 @@ def whoami(self, machine=None) -> Optional[str]:
# Invalid token, cannot retrieve username
return None

def groups(self, machine) -> t.UserId:
"""Returns the output of the `id` command, user and group ids.
:calls: GET `/utilities/whoami`
.. warning:: This is available only for FirecREST>=1.15.0
"""
resp = self._get_request(
endpoint="/utilities/whoami",
additional_headers={"X-Machine-Name": machine},
params={
"groups": True
}
)
return self._json_response([resp], 200)["output"]

# Compute
def _submit_request(self, machine: str, job_script, local_file, account=None, env_vars=None):
data = {}
Expand Down
28 changes: 28 additions & 0 deletions firecrest/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,34 @@ def whoami(
raise typer.Exit(code=1)


@app.command(rich_help_panel="Utilities commands")
def id(
config_from_parent: str = typer.Option(None,
callback=config_parent_load_callback,
is_eager=True,
hidden=True
),
system: str = typer.Option(
None,
"-s",
"--system",
help="The name of the system where the `id` command will run.",
envvar="FIRECREST_SYSTEM",
),
):
"""Return the identity of the user in the remote system.
"""
try:
result = client.groups(system)
user = f"{result['user']['id']}({result['user']['name']})"
group = f"{result['group']['id']}({result['group']['name']})"
all_groups = ",".join([f"{g['id']}({g['name']})" for g in result["groups"]])
console.print(f"uid={user} gid={group} groups={all_groups}")
except Exception as e:
examine_exeption(e)
raise typer.Exit(code=1)


class TransferType(str, Enum):
direct = "direct"
external = "external"
Expand Down
13 changes: 13 additions & 0 deletions firecrest/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,16 @@ class JobSubmit(TypedDict):
job_file_out: str
jobid: int
result: str


class Id(TypedDict):
name: str
id: str


class UserId(TypedDict):
"""A record from the `id` command"""

user: Id
group: Id
groups: list[Id]
49 changes: 48 additions & 1 deletion tests/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,8 +730,21 @@ def whoami_handler(request: Request):
content_type="application/json",
)

groups = request.args.get("groups", False)
if groups:
ret = {
"description": "User information",
"output": {
"group": {"id": "1000", "name": "group1"},
"groups": [{"id": "1000", "name": "group1"}, {"id": "1001", "name": "group2"}],
"user": {"id": "10000", "name": "test_user"},
}
}
else:
ret = {"description": "Success on whoami operation.", "output": "username"}

return Response(
json.dumps({"description": "Success on whoami operation.", "output": "username"}),
json.dumps(ret),
status=200,
content_type="application/json",
)
Expand Down Expand Up @@ -1510,3 +1523,37 @@ def test_whoami_invalid_machine(valid_client):
def test_whoami_invalid_client(invalid_client):
with pytest.raises(firecrest.UnauthorizedException):
invalid_client.whoami("cluster1")


def test_cli_whoami(valid_credentials):
args = valid_credentials + ["whoami", "--system", "cluster1"]
result = runner.invoke(cli.app, args=args)
stdout = common.clean_stdout(result.stdout)
assert result.exit_code == 0
assert "username" in stdout


def test_groups(valid_client):
assert valid_client.groups("cluster1") == {
"group": {"id": "1000", "name": "group1"},
"groups": [{"id": "1000", "name": "group1"}, {"id": "1001", "name": "group2"}],
"user": {"id": "10000", "name": "test_user"},
}


def test_groups_invalid_machine(valid_client):
with pytest.raises(firecrest.HeaderException):
valid_client.groups("cluster2")


def test_groups_invalid_client(invalid_client):
with pytest.raises(firecrest.UnauthorizedException):
invalid_client.groups("cluster1")


def test_cli_id(valid_credentials):
args = valid_credentials + ["id", "--system", "cluster1"]
result = runner.invoke(cli.app, args=args)
stdout = common.clean_stdout(result.stdout)
assert result.exit_code == 0
assert "uid=10000(test_user) gid=1000(group1) groups=1000(group1),1001(group2)" in stdout
22 changes: 22 additions & 0 deletions tests/test_utilities_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -651,3 +651,25 @@ async def test_whoami_invalid_machine(valid_client):
async def test_whoami_invalid_client(invalid_client):
with pytest.raises(firecrest.UnauthorizedException):
await invalid_client.whoami("cluster1")


@pytest.mark.asyncio
async def test_groups(valid_client):
assert await valid_client.groups("cluster1") == {
"group": {"id": "1000", "name": "group1"},
"groups": [{"id": "1000", "name": "group1"}, {"id": "1001", "name": "group2"}],
"user": {"id": "10000", "name": "test_user"},
}


@pytest.mark.asyncio
async def test_groups_invalid_machine(valid_client):
with pytest.raises(firecrest.HeaderException):
await valid_client.groups("cluster2")


@pytest.mark.asyncio
async def test_groups_invalid_client(invalid_client):
with pytest.raises(firecrest.UnauthorizedException):
await invalid_client.groups("cluster1")

0 comments on commit f1644d9

Please sign in to comment.