Skip to content

Commit 756cad2

Browse files
committed
services/kill.py: Allow admins to kill any run
Signed-off-by: Vallari Agrawal <val.agl002@gmail.com>
1 parent f0a9d59 commit 756cad2

File tree

4 files changed

+49
-17
lines changed

4 files changed

+49
-17
lines changed

.env.dev

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ GH_CLIENT_SECRET=
88
GH_AUTHORIZATION_BASE_URL='https://github.com/login/oauth/authorize'
99
GH_TOKEN_URL='https://github.com/login/oauth/access_token'
1010
GH_FETCH_MEMBERSHIP_URL='https://api.github.com/user/memberships/orgs/ceph'
11+
ADMIN_TEAM='Ceph'
1112

1213
#Session Related Stuff
1314
## SESSION_SECRET_KEY is used to encrypt session data

src/teuthology_api/config.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ class APISettings(BaseSettings):
2727
model_config = SettingsConfigDict(
2828
env_file=".env", env_file_encoding="utf-8", extra="ignore"
2929
)
30-
# TODO: team names need to be changed below when created
31-
admin_team: str = "ceph" # ceph's github team with *sudo* access to sepia
32-
teuth_team: str = "teuth" # ceph's github team with access to sepia
30+
admin_team: str = "Ceph" # ceph's github team with *sudo* access to sepia
3331

3432

3533
@lru_cache()

src/teuthology_api/routes/kill.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22

3-
from fastapi import APIRouter, Depends, Request
3+
from fastapi import APIRouter, Depends, Request, HTTPException
4+
from requests.exceptions import HTTPError
45

56
from teuthology_api.services.kill import run
67
from teuthology_api.services.helpers import get_token
@@ -15,7 +16,7 @@
1516

1617

1718
@router.post("/", status_code=200)
18-
def create_run(
19+
async def create_run(
1920
request: Request,
2021
args: KillArgs,
2122
logs: bool = False,
@@ -28,5 +29,16 @@ def create_run(
2829
or else it will SyntaxError: non-dafault
2930
argument follows default argument error.
3031
"""
31-
args = args.model_dump(by_alias=True, exclude_unset=True)
32-
return run(args, logs, access_token, request)
32+
try:
33+
args = args.model_dump(by_alias=True, exclude_unset=True)
34+
return await run(args, logs, access_token, request)
35+
except HTTPException:
36+
raise
37+
except HTTPError as http_err:
38+
log.error(http_err)
39+
raise HTTPException(
40+
status_code=http_err.response.status_code, detail=repr(http_err)
41+
) from http_err
42+
except Exception as err:
43+
log.error(err)
44+
raise HTTPException(status_code=500, detail=repr(err)) from err

src/teuthology_api/services/kill.py

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import subprocess
3+
import httpx
34

45
from fastapi import HTTPException, Request
56

@@ -8,10 +9,11 @@
89

910

1011
TEUTHOLOGY_PATH = settings.teuthology_path
12+
ADMIN_TEAM = settings.admin_team
1113
log = logging.getLogger(__name__)
1214

1315

14-
def run(args, send_logs: bool, access_token: str, request: Request):
16+
async def run(args, send_logs: bool, access_token: dict, request: Request):
1517
"""
1618
Kill running teuthology jobs.
1719
"""
@@ -30,16 +32,19 @@ def run(args, send_logs: bool, access_token: str, request: Request):
3032
else:
3133
log.error("teuthology-kill is missing --run")
3234
raise HTTPException(status_code=400, detail="--run is a required argument")
33-
# TODO if user has admin priviledge, then they can kill any run/job.
35+
3436
if run_owner.lower() != username.lower():
35-
log.error(
36-
"%s doesn't have permission to kill a job scheduled by: %s",
37-
username,
38-
run_owner,
39-
)
40-
raise HTTPException(
41-
status_code=401, detail="You don't have permission to kill this run/job"
42-
)
37+
isUserAdmin = await isAdmin(username, access_token)
38+
if not isUserAdmin:
39+
log.error(
40+
"%s doesn't have permission to kill a job scheduled by: %s",
41+
username,
42+
run_owner,
43+
)
44+
raise HTTPException(
45+
status_code=401, detail="You don't have permission to kill this run/job"
46+
)
47+
log.info("Killing with admin privileges")
4348
try:
4449
kill_cmd = [f"{TEUTHOLOGY_PATH}/virtualenv/bin/teuthology-kill"]
4550
for flag, flag_value in args.items():
@@ -61,3 +66,19 @@ def run(args, send_logs: bool, access_token: str, request: Request):
6166
except Exception as exc:
6267
log.error("teuthology-kill command failed with the error: %s", repr(exc))
6368
raise HTTPException(status_code=500, detail=repr(exc)) from exc
69+
70+
71+
async def isAdmin(username, token):
72+
TEAM_MEMBER_URL = (
73+
f"https://api.github.com/orgs/ceph/teams/{ADMIN_TEAM}/memberships/{username}"
74+
)
75+
async with httpx.AsyncClient() as client:
76+
headers = {
77+
"Authorization": "token " + token["access_token"],
78+
"Accept": "application/json",
79+
}
80+
response_org = await client.get(url=TEAM_MEMBER_URL, headers=headers)
81+
response_org_dic = dict(response_org.json())
82+
if response_org_dic.get("state") == "active":
83+
return True
84+
return False

0 commit comments

Comments
 (0)