mirror of https://github.com/docker/docs.git
312 lines
12 KiB
Markdown
312 lines
12 KiB
Markdown
---
|
|
title: Manage webhooks via the API
|
|
description: Learn how to create, configure, and test webhooks for DTR using the API.
|
|
keywords: dtr, webhooks, api, registry
|
|
---
|
|
|
|
## Prerequisite
|
|
|
|
See [Webhook types](/ee/dtr/admin/manage-webhooks/index.md/#webhook-types) for a list of events you can trigger notifications for via the API.
|
|
|
|
## API Base URL
|
|
|
|
Your DTR hostname serves as the base URL for your API requests.
|
|
|
|
## Swagger API explorer
|
|
|
|
From the DTR web interface, click **API** on the bottom left navigation pane to explore the API resources and endpoints. Click **Execute** to send your API request.
|
|
|
|
## API requests via curl
|
|
|
|
You can use [curl](https://curl.haxx.se/docs/manpage.html) to send HTTP or HTTPS API requests. Note that you will have to specify `skipTLSVerification: true` on your request in order to test the webhook endpoint over HTTP.
|
|
|
|
### Example curl request
|
|
|
|
```bash
|
|
curl -u test-user:$TOKEN -X POST "https://dtr-example.com/api/v0/webhooks" -H "accept: application/json" -H "content-type: application/json" -d "{ \"endpoint\": \"https://webhook.site/441b1584-949d-4608-a7f3-f240bdd31019\", \"key\": \"maria-testorg/lab-words\", \"skipTLSVerification\": true, \"type\": \"TAG_PULL\"}"
|
|
```
|
|
|
|
### Example JSON response
|
|
|
|
```json
|
|
{
|
|
"id": "b7bf702c31601efb4796da59900ddc1b7c72eb8ca80fdfb1b9fecdbad5418155",
|
|
"type": "TAG_PULL",
|
|
"key": "maria-testorg/lab-words",
|
|
"endpoint": "https://webhook.site/441b1584-949d-4608-a7f3-f240bdd31019",
|
|
"authorID": "194efd8e-9ee6-4d43-a34b-eefd9ce39087",
|
|
"createdAt": "2019-05-22T01:55:20.471286995Z",
|
|
"lastSuccessfulAt": "0001-01-01T00:00:00Z",
|
|
"inactive": false,
|
|
"tlsCert": "",
|
|
"skipTLSVerification": true
|
|
}
|
|
```
|
|
|
|
## Subscribe to events
|
|
|
|
To subscribe to events, send a `POST` request to
|
|
`/api/v0/webhooks` with the following JSON payload:
|
|
|
|
### Example usage
|
|
|
|
```
|
|
{
|
|
"type": "TAG_PUSH",
|
|
"key": "foo/bar",
|
|
"endpoint": "https://example.com"
|
|
}
|
|
```
|
|
|
|
The keys in the payload are:
|
|
|
|
- `type`: The event type to subcribe to.
|
|
- `key`: The namespace/organization or repo to subscribe to. For example, "foo/bar" to subscribe to
|
|
pushes to the "bar" repository within the namespace/organization "foo".
|
|
- `endpoint`: The URL to send the JSON payload to.
|
|
|
|
Normal users **must** supply a "key" to scope a particular webhook event to
|
|
a repository or a namespace/organization. DTR admins can choose to omit this,
|
|
meaning a POST event notification of your specified type will be sent for all DTR repositories and namespaces.
|
|
|
|
### Receive a payload
|
|
|
|
Whenever your specified event type occurs, DTR will send a POST request to the given
|
|
endpoint with a JSON-encoded payload. The payload will always have the
|
|
following wrapper:
|
|
|
|
```
|
|
{
|
|
"type": "...",
|
|
"createdAt": "2012-04-23T18:25:43.511Z",
|
|
"contents": {...}
|
|
}
|
|
```
|
|
|
|
- `type` refers to the event type received at the specified subscription endpoint.
|
|
- `contents` refers to the payload of the event itself. Each event is different, therefore the
|
|
structure of the JSON object in `contents` will change depending on the event
|
|
type. See [Content structure](#content-structure) for more details.
|
|
|
|
### Test payload subscriptions
|
|
|
|
Before subscribing to an event, you can view and test your endpoints using
|
|
fake data. To send a test payload, send `POST` request to
|
|
`/api/v0/webhooks/test` with the following payload:
|
|
|
|
```
|
|
{
|
|
"type": "...",
|
|
"endpoint": "https://www.example.com/"
|
|
}
|
|
```
|
|
|
|
Change `type` to the event type that you want to receive. DTR will then send
|
|
an example payload to your specified endpoint. The example
|
|
payload sent is always the same.
|
|
|
|
## Content structure
|
|
|
|
Comments after (`//`) are for informational purposes only, and the example payloads have been clipped for brevity.
|
|
|
|
### Repository event content structure
|
|
|
|
**Tag push**
|
|
|
|
```
|
|
{
|
|
"namespace": "", // (string) namespace/organization for the repository
|
|
"repository": "", // (string) repository name
|
|
"tag": "", // (string) the name of the tag just pushed
|
|
"digest": "", // (string) sha256 digest of the manifest the tag points to (eg. "sha256:0afb...")
|
|
"imageName": "", // (string) the fully-qualified image name including DTR host used to pull the image (eg. 10.10.10.1/foo/bar:tag)
|
|
"os": "", // (string) the OS for the tag's manifest
|
|
"architecture": "", // (string) the architecture for the tag's manifest
|
|
"author": "", // (string) the username of the person who pushed the tag
|
|
"pushedAt": "", // (string) JSON-encoded timestamp of when the push occurred
|
|
...
|
|
}
|
|
```
|
|
|
|
**Tag delete**
|
|
|
|
```
|
|
{
|
|
"namespace": "", // (string) namespace/organization for the repository
|
|
"repository": "", // (string) repository name
|
|
"tag": "", // (string) the name of the tag just deleted
|
|
"digest": "", // (string) sha256 digest of the manifest the tag points to (eg. "sha256:0afb...")
|
|
"imageName": "", // (string) the fully-qualified image name including DTR host used to pull the image (eg. 10.10.10.1/foo/bar:tag)
|
|
"os": "", // (string) the OS for the tag's manifest
|
|
"architecture": "", // (string) the architecture for the tag's manifest
|
|
"author": "", // (string) the username of the person who deleted the tag
|
|
"deletedAt": "", // (string) JSON-encoded timestamp of when the delete occurred
|
|
...
|
|
}
|
|
```
|
|
**Manifest push**
|
|
|
|
```
|
|
{
|
|
"namespace": "", // (string) namespace/organization for the repository
|
|
"repository": "", // (string) repository name
|
|
"digest": "", // (string) sha256 digest of the manifest (eg. "sha256:0afb...")
|
|
"imageName": "", // (string) the fully-qualified image name including DTR host used to pull the image (eg. 10.10.10.1/foo/bar@sha256:0afb...)
|
|
"os": "", // (string) the OS for the manifest
|
|
"architecture": "", // (string) the architecture for the manifest
|
|
"author": "", // (string) the username of the person who pushed the manifest
|
|
...
|
|
}
|
|
```
|
|
|
|
**Manifest delete**
|
|
|
|
```
|
|
{
|
|
"namespace": "", // (string) namespace/organization for the repository
|
|
"repository": "", // (string) repository name
|
|
"digest": "", // (string) sha256 digest of the manifest (eg. "sha256:0afb...")
|
|
"imageName": "", // (string) the fully-qualified image name including DTR host used to pull the image (eg. 10.10.10.1/foo/bar@sha256:0afb...)
|
|
"os": "", // (string) the OS for the manifest
|
|
"architecture": "", // (string) the architecture for the manifest
|
|
"author": "", // (string) the username of the person who deleted the manifest
|
|
"deletedAt": "", // (string) JSON-encoded timestamp of when the delete occurred
|
|
...
|
|
}
|
|
```
|
|
|
|
**Security scan completed**
|
|
|
|
```
|
|
{
|
|
"namespace": "", // (string) namespace/organization for the repository
|
|
"repository": "", // (string) repository name
|
|
"tag": "", // (string) the name of the tag scanned
|
|
"imageName": "", // (string) the fully-qualified image name including DTR host used to pull the image (eg. 10.10.10.1/foo/bar:tag)
|
|
"scanSummary": {
|
|
"namespace": "", // (string) repository's namespace/organization name
|
|
"repository": "", // (string) repository name
|
|
"tag": "", // (string) the name of the tag just pushed
|
|
"critical": 0, // (int) number of critical issues, where CVSS >= 7.0
|
|
"major": 0, // (int) number of major issues, where CVSS >= 4.0 && CVSS < 7
|
|
"minor": 0, // (int) number of minor issues, where CVSS > 0 && CVSS < 4.0
|
|
"last_scan_status": 0, // (int) enum; see scan status section
|
|
"check_completed_at": "", // (string) JSON-encoded timestamp of when the scan completed
|
|
...
|
|
}
|
|
}
|
|
```
|
|
|
|
**Security scan failed**
|
|
|
|
```
|
|
{
|
|
"namespace": "", // (string) namespace/organization for the repository
|
|
"repository": "", // (string) repository name
|
|
"tag": "", // (string) the name of the tag scanned
|
|
"imageName": "", // (string) the fully-qualified image name including DTR host used to pull the image (eg. 10.10.10.1/foo/bar@sha256:0afb...)
|
|
"error": "", // (string) the error that occurred while scanning
|
|
...
|
|
}
|
|
```
|
|
|
|
### Namespace-specific event structure
|
|
|
|
**Repository event (created/updated/deleted)**
|
|
|
|
```
|
|
{
|
|
"namespace": "", // (string) repository's namespace/organization name
|
|
"repository": "", // (string) repository name
|
|
"event": "", // (string) enum: "REPO_CREATED", "REPO_DELETED" or "REPO_UPDATED"
|
|
"author": "", // (string) the name of the user responsible for the event
|
|
"data": {} // (object) when updating or creating a repo this follows the same format as an API response from /api/v0/repositories/{namespace}/{repository}
|
|
}
|
|
```
|
|
|
|
### Global event structure
|
|
|
|
**Security scanner update complete**
|
|
|
|
```
|
|
{
|
|
"scanner_version": "",
|
|
"scanner_updated_at": "", // (string) JSON-encoded timestamp of when the scanner updated
|
|
"db_version": 0, // (int) newly updated database version
|
|
"db_updated_at": "", // (string) JSON-encoded timestamp of when the database updated
|
|
"success": <true|false> // (bool) whether the update was successful
|
|
"replicas": { // (object) a map keyed by replica ID containing update information for each replica
|
|
"replica_id": {
|
|
"db_updated_at": "", // (string) JSON-encoded time of when the replica updated
|
|
"version": "", // (string) version updated to
|
|
"replica_id": "" // (string) replica ID
|
|
},
|
|
...
|
|
}
|
|
}
|
|
```
|
|
|
|
### Security scan status codes
|
|
|
|
|
|
- 0: **Failed**. An error occurred checking an image's layer
|
|
- 1: **Unscanned**. The image has not yet been scanned
|
|
- 2: **Scanning**. Scanning in progress
|
|
- 3: **Pending**: The image will be scanned when a worker is available
|
|
- 4: **Scanned**: The image has been scanned but vulnerabilities have not yet been checked
|
|
- 5: **Checking**: The image is being checked for vulnerabilities
|
|
- 6: **Completed**: The image has been fully security scanned
|
|
|
|
|
|
## View and manage existing subscriptions
|
|
|
|
### View all subscriptions
|
|
|
|
To view existing subscriptions, send a `GET` request to `/api/v0/webhooks`. As
|
|
a normal user (i.e. not a DTR admin), this will show all of your
|
|
current subscriptions across every namespace/organization and repository. As a DTR
|
|
admin, this will show **every** webhook configured for your DTR.
|
|
|
|
The API response will be in the following format:
|
|
|
|
```
|
|
[
|
|
{
|
|
"id": "", // (string): UUID of the webhook subscription
|
|
"type": "", // (string): webhook event type
|
|
"key": "", // (string): the individual resource this subscription is scoped to
|
|
"endpoint": "", // (string): the endpoint to send POST event notifications to
|
|
"authorID": "", // (string): the user ID resposible for creating the subscription
|
|
"createdAt": "", // (string): JSON-encoded datetime when the subscription was created
|
|
},
|
|
...
|
|
]
|
|
```
|
|
|
|
For more information, [view the API documentation](/reference/dtr/{{site.dtr_version}}/api/).
|
|
|
|
### View subscriptions for a particular resource
|
|
|
|
You can also view subscriptions for a given resource that you are an
|
|
admin of. For example, if you have admin rights to the repository
|
|
"foo/bar", you can view all subscriptions (even other people's) from a
|
|
particular API endpoint. These endpoints are:
|
|
|
|
- `GET /api/v0/repositories/{namespace}/{repository}/webhooks`: View all
|
|
webhook subscriptions for a repository
|
|
- `GET /api/v0/repositories/{namespace}/webhooks`: View all webhook subscriptions for a
|
|
namespace/organization
|
|
|
|
### Delete a subscription
|
|
|
|
To delete a webhook subscription, send a `DELETE` request to
|
|
`/api/v0/webhooks/{id}`, replacing `{id}` with the webhook subscription ID
|
|
which you would like to delete.
|
|
|
|
Only a DTR admin or an admin for the resource with the event subscription can delete a subscription. As a normal user, you can only
|
|
delete subscriptions for repositories which you manage.
|
|
|
|
## Where to go next
|
|
|
|
- [Manage jobs](/ee/dtr/admin/manage-jobs/job-queue/)
|