Skip to content

Commit 46f0d30

Browse files
committed
also do event classes APIs
1 parent 3aee3cd commit 46f0d30

File tree

6 files changed

+241
-0
lines changed

6 files changed

+241
-0
lines changed

nexus/external-api/output/nexus_tags.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ webhook_create POST /experimental/v1/webhooks
237237
webhook_delete DELETE /experimental/v1/webhooks/{webhook_id}
238238
webhook_delivery_list GET /experimental/v1/webhooks/{webhook_id}/deliveries
239239
webhook_delivery_resend POST /experimental/v1/webhooks/{webhook_id}/deliveries/{event_id}/resend
240+
webhook_event_class_list GET /experimental/v1/webhook-events/classes
241+
webhook_event_class_view GET /experimental/v1/webhook-events/classes/{name}
240242
webhook_secrets_add POST /experimental/v1/webhooks/{webhook_id}/secrets
241243
webhook_secrets_list GET /experimental/v1/webhooks/{webhook_id}/secrets
242244
webhook_update PUT /experimental/v1/webhooks/{webhook_id}

nexus/external-api/src/lib.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3097,6 +3097,30 @@ pub trait NexusExternalApi {
30973097

30983098
// Webhooks (experimental)
30993099

3100+
/// List webhook event classes
3101+
#[endpoint {
3102+
method = GET,
3103+
path = "/experimental/v1/webhook-events/classes",
3104+
tags = ["system/webhooks"],
3105+
}]
3106+
async fn webhook_event_class_list(
3107+
rqctx: RequestContext<Self::Context>,
3108+
query_params: Query<
3109+
PaginationParams<params::EventClassFilter, params::EventClassPage>,
3110+
>,
3111+
) -> Result<HttpResponseOk<ResultsPage<views::EventClass>>, HttpError>;
3112+
3113+
/// Fetch details on an event class by name.
3114+
#[endpoint {
3115+
method = GET,
3116+
path ="/experimental/v1/webhook-events/classes/{name}",
3117+
tags = ["system/webhooks"],
3118+
}]
3119+
async fn webhook_event_class_view(
3120+
rqctx: RequestContext<Self::Context>,
3121+
path_params: Path<params::EventClassSelector>,
3122+
) -> Result<HttpResponseOk<views::EventClass>, HttpError>;
3123+
31003124
/// Get the configuration for a webhook receiver.
31013125
#[endpoint {
31023126
method = GET,

nexus/src/external_api/http_entrypoints.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6299,6 +6299,54 @@ impl NexusExternalApi for NexusExternalApiImpl {
62996299
device_auth::device_access_token(rqctx, params.into_inner()).await
63006300
}
63016301

6302+
async fn webhook_event_class_list(
6303+
rqctx: RequestContext<Self::Context>,
6304+
query_params: Query<
6305+
PaginationParams<params::EventClassFilter, params::EventClassPage>,
6306+
>,
6307+
) -> Result<HttpResponseOk<ResultsPage<views::EventClass>>, HttpError> {
6308+
let apictx = rqctx.context();
6309+
let handler = async {
6310+
let nexus = &apictx.context.nexus;
6311+
6312+
let opctx =
6313+
crate::context::op_context_for_external_api(&rqctx).await?;
6314+
6315+
Err(nexus
6316+
.unimplemented_todo(&opctx, crate::app::Unimpl::Public)
6317+
.await
6318+
.into())
6319+
};
6320+
apictx
6321+
.context
6322+
.external_latencies
6323+
.instrument_dropshot_handler(&rqctx, handler)
6324+
.await
6325+
}
6326+
6327+
async fn webhook_event_class_view(
6328+
rqctx: RequestContext<Self::Context>,
6329+
path_params: Path<params::EventClassSelector>,
6330+
) -> Result<HttpResponseOk<views::EventClass>, HttpError> {
6331+
let apictx = rqctx.context();
6332+
let handler = async {
6333+
let nexus = &apictx.context.nexus;
6334+
6335+
let opctx =
6336+
crate::context::op_context_for_external_api(&rqctx).await?;
6337+
6338+
Err(nexus
6339+
.unimplemented_todo(&opctx, crate::app::Unimpl::Public)
6340+
.await
6341+
.into())
6342+
};
6343+
apictx
6344+
.context
6345+
.external_latencies
6346+
.instrument_dropshot_handler(&rqctx, handler)
6347+
.await
6348+
}
6349+
63026350
async fn webhook_view(
63036351
rqctx: RequestContext<Self::Context>,
63046352
_path_params: Path<params::WebhookPath>,

nexus/types/src/external_api/params.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2282,6 +2282,25 @@ pub struct DeviceAccessTokenRequest {
22822282

22832283
// Webhooks
22842284

2285+
/// Query params for listing webhook event classes.
2286+
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
2287+
pub struct EventClassFilter {
2288+
/// An optional glob pattern for filtering event class names.
2289+
pub filter: Option<String>,
2290+
}
2291+
2292+
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
2293+
pub struct EventClassPage {
2294+
/// The last webhook event class returned by a previous page.
2295+
pub last_seen: String,
2296+
}
2297+
2298+
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
2299+
pub struct EventClassSelector {
2300+
/// The name of the event class.
2301+
pub name: String,
2302+
}
2303+
22852304
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
22862305
pub struct WebhookCreate {
22872306
/// An identifier for this webhook receiver, which must be unique.

nexus/types/src/external_api/views.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,16 @@ pub struct OxqlQueryResult {
10301030

10311031
// WEBHOOKS
10321032

1033+
/// A webhook event class.
1034+
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
1035+
pub struct EventClass {
1036+
/// The name of the event class.
1037+
pub name: String,
1038+
1039+
/// A description of what this event class represents.
1040+
pub description: String,
1041+
}
1042+
10331043
/// The configuration for a webhook.
10341044
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
10351045
pub struct Webhook {

openapi/nexus.json

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,105 @@
301301
}
302302
}
303303
},
304+
"/experimental/v1/webhook-events/classes": {
305+
"get": {
306+
"tags": [
307+
"system/webhooks"
308+
],
309+
"summary": "List webhook event classes",
310+
"operationId": "webhook_event_class_list",
311+
"parameters": [
312+
{
313+
"in": "query",
314+
"name": "filter",
315+
"description": "An optional glob pattern for filtering event class names.",
316+
"schema": {
317+
"nullable": true,
318+
"type": "string"
319+
}
320+
},
321+
{
322+
"in": "query",
323+
"name": "limit",
324+
"description": "Maximum number of items returned by a single call",
325+
"schema": {
326+
"nullable": true,
327+
"type": "integer",
328+
"format": "uint32",
329+
"minimum": 1
330+
}
331+
},
332+
{
333+
"in": "query",
334+
"name": "page_token",
335+
"description": "Token returned by previous call to retrieve the subsequent page",
336+
"schema": {
337+
"nullable": true,
338+
"type": "string"
339+
}
340+
}
341+
],
342+
"responses": {
343+
"200": {
344+
"description": "successful operation",
345+
"content": {
346+
"application/json": {
347+
"schema": {
348+
"$ref": "#/components/schemas/EventClassResultsPage"
349+
}
350+
}
351+
}
352+
},
353+
"4XX": {
354+
"$ref": "#/components/responses/Error"
355+
},
356+
"5XX": {
357+
"$ref": "#/components/responses/Error"
358+
}
359+
},
360+
"x-dropshot-pagination": {
361+
"required": []
362+
}
363+
}
364+
},
365+
"/experimental/v1/webhook-events/classes/{name}": {
366+
"get": {
367+
"tags": [
368+
"system/webhooks"
369+
],
370+
"summary": "Fetch details on an event class by name.",
371+
"operationId": "webhook_event_class_view",
372+
"parameters": [
373+
{
374+
"in": "path",
375+
"name": "name",
376+
"description": "The name of the event class.",
377+
"required": true,
378+
"schema": {
379+
"type": "string"
380+
}
381+
}
382+
],
383+
"responses": {
384+
"200": {
385+
"description": "successful operation",
386+
"content": {
387+
"application/json": {
388+
"schema": {
389+
"$ref": "#/components/schemas/EventClass"
390+
}
391+
}
392+
}
393+
},
394+
"4XX": {
395+
"$ref": "#/components/responses/Error"
396+
},
397+
"5XX": {
398+
"$ref": "#/components/responses/Error"
399+
}
400+
}
401+
}
402+
},
304403
"/experimental/v1/webhooks": {
305404
"post": {
306405
"tags": [
@@ -14296,6 +14395,45 @@
1429614395
"request_id"
1429714396
]
1429814397
},
14398+
"EventClass": {
14399+
"description": "A webhook event class.",
14400+
"type": "object",
14401+
"properties": {
14402+
"description": {
14403+
"description": "A description of what this event class represents.",
14404+
"type": "string"
14405+
},
14406+
"name": {
14407+
"description": "The name of the event class.",
14408+
"type": "string"
14409+
}
14410+
},
14411+
"required": [
14412+
"description",
14413+
"name"
14414+
]
14415+
},
14416+
"EventClassResultsPage": {
14417+
"description": "A single page of results",
14418+
"type": "object",
14419+
"properties": {
14420+
"items": {
14421+
"description": "list of items on this page of results",
14422+
"type": "array",
14423+
"items": {
14424+
"$ref": "#/components/schemas/EventClass"
14425+
}
14426+
},
14427+
"next_page": {
14428+
"nullable": true,
14429+
"description": "token used to fetch the next page of results (if any)",
14430+
"type": "string"
14431+
}
14432+
},
14433+
"required": [
14434+
"items"
14435+
]
14436+
},
1429914437
"ExternalIp": {
1430014438
"oneOf": [
1430114439
{

0 commit comments

Comments
 (0)