Skip to content

Commit

Permalink
also do event classes APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
hawkw committed Jan 2, 2025
1 parent 3aee3cd commit b579475
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 0 deletions.
2 changes: 2 additions & 0 deletions nexus/external-api/output/nexus_tags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ webhook_create POST /experimental/v1/webhooks
webhook_delete DELETE /experimental/v1/webhooks/{webhook_id}
webhook_delivery_list GET /experimental/v1/webhooks/{webhook_id}/deliveries
webhook_delivery_resend POST /experimental/v1/webhooks/{webhook_id}/deliveries/{event_id}/resend
webhook_event_class_list GET /experimental/v1/webhook-events/classes
webhook_event_class_view GET /experimental/v1/webhook-events/classes/{name}
webhook_secrets_add POST /experimental/v1/webhooks/{webhook_id}/secrets
webhook_secrets_list GET /experimental/v1/webhooks/{webhook_id}/secrets
webhook_update PUT /experimental/v1/webhooks/{webhook_id}
Expand Down
24 changes: 24 additions & 0 deletions nexus/external-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3097,6 +3097,30 @@ pub trait NexusExternalApi {

// Webhooks (experimental)

/// List webhook event classes
#[endpoint {
method = GET,
path = "/experimental/v1/webhook-events/classes",
tags = ["system/webhooks"],
}]
async fn webhook_event_class_list(
rqctx: RequestContext<Self::Context>,
query_params: Query<
PaginationParams<params::EventClassFilter, params::EventClassPage>,
>,
) -> Result<HttpResponseOk<ResultsPage<views::EventClass>>, HttpError>;

/// Fetch details on an event class by name.
#[endpoint {
method = GET,
path ="/experimental/v1/webhook-events/classes/{name}",
tags = ["system/webhooks"],
}]
async fn webhook_event_class_view(
rqctx: RequestContext<Self::Context>,
path_params: Path<params::EventClassSelector>,
) -> Result<HttpResponseOk<views::EventClass>, HttpError>;

/// Get the configuration for a webhook receiver.
#[endpoint {
method = GET,
Expand Down
48 changes: 48 additions & 0 deletions nexus/src/external_api/http_entrypoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6299,6 +6299,54 @@ impl NexusExternalApi for NexusExternalApiImpl {
device_auth::device_access_token(rqctx, params.into_inner()).await
}

async fn webhook_event_class_list(
rqctx: RequestContext<Self::Context>,
_query_params: Query<
PaginationParams<params::EventClassFilter, params::EventClassPage>,
>,
) -> Result<HttpResponseOk<ResultsPage<views::EventClass>>, HttpError> {
let apictx = rqctx.context();
let handler = async {
let nexus = &apictx.context.nexus;

let opctx =
crate::context::op_context_for_external_api(&rqctx).await?;

Err(nexus
.unimplemented_todo(&opctx, crate::app::Unimpl::Public)
.await
.into())
};
apictx
.context
.external_latencies
.instrument_dropshot_handler(&rqctx, handler)
.await
}

async fn webhook_event_class_view(
rqctx: RequestContext<Self::Context>,
_path_params: Path<params::EventClassSelector>,
) -> Result<HttpResponseOk<views::EventClass>, HttpError> {
let apictx = rqctx.context();
let handler = async {
let nexus = &apictx.context.nexus;

let opctx =
crate::context::op_context_for_external_api(&rqctx).await?;

Err(nexus
.unimplemented_todo(&opctx, crate::app::Unimpl::Public)
.await
.into())
};
apictx
.context
.external_latencies
.instrument_dropshot_handler(&rqctx, handler)
.await
}

async fn webhook_view(
rqctx: RequestContext<Self::Context>,
_path_params: Path<params::WebhookPath>,
Expand Down
19 changes: 19 additions & 0 deletions nexus/types/src/external_api/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2282,6 +2282,25 @@ pub struct DeviceAccessTokenRequest {

// Webhooks

/// Query params for listing webhook event classes.
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct EventClassFilter {
/// An optional glob pattern for filtering event class names.
pub filter: Option<String>,
}

#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct EventClassPage {
/// The last webhook event class returned by a previous page.
pub last_seen: String,
}

#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct EventClassSelector {
/// The name of the event class.
pub name: String,
}

#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct WebhookCreate {
/// An identifier for this webhook receiver, which must be unique.
Expand Down
10 changes: 10 additions & 0 deletions nexus/types/src/external_api/views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,16 @@ pub struct OxqlQueryResult {

// WEBHOOKS

/// A webhook event class.
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct EventClass {
/// The name of the event class.
pub name: String,

/// A description of what this event class represents.
pub description: String,
}

/// The configuration for a webhook.
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct Webhook {
Expand Down
138 changes: 138 additions & 0 deletions openapi/nexus.json
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,105 @@
}
}
},
"/experimental/v1/webhook-events/classes": {
"get": {
"tags": [
"system/webhooks"
],
"summary": "List webhook event classes",
"operationId": "webhook_event_class_list",
"parameters": [
{
"in": "query",
"name": "filter",
"description": "An optional glob pattern for filtering event class names.",
"schema": {
"nullable": true,
"type": "string"
}
},
{
"in": "query",
"name": "limit",
"description": "Maximum number of items returned by a single call",
"schema": {
"nullable": true,
"type": "integer",
"format": "uint32",
"minimum": 1
}
},
{
"in": "query",
"name": "page_token",
"description": "Token returned by previous call to retrieve the subsequent page",
"schema": {
"nullable": true,
"type": "string"
}
}
],
"responses": {
"200": {
"description": "successful operation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EventClassResultsPage"
}
}
}
},
"4XX": {
"$ref": "#/components/responses/Error"
},
"5XX": {
"$ref": "#/components/responses/Error"
}
},
"x-dropshot-pagination": {
"required": []
}
}
},
"/experimental/v1/webhook-events/classes/{name}": {
"get": {
"tags": [
"system/webhooks"
],
"summary": "Fetch details on an event class by name.",
"operationId": "webhook_event_class_view",
"parameters": [
{
"in": "path",
"name": "name",
"description": "The name of the event class.",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "successful operation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EventClass"
}
}
}
},
"4XX": {
"$ref": "#/components/responses/Error"
},
"5XX": {
"$ref": "#/components/responses/Error"
}
}
}
},
"/experimental/v1/webhooks": {
"post": {
"tags": [
Expand Down Expand Up @@ -14296,6 +14395,45 @@
"request_id"
]
},
"EventClass": {
"description": "A webhook event class.",
"type": "object",
"properties": {
"description": {
"description": "A description of what this event class represents.",
"type": "string"
},
"name": {
"description": "The name of the event class.",
"type": "string"
}
},
"required": [
"description",
"name"
]
},
"EventClassResultsPage": {
"description": "A single page of results",
"type": "object",
"properties": {
"items": {
"description": "list of items on this page of results",
"type": "array",
"items": {
"$ref": "#/components/schemas/EventClass"
}
},
"next_page": {
"nullable": true,
"description": "token used to fetch the next page of results (if any)",
"type": "string"
}
},
"required": [
"items"
]
},
"ExternalIp": {
"oneOf": [
{
Expand Down

0 comments on commit b579475

Please sign in to comment.