Skip to content

Commit bd0d29d

Browse files
committed
Support secret events in API, CLI, and UI
1 parent b4c6f17 commit bd0d29d

10 files changed

Lines changed: 69 additions & 2 deletions

File tree

frontend/src/pages/Events/List/hooks/useColumnDefinitions.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,19 @@ export const useColumnsDefinitions = () => {
138138
</div>
139139
);
140140

141+
case 'secret':
142+
return (
143+
<div>
144+
Secret{' '}
145+
{target.project_name && (
146+
<NavigateLink href={ROUTES.PROJECT.DETAILS.FORMAT(target.project_name)}>
147+
{target.project_name}
148+
</NavigateLink>
149+
)}
150+
/{target.name}
151+
</div>
152+
);
153+
141154
default:
142155
return '---';
143156
}

frontend/src/pages/Events/List/hooks/useFilters.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type RequestParamsKeys = keyof Pick<
1919
| 'target_jobs'
2020
| 'target_volumes'
2121
| 'target_gateways'
22+
| 'target_secrets'
2223
| 'within_projects'
2324
| 'within_fleets'
2425
| 'within_runs'
@@ -35,6 +36,7 @@ const filterKeys: Record<string, RequestParamsKeys> = {
3536
TARGET_JOBS: 'target_jobs',
3637
TARGET_VOLUMES: 'target_volumes',
3738
TARGET_GATEWAYS: 'target_gateways',
39+
TARGET_SECRETS: 'target_secrets',
3840
WITHIN_PROJECTS: 'within_projects',
3941
WITHIN_FLEETS: 'within_fleets',
4042
WITHIN_RUNS: 'within_runs',
@@ -53,6 +55,7 @@ const multipleChoiseKeys: RequestParamsKeys[] = [
5355
'target_jobs',
5456
'target_volumes',
5557
'target_gateways',
58+
'target_secrets',
5659
'within_projects',
5760
'within_fleets',
5861
'within_runs',
@@ -69,6 +72,7 @@ const targetTypes = [
6972
{ label: 'Job', value: 'job' },
7073
{ label: 'Volume', value: 'volume' },
7174
{ label: 'Gateway', value: 'gateway' },
75+
{ label: 'Secret', value: 'secret' },
7276
];
7377

7478
export const useFilters = () => {
@@ -171,6 +175,11 @@ export const useFilters = () => {
171175
operators: ['='],
172176
propertyLabel: 'Target gateways',
173177
},
178+
{
179+
key: filterKeys.TARGET_SECRETS,
180+
operators: ['='],
181+
propertyLabel: 'Target secrets',
182+
},
174183

175184
{
176185
key: filterKeys.WITHIN_PROJECTS,

frontend/src/types/event.d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
declare type TEventTargetType = 'project' | 'user' | 'fleet' | 'instance' | 'run' | 'job' | 'volume' | 'gateway';
1+
declare type TEventTargetType = 'project' | 'user' | 'fleet' | 'instance' | 'run' | 'job' | 'volume' | 'gateway' | 'secret';
22

33
declare type TEventListRequestParams = Omit<TBaseRequestListParams, 'prev_created_at'> & {
44
prev_recorded_at?: string;
@@ -10,6 +10,7 @@ declare type TEventListRequestParams = Omit<TBaseRequestListParams, 'prev_create
1010
target_jobs?: string[];
1111
target_volumes?: string[];
1212
target_gateways?: string[];
13+
target_secrets?: string[];
1314
within_projects?: string[];
1415
within_fleets?: string[];
1516
within_runs?: string[];
@@ -18,7 +19,7 @@ declare type TEventListRequestParams = Omit<TBaseRequestListParams, 'prev_create
1819
};
1920

2021
declare interface IEventTarget {
21-
type: 'project' | 'user' | 'fleet' | 'instance' | 'run' | 'job' | 'volume' | 'gateway';
22+
type: 'project' | 'user' | 'fleet' | 'instance' | 'run' | 'job' | 'volume' | 'gateway' | 'secret';
2223
project_id?: string;
2324
project_name?: string;
2425
id: string;

src/dstack/_internal/cli/commands/event.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ def _register(self):
6767
dest="target_gateways",
6868
help="Only show events that target the specified gateways",
6969
)
70+
target_filters_group.add_argument(
71+
"--target-secret",
72+
action="append",
73+
metavar="NAME",
74+
dest="target_secrets",
75+
help="Only show events that target the specified secrets",
76+
)
7077
within_filters_group = parser.add_mutually_exclusive_group()
7178
within_filters_group.add_argument(
7279
"--within-fleet",
@@ -139,6 +146,10 @@ def _build_filters(args: argparse.Namespace, api: Client) -> EventListFilters:
139146
" Update the server to 0.20.7 or higher or remove --target-gateway."
140147
)
141148
filters.target_gateways.append(id)
149+
elif args.target_secrets:
150+
filters.target_secrets = [
151+
api.client.secrets.get(api.project, name=name).id for name in args.target_secrets
152+
]
142153

143154
if args.within_fleets:
144155
filters.within_fleets = [

src/dstack/_internal/cli/services/events.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class EventListFilters:
1818
target_runs: Optional[list[uuid.UUID]] = None
1919
target_volumes: Optional[list[uuid.UUID]] = None
2020
target_gateways: Optional[list[uuid.UUID]] = None
21+
target_secrets: Optional[list[uuid.UUID]] = None
2122
within_projects: Optional[list[uuid.UUID]] = None
2223
within_fleets: Optional[list[uuid.UUID]] = None
2324
within_runs: Optional[list[uuid.UUID]] = None

src/dstack/_internal/core/models/events.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class EventTargetType(str, Enum):
1818
JOB = "job"
1919
VOLUME = "volume"
2020
GATEWAY = "gateway"
21+
SECRET = "secret"
2122

2223

2324
class EventTarget(CoreModel):

src/dstack/_internal/server/routers/events.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ async def list_events(
4646
target_jobs=body.target_jobs,
4747
target_volumes=body.target_volumes,
4848
target_gateways=body.target_gateways,
49+
target_secrets=body.target_secrets,
4950
within_projects=body.within_projects,
5051
within_fleets=body.within_fleets,
5152
within_runs=body.within_runs,

src/dstack/_internal/server/schemas/events.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,17 @@ class ListEventsRequest(CoreModel):
102102
max_items=MAX_FILTER_ITEMS,
103103
),
104104
] = None
105+
target_secrets: Annotated[
106+
Optional[list[uuid.UUID]],
107+
Field(
108+
description=(
109+
"List of secret IDs."
110+
" The response will only include events that target the specified secrets"
111+
),
112+
min_items=MIN_FILTER_ITEMS,
113+
max_items=MAX_FILTER_ITEMS,
114+
),
115+
] = None
105116
within_projects: Annotated[
106117
Optional[list[uuid.UUID]],
107118
Field(

src/dstack/_internal/server/services/events.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
MemberModel,
2121
ProjectModel,
2222
RunModel,
23+
SecretModel,
2324
UserModel,
2425
VolumeModel,
2526
)
@@ -93,6 +94,7 @@ def from_model(
9394
JobModel,
9495
ProjectModel,
9596
RunModel,
97+
SecretModel,
9698
UserModel,
9799
VolumeModel,
98100
],
@@ -139,6 +141,13 @@ def from_model(
139141
id=model.id,
140142
name=model.run_name,
141143
)
144+
if isinstance(model, SecretModel):
145+
return Target(
146+
type=EventTargetType.SECRET,
147+
project_id=model.project_id or model.project.id,
148+
id=model.id,
149+
name=model.name,
150+
)
142151
if isinstance(model, UserModel):
143152
return Target(
144153
type=EventTargetType.USER,
@@ -232,6 +241,7 @@ async def list_events(
232241
target_jobs: Optional[list[uuid.UUID]],
233242
target_volumes: Optional[list[uuid.UUID]],
234243
target_gateways: Optional[list[uuid.UUID]],
244+
target_secrets: Optional[list[uuid.UUID]],
235245
within_projects: Optional[list[uuid.UUID]],
236246
within_fleets: Optional[list[uuid.UUID]],
237247
within_runs: Optional[list[uuid.UUID]],
@@ -315,6 +325,13 @@ async def list_events(
315325
EventTargetModel.entity_id.in_(target_gateways),
316326
)
317327
)
328+
if target_secrets is not None:
329+
target_filters.append(
330+
and_(
331+
EventTargetModel.entity_type == EventTargetType.SECRET,
332+
EventTargetModel.entity_id.in_(target_secrets),
333+
)
334+
)
318335
if within_projects is not None:
319336
target_filters.append(EventTargetModel.entity_project_id.in_(within_projects))
320337
if within_fleets is not None:

src/dstack/api/server/_events.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def list(
3131
# NOTE: New parameters go here. Avoid positional parameters, they can break compatibility.
3232
target_volumes: Optional[list[UUID]] = None,
3333
target_gateways: Optional[list[UUID]] = None,
34+
target_secrets: Optional[list[UUID]] = None,
3435
) -> list[Event]:
3536
if prev_recorded_at is not None:
3637
# Time zones other than UTC are misinterpreted by the server:
@@ -45,6 +46,7 @@ def list(
4546
target_jobs=target_jobs,
4647
target_volumes=target_volumes,
4748
target_gateways=target_gateways,
49+
target_secrets=target_secrets,
4850
within_projects=within_projects,
4951
within_fleets=within_fleets,
5052
within_runs=within_runs,

0 commit comments

Comments
 (0)